All of lore.kernel.org
 help / color / mirror / Atom feed
* [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17
@ 2021-06-17  9:30 Paolo Bonzini
  2021-06-17  9:30 ` [PULL 01/45] vnc: avoid deprecation warnings for SASL on OS X Paolo Bonzini
                   ` (46 more replies)
  0 siblings, 47 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:30 UTC (permalink / raw)
  To: qemu-devel

The following changes since commit 1ea06abceec61b6f3ab33dadb0510b6e09fb61e2:

  Merge remote-tracking branch 'remotes/berrange-gitlab/tags/misc-fixes-pull-request' into staging (2021-06-14 15:59:13 +0100)

are available in the Git repository at:

  https://gitlab.com/bonzini/qemu.git tags/for-upstream

for you to fetch changes up to f51f8e3591393f7f274e1435ac22188e2dafdfe8:

  configure: Remove probe for _Static_assert (2021-06-16 15:03:26 +0200)

----------------------------------------------------------------
* avoid deprecation warnings for SASL on macOS 10.11 or newer
* fix -readconfig when config blocks have an id (like [chardev "qmp"])
* Error* initialization fixes
* Improvements to ESP emulation (Mark)
* Allow creating noreserve memory backends (David)
* Improvements to query-memdev (David)
* Bump compiler to C11 (Richard)
* First round of SVM fixes from GSoC project (Lara)

----------------------------------------------------------------
David Hildenbrand (18):
      softmmu/physmem: Mark shared anonymous memory RAM_SHARED
      softmmu/physmem: Fix ram_block_discard_range() to handle shared anonymous memory
      softmmu/physmem: Fix qemu_ram_remap() to handle shared anonymous memory
      util/mmap-alloc: Factor out calculation of the pagesize for the guard page
      util/mmap-alloc: Factor out reserving of a memory region to mmap_reserve()
      util/mmap-alloc: Factor out activating of memory to mmap_activate()
      softmmu/memory: Pass ram_flags to qemu_ram_alloc_from_fd()
      softmmu/memory: Pass ram_flags to memory_region_init_ram_shared_nomigrate()
      softmmu/memory: Pass ram_flags to qemu_ram_alloc() and qemu_ram_alloc_internal()
      util/mmap-alloc: Pass flags instead of separate bools to qemu_ram_mmap()
      memory: Introduce RAM_NORESERVE and wire it up in qemu_ram_mmap()
      util/mmap-alloc: Support RAM_NORESERVE via MAP_NORESERVE under Linux
      hostmem: Wire up RAM_NORESERVE via "reserve" property
      qmp: Clarify memory backend properties returned via query-memdev
      qmp: Include "share" property of memory backends
      hmp: Print "share" property of memory backends with "info memdev"
      qmp: Include "reserve" property of memory backends
      hmp: Print "reserve" property of memory backends with "info memdev"

David Michael (1):
      configure: map x32 to cpu_family x86_64 for meson

Lara Lazier (4):
      target/i386: Refactored intercept checks into cpu_svm_has_intercept
      target/i386: Added consistency checks for VMRUN intercept and ASID
      target/i386: Added consistency checks for CR0
      target/i386: Added Intercept CR0 writes check

Mark Cave-Ayland (8):
      esp: only assert INTR_DC interrupt flag if selection fails
      esp: only set ESP_RSEQ at the start of the select sequence
      esp: allow non-DMA callback in esp_transfer_data() initial transfer
      esp: handle non-DMA transfers from the target one byte at a time
      esp: ensure PDMA write transfers are flushed from the FIFO to the target immediately
      esp: revert 75ef849696 "esp: correctly fill bus id with requested lun"
      esp: correctly accumulate extended messages for PDMA
      esp: fix migration version check in esp_is_version_5()

Maxim Levitsky (1):
      block/scsi: correctly emulate the VPD block limits page

Paolo Bonzini (3):
      vnc: avoid deprecation warnings for SASL on OS X
      qemu-config: use qemu_opts_from_qdict
      esp: store lun coming from the MESSAGE OUT phase

Peng Liang (1):
      runstate: Initialize Error * to NULL

Richard Henderson (8):
      configure: Use -std=gnu11
      softfloat: Use _Generic instead of QEMU_GENERIC
      util: Use real functions for thread-posix QemuRecMutex
      util: Pass file+line to qemu_rec_mutex_unlock_impl
      util: Use unique type for QemuRecMutex in thread-posix.h
      include/qemu/lockable: Use _Generic instead of QEMU_GENERIC
      qemu/compiler: Remove QEMU_GENERIC
      configure: Remove probe for _Static_assert

Zhenzhong Duan (1):
      vl: Fix an assert failure in error path

 backends/hostmem-file.c                            |  11 +-
 backends/hostmem-memfd.c                           |   8 +-
 backends/hostmem-ram.c                             |   7 +-
 backends/hostmem.c                                 |  36 ++++
 configure                                          |  24 +--
 fpu/softfloat.c                                    |  16 +-
 hw/core/machine-hmp-cmds.c                         |   6 +
 hw/core/machine-qmp-cmds.c                         |   8 +
 hw/m68k/next-cube.c                                |   4 +-
 hw/misc/ivshmem.c                                  |   5 +-
 hw/scsi/esp.c                                      | 199 ++++++++++++-------
 hw/scsi/scsi-generic.c                             |   9 +-
 hw/scsi/trace-events                               |   3 +-
 include/exec/cpu-common.h                          |   1 +
 include/exec/memory.h                              |  42 ++--
 include/exec/ram_addr.h                            |   9 +-
 include/hw/scsi/esp.h                              |   1 +
 include/qemu/compiler.h                            |  51 -----
 include/qemu/lockable.h                            |  90 ++++-----
 include/qemu/mmap-alloc.h                          |  16 +-
 include/qemu/osdep.h                               |  34 +++-
 include/qemu/thread-posix.h                        |  14 +-
 include/qemu/thread-win32.h                        |   6 -
 include/qemu/thread.h                              |  15 +-
 include/sysemu/hostmem.h                           |   2 +-
 meson.build                                        |   2 +-
 migration/ram.c                                    |   3 +-
 qapi/machine.json                                  |  16 +-
 qapi/qom.json                                      |  10 +
 .../coccinelle/memory-region-housekeeping.cocci    |   8 +-
 softmmu/memory.c                                   |  27 ++-
 softmmu/physmem.c                                  |  68 ++++---
 softmmu/runstate.c                                 |   2 +-
 softmmu/vl.c                                       |   2 +-
 target/i386/cpu.h                                  |   6 +
 target/i386/svm.h                                  |   2 +
 target/i386/tcg/sysemu/misc_helper.c               |   9 +
 target/i386/tcg/sysemu/svm_helper.c                | 155 ++++++++-------
 ui/vnc-auth-sasl.c                                 |  20 ++
 ui/vnc-auth-sasl.h                                 |   1 +
 ui/vnc.c                                           |  10 +-
 util/mmap-alloc.c                                  | 212 +++++++++++++++------
 util/oslib-posix.c                                 |   7 +-
 util/oslib-win32.c                                 |  13 +-
 util/qemu-config.c                                 |  17 +-
 util/qemu-thread-posix.c                           |  24 ++-
 util/qemu-thread-win32.c                           |   2 +-
 47 files changed, 757 insertions(+), 476 deletions(-)
-- 
2.31.1



^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PULL 01/45] vnc: avoid deprecation warnings for SASL on OS X
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
@ 2021-06-17  9:30 ` Paolo Bonzini
  2021-06-17  9:30 ` [PULL 02/45] vl: Fix an assert failure in error path Paolo Bonzini
                   ` (45 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:30 UTC (permalink / raw)
  To: qemu-devel

Apple has deprecated sasl.h functions in OS X 10.11.  Therefore,
all files that use SASL API need to disable -Wdeprecated-declarations.
Remove the only use that is outside vnc-auth-sasl.c and add the
relevant #pragma GCC diagnostic there.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20210604120915.286195-1-pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 ui/vnc-auth-sasl.c | 20 ++++++++++++++++++++
 ui/vnc-auth-sasl.h |  1 +
 ui/vnc.c           | 10 ++--------
 3 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/ui/vnc-auth-sasl.c b/ui/vnc-auth-sasl.c
index df7dc08e9f..47fdae5b21 100644
--- a/ui/vnc-auth-sasl.c
+++ b/ui/vnc-auth-sasl.c
@@ -28,10 +28,30 @@
 #include "vnc.h"
 #include "trace.h"
 
+/*
+ * Apple has deprecated sasl.h functions in OS X 10.11.  Therefore,
+ * files that use SASL API need to disable -Wdeprecated-declarations.
+ */
+#ifdef CONFIG_DARWIN
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+
 /* Max amount of data we send/recv for SASL steps to prevent DOS */
 #define SASL_DATA_MAX_LEN (1024 * 1024)
 
 
+bool vnc_sasl_server_init(Error **errp)
+{
+    int saslErr = sasl_server_init(NULL, "qemu");
+
+    if (saslErr != SASL_OK) {
+        error_setg(errp, "Failed to initialize SASL auth: %s",
+                   sasl_errstring(saslErr, NULL, NULL));
+        return false;
+    }
+    return true;
+}
+
 void vnc_sasl_client_cleanup(VncState *vs)
 {
     if (vs->sasl.conn) {
diff --git a/ui/vnc-auth-sasl.h b/ui/vnc-auth-sasl.h
index 1bfb86c6f5..367b8672cc 100644
--- a/ui/vnc-auth-sasl.h
+++ b/ui/vnc-auth-sasl.h
@@ -63,6 +63,7 @@ struct VncDisplaySASL {
     char *authzid;
 };
 
+bool vnc_sasl_server_init(Error **errp);
 void vnc_sasl_client_cleanup(VncState *vs);
 
 size_t vnc_client_read_sasl(VncState *vs);
diff --git a/ui/vnc.c b/ui/vnc.c
index b3d4d7b9a5..f0a1550d58 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -4154,14 +4154,8 @@ void vnc_display_open(const char *id, Error **errp)
     trace_vnc_auth_init(vd, 1, vd->ws_auth, vd->ws_subauth);
 
 #ifdef CONFIG_VNC_SASL
-    if (sasl) {
-        int saslErr = sasl_server_init(NULL, "qemu");
-
-        if (saslErr != SASL_OK) {
-            error_setg(errp, "Failed to initialize SASL auth: %s",
-                       sasl_errstring(saslErr, NULL, NULL));
-            goto fail;
-        }
+    if (sasl && !vnc_sasl_server_init(errp)) {
+        goto fail;
     }
 #endif
     vd->lock_key_sync = lock_key_sync;
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 02/45] vl: Fix an assert failure in error path
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
  2021-06-17  9:30 ` [PULL 01/45] vnc: avoid deprecation warnings for SASL on OS X Paolo Bonzini
@ 2021-06-17  9:30 ` Paolo Bonzini
  2021-06-17  9:30 ` [PULL 03/45] qemu-config: use qemu_opts_from_qdict Paolo Bonzini
                   ` (44 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: Zhenzhong Duan, qemu-stable

From: Zhenzhong Duan <zhenzhong.duan@intel.com>

Based on the description of error_setg(), the local variable err in
qemu_maybe_daemonize() should be initialized to NULL.

Without fix, the uninitialized *errp triggers assert failure which
doesn't show much valuable information.

Before the fix:
qemu-system-x86_64: ../util/error.c:59: error_setv: Assertion `*errp == NULL' failed.

After fix:
qemu-system-x86_64: cannot create PID file: Cannot open pid file: Permission denied

Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Message-Id: <20210610084741.456260-1-zhenzhong.duan@intel.com>
Cc: qemu-stable@nongnu.org
Fixes: 0546c0609c ("vl: split various early command line options to a separate function", 2020-12-10)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 softmmu/vl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/softmmu/vl.c b/softmmu/vl.c
index 326c1e9080..feb4d201f3 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -2522,7 +2522,7 @@ static void qemu_process_help_options(void)
 
 static void qemu_maybe_daemonize(const char *pid_file)
 {
-    Error *err;
+    Error *err = NULL;
 
     os_daemonize();
     rcu_disable_atfork();
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 03/45] qemu-config: use qemu_opts_from_qdict
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
  2021-06-17  9:30 ` [PULL 01/45] vnc: avoid deprecation warnings for SASL on OS X Paolo Bonzini
  2021-06-17  9:30 ` [PULL 02/45] vl: Fix an assert failure in error path Paolo Bonzini
@ 2021-06-17  9:30 ` Paolo Bonzini
  2021-06-17  9:30 ` [PULL 04/45] block/scsi: correctly emulate the VPD block limits page Paolo Bonzini
                   ` (43 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: Markus Armbruster, qemu-stable

Using qemu_opts_absorb_qdict, and then checking for any leftover options,
is redundant because there is already a function that does the same,
qemu_opts_from_qdict.  qemu_opts_from_qdict consumes the whole dictionary
and therefore can just return an error message if an option fails to validate.

This also fixes a bug, because the "id" entry was retrieved in
qemu_config_do_parse and then left there by qemu_opts_absorb_qdict.
As a result, it was reported as an unrecognized option.

Reported-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Fixes: 3770141139 ("qemu-config: parse configuration files to a QDict")
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 util/qemu-config.c | 17 +----------------
 1 file changed, 1 insertion(+), 16 deletions(-)

diff --git a/util/qemu-config.c b/util/qemu-config.c
index 374f3bc460..84ee6dc4ea 100644
--- a/util/qemu-config.c
+++ b/util/qemu-config.c
@@ -429,29 +429,14 @@ out:
 void qemu_config_do_parse(const char *group, QDict *qdict, void *opaque, Error **errp)
 {
     QemuOptsList **lists = opaque;
-    const char *id = qdict_get_try_str(qdict, "id");
     QemuOptsList *list;
-    QemuOpts *opts;
-    const QDictEntry *unrecognized;
 
     list = find_list(lists, group, errp);
     if (!list) {
         return;
     }
 
-    opts = qemu_opts_create(list, id, 1, errp);
-    if (!opts) {
-        return;
-    }
-    if (!qemu_opts_absorb_qdict(opts, qdict, errp)) {
-        qemu_opts_del(opts);
-        return;
-    }
-    unrecognized = qdict_first(qdict);
-    if (unrecognized) {
-        error_setg(errp, QERR_INVALID_PARAMETER, unrecognized->key);
-        qemu_opts_del(opts);
-    }
+    qemu_opts_from_qdict(list, qdict, errp);
 }
 
 int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname, Error **errp)
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 04/45] block/scsi: correctly emulate the VPD block limits page
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (2 preceding siblings ...)
  2021-06-17  9:30 ` [PULL 03/45] qemu-config: use qemu_opts_from_qdict Paolo Bonzini
@ 2021-06-17  9:30 ` Paolo Bonzini
  2021-06-17  9:30 ` [PULL 05/45] runstate: Initialize Error * to NULL Paolo Bonzini
                   ` (42 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: Max Reitz, Maxim Levitsky

From: Maxim Levitsky <mlevitsk@redhat.com>

When the device doesn't support the VPD block limits page, we emulate it even
for SCSI passthrough.

As a part of the emulation we need to add it to the 'Supported VPD Pages'

The code that does this adds it to the page, but it doesn't increase the length
of the data to be copied to the guest, thus the guest never sees the VPD block
limits page as supported.

Bump the transfer size by 1 in this case.

Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20201217165612.942849-6-mlevitsk@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi/scsi-generic.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index 98c30c5d5c..40e039864f 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -147,7 +147,7 @@ static int execute_command(BlockBackend *blk,
     return 0;
 }
 
-static void scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s)
+static int scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s, int len)
 {
     uint8_t page, page_idx;
 
@@ -213,8 +213,13 @@ static void scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s)
                 r->buf[page_idx] = 0xb0;
             }
             stw_be_p(r->buf + 2, lduw_be_p(r->buf + 2) + 1);
+
+            if (len < r->buflen) {
+                len++;
+            }
         }
     }
+    return len;
 }
 
 static int scsi_generic_emulate_block_limits(SCSIGenericReq *r, SCSIDevice *s)
@@ -332,7 +337,7 @@ static void scsi_read_complete(void * opaque, int ret)
         }
     }
     if (r->req.cmd.buf[0] == INQUIRY) {
-        scsi_handle_inquiry_reply(r, s);
+        len = scsi_handle_inquiry_reply(r, s, len);
     }
 
 req_complete:
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 05/45] runstate: Initialize Error * to NULL
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (3 preceding siblings ...)
  2021-06-17  9:30 ` [PULL 04/45] block/scsi: correctly emulate the VPD block limits page Paolo Bonzini
@ 2021-06-17  9:30 ` Paolo Bonzini
  2021-06-17  9:30 ` [PULL 06/45] esp: only assert INTR_DC interrupt flag if selection fails Paolo Bonzini
                   ` (41 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peng Liang, Daniel P . Berrangé, qemu-stable

From: Peng Liang <liangpeng10@huawei.com>

Based on the description of error_setg(), the local variable err in
qemu_init_subsystems() should be initialized to NULL.

Fixes: efd7ab22fb ("vl: extract qemu_init_subsystems")
Cc: qemu-stable@nongnu.org
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Message-Id: <20210610131729.3906565-1-liangpeng10@huawei.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 softmmu/runstate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/softmmu/runstate.c b/softmmu/runstate.c
index 15640572c0..10d9b7365a 100644
--- a/softmmu/runstate.c
+++ b/softmmu/runstate.c
@@ -747,7 +747,7 @@ static void qemu_run_exit_notifiers(void)
 
 void qemu_init_subsystems(void)
 {
-    Error *err;
+    Error *err = NULL;
 
     os_set_line_buffering();
 
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 06/45] esp: only assert INTR_DC interrupt flag if selection fails
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (4 preceding siblings ...)
  2021-06-17  9:30 ` [PULL 05/45] runstate: Initialize Error * to NULL Paolo Bonzini
@ 2021-06-17  9:30 ` Paolo Bonzini
  2021-06-17  9:30 ` [PULL 07/45] esp: only set ESP_RSEQ at the start of the select sequence Paolo Bonzini
                   ` (40 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: Mark Cave-Ayland

From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

The datasheet sequence tables confirm that when a target selection fails, only
the INTR_DC interrupt flag should be asserted.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Fixes: cf47a41e05 ("esp: latch individual bits in ESP_RINTR register")
Message-Id: <20210518212511.21688-2-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi/esp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index b668acef82..000e45a624 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -213,7 +213,7 @@ static int esp_select(ESPState *s)
     if (!s->current_dev) {
         /* No such drive */
         s->rregs[ESP_RSTAT] = 0;
-        s->rregs[ESP_RINTR] |= INTR_DC;
+        s->rregs[ESP_RINTR] = INTR_DC;
         s->rregs[ESP_RSEQ] = SEQ_0;
         esp_raise_irq(s);
         return -1;
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 07/45] esp: only set ESP_RSEQ at the start of the select sequence
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (5 preceding siblings ...)
  2021-06-17  9:30 ` [PULL 06/45] esp: only assert INTR_DC interrupt flag if selection fails Paolo Bonzini
@ 2021-06-17  9:30 ` Paolo Bonzini
  2021-06-17  9:30 ` [PULL 08/45] esp: allow non-DMA callback in esp_transfer_data() initial transfer Paolo Bonzini
                   ` (39 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: Mark Cave-Ayland

From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

When processing a command to select a target and send a CDB, the ESP device
maintains a sequence step register so that if an error occurs the host can
determine which part of the selection/CDB submission sequence failed.

The old Linux 2.6 driver is really pedantic here: it checks the sequence step
register even if a command succeeds and complains loudly on the console if the
sequence step register doesn't match the expected bus phase and interrupt flags.

This reason this mismatch occurs is because the ESP emulation currently doesn't
update the bus phase until the next TI (Transfer Information) command and so the
cleared sequence step register is considered invalid for the stale bus phase.

Normally this isn't an issue as the host only checks the sequence step register
if an error occurs but the old Linux 2.6 driver does this in several places
causing a large stream of "esp0: STEP_ASEL for tgt 0" messages to appear on the
console during the boot process.

Fix this by not clearing the sequence step register when reading the interrupt
register and clearing the DMA status, so the guest sees a valid sequence step
and bus phase combination at the end of the command phase. No other change is
required since the sequence step register is correctly updated throughout the
selection/CDB submission sequence once one of the select commands is issued.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Fixes: 1b9e48a5bd ("esp: implement non-DMA transfers in PDMA mode")
Message-Id: <20210518212511.21688-3-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi/esp.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 000e45a624..18d4d56392 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -481,7 +481,6 @@ static void esp_dma_done(ESPState *s)
 {
     s->rregs[ESP_RSTAT] |= STAT_TC;
     s->rregs[ESP_RINTR] |= INTR_BS;
-    s->rregs[ESP_RSEQ] = 0;
     s->rregs[ESP_RFLAGS] = 0;
     esp_set_tc(s, 0);
     esp_raise_irq(s);
@@ -917,7 +916,15 @@ uint64_t esp_reg_read(ESPState *s, uint32_t saddr)
         val = s->rregs[ESP_RINTR];
         s->rregs[ESP_RINTR] = 0;
         s->rregs[ESP_RSTAT] &= ~STAT_TC;
-        s->rregs[ESP_RSEQ] = SEQ_0;
+        /*
+         * According to the datasheet ESP_RSEQ should be cleared, but as the
+         * emulation currently defers information transfers to the next TI
+         * command leave it for now so that pedantic guests such as the old
+         * Linux 2.6 driver see the correct flags before the next SCSI phase
+         * transition.
+         *
+         * s->rregs[ESP_RSEQ] = SEQ_0;
+         */
         esp_lower_irq(s);
         break;
     case ESP_TCHI:
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 08/45] esp: allow non-DMA callback in esp_transfer_data() initial transfer
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (6 preceding siblings ...)
  2021-06-17  9:30 ` [PULL 07/45] esp: only set ESP_RSEQ at the start of the select sequence Paolo Bonzini
@ 2021-06-17  9:30 ` Paolo Bonzini
  2021-06-17  9:30 ` [PULL 09/45] esp: handle non-DMA transfers from the target one byte at a time Paolo Bonzini
                   ` (38 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: Mark Cave-Ayland

From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

The current implementation only resumes DMA transfers when incoming data is
received from the target device, but this is also required for non-DMA transfers
with the next set of non-DMA changes.

Rather than duplicate the DMA/non-DMA dispatch logic in the initial transfer
section, update the code so that the initial transfer section can just
fallthrough to the main DMA/non-DMA dispatch logic.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Message-Id: <20210519100803.10293-2-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi/esp.c | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 18d4d56392..50757e9264 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -803,16 +803,6 @@ void esp_transfer_data(SCSIRequest *req, uint32_t len)
         s->rregs[ESP_RSTAT] |= STAT_TC;
         s->rregs[ESP_RINTR] |= INTR_BS;
         esp_raise_irq(s);
-
-        /*
-         * If data is ready to transfer and the TI command has already
-         * been executed, start DMA immediately. Otherwise DMA will start
-         * when host sends the TI command
-         */
-        if (s->ti_size && (s->rregs[ESP_CMD] == (CMD_TI | CMD_DMA))) {
-            esp_do_dma(s);
-        }
-        return;
     }
 
     if (s->ti_cmd == 0) {
@@ -826,7 +816,7 @@ void esp_transfer_data(SCSIRequest *req, uint32_t len)
         return;
     }
 
-    if (s->ti_cmd & CMD_DMA) {
+    if (s->ti_cmd == (CMD_TI | CMD_DMA)) {
         if (dmalen) {
             esp_do_dma(s);
         } else if (s->ti_size <= 0) {
@@ -837,7 +827,7 @@ void esp_transfer_data(SCSIRequest *req, uint32_t len)
             esp_dma_done(s);
             esp_lower_drq(s);
         }
-    } else {
+    } else if (s->ti_cmd == CMD_TI) {
         esp_do_nodma(s);
     }
 }
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 09/45] esp: handle non-DMA transfers from the target one byte at a time
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (7 preceding siblings ...)
  2021-06-17  9:30 ` [PULL 08/45] esp: allow non-DMA callback in esp_transfer_data() initial transfer Paolo Bonzini
@ 2021-06-17  9:30 ` Paolo Bonzini
  2021-06-17  9:30 ` [PULL 10/45] esp: ensure PDMA write transfers are flushed from the FIFO to the target immediately Paolo Bonzini
                   ` (37 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: Mark Cave-Ayland

From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

The initial implementation of non-DMA transfers was based upon analysis of traces
from the MacOS toolbox ROM for handling unaligned reads but missed one key
aspect - during a non-DMA transfer from the target, the bus service interrupt
should be raised for every single byte received from the bus and not just at either
the end of the transfer or when the FIFO is full.

Adjust the non-DMA code accordingly so that esp_do_nodma() is called for every byte
received from the target. This also includes special handling for managing the change
from DATA IN to STATUS phase as this needs to occur when the final byte is read out
from the FIFO, and not at the end of the transfer of the last byte into the FIFO.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Message-Id: <20210519100803.10293-3-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi/esp.c | 72 +++++++++++++++++++++++++++++++++++----------------
 1 file changed, 50 insertions(+), 22 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 50757e9264..a0dab319f2 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -739,20 +739,17 @@ static void esp_do_nodma(ESPState *s)
         s->async_len -= len;
         s->ti_size += len;
     } else {
-        len = MIN(s->ti_size, s->async_len);
-        len = MIN(len, fifo8_num_free(&s->fifo));
-        fifo8_push_all(&s->fifo, s->async_buf, len);
-        s->async_buf += len;
-        s->async_len -= len;
-        s->ti_size -= len;
+        if (fifo8_is_empty(&s->fifo)) {
+            fifo8_push(&s->fifo, s->async_buf[0]);
+            s->async_buf++;
+            s->async_len--;
+            s->ti_size--;
+        }
     }
 
     if (s->async_len == 0) {
         scsi_req_continue(s->current_req);
-
-        if (to_device || s->ti_size == 0) {
-            return;
-        }
+        return;
     }
 
     s->rregs[ESP_RINTR] |= INTR_BS;
@@ -762,20 +759,37 @@ static void esp_do_nodma(ESPState *s)
 void esp_command_complete(SCSIRequest *req, size_t resid)
 {
     ESPState *s = req->hba_private;
+    int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO);
 
     trace_esp_command_complete();
-    if (s->ti_size != 0) {
-        trace_esp_command_complete_unexpected();
+
+    /*
+     * Non-DMA transfers from the target will leave the last byte in
+     * the FIFO so don't reset ti_size in this case
+     */
+    if (s->dma || to_device) {
+        if (s->ti_size != 0) {
+            trace_esp_command_complete_unexpected();
+        }
+        s->ti_size = 0;
     }
-    s->ti_size = 0;
+
     s->async_len = 0;
     if (req->status) {
         trace_esp_command_complete_fail();
     }
     s->status = req->status;
-    s->rregs[ESP_RSTAT] = STAT_ST;
-    esp_dma_done(s);
-    esp_lower_drq(s);
+
+    /*
+     * If the transfer is finished, switch to status phase. For non-DMA
+     * transfers from the target the last byte is still in the FIFO
+     */
+    if (s->ti_size == 0) {
+        s->rregs[ESP_RSTAT] = STAT_TC | STAT_ST;
+        esp_dma_done(s);
+        esp_lower_drq(s);
+    }
+
     if (s->current_req) {
         scsi_req_unref(s->current_req);
         s->current_req = NULL;
@@ -894,6 +908,17 @@ uint64_t esp_reg_read(ESPState *s, uint32_t saddr)
             qemu_log_mask(LOG_UNIMP, "esp: PIO data read not implemented\n");
             s->rregs[ESP_FIFO] = 0;
         } else {
+            if ((s->rregs[ESP_RSTAT] & 0x7) == STAT_DI) {
+                if (s->ti_size) {
+                    esp_do_nodma(s);
+                } else {
+                    /*
+                     * The last byte of a non-DMA transfer has been read out
+                     * of the FIFO so switch to status phase
+                     */
+                    s->rregs[ESP_RSTAT] = STAT_TC | STAT_ST;
+                }
+            }
             s->rregs[ESP_FIFO] = esp_fifo_pop(&s->fifo);
         }
         val = s->rregs[ESP_FIFO];
@@ -952,15 +977,18 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
     case ESP_FIFO:
         if (s->do_cmd) {
             esp_fifo_push(&s->cmdfifo, val);
+
+            /*
+             * If any unexpected message out/command phase data is
+             * transferred using non-DMA, raise the interrupt
+             */
+            if (s->rregs[ESP_CMD] == CMD_TI) {
+                s->rregs[ESP_RINTR] |= INTR_BS;
+                esp_raise_irq(s);
+            }
         } else {
             esp_fifo_push(&s->fifo, val);
         }
-
-        /* Non-DMA transfers raise an interrupt after every byte */
-        if (s->rregs[ESP_CMD] == CMD_TI) {
-            s->rregs[ESP_RINTR] |= INTR_FC | INTR_BS;
-            esp_raise_irq(s);
-        }
         break;
     case ESP_CMD:
         s->rregs[saddr] = val;
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 10/45] esp: ensure PDMA write transfers are flushed from the FIFO to the target immediately
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (8 preceding siblings ...)
  2021-06-17  9:30 ` [PULL 09/45] esp: handle non-DMA transfers from the target one byte at a time Paolo Bonzini
@ 2021-06-17  9:30 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 11/45] esp: revert 75ef849696 "esp: correctly fill bus id with requested lun" Paolo Bonzini
                   ` (36 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: Mark Cave-Ayland

From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

After each PDMA write transfer the MacOS CDROM driver waits until the FIFO is empty
(i.e. its contents have been written out to the SCSI bus) by polling the FIFO count
register until it reads 0. This doesn't work with the current PDMA write
implementation which waits until either the FIFO is full or the transfer is complete
before invoking the PDMA callback to process the FIFO contents.

Change the PDMA write transfer logic so that the PDMA callback is invoked after each
PDMA write to transfer the FIFO contents to the target buffer immediately, and hence
avoid getting stuck in the FIFO count register polling loop.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Message-Id: <20210519100803.10293-4-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi/esp.c | 25 +++++++++++--------------
 1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index a0dab319f2..8e314ef156 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -338,9 +338,9 @@ static void do_cmd(ESPState *s)
 
 static void satn_pdma_cb(ESPState *s)
 {
-    s->do_cmd = 0;
-    if (!fifo8_is_empty(&s->cmdfifo)) {
+    if (!esp_get_tc(s) && !fifo8_is_empty(&s->cmdfifo)) {
         s->cmdfifo_cdb_offset = 1;
+        s->do_cmd = 0;
         do_cmd(s);
     }
 }
@@ -369,12 +369,9 @@ static void handle_satn(ESPState *s)
 
 static void s_without_satn_pdma_cb(ESPState *s)
 {
-    uint32_t len;
-
-    s->do_cmd = 0;
-    len = fifo8_num_used(&s->cmdfifo);
-    if (len) {
+    if (!esp_get_tc(s) && !fifo8_is_empty(&s->cmdfifo)) {
         s->cmdfifo_cdb_offset = 0;
+        s->do_cmd = 0;
         do_busid_cmd(s, 0);
     }
 }
@@ -403,8 +400,7 @@ static void handle_s_without_atn(ESPState *s)
 
 static void satn_stop_pdma_cb(ESPState *s)
 {
-    s->do_cmd = 0;
-    if (!fifo8_is_empty(&s->cmdfifo)) {
+    if (!esp_get_tc(s) && !fifo8_is_empty(&s->cmdfifo)) {
         trace_esp_handle_satn_stop(fifo8_num_used(&s->cmdfifo));
         s->do_cmd = 1;
         s->cmdfifo_cdb_offset = 1;
@@ -493,6 +489,11 @@ static void do_dma_pdma_cb(ESPState *s)
     uint32_t n;
 
     if (s->do_cmd) {
+        /* Ensure we have received complete command after SATN and stop */
+        if (esp_get_tc(s) || fifo8_is_empty(&s->cmdfifo)) {
+            return;
+        }
+
         s->ti_size = 0;
         s->do_cmd = 0;
         do_cmd(s);
@@ -1220,7 +1221,6 @@ static void sysbus_esp_pdma_write(void *opaque, hwaddr addr,
 {
     SysBusESPState *sysbus = opaque;
     ESPState *s = ESP(&sysbus->esp);
-    uint32_t dmalen;
 
     trace_esp_pdma_write(size);
 
@@ -1233,10 +1233,7 @@ static void sysbus_esp_pdma_write(void *opaque, hwaddr addr,
         esp_pdma_write(s, val);
         break;
     }
-    dmalen = esp_get_tc(s);
-    if (dmalen == 0 || fifo8_num_free(&s->fifo) < 2) {
-        s->pdma_cb(s);
-    }
+    s->pdma_cb(s);
 }
 
 static uint64_t sysbus_esp_pdma_read(void *opaque, hwaddr addr,
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 11/45] esp: revert 75ef849696 "esp: correctly fill bus id with requested lun"
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (9 preceding siblings ...)
  2021-06-17  9:30 ` [PULL 10/45] esp: ensure PDMA write transfers are flushed from the FIFO to the target immediately Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 12/45] esp: correctly accumulate extended messages for PDMA Paolo Bonzini
                   ` (35 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Mark Cave-Ayland

From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

This commit from nearly 10 years ago is now broken due to the improvements
in esp emulation (or perhaps was never correct).  It shows up as a bug
in detecting the CDROM drive under MacOS. The error is caused by the
MacOS CDROM driver sending this CDB with an "S without ATN" command and
without DMA:

    0x12 0x00 0x00 0x00 0x05 0x00 (INQUIRY)

This is a valid INQUIRY command, however with this logic present the 3rd
byte (0x0) is copied over the 1st byte (0x12) which silently converts the
INQUIRY command to a TEST UNIT READY command before passing it to the
QEMU SCSI layer.  Since the TEST UNIT READY command has a zero length
response the MacOS CDROM driver never receives a response and assumes
the CDROM is not present.

The logic was to ignore the IDENTIFY byte and copy the LUN over from
the CDB, which did store the LUN in bits 5-7 of the second byte in
olden times.  This however is all obsolete, so just drop the code.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Message-Id: <20210519100803.10293-5-mark.cave-ayland@ilande.co.uk>
[Tweaked commit message. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi/esp.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 8e314ef156..16e4b7ead6 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -260,9 +260,6 @@ static uint32_t get_cmd(ESPState *s, uint32_t maxlen)
             return 0;
         }
         n = esp_fifo_pop_buf(&s->fifo, buf, dmalen);
-        if (n >= 3) {
-            buf[0] = buf[2] >> 5;
-        }
         n = MIN(fifo8_num_free(&s->cmdfifo), n);
         fifo8_push_all(&s->cmdfifo, buf, n);
     }
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 12/45] esp: correctly accumulate extended messages for PDMA
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (10 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 11/45] esp: revert 75ef849696 "esp: correctly fill bus id with requested lun" Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 13/45] esp: fix migration version check in esp_is_version_5() Paolo Bonzini
                   ` (34 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Mark Cave-Ayland

From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

Commit 799d90d818 "esp: transition to message out phase after SATN and stop
command" added logic to correctly handle extended messages for DMA requests
but not for PDMA requests.

Apply the same logic in esp_do_dma() to do_dma_pdma_cb() so that extended
messages terminated with a PDMA request are accumulated correctly. This allows
the ESP device to respond correctly to the SDTR negotiation initiated by the
NetBSD ESP driver without causing errors and timeouts on boot.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Message-Id: <20210519100803.10293-6-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi/esp.c | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 16e4b7ead6..3e6f4094fc 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -492,9 +492,26 @@ static void do_dma_pdma_cb(ESPState *s)
         }
 
         s->ti_size = 0;
-        s->do_cmd = 0;
-        do_cmd(s);
-        esp_lower_drq(s);
+        if ((s->rregs[ESP_RSTAT] & 7) == STAT_CD) {
+            /* No command received */
+            if (s->cmdfifo_cdb_offset == fifo8_num_used(&s->cmdfifo)) {
+                return;
+            }
+
+            /* Command has been received */
+            s->do_cmd = 0;
+            do_cmd(s);
+        } else {
+            /*
+             * Extra message out bytes received: update cmdfifo_cdb_offset
+             * and then switch to commmand phase
+             */
+            s->cmdfifo_cdb_offset = fifo8_num_used(&s->cmdfifo);
+            s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD;
+            s->rregs[ESP_RSEQ] = SEQ_CD;
+            s->rregs[ESP_RINTR] |= INTR_BS;
+            esp_raise_irq(s);
+        }
         return;
     }
 
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 13/45] esp: fix migration version check in esp_is_version_5()
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (11 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 12/45] esp: correctly accumulate extended messages for PDMA Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 14/45] esp: store lun coming from the MESSAGE OUT phase Paolo Bonzini
                   ` (33 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Mark Cave-Ayland

From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

Commit 4e78f3bf35 "esp: defer command completion interrupt on incoming data
transfers" added a version check for use with VMSTATE_*_TEST macros to allow
migration from older QEMU versions. Unfortunately the version check fails to
work in its current form since if the VMStateDescription version_id is
incremented, the test returns false and so the fields are not included in the
outgoing migration stream.

Change the version check to use >= rather == to ensure that migration works
correctly when the ESPState VMStateDescription has version_id > 5.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Fixes: 4e78f3bf35 ("esp: defer command completion interrupt on incoming data transfers")
Message-Id: <20210613102614.5438-1-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi/esp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 3e6f4094fc..8fad87be9d 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -1128,7 +1128,7 @@ static bool esp_is_version_5(void *opaque, int version_id)
     ESPState *s = ESP(opaque);
 
     version_id = MIN(version_id, s->mig_version_id);
-    return version_id == 5;
+    return version_id >= 5;
 }
 
 int esp_pre_save(void *opaque)
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 14/45] esp: store lun coming from the MESSAGE OUT phase
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (12 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 13/45] esp: fix migration version check in esp_is_version_5() Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 15/45] softmmu/physmem: Mark shared anonymous memory RAM_SHARED Paolo Bonzini
                   ` (32 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Mark Cave-Ayland

The LUN is selected with an IDENTIFY message, and persists
until the next message out phase.  Instead of passing it to
do_busid_cmd, store it in ESPState.  Because do_cmd can simply
skip the message out phase if cmdfifo_cdb_offset is zero, it
can now be used for the S without ATN cases as well.

Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi/esp.c         | 47 ++++++++++++++++++++++++++++---------------
 hw/scsi/trace-events  |  3 ++-
 include/hw/scsi/esp.h |  1 +
 3 files changed, 34 insertions(+), 17 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 8fad87be9d..4ac2114788 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -221,7 +221,7 @@ static int esp_select(ESPState *s)
 
     /*
      * Note that we deliberately don't raise the IRQ here: this will be done
-     * either in do_busid_cmd() for DATA OUT transfers or by the deferred
+     * either in do_command_phase() for DATA OUT transfers or by the deferred
      * IRQ mechanism in esp_transfer_data() for DATA IN transfers
      */
     s->rregs[ESP_RINTR] |= INTR_FC;
@@ -272,24 +272,22 @@ static uint32_t get_cmd(ESPState *s, uint32_t maxlen)
     return dmalen;
 }
 
-static void do_busid_cmd(ESPState *s, uint8_t busid)
+static void do_command_phase(ESPState *s)
 {
     uint32_t cmdlen;
     int32_t datalen;
-    int lun;
     SCSIDevice *current_lun;
     uint8_t buf[ESP_CMDFIFO_SZ];
 
-    trace_esp_do_busid_cmd(busid);
-    lun = busid & 7;
+    trace_esp_do_command_phase(s->lun);
     cmdlen = fifo8_num_used(&s->cmdfifo);
     if (!cmdlen || !s->current_dev) {
         return;
     }
     esp_fifo_pop_buf(&s->cmdfifo, buf, cmdlen);
 
-    current_lun = scsi_device_find(&s->bus, 0, s->current_dev->id, lun);
-    s->current_req = scsi_req_new(current_lun, 0, lun, buf, s);
+    current_lun = scsi_device_find(&s->bus, 0, s->current_dev->id, s->lun);
+    s->current_req = scsi_req_new(current_lun, 0, s->lun, buf, s);
     datalen = scsi_req_enqueue(s->current_req);
     s->ti_size = datalen;
     fifo8_reset(&s->cmdfifo);
@@ -316,21 +314,29 @@ static void do_busid_cmd(ESPState *s, uint8_t busid)
     }
 }
 
-static void do_cmd(ESPState *s)
+static void do_message_phase(ESPState *s)
 {
-    uint8_t busid = esp_fifo_pop(&s->cmdfifo);
-    int len;
+    if (s->cmdfifo_cdb_offset) {
+        uint8_t message = esp_fifo_pop(&s->cmdfifo);
 
-    s->cmdfifo_cdb_offset--;
+        trace_esp_do_identify(message);
+        s->lun = message & 7;
+        s->cmdfifo_cdb_offset--;
+    }
 
     /* Ignore extended messages for now */
     if (s->cmdfifo_cdb_offset) {
-        len = MIN(s->cmdfifo_cdb_offset, fifo8_num_used(&s->cmdfifo));
+        int len = MIN(s->cmdfifo_cdb_offset, fifo8_num_used(&s->cmdfifo));
         esp_fifo_pop_buf(&s->cmdfifo, NULL, len);
         s->cmdfifo_cdb_offset = 0;
     }
+}
 
-    do_busid_cmd(s, busid);
+static void do_cmd(ESPState *s)
+{
+    do_message_phase(s);
+    assert(s->cmdfifo_cdb_offset == 0);
+    do_command_phase(s);
 }
 
 static void satn_pdma_cb(ESPState *s)
@@ -369,7 +375,7 @@ static void s_without_satn_pdma_cb(ESPState *s)
     if (!esp_get_tc(s) && !fifo8_is_empty(&s->cmdfifo)) {
         s->cmdfifo_cdb_offset = 0;
         s->do_cmd = 0;
-        do_busid_cmd(s, 0);
+        do_cmd(s);
     }
 }
 
@@ -386,7 +392,7 @@ static void handle_s_without_atn(ESPState *s)
     if (cmdlen > 0) {
         s->cmdfifo_cdb_offset = 0;
         s->do_cmd = 0;
-        do_busid_cmd(s, 0);
+        do_cmd(s);
     } else if (cmdlen == 0) {
         s->do_cmd = 1;
         /* Target present, but no cmd yet - switch to command phase */
@@ -1131,6 +1137,14 @@ static bool esp_is_version_5(void *opaque, int version_id)
     return version_id >= 5;
 }
 
+static bool esp_is_version_6(void *opaque, int version_id)
+{
+    ESPState *s = ESP(opaque);
+
+    version_id = MIN(version_id, s->mig_version_id);
+    return version_id >= 6;
+}
+
 int esp_pre_save(void *opaque)
 {
     ESPState *s = ESP(object_resolve_path_component(
@@ -1168,7 +1182,7 @@ static int esp_post_load(void *opaque, int version_id)
 
 const VMStateDescription vmstate_esp = {
     .name = "esp",
-    .version_id = 5,
+    .version_id = 6,
     .minimum_version_id = 3,
     .post_load = esp_post_load,
     .fields = (VMStateField[]) {
@@ -1197,6 +1211,7 @@ const VMStateDescription vmstate_esp = {
         VMSTATE_FIFO8_TEST(fifo, ESPState, esp_is_version_5),
         VMSTATE_FIFO8_TEST(cmdfifo, ESPState, esp_is_version_5),
         VMSTATE_UINT8_TEST(ti_cmd, ESPState, esp_is_version_5),
+        VMSTATE_UINT8_TEST(lun, ESPState, esp_is_version_6),
         VMSTATE_END_OF_LIST()
     },
 };
diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events
index 1a27e141ae..92d5b40f89 100644
--- a/hw/scsi/trace-events
+++ b/hw/scsi/trace-events
@@ -166,7 +166,8 @@ esp_dma_disable(void) "Lower enable"
 esp_pdma_read(int size) "pDMA read %u bytes"
 esp_pdma_write(int size) "pDMA write %u bytes"
 esp_get_cmd(uint32_t dmalen, int target) "len %d target %d"
-esp_do_busid_cmd(uint8_t busid) "busid 0x%x"
+esp_do_command_phase(uint8_t busid) "busid 0x%x"
+esp_do_identify(uint8_t byte) "0x%x"
 esp_handle_satn_stop(uint32_t cmdlen) "cmdlen %d"
 esp_write_response(uint32_t status) "Transfer status (status=%d)"
 esp_do_dma(uint32_t cmdlen, uint32_t len) "command len %d + %d"
diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h
index aada3680b7..b1ec27612f 100644
--- a/include/hw/scsi/esp.h
+++ b/include/hw/scsi/esp.h
@@ -37,6 +37,7 @@ struct ESPState {
     SCSIRequest *current_req;
     Fifo8 cmdfifo;
     uint8_t cmdfifo_cdb_offset;
+    uint8_t lun;
     uint32_t do_cmd;
 
     bool data_in_ready;
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 15/45] softmmu/physmem: Mark shared anonymous memory RAM_SHARED
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (13 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 14/45] esp: store lun coming from the MESSAGE OUT phase Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 16/45] softmmu/physmem: Fix ram_block_discard_range() to handle shared anonymous memory Paolo Bonzini
                   ` (31 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Igor Kotrasinski, Richard Henderson, Peter Xu, David Hildenbrand

From: David Hildenbrand <david@redhat.com>

Let's drop the "shared" parameter from ram_block_add() and properly
store it in the flags of the ram block instead, such that
qemu_ram_is_shared() properly succeeds on all ram blocks that were mapped
MAP_SHARED.

We'll use this information next to fix some cases with shared anonymous
memory.

Reviewed-by: Igor Kotrasinski <i.kotrasinsk@partner.samsung.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20210406080126.24010-2-david@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 softmmu/physmem.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index 1c8717684a..b78b30e7ba 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -1946,8 +1946,9 @@ static void dirty_memory_extend(ram_addr_t old_ram_size,
     }
 }
 
-static void ram_block_add(RAMBlock *new_block, Error **errp, bool shared)
+static void ram_block_add(RAMBlock *new_block, Error **errp)
 {
+    const bool shared = qemu_ram_is_shared(new_block);
     RAMBlock *block;
     RAMBlock *last_block = NULL;
     ram_addr_t old_ram_size, new_ram_size;
@@ -2084,7 +2085,7 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
         return NULL;
     }
 
-    ram_block_add(new_block, &local_err, ram_flags & RAM_SHARED);
+    ram_block_add(new_block, &local_err);
     if (local_err) {
         g_free(new_block);
         error_propagate(errp, local_err);
@@ -2147,10 +2148,13 @@ RAMBlock *qemu_ram_alloc_internal(ram_addr_t size, ram_addr_t max_size,
     if (host) {
         new_block->flags |= RAM_PREALLOC;
     }
+    if (share) {
+        new_block->flags |= RAM_SHARED;
+    }
     if (resizeable) {
         new_block->flags |= RAM_RESIZEABLE;
     }
-    ram_block_add(new_block, &local_err, share);
+    ram_block_add(new_block, &local_err);
     if (local_err) {
         g_free(new_block);
         error_propagate(errp, local_err);
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 16/45] softmmu/physmem: Fix ram_block_discard_range() to handle shared anonymous memory
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (14 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 15/45] softmmu/physmem: Mark shared anonymous memory RAM_SHARED Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 17/45] softmmu/physmem: Fix qemu_ram_remap() " Paolo Bonzini
                   ` (30 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Dr . David Alan Gilbert, Peter Xu, David Hildenbrand

From: David Hildenbrand <david@redhat.com>

We can create shared anonymous memory via
    "-object memory-backend-ram,share=on,..."
which is, for example, required by PVRDMA for mremap() to work.

Shared anonymous memory is weird, though. Instead of MADV_DONTNEED, we
have to use MADV_REMOVE: MADV_DONTNEED will only remove / zap all
relevant page table entries of the current process, the backend storage
will not get removed, resulting in no reduced memory consumption and
a repopulation of previous content on next access.

Shared anonymous memory is internally really just shmem, but without a
fd exposed. As we cannot use fallocate() without the fd to discard the
backing storage, MADV_REMOVE gets the same job done without a fd as
documented in "man 2 madvise". Removing backing storage implicitly
invalidates all page table entries with relevant mappings - an additional
MADV_DONTNEED is not required.

Fixes: 06329ccecfa0 ("mem: add share parameter to memory-backend-ram")
Reviewed-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20210406080126.24010-3-david@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/osdep.h | 4 ++--
 softmmu/physmem.c    | 7 ++++++-
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 236a045671..18a9e3fb4c 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -410,7 +410,7 @@ void qemu_anon_ram_free(void *ptr, size_t size);
 #ifdef MADV_REMOVE
 #define QEMU_MADV_REMOVE MADV_REMOVE
 #else
-#define QEMU_MADV_REMOVE QEMU_MADV_INVALID
+#define QEMU_MADV_REMOVE QEMU_MADV_DONTNEED
 #endif
 
 #elif defined(CONFIG_POSIX_MADVISE)
@@ -424,7 +424,7 @@ void qemu_anon_ram_free(void *ptr, size_t size);
 #define QEMU_MADV_DONTDUMP QEMU_MADV_INVALID
 #define QEMU_MADV_HUGEPAGE  QEMU_MADV_INVALID
 #define QEMU_MADV_NOHUGEPAGE  QEMU_MADV_INVALID
-#define QEMU_MADV_REMOVE QEMU_MADV_INVALID
+#define QEMU_MADV_REMOVE QEMU_MADV_DONTNEED
 
 #else /* no-op */
 
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index b78b30e7ba..c0a3c47167 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -3527,6 +3527,7 @@ int ram_block_discard_range(RAMBlock *rb, uint64_t start, size_t length)
         /* The logic here is messy;
          *    madvise DONTNEED fails for hugepages
          *    fallocate works on hugepages and shmem
+         *    shared anonymous memory requires madvise REMOVE
          */
         need_madvise = (rb->page_size == qemu_host_page_size);
         need_fallocate = rb->fd != -1;
@@ -3560,7 +3561,11 @@ int ram_block_discard_range(RAMBlock *rb, uint64_t start, size_t length)
              * fallocate'd away).
              */
 #if defined(CONFIG_MADVISE)
-            ret =  madvise(host_startaddr, length, MADV_DONTNEED);
+            if (qemu_ram_is_shared(rb) && rb->fd < 0) {
+                ret = madvise(host_startaddr, length, QEMU_MADV_REMOVE);
+            } else {
+                ret = madvise(host_startaddr, length, QEMU_MADV_DONTNEED);
+            }
             if (ret) {
                 ret = -errno;
                 error_report("ram_block_discard_range: Failed to discard range "
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 17/45] softmmu/physmem: Fix qemu_ram_remap() to handle shared anonymous memory
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (15 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 16/45] softmmu/physmem: Fix ram_block_discard_range() to handle shared anonymous memory Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 18/45] util/mmap-alloc: Factor out calculation of the pagesize for the guard page Paolo Bonzini
                   ` (29 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Xu, David Hildenbrand

From: David Hildenbrand <david@redhat.com>

RAM_SHARED now also properly indicates shared anonymous memory. Let's check
that flag for anonymous memory as well, to restore the proper mapping.

Fixes: 06329ccecfa0 ("mem: add share parameter to memory-backend-ram")
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20210406080126.24010-4-david@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 softmmu/physmem.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index c0a3c47167..b75d205e8a 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -2243,13 +2243,13 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
                 abort();
             } else {
                 flags = MAP_FIXED;
+                flags |= block->flags & RAM_SHARED ?
+                         MAP_SHARED : MAP_PRIVATE;
                 if (block->fd >= 0) {
-                    flags |= (block->flags & RAM_SHARED ?
-                              MAP_SHARED : MAP_PRIVATE);
                     area = mmap(vaddr, length, PROT_READ | PROT_WRITE,
                                 flags, block->fd, offset);
                 } else {
-                    flags |= MAP_PRIVATE | MAP_ANONYMOUS;
+                    flags |= MAP_ANONYMOUS;
                     area = mmap(vaddr, length, PROT_READ | PROT_WRITE,
                                 flags, -1, 0);
                 }
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 18/45] util/mmap-alloc: Factor out calculation of the pagesize for the guard page
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (16 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 17/45] softmmu/physmem: Fix qemu_ram_remap() " Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 19/45] util/mmap-alloc: Factor out reserving of a memory region to mmap_reserve() Paolo Bonzini
                   ` (28 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Igor Kotrasinski, Murilo Opsfelder Araujo, Eduardo Habkost,
	Peter Xu, David Hildenbrand

From: David Hildenbrand <david@redhat.com>

Let's factor out calculating the size of the guard page and rename the
variable to make it clearer that this pagesize only applies to the
guard page.

Reviewed-by: Peter Xu <peterx@redhat.com>
Acked-by: Murilo Opsfelder Araujo <muriloo@linux.ibm.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com> for memory backend and machine core
Cc: Igor Kotrasinski <i.kotrasinsk@partner.samsung.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20210510114328.21835-2-david@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 util/mmap-alloc.c | 31 ++++++++++++++++---------------
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c
index e6fa8b598b..24854064b4 100644
--- a/util/mmap-alloc.c
+++ b/util/mmap-alloc.c
@@ -82,6 +82,16 @@ size_t qemu_mempath_getpagesize(const char *mem_path)
     return qemu_real_host_page_size;
 }
 
+static inline size_t mmap_guard_pagesize(int fd)
+{
+#if defined(__powerpc64__) && defined(__linux__)
+    /* Mappings in the same segment must share the same page size */
+    return qemu_fd_getpagesize(fd);
+#else
+    return qemu_real_host_page_size;
+#endif
+}
+
 void *qemu_ram_mmap(int fd,
                     size_t size,
                     size_t align,
@@ -90,12 +100,12 @@ void *qemu_ram_mmap(int fd,
                     bool is_pmem,
                     off_t map_offset)
 {
+    const size_t guard_pagesize = mmap_guard_pagesize(fd);
     int prot;
     int flags;
     int map_sync_flags = 0;
     int guardfd;
     size_t offset;
-    size_t pagesize;
     size_t total;
     void *guardptr;
     void *ptr;
@@ -116,8 +126,7 @@ void *qemu_ram_mmap(int fd,
      * anonymous memory is OK.
      */
     flags = MAP_PRIVATE;
-    pagesize = qemu_fd_getpagesize(fd);
-    if (fd == -1 || pagesize == qemu_real_host_page_size) {
+    if (fd == -1 || guard_pagesize == qemu_real_host_page_size) {
         guardfd = -1;
         flags |= MAP_ANONYMOUS;
     } else {
@@ -126,7 +135,6 @@ void *qemu_ram_mmap(int fd,
     }
 #else
     guardfd = -1;
-    pagesize = qemu_real_host_page_size;
     flags = MAP_PRIVATE | MAP_ANONYMOUS;
 #endif
 
@@ -138,7 +146,7 @@ void *qemu_ram_mmap(int fd,
 
     assert(is_power_of_2(align));
     /* Always align to host page size */
-    assert(align >= pagesize);
+    assert(align >= guard_pagesize);
 
     flags = MAP_FIXED;
     flags |= fd == -1 ? MAP_ANONYMOUS : 0;
@@ -193,8 +201,8 @@ void *qemu_ram_mmap(int fd,
      * a guard page guarding against potential buffer overflows.
      */
     total -= offset;
-    if (total > size + pagesize) {
-        munmap(ptr + size + pagesize, total - size - pagesize);
+    if (total > size + guard_pagesize) {
+        munmap(ptr + size + guard_pagesize, total - size - guard_pagesize);
     }
 
     return ptr;
@@ -202,15 +210,8 @@ void *qemu_ram_mmap(int fd,
 
 void qemu_ram_munmap(int fd, void *ptr, size_t size)
 {
-    size_t pagesize;
-
     if (ptr) {
         /* Unmap both the RAM block and the guard page */
-#if defined(__powerpc64__) && defined(__linux__)
-        pagesize = qemu_fd_getpagesize(fd);
-#else
-        pagesize = qemu_real_host_page_size;
-#endif
-        munmap(ptr, size + pagesize);
+        munmap(ptr, size + mmap_guard_pagesize(fd));
     }
 }
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 19/45] util/mmap-alloc: Factor out reserving of a memory region to mmap_reserve()
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (17 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 18/45] util/mmap-alloc: Factor out calculation of the pagesize for the guard page Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 20/45] util/mmap-alloc: Factor out activating of memory to mmap_activate() Paolo Bonzini
                   ` (27 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eduardo Habkost, David Hildenbrand, Igor Kotrasinski,
	Richard Henderson, Peter Xu, Murilo Opsfelder Araujo

From: David Hildenbrand <david@redhat.com>

We want to reserve a memory region without actually populating memory.
Let's factor that out.

Reviewed-by: Igor Kotrasinski <i.kotrasinsk@partner.samsung.com>
Acked-by: Murilo Opsfelder Araujo <muriloo@linux.ibm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Peter Xu <peterx@redhat.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com> for memory backend and machine core
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20210510114328.21835-3-david@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 util/mmap-alloc.c | 58 +++++++++++++++++++++++++++--------------------
 1 file changed, 33 insertions(+), 25 deletions(-)

diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c
index 24854064b4..223d66219c 100644
--- a/util/mmap-alloc.c
+++ b/util/mmap-alloc.c
@@ -82,6 +82,38 @@ size_t qemu_mempath_getpagesize(const char *mem_path)
     return qemu_real_host_page_size;
 }
 
+/*
+ * Reserve a new memory region of the requested size to be used for mapping
+ * from the given fd (if any).
+ */
+static void *mmap_reserve(size_t size, int fd)
+{
+    int flags = MAP_PRIVATE;
+
+#if defined(__powerpc64__) && defined(__linux__)
+    /*
+     * On ppc64 mappings in the same segment (aka slice) must share the same
+     * page size. Since we will be re-allocating part of this segment
+     * from the supplied fd, we should make sure to use the same page size, to
+     * this end we mmap the supplied fd.  In this case, set MAP_NORESERVE to
+     * avoid allocating backing store memory.
+     * We do this unless we are using the system page size, in which case
+     * anonymous memory is OK.
+     */
+    if (fd == -1 || qemu_fd_getpagesize(fd) == qemu_real_host_page_size) {
+        fd = -1;
+        flags |= MAP_ANONYMOUS;
+    } else {
+        flags |= MAP_NORESERVE;
+    }
+#else
+    fd = -1;
+    flags |= MAP_ANONYMOUS;
+#endif
+
+    return mmap(0, size, PROT_NONE, flags, fd, 0);
+}
+
 static inline size_t mmap_guard_pagesize(int fd)
 {
 #if defined(__powerpc64__) && defined(__linux__)
@@ -104,7 +136,6 @@ void *qemu_ram_mmap(int fd,
     int prot;
     int flags;
     int map_sync_flags = 0;
-    int guardfd;
     size_t offset;
     size_t total;
     void *guardptr;
@@ -116,30 +147,7 @@ void *qemu_ram_mmap(int fd,
      */
     total = size + align;
 
-#if defined(__powerpc64__) && defined(__linux__)
-    /* On ppc64 mappings in the same segment (aka slice) must share the same
-     * page size. Since we will be re-allocating part of this segment
-     * from the supplied fd, we should make sure to use the same page size, to
-     * this end we mmap the supplied fd.  In this case, set MAP_NORESERVE to
-     * avoid allocating backing store memory.
-     * We do this unless we are using the system page size, in which case
-     * anonymous memory is OK.
-     */
-    flags = MAP_PRIVATE;
-    if (fd == -1 || guard_pagesize == qemu_real_host_page_size) {
-        guardfd = -1;
-        flags |= MAP_ANONYMOUS;
-    } else {
-        guardfd = fd;
-        flags |= MAP_NORESERVE;
-    }
-#else
-    guardfd = -1;
-    flags = MAP_PRIVATE | MAP_ANONYMOUS;
-#endif
-
-    guardptr = mmap(0, total, PROT_NONE, flags, guardfd, 0);
-
+    guardptr = mmap_reserve(total, fd);
     if (guardptr == MAP_FAILED) {
         return MAP_FAILED;
     }
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 20/45] util/mmap-alloc: Factor out activating of memory to mmap_activate()
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (18 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 19/45] util/mmap-alloc: Factor out reserving of a memory region to mmap_reserve() Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 21/45] softmmu/memory: Pass ram_flags to qemu_ram_alloc_from_fd() Paolo Bonzini
                   ` (26 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Murilo Opsfelder Araujo, Richard Henderson, Eduardo Habkost,
	Peter Xu, David Hildenbrand

From: David Hildenbrand <david@redhat.com>

We want to activate memory within a reserved memory region, to make it
accessible. Let's factor that out.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Acked-by: Murilo Opsfelder Araujo <muriloo@linux.ibm.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com> for memory backend and machine core
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20210510114328.21835-4-david@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 util/mmap-alloc.c | 94 +++++++++++++++++++++++++----------------------
 1 file changed, 50 insertions(+), 44 deletions(-)

diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c
index 223d66219c..0e2bd7bc0e 100644
--- a/util/mmap-alloc.c
+++ b/util/mmap-alloc.c
@@ -114,6 +114,52 @@ static void *mmap_reserve(size_t size, int fd)
     return mmap(0, size, PROT_NONE, flags, fd, 0);
 }
 
+/*
+ * Activate memory in a reserved region from the given fd (if any), to make
+ * it accessible.
+ */
+static void *mmap_activate(void *ptr, size_t size, int fd, bool readonly,
+                           bool shared, bool is_pmem, off_t map_offset)
+{
+    const int prot = PROT_READ | (readonly ? 0 : PROT_WRITE);
+    int map_sync_flags = 0;
+    int flags = MAP_FIXED;
+    void *activated_ptr;
+
+    flags |= fd == -1 ? MAP_ANONYMOUS : 0;
+    flags |= shared ? MAP_SHARED : MAP_PRIVATE;
+    if (shared && is_pmem) {
+        map_sync_flags = MAP_SYNC | MAP_SHARED_VALIDATE;
+    }
+
+    activated_ptr = mmap(ptr, size, prot, flags | map_sync_flags, fd,
+                         map_offset);
+    if (activated_ptr == MAP_FAILED && map_sync_flags) {
+        if (errno == ENOTSUP) {
+            char *proc_link = g_strdup_printf("/proc/self/fd/%d", fd);
+            char *file_name = g_malloc0(PATH_MAX);
+            int len = readlink(proc_link, file_name, PATH_MAX - 1);
+
+            if (len < 0) {
+                len = 0;
+            }
+            file_name[len] = '\0';
+            fprintf(stderr, "Warning: requesting persistence across crashes "
+                    "for backend file %s failed. Proceeding without "
+                    "persistence, data might become corrupted in case of host "
+                    "crash.\n", file_name);
+            g_free(proc_link);
+            g_free(file_name);
+        }
+        /*
+         * If mmap failed with MAP_SHARED_VALIDATE | MAP_SYNC, we will try
+         * again without these flags to handle backwards compatibility.
+         */
+        activated_ptr = mmap(ptr, size, prot, flags, fd, map_offset);
+    }
+    return activated_ptr;
+}
+
 static inline size_t mmap_guard_pagesize(int fd)
 {
 #if defined(__powerpc64__) && defined(__linux__)
@@ -133,13 +179,8 @@ void *qemu_ram_mmap(int fd,
                     off_t map_offset)
 {
     const size_t guard_pagesize = mmap_guard_pagesize(fd);
-    int prot;
-    int flags;
-    int map_sync_flags = 0;
-    size_t offset;
-    size_t total;
-    void *guardptr;
-    void *ptr;
+    size_t offset, total;
+    void *ptr, *guardptr;
 
     /*
      * Note: this always allocates at least one extra page of virtual address
@@ -156,45 +197,10 @@ void *qemu_ram_mmap(int fd,
     /* Always align to host page size */
     assert(align >= guard_pagesize);
 
-    flags = MAP_FIXED;
-    flags |= fd == -1 ? MAP_ANONYMOUS : 0;
-    flags |= shared ? MAP_SHARED : MAP_PRIVATE;
-    if (shared && is_pmem) {
-        map_sync_flags = MAP_SYNC | MAP_SHARED_VALIDATE;
-    }
-
     offset = QEMU_ALIGN_UP((uintptr_t)guardptr, align) - (uintptr_t)guardptr;
 
-    prot = PROT_READ | (readonly ? 0 : PROT_WRITE);
-
-    ptr = mmap(guardptr + offset, size, prot,
-               flags | map_sync_flags, fd, map_offset);
-
-    if (ptr == MAP_FAILED && map_sync_flags) {
-        if (errno == ENOTSUP) {
-            char *proc_link, *file_name;
-            int len;
-            proc_link = g_strdup_printf("/proc/self/fd/%d", fd);
-            file_name = g_malloc0(PATH_MAX);
-            len = readlink(proc_link, file_name, PATH_MAX - 1);
-            if (len < 0) {
-                len = 0;
-            }
-            file_name[len] = '\0';
-            fprintf(stderr, "Warning: requesting persistence across crashes "
-                    "for backend file %s failed. Proceeding without "
-                    "persistence, data might become corrupted in case of host "
-                    "crash.\n", file_name);
-            g_free(proc_link);
-            g_free(file_name);
-        }
-        /*
-         * if map failed with MAP_SHARED_VALIDATE | MAP_SYNC,
-         * we will remove these flags to handle compatibility.
-         */
-        ptr = mmap(guardptr + offset, size, prot, flags, fd, map_offset);
-    }
-
+    ptr = mmap_activate(guardptr + offset, size, fd, readonly, shared, is_pmem,
+                        map_offset);
     if (ptr == MAP_FAILED) {
         munmap(guardptr, total);
         return MAP_FAILED;
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 21/45] softmmu/memory: Pass ram_flags to qemu_ram_alloc_from_fd()
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (19 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 20/45] util/mmap-alloc: Factor out activating of memory to mmap_activate() Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 22/45] softmmu/memory: Pass ram_flags to memory_region_init_ram_shared_nomigrate() Paolo Bonzini
                   ` (25 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Philippe Mathieu-Daudé,
	Eduardo Habkost, Peter Xu, David Hildenbrand

From: David Hildenbrand <david@redhat.com>

Let's pass in ram flags just like we do with qemu_ram_alloc_from_file(),
to clean up and prepare for more flags.

Simplify the documentation of passed ram flags: Looking at our
documentation of RAM_SHARED and RAM_PMEM is sufficient, no need to be
repetitive.

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com> for memory backend and machine core
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20210510114328.21835-5-david@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 backends/hostmem-memfd.c | 7 ++++---
 hw/misc/ivshmem.c        | 5 ++---
 include/exec/memory.h    | 9 +++------
 include/exec/ram_addr.h  | 6 +-----
 softmmu/memory.c         | 7 +++----
 5 files changed, 13 insertions(+), 21 deletions(-)

diff --git a/backends/hostmem-memfd.c b/backends/hostmem-memfd.c
index da75e27057..3076da146d 100644
--- a/backends/hostmem-memfd.c
+++ b/backends/hostmem-memfd.c
@@ -35,6 +35,7 @@ static void
 memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
 {
     HostMemoryBackendMemfd *m = MEMORY_BACKEND_MEMFD(backend);
+    uint32_t ram_flags;
     char *name;
     int fd;
 
@@ -52,9 +53,9 @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
     }
 
     name = host_memory_backend_get_name(backend);
-    memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend),
-                                   name, backend->size,
-                                   backend->share, fd, 0, errp);
+    ram_flags = backend->share ? RAM_SHARED : 0;
+    memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend), name,
+                                   backend->size, ram_flags, fd, 0, errp);
     g_free(name);
 }
 
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index a1fa4878be..1ba4a98377 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -493,9 +493,8 @@ static void process_msg_shmem(IVShmemState *s, int fd, Error **errp)
     size = buf.st_size;
 
     /* mmap the region and map into the BAR2 */
-    memory_region_init_ram_from_fd(&s->server_bar2, OBJECT(s),
-                                   "ivshmem.bar2", size, true, fd, 0,
-                                   &local_err);
+    memory_region_init_ram_from_fd(&s->server_bar2, OBJECT(s), "ivshmem.bar2",
+                                   size, RAM_SHARED, fd, 0, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         return;
diff --git a/include/exec/memory.h b/include/exec/memory.h
index b114f5454b..8aa69a10d7 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -1005,10 +1005,7 @@ void memory_region_init_resizeable_ram(MemoryRegion *mr,
  * @size: size of the region.
  * @align: alignment of the region base address; if 0, the default alignment
  *         (getpagesize()) will be used.
- * @ram_flags: Memory region features:
- *             - RAM_SHARED: memory must be mmaped with the MAP_SHARED flag
- *             - RAM_PMEM: the memory is persistent memory
- *             Other bits are ignored now.
+ * @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM.
  * @path: the path in which to allocate the RAM.
  * @readonly: true to open @path for reading, false for read/write.
  * @errp: pointer to Error*, to store an error if it happens.
@@ -1034,7 +1031,7 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
  * @owner: the object that tracks the region's reference count
  * @name: the name of the region.
  * @size: size of the region.
- * @share: %true if memory must be mmaped with the MAP_SHARED flag
+ * @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM.
  * @fd: the fd to mmap.
  * @offset: offset within the file referenced by fd
  * @errp: pointer to Error*, to store an error if it happens.
@@ -1046,7 +1043,7 @@ void memory_region_init_ram_from_fd(MemoryRegion *mr,
                                     Object *owner,
                                     const char *name,
                                     uint64_t size,
-                                    bool share,
+                                    uint32_t ram_flags,
                                     int fd,
                                     ram_addr_t offset,
                                     Error **errp);
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index 3cb9791df3..a7e3378340 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -104,11 +104,7 @@ long qemu_maxrampagesize(void);
  * Parameters:
  *  @size: the size in bytes of the ram block
  *  @mr: the memory region where the ram block is
- *  @ram_flags: specify the properties of the ram block, which can be one
- *              or bit-or of following values
- *              - RAM_SHARED: mmap the backing file or device with MAP_SHARED
- *              - RAM_PMEM: the backend @mem_path or @fd is persistent memory
- *              Other bits are ignored.
+ *  @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM.
  *  @mem_path or @fd: specify the backing file or device
  *  @readonly: true to open @path for reading, false for read/write.
  *  @errp: pointer to Error*, to store an error if it happens
diff --git a/softmmu/memory.c b/softmmu/memory.c
index c19b0be6b1..f777504ac5 100644
--- a/softmmu/memory.c
+++ b/softmmu/memory.c
@@ -1609,7 +1609,7 @@ void memory_region_init_ram_from_fd(MemoryRegion *mr,
                                     Object *owner,
                                     const char *name,
                                     uint64_t size,
-                                    bool share,
+                                    uint32_t ram_flags,
                                     int fd,
                                     ram_addr_t offset,
                                     Error **errp)
@@ -1619,9 +1619,8 @@ void memory_region_init_ram_from_fd(MemoryRegion *mr,
     mr->ram = true;
     mr->terminates = true;
     mr->destructor = memory_region_destructor_ram;
-    mr->ram_block = qemu_ram_alloc_from_fd(size, mr,
-                                           share ? RAM_SHARED : 0,
-                                           fd, offset, false, &err);
+    mr->ram_block = qemu_ram_alloc_from_fd(size, mr, ram_flags, fd, offset,
+                                           false, &err);
     if (err) {
         mr->size = int128_zero();
         object_unparent(OBJECT(mr));
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 22/45] softmmu/memory: Pass ram_flags to memory_region_init_ram_shared_nomigrate()
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (20 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 21/45] softmmu/memory: Pass ram_flags to qemu_ram_alloc_from_fd() Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 23/45] softmmu/memory: Pass ram_flags to qemu_ram_alloc() and qemu_ram_alloc_internal() Paolo Bonzini
                   ` (24 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Philippe Mathieu-Daudé,
	Eduardo Habkost, Peter Xu, David Hildenbrand

From: David Hildenbrand <david@redhat.com>

Let's forward ram_flags instead, renaming
memory_region_init_ram_shared_nomigrate() into
memory_region_init_ram_flags_nomigrate().

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com> for memory backend and machine core
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20210510114328.21835-6-david@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 backends/hostmem-ram.c                        |  6 +++--
 hw/m68k/next-cube.c                           |  4 ++--
 include/exec/memory.h                         | 24 +++++++++----------
 .../memory-region-housekeeping.cocci          |  8 +++----
 softmmu/memory.c                              | 18 +++++++-------
 5 files changed, 31 insertions(+), 29 deletions(-)

diff --git a/backends/hostmem-ram.c b/backends/hostmem-ram.c
index 5cc53e76c9..741e701062 100644
--- a/backends/hostmem-ram.c
+++ b/backends/hostmem-ram.c
@@ -19,6 +19,7 @@
 static void
 ram_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
 {
+    uint32_t ram_flags;
     char *name;
 
     if (!backend->size) {
@@ -27,8 +28,9 @@ ram_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
     }
 
     name = host_memory_backend_get_name(backend);
-    memory_region_init_ram_shared_nomigrate(&backend->mr, OBJECT(backend), name,
-                           backend->size, backend->share, errp);
+    ram_flags = backend->share ? RAM_SHARED : 0;
+    memory_region_init_ram_flags_nomigrate(&backend->mr, OBJECT(backend), name,
+                                           backend->size, ram_flags, errp);
     g_free(name);
 }
 
diff --git a/hw/m68k/next-cube.c b/hw/m68k/next-cube.c
index de951ffe5d..e0d4a94f9d 100644
--- a/hw/m68k/next-cube.c
+++ b/hw/m68k/next-cube.c
@@ -984,8 +984,8 @@ static void next_cube_init(MachineState *machine)
     sysbus_mmio_map(SYS_BUS_DEVICE(pcdev), 1, 0x02100000);
 
     /* BMAP memory */
-    memory_region_init_ram_shared_nomigrate(bmapm1, NULL, "next.bmapmem", 64,
-                                            true, &error_fatal);
+    memory_region_init_ram_flags_nomigrate(bmapm1, NULL, "next.bmapmem", 64,
+                                           RAM_SHARED, &error_fatal);
     memory_region_add_subregion(sysmem, 0x020c0000, bmapm1);
     /* The Rev_2.5_v66.bin firmware accesses it at 0x820c0020, too */
     memory_region_init_alias(bmapm2, NULL, "next.bmapmem2", bmapm1, 0x0, 64);
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 8aa69a10d7..b1f8fa1df0 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -940,27 +940,27 @@ void memory_region_init_ram_nomigrate(MemoryRegion *mr,
                                       Error **errp);
 
 /**
- * memory_region_init_ram_shared_nomigrate:  Initialize RAM memory region.
- *                                           Accesses into the region will
- *                                           modify memory directly.
+ * memory_region_init_ram_flags_nomigrate:  Initialize RAM memory region.
+ *                                          Accesses into the region will
+ *                                          modify memory directly.
  *
  * @mr: the #MemoryRegion to be initialized.
  * @owner: the object that tracks the region's reference count
  * @name: Region name, becomes part of RAMBlock name used in migration stream
  *        must be unique within any device
  * @size: size of the region.
- * @share: allow remapping RAM to different addresses
+ * @ram_flags: RamBlock flags. Supported flags: RAM_SHARED.
  * @errp: pointer to Error*, to store an error if it happens.
  *
- * Note that this function is similar to memory_region_init_ram_nomigrate.
- * The only difference is part of the RAM region can be remapped.
+ * Note that this function does not do anything to cause the data in the
+ * RAM memory region to be migrated; that is the responsibility of the caller.
  */
-void memory_region_init_ram_shared_nomigrate(MemoryRegion *mr,
-                                             Object *owner,
-                                             const char *name,
-                                             uint64_t size,
-                                             bool share,
-                                             Error **errp);
+void memory_region_init_ram_flags_nomigrate(MemoryRegion *mr,
+                                            Object *owner,
+                                            const char *name,
+                                            uint64_t size,
+                                            uint32_t ram_flags,
+                                            Error **errp);
 
 /**
  * memory_region_init_resizeable_ram:  Initialize memory region with resizeable
diff --git a/scripts/coccinelle/memory-region-housekeeping.cocci b/scripts/coccinelle/memory-region-housekeeping.cocci
index c768d8140a..29651ebde9 100644
--- a/scripts/coccinelle/memory-region-housekeeping.cocci
+++ b/scripts/coccinelle/memory-region-housekeeping.cocci
@@ -127,8 +127,8 @@ static void device_fn(DeviceState *dev, ...)
 - memory_region_init_rom(E1, NULL, E2, E3, E4);
 + memory_region_init_rom(E1, obj, E2, E3, E4);
 |
-- memory_region_init_ram_shared_nomigrate(E1, NULL, E2, E3, E4, E5);
-+ memory_region_init_ram_shared_nomigrate(E1, obj, E2, E3, E4, E5);
+- memory_region_init_ram_flags_nomigrate(E1, NULL, E2, E3, E4, E5);
++ memory_region_init_ram_flags_nomigrate(E1, obj, E2, E3, E4, E5);
 )
   ...+>
 }
@@ -152,8 +152,8 @@ static void device_fn(DeviceState *dev, ...)
 - memory_region_init_rom(E1, NULL, E2, E3, E4);
 + memory_region_init_rom(E1, OBJECT(dev), E2, E3, E4);
 |
-- memory_region_init_ram_shared_nomigrate(E1, NULL, E2, E3, E4, E5);
-+ memory_region_init_ram_shared_nomigrate(E1, OBJECT(dev), E2, E3, E4, E5);
+- memory_region_init_ram_flags_nomigrate(E1, NULL, E2, E3, E4, E5);
++ memory_region_init_ram_flags_nomigrate(E1, OBJECT(dev), E2, E3, E4, E5);
 )
   ...+>
 }
diff --git a/softmmu/memory.c b/softmmu/memory.c
index f777504ac5..5c0ff76c06 100644
--- a/softmmu/memory.c
+++ b/softmmu/memory.c
@@ -1531,22 +1531,22 @@ void memory_region_init_ram_nomigrate(MemoryRegion *mr,
                                       uint64_t size,
                                       Error **errp)
 {
-    memory_region_init_ram_shared_nomigrate(mr, owner, name, size, false, errp);
+    memory_region_init_ram_flags_nomigrate(mr, owner, name, size, 0, errp);
 }
 
-void memory_region_init_ram_shared_nomigrate(MemoryRegion *mr,
-                                             Object *owner,
-                                             const char *name,
-                                             uint64_t size,
-                                             bool share,
-                                             Error **errp)
+void memory_region_init_ram_flags_nomigrate(MemoryRegion *mr,
+                                            Object *owner,
+                                            const char *name,
+                                            uint64_t size,
+                                            uint32_t ram_flags,
+                                            Error **errp)
 {
     Error *err = NULL;
     memory_region_init(mr, owner, name, size);
     mr->ram = true;
     mr->terminates = true;
     mr->destructor = memory_region_destructor_ram;
-    mr->ram_block = qemu_ram_alloc(size, share, mr, &err);
+    mr->ram_block = qemu_ram_alloc(size, ram_flags & RAM_SHARED, mr, &err);
     if (err) {
         mr->size = int128_zero();
         object_unparent(OBJECT(mr));
@@ -1682,7 +1682,7 @@ void memory_region_init_rom_nomigrate(MemoryRegion *mr,
                                       uint64_t size,
                                       Error **errp)
 {
-    memory_region_init_ram_shared_nomigrate(mr, owner, name, size, false, errp);
+    memory_region_init_ram_flags_nomigrate(mr, owner, name, size, 0, errp);
     mr->readonly = true;
 }
 
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 23/45] softmmu/memory: Pass ram_flags to qemu_ram_alloc() and qemu_ram_alloc_internal()
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (21 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 22/45] softmmu/memory: Pass ram_flags to memory_region_init_ram_shared_nomigrate() Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 24/45] util/mmap-alloc: Pass flags instead of separate bools to qemu_ram_mmap() Paolo Bonzini
                   ` (23 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Philippe Mathieu-Daudé, Eduardo Habkost, David Hildenbrand

From: David Hildenbrand <david@redhat.com>

Let's pass ram_flags to qemu_ram_alloc() and qemu_ram_alloc_internal(),
preparing for passing additional flags.

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com> for memory backend and machine core
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20210510114328.21835-7-david@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/exec/ram_addr.h |  2 +-
 softmmu/memory.c        |  4 ++--
 softmmu/physmem.c       | 29 ++++++++++++-----------------
 3 files changed, 15 insertions(+), 20 deletions(-)

diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index a7e3378340..6d4513f8e2 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -122,7 +122,7 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
 
 RAMBlock *qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
                                   MemoryRegion *mr, Error **errp);
-RAMBlock *qemu_ram_alloc(ram_addr_t size, bool share, MemoryRegion *mr,
+RAMBlock *qemu_ram_alloc(ram_addr_t size, uint32_t ram_flags, MemoryRegion *mr,
                          Error **errp);
 RAMBlock *qemu_ram_alloc_resizeable(ram_addr_t size, ram_addr_t max_size,
                                     void (*resized)(const char*,
diff --git a/softmmu/memory.c b/softmmu/memory.c
index 5c0ff76c06..f0161515e9 100644
--- a/softmmu/memory.c
+++ b/softmmu/memory.c
@@ -1546,7 +1546,7 @@ void memory_region_init_ram_flags_nomigrate(MemoryRegion *mr,
     mr->ram = true;
     mr->terminates = true;
     mr->destructor = memory_region_destructor_ram;
-    mr->ram_block = qemu_ram_alloc(size, ram_flags & RAM_SHARED, mr, &err);
+    mr->ram_block = qemu_ram_alloc(size, ram_flags, mr, &err);
     if (err) {
         mr->size = int128_zero();
         object_unparent(OBJECT(mr));
@@ -1702,7 +1702,7 @@ void memory_region_init_rom_device_nomigrate(MemoryRegion *mr,
     mr->terminates = true;
     mr->rom_device = true;
     mr->destructor = memory_region_destructor_ram;
-    mr->ram_block = qemu_ram_alloc(size, false,  mr, &err);
+    mr->ram_block = qemu_ram_alloc(size, 0, mr, &err);
     if (err) {
         mr->size = int128_zero();
         object_unparent(OBJECT(mr));
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index b75d205e8a..f00304e254 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -2128,12 +2128,15 @@ RAMBlock *qemu_ram_alloc_internal(ram_addr_t size, ram_addr_t max_size,
                                   void (*resized)(const char*,
                                                   uint64_t length,
                                                   void *host),
-                                  void *host, bool resizeable, bool share,
+                                  void *host, uint32_t ram_flags,
                                   MemoryRegion *mr, Error **errp)
 {
     RAMBlock *new_block;
     Error *local_err = NULL;
 
+    assert((ram_flags & ~(RAM_SHARED | RAM_RESIZEABLE | RAM_PREALLOC)) == 0);
+    assert(!host ^ (ram_flags & RAM_PREALLOC));
+
     size = HOST_PAGE_ALIGN(size);
     max_size = HOST_PAGE_ALIGN(max_size);
     new_block = g_malloc0(sizeof(*new_block));
@@ -2145,15 +2148,7 @@ RAMBlock *qemu_ram_alloc_internal(ram_addr_t size, ram_addr_t max_size,
     new_block->fd = -1;
     new_block->page_size = qemu_real_host_page_size;
     new_block->host = host;
-    if (host) {
-        new_block->flags |= RAM_PREALLOC;
-    }
-    if (share) {
-        new_block->flags |= RAM_SHARED;
-    }
-    if (resizeable) {
-        new_block->flags |= RAM_RESIZEABLE;
-    }
+    new_block->flags = ram_flags;
     ram_block_add(new_block, &local_err);
     if (local_err) {
         g_free(new_block);
@@ -2166,15 +2161,15 @@ RAMBlock *qemu_ram_alloc_internal(ram_addr_t size, ram_addr_t max_size,
 RAMBlock *qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
                                    MemoryRegion *mr, Error **errp)
 {
-    return qemu_ram_alloc_internal(size, size, NULL, host, false,
-                                   false, mr, errp);
+    return qemu_ram_alloc_internal(size, size, NULL, host, RAM_PREALLOC, mr,
+                                   errp);
 }
 
-RAMBlock *qemu_ram_alloc(ram_addr_t size, bool share,
+RAMBlock *qemu_ram_alloc(ram_addr_t size, uint32_t ram_flags,
                          MemoryRegion *mr, Error **errp)
 {
-    return qemu_ram_alloc_internal(size, size, NULL, NULL, false,
-                                   share, mr, errp);
+    assert((ram_flags & ~RAM_SHARED) == 0);
+    return qemu_ram_alloc_internal(size, size, NULL, NULL, ram_flags, mr, errp);
 }
 
 RAMBlock *qemu_ram_alloc_resizeable(ram_addr_t size, ram_addr_t maxsz,
@@ -2183,8 +2178,8 @@ RAMBlock *qemu_ram_alloc_resizeable(ram_addr_t size, ram_addr_t maxsz,
                                                      void *host),
                                      MemoryRegion *mr, Error **errp)
 {
-    return qemu_ram_alloc_internal(size, maxsz, resized, NULL, true,
-                                   false, mr, errp);
+    return qemu_ram_alloc_internal(size, maxsz, resized, NULL,
+                                   RAM_RESIZEABLE, mr, errp);
 }
 
 static void reclaim_ramblock(RAMBlock *block)
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 24/45] util/mmap-alloc: Pass flags instead of separate bools to qemu_ram_mmap()
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (22 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 23/45] softmmu/memory: Pass ram_flags to qemu_ram_alloc() and qemu_ram_alloc_internal() Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 25/45] memory: Introduce RAM_NORESERVE and wire it up in qemu_ram_mmap() Paolo Bonzini
                   ` (22 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Philippe Mathieu-Daudé,
	Eduardo Habkost, Peter Xu, David Hildenbrand

From: David Hildenbrand <david@redhat.com>

Let's pass flags instead of bools to prepare for passing other flags and
update the documentation of qemu_ram_mmap(). Introduce new QEMU_MAP_
flags that abstract the mmap() PROT_ and MAP_ flag handling and simplify
it.

We expose only flags that are currently supported by qemu_ram_mmap().
Maybe, we'll see qemu_mmap() in the future as well that can implement these
flags.

Note: We don't use MAP_ flags as some flags (e.g., MAP_SYNC) are only
defined for some systems and we want to always be able to identify
these flags reliably inside qemu_ram_mmap() -- for example, to properly
warn when some future flags are not available or effective on a system.
Also, this way we can simplify PROT_ handling as well.

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com> for memory backend and machine core
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20210510114328.21835-8-david@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/mmap-alloc.h | 16 +++++++++-------
 include/qemu/osdep.h      | 18 ++++++++++++++++++
 softmmu/physmem.c         |  8 +++++---
 util/mmap-alloc.c         | 15 ++++++++-------
 util/oslib-posix.c        |  3 ++-
 5 files changed, 42 insertions(+), 18 deletions(-)

diff --git a/include/qemu/mmap-alloc.h b/include/qemu/mmap-alloc.h
index 456ff87df1..90d0eee705 100644
--- a/include/qemu/mmap-alloc.h
+++ b/include/qemu/mmap-alloc.h
@@ -7,18 +7,22 @@ size_t qemu_fd_getpagesize(int fd);
 size_t qemu_mempath_getpagesize(const char *mem_path);
 
 /**
- * qemu_ram_mmap: mmap the specified file or device.
+ * qemu_ram_mmap: mmap anonymous memory, the specified file or device.
+ *
+ * mmap() abstraction to map guest RAM, simplifying flag handling, taking
+ * care of alignment requirements and installing guard pages.
  *
  * Parameters:
  *  @fd: the file or the device to mmap
  *  @size: the number of bytes to be mmaped
  *  @align: if not zero, specify the alignment of the starting mapping address;
  *          otherwise, the alignment in use will be determined by QEMU.
- *  @readonly: true for a read-only mapping, false for read/write.
- *  @shared: map has RAM_SHARED flag.
- *  @is_pmem: map has RAM_PMEM flag.
+ *  @qemu_map_flags: QEMU_MAP_* flags
  *  @map_offset: map starts at offset of map_offset from the start of fd
  *
+ * Internally, MAP_PRIVATE, MAP_ANONYMOUS and MAP_SHARED_VALIDATE are set
+ * implicitly based on other parameters.
+ *
  * Return:
  *  On success, return a pointer to the mapped area.
  *  On failure, return MAP_FAILED.
@@ -26,9 +30,7 @@ size_t qemu_mempath_getpagesize(const char *mem_path);
 void *qemu_ram_mmap(int fd,
                     size_t size,
                     size_t align,
-                    bool readonly,
-                    bool shared,
-                    bool is_pmem,
+                    uint32_t qemu_map_flags,
                     off_t map_offset);
 
 void qemu_ram_munmap(int fd, void *ptr, size_t size);
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 18a9e3fb4c..37a38c4af3 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -366,6 +366,24 @@ void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared);
 void qemu_vfree(void *ptr);
 void qemu_anon_ram_free(void *ptr, size_t size);
 
+/*
+ * Abstraction of PROT_ and MAP_ flags as passed to mmap(), for example,
+ * consumed by qemu_ram_mmap().
+ */
+
+/* Map PROT_READ instead of PROT_READ | PROT_WRITE. */
+#define QEMU_MAP_READONLY   (1 << 0)
+
+/* Use MAP_SHARED instead of MAP_PRIVATE. */
+#define QEMU_MAP_SHARED     (1 << 1)
+
+/*
+ * Use MAP_SYNC | MAP_SHARED_VALIDATE if supported. Ignored without
+ * QEMU_MAP_SHARED. If mapping fails, warn and fallback to !QEMU_MAP_SYNC.
+ */
+#define QEMU_MAP_SYNC       (1 << 2)
+
+
 #define QEMU_MADV_INVALID -1
 
 #if defined(CONFIG_MADVISE)
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index f00304e254..a110aa67fd 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -1540,6 +1540,7 @@ static void *file_ram_alloc(RAMBlock *block,
                             off_t offset,
                             Error **errp)
 {
+    uint32_t qemu_map_flags;
     void *area;
 
     block->page_size = qemu_fd_getpagesize(fd);
@@ -1587,9 +1588,10 @@ static void *file_ram_alloc(RAMBlock *block,
         perror("ftruncate");
     }
 
-    area = qemu_ram_mmap(fd, memory, block->mr->align, readonly,
-                         block->flags & RAM_SHARED, block->flags & RAM_PMEM,
-                         offset);
+    qemu_map_flags = readonly ? QEMU_MAP_READONLY : 0;
+    qemu_map_flags |= (block->flags & RAM_SHARED) ? QEMU_MAP_SHARED : 0;
+    qemu_map_flags |= (block->flags & RAM_PMEM) ? QEMU_MAP_SYNC : 0;
+    area = qemu_ram_mmap(fd, memory, block->mr->align, qemu_map_flags, offset);
     if (area == MAP_FAILED) {
         error_setg_errno(errp, errno,
                          "unable to map backing store for guest RAM");
diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c
index 0e2bd7bc0e..1ddc0e2a1e 100644
--- a/util/mmap-alloc.c
+++ b/util/mmap-alloc.c
@@ -118,9 +118,12 @@ static void *mmap_reserve(size_t size, int fd)
  * Activate memory in a reserved region from the given fd (if any), to make
  * it accessible.
  */
-static void *mmap_activate(void *ptr, size_t size, int fd, bool readonly,
-                           bool shared, bool is_pmem, off_t map_offset)
+static void *mmap_activate(void *ptr, size_t size, int fd,
+                           uint32_t qemu_map_flags, off_t map_offset)
 {
+    const bool readonly = qemu_map_flags & QEMU_MAP_READONLY;
+    const bool shared = qemu_map_flags & QEMU_MAP_SHARED;
+    const bool sync = qemu_map_flags & QEMU_MAP_SYNC;
     const int prot = PROT_READ | (readonly ? 0 : PROT_WRITE);
     int map_sync_flags = 0;
     int flags = MAP_FIXED;
@@ -128,7 +131,7 @@ static void *mmap_activate(void *ptr, size_t size, int fd, bool readonly,
 
     flags |= fd == -1 ? MAP_ANONYMOUS : 0;
     flags |= shared ? MAP_SHARED : MAP_PRIVATE;
-    if (shared && is_pmem) {
+    if (shared && sync) {
         map_sync_flags = MAP_SYNC | MAP_SHARED_VALIDATE;
     }
 
@@ -173,9 +176,7 @@ static inline size_t mmap_guard_pagesize(int fd)
 void *qemu_ram_mmap(int fd,
                     size_t size,
                     size_t align,
-                    bool readonly,
-                    bool shared,
-                    bool is_pmem,
+                    uint32_t qemu_map_flags,
                     off_t map_offset)
 {
     const size_t guard_pagesize = mmap_guard_pagesize(fd);
@@ -199,7 +200,7 @@ void *qemu_ram_mmap(int fd,
 
     offset = QEMU_ALIGN_UP((uintptr_t)guardptr, align) - (uintptr_t)guardptr;
 
-    ptr = mmap_activate(guardptr + offset, size, fd, readonly, shared, is_pmem,
+    ptr = mmap_activate(guardptr + offset, size, fd, qemu_map_flags,
                         map_offset);
     if (ptr == MAP_FAILED) {
         munmap(guardptr, total);
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 7b4bec1402..0dd7784a88 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -229,8 +229,9 @@ void *qemu_memalign(size_t alignment, size_t size)
 /* alloc shared memory pages */
 void *qemu_anon_ram_alloc(size_t size, uint64_t *alignment, bool shared)
 {
+    const uint32_t qemu_map_flags = shared ? QEMU_MAP_SHARED : 0;
     size_t align = QEMU_VMALLOC_ALIGN;
-    void *ptr = qemu_ram_mmap(-1, size, align, false, shared, false, 0);
+    void *ptr = qemu_ram_mmap(-1, size, align, qemu_map_flags, 0);
 
     if (ptr == MAP_FAILED) {
         return NULL;
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 25/45] memory: Introduce RAM_NORESERVE and wire it up in qemu_ram_mmap()
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (23 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 24/45] util/mmap-alloc: Pass flags instead of separate bools to qemu_ram_mmap() Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 26/45] util/mmap-alloc: Support RAM_NORESERVE via MAP_NORESERVE under Linux Paolo Bonzini
                   ` (21 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Philippe Mathieu-Daudé,
	Eduardo Habkost, Peter Xu, David Hildenbrand

From: David Hildenbrand <david@redhat.com>

Let's introduce RAM_NORESERVE, allowing mmap'ing with MAP_NORESERVE. The
new flag has the following semantics:

"
RAM is mmap-ed with MAP_NORESERVE. When set, reserving swap space (or huge
pages if applicable) is skipped: will bail out if not supported. When not
set, the OS will do the reservation, if supported for the memory type.
"

Allow passing it into:
- memory_region_init_ram_nomigrate()
- memory_region_init_resizeable_ram()
- memory_region_init_ram_from_file()

... and teach qemu_ram_mmap() and qemu_anon_ram_alloc() about the flag.
Bail out if the flag is not supported, which is the case right now for
both, POSIX and win32. We will add Linux support next and allow specifying
RAM_NORESERVE via memory backends.

The target use case is virtio-mem, which dynamically exposes memory
inside a large, sparse memory area to the VM.

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com> for memory backend and machine core
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20210510114328.21835-9-david@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/exec/cpu-common.h |  1 +
 include/exec/memory.h     | 15 ++++++++++++---
 include/exec/ram_addr.h   |  3 ++-
 include/qemu/osdep.h      |  9 ++++++++-
 migration/ram.c           |  3 +--
 softmmu/physmem.c         | 15 ++++++++++++---
 util/mmap-alloc.c         |  7 +++++++
 util/oslib-posix.c        |  6 ++++--
 util/oslib-win32.c        | 13 ++++++++++++-
 9 files changed, 59 insertions(+), 13 deletions(-)

diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index ccabed4003..039d422bf4 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -59,6 +59,7 @@ ram_addr_t qemu_ram_get_offset(RAMBlock *rb);
 ram_addr_t qemu_ram_get_used_length(RAMBlock *rb);
 ram_addr_t qemu_ram_get_max_length(RAMBlock *rb);
 bool qemu_ram_is_shared(RAMBlock *rb);
+bool qemu_ram_is_noreserve(RAMBlock *rb);
 bool qemu_ram_is_uf_zeroable(RAMBlock *rb);
 void qemu_ram_set_uf_zeroable(RAMBlock *rb);
 bool qemu_ram_is_migratable(RAMBlock *rb);
diff --git a/include/exec/memory.h b/include/exec/memory.h
index b1f8fa1df0..b116f7c64e 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -155,6 +155,13 @@ typedef struct IOMMUTLBEvent {
  */
 #define RAM_UF_WRITEPROTECT (1 << 6)
 
+/*
+ * RAM is mmap-ed with MAP_NORESERVE. When set, reserving swap space (or huge
+ * pages if applicable) is skipped: will bail out if not supported. When not
+ * set, the OS will do the reservation, if supported for the memory type.
+ */
+#define RAM_NORESERVE (1 << 7)
+
 static inline void iommu_notifier_init(IOMMUNotifier *n, IOMMUNotify fn,
                                        IOMMUNotifierFlag flags,
                                        hwaddr start, hwaddr end,
@@ -949,7 +956,7 @@ void memory_region_init_ram_nomigrate(MemoryRegion *mr,
  * @name: Region name, becomes part of RAMBlock name used in migration stream
  *        must be unique within any device
  * @size: size of the region.
- * @ram_flags: RamBlock flags. Supported flags: RAM_SHARED.
+ * @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_NORESERVE.
  * @errp: pointer to Error*, to store an error if it happens.
  *
  * Note that this function does not do anything to cause the data in the
@@ -1005,7 +1012,8 @@ void memory_region_init_resizeable_ram(MemoryRegion *mr,
  * @size: size of the region.
  * @align: alignment of the region base address; if 0, the default alignment
  *         (getpagesize()) will be used.
- * @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM.
+ * @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM,
+ *             RAM_NORESERVE,
  * @path: the path in which to allocate the RAM.
  * @readonly: true to open @path for reading, false for read/write.
  * @errp: pointer to Error*, to store an error if it happens.
@@ -1031,7 +1039,8 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
  * @owner: the object that tracks the region's reference count
  * @name: the name of the region.
  * @size: size of the region.
- * @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM.
+ * @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM,
+ *             RAM_NORESERVE.
  * @fd: the fd to mmap.
  * @offset: offset within the file referenced by fd
  * @errp: pointer to Error*, to store an error if it happens.
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index 6d4513f8e2..551876bed0 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -104,7 +104,8 @@ long qemu_maxrampagesize(void);
  * Parameters:
  *  @size: the size in bytes of the ram block
  *  @mr: the memory region where the ram block is
- *  @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM.
+ *  @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM,
+ *              RAM_NORESERVE.
  *  @mem_path or @fd: specify the backing file or device
  *  @readonly: true to open @path for reading, false for read/write.
  *  @errp: pointer to Error*, to store an error if it happens
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 37a38c4af3..c2c7fe5c47 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -362,7 +362,8 @@ extern "C" {
 int qemu_daemon(int nochdir, int noclose);
 void *qemu_try_memalign(size_t alignment, size_t size);
 void *qemu_memalign(size_t alignment, size_t size);
-void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared);
+void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared,
+                          bool noreserve);
 void qemu_vfree(void *ptr);
 void qemu_anon_ram_free(void *ptr, size_t size);
 
@@ -383,6 +384,12 @@ void qemu_anon_ram_free(void *ptr, size_t size);
  */
 #define QEMU_MAP_SYNC       (1 << 2)
 
+/*
+ * Use MAP_NORESERVE to skip reservation of swap space (or huge pages if
+ * applicable). Bail out if not supported/effective.
+ */
+#define QEMU_MAP_NORESERVE  (1 << 3)
+
 
 #define QEMU_MADV_INVALID -1
 
diff --git a/migration/ram.c b/migration/ram.c
index 60ea913c54..723af67c2e 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -3343,8 +3343,7 @@ int colo_init_ram_cache(void)
     WITH_RCU_READ_LOCK_GUARD() {
         RAMBLOCK_FOREACH_NOT_IGNORED(block) {
             block->colo_cache = qemu_anon_ram_alloc(block->used_length,
-                                                    NULL,
-                                                    false);
+                                                    NULL, false, false);
             if (!block->colo_cache) {
                 error_report("%s: Can't alloc memory for COLO cache of block %s,"
                              "size 0x" RAM_ADDR_FMT, __func__, block->idstr,
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index a110aa67fd..11ea8e19a6 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -1591,6 +1591,7 @@ static void *file_ram_alloc(RAMBlock *block,
     qemu_map_flags = readonly ? QEMU_MAP_READONLY : 0;
     qemu_map_flags |= (block->flags & RAM_SHARED) ? QEMU_MAP_SHARED : 0;
     qemu_map_flags |= (block->flags & RAM_PMEM) ? QEMU_MAP_SYNC : 0;
+    qemu_map_flags |= (block->flags & RAM_NORESERVE) ? QEMU_MAP_NORESERVE : 0;
     area = qemu_ram_mmap(fd, memory, block->mr->align, qemu_map_flags, offset);
     if (area == MAP_FAILED) {
         error_setg_errno(errp, errno,
@@ -1716,6 +1717,11 @@ bool qemu_ram_is_shared(RAMBlock *rb)
     return rb->flags & RAM_SHARED;
 }
 
+bool qemu_ram_is_noreserve(RAMBlock *rb)
+{
+    return rb->flags & RAM_NORESERVE;
+}
+
 /* Note: Only set at the start of postcopy */
 bool qemu_ram_is_uf_zeroable(RAMBlock *rb)
 {
@@ -1950,6 +1956,7 @@ static void dirty_memory_extend(ram_addr_t old_ram_size,
 
 static void ram_block_add(RAMBlock *new_block, Error **errp)
 {
+    const bool noreserve = qemu_ram_is_noreserve(new_block);
     const bool shared = qemu_ram_is_shared(new_block);
     RAMBlock *block;
     RAMBlock *last_block = NULL;
@@ -1973,7 +1980,7 @@ static void ram_block_add(RAMBlock *new_block, Error **errp)
         } else {
             new_block->host = qemu_anon_ram_alloc(new_block->max_length,
                                                   &new_block->mr->align,
-                                                  shared);
+                                                  shared, noreserve);
             if (!new_block->host) {
                 error_setg_errno(errp, errno,
                                  "cannot set up guest memory '%s'",
@@ -2045,7 +2052,7 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
     int64_t file_size, file_align;
 
     /* Just support these ram flags by now. */
-    assert((ram_flags & ~(RAM_SHARED | RAM_PMEM)) == 0);
+    assert((ram_flags & ~(RAM_SHARED | RAM_PMEM | RAM_NORESERVE)) == 0);
 
     if (xen_enabled()) {
         error_setg(errp, "-mem-path not supported with Xen");
@@ -2137,6 +2144,8 @@ RAMBlock *qemu_ram_alloc_internal(ram_addr_t size, ram_addr_t max_size,
     Error *local_err = NULL;
 
     assert((ram_flags & ~(RAM_SHARED | RAM_RESIZEABLE | RAM_PREALLOC)) == 0);
+    assert((ram_flags & ~(RAM_SHARED | RAM_RESIZEABLE | RAM_PREALLOC |
+                          RAM_NORESERVE)) == 0);
     assert(!host ^ (ram_flags & RAM_PREALLOC));
 
     size = HOST_PAGE_ALIGN(size);
@@ -2170,7 +2179,7 @@ RAMBlock *qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
 RAMBlock *qemu_ram_alloc(ram_addr_t size, uint32_t ram_flags,
                          MemoryRegion *mr, Error **errp)
 {
-    assert((ram_flags & ~RAM_SHARED) == 0);
+    assert((ram_flags & ~(RAM_SHARED | RAM_NORESERVE)) == 0);
     return qemu_ram_alloc_internal(size, size, NULL, NULL, ram_flags, mr, errp);
 }
 
diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c
index 1ddc0e2a1e..d0cf4aaee5 100644
--- a/util/mmap-alloc.c
+++ b/util/mmap-alloc.c
@@ -20,6 +20,7 @@
 #include "qemu/osdep.h"
 #include "qemu/mmap-alloc.h"
 #include "qemu/host-utils.h"
+#include "qemu/error-report.h"
 
 #define HUGETLBFS_MAGIC       0x958458f6
 
@@ -121,6 +122,7 @@ static void *mmap_reserve(size_t size, int fd)
 static void *mmap_activate(void *ptr, size_t size, int fd,
                            uint32_t qemu_map_flags, off_t map_offset)
 {
+    const bool noreserve = qemu_map_flags & QEMU_MAP_NORESERVE;
     const bool readonly = qemu_map_flags & QEMU_MAP_READONLY;
     const bool shared = qemu_map_flags & QEMU_MAP_SHARED;
     const bool sync = qemu_map_flags & QEMU_MAP_SYNC;
@@ -129,6 +131,11 @@ static void *mmap_activate(void *ptr, size_t size, int fd,
     int flags = MAP_FIXED;
     void *activated_ptr;
 
+    if (noreserve) {
+        error_report("Skipping reservation of swap space is not supported");
+        return MAP_FAILED;
+    }
+
     flags |= fd == -1 ? MAP_ANONYMOUS : 0;
     flags |= shared ? MAP_SHARED : MAP_PRIVATE;
     if (shared && sync) {
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 0dd7784a88..e8bdb02e1d 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -227,9 +227,11 @@ void *qemu_memalign(size_t alignment, size_t size)
 }
 
 /* alloc shared memory pages */
-void *qemu_anon_ram_alloc(size_t size, uint64_t *alignment, bool shared)
+void *qemu_anon_ram_alloc(size_t size, uint64_t *alignment, bool shared,
+                          bool noreserve)
 {
-    const uint32_t qemu_map_flags = shared ? QEMU_MAP_SHARED : 0;
+    const uint32_t qemu_map_flags = (shared ? QEMU_MAP_SHARED : 0) |
+                                    (noreserve ? QEMU_MAP_NORESERVE : 0);
     size_t align = QEMU_VMALLOC_ALIGN;
     void *ptr = qemu_ram_mmap(-1, size, align, qemu_map_flags, 0);
 
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
index ca99356fdf..ee3a3692d8 100644
--- a/util/oslib-win32.c
+++ b/util/oslib-win32.c
@@ -38,6 +38,7 @@
 #include "trace.h"
 #include "qemu/sockets.h"
 #include "qemu/cutils.h"
+#include "qemu/error-report.h"
 #include <malloc.h>
 
 /* this must come after including "trace.h" */
@@ -76,10 +77,20 @@ static int get_allocation_granularity(void)
     return system_info.dwAllocationGranularity;
 }
 
-void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared)
+void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared,
+                          bool noreserve)
 {
     void *ptr;
 
+    if (noreserve) {
+        /*
+         * We need a MEM_COMMIT before accessing any memory in a MEM_RESERVE
+         * area; we cannot easily mimic POSIX MAP_NORESERVE semantics.
+         */
+        error_report("Skipping reservation of swap space is not supported.");
+        return NULL;
+    }
+
     ptr = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
     trace_qemu_anon_ram_alloc(size, ptr);
 
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 26/45] util/mmap-alloc: Support RAM_NORESERVE via MAP_NORESERVE under Linux
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (24 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 25/45] memory: Introduce RAM_NORESERVE and wire it up in qemu_ram_mmap() Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 27/45] hostmem: Wire up RAM_NORESERVE via "reserve" property Paolo Bonzini
                   ` (20 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Eduardo Habkost, Peter Xu, David Hildenbrand

From: David Hildenbrand <david@redhat.com>

Let's support RAM_NORESERVE via MAP_NORESERVE on Linux. The flag has no
effect on most shared mappings - except for hugetlbfs and anonymous memory.

Linux man page:
  "MAP_NORESERVE: Do not reserve swap space for this mapping. When swap
  space is reserved, one has the guarantee that it is possible to modify
  the mapping. When swap space is not reserved one might get SIGSEGV
  upon a write if no physical memory is available. See also the discussion
  of the file /proc/sys/vm/overcommit_memory in proc(5). In kernels before
  2.6, this flag had effect only for private writable mappings."

Note that the "guarantee" part is wrong with memory overcommit in Linux.

Also, in Linux hugetlbfs is treated differently - we configure reservation
of huge pages from the pool, not reservation of swap space (huge pages
cannot be swapped).

The rough behavior is [1]:
a) !Hugetlbfs:

  1) Without MAP_NORESERVE *or* with memory overcommit under Linux
     disabled ("/proc/sys/vm/overcommit_memory == 2"), the following
     accounting/reservation happens:
      For a file backed map
       SHARED or READ-only - 0 cost (the file is the map not swap)
       PRIVATE WRITABLE - size of mapping per instance

      For an anonymous or /dev/zero map
       SHARED   - size of mapping
       PRIVATE READ-only - 0 cost (but of little use)
       PRIVATE WRITABLE - size of mapping per instance

  2) With MAP_NORESERVE, no accounting/reservation happens.

b) Hugetlbfs:

  1) Without MAP_NORESERVE, huge pages are reserved.

  2) With MAP_NORESERVE, no huge pages are reserved.

Note: With "/proc/sys/vm/overcommit_memory == 0", we were already able
to configure it for !hugetlbfs globally; this toggle now allows
configuring it more fine-grained, not for the whole system.

The target use case is virtio-mem, which dynamically exposes memory
inside a large, sparse memory area to the VM.

[1] https://www.kernel.org/doc/Documentation/vm/overcommit-accounting

Reviewed-by: Peter Xu <peterx@redhat.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com> for memory backend and machine core
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20210510114328.21835-10-david@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/osdep.h |  3 ++
 softmmu/physmem.c    |  1 +
 util/mmap-alloc.c    | 69 ++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index c2c7fe5c47..0a54bf7be8 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -195,6 +195,9 @@ extern "C" {
 #ifndef MAP_FIXED_NOREPLACE
 #define MAP_FIXED_NOREPLACE 0
 #endif
+#ifndef MAP_NORESERVE
+#define MAP_NORESERVE 0
+#endif
 #ifndef ENOMEDIUM
 #define ENOMEDIUM ENODEV
 #endif
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index 11ea8e19a6..9b171c9dbe 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -2251,6 +2251,7 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
                 flags = MAP_FIXED;
                 flags |= block->flags & RAM_SHARED ?
                          MAP_SHARED : MAP_PRIVATE;
+                flags |= block->flags & RAM_NORESERVE ? MAP_NORESERVE : 0;
                 if (block->fd >= 0) {
                     area = mmap(vaddr, length, PROT_READ | PROT_WRITE,
                                 flags, block->fd, offset);
diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c
index d0cf4aaee5..838e286ce5 100644
--- a/util/mmap-alloc.c
+++ b/util/mmap-alloc.c
@@ -20,6 +20,7 @@
 #include "qemu/osdep.h"
 #include "qemu/mmap-alloc.h"
 #include "qemu/host-utils.h"
+#include "qemu/cutils.h"
 #include "qemu/error-report.h"
 
 #define HUGETLBFS_MAGIC       0x958458f6
@@ -83,6 +84,70 @@ size_t qemu_mempath_getpagesize(const char *mem_path)
     return qemu_real_host_page_size;
 }
 
+#define OVERCOMMIT_MEMORY_PATH "/proc/sys/vm/overcommit_memory"
+static bool map_noreserve_effective(int fd, uint32_t qemu_map_flags)
+{
+#if defined(__linux__)
+    const bool readonly = qemu_map_flags & QEMU_MAP_READONLY;
+    const bool shared = qemu_map_flags & QEMU_MAP_SHARED;
+    gchar *content = NULL;
+    const char *endptr;
+    unsigned int tmp;
+
+    /*
+     * hugeltb accounting is different than ordinary swap reservation:
+     * a) Hugetlb pages from the pool are reserved for both private and
+     *    shared mappings. For shared mappings, all mappers have to specify
+     *    MAP_NORESERVE.
+     * b) MAP_NORESERVE is not affected by /proc/sys/vm/overcommit_memory.
+     */
+    if (qemu_fd_getpagesize(fd) != qemu_real_host_page_size) {
+        return true;
+    }
+
+    /*
+     * Accountable mappings in the kernel that can be affected by MAP_NORESEVE
+     * are private writable mappings (see mm/mmap.c:accountable_mapping() in
+     * Linux). For all shared or readonly mappings, MAP_NORESERVE is always
+     * implicitly active -- no reservation; this includes shmem. The only
+     * exception is shared anonymous memory, it is accounted like private
+     * anonymous memory.
+     */
+    if (readonly || (shared && fd >= 0)) {
+        return true;
+    }
+
+    /*
+     * MAP_NORESERVE is globally ignored for applicable !hugetlb mappings when
+     * memory overcommit is set to "never". Sparse memory regions aren't really
+     * possible in this system configuration.
+     *
+     * Bail out now instead of silently committing way more memory than
+     * currently desired by the user.
+     */
+    if (g_file_get_contents(OVERCOMMIT_MEMORY_PATH, &content, NULL, NULL) &&
+        !qemu_strtoui(content, &endptr, 0, &tmp) &&
+        (!endptr || *endptr == '\n')) {
+        if (tmp == 2) {
+            error_report("Skipping reservation of swap space is not supported:"
+                         " \"" OVERCOMMIT_MEMORY_PATH "\" is \"2\"");
+            return false;
+        }
+        return true;
+    }
+    /* this interface has been around since Linux 2.6 */
+    error_report("Skipping reservation of swap space is not supported:"
+                 " Could not read: \"" OVERCOMMIT_MEMORY_PATH "\"");
+    return false;
+#endif
+    /*
+     * E.g., FreeBSD used to define MAP_NORESERVE, never implemented it,
+     * and removed it a while ago.
+     */
+    error_report("Skipping reservation of swap space is not supported");
+    return false;
+}
+
 /*
  * Reserve a new memory region of the requested size to be used for mapping
  * from the given fd (if any).
@@ -131,13 +196,13 @@ static void *mmap_activate(void *ptr, size_t size, int fd,
     int flags = MAP_FIXED;
     void *activated_ptr;
 
-    if (noreserve) {
-        error_report("Skipping reservation of swap space is not supported");
+    if (noreserve && !map_noreserve_effective(fd, qemu_map_flags)) {
         return MAP_FAILED;
     }
 
     flags |= fd == -1 ? MAP_ANONYMOUS : 0;
     flags |= shared ? MAP_SHARED : MAP_PRIVATE;
+    flags |= noreserve ? MAP_NORESERVE : 0;
     if (shared && sync) {
         map_sync_flags = MAP_SYNC | MAP_SHARED_VALIDATE;
     }
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 27/45] hostmem: Wire up RAM_NORESERVE via "reserve" property
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (25 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 26/45] util/mmap-alloc: Support RAM_NORESERVE via MAP_NORESERVE under Linux Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 28/45] qmp: Clarify memory backend properties returned via query-memdev Paolo Bonzini
                   ` (19 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eduardo Habkost, David Hildenbrand, Markus Armbruster, Peter Xu,
	Igor Mammedov, Eric Blake

From: David Hildenbrand <david@redhat.com>

Let's provide a way to control the use of RAM_NORESERVE via memory
backends using the "reserve" property which defaults to true (old
behavior).

Only Linux currently supports clearing the flag (and support is checked at
runtime, depending on the setting of "/proc/sys/vm/overcommit_memory").
Windows and other POSIX systems will bail out with "reserve=false".

The target use case is virtio-mem, which dynamically exposes memory
inside a large, sparse memory area to the VM. This essentially allows
avoiding to set "/proc/sys/vm/overcommit_memory == 0") when using
virtio-mem and also supporting hugetlbfs in the future.

As really only Linux implements RAM_NORESERVE right now, let's expose
the property only with CONFIG_LINUX. Setting the property to "false"
will then only fail in corner cases -- for example on very old kernels
or when memory overcommit was completely disabled by the admin.

Reviewed-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com> for memory backend and machine core
Cc: Markus Armbruster <armbru@redhat.com>
Cc: Eric Blake <eblake@redhat.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20210510114328.21835-11-david@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 backends/hostmem-file.c  | 11 ++++++-----
 backends/hostmem-memfd.c |  1 +
 backends/hostmem-ram.c   |  1 +
 backends/hostmem.c       | 36 ++++++++++++++++++++++++++++++++++++
 include/sysemu/hostmem.h |  2 +-
 qapi/qom.json            | 10 ++++++++++
 6 files changed, 55 insertions(+), 6 deletions(-)

diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index 9b1b9f0a56..cd038024fa 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -39,6 +39,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
                object_get_typename(OBJECT(backend)));
 #else
     HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(backend);
+    uint32_t ram_flags;
     gchar *name;
 
     if (!backend->size) {
@@ -51,11 +52,11 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
     }
 
     name = host_memory_backend_get_name(backend);
-    memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
-                                     name,
-                                     backend->size, fb->align,
-                                     (backend->share ? RAM_SHARED : 0) |
-                                     (fb->is_pmem ? RAM_PMEM : 0),
+    ram_flags = backend->share ? RAM_SHARED : 0;
+    ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
+    ram_flags |= fb->is_pmem ? RAM_PMEM : 0;
+    memory_region_init_ram_from_file(&backend->mr, OBJECT(backend), name,
+                                     backend->size, fb->align, ram_flags,
                                      fb->mem_path, fb->readonly, errp);
     g_free(name);
 #endif
diff --git a/backends/hostmem-memfd.c b/backends/hostmem-memfd.c
index 3076da146d..3fc85c3db8 100644
--- a/backends/hostmem-memfd.c
+++ b/backends/hostmem-memfd.c
@@ -54,6 +54,7 @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
 
     name = host_memory_backend_get_name(backend);
     ram_flags = backend->share ? RAM_SHARED : 0;
+    ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
     memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend), name,
                                    backend->size, ram_flags, fd, 0, errp);
     g_free(name);
diff --git a/backends/hostmem-ram.c b/backends/hostmem-ram.c
index 741e701062..b8e55cdbd0 100644
--- a/backends/hostmem-ram.c
+++ b/backends/hostmem-ram.c
@@ -29,6 +29,7 @@ ram_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
 
     name = host_memory_backend_get_name(backend);
     ram_flags = backend->share ? RAM_SHARED : 0;
+    ram_flags |= backend->reserve ? 0 : RAM_NORESERVE;
     memory_region_init_ram_flags_nomigrate(&backend->mr, OBJECT(backend), name,
                                            backend->size, ram_flags, errp);
     g_free(name);
diff --git a/backends/hostmem.c b/backends/hostmem.c
index aab3de8408..4c05862ed5 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -216,6 +216,11 @@ static void host_memory_backend_set_prealloc(Object *obj, bool value,
     Error *local_err = NULL;
     HostMemoryBackend *backend = MEMORY_BACKEND(obj);
 
+    if (!backend->reserve && value) {
+        error_setg(errp, "'prealloc=on' and 'reserve=off' are incompatible");
+        return;
+    }
+
     if (!host_memory_backend_mr_inited(backend)) {
         backend->prealloc = value;
         return;
@@ -267,6 +272,7 @@ static void host_memory_backend_init(Object *obj)
     /* TODO: convert access to globals to compat properties */
     backend->merge = machine_mem_merge(machine);
     backend->dump = machine_dump_guest_core(machine);
+    backend->reserve = true;
     backend->prealloc_threads = 1;
 }
 
@@ -425,6 +431,30 @@ static void host_memory_backend_set_share(Object *o, bool value, Error **errp)
     backend->share = value;
 }
 
+#ifdef CONFIG_LINUX
+static bool host_memory_backend_get_reserve(Object *o, Error **errp)
+{
+    HostMemoryBackend *backend = MEMORY_BACKEND(o);
+
+    return backend->reserve;
+}
+
+static void host_memory_backend_set_reserve(Object *o, bool value, Error **errp)
+{
+    HostMemoryBackend *backend = MEMORY_BACKEND(o);
+
+    if (host_memory_backend_mr_inited(backend)) {
+        error_setg(errp, "cannot change property value");
+        return;
+    }
+    if (backend->prealloc && !value) {
+        error_setg(errp, "'prealloc=on' and 'reserve=off' are incompatible");
+        return;
+    }
+    backend->reserve = value;
+}
+#endif /* CONFIG_LINUX */
+
 static bool
 host_memory_backend_get_use_canonical_path(Object *obj, Error **errp)
 {
@@ -493,6 +523,12 @@ host_memory_backend_class_init(ObjectClass *oc, void *data)
         host_memory_backend_get_share, host_memory_backend_set_share);
     object_class_property_set_description(oc, "share",
         "Mark the memory as private to QEMU or shared");
+#ifdef CONFIG_LINUX
+    object_class_property_add_bool(oc, "reserve",
+        host_memory_backend_get_reserve, host_memory_backend_set_reserve);
+    object_class_property_set_description(oc, "reserve",
+        "Reserve swap space (or huge pages) if applicable");
+#endif /* CONFIG_LINUX */
     /*
      * Do not delete/rename option. This option must be considered stable
      * (as if it didn't have the 'x-' prefix including deprecation period) as
diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h
index df5644723a..9ff5c16963 100644
--- a/include/sysemu/hostmem.h
+++ b/include/sysemu/hostmem.h
@@ -64,7 +64,7 @@ struct HostMemoryBackend {
     /* protected */
     uint64_t size;
     bool merge, dump, use_canonical_path;
-    bool prealloc, is_mapped, share;
+    bool prealloc, is_mapped, share, reserve;
     uint32_t prealloc_threads;
     DECLARE_BITMAP(host_nodes, MAX_NODES + 1);
     HostMemPolicy policy;
diff --git a/qapi/qom.json b/qapi/qom.json
index f7ef30f940..652be317b8 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -545,6 +545,9 @@
 # @share: if false, the memory is private to QEMU; if true, it is shared
 #         (default: false)
 #
+# @reserve: if true, reserve swap space (or huge pages) if applicable
+#           (default: true) (since 6.1)
+#
 # @size: size of the memory region in bytes
 #
 # @x-use-canonical-path-for-ramblock-id: if true, the canoncial path is used
@@ -556,6 +559,12 @@
 #                                        false generally, but true for machine
 #                                        types <= 4.0)
 #
+# Note: prealloc=true and reserve=false cannot be set at the same time. With
+#       reserve=true, the behavior depends on the operating system: for example,
+#       Linux will not reserve swap space for shared file mappings --
+#       "not applicable". In contrast, reserve=false will bail out if it cannot
+#       be configured accordingly.
+#
 # Since: 2.1
 ##
 { 'struct': 'MemoryBackendProperties',
@@ -566,6 +575,7 @@
             '*prealloc': 'bool',
             '*prealloc-threads': 'uint32',
             '*share': 'bool',
+            '*reserve': 'bool',
             'size': 'size',
             '*x-use-canonical-path-for-ramblock-id': 'bool' } }
 
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 28/45] qmp: Clarify memory backend properties returned via query-memdev
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (26 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 27/45] hostmem: Wire up RAM_NORESERVE via "reserve" property Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 29/45] qmp: Include "share" property of memory backends Paolo Bonzini
                   ` (18 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eduardo Habkost, David Hildenbrand, Eric Blake,
	Markus Armbruster, Igor Mammedov, Philippe Mathieu-Daudé

From: David Hildenbrand <david@redhat.com>

We return information on the currently configured memory backends and
don't configure them, so decribe what the currently set properties
express.

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Suggested-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com> for memory backend and machine core
Cc: Eric Blake <eblake@redhat.com>
Cc: Markus Armbruster <armbru@redhat.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20210510114328.21835-12-david@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 qapi/machine.json | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/qapi/machine.json b/qapi/machine.json
index 58a9c86b36..eb14364819 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -790,11 +790,11 @@
 #
 # @size: memory backend size
 #
-# @merge: enables or disables memory merge support
+# @merge: whether memory merge support is enabled
 #
-# @dump: includes memory backend's memory in a core dump or not
+# @dump: whether memory backend's memory is included in a core dump
 #
-# @prealloc: enables or disables memory preallocation
+# @prealloc: whether memory was preallocated
 #
 # @host-nodes: host nodes for its memory policy
 #
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 29/45] qmp: Include "share" property of memory backends
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (27 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 28/45] qmp: Clarify memory backend properties returned via query-memdev Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 30/45] hmp: Print "share" property of memory backends with "info memdev" Paolo Bonzini
                   ` (17 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eduardo Habkost, David Hildenbrand, Eric Blake,
	Markus Armbruster, Igor Mammedov, Philippe Mathieu-Daudé

From: David Hildenbrand <david@redhat.com>

Let's include the property, which can be helpful when debugging,
for example, to spot misuse of MAP_PRIVATE which can result in some ugly
corner cases (e.g., double-memory consumption on shmem).

Use the same description we also use for describing the property.

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com> for memory backend and machine core
Cc: Eric Blake <eblake@redhat.com>
Cc: Markus Armbruster <armbru@redhat.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20210510114328.21835-13-david@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/core/machine-qmp-cmds.c | 1 +
 qapi/machine.json          | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
index a36c96608f..a36ceaf4f3 100644
--- a/hw/core/machine-qmp-cmds.c
+++ b/hw/core/machine-qmp-cmds.c
@@ -172,6 +172,7 @@ static int query_memdev(Object *obj, void *opaque)
         m->merge = object_property_get_bool(obj, "merge", &error_abort);
         m->dump = object_property_get_bool(obj, "dump", &error_abort);
         m->prealloc = object_property_get_bool(obj, "prealloc", &error_abort);
+        m->share = object_property_get_bool(obj, "share", &error_abort);
         m->policy = object_property_get_enum(obj, "policy", "HostMemPolicy",
                                              &error_abort);
         host_nodes = object_property_get_qobject(obj,
diff --git a/qapi/machine.json b/qapi/machine.json
index eb14364819..1395742a4a 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -796,6 +796,8 @@
 #
 # @prealloc: whether memory was preallocated
 #
+# @share: whether memory is private to QEMU or shared (since 6.1)
+#
 # @host-nodes: host nodes for its memory policy
 #
 # @policy: memory policy of memory backend
@@ -809,6 +811,7 @@
     'merge':      'bool',
     'dump':       'bool',
     'prealloc':   'bool',
+    'share':      'bool',
     'host-nodes': ['uint16'],
     'policy':     'HostMemPolicy' }}
 
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 30/45] hmp: Print "share" property of memory backends with "info memdev"
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (28 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 29/45] qmp: Include "share" property of memory backends Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 31/45] qmp: Include "reserve" property of memory backends Paolo Bonzini
                   ` (16 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eduardo Habkost, David Hildenbrand, Philippe Mathieu-Daudé,
	Markus Armbruster, Dr . David Alan Gilbert, Igor Mammedov,
	Eric Blake

From: David Hildenbrand <david@redhat.com>

Let's print the property.

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com> for memory backend and machine core
Cc: Markus Armbruster <armbru@redhat.com>
Cc: Eric Blake <eblake@redhat.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20210510114328.21835-14-david@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/core/machine-hmp-cmds.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
index 58248cffa3..004a92b3d6 100644
--- a/hw/core/machine-hmp-cmds.c
+++ b/hw/core/machine-hmp-cmds.c
@@ -110,6 +110,8 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict)
                        m->value->dump ? "true" : "false");
         monitor_printf(mon, "  prealloc: %s\n",
                        m->value->prealloc ? "true" : "false");
+        monitor_printf(mon, "  share: %s\n",
+                       m->value->share ? "true" : "false");
         monitor_printf(mon, "  policy: %s\n",
                        HostMemPolicy_str(m->value->policy));
         visit_complete(v, &str);
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 31/45] qmp: Include "reserve" property of memory backends
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (29 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 30/45] hmp: Print "share" property of memory backends with "info memdev" Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 32/45] hmp: Print "reserve" property of memory backends with "info memdev" Paolo Bonzini
                   ` (15 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eduardo Habkost, David Hildenbrand, Eric Blake,
	Markus Armbruster, Igor Mammedov, Philippe Mathieu-Daudé

From: David Hildenbrand <david@redhat.com>

Let's include the new property. Instead of relying on CONFIG_LINUX,
let's try to unconditionally grab the property and treat errors as
"does not exist".

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com> for memory backend and machine core
Cc: Eric Blake <eblake@redhat.com>
Cc: Markus Armbruster <armbru@redhat.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20210510114328.21835-15-david@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/core/machine-qmp-cmds.c | 7 +++++++
 qapi/machine.json          | 7 +++++++
 2 files changed, 14 insertions(+)

diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
index a36ceaf4f3..216fdfaf3a 100644
--- a/hw/core/machine-qmp-cmds.c
+++ b/hw/core/machine-qmp-cmds.c
@@ -157,6 +157,7 @@ void qmp_set_numa_node(NumaOptions *cmd, Error **errp)
 
 static int query_memdev(Object *obj, void *opaque)
 {
+    Error *err = NULL;
     MemdevList **list = opaque;
     Memdev *m;
     QObject *host_nodes;
@@ -173,6 +174,12 @@ static int query_memdev(Object *obj, void *opaque)
         m->dump = object_property_get_bool(obj, "dump", &error_abort);
         m->prealloc = object_property_get_bool(obj, "prealloc", &error_abort);
         m->share = object_property_get_bool(obj, "share", &error_abort);
+        m->reserve = object_property_get_bool(obj, "reserve", &err);
+        if (err) {
+            error_free_or_abort(&err);
+        } else {
+            m->has_reserve = true;
+        }
         m->policy = object_property_get_enum(obj, "policy", "HostMemPolicy",
                                              &error_abort);
         host_nodes = object_property_get_qobject(obj,
diff --git a/qapi/machine.json b/qapi/machine.json
index 1395742a4a..e4d0f9b24f 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -798,6 +798,12 @@
 #
 # @share: whether memory is private to QEMU or shared (since 6.1)
 #
+# @reserve: whether swap space (or huge pages) was reserved if applicable.
+#           This corresponds to the user configuration and not the actual
+#           behavior implemented in the OS to perform the reservation.
+#           For example, Linux will never reserve swap space for shared
+#           file mappings. (since 6.1)
+#
 # @host-nodes: host nodes for its memory policy
 #
 # @policy: memory policy of memory backend
@@ -812,6 +818,7 @@
     'dump':       'bool',
     'prealloc':   'bool',
     'share':      'bool',
+    '*reserve':    'bool',
     'host-nodes': ['uint16'],
     'policy':     'HostMemPolicy' }}
 
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 32/45] hmp: Print "reserve" property of memory backends with "info memdev"
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (30 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 31/45] qmp: Include "reserve" property of memory backends Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 33/45] configure: map x32 to cpu_family x86_64 for meson Paolo Bonzini
                   ` (14 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Eduardo Habkost, David Hildenbrand, Philippe Mathieu-Daudé,
	Markus Armbruster, Dr . David Alan Gilbert, Igor Mammedov,
	Eric Blake

From: David Hildenbrand <david@redhat.com>

Let's print the new property.

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Eduardo Habkost <ehabkost@redhat.com> for memory backend and machine core
Cc: Markus Armbruster <armbru@redhat.com>
Cc: Eric Blake <eblake@redhat.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20210510114328.21835-16-david@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/core/machine-hmp-cmds.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
index 004a92b3d6..76b22b00d6 100644
--- a/hw/core/machine-hmp-cmds.c
+++ b/hw/core/machine-hmp-cmds.c
@@ -112,6 +112,10 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict)
                        m->value->prealloc ? "true" : "false");
         monitor_printf(mon, "  share: %s\n",
                        m->value->share ? "true" : "false");
+        if (m->value->has_reserve) {
+            monitor_printf(mon, "  reserve: %s\n",
+                           m->value->reserve ? "true" : "false");
+        }
         monitor_printf(mon, "  policy: %s\n",
                        HostMemPolicy_str(m->value->policy));
         visit_complete(v, &str);
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 33/45] configure: map x32 to cpu_family x86_64 for meson
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (31 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 32/45] hmp: Print "reserve" property of memory backends with "info memdev" Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 34/45] target/i386: Refactored intercept checks into cpu_svm_has_intercept Paolo Bonzini
                   ` (13 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: David Michael

From: David Michael <fedora.dm0@gmail.com>

The meson.build file defines supported_cpus which does not contain
x32, and x32 is not one of meson's stable built-in values:
https://mesonbuild.com/Reference-tables.html#cpu-families

Signed-off-by: David Michael <fedora.dm0@gmail.com>
Message-Id: <878s3jrzm0.fsf@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 configure | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configure b/configure
index 8dcb9965b2..4478f3889a 100755
--- a/configure
+++ b/configure
@@ -6384,7 +6384,7 @@ if test "$skip_meson" = no; then
         i386)
             echo "cpu_family = 'x86'" >> $cross
             ;;
-        x86_64)
+        x86_64|x32)
             echo "cpu_family = 'x86_64'" >> $cross
             ;;
         ppc64le)
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 34/45] target/i386: Refactored intercept checks into cpu_svm_has_intercept
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (32 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 33/45] configure: map x32 to cpu_family x86_64 for meson Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 35/45] target/i386: Added consistency checks for VMRUN intercept and ASID Paolo Bonzini
                   ` (12 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Lara Lazier

From: Lara Lazier <laramglazier@gmail.com>

Added cpu_svm_has_intercept to reduce duplication when checking the
corresponding intercept bit outside of cpu_svm_check_intercept_param

Signed-off-by: Lara Lazier <laramglazier@gmail.com>
Message-Id: <20210616123907.17765-2-laramglazier@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/cpu.h                   |   4 +
 target/i386/tcg/sysemu/svm_helper.c | 133 +++++++++++++++-------------
 2 files changed, 76 insertions(+), 61 deletions(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index ac3abea97c..64b4e46731 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -2149,9 +2149,13 @@ static inline void
 cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type,
                               uint64_t param, uintptr_t retaddr)
 { /* no-op */ }
+static inline bool
+cpu_svm_has_intercept(CPUX86State *env, uint32_t type)
+{ return false; }
 #else
 void cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type,
                                    uint64_t param, uintptr_t retaddr);
+bool cpu_svm_has_intercept(CPUX86State *env, uint32_t type);
 #endif
 
 /* apic.c */
diff --git a/target/i386/tcg/sysemu/svm_helper.c b/target/i386/tcg/sysemu/svm_helper.c
index 9d671297cf..2f7606bebf 100644
--- a/target/i386/tcg/sysemu/svm_helper.c
+++ b/target/i386/tcg/sysemu/svm_helper.c
@@ -412,6 +412,43 @@ void helper_clgi(CPUX86State *env)
     env->hflags2 &= ~HF2_GIF_MASK;
 }
 
+bool cpu_svm_has_intercept(CPUX86State *env, uint32_t type)
+{
+    switch (type) {
+    case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR0 + 8:
+        if (env->intercept_cr_read & (1 << (type - SVM_EXIT_READ_CR0))) {
+            return true;
+        }
+        break;
+    case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR0 + 8:
+        if (env->intercept_cr_write & (1 << (type - SVM_EXIT_WRITE_CR0))) {
+            return true;
+        }
+        break;
+    case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR0 + 7:
+        if (env->intercept_dr_read & (1 << (type - SVM_EXIT_READ_DR0))) {
+            return true;
+        }
+        break;
+    case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR0 + 7:
+        if (env->intercept_dr_write & (1 << (type - SVM_EXIT_WRITE_DR0))) {
+            return true;
+        }
+        break;
+    case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 31:
+        if (env->intercept_exceptions & (1 << (type - SVM_EXIT_EXCP_BASE))) {
+            return true;
+        }
+        break;
+    default:
+        if (env->intercept & (1ULL << (type - SVM_EXIT_INTR))) {
+            return true;
+        }
+        break;
+    }
+    return false;
+}
+
 void cpu_svm_check_intercept_param(CPUX86State *env, uint32_t type,
                                    uint64_t param, uintptr_t retaddr)
 {
@@ -420,72 +457,46 @@ void cpu_svm_check_intercept_param(CPUX86State *env, uint32_t type,
     if (likely(!(env->hflags & HF_GUEST_MASK))) {
         return;
     }
-    switch (type) {
-    case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR0 + 8:
-        if (env->intercept_cr_read & (1 << (type - SVM_EXIT_READ_CR0))) {
-            cpu_vmexit(env, type, param, retaddr);
-        }
-        break;
-    case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR0 + 8:
-        if (env->intercept_cr_write & (1 << (type - SVM_EXIT_WRITE_CR0))) {
-            cpu_vmexit(env, type, param, retaddr);
-        }
-        break;
-    case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR0 + 7:
-        if (env->intercept_dr_read & (1 << (type - SVM_EXIT_READ_DR0))) {
-            cpu_vmexit(env, type, param, retaddr);
-        }
-        break;
-    case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR0 + 7:
-        if (env->intercept_dr_write & (1 << (type - SVM_EXIT_WRITE_DR0))) {
-            cpu_vmexit(env, type, param, retaddr);
-        }
-        break;
-    case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 31:
-        if (env->intercept_exceptions & (1 << (type - SVM_EXIT_EXCP_BASE))) {
-            cpu_vmexit(env, type, param, retaddr);
-        }
-        break;
-    case SVM_EXIT_MSR:
-        if (env->intercept & (1ULL << (SVM_EXIT_MSR - SVM_EXIT_INTR))) {
-            /* FIXME: this should be read in at vmrun (faster this way?) */
-            uint64_t addr = x86_ldq_phys(cs, env->vm_vmcb +
-                                     offsetof(struct vmcb,
-                                              control.msrpm_base_pa));
-            uint32_t t0, t1;
 
-            switch ((uint32_t)env->regs[R_ECX]) {
-            case 0 ... 0x1fff:
-                t0 = (env->regs[R_ECX] * 2) % 8;
-                t1 = (env->regs[R_ECX] * 2) / 8;
-                break;
-            case 0xc0000000 ... 0xc0001fff:
-                t0 = (8192 + env->regs[R_ECX] - 0xc0000000) * 2;
-                t1 = (t0 / 8);
-                t0 %= 8;
-                break;
-            case 0xc0010000 ... 0xc0011fff:
-                t0 = (16384 + env->regs[R_ECX] - 0xc0010000) * 2;
-                t1 = (t0 / 8);
-                t0 %= 8;
-                break;
-            default:
-                cpu_vmexit(env, type, param, retaddr);
-                t0 = 0;
-                t1 = 0;
-                break;
-            }
-            if (x86_ldub_phys(cs, addr + t1) & ((1 << param) << t0)) {
-                cpu_vmexit(env, type, param, retaddr);
-            }
+    if (!cpu_svm_has_intercept(env, type)) {
+        return;
+    }
+
+    if (type == SVM_EXIT_MSR) {
+        /* FIXME: this should be read in at vmrun (faster this way?) */
+        uint64_t addr = x86_ldq_phys(cs, env->vm_vmcb +
+                                    offsetof(struct vmcb,
+                                            control.msrpm_base_pa));
+        uint32_t t0, t1;
+
+        switch ((uint32_t)env->regs[R_ECX]) {
+        case 0 ... 0x1fff:
+            t0 = (env->regs[R_ECX] * 2) % 8;
+            t1 = (env->regs[R_ECX] * 2) / 8;
+            break;
+        case 0xc0000000 ... 0xc0001fff:
+            t0 = (8192 + env->regs[R_ECX] - 0xc0000000) * 2;
+            t1 = (t0 / 8);
+            t0 %= 8;
+            break;
+        case 0xc0010000 ... 0xc0011fff:
+            t0 = (16384 + env->regs[R_ECX] - 0xc0010000) * 2;
+            t1 = (t0 / 8);
+            t0 %= 8;
+            break;
+        default:
+            cpu_vmexit(env, type, param, retaddr);
+            t0 = 0;
+            t1 = 0;
+            break;
         }
-        break;
-    default:
-        if (env->intercept & (1ULL << (type - SVM_EXIT_INTR))) {
+        if (x86_ldub_phys(cs, addr + t1) & ((1 << param) << t0)) {
             cpu_vmexit(env, type, param, retaddr);
         }
-        break;
+        return;
     }
+
+    cpu_vmexit(env, type, param, retaddr);
 }
 
 void helper_svm_check_intercept(CPUX86State *env, uint32_t type)
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 35/45] target/i386: Added consistency checks for VMRUN intercept and ASID
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (33 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 34/45] target/i386: Refactored intercept checks into cpu_svm_has_intercept Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 36/45] target/i386: Added consistency checks for CR0 Paolo Bonzini
                   ` (11 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Lara Lazier

From: Lara Lazier <laramglazier@gmail.com>

Zero VMRUN intercept and ASID should cause an immediate VMEXIT
during the consistency checks performed by VMRUN.
(AMD64 Architecture Programmer's Manual, V2, 15.5)

Signed-off-by: Lara Lazier <laramglazier@gmail.com>
Message-Id: <20210616123907.17765-3-laramglazier@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/tcg/sysemu/svm_helper.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/target/i386/tcg/sysemu/svm_helper.c b/target/i386/tcg/sysemu/svm_helper.c
index 2f7606bebf..902bf03fc3 100644
--- a/target/i386/tcg/sysemu/svm_helper.c
+++ b/target/i386/tcg/sysemu/svm_helper.c
@@ -72,6 +72,7 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
     uint64_t nested_ctl;
     uint32_t event_inj;
     uint32_t int_ctl;
+    uint32_t asid;
 
     cpu_svm_check_intercept_param(env, SVM_EXIT_VMRUN, 0, GETPC());
 
@@ -154,9 +155,18 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
 
     nested_ctl = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
                                                           control.nested_ctl));
+    asid = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
+                                                          control.asid));
 
     env->nested_pg_mode = 0;
 
+    if (!cpu_svm_has_intercept(env, SVM_EXIT_VMRUN)) {
+        cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
+    }
+    if (asid == 0) {
+        cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
+    }
+
     if (nested_ctl & SVM_NPT_ENABLED) {
         env->nested_cr3 = x86_ldq_phys(cs,
                                 env->vm_vmcb + offsetof(struct vmcb,
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 36/45] target/i386: Added consistency checks for CR0
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (34 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 35/45] target/i386: Added consistency checks for VMRUN intercept and ASID Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 37/45] target/i386: Added Intercept CR0 writes check Paolo Bonzini
                   ` (10 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Lara Lazier

From: Lara Lazier <laramglazier@gmail.com>

The combination of unset CD and set NW bit in CR0 is illegal.
CR0[63:32] are also reserved and need to be zero.
(AMD64 Architecture Programmer's Manual, V2, 15.5)

Signed-off-by: Lara Lazier <laramglazier@gmail.com>
Message-Id: <20210616123907.17765-4-laramglazier@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/cpu.h                   |  2 ++
 target/i386/svm.h                   |  2 ++
 target/i386/tcg/sysemu/svm_helper.c | 12 +++++++++---
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 64b4e46731..1e11071d81 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -224,6 +224,8 @@ typedef enum X86Seg {
 #define CR0_NE_MASK  (1U << 5)
 #define CR0_WP_MASK  (1U << 16)
 #define CR0_AM_MASK  (1U << 18)
+#define CR0_NW_MASK  (1U << 29)
+#define CR0_CD_MASK  (1U << 30)
 #define CR0_PG_MASK  (1U << 31)
 
 #define CR4_VME_MASK  (1U << 0)
diff --git a/target/i386/svm.h b/target/i386/svm.h
index 87965e5bc2..5098733053 100644
--- a/target/i386/svm.h
+++ b/target/i386/svm.h
@@ -135,6 +135,8 @@
 #define SVM_NPTEXIT_GPA     (1ULL << 32)
 #define SVM_NPTEXIT_GPT     (1ULL << 33)
 
+#define SVM_CR0_RESERVED_MASK 0xffffffff00000000U
+
 struct QEMU_PACKED vmcb_control_area {
 	uint16_t intercept_cr_read;
 	uint16_t intercept_cr_write;
diff --git a/target/i386/tcg/sysemu/svm_helper.c b/target/i386/tcg/sysemu/svm_helper.c
index 902bf03fc3..1c2dbc1862 100644
--- a/target/i386/tcg/sysemu/svm_helper.c
+++ b/target/i386/tcg/sysemu/svm_helper.c
@@ -73,6 +73,7 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
     uint32_t event_inj;
     uint32_t int_ctl;
     uint32_t asid;
+    uint64_t new_cr0;
 
     cpu_svm_check_intercept_param(env, SVM_EXIT_VMRUN, 0, GETPC());
 
@@ -192,13 +193,18 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
     env->idt.limit = x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
                                                       save.idtr.limit));
 
+    new_cr0 = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.cr0));
+    if (new_cr0 & SVM_CR0_RESERVED_MASK) {
+        cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
+    }
+    if ((new_cr0 & CR0_NW_MASK) && !(new_cr0 & CR0_CD_MASK)) {
+        cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
+    }
     /* clear exit_info_2 so we behave like the real hardware */
     x86_stq_phys(cs,
              env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 0);
 
-    cpu_x86_update_cr0(env, x86_ldq_phys(cs,
-                                     env->vm_vmcb + offsetof(struct vmcb,
-                                                             save.cr0)));
+    cpu_x86_update_cr0(env, new_cr0);
     cpu_x86_update_cr4(env, x86_ldq_phys(cs,
                                      env->vm_vmcb + offsetof(struct vmcb,
                                                              save.cr4)));
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 37/45] target/i386: Added Intercept CR0 writes check
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (35 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 36/45] target/i386: Added consistency checks for CR0 Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 38/45] configure: Use -std=gnu11 Paolo Bonzini
                   ` (9 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Lara Lazier

From: Lara Lazier <laramglazier@gmail.com>

When the selective CR0 write intercept is set, all writes to bits in
CR0 other than CR0.TS or CR0.MP cause a VMEXIT.

Signed-off-by: Lara Lazier <laramglazier@gmail.com>
Message-Id: <20210616123907.17765-5-laramglazier@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/tcg/sysemu/misc_helper.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/target/i386/tcg/sysemu/misc_helper.c b/target/i386/tcg/sysemu/misc_helper.c
index 0cef2f1a4c..db0d8a9d79 100644
--- a/target/i386/tcg/sysemu/misc_helper.c
+++ b/target/i386/tcg/sysemu/misc_helper.c
@@ -84,6 +84,15 @@ void helper_write_crN(CPUX86State *env, int reg, target_ulong t0)
 {
     switch (reg) {
     case 0:
+        /*
+        * If we reach this point, the CR0 write intercept is disabled.
+        * But we could still exit if the hypervisor has requested the selective
+        * intercept for bits other than TS and MP
+        */
+        if (cpu_svm_has_intercept(env, SVM_EXIT_CR0_SEL_WRITE) &&
+            ((env->cr[0] ^ t0) & ~(CR0_TS_MASK | CR0_MP_MASK))) {
+            cpu_vmexit(env, SVM_EXIT_CR0_SEL_WRITE, 0, GETPC());
+        }
         cpu_x86_update_cr0(env, t0);
         break;
     case 3:
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 38/45] configure: Use -std=gnu11
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (36 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 37/45] target/i386: Added Intercept CR0 writes check Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 39/45] softfloat: Use _Generic instead of QEMU_GENERIC Paolo Bonzini
                   ` (8 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alex Bennée, Thomas Huth, Richard Henderson,
	Philippe Mathieu-Daudé

From: Richard Henderson <richard.henderson@linaro.org>

Now that the minimum gcc version is 7.5, we can use C11.
This will allow lots of cleanups to the code, currently
hidden behind macros in include/qemu/compiler.h.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20210614233143.1221879-2-richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 configure   | 4 ++--
 meson.build | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/configure b/configure
index 4478f3889a..ebc016111a 100755
--- a/configure
+++ b/configure
@@ -159,7 +159,7 @@ update_cxxflags() {
     # options which some versions of GCC's C++ compiler complain about
     # because they only make sense for C programs.
     QEMU_CXXFLAGS="$QEMU_CXXFLAGS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS"
-    CONFIGURE_CXXFLAGS=$(echo "$CONFIGURE_CFLAGS" | sed s/-std=gnu99/-std=gnu++11/)
+    CONFIGURE_CXXFLAGS=$(echo "$CONFIGURE_CFLAGS" | sed s/-std=gnu11/-std=gnu++11/)
     for arg in $QEMU_CFLAGS; do
         case $arg in
             -Wstrict-prototypes|-Wmissing-prototypes|-Wnested-externs|\
@@ -538,7 +538,7 @@ QEMU_CFLAGS="-Wstrict-prototypes -Wredundant-decls $QEMU_CFLAGS"
 QEMU_CFLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE $QEMU_CFLAGS"
 
 # Flags that are needed during configure but later taken care of by Meson
-CONFIGURE_CFLAGS="-std=gnu99 -Wall"
+CONFIGURE_CFLAGS="-std=gnu11 -Wall"
 CONFIGURE_LDFLAGS=
 
 
diff --git a/meson.build b/meson.build
index a2311eda6e..d8a92666fb 100644
--- a/meson.build
+++ b/meson.build
@@ -1,5 +1,5 @@
 project('qemu', ['c'], meson_version: '>=0.55.0',
-        default_options: ['warning_level=1', 'c_std=gnu99', 'cpp_std=gnu++11', 'b_colorout=auto'] +
+        default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto'] +
                          (meson.version().version_compare('>=0.56.0') ? [ 'b_staticpic=false' ] : []),
         version: run_command('head', meson.source_root() / 'VERSION').stdout().strip())
 
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 39/45] softfloat: Use _Generic instead of QEMU_GENERIC
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (37 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 38/45] configure: Use -std=gnu11 Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 40/45] util: Use real functions for thread-posix QemuRecMutex Paolo Bonzini
                   ` (7 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alex Bennée, Thomas Huth, Richard Henderson

From: Richard Henderson <richard.henderson@linaro.org>

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20210614233143.1221879-3-richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 fpu/softfloat.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 4d0160fe9c..6e769f990c 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -686,11 +686,13 @@ static float128 float128_pack_raw(const FloatParts128 *p)
 #include "softfloat-specialize.c.inc"
 
 #define PARTS_GENERIC_64_128(NAME, P) \
-    QEMU_GENERIC(P, (FloatParts128 *, parts128_##NAME), parts64_##NAME)
+    _Generic((P), FloatParts64 *: parts64_##NAME, \
+                  FloatParts128 *: parts128_##NAME)
 
 #define PARTS_GENERIC_64_128_256(NAME, P) \
-    QEMU_GENERIC(P, (FloatParts256 *, parts256_##NAME), \
-                 (FloatParts128 *, parts128_##NAME), parts64_##NAME)
+    _Generic((P), FloatParts64 *: parts64_##NAME, \
+                  FloatParts128 *: parts128_##NAME, \
+                  FloatParts256 *: parts256_##NAME)
 
 #define parts_default_nan(P, S)    PARTS_GENERIC_64_128(default_nan, P)(P, S)
 #define parts_silence_nan(P, S)    PARTS_GENERIC_64_128(silence_nan, P)(P, S)
@@ -892,11 +894,13 @@ static void parts128_log2(FloatParts128 *a, float_status *s, const FloatFmt *f);
  */
 
 #define FRAC_GENERIC_64_128(NAME, P) \
-    QEMU_GENERIC(P, (FloatParts128 *, frac128_##NAME), frac64_##NAME)
+    _Generic((P), FloatParts64 *: frac64_##NAME, \
+                  FloatParts128 *: frac128_##NAME)
 
 #define FRAC_GENERIC_64_128_256(NAME, P) \
-    QEMU_GENERIC(P, (FloatParts256 *, frac256_##NAME), \
-                 (FloatParts128 *, frac128_##NAME), frac64_##NAME)
+    _Generic((P), FloatParts64 *: frac64_##NAME, \
+                  FloatParts128 *: frac128_##NAME, \
+                  FloatParts256 *: frac256_##NAME)
 
 static bool frac64_add(FloatParts64 *r, FloatParts64 *a, FloatParts64 *b)
 {
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 40/45] util: Use real functions for thread-posix QemuRecMutex
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (38 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 39/45] softfloat: Use _Generic instead of QEMU_GENERIC Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 41/45] util: Pass file+line to qemu_rec_mutex_unlock_impl Paolo Bonzini
                   ` (6 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alex Bennée, Thomas Huth, Richard Henderson

From: Richard Henderson <richard.henderson@linaro.org>

Move the declarations from thread-win32.h into thread.h
and remove the macro redirection from thread-posix.h.
This will be required by following cleanups.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20210614233143.1221879-4-richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/thread-posix.h |  4 ----
 include/qemu/thread-win32.h |  6 ------
 include/qemu/thread.h       |  9 ++++++---
 util/qemu-thread-posix.c    | 20 ++++++++++++++++++++
 4 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/include/qemu/thread-posix.h b/include/qemu/thread-posix.h
index c903525062..cf8bc90468 100644
--- a/include/qemu/thread-posix.h
+++ b/include/qemu/thread-posix.h
@@ -5,10 +5,6 @@
 #include <semaphore.h>
 
 typedef QemuMutex QemuRecMutex;
-#define qemu_rec_mutex_destroy qemu_mutex_destroy
-#define qemu_rec_mutex_lock_impl    qemu_mutex_lock_impl
-#define qemu_rec_mutex_trylock_impl qemu_mutex_trylock_impl
-#define qemu_rec_mutex_unlock qemu_mutex_unlock
 
 struct QemuMutex {
     pthread_mutex_t lock;
diff --git a/include/qemu/thread-win32.h b/include/qemu/thread-win32.h
index d0a1a9597e..d95af4498f 100644
--- a/include/qemu/thread-win32.h
+++ b/include/qemu/thread-win32.h
@@ -18,12 +18,6 @@ struct QemuRecMutex {
     bool initialized;
 };
 
-void qemu_rec_mutex_destroy(QemuRecMutex *mutex);
-void qemu_rec_mutex_lock_impl(QemuRecMutex *mutex, const char *file, int line);
-int qemu_rec_mutex_trylock_impl(QemuRecMutex *mutex, const char *file,
-                                int line);
-void qemu_rec_mutex_unlock(QemuRecMutex *mutex);
-
 struct QemuCond {
     CONDITION_VARIABLE var;
     bool initialized;
diff --git a/include/qemu/thread.h b/include/qemu/thread.h
index 5435763184..2c0d85f3bc 100644
--- a/include/qemu/thread.h
+++ b/include/qemu/thread.h
@@ -28,6 +28,12 @@ int qemu_mutex_trylock_impl(QemuMutex *mutex, const char *file, const int line);
 void qemu_mutex_lock_impl(QemuMutex *mutex, const char *file, const int line);
 void qemu_mutex_unlock_impl(QemuMutex *mutex, const char *file, const int line);
 
+void qemu_rec_mutex_init(QemuRecMutex *mutex);
+void qemu_rec_mutex_destroy(QemuRecMutex *mutex);
+void qemu_rec_mutex_lock_impl(QemuRecMutex *mutex, const char *file, int line);
+int qemu_rec_mutex_trylock_impl(QemuRecMutex *mutex, const char *file, int line);
+void qemu_rec_mutex_unlock(QemuRecMutex *mutex);
+
 typedef void (*QemuMutexLockFunc)(QemuMutex *m, const char *f, int l);
 typedef int (*QemuMutexTrylockFunc)(QemuMutex *m, const char *f, int l);
 typedef void (*QemuRecMutexLockFunc)(QemuRecMutex *m, const char *f, int l);
@@ -129,9 +135,6 @@ static inline int (qemu_rec_mutex_trylock)(QemuRecMutex *mutex)
     return qemu_rec_mutex_trylock(mutex);
 }
 
-/* Prototypes for other functions are in thread-posix.h/thread-win32.h.  */
-void qemu_rec_mutex_init(QemuRecMutex *mutex);
-
 void qemu_cond_init(QemuCond *cond);
 void qemu_cond_destroy(QemuCond *cond);
 
diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c
index dcff5e7c5d..8e2b6653f5 100644
--- a/util/qemu-thread-posix.c
+++ b/util/qemu-thread-posix.c
@@ -124,6 +124,26 @@ void qemu_rec_mutex_init(QemuRecMutex *mutex)
     mutex->initialized = true;
 }
 
+void qemu_rec_mutex_destroy(QemuRecMutex *mutex)
+{
+    qemu_mutex_destroy(mutex);
+}
+
+void qemu_rec_mutex_lock_impl(QemuRecMutex *mutex, const char *file, int line)
+{
+    qemu_mutex_lock_impl(mutex, file, line);
+}
+
+int qemu_rec_mutex_trylock_impl(QemuRecMutex *mutex, const char *file, int line)
+{
+    return qemu_mutex_trylock_impl(mutex, file, line);
+}
+
+void qemu_rec_mutex_unlock(QemuRecMutex *mutex)
+{
+    qemu_mutex_unlock(mutex);
+}
+
 void qemu_cond_init(QemuCond *cond)
 {
     int err;
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 41/45] util: Pass file+line to qemu_rec_mutex_unlock_impl
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (39 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 40/45] util: Use real functions for thread-posix QemuRecMutex Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 42/45] util: Use unique type for QemuRecMutex in thread-posix.h Paolo Bonzini
                   ` (5 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Alex Bennée, Richard Henderson, Philippe Mathieu-Daudé

From: Richard Henderson <richard.henderson@linaro.org>

Create macros for file+line expansion in qemu_rec_mutex_unlock
like we have for qemu_mutex_unlock.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20210614233143.1221879-5-richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/thread.h    | 10 +++++++++-
 util/qemu-thread-posix.c |  4 ++--
 util/qemu-thread-win32.c |  2 +-
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/include/qemu/thread.h b/include/qemu/thread.h
index 2c0d85f3bc..460568d67d 100644
--- a/include/qemu/thread.h
+++ b/include/qemu/thread.h
@@ -32,7 +32,7 @@ void qemu_rec_mutex_init(QemuRecMutex *mutex);
 void qemu_rec_mutex_destroy(QemuRecMutex *mutex);
 void qemu_rec_mutex_lock_impl(QemuRecMutex *mutex, const char *file, int line);
 int qemu_rec_mutex_trylock_impl(QemuRecMutex *mutex, const char *file, int line);
-void qemu_rec_mutex_unlock(QemuRecMutex *mutex);
+void qemu_rec_mutex_unlock_impl(QemuRecMutex *mutex, const char *file, int line);
 
 typedef void (*QemuMutexLockFunc)(QemuMutex *m, const char *f, int l);
 typedef int (*QemuMutexTrylockFunc)(QemuMutex *m, const char *f, int l);
@@ -110,6 +110,9 @@ extern QemuCondTimedWaitFunc qemu_cond_timedwait_func;
 #define qemu_mutex_unlock(mutex) \
         qemu_mutex_unlock_impl(mutex, __FILE__, __LINE__)
 
+#define qemu_rec_mutex_unlock(mutex) \
+        qemu_rec_mutex_unlock_impl(mutex, __FILE__, __LINE__)
+
 static inline void (qemu_mutex_lock)(QemuMutex *mutex)
 {
     qemu_mutex_lock(mutex);
@@ -135,6 +138,11 @@ static inline int (qemu_rec_mutex_trylock)(QemuRecMutex *mutex)
     return qemu_rec_mutex_trylock(mutex);
 }
 
+static inline void (qemu_rec_mutex_unlock)(QemuRecMutex *mutex)
+{
+    qemu_rec_mutex_unlock(mutex);
+}
+
 void qemu_cond_init(QemuCond *cond);
 void qemu_cond_destroy(QemuCond *cond);
 
diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c
index 8e2b6653f5..d990826ed8 100644
--- a/util/qemu-thread-posix.c
+++ b/util/qemu-thread-posix.c
@@ -139,9 +139,9 @@ int qemu_rec_mutex_trylock_impl(QemuRecMutex *mutex, const char *file, int line)
     return qemu_mutex_trylock_impl(mutex, file, line);
 }
 
-void qemu_rec_mutex_unlock(QemuRecMutex *mutex)
+void qemu_rec_mutex_unlock_impl(QemuRecMutex *mutex, const char *file, int line)
 {
-    qemu_mutex_unlock(mutex);
+    qemu_mutex_unlock_impl(mutex, file, line);
 }
 
 void qemu_cond_init(QemuCond *cond)
diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c
index cb5aa2018c..52eb19f351 100644
--- a/util/qemu-thread-win32.c
+++ b/util/qemu-thread-win32.c
@@ -105,7 +105,7 @@ int qemu_rec_mutex_trylock_impl(QemuRecMutex *mutex, const char *file, int line)
     return !TryEnterCriticalSection(&mutex->lock);
 }
 
-void qemu_rec_mutex_unlock(QemuRecMutex *mutex)
+void qemu_rec_mutex_unlock_impl(QemuRecMutex *mutex, const char *file, int line)
 {
     assert(mutex->initialized);
     LeaveCriticalSection(&mutex->lock);
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 42/45] util: Use unique type for QemuRecMutex in thread-posix.h
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (40 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 41/45] util: Pass file+line to qemu_rec_mutex_unlock_impl Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 43/45] include/qemu/lockable: Use _Generic instead of QEMU_GENERIC Paolo Bonzini
                   ` (4 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alex Bennée, Thomas Huth, Richard Henderson

From: Richard Henderson <richard.henderson@linaro.org>

We will shortly convert lockable.h to _Generic, and we cannot
have two compatible types in the same expansion.  Wrap QemuMutex
in a struct, and unwrap in qemu-thread-posix.c.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20210614233143.1221879-6-richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/thread-posix.h | 10 ++++++++--
 util/qemu-thread-posix.c    | 12 ++++++------
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/include/qemu/thread-posix.h b/include/qemu/thread-posix.h
index cf8bc90468..b792e6ef37 100644
--- a/include/qemu/thread-posix.h
+++ b/include/qemu/thread-posix.h
@@ -4,8 +4,6 @@
 #include <pthread.h>
 #include <semaphore.h>
 
-typedef QemuMutex QemuRecMutex;
-
 struct QemuMutex {
     pthread_mutex_t lock;
 #ifdef CONFIG_DEBUG_MUTEX
@@ -15,6 +13,14 @@ struct QemuMutex {
     bool initialized;
 };
 
+/*
+ * QemuRecMutex cannot be a typedef of QemuMutex lest we have two
+ * compatible cases in _Generic.  See qemu/lockable.h.
+ */
+typedef struct QemuRecMutex {
+    QemuMutex m;
+} QemuRecMutex;
+
 struct QemuCond {
     pthread_cond_t cond;
     bool initialized;
diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c
index d990826ed8..fd9d714038 100644
--- a/util/qemu-thread-posix.c
+++ b/util/qemu-thread-posix.c
@@ -116,32 +116,32 @@ void qemu_rec_mutex_init(QemuRecMutex *mutex)
 
     pthread_mutexattr_init(&attr);
     pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-    err = pthread_mutex_init(&mutex->lock, &attr);
+    err = pthread_mutex_init(&mutex->m.lock, &attr);
     pthread_mutexattr_destroy(&attr);
     if (err) {
         error_exit(err, __func__);
     }
-    mutex->initialized = true;
+    mutex->m.initialized = true;
 }
 
 void qemu_rec_mutex_destroy(QemuRecMutex *mutex)
 {
-    qemu_mutex_destroy(mutex);
+    qemu_mutex_destroy(&mutex->m);
 }
 
 void qemu_rec_mutex_lock_impl(QemuRecMutex *mutex, const char *file, int line)
 {
-    qemu_mutex_lock_impl(mutex, file, line);
+    qemu_mutex_lock_impl(&mutex->m, file, line);
 }
 
 int qemu_rec_mutex_trylock_impl(QemuRecMutex *mutex, const char *file, int line)
 {
-    return qemu_mutex_trylock_impl(mutex, file, line);
+    return qemu_mutex_trylock_impl(&mutex->m, file, line);
 }
 
 void qemu_rec_mutex_unlock_impl(QemuRecMutex *mutex, const char *file, int line)
 {
-    qemu_mutex_unlock_impl(mutex, file, line);
+    qemu_mutex_unlock_impl(&mutex->m, file, line);
 }
 
 void qemu_cond_init(QemuCond *cond)
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 43/45] include/qemu/lockable: Use _Generic instead of QEMU_GENERIC
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (41 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 42/45] util: Use unique type for QemuRecMutex in thread-posix.h Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 44/45] qemu/compiler: Remove QEMU_GENERIC Paolo Bonzini
                   ` (3 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alex Bennée, Richard Henderson

From: Richard Henderson <richard.henderson@linaro.org>

This is both more and less complicated than our expansion
using __builtin_choose_expr and __builtin_types_compatible_p.

The expansion through QEMU_MAKE_LOCKABLE_ doesn't work because
we're not emumerating all of the types within the same _Generic,
which results in errors about unhandled cases.  We must also
handle void* explicitly, so that the NULL constant can be used.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20210614233143.1221879-7-richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/lockable.h | 90 +++++++++++++++++++----------------------
 1 file changed, 41 insertions(+), 49 deletions(-)

diff --git a/include/qemu/lockable.h b/include/qemu/lockable.h
index b620023141..86db7cb04c 100644
--- a/include/qemu/lockable.h
+++ b/include/qemu/lockable.h
@@ -24,79 +24,71 @@ struct QemuLockable {
     QemuLockUnlockFunc *unlock;
 };
 
-/* This function gives an error if an invalid, non-NULL pointer type is passed
- * to QEMU_MAKE_LOCKABLE.  For optimized builds, we can rely on dead-code elimination
- * from the compiler, and give the errors already at link time.
- */
-#if defined(__OPTIMIZE__) && !defined(__SANITIZE_ADDRESS__)
-void unknown_lock_type(void *);
-#else
-static inline void unknown_lock_type(void *unused)
-{
-    abort();
-}
-#endif
-
 static inline __attribute__((__always_inline__)) QemuLockable *
 qemu_make_lockable(void *x, QemuLockable *lockable)
 {
-    /* We cannot test this in a macro, otherwise we get compiler
+    /*
+     * We cannot test this in a macro, otherwise we get compiler
      * warnings like "the address of 'm' will always evaluate as 'true'".
      */
     return x ? lockable : NULL;
 }
 
-/* Auxiliary macros to simplify QEMU_MAKE_LOCABLE.  */
-#define QEMU_LOCK_FUNC(x) ((QemuLockUnlockFunc *)    \
-    QEMU_GENERIC(x,                                  \
-                 (QemuMutex *, qemu_mutex_lock),     \
-                 (QemuRecMutex *, qemu_rec_mutex_lock), \
-                 (CoMutex *, qemu_co_mutex_lock),    \
-                 (QemuSpin *, qemu_spin_lock),       \
-                 unknown_lock_type))
+static inline __attribute__((__always_inline__)) QemuLockable *
+qemu_null_lockable(void *x)
+{
+    if (x != NULL) {
+        qemu_build_not_reached();
+    }
+    return NULL;
+}
 
-#define QEMU_UNLOCK_FUNC(x) ((QemuLockUnlockFunc *)  \
-    QEMU_GENERIC(x,                                  \
-                 (QemuMutex *, qemu_mutex_unlock),   \
-                 (QemuRecMutex *, qemu_rec_mutex_unlock), \
-                 (CoMutex *, qemu_co_mutex_unlock),  \
-                 (QemuSpin *, qemu_spin_unlock),     \
-                 unknown_lock_type))
-
-/* In C, compound literals have the lifetime of an automatic variable.
+/*
+ * In C, compound literals have the lifetime of an automatic variable.
  * In C++ it would be different, but then C++ wouldn't need QemuLockable
  * either...
  */
-#define QEMU_MAKE_LOCKABLE_(x) (&(QemuLockable) {     \
-        .object = (x),                               \
-        .lock = QEMU_LOCK_FUNC(x),                   \
-        .unlock = QEMU_UNLOCK_FUNC(x),               \
+#define QML_OBJ_(x, name) (&(QemuLockable) {                            \
+        .object = (x),                                                  \
+        .lock = (QemuLockUnlockFunc *) qemu_ ## name ## _lock,          \
+        .unlock = (QemuLockUnlockFunc *) qemu_ ## name ## _unlock       \
     })
 
-/* QEMU_MAKE_LOCKABLE - Make a polymorphic QemuLockable
+/**
+ * QEMU_MAKE_LOCKABLE - Make a polymorphic QemuLockable
  *
- * @x: a lock object (currently one of QemuMutex, QemuRecMutex, CoMutex, QemuSpin).
+ * @x: a lock object (currently one of QemuMutex, QemuRecMutex,
+ *     CoMutex, QemuSpin).
  *
  * Returns a QemuLockable object that can be passed around
  * to a function that can operate with locks of any kind, or
  * NULL if @x is %NULL.
- */
-#define QEMU_MAKE_LOCKABLE(x)                        \
-    QEMU_GENERIC(x,                                  \
-                 (QemuLockable *, (x)),              \
-                 qemu_make_lockable((x), QEMU_MAKE_LOCKABLE_(x)))
-
-/* QEMU_MAKE_LOCKABLE_NONNULL - Make a polymorphic QemuLockable
  *
- * @x: a lock object (currently one of QemuMutex, QemuRecMutex, CoMutex, QemuSpin).
+ * Note the special case for void *, so that we may pass "NULL".
+ */
+#define QEMU_MAKE_LOCKABLE(x)                                           \
+    _Generic((x), QemuLockable *: (x),                                  \
+             void *: qemu_null_lockable(x),                             \
+             QemuMutex *: qemu_make_lockable(x, QML_OBJ_(x, mutex)),    \
+             QemuRecMutex *: qemu_make_lockable(x, QML_OBJ_(x, rec_mutex)), \
+             CoMutex *: qemu_make_lockable(x, QML_OBJ_(x, co_mutex)),   \
+             QemuSpin *: qemu_make_lockable(x, QML_OBJ_(x, spin)))
+
+/**
+ * QEMU_MAKE_LOCKABLE_NONNULL - Make a polymorphic QemuLockable
+ *
+ * @x: a lock object (currently one of QemuMutex, QemuRecMutex,
+ *     CoMutex, QemuSpin).
  *
  * Returns a QemuLockable object that can be passed around
  * to a function that can operate with locks of any kind.
  */
-#define QEMU_MAKE_LOCKABLE_NONNULL(x)                \
-    QEMU_GENERIC(x,                                  \
-                 (QemuLockable *, (x)),              \
-                 QEMU_MAKE_LOCKABLE_(x))
+#define QEMU_MAKE_LOCKABLE_NONNULL(x)                           \
+    _Generic((x), QemuLockable *: (x),                          \
+                  QemuMutex *: QML_OBJ_(x, mutex),              \
+                  QemuRecMutex *: QML_OBJ_(x, rec_mutex),       \
+                  CoMutex *: QML_OBJ_(x, co_mutex),             \
+                  QemuSpin *: QML_OBJ_(x, spin))
 
 static inline void qemu_lockable_lock(QemuLockable *x)
 {
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 44/45] qemu/compiler: Remove QEMU_GENERIC
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (42 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 43/45] include/qemu/lockable: Use _Generic instead of QEMU_GENERIC Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17  9:31 ` [PULL 45/45] configure: Remove probe for _Static_assert Paolo Bonzini
                   ` (2 subsequent siblings)
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alex Bennée, Richard Henderson

From: Richard Henderson <richard.henderson@linaro.org>

All previous users now use C11 _Generic.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20210614233143.1221879-8-richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/compiler.h | 40 ----------------------------------------
 1 file changed, 40 deletions(-)

diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h
index 091c45248b..5766d61589 100644
--- a/include/qemu/compiler.h
+++ b/include/qemu/compiler.h
@@ -173,46 +173,6 @@
 #define QEMU_ALWAYS_INLINE
 #endif
 
-/* Implement C11 _Generic via GCC builtins.  Example:
- *
- *    QEMU_GENERIC(x, (float, sinf), (long double, sinl), sin) (x)
- *
- * The first argument is the discriminator.  The last is the default value.
- * The middle ones are tuples in "(type, expansion)" format.
- */
-
-/* First, find out the number of generic cases.  */
-#define QEMU_GENERIC(x, ...) \
-    QEMU_GENERIC_(typeof(x), __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
-
-/* There will be extra arguments, but they are not used.  */
-#define QEMU_GENERIC_(x, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, count, ...) \
-    QEMU_GENERIC##count(x, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)
-
-/* Two more helper macros, this time to extract items from a parenthesized
- * list.
- */
-#define QEMU_FIRST_(a, b) a
-#define QEMU_SECOND_(a, b) b
-
-/* ... and a final one for the common part of the "recursion".  */
-#define QEMU_GENERIC_IF(x, type_then, else_)                                   \
-    __builtin_choose_expr(__builtin_types_compatible_p(x,                      \
-                                                       QEMU_FIRST_ type_then), \
-                          QEMU_SECOND_ type_then, else_)
-
-/* CPP poor man's "recursion".  */
-#define QEMU_GENERIC1(x, a0, ...) (a0)
-#define QEMU_GENERIC2(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC1(x, __VA_ARGS__))
-#define QEMU_GENERIC3(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC2(x, __VA_ARGS__))
-#define QEMU_GENERIC4(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC3(x, __VA_ARGS__))
-#define QEMU_GENERIC5(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC4(x, __VA_ARGS__))
-#define QEMU_GENERIC6(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC5(x, __VA_ARGS__))
-#define QEMU_GENERIC7(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC6(x, __VA_ARGS__))
-#define QEMU_GENERIC8(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC7(x, __VA_ARGS__))
-#define QEMU_GENERIC9(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC8(x, __VA_ARGS__))
-#define QEMU_GENERIC10(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC9(x, __VA_ARGS__))
-
 /**
  * qemu_build_not_reached()
  *
-- 
2.31.1




^ permalink raw reply related	[flat|nested] 48+ messages in thread

* [PULL 45/45] configure: Remove probe for _Static_assert
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (43 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 44/45] qemu/compiler: Remove QEMU_GENERIC Paolo Bonzini
@ 2021-06-17  9:31 ` Paolo Bonzini
  2021-06-17 10:21 ` [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 no-reply
  2021-06-18  8:53 ` Peter Maydell
  46 siblings, 0 replies; 48+ messages in thread
From: Paolo Bonzini @ 2021-06-17  9:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alex Bennée, Thomas Huth, Richard Henderson

From: Richard Henderson <richard.henderson@linaro.org>

_Static_assert is part of C11, which is now required.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20210614233143.1221879-9-richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 configure               | 18 ------------------
 include/qemu/compiler.h | 11 -----------
 2 files changed, 29 deletions(-)

diff --git a/configure b/configure
index ebc016111a..262ab71802 100755
--- a/configure
+++ b/configure
@@ -5090,20 +5090,6 @@ if compile_prog "" "" ; then
     have_sysmacros=yes
 fi
 
-##########################################
-# check for _Static_assert()
-
-have_static_assert=no
-cat > $TMPC << EOF
-_Static_assert(1, "success");
-int main(void) {
-    return 0;
-}
-EOF
-if compile_prog "" "" ; then
-    have_static_assert=yes
-fi
-
 ##########################################
 # check for utmpx.h, it is missing e.g. on OpenBSD
 
@@ -6035,10 +6021,6 @@ if test "$have_sysmacros" = "yes" ; then
   echo "CONFIG_SYSMACROS=y" >> $config_host_mak
 fi
 
-if test "$have_static_assert" = "yes" ; then
-  echo "CONFIG_STATIC_ASSERT=y" >> $config_host_mak
-fi
-
 if test "$have_utmpx" = "yes" ; then
   echo "HAVE_UTMPX=y" >> $config_host_mak
 fi
diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h
index 5766d61589..3baa5e3790 100644
--- a/include/qemu/compiler.h
+++ b/include/qemu/compiler.h
@@ -72,18 +72,7 @@
         int:(x) ? -1 : 1; \
     }
 
-/* QEMU_BUILD_BUG_MSG() emits the message given if _Static_assert is
- * supported; otherwise, it will be omitted from the compiler error
- * message (but as it remains present in the source code, it can still
- * be useful when debugging). */
-#if defined(CONFIG_STATIC_ASSERT)
 #define QEMU_BUILD_BUG_MSG(x, msg) _Static_assert(!(x), msg)
-#elif defined(__COUNTER__)
-#define QEMU_BUILD_BUG_MSG(x, msg) typedef QEMU_BUILD_BUG_ON_STRUCT(x) \
-    glue(qemu_build_bug_on__, __COUNTER__) __attribute__((unused))
-#else
-#define QEMU_BUILD_BUG_MSG(x, msg)
-#endif
 
 #define QEMU_BUILD_BUG_ON(x) QEMU_BUILD_BUG_MSG(x, "not expecting: " #x)
 
-- 
2.31.1



^ permalink raw reply related	[flat|nested] 48+ messages in thread

* Re: [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (44 preceding siblings ...)
  2021-06-17  9:31 ` [PULL 45/45] configure: Remove probe for _Static_assert Paolo Bonzini
@ 2021-06-17 10:21 ` no-reply
  2021-06-18  8:53 ` Peter Maydell
  46 siblings, 0 replies; 48+ messages in thread
From: no-reply @ 2021-06-17 10:21 UTC (permalink / raw)
  To: pbonzini; +Cc: qemu-devel

Patchew URL: https://patchew.org/QEMU/20210617093134.900014-1-pbonzini@redhat.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20210617093134.900014-1-pbonzini@redhat.com
Subject: [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]         patchew/20210617093134.900014-1-pbonzini@redhat.com -> patchew/20210617093134.900014-1-pbonzini@redhat.com
Switched to a new branch 'test'
76c1d1c configure: Remove probe for _Static_assert
bb7b711 qemu/compiler: Remove QEMU_GENERIC
bb5b937 include/qemu/lockable: Use _Generic instead of QEMU_GENERIC
f12590d util: Use unique type for QemuRecMutex in thread-posix.h
bad1bfa util: Pass file+line to qemu_rec_mutex_unlock_impl
cce4c5d util: Use real functions for thread-posix QemuRecMutex
bc05aa3 softfloat: Use _Generic instead of QEMU_GENERIC
f09e1b8 configure: Use -std=gnu11
e3dddf2 target/i386: Added Intercept CR0 writes check
0d849e8 target/i386: Added consistency checks for CR0
76dcd43 target/i386: Added consistency checks for VMRUN intercept and ASID
567459b target/i386: Refactored intercept checks into cpu_svm_has_intercept
b4e527e configure: map x32 to cpu_family x86_64 for meson
8163813 hmp: Print "reserve" property of memory backends with "info memdev"
567770f qmp: Include "reserve" property of memory backends
0512c46 hmp: Print "share" property of memory backends with "info memdev"
11f6aaf qmp: Include "share" property of memory backends
f2bf2ce qmp: Clarify memory backend properties returned via query-memdev
f4a1776 hostmem: Wire up RAM_NORESERVE via "reserve" property
16cee78 util/mmap-alloc: Support RAM_NORESERVE via MAP_NORESERVE under Linux
adf9a93 memory: Introduce RAM_NORESERVE and wire it up in qemu_ram_mmap()
1b69bfd util/mmap-alloc: Pass flags instead of separate bools to qemu_ram_mmap()
a527698 softmmu/memory: Pass ram_flags to qemu_ram_alloc() and qemu_ram_alloc_internal()
4f00790 softmmu/memory: Pass ram_flags to memory_region_init_ram_shared_nomigrate()
5289155 softmmu/memory: Pass ram_flags to qemu_ram_alloc_from_fd()
8edf57d util/mmap-alloc: Factor out activating of memory to mmap_activate()
991926b util/mmap-alloc: Factor out reserving of a memory region to mmap_reserve()
c3819fc util/mmap-alloc: Factor out calculation of the pagesize for the guard page
917d149 softmmu/physmem: Fix qemu_ram_remap() to handle shared anonymous memory
9e6a704 softmmu/physmem: Fix ram_block_discard_range() to handle shared anonymous memory
2a1a5ba softmmu/physmem: Mark shared anonymous memory RAM_SHARED
f0c8ef8 esp: store lun coming from the MESSAGE OUT phase
689f708 esp: fix migration version check in esp_is_version_5()
d2adf20 esp: correctly accumulate extended messages for PDMA
26a1d08 esp: revert 75ef849696 "esp: correctly fill bus id with requested lun"
d48286b esp: ensure PDMA write transfers are flushed from the FIFO to the target immediately
195cadb esp: handle non-DMA transfers from the target one byte at a time
cbd0dea esp: allow non-DMA callback in esp_transfer_data() initial transfer
6c54d24 esp: only set ESP_RSEQ at the start of the select sequence
1567f98 esp: only assert INTR_DC interrupt flag if selection fails
2bedf0a runstate: Initialize Error * to NULL
51adfa2 block/scsi: correctly emulate the VPD block limits page
72a6110 qemu-config: use qemu_opts_from_qdict
0c0076a vl: Fix an assert failure in error path
f427609 vnc: avoid deprecation warnings for SASL on OS X

=== OUTPUT BEGIN ===
1/45 Checking commit f42760961c6d (vnc: avoid deprecation warnings for SASL on OS X)
2/45 Checking commit 0c0076a4935e (vl: Fix an assert failure in error path)
3/45 Checking commit 72a6110a41c2 (qemu-config: use qemu_opts_from_qdict)
4/45 Checking commit 51adfa2fb1de (block/scsi: correctly emulate the VPD block limits page)
5/45 Checking commit 2bedf0a004fd (runstate: Initialize Error * to NULL)
6/45 Checking commit 1567f98b866c (esp: only assert INTR_DC interrupt flag if selection fails)
7/45 Checking commit 6c54d2493304 (esp: only set ESP_RSEQ at the start of the select sequence)
8/45 Checking commit cbd0deae8cff (esp: allow non-DMA callback in esp_transfer_data() initial transfer)
9/45 Checking commit 195cadbab65e (esp: handle non-DMA transfers from the target one byte at a time)
10/45 Checking commit d48286bd0534 (esp: ensure PDMA write transfers are flushed from the FIFO to the target immediately)
11/45 Checking commit 26a1d08d933f (esp: revert 75ef849696 "esp: correctly fill bus id with requested lun")
12/45 Checking commit d2adf20b0668 (esp: correctly accumulate extended messages for PDMA)
13/45 Checking commit 689f70888315 (esp: fix migration version check in esp_is_version_5())
14/45 Checking commit f0c8ef85d8c3 (esp: store lun coming from the MESSAGE OUT phase)
15/45 Checking commit 2a1a5ba6a929 (softmmu/physmem: Mark shared anonymous memory RAM_SHARED)
16/45 Checking commit 9e6a70412da8 (softmmu/physmem: Fix ram_block_discard_range() to handle shared anonymous memory)
17/45 Checking commit 917d1492b37c (softmmu/physmem: Fix qemu_ram_remap() to handle shared anonymous memory)
18/45 Checking commit c3819fc58a75 (util/mmap-alloc: Factor out calculation of the pagesize for the guard page)
WARNING: architecture specific defines should be avoided
#33: FILE: util/mmap-alloc.c:87:
+#if defined(__powerpc64__) && defined(__linux__)

total: 0 errors, 1 warnings, 79 lines checked

Patch 18/45 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
19/45 Checking commit 991926bca089 (util/mmap-alloc: Factor out reserving of a memory region to mmap_reserve())
WARNING: architecture specific defines should be avoided
#39: FILE: util/mmap-alloc.c:93:
+#if defined(__powerpc64__) && defined(__linux__)

total: 0 errors, 1 warnings, 76 lines checked

Patch 19/45 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
20/45 Checking commit 8edf57d883b5 (util/mmap-alloc: Factor out activating of memory to mmap_activate())
21/45 Checking commit 5289155a8882 (softmmu/memory: Pass ram_flags to qemu_ram_alloc_from_fd())
22/45 Checking commit 4f0079014b3d (softmmu/memory: Pass ram_flags to memory_region_init_ram_shared_nomigrate())
23/45 Checking commit a52769898b3e (softmmu/memory: Pass ram_flags to qemu_ram_alloc() and qemu_ram_alloc_internal())
24/45 Checking commit 1b69bfd71a31 (util/mmap-alloc: Pass flags instead of separate bools to qemu_ram_mmap())
25/45 Checking commit adf9a9329811 (memory: Introduce RAM_NORESERVE and wire it up in qemu_ram_mmap())
26/45 Checking commit 16cee789337c (util/mmap-alloc: Support RAM_NORESERVE via MAP_NORESERVE under Linux)
WARNING: architecture specific defines should be avoided
#113: FILE: util/mmap-alloc.c:90:
+#if defined(__linux__)

total: 0 errors, 1 warnings, 108 lines checked

Patch 26/45 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
27/45 Checking commit f4a1776bf512 (hostmem: Wire up RAM_NORESERVE via "reserve" property)
28/45 Checking commit f2bf2cec1eca (qmp: Clarify memory backend properties returned via query-memdev)
29/45 Checking commit 11f6aaf8fa96 (qmp: Include "share" property of memory backends)
30/45 Checking commit 0512c4667293 (hmp: Print "share" property of memory backends with "info memdev")
31/45 Checking commit 567770f5834f (qmp: Include "reserve" property of memory backends)
32/45 Checking commit 8163813a3ee9 (hmp: Print "reserve" property of memory backends with "info memdev")
33/45 Checking commit b4e527ea0246 (configure: map x32 to cpu_family x86_64 for meson)
34/45 Checking commit 567459bb087d (target/i386: Refactored intercept checks into cpu_svm_has_intercept)
35/45 Checking commit 76dcd43c252c (target/i386: Added consistency checks for VMRUN intercept and ASID)
36/45 Checking commit 0d849e8b36ce (target/i386: Added consistency checks for CR0)
37/45 Checking commit e3dddf2cc81b (target/i386: Added Intercept CR0 writes check)
WARNING: Block comments should align the * on each line
#27: FILE: target/i386/tcg/sysemu/misc_helper.c:88:
+        /*
+        * If we reach this point, the CR0 write intercept is disabled.

total: 0 errors, 1 warnings, 15 lines checked

Patch 37/45 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
38/45 Checking commit f09e1b86bc08 (configure: Use -std=gnu11)
39/45 Checking commit bc05aa3683f2 (softfloat: Use _Generic instead of QEMU_GENERIC)
ERROR: spaces required around that '*' (ctx:WxO)
#26: FILE: fpu/softfloat.c:689:
+    _Generic((P), FloatParts64 *: parts64_##NAME, \
                                ^

ERROR: spaces required around that ':' (ctx:OxW)
#26: FILE: fpu/softfloat.c:689:
+    _Generic((P), FloatParts64 *: parts64_##NAME, \
                                 ^

ERROR: spaces required around that '*' (ctx:WxO)
#27: FILE: fpu/softfloat.c:690:
+                  FloatParts128 *: parts128_##NAME)
                                 ^

ERROR: spaces required around that ':' (ctx:OxW)
#27: FILE: fpu/softfloat.c:690:
+                  FloatParts128 *: parts128_##NAME)
                                  ^

ERROR: spaces required around that '*' (ctx:WxO)
#32: FILE: fpu/softfloat.c:693:
+    _Generic((P), FloatParts64 *: parts64_##NAME, \
                                ^

ERROR: spaces required around that ':' (ctx:OxW)
#32: FILE: fpu/softfloat.c:693:
+    _Generic((P), FloatParts64 *: parts64_##NAME, \
                                 ^

ERROR: spaces required around that '*' (ctx:WxO)
#33: FILE: fpu/softfloat.c:694:
+                  FloatParts128 *: parts128_##NAME, \
                                 ^

ERROR: spaces required around that ':' (ctx:OxW)
#33: FILE: fpu/softfloat.c:694:
+                  FloatParts128 *: parts128_##NAME, \
                                  ^

ERROR: spaces required around that '*' (ctx:WxO)
#34: FILE: fpu/softfloat.c:695:
+                  FloatParts256 *: parts256_##NAME)
                                 ^

ERROR: spaces required around that ':' (ctx:OxW)
#34: FILE: fpu/softfloat.c:695:
+                  FloatParts256 *: parts256_##NAME)
                                  ^

ERROR: spaces required around that '*' (ctx:WxO)
#43: FILE: fpu/softfloat.c:897:
+    _Generic((P), FloatParts64 *: frac64_##NAME, \
                                ^

ERROR: spaces required around that ':' (ctx:OxW)
#43: FILE: fpu/softfloat.c:897:
+    _Generic((P), FloatParts64 *: frac64_##NAME, \
                                 ^

ERROR: spaces required around that '*' (ctx:WxO)
#44: FILE: fpu/softfloat.c:898:
+                  FloatParts128 *: frac128_##NAME)
                                 ^

ERROR: spaces required around that ':' (ctx:OxW)
#44: FILE: fpu/softfloat.c:898:
+                  FloatParts128 *: frac128_##NAME)
                                  ^

ERROR: spaces required around that '*' (ctx:WxO)
#49: FILE: fpu/softfloat.c:901:
+    _Generic((P), FloatParts64 *: frac64_##NAME, \
                                ^

ERROR: spaces required around that ':' (ctx:OxW)
#49: FILE: fpu/softfloat.c:901:
+    _Generic((P), FloatParts64 *: frac64_##NAME, \
                                 ^

ERROR: spaces required around that '*' (ctx:WxO)
#50: FILE: fpu/softfloat.c:902:
+                  FloatParts128 *: frac128_##NAME, \
                                 ^

ERROR: spaces required around that ':' (ctx:OxW)
#50: FILE: fpu/softfloat.c:902:
+                  FloatParts128 *: frac128_##NAME, \
                                  ^

ERROR: spaces required around that '*' (ctx:WxO)
#51: FILE: fpu/softfloat.c:903:
+                  FloatParts256 *: frac256_##NAME)
                                 ^

ERROR: spaces required around that ':' (ctx:OxW)
#51: FILE: fpu/softfloat.c:903:
+                  FloatParts256 *: frac256_##NAME)
                                  ^

total: 20 errors, 0 warnings, 32 lines checked

Patch 39/45 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

40/45 Checking commit cce4c5d00991 (util: Use real functions for thread-posix QemuRecMutex)
WARNING: line over 80 characters
#67: FILE: include/qemu/thread.h:34:
+int qemu_rec_mutex_trylock_impl(QemuRecMutex *mutex, const char *file, int line);

total: 0 errors, 1 warnings, 69 lines checked

Patch 40/45 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
41/45 Checking commit bad1bfa87974 (util: Pass file+line to qemu_rec_mutex_unlock_impl)
WARNING: line over 80 characters
#31: FILE: include/qemu/thread.h:35:
+void qemu_rec_mutex_unlock_impl(QemuRecMutex *mutex, const char *file, int line);

total: 0 errors, 1 warnings, 47 lines checked

Patch 41/45 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
42/45 Checking commit f12590d5a5e1 (util: Use unique type for QemuRecMutex in thread-posix.h)
43/45 Checking commit bb5b9371bfe0 (include/qemu/lockable: Use _Generic instead of QEMU_GENERIC)
ERROR: spaces required around that '*' (ctx:WxO)
#121: FILE: include/qemu/lockable.h:70:
+    _Generic((x), QemuLockable *: (x),                                  \
                                ^

ERROR: spaces required around that ':' (ctx:OxW)
#121: FILE: include/qemu/lockable.h:70:
+    _Generic((x), QemuLockable *: (x),                                  \
                                 ^

ERROR: spaces required around that '*' (ctx:WxO)
#122: FILE: include/qemu/lockable.h:71:
+             void *: qemu_null_lockable(x),                             \
                   ^

ERROR: spaces required around that ':' (ctx:OxW)
#122: FILE: include/qemu/lockable.h:71:
+             void *: qemu_null_lockable(x),                             \
                    ^

ERROR: spaces required around that '*' (ctx:WxO)
#123: FILE: include/qemu/lockable.h:72:
+             QemuMutex *: qemu_make_lockable(x, QML_OBJ_(x, mutex)),    \
                        ^

ERROR: spaces required around that ':' (ctx:OxW)
#123: FILE: include/qemu/lockable.h:72:
+             QemuMutex *: qemu_make_lockable(x, QML_OBJ_(x, mutex)),    \
                         ^

ERROR: spaces required around that '*' (ctx:WxO)
#124: FILE: include/qemu/lockable.h:73:
+             QemuRecMutex *: qemu_make_lockable(x, QML_OBJ_(x, rec_mutex)), \
                           ^

ERROR: spaces required around that ':' (ctx:OxW)
#124: FILE: include/qemu/lockable.h:73:
+             QemuRecMutex *: qemu_make_lockable(x, QML_OBJ_(x, rec_mutex)), \
                            ^

ERROR: spaces required around that '*' (ctx:WxO)
#125: FILE: include/qemu/lockable.h:74:
+             CoMutex *: qemu_make_lockable(x, QML_OBJ_(x, co_mutex)),   \
                      ^

ERROR: spaces required around that ':' (ctx:OxW)
#125: FILE: include/qemu/lockable.h:74:
+             CoMutex *: qemu_make_lockable(x, QML_OBJ_(x, co_mutex)),   \
                       ^

ERROR: spaces required around that '*' (ctx:WxO)
#126: FILE: include/qemu/lockable.h:75:
+             QemuSpin *: qemu_make_lockable(x, QML_OBJ_(x, spin)))
                       ^

ERROR: spaces required around that ':' (ctx:OxW)
#126: FILE: include/qemu/lockable.h:75:
+             QemuSpin *: qemu_make_lockable(x, QML_OBJ_(x, spin)))
                        ^

ERROR: spaces required around that '*' (ctx:WxO)
#142: FILE: include/qemu/lockable.h:87:
+    _Generic((x), QemuLockable *: (x),                          \
                                ^

ERROR: spaces required around that ':' (ctx:OxW)
#142: FILE: include/qemu/lockable.h:87:
+    _Generic((x), QemuLockable *: (x),                          \
                                 ^

ERROR: spaces required around that '*' (ctx:WxO)
#143: FILE: include/qemu/lockable.h:88:
+                  QemuMutex *: QML_OBJ_(x, mutex),              \
                             ^

ERROR: spaces required around that ':' (ctx:OxW)
#143: FILE: include/qemu/lockable.h:88:
+                  QemuMutex *: QML_OBJ_(x, mutex),              \
                              ^

ERROR: spaces required around that '*' (ctx:WxO)
#144: FILE: include/qemu/lockable.h:89:
+                  QemuRecMutex *: QML_OBJ_(x, rec_mutex),       \
                                ^

ERROR: spaces required around that ':' (ctx:OxW)
#144: FILE: include/qemu/lockable.h:89:
+                  QemuRecMutex *: QML_OBJ_(x, rec_mutex),       \
                                 ^

ERROR: spaces required around that '*' (ctx:WxO)
#145: FILE: include/qemu/lockable.h:90:
+                  CoMutex *: QML_OBJ_(x, co_mutex),             \
                           ^

ERROR: spaces required around that ':' (ctx:OxW)
#145: FILE: include/qemu/lockable.h:90:
+                  CoMutex *: QML_OBJ_(x, co_mutex),             \
                            ^

ERROR: spaces required around that '*' (ctx:WxO)
#146: FILE: include/qemu/lockable.h:91:
+                  QemuSpin *: QML_OBJ_(x, spin))
                            ^

ERROR: spaces required around that ':' (ctx:OxW)
#146: FILE: include/qemu/lockable.h:91:
+                  QemuSpin *: QML_OBJ_(x, spin))
                             ^

total: 22 errors, 0 warnings, 120 lines checked

Patch 43/45 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

44/45 Checking commit bb7b711069b8 (qemu/compiler: Remove QEMU_GENERIC)
45/45 Checking commit 76c1d1c235e8 (configure: Remove probe for _Static_assert)
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20210617093134.900014-1-pbonzini@redhat.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17
  2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
                   ` (45 preceding siblings ...)
  2021-06-17 10:21 ` [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 no-reply
@ 2021-06-18  8:53 ` Peter Maydell
  46 siblings, 0 replies; 48+ messages in thread
From: Peter Maydell @ 2021-06-18  8:53 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: QEMU Developers

On Thu, 17 Jun 2021 at 10:36, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> The following changes since commit 1ea06abceec61b6f3ab33dadb0510b6e09fb61e2:
>
>   Merge remote-tracking branch 'remotes/berrange-gitlab/tags/misc-fixes-pull-request' into staging (2021-06-14 15:59:13 +0100)
>
> are available in the Git repository at:
>
>   https://gitlab.com/bonzini/qemu.git tags/for-upstream
>
> for you to fetch changes up to f51f8e3591393f7f274e1435ac22188e2dafdfe8:
>
>   configure: Remove probe for _Static_assert (2021-06-16 15:03:26 +0200)
>
> ----------------------------------------------------------------
> * avoid deprecation warnings for SASL on macOS 10.11 or newer
> * fix -readconfig when config blocks have an id (like [chardev "qmp"])
> * Error* initialization fixes
> * Improvements to ESP emulation (Mark)
> * Allow creating noreserve memory backends (David)
> * Improvements to query-memdev (David)
> * Bump compiler to C11 (Richard)
> * First round of SVM fixes from GSoC project (Lara)


Applied, thanks. (Richard sent his C11 set as a separate pull,
but git seems to have coped with the merge.)

Please update the changelog at https://wiki.qemu.org/ChangeLog/6.1
for any user-visible changes.

-- PMM


^ permalink raw reply	[flat|nested] 48+ messages in thread

end of thread, other threads:[~2021-06-18  8:56 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-17  9:30 [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 Paolo Bonzini
2021-06-17  9:30 ` [PULL 01/45] vnc: avoid deprecation warnings for SASL on OS X Paolo Bonzini
2021-06-17  9:30 ` [PULL 02/45] vl: Fix an assert failure in error path Paolo Bonzini
2021-06-17  9:30 ` [PULL 03/45] qemu-config: use qemu_opts_from_qdict Paolo Bonzini
2021-06-17  9:30 ` [PULL 04/45] block/scsi: correctly emulate the VPD block limits page Paolo Bonzini
2021-06-17  9:30 ` [PULL 05/45] runstate: Initialize Error * to NULL Paolo Bonzini
2021-06-17  9:30 ` [PULL 06/45] esp: only assert INTR_DC interrupt flag if selection fails Paolo Bonzini
2021-06-17  9:30 ` [PULL 07/45] esp: only set ESP_RSEQ at the start of the select sequence Paolo Bonzini
2021-06-17  9:30 ` [PULL 08/45] esp: allow non-DMA callback in esp_transfer_data() initial transfer Paolo Bonzini
2021-06-17  9:30 ` [PULL 09/45] esp: handle non-DMA transfers from the target one byte at a time Paolo Bonzini
2021-06-17  9:30 ` [PULL 10/45] esp: ensure PDMA write transfers are flushed from the FIFO to the target immediately Paolo Bonzini
2021-06-17  9:31 ` [PULL 11/45] esp: revert 75ef849696 "esp: correctly fill bus id with requested lun" Paolo Bonzini
2021-06-17  9:31 ` [PULL 12/45] esp: correctly accumulate extended messages for PDMA Paolo Bonzini
2021-06-17  9:31 ` [PULL 13/45] esp: fix migration version check in esp_is_version_5() Paolo Bonzini
2021-06-17  9:31 ` [PULL 14/45] esp: store lun coming from the MESSAGE OUT phase Paolo Bonzini
2021-06-17  9:31 ` [PULL 15/45] softmmu/physmem: Mark shared anonymous memory RAM_SHARED Paolo Bonzini
2021-06-17  9:31 ` [PULL 16/45] softmmu/physmem: Fix ram_block_discard_range() to handle shared anonymous memory Paolo Bonzini
2021-06-17  9:31 ` [PULL 17/45] softmmu/physmem: Fix qemu_ram_remap() " Paolo Bonzini
2021-06-17  9:31 ` [PULL 18/45] util/mmap-alloc: Factor out calculation of the pagesize for the guard page Paolo Bonzini
2021-06-17  9:31 ` [PULL 19/45] util/mmap-alloc: Factor out reserving of a memory region to mmap_reserve() Paolo Bonzini
2021-06-17  9:31 ` [PULL 20/45] util/mmap-alloc: Factor out activating of memory to mmap_activate() Paolo Bonzini
2021-06-17  9:31 ` [PULL 21/45] softmmu/memory: Pass ram_flags to qemu_ram_alloc_from_fd() Paolo Bonzini
2021-06-17  9:31 ` [PULL 22/45] softmmu/memory: Pass ram_flags to memory_region_init_ram_shared_nomigrate() Paolo Bonzini
2021-06-17  9:31 ` [PULL 23/45] softmmu/memory: Pass ram_flags to qemu_ram_alloc() and qemu_ram_alloc_internal() Paolo Bonzini
2021-06-17  9:31 ` [PULL 24/45] util/mmap-alloc: Pass flags instead of separate bools to qemu_ram_mmap() Paolo Bonzini
2021-06-17  9:31 ` [PULL 25/45] memory: Introduce RAM_NORESERVE and wire it up in qemu_ram_mmap() Paolo Bonzini
2021-06-17  9:31 ` [PULL 26/45] util/mmap-alloc: Support RAM_NORESERVE via MAP_NORESERVE under Linux Paolo Bonzini
2021-06-17  9:31 ` [PULL 27/45] hostmem: Wire up RAM_NORESERVE via "reserve" property Paolo Bonzini
2021-06-17  9:31 ` [PULL 28/45] qmp: Clarify memory backend properties returned via query-memdev Paolo Bonzini
2021-06-17  9:31 ` [PULL 29/45] qmp: Include "share" property of memory backends Paolo Bonzini
2021-06-17  9:31 ` [PULL 30/45] hmp: Print "share" property of memory backends with "info memdev" Paolo Bonzini
2021-06-17  9:31 ` [PULL 31/45] qmp: Include "reserve" property of memory backends Paolo Bonzini
2021-06-17  9:31 ` [PULL 32/45] hmp: Print "reserve" property of memory backends with "info memdev" Paolo Bonzini
2021-06-17  9:31 ` [PULL 33/45] configure: map x32 to cpu_family x86_64 for meson Paolo Bonzini
2021-06-17  9:31 ` [PULL 34/45] target/i386: Refactored intercept checks into cpu_svm_has_intercept Paolo Bonzini
2021-06-17  9:31 ` [PULL 35/45] target/i386: Added consistency checks for VMRUN intercept and ASID Paolo Bonzini
2021-06-17  9:31 ` [PULL 36/45] target/i386: Added consistency checks for CR0 Paolo Bonzini
2021-06-17  9:31 ` [PULL 37/45] target/i386: Added Intercept CR0 writes check Paolo Bonzini
2021-06-17  9:31 ` [PULL 38/45] configure: Use -std=gnu11 Paolo Bonzini
2021-06-17  9:31 ` [PULL 39/45] softfloat: Use _Generic instead of QEMU_GENERIC Paolo Bonzini
2021-06-17  9:31 ` [PULL 40/45] util: Use real functions for thread-posix QemuRecMutex Paolo Bonzini
2021-06-17  9:31 ` [PULL 41/45] util: Pass file+line to qemu_rec_mutex_unlock_impl Paolo Bonzini
2021-06-17  9:31 ` [PULL 42/45] util: Use unique type for QemuRecMutex in thread-posix.h Paolo Bonzini
2021-06-17  9:31 ` [PULL 43/45] include/qemu/lockable: Use _Generic instead of QEMU_GENERIC Paolo Bonzini
2021-06-17  9:31 ` [PULL 44/45] qemu/compiler: Remove QEMU_GENERIC Paolo Bonzini
2021-06-17  9:31 ` [PULL 45/45] configure: Remove probe for _Static_assert Paolo Bonzini
2021-06-17 10:21 ` [PULL 00/45] Memory, i386, compilation, bugfix changes for 2021-06-17 no-reply
2021-06-18  8:53 ` Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.