All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/15] Finish cleaning up qemu_init
@ 2020-12-02  8:18 Paolo Bonzini
  2020-12-02  8:18 ` [PATCH 01/15] remove preconfig state Paolo Bonzini
                   ` (15 more replies)
  0 siblings, 16 replies; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-02  8:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo

These are the patches that needed another review, had some conflicts,
or were not quite ready for the previous posting.

Highlights include:

- fixing the HMP prompt for -preconfig

- enabling the qtest server with -object instead of -qtest

- decoupling target machine code from QemuOpts

Based-on: <20201202080849.4125477-1-pbonzini@redhat.com>

Paolo Bonzini (15):
  remove preconfig state
  vl: remove separate preconfig main_loop
  vl: allow -incoming defer with -preconfig
  vl: extract softmmu/runstate.c
  vl: extract softmmu/globals.c
  vl: move all generic initialization out of vl.c
  chardev: do not use machine_init_done
  machine: introduce MachineInitPhase
  machine: record whether nvdimm= was set
  vl: make qemu_get_machine_opts static
  qtest: add a QOM object for qtest
  plugin: propagate errors
  memory: allow creating MemoryRegions before accelerators
  null-machine: do not create a default memdev
  monitor: allow quitting while in preconfig state

 accel/kvm/kvm-all.c           |  11 +-
 chardev/char-mux.c            |  38 +-
 chardev/chardev-sysemu.c      |  69 ---
 chardev/meson.build           |   2 +-
 hmp-commands.hx               |   1 +
 hw/arm/boot.c                 |   2 +-
 hw/core/machine-qmp-cmds.c    |   7 +-
 hw/core/machine.c             |  56 +-
 hw/core/null-machine.c        |   2 +-
 hw/core/qdev.c                |  28 +-
 hw/microblaze/boot.c          |   9 +-
 hw/nios2/boot.c               |   9 +-
 hw/pci/pci.c                  |   2 +-
 hw/ppc/e500.c                 |   5 +-
 hw/ppc/spapr_nvdimm.c         |   4 +-
 hw/ppc/virtex_ml507.c         |   2 +-
 hw/riscv/sifive_u.c           |   6 +-
 hw/riscv/virt.c               |   6 +-
 hw/usb/core.c                 |   2 +-
 hw/virtio/virtio-iommu.c      |   2 +-
 hw/xtensa/xtfpga.c            |   9 +-
 include/chardev/char.h        |   6 +-
 include/exec/cpu-common.h     |   3 +
 include/exec/exec-all.h       |   3 -
 include/hw/mem/nvdimm.h       |   2 +-
 include/hw/qdev-core.h        |  33 +-
 include/qapi/qmp/dispatch.h   |   1 +
 include/qemu/plugin.h         |   4 +-
 include/sysemu/runstate.h     |   1 -
 include/sysemu/sysemu.h       |   7 +-
 linux-user/main.c             |   4 +-
 monitor/hmp.c                 |   7 +-
 monitor/qmp-cmds.c            |  10 -
 plugins/loader.c              |  34 +-
 qapi/control.json             |   3 +-
 qapi/qmp-dispatch.c           |   5 +-
 qapi/run-state.json           |   5 +-
 softmmu/device_tree.c         |   2 +-
 softmmu/globals.c             |  74 +++
 softmmu/memory.c              |  12 +-
 softmmu/meson.build           |   2 +
 softmmu/qdev-monitor.c        |  34 +-
 softmmu/qtest.c               | 144 ++++-
 softmmu/runstate.c            | 800 ++++++++++++++++++++++++++++
 softmmu/vl.c                  | 958 ++--------------------------------
 stubs/machine-init-done.c     |   8 -
 stubs/meson.build             |   2 +-
 stubs/qmp-command-available.c |   7 +
 tests/qtest/qmp-test.c        |   2 +-
 ui/console.c                  |   2 +-
 50 files changed, 1312 insertions(+), 1135 deletions(-)
 delete mode 100644 chardev/chardev-sysemu.c
 create mode 100644 softmmu/globals.c
 create mode 100644 softmmu/runstate.c
 delete mode 100644 stubs/machine-init-done.c
 create mode 100644 stubs/qmp-command-available.c

-- 
2.26.2



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

* [PATCH 01/15] remove preconfig state
  2020-12-02  8:18 [PATCH 00/15] Finish cleaning up qemu_init Paolo Bonzini
@ 2020-12-02  8:18 ` Paolo Bonzini
  2020-12-07 13:57   ` Igor Mammedov
  2020-12-02  8:18 ` [PATCH 02/15] vl: remove separate preconfig main_loop Paolo Bonzini
                   ` (14 subsequent siblings)
  15 siblings, 1 reply; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-02  8:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo

The preconfig state is only used if -incoming is not specified, which
makes the RunState state machine more tricky than it need be.  However
there is already an equivalent condition which works even with -incoming,
namely qdev_hotplug.  Use it instead of a separate runstate.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/core/machine-qmp-cmds.c    |  5 ++---
 include/qapi/qmp/dispatch.h   |  1 +
 monitor/hmp.c                 |  7 ++++---
 monitor/qmp-cmds.c            |  5 ++---
 qapi/qmp-dispatch.c           |  5 +----
 qapi/run-state.json           |  5 +----
 softmmu/qdev-monitor.c        | 12 ++++++++++++
 softmmu/vl.c                  | 13 ++-----------
 stubs/meson.build             |  1 +
 stubs/qmp-command-available.c |  7 +++++++
 tests/qtest/qmp-test.c        |  2 +-
 11 files changed, 34 insertions(+), 29 deletions(-)
 create mode 100644 stubs/qmp-command-available.c

diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
index 5362c80a18..cb9387c5f5 100644
--- a/hw/core/machine-qmp-cmds.c
+++ b/hw/core/machine-qmp-cmds.c
@@ -286,9 +286,8 @@ HotpluggableCPUList *qmp_query_hotpluggable_cpus(Error **errp)
 
 void qmp_set_numa_node(NumaOptions *cmd, Error **errp)
 {
-    if (!runstate_check(RUN_STATE_PRECONFIG)) {
-        error_setg(errp, "The command is permitted only in '%s' state",
-                   RunState_str(RUN_STATE_PRECONFIG));
+    if (qdev_hotplug) {
+         error_setg(errp, "The command is permitted only before the machine has been created");
          return;
     }
 
diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
index af8d96c570..1486cac3ef 100644
--- a/include/qapi/qmp/dispatch.h
+++ b/include/qapi/qmp/dispatch.h
@@ -48,6 +48,7 @@ void qmp_disable_command(QmpCommandList *cmds, const char *name);
 void qmp_enable_command(QmpCommandList *cmds, const char *name);
 
 bool qmp_command_is_enabled(const QmpCommand *cmd);
+bool qmp_command_available(const QmpCommand *cmd, Error **errp);
 const char *qmp_command_name(const QmpCommand *cmd);
 bool qmp_has_success_response(const QmpCommand *cmd);
 QDict *qmp_error_response(Error *err);
diff --git a/monitor/hmp.c b/monitor/hmp.c
index d40f4f4391..f2fe192d69 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -24,6 +24,7 @@
 
 #include "qemu/osdep.h"
 #include <dirent.h>
+#include "hw/qdev-core.h"
 #include "monitor-internal.h"
 #include "qapi/error.h"
 #include "qapi/qmp/qdict.h"
@@ -215,7 +216,7 @@ static bool cmd_can_preconfig(const HMPCommand *cmd)
 
 static bool cmd_available(const HMPCommand *cmd)
 {
-    return !runstate_check(RUN_STATE_PRECONFIG) || cmd_can_preconfig(cmd);
+    return qdev_hotplug || cmd_can_preconfig(cmd);
 }
 
 static void help_cmd_dump_one(Monitor *mon,
@@ -658,8 +659,8 @@ static const HMPCommand *monitor_parse_command(MonitorHMP *hmp_mon,
         return NULL;
     }
     if (!cmd_available(cmd)) {
-        monitor_printf(mon, "Command '%.*s' not available with -preconfig "
-                            "until after exit_preconfig.\n",
+        monitor_printf(mon, "Command '%.*s' not available "
+                            "until machine initialization has completed.\n",
                        (int)(p - cmdp_start), cmdp_start);
         return NULL;
     }
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index 6299c0c8c7..501a3024c7 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -104,9 +104,8 @@ void qmp_system_powerdown(Error **errp)
 
 void qmp_x_exit_preconfig(Error **errp)
 {
-    if (!runstate_check(RUN_STATE_PRECONFIG)) {
-        error_setg(errp, "The command is permitted only in '%s' state",
-                   RunState_str(RUN_STATE_PRECONFIG));
+    if (qdev_hotplug) {
+        error_setg(errp, "The command is permitted only before machine initialization");
         return;
     }
     qemu_exit_preconfig_request();
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index 9a2d7dd29a..0a2b20a4e4 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -167,10 +167,7 @@ QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request,
         goto out;
     }
 
-    if (runstate_check(RUN_STATE_PRECONFIG) &&
-        !(cmd->options & QCO_ALLOW_PRECONFIG)) {
-        error_setg(&err, "The command '%s' isn't permitted in '%s' state",
-                   cmd->name, RunState_str(RUN_STATE_PRECONFIG));
+    if (!qmp_command_available(cmd, &err)) {
         goto out;
     }
 
diff --git a/qapi/run-state.json b/qapi/run-state.json
index 964c8ef391..38194b0e44 100644
--- a/qapi/run-state.json
+++ b/qapi/run-state.json
@@ -50,15 +50,12 @@
 # @colo: guest is paused to save/restore VM state under colo checkpoint,
 #        VM can not get into this state unless colo capability is enabled
 #        for migration. (since 2.8)
-# @preconfig: QEMU is paused before board specific init callback is executed.
-#             The state is reachable only if the --preconfig CLI option is used.
-#             (Since 3.0)
 ##
 { 'enum': 'RunState',
   'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused',
             'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm',
             'running', 'save-vm', 'shutdown', 'suspended', 'watchdog',
-            'guest-panicked', 'colo', 'preconfig' ] }
+            'guest-panicked', 'colo' ] }
 
 ##
 # @ShutdownCause:
diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
index d060e765da..e967d13bd0 100644
--- a/softmmu/qdev-monitor.c
+++ b/softmmu/qdev-monitor.c
@@ -25,6 +25,7 @@
 #include "sysemu/arch_init.h"
 #include "qapi/error.h"
 #include "qapi/qapi-commands-qdev.h"
+#include "qapi/qmp/dispatch.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qerror.h"
 #include "qemu/config-file.h"
@@ -997,3 +998,14 @@ int qemu_global_option(const char *str)
 
     return 0;
 }
+
+bool qmp_command_available(const QmpCommand *cmd, Error **errp)
+{
+    if (!qdev_hotplug &&
+        !(cmd->options & QCO_ALLOW_PRECONFIG)) {
+        error_setg(errp, "The command '%s' is permitted only after machine initialization has completed",
+                   cmd->name);
+        return false;
+    }
+    return true;
+}
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 7146fbe219..ab2210bc79 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -557,7 +557,7 @@ static int default_driver_check(void *opaque, QemuOpts *opts, Error **errp)
 /***********************************************************/
 /* QEMU state */
 
-static RunState current_run_state = RUN_STATE_PRECONFIG;
+static RunState current_run_state = RUN_STATE_PRELAUNCH;
 
 /* We use RUN_STATE__MAX but any invalid value will do */
 static RunState vmstop_requested = RUN_STATE__MAX;
@@ -569,13 +569,7 @@ typedef struct {
 } RunStateTransition;
 
 static const RunStateTransition runstate_transitions_def[] = {
-    /*     from      ->     to      */
-    { RUN_STATE_PRECONFIG, RUN_STATE_PRELAUNCH },
-      /* Early switch to inmigrate state to allow  -incoming CLI option work
-       * as it used to. TODO: delay actual switching to inmigrate state to
-       * the point after machine is built and remove this hack.
-       */
-    { RUN_STATE_PRECONFIG, RUN_STATE_INMIGRATE },
+    { RUN_STATE_PRELAUNCH, RUN_STATE_INMIGRATE },
 
     { RUN_STATE_DEBUG, RUN_STATE_RUNNING },
     { RUN_STATE_DEBUG, RUN_STATE_FINISH_MIGRATE },
@@ -1471,9 +1465,6 @@ static bool main_loop_should_exit(void)
     ShutdownCause request;
 
     if (preconfig_exit_requested) {
-        if (runstate_check(RUN_STATE_PRECONFIG)) {
-            runstate_set(RUN_STATE_PRELAUNCH);
-        }
         preconfig_exit_requested = false;
         return true;
     }
diff --git a/stubs/meson.build b/stubs/meson.build
index 82b7ba60ab..cc56c83063 100644
--- a/stubs/meson.build
+++ b/stubs/meson.build
@@ -29,6 +29,7 @@ stub_ss.add(files('pci-bus.c'))
 stub_ss.add(files('pci-host-piix.c'))
 stub_ss.add(files('qemu-timer-notify-cb.c'))
 stub_ss.add(files('qmp_memory_device.c'))
+stub_ss.add(files('qmp-command-available.c'))
 stub_ss.add(files('qtest.c'))
 stub_ss.add(files('ram-block.c'))
 stub_ss.add(files('ramfb.c'))
diff --git a/stubs/qmp-command-available.c b/stubs/qmp-command-available.c
new file mode 100644
index 0000000000..46540af7bf
--- /dev/null
+++ b/stubs/qmp-command-available.c
@@ -0,0 +1,7 @@
+#include "qemu/osdep.h"
+#include "qapi/qmp/dispatch.h"
+
+bool qmp_command_available(const QmpCommand *cmd, Error **errp)
+{
+    return true;
+}
diff --git a/tests/qtest/qmp-test.c b/tests/qtest/qmp-test.c
index eb1cd8abb8..11614bf63f 100644
--- a/tests/qtest/qmp-test.c
+++ b/tests/qtest/qmp-test.c
@@ -295,7 +295,7 @@ static void test_qmp_preconfig(void)
     rsp = qtest_qmp(qs, "{ 'execute': 'query-status' }");
     ret = qdict_get_qdict(rsp, "return");
     g_assert(ret);
-    g_assert_cmpstr(qdict_get_try_str(ret, "status"), ==, "preconfig");
+    g_assert_cmpstr(qdict_get_try_str(ret, "status"), ==, "prelaunch");
     qobject_unref(rsp);
 
     /* exit preconfig state */
-- 
2.26.2




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

* [PATCH 02/15] vl: remove separate preconfig main_loop
  2020-12-02  8:18 [PATCH 00/15] Finish cleaning up qemu_init Paolo Bonzini
  2020-12-02  8:18 ` [PATCH 01/15] remove preconfig state Paolo Bonzini
@ 2020-12-02  8:18 ` Paolo Bonzini
  2020-12-07 14:02   ` Igor Mammedov
  2020-12-02  8:18 ` [PATCH 03/15] vl: allow -incoming defer with -preconfig Paolo Bonzini
                   ` (13 subsequent siblings)
  15 siblings, 1 reply; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-02  8:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo

Move post-preconfig initialization to the x-exit-preconfig.  If preconfig
is not requested, just exit preconfig mode immediately with the QMP
command.

As a result, the preconfig loop will run with accel_setup_post
and os_setup_post restrictions (xen_restrict, chroot, etc.)
already done.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/sysemu/runstate.h |  1 -
 monitor/qmp-cmds.c        |  9 ----
 softmmu/vl.c              | 95 +++++++++++++++++----------------------
 3 files changed, 41 insertions(+), 64 deletions(-)

diff --git a/include/sysemu/runstate.h b/include/sysemu/runstate.h
index f760094858..e557f470d4 100644
--- a/include/sysemu/runstate.h
+++ b/include/sysemu/runstate.h
@@ -41,7 +41,6 @@ typedef enum WakeupReason {
     QEMU_WAKEUP_REASON_OTHER,
 } WakeupReason;
 
-void qemu_exit_preconfig_request(void);
 void qemu_system_reset_request(ShutdownCause reason);
 void qemu_system_suspend_request(void);
 void qemu_register_suspend_notifier(Notifier *notifier);
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index 501a3024c7..7ced7eb3e8 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -102,15 +102,6 @@ void qmp_system_powerdown(Error **errp)
     qemu_system_powerdown_request();
 }
 
-void qmp_x_exit_preconfig(Error **errp)
-{
-    if (qdev_hotplug) {
-        error_setg(errp, "The command is permitted only before machine initialization");
-        return;
-    }
-    qemu_exit_preconfig_request();
-}
-
 void qmp_cont(Error **errp)
 {
     BlockBackend *blk;
diff --git a/softmmu/vl.c b/softmmu/vl.c
index ab2210bc79..abbbb83e1a 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -1151,7 +1151,6 @@ static pid_t shutdown_pid;
 static int powerdown_requested;
 static int debug_requested;
 static int suspend_requested;
-static bool preconfig_exit_requested = true;
 static WakeupReason wakeup_reason;
 static NotifierList powerdown_notifiers =
     NOTIFIER_LIST_INITIALIZER(powerdown_notifiers);
@@ -1238,11 +1237,6 @@ static int qemu_debug_requested(void)
     return r;
 }
 
-void qemu_exit_preconfig_request(void)
-{
-    preconfig_exit_requested = true;
-}
-
 /*
  * Reset the VM. Issue an event unless @reason is SHUTDOWN_CAUSE_NONE.
  */
@@ -1464,10 +1458,6 @@ static bool main_loop_should_exit(void)
     RunState r;
     ShutdownCause request;
 
-    if (preconfig_exit_requested) {
-        preconfig_exit_requested = false;
-        return true;
-    }
     if (qemu_debug_requested()) {
         vm_stop(RUN_STATE_DEBUG);
     }
@@ -3283,6 +3273,43 @@ static void qemu_machine_creation_done(void)
     register_global_state();
 }
 
+void qmp_x_exit_preconfig(Error **errp)
+{
+    if (qdev_hotplug) {
+        error_setg(errp, "The command is permitted only before machine initialization");
+        return;
+    }
+
+    qemu_init_board();
+    qemu_create_cli_devices();
+    qemu_machine_creation_done();
+
+    if (loadvm) {
+        Error *local_err = NULL;
+        if (load_snapshot(loadvm, &local_err) < 0) {
+            error_report_err(local_err);
+            autostart = 0;
+            exit(1);
+        }
+    }
+    if (replay_mode != REPLAY_MODE_NONE) {
+        replay_vmstate_init();
+    }
+
+    if (incoming) {
+        Error *local_err = NULL;
+        if (strcmp(incoming, "defer") != 0) {
+            qmp_migrate_incoming(incoming, &local_err);
+            if (local_err) {
+                error_reportf_err(local_err, "-incoming %s: ", incoming);
+                exit(1);
+            }
+        }
+    } else if (autostart) {
+        qmp_cont(NULL);
+    }
+}
+
 void qemu_init(int argc, char **argv, char **envp)
 {
     QemuOpts *opts;
@@ -3847,7 +3874,6 @@ void qemu_init(int argc, char **argv, char **envp)
                 }
                 break;
             case QEMU_OPTION_preconfig:
-                preconfig_exit_requested = false;
                 preconfig_requested = true;
                 break;
             case QEMU_OPTION_enable_kvm:
@@ -4272,57 +4298,18 @@ void qemu_init(int argc, char **argv, char **envp)
     qemu_resolve_machine_memdev();
     parse_numa_opts(current_machine);
 
-    if (preconfig_requested) {
-        qemu_init_displays();
-    }
-
-    /* do monitor/qmp handling at preconfig state if requested */
-    qemu_main_loop();
-
-    qemu_init_board();
-
-    qemu_create_cli_devices();
-
-    /* initialize displays after all errors have been reported */
-    if (!preconfig_requested) {
-        qemu_init_displays();
-    }
-    qemu_machine_creation_done();
-
-    if (loadvm) {
-        Error *local_err = NULL;
-        if (load_snapshot(loadvm, &local_err) < 0) {
-            error_report_err(local_err);
-            autostart = 0;
-            exit(1);
-        }
-    }
-    if (replay_mode != REPLAY_MODE_NONE) {
-        replay_vmstate_init();
-    }
-
     if (vmstate_dump_file) {
         /* dump and exit */
         dump_vmstate_json_to_file(vmstate_dump_file);
         exit(0);
     }
-    if (incoming) {
-        Error *local_err = NULL;
-        if (strcmp(incoming, "defer") != 0) {
-            qmp_migrate_incoming(incoming, &local_err);
-            if (local_err) {
-                error_reportf_err(local_err, "-incoming %s: ", incoming);
-                exit(1);
-            }
-        }
-    } else if (autostart) {
-        qmp_cont(NULL);
-    }
 
+    qemu_init_displays();
+    if (!preconfig_requested) {
+        qmp_x_exit_preconfig(&error_fatal);
+    }
     accel_setup_post(current_machine);
     os_setup_post();
-
-    return;
 }
 
 void qemu_cleanup(void)
-- 
2.26.2




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

* [PATCH 03/15] vl: allow -incoming defer with -preconfig
  2020-12-02  8:18 [PATCH 00/15] Finish cleaning up qemu_init Paolo Bonzini
  2020-12-02  8:18 ` [PATCH 01/15] remove preconfig state Paolo Bonzini
  2020-12-02  8:18 ` [PATCH 02/15] vl: remove separate preconfig main_loop Paolo Bonzini
@ 2020-12-02  8:18 ` Paolo Bonzini
  2020-12-02  8:18 ` [PATCH 04/15] vl: extract softmmu/runstate.c Paolo Bonzini
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-02  8:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo

Now that there is no RUN_STATE_PRECONFIG anymore that can conflict with
RUN_STATE_INMIGRATE, we can allow -incoming defer with -preconfig.

Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 softmmu/vl.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/softmmu/vl.c b/softmmu/vl.c
index abbbb83e1a..3dfac8299b 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -2986,9 +2986,8 @@ static void qemu_validate_options(void)
                      "mutually exclusive");
         exit(EXIT_FAILURE);
     }
-    if (incoming && preconfig_requested) {
-        error_report("'preconfig' and 'incoming' options are "
-                     "mutually exclusive");
+    if (incoming && preconfig_requested && strcmp(incoming, "defer") != 0) {
+        error_report("'preconfig' supports '-incoming defer' only");
         exit(EXIT_FAILURE);
     }
 
-- 
2.26.2




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

* [PATCH 04/15] vl: extract softmmu/runstate.c
  2020-12-02  8:18 [PATCH 00/15] Finish cleaning up qemu_init Paolo Bonzini
                   ` (2 preceding siblings ...)
  2020-12-02  8:18 ` [PATCH 03/15] vl: allow -incoming defer with -preconfig Paolo Bonzini
@ 2020-12-02  8:18 ` Paolo Bonzini
  2020-12-02  8:18 ` [PATCH 05/15] vl: extract softmmu/globals.c Paolo Bonzini
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-02  8:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo

Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/sysemu/sysemu.h |   3 +
 softmmu/meson.build     |   1 +
 softmmu/runstate.c      | 800 ++++++++++++++++++++++++++++++++++++++++
 softmmu/vl.c            | 752 +------------------------------------
 4 files changed, 805 insertions(+), 751 deletions(-)
 create mode 100644 softmmu/runstate.c

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 29c32f9851..0e7b405d22 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -24,6 +24,8 @@ void qemu_remove_machine_init_done_notifier(Notifier *notify);
 
 void configure_rtc(QemuOpts *opts);
 
+void qemu_init_subsystems(void);
+
 extern int autostart;
 
 typedef enum {
@@ -44,6 +46,7 @@ extern int alt_grab;
 extern int ctrl_grab;
 extern int graphic_rotate;
 extern int no_shutdown;
+extern int no_reboot;
 extern int old_param;
 extern int boot_menu;
 extern bool boot_strict;
diff --git a/softmmu/meson.build b/softmmu/meson.build
index d098d89653..2a73ebc223 100644
--- a/softmmu/meson.build
+++ b/softmmu/meson.build
@@ -7,6 +7,7 @@ specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: [files(
   'physmem.c',
   'ioport.c',
   'rtc.c',
+  'runstate.c',
   'memory.c',
   'memory_mapping.c',
   'qtest.c',
diff --git a/softmmu/runstate.c b/softmmu/runstate.c
new file mode 100644
index 0000000000..892f2f679f
--- /dev/null
+++ b/softmmu/runstate.c
@@ -0,0 +1,800 @@
+/*
+ * QEMU main system emulation loop
+ *
+ * Copyright (c) 2003-2020 QEMU contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "audio/audio.h"
+#include "block/block.h"
+#include "chardev/char.h"
+#include "crypto/cipher.h"
+#include "crypto/init.h"
+#include "exec/cpu-common.h"
+#include "exec/exec-all.h"
+#include "exec/gdbstub.h"
+#include "hw/boards.h"
+#include "migration/misc.h"
+#include "migration/postcopy-ram.h"
+#include "monitor/monitor.h"
+#include "net/net.h"
+#include "net/vhost_net.h"
+#include "qapi/error.h"
+#include "qapi/qapi-commands-run-state.h"
+#include "qapi/qapi-events-run-state.h"
+#include "qemu-common.h"
+#include "qemu/error-report.h"
+#include "qemu/job.h"
+#include "qemu/module.h"
+#include "qemu/plugin.h"
+#include "qemu/sockets.h"
+#include "qemu/thread.h"
+#include "qom/object.h"
+#include "qom/object_interfaces.h"
+#include "sysemu/cpus.h"
+#include "sysemu/qtest.h"
+#include "sysemu/replay.h"
+#include "sysemu/reset.h"
+#include "sysemu/runstate.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/tpm.h"
+#include "trace.h"
+
+static NotifierList exit_notifiers =
+    NOTIFIER_LIST_INITIALIZER(exit_notifiers);
+
+static RunState current_run_state = RUN_STATE_PRELAUNCH;
+
+/* We use RUN_STATE__MAX but any invalid value will do */
+static RunState vmstop_requested = RUN_STATE__MAX;
+static QemuMutex vmstop_lock;
+
+typedef struct {
+    RunState from;
+    RunState to;
+} RunStateTransition;
+
+static const RunStateTransition runstate_transitions_def[] = {
+    { RUN_STATE_PRELAUNCH, RUN_STATE_INMIGRATE },
+
+    { RUN_STATE_DEBUG, RUN_STATE_RUNNING },
+    { RUN_STATE_DEBUG, RUN_STATE_FINISH_MIGRATE },
+    { RUN_STATE_DEBUG, RUN_STATE_PRELAUNCH },
+
+    { RUN_STATE_INMIGRATE, RUN_STATE_INTERNAL_ERROR },
+    { RUN_STATE_INMIGRATE, RUN_STATE_IO_ERROR },
+    { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED },
+    { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING },
+    { RUN_STATE_INMIGRATE, RUN_STATE_SHUTDOWN },
+    { RUN_STATE_INMIGRATE, RUN_STATE_SUSPENDED },
+    { RUN_STATE_INMIGRATE, RUN_STATE_WATCHDOG },
+    { RUN_STATE_INMIGRATE, RUN_STATE_GUEST_PANICKED },
+    { RUN_STATE_INMIGRATE, RUN_STATE_FINISH_MIGRATE },
+    { RUN_STATE_INMIGRATE, RUN_STATE_PRELAUNCH },
+    { RUN_STATE_INMIGRATE, RUN_STATE_POSTMIGRATE },
+    { RUN_STATE_INMIGRATE, RUN_STATE_COLO },
+
+    { RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED },
+    { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE },
+    { RUN_STATE_INTERNAL_ERROR, RUN_STATE_PRELAUNCH },
+
+    { RUN_STATE_IO_ERROR, RUN_STATE_RUNNING },
+    { RUN_STATE_IO_ERROR, RUN_STATE_FINISH_MIGRATE },
+    { RUN_STATE_IO_ERROR, RUN_STATE_PRELAUNCH },
+
+    { RUN_STATE_PAUSED, RUN_STATE_RUNNING },
+    { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE },
+    { RUN_STATE_PAUSED, RUN_STATE_POSTMIGRATE },
+    { RUN_STATE_PAUSED, RUN_STATE_PRELAUNCH },
+    { RUN_STATE_PAUSED, RUN_STATE_COLO},
+
+    { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING },
+    { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE },
+    { RUN_STATE_POSTMIGRATE, RUN_STATE_PRELAUNCH },
+
+    { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING },
+    { RUN_STATE_PRELAUNCH, RUN_STATE_FINISH_MIGRATE },
+    { RUN_STATE_PRELAUNCH, RUN_STATE_INMIGRATE },
+
+    { RUN_STATE_FINISH_MIGRATE, RUN_STATE_RUNNING },
+    { RUN_STATE_FINISH_MIGRATE, RUN_STATE_PAUSED },
+    { RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE },
+    { RUN_STATE_FINISH_MIGRATE, RUN_STATE_PRELAUNCH },
+    { RUN_STATE_FINISH_MIGRATE, RUN_STATE_COLO},
+
+    { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING },
+    { RUN_STATE_RESTORE_VM, RUN_STATE_PRELAUNCH },
+
+    { RUN_STATE_COLO, RUN_STATE_RUNNING },
+
+    { RUN_STATE_RUNNING, RUN_STATE_DEBUG },
+    { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR },
+    { RUN_STATE_RUNNING, RUN_STATE_IO_ERROR },
+    { RUN_STATE_RUNNING, RUN_STATE_PAUSED },
+    { RUN_STATE_RUNNING, RUN_STATE_FINISH_MIGRATE },
+    { RUN_STATE_RUNNING, RUN_STATE_RESTORE_VM },
+    { RUN_STATE_RUNNING, RUN_STATE_SAVE_VM },
+    { RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN },
+    { RUN_STATE_RUNNING, RUN_STATE_WATCHDOG },
+    { RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED },
+    { RUN_STATE_RUNNING, RUN_STATE_COLO},
+
+    { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING },
+
+    { RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED },
+    { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE },
+    { RUN_STATE_SHUTDOWN, RUN_STATE_PRELAUNCH },
+    { RUN_STATE_SHUTDOWN, RUN_STATE_COLO },
+
+    { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED },
+    { RUN_STATE_RUNNING, RUN_STATE_SUSPENDED },
+    { RUN_STATE_SUSPENDED, RUN_STATE_RUNNING },
+    { RUN_STATE_SUSPENDED, RUN_STATE_FINISH_MIGRATE },
+    { RUN_STATE_SUSPENDED, RUN_STATE_PRELAUNCH },
+    { RUN_STATE_SUSPENDED, RUN_STATE_COLO},
+
+    { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING },
+    { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE },
+    { RUN_STATE_WATCHDOG, RUN_STATE_PRELAUNCH },
+    { RUN_STATE_WATCHDOG, RUN_STATE_COLO},
+
+    { RUN_STATE_GUEST_PANICKED, RUN_STATE_RUNNING },
+    { RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE },
+    { RUN_STATE_GUEST_PANICKED, RUN_STATE_PRELAUNCH },
+
+    { RUN_STATE__MAX, RUN_STATE__MAX },
+};
+
+static bool runstate_valid_transitions[RUN_STATE__MAX][RUN_STATE__MAX];
+
+bool runstate_check(RunState state)
+{
+    return current_run_state == state;
+}
+
+bool runstate_store(char *str, size_t size)
+{
+    const char *state = RunState_str(current_run_state);
+    size_t len = strlen(state) + 1;
+
+    if (len > size) {
+        return false;
+    }
+    memcpy(str, state, len);
+    return true;
+}
+
+static void runstate_init(void)
+{
+    const RunStateTransition *p;
+
+    memset(&runstate_valid_transitions, 0, sizeof(runstate_valid_transitions));
+    for (p = &runstate_transitions_def[0]; p->from != RUN_STATE__MAX; p++) {
+        runstate_valid_transitions[p->from][p->to] = true;
+    }
+
+    qemu_mutex_init(&vmstop_lock);
+}
+
+/* This function will abort() on invalid state transitions */
+void runstate_set(RunState new_state)
+{
+    assert(new_state < RUN_STATE__MAX);
+
+    trace_runstate_set(current_run_state, RunState_str(current_run_state),
+                       new_state, RunState_str(new_state));
+
+    if (current_run_state == new_state) {
+        return;
+    }
+
+    if (!runstate_valid_transitions[current_run_state][new_state]) {
+        error_report("invalid runstate transition: '%s' -> '%s'",
+                     RunState_str(current_run_state),
+                     RunState_str(new_state));
+        abort();
+    }
+
+    current_run_state = new_state;
+}
+
+int runstate_is_running(void)
+{
+    return runstate_check(RUN_STATE_RUNNING);
+}
+
+bool runstate_needs_reset(void)
+{
+    return runstate_check(RUN_STATE_INTERNAL_ERROR) ||
+        runstate_check(RUN_STATE_SHUTDOWN);
+}
+
+StatusInfo *qmp_query_status(Error **errp)
+{
+    StatusInfo *info = g_malloc0(sizeof(*info));
+
+    info->running = runstate_is_running();
+    info->singlestep = singlestep;
+    info->status = current_run_state;
+
+    return info;
+}
+
+bool qemu_vmstop_requested(RunState *r)
+{
+    qemu_mutex_lock(&vmstop_lock);
+    *r = vmstop_requested;
+    vmstop_requested = RUN_STATE__MAX;
+    qemu_mutex_unlock(&vmstop_lock);
+    return *r < RUN_STATE__MAX;
+}
+
+void qemu_system_vmstop_request_prepare(void)
+{
+    qemu_mutex_lock(&vmstop_lock);
+}
+
+void qemu_system_vmstop_request(RunState state)
+{
+    vmstop_requested = state;
+    qemu_mutex_unlock(&vmstop_lock);
+    qemu_notify_event();
+}
+struct VMChangeStateEntry {
+    VMChangeStateHandler *cb;
+    void *opaque;
+    QTAILQ_ENTRY(VMChangeStateEntry) entries;
+    int priority;
+};
+
+static QTAILQ_HEAD(, VMChangeStateEntry) vm_change_state_head =
+    QTAILQ_HEAD_INITIALIZER(vm_change_state_head);
+
+/**
+ * qemu_add_vm_change_state_handler_prio:
+ * @cb: the callback to invoke
+ * @opaque: user data passed to the callback
+ * @priority: low priorities execute first when the vm runs and the reverse is
+ *            true when the vm stops
+ *
+ * Register a callback function that is invoked when the vm starts or stops
+ * running.
+ *
+ * Returns: an entry to be freed using qemu_del_vm_change_state_handler()
+ */
+VMChangeStateEntry *qemu_add_vm_change_state_handler_prio(
+        VMChangeStateHandler *cb, void *opaque, int priority)
+{
+    VMChangeStateEntry *e;
+    VMChangeStateEntry *other;
+
+    e = g_malloc0(sizeof(*e));
+    e->cb = cb;
+    e->opaque = opaque;
+    e->priority = priority;
+
+    /* Keep list sorted in ascending priority order */
+    QTAILQ_FOREACH(other, &vm_change_state_head, entries) {
+        if (priority < other->priority) {
+            QTAILQ_INSERT_BEFORE(other, e, entries);
+            return e;
+        }
+    }
+
+    QTAILQ_INSERT_TAIL(&vm_change_state_head, e, entries);
+    return e;
+}
+
+VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
+                                                     void *opaque)
+{
+    return qemu_add_vm_change_state_handler_prio(cb, opaque, 0);
+}
+
+void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
+{
+    QTAILQ_REMOVE(&vm_change_state_head, e, entries);
+    g_free(e);
+}
+
+void vm_state_notify(int running, RunState state)
+{
+    VMChangeStateEntry *e, *next;
+
+    trace_vm_state_notify(running, state, RunState_str(state));
+
+    if (running) {
+        QTAILQ_FOREACH_SAFE(e, &vm_change_state_head, entries, next) {
+            e->cb(e->opaque, running, state);
+        }
+    } else {
+        QTAILQ_FOREACH_REVERSE_SAFE(e, &vm_change_state_head, entries, next) {
+            e->cb(e->opaque, running, state);
+        }
+    }
+}
+
+static ShutdownCause reset_requested;
+static ShutdownCause shutdown_requested;
+static int shutdown_signal;
+static pid_t shutdown_pid;
+static int powerdown_requested;
+static int debug_requested;
+static int suspend_requested;
+static WakeupReason wakeup_reason;
+static NotifierList powerdown_notifiers =
+    NOTIFIER_LIST_INITIALIZER(powerdown_notifiers);
+static NotifierList suspend_notifiers =
+    NOTIFIER_LIST_INITIALIZER(suspend_notifiers);
+static NotifierList wakeup_notifiers =
+    NOTIFIER_LIST_INITIALIZER(wakeup_notifiers);
+static NotifierList shutdown_notifiers =
+    NOTIFIER_LIST_INITIALIZER(shutdown_notifiers);
+static uint32_t wakeup_reason_mask = ~(1 << QEMU_WAKEUP_REASON_NONE);
+
+ShutdownCause qemu_shutdown_requested_get(void)
+{
+    return shutdown_requested;
+}
+
+ShutdownCause qemu_reset_requested_get(void)
+{
+    return reset_requested;
+}
+
+static int qemu_shutdown_requested(void)
+{
+    return qatomic_xchg(&shutdown_requested, SHUTDOWN_CAUSE_NONE);
+}
+
+static void qemu_kill_report(void)
+{
+    if (!qtest_driver() && shutdown_signal) {
+        if (shutdown_pid == 0) {
+            /* This happens for eg ^C at the terminal, so it's worth
+             * avoiding printing an odd message in that case.
+             */
+            error_report("terminating on signal %d", shutdown_signal);
+        } else {
+            char *shutdown_cmd = qemu_get_pid_name(shutdown_pid);
+
+            error_report("terminating on signal %d from pid " FMT_pid " (%s)",
+                         shutdown_signal, shutdown_pid,
+                         shutdown_cmd ? shutdown_cmd : "<unknown process>");
+            g_free(shutdown_cmd);
+        }
+        shutdown_signal = 0;
+    }
+}
+
+static ShutdownCause qemu_reset_requested(void)
+{
+    ShutdownCause r = reset_requested;
+
+    if (r && replay_checkpoint(CHECKPOINT_RESET_REQUESTED)) {
+        reset_requested = SHUTDOWN_CAUSE_NONE;
+        return r;
+    }
+    return SHUTDOWN_CAUSE_NONE;
+}
+
+static int qemu_suspend_requested(void)
+{
+    int r = suspend_requested;
+    if (r && replay_checkpoint(CHECKPOINT_SUSPEND_REQUESTED)) {
+        suspend_requested = 0;
+        return r;
+    }
+    return false;
+}
+
+static WakeupReason qemu_wakeup_requested(void)
+{
+    return wakeup_reason;
+}
+
+static int qemu_powerdown_requested(void)
+{
+    int r = powerdown_requested;
+    powerdown_requested = 0;
+    return r;
+}
+
+static int qemu_debug_requested(void)
+{
+    int r = debug_requested;
+    debug_requested = 0;
+    return r;
+}
+
+/*
+ * Reset the VM. Issue an event unless @reason is SHUTDOWN_CAUSE_NONE.
+ */
+void qemu_system_reset(ShutdownCause reason)
+{
+    MachineClass *mc;
+
+    mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL;
+
+    cpu_synchronize_all_states();
+
+    if (mc && mc->reset) {
+        mc->reset(current_machine);
+    } else {
+        qemu_devices_reset();
+    }
+    if (reason && reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) {
+        qapi_event_send_reset(shutdown_caused_by_guest(reason), reason);
+    }
+    cpu_synchronize_all_post_reset();
+}
+
+/*
+ * Wake the VM after suspend.
+ */
+static void qemu_system_wakeup(void)
+{
+    MachineClass *mc;
+
+    mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL;
+
+    if (mc && mc->wakeup) {
+        mc->wakeup(current_machine);
+    }
+}
+
+void qemu_system_guest_panicked(GuestPanicInformation *info)
+{
+    qemu_log_mask(LOG_GUEST_ERROR, "Guest crashed");
+
+    if (current_cpu) {
+        current_cpu->crash_occurred = true;
+    }
+    qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE,
+                                   !!info, info);
+    vm_stop(RUN_STATE_GUEST_PANICKED);
+    if (!no_shutdown) {
+        qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_POWEROFF,
+                                       !!info, info);
+        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_PANIC);
+    }
+
+    if (info) {
+        if (info->type == GUEST_PANIC_INFORMATION_TYPE_HYPER_V) {
+            qemu_log_mask(LOG_GUEST_ERROR, "\nHV crash parameters: (%#"PRIx64
+                          " %#"PRIx64" %#"PRIx64" %#"PRIx64" %#"PRIx64")\n",
+                          info->u.hyper_v.arg1,
+                          info->u.hyper_v.arg2,
+                          info->u.hyper_v.arg3,
+                          info->u.hyper_v.arg4,
+                          info->u.hyper_v.arg5);
+        } else if (info->type == GUEST_PANIC_INFORMATION_TYPE_S390) {
+            qemu_log_mask(LOG_GUEST_ERROR, " on cpu %d: %s\n"
+                          "PSW: 0x%016" PRIx64 " 0x%016" PRIx64"\n",
+                          info->u.s390.core,
+                          S390CrashReason_str(info->u.s390.reason),
+                          info->u.s390.psw_mask,
+                          info->u.s390.psw_addr);
+        }
+        qapi_free_GuestPanicInformation(info);
+    }
+}
+
+void qemu_system_guest_crashloaded(GuestPanicInformation *info)
+{
+    qemu_log_mask(LOG_GUEST_ERROR, "Guest crash loaded");
+
+    qapi_event_send_guest_crashloaded(GUEST_PANIC_ACTION_RUN,
+                                   !!info, info);
+
+    if (info) {
+        qapi_free_GuestPanicInformation(info);
+    }
+}
+
+void qemu_system_reset_request(ShutdownCause reason)
+{
+    if (no_reboot && reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) {
+        shutdown_requested = reason;
+    } else {
+        reset_requested = reason;
+    }
+    cpu_stop_current();
+    qemu_notify_event();
+}
+
+static void qemu_system_suspend(void)
+{
+    pause_all_vcpus();
+    notifier_list_notify(&suspend_notifiers, NULL);
+    runstate_set(RUN_STATE_SUSPENDED);
+    qapi_event_send_suspend();
+}
+
+void qemu_system_suspend_request(void)
+{
+    if (runstate_check(RUN_STATE_SUSPENDED)) {
+        return;
+    }
+    suspend_requested = 1;
+    cpu_stop_current();
+    qemu_notify_event();
+}
+
+void qemu_register_suspend_notifier(Notifier *notifier)
+{
+    notifier_list_add(&suspend_notifiers, notifier);
+}
+
+void qemu_system_wakeup_request(WakeupReason reason, Error **errp)
+{
+    trace_system_wakeup_request(reason);
+
+    if (!runstate_check(RUN_STATE_SUSPENDED)) {
+        error_setg(errp,
+                   "Unable to wake up: guest is not in suspended state");
+        return;
+    }
+    if (!(wakeup_reason_mask & (1 << reason))) {
+        return;
+    }
+    runstate_set(RUN_STATE_RUNNING);
+    wakeup_reason = reason;
+    qemu_notify_event();
+}
+
+void qemu_system_wakeup_enable(WakeupReason reason, bool enabled)
+{
+    if (enabled) {
+        wakeup_reason_mask |= (1 << reason);
+    } else {
+        wakeup_reason_mask &= ~(1 << reason);
+    }
+}
+
+void qemu_register_wakeup_notifier(Notifier *notifier)
+{
+    notifier_list_add(&wakeup_notifiers, notifier);
+}
+
+static bool wakeup_suspend_enabled;
+
+void qemu_register_wakeup_support(void)
+{
+    wakeup_suspend_enabled = true;
+}
+
+bool qemu_wakeup_suspend_enabled(void)
+{
+    return wakeup_suspend_enabled;
+}
+
+void qemu_system_killed(int signal, pid_t pid)
+{
+    shutdown_signal = signal;
+    shutdown_pid = pid;
+    no_shutdown = 0;
+
+    /* Cannot call qemu_system_shutdown_request directly because
+     * we are in a signal handler.
+     */
+    shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL;
+    qemu_notify_event();
+}
+
+void qemu_system_shutdown_request(ShutdownCause reason)
+{
+    trace_qemu_system_shutdown_request(reason);
+    replay_shutdown_request(reason);
+    shutdown_requested = reason;
+    qemu_notify_event();
+}
+
+static void qemu_system_powerdown(void)
+{
+    qapi_event_send_powerdown();
+    notifier_list_notify(&powerdown_notifiers, NULL);
+}
+
+static void qemu_system_shutdown(ShutdownCause cause)
+{
+    qapi_event_send_shutdown(shutdown_caused_by_guest(cause), cause);
+    notifier_list_notify(&shutdown_notifiers, &cause);
+}
+
+void qemu_system_powerdown_request(void)
+{
+    trace_qemu_system_powerdown_request();
+    powerdown_requested = 1;
+    qemu_notify_event();
+}
+
+void qemu_register_powerdown_notifier(Notifier *notifier)
+{
+    notifier_list_add(&powerdown_notifiers, notifier);
+}
+
+void qemu_register_shutdown_notifier(Notifier *notifier)
+{
+    notifier_list_add(&shutdown_notifiers, notifier);
+}
+
+void qemu_system_debug_request(void)
+{
+    debug_requested = 1;
+    qemu_notify_event();
+}
+
+static bool main_loop_should_exit(void)
+{
+    RunState r;
+    ShutdownCause request;
+
+    if (qemu_debug_requested()) {
+        vm_stop(RUN_STATE_DEBUG);
+    }
+    if (qemu_suspend_requested()) {
+        qemu_system_suspend();
+    }
+    request = qemu_shutdown_requested();
+    if (request) {
+        qemu_kill_report();
+        qemu_system_shutdown(request);
+        if (no_shutdown) {
+            vm_stop(RUN_STATE_SHUTDOWN);
+        } else {
+            return true;
+        }
+    }
+    request = qemu_reset_requested();
+    if (request) {
+        pause_all_vcpus();
+        qemu_system_reset(request);
+        resume_all_vcpus();
+        /*
+         * runstate can change in pause_all_vcpus()
+         * as iothread mutex is unlocked
+         */
+        if (!runstate_check(RUN_STATE_RUNNING) &&
+                !runstate_check(RUN_STATE_INMIGRATE) &&
+                !runstate_check(RUN_STATE_FINISH_MIGRATE)) {
+            runstate_set(RUN_STATE_PRELAUNCH);
+        }
+    }
+    if (qemu_wakeup_requested()) {
+        pause_all_vcpus();
+        qemu_system_wakeup();
+        notifier_list_notify(&wakeup_notifiers, &wakeup_reason);
+        wakeup_reason = QEMU_WAKEUP_REASON_NONE;
+        resume_all_vcpus();
+        qapi_event_send_wakeup();
+    }
+    if (qemu_powerdown_requested()) {
+        qemu_system_powerdown();
+    }
+    if (qemu_vmstop_requested(&r)) {
+        vm_stop(r);
+    }
+    return false;
+}
+
+void qemu_main_loop(void)
+{
+#ifdef CONFIG_PROFILER
+    int64_t ti;
+#endif
+    while (!main_loop_should_exit()) {
+#ifdef CONFIG_PROFILER
+        ti = profile_getclock();
+#endif
+        main_loop_wait(false);
+#ifdef CONFIG_PROFILER
+        dev_time += profile_getclock() - ti;
+#endif
+    }
+}
+
+void qemu_add_exit_notifier(Notifier *notify)
+{
+    notifier_list_add(&exit_notifiers, notify);
+}
+
+void qemu_remove_exit_notifier(Notifier *notify)
+{
+    notifier_remove(notify);
+}
+
+static void qemu_run_exit_notifiers(void)
+{
+    notifier_list_notify(&exit_notifiers, NULL);
+}
+
+void qemu_init_subsystems(void)
+{
+    Error *err;
+
+    os_set_line_buffering();
+
+    module_call_init(MODULE_INIT_TRACE);
+
+    qemu_init_cpu_list();
+    qemu_init_cpu_loop();
+    qemu_mutex_lock_iothread();
+
+    atexit(qemu_run_exit_notifiers);
+
+    module_call_init(MODULE_INIT_QOM);
+    module_call_init(MODULE_INIT_MIGRATION);
+
+    runstate_init();
+    precopy_infrastructure_init();
+    postcopy_infrastructure_init();
+    monitor_init_globals();
+
+    if (qcrypto_init(&err) < 0) {
+        error_reportf_err(err, "cannot initialize crypto: ");
+        exit(1);
+    }
+
+    os_setup_early_signal_handling();
+
+    bdrv_init_with_whitelist();
+    socket_init();
+}
+
+
+void qemu_cleanup(void)
+{
+    gdbserver_cleanup();
+
+    /*
+     * cleaning up the migration object cancels any existing migration
+     * try to do this early so that it also stops using devices.
+     */
+    migration_shutdown();
+
+    /*
+     * We must cancel all block jobs while the block layer is drained,
+     * or cancelling will be affected by throttling and thus may block
+     * for an extended period of time.
+     * vm_shutdown() will bdrv_drain_all(), so we may as well include
+     * it in the drained section.
+     * We do not need to end this section, because we do not want any
+     * requests happening from here on anyway.
+     */
+    bdrv_drain_all_begin();
+
+    /* No more vcpu or device emulation activity beyond this point */
+    vm_shutdown();
+    replay_finish();
+
+    job_cancel_sync_all();
+    bdrv_close_all();
+
+    /* vhost-user must be cleaned up before chardevs.  */
+    tpm_cleanup();
+    net_cleanup();
+    audio_cleanup();
+    monitor_cleanup();
+    qemu_chr_cleanup();
+    user_creatable_cleanup();
+    /* TODO: unref root container, check all devices are ok */
+}
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 3dfac8299b..6282ae2101 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -112,7 +112,6 @@
 #include "qapi/qapi-commands-block-core.h"
 #include "qapi/qapi-commands-migration.h"
 #include "qapi/qapi-commands-misc.h"
-#include "qapi/qapi-commands-run-state.h"
 #include "qapi/qapi-commands-ui.h"
 #include "qapi/qmp/qerror.h"
 #include "sysemu/iothread.h"
@@ -162,7 +161,7 @@ Chardev *parallel_hds[MAX_PARALLEL_PORTS];
 int win2k_install_hack = 0;
 int singlestep = 0;
 int fd_bootchk = 1;
-static int no_reboot;
+int no_reboot;
 int no_shutdown = 0;
 int graphic_rotate = 0;
 static const char *watchdog;
@@ -189,9 +188,6 @@ static const char *qtest_log;
 QemuUUID qemu_uuid;
 bool qemu_uuid_set;
 
-static NotifierList exit_notifiers =
-    NOTIFIER_LIST_INITIALIZER(exit_notifiers);
-
 uint32_t xen_domid;
 enum xen_mode xen_mode = XEN_EMULATE;
 bool xen_domid_restrict;
@@ -533,12 +529,6 @@ const char *qemu_get_vm_name(void)
     return qemu_name;
 }
 
-static void res_free(void)
-{
-    g_free(boot_splash_filedata);
-    boot_splash_filedata = NULL;
-}
-
 static int default_driver_check(void *opaque, QemuOpts *opts, Error **errp)
 {
     const char *driver = qemu_opt_get(opts, "driver");
@@ -554,206 +544,6 @@ static int default_driver_check(void *opaque, QemuOpts *opts, Error **errp)
     return 0;
 }
 
-/***********************************************************/
-/* QEMU state */
-
-static RunState current_run_state = RUN_STATE_PRELAUNCH;
-
-/* We use RUN_STATE__MAX but any invalid value will do */
-static RunState vmstop_requested = RUN_STATE__MAX;
-static QemuMutex vmstop_lock;
-
-typedef struct {
-    RunState from;
-    RunState to;
-} RunStateTransition;
-
-static const RunStateTransition runstate_transitions_def[] = {
-    { RUN_STATE_PRELAUNCH, RUN_STATE_INMIGRATE },
-
-    { RUN_STATE_DEBUG, RUN_STATE_RUNNING },
-    { RUN_STATE_DEBUG, RUN_STATE_FINISH_MIGRATE },
-    { RUN_STATE_DEBUG, RUN_STATE_PRELAUNCH },
-
-    { RUN_STATE_INMIGRATE, RUN_STATE_INTERNAL_ERROR },
-    { RUN_STATE_INMIGRATE, RUN_STATE_IO_ERROR },
-    { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED },
-    { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING },
-    { RUN_STATE_INMIGRATE, RUN_STATE_SHUTDOWN },
-    { RUN_STATE_INMIGRATE, RUN_STATE_SUSPENDED },
-    { RUN_STATE_INMIGRATE, RUN_STATE_WATCHDOG },
-    { RUN_STATE_INMIGRATE, RUN_STATE_GUEST_PANICKED },
-    { RUN_STATE_INMIGRATE, RUN_STATE_FINISH_MIGRATE },
-    { RUN_STATE_INMIGRATE, RUN_STATE_PRELAUNCH },
-    { RUN_STATE_INMIGRATE, RUN_STATE_POSTMIGRATE },
-    { RUN_STATE_INMIGRATE, RUN_STATE_COLO },
-
-    { RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED },
-    { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE },
-    { RUN_STATE_INTERNAL_ERROR, RUN_STATE_PRELAUNCH },
-
-    { RUN_STATE_IO_ERROR, RUN_STATE_RUNNING },
-    { RUN_STATE_IO_ERROR, RUN_STATE_FINISH_MIGRATE },
-    { RUN_STATE_IO_ERROR, RUN_STATE_PRELAUNCH },
-
-    { RUN_STATE_PAUSED, RUN_STATE_RUNNING },
-    { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE },
-    { RUN_STATE_PAUSED, RUN_STATE_POSTMIGRATE },
-    { RUN_STATE_PAUSED, RUN_STATE_PRELAUNCH },
-    { RUN_STATE_PAUSED, RUN_STATE_COLO},
-
-    { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING },
-    { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE },
-    { RUN_STATE_POSTMIGRATE, RUN_STATE_PRELAUNCH },
-
-    { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING },
-    { RUN_STATE_PRELAUNCH, RUN_STATE_FINISH_MIGRATE },
-    { RUN_STATE_PRELAUNCH, RUN_STATE_INMIGRATE },
-
-    { RUN_STATE_FINISH_MIGRATE, RUN_STATE_RUNNING },
-    { RUN_STATE_FINISH_MIGRATE, RUN_STATE_PAUSED },
-    { RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE },
-    { RUN_STATE_FINISH_MIGRATE, RUN_STATE_PRELAUNCH },
-    { RUN_STATE_FINISH_MIGRATE, RUN_STATE_COLO},
-
-    { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING },
-    { RUN_STATE_RESTORE_VM, RUN_STATE_PRELAUNCH },
-
-    { RUN_STATE_COLO, RUN_STATE_RUNNING },
-
-    { RUN_STATE_RUNNING, RUN_STATE_DEBUG },
-    { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR },
-    { RUN_STATE_RUNNING, RUN_STATE_IO_ERROR },
-    { RUN_STATE_RUNNING, RUN_STATE_PAUSED },
-    { RUN_STATE_RUNNING, RUN_STATE_FINISH_MIGRATE },
-    { RUN_STATE_RUNNING, RUN_STATE_RESTORE_VM },
-    { RUN_STATE_RUNNING, RUN_STATE_SAVE_VM },
-    { RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN },
-    { RUN_STATE_RUNNING, RUN_STATE_WATCHDOG },
-    { RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED },
-    { RUN_STATE_RUNNING, RUN_STATE_COLO},
-
-    { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING },
-
-    { RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED },
-    { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE },
-    { RUN_STATE_SHUTDOWN, RUN_STATE_PRELAUNCH },
-    { RUN_STATE_SHUTDOWN, RUN_STATE_COLO },
-
-    { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED },
-    { RUN_STATE_RUNNING, RUN_STATE_SUSPENDED },
-    { RUN_STATE_SUSPENDED, RUN_STATE_RUNNING },
-    { RUN_STATE_SUSPENDED, RUN_STATE_FINISH_MIGRATE },
-    { RUN_STATE_SUSPENDED, RUN_STATE_PRELAUNCH },
-    { RUN_STATE_SUSPENDED, RUN_STATE_COLO},
-
-    { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING },
-    { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE },
-    { RUN_STATE_WATCHDOG, RUN_STATE_PRELAUNCH },
-    { RUN_STATE_WATCHDOG, RUN_STATE_COLO},
-
-    { RUN_STATE_GUEST_PANICKED, RUN_STATE_RUNNING },
-    { RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE },
-    { RUN_STATE_GUEST_PANICKED, RUN_STATE_PRELAUNCH },
-
-    { RUN_STATE__MAX, RUN_STATE__MAX },
-};
-
-static bool runstate_valid_transitions[RUN_STATE__MAX][RUN_STATE__MAX];
-
-bool runstate_check(RunState state)
-{
-    return current_run_state == state;
-}
-
-bool runstate_store(char *str, size_t size)
-{
-    const char *state = RunState_str(current_run_state);
-    size_t len = strlen(state) + 1;
-
-    if (len > size) {
-        return false;
-    }
-    memcpy(str, state, len);
-    return true;
-}
-
-static void runstate_init(void)
-{
-    const RunStateTransition *p;
-
-    memset(&runstate_valid_transitions, 0, sizeof(runstate_valid_transitions));
-    for (p = &runstate_transitions_def[0]; p->from != RUN_STATE__MAX; p++) {
-        runstate_valid_transitions[p->from][p->to] = true;
-    }
-
-    qemu_mutex_init(&vmstop_lock);
-}
-
-/* This function will abort() on invalid state transitions */
-void runstate_set(RunState new_state)
-{
-    assert(new_state < RUN_STATE__MAX);
-
-    trace_runstate_set(current_run_state, RunState_str(current_run_state),
-                       new_state, RunState_str(new_state));
-
-    if (current_run_state == new_state) {
-        return;
-    }
-
-    if (!runstate_valid_transitions[current_run_state][new_state]) {
-        error_report("invalid runstate transition: '%s' -> '%s'",
-                     RunState_str(current_run_state),
-                     RunState_str(new_state));
-        abort();
-    }
-
-    current_run_state = new_state;
-}
-
-int runstate_is_running(void)
-{
-    return runstate_check(RUN_STATE_RUNNING);
-}
-
-bool runstate_needs_reset(void)
-{
-    return runstate_check(RUN_STATE_INTERNAL_ERROR) ||
-        runstate_check(RUN_STATE_SHUTDOWN);
-}
-
-StatusInfo *qmp_query_status(Error **errp)
-{
-    StatusInfo *info = g_malloc0(sizeof(*info));
-
-    info->running = runstate_is_running();
-    info->singlestep = singlestep;
-    info->status = current_run_state;
-
-    return info;
-}
-
-bool qemu_vmstop_requested(RunState *r)
-{
-    qemu_mutex_lock(&vmstop_lock);
-    *r = vmstop_requested;
-    vmstop_requested = RUN_STATE__MAX;
-    qemu_mutex_unlock(&vmstop_lock);
-    return *r < RUN_STATE__MAX;
-}
-
-void qemu_system_vmstop_request_prepare(void)
-{
-    qemu_mutex_lock(&vmstop_lock);
-}
-
-void qemu_system_vmstop_request(RunState state)
-{
-    vmstop_requested = state;
-    qemu_mutex_unlock(&vmstop_lock);
-    qemu_notify_event();
-}
 static int parse_name(void *opaque, QemuOpts *opts, Error **errp)
 {
     const char *proc_name;
@@ -1070,458 +860,6 @@ static int machine_help_func(QemuOpts *opts, MachineState *machine)
     return 1;
 }
 
-struct VMChangeStateEntry {
-    VMChangeStateHandler *cb;
-    void *opaque;
-    QTAILQ_ENTRY(VMChangeStateEntry) entries;
-    int priority;
-};
-
-static QTAILQ_HEAD(, VMChangeStateEntry) vm_change_state_head =
-    QTAILQ_HEAD_INITIALIZER(vm_change_state_head);
-
-/**
- * qemu_add_vm_change_state_handler_prio:
- * @cb: the callback to invoke
- * @opaque: user data passed to the callback
- * @priority: low priorities execute first when the vm runs and the reverse is
- *            true when the vm stops
- *
- * Register a callback function that is invoked when the vm starts or stops
- * running.
- *
- * Returns: an entry to be freed using qemu_del_vm_change_state_handler()
- */
-VMChangeStateEntry *qemu_add_vm_change_state_handler_prio(
-        VMChangeStateHandler *cb, void *opaque, int priority)
-{
-    VMChangeStateEntry *e;
-    VMChangeStateEntry *other;
-
-    e = g_malloc0(sizeof(*e));
-    e->cb = cb;
-    e->opaque = opaque;
-    e->priority = priority;
-
-    /* Keep list sorted in ascending priority order */
-    QTAILQ_FOREACH(other, &vm_change_state_head, entries) {
-        if (priority < other->priority) {
-            QTAILQ_INSERT_BEFORE(other, e, entries);
-            return e;
-        }
-    }
-
-    QTAILQ_INSERT_TAIL(&vm_change_state_head, e, entries);
-    return e;
-}
-
-VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
-                                                     void *opaque)
-{
-    return qemu_add_vm_change_state_handler_prio(cb, opaque, 0);
-}
-
-void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
-{
-    QTAILQ_REMOVE(&vm_change_state_head, e, entries);
-    g_free(e);
-}
-
-void vm_state_notify(int running, RunState state)
-{
-    VMChangeStateEntry *e, *next;
-
-    trace_vm_state_notify(running, state, RunState_str(state));
-
-    if (running) {
-        QTAILQ_FOREACH_SAFE(e, &vm_change_state_head, entries, next) {
-            e->cb(e->opaque, running, state);
-        }
-    } else {
-        QTAILQ_FOREACH_REVERSE_SAFE(e, &vm_change_state_head, entries, next) {
-            e->cb(e->opaque, running, state);
-        }
-    }
-}
-
-static ShutdownCause reset_requested;
-static ShutdownCause shutdown_requested;
-static int shutdown_signal;
-static pid_t shutdown_pid;
-static int powerdown_requested;
-static int debug_requested;
-static int suspend_requested;
-static WakeupReason wakeup_reason;
-static NotifierList powerdown_notifiers =
-    NOTIFIER_LIST_INITIALIZER(powerdown_notifiers);
-static NotifierList suspend_notifiers =
-    NOTIFIER_LIST_INITIALIZER(suspend_notifiers);
-static NotifierList wakeup_notifiers =
-    NOTIFIER_LIST_INITIALIZER(wakeup_notifiers);
-static NotifierList shutdown_notifiers =
-    NOTIFIER_LIST_INITIALIZER(shutdown_notifiers);
-static uint32_t wakeup_reason_mask = ~(1 << QEMU_WAKEUP_REASON_NONE);
-
-ShutdownCause qemu_shutdown_requested_get(void)
-{
-    return shutdown_requested;
-}
-
-ShutdownCause qemu_reset_requested_get(void)
-{
-    return reset_requested;
-}
-
-static int qemu_shutdown_requested(void)
-{
-    return qatomic_xchg(&shutdown_requested, SHUTDOWN_CAUSE_NONE);
-}
-
-static void qemu_kill_report(void)
-{
-    if (!qtest_driver() && shutdown_signal) {
-        if (shutdown_pid == 0) {
-            /* This happens for eg ^C at the terminal, so it's worth
-             * avoiding printing an odd message in that case.
-             */
-            error_report("terminating on signal %d", shutdown_signal);
-        } else {
-            char *shutdown_cmd = qemu_get_pid_name(shutdown_pid);
-
-            error_report("terminating on signal %d from pid " FMT_pid " (%s)",
-                         shutdown_signal, shutdown_pid,
-                         shutdown_cmd ? shutdown_cmd : "<unknown process>");
-            g_free(shutdown_cmd);
-        }
-        shutdown_signal = 0;
-    }
-}
-
-static ShutdownCause qemu_reset_requested(void)
-{
-    ShutdownCause r = reset_requested;
-
-    if (r && replay_checkpoint(CHECKPOINT_RESET_REQUESTED)) {
-        reset_requested = SHUTDOWN_CAUSE_NONE;
-        return r;
-    }
-    return SHUTDOWN_CAUSE_NONE;
-}
-
-static int qemu_suspend_requested(void)
-{
-    int r = suspend_requested;
-    if (r && replay_checkpoint(CHECKPOINT_SUSPEND_REQUESTED)) {
-        suspend_requested = 0;
-        return r;
-    }
-    return false;
-}
-
-static WakeupReason qemu_wakeup_requested(void)
-{
-    return wakeup_reason;
-}
-
-static int qemu_powerdown_requested(void)
-{
-    int r = powerdown_requested;
-    powerdown_requested = 0;
-    return r;
-}
-
-static int qemu_debug_requested(void)
-{
-    int r = debug_requested;
-    debug_requested = 0;
-    return r;
-}
-
-/*
- * Reset the VM. Issue an event unless @reason is SHUTDOWN_CAUSE_NONE.
- */
-void qemu_system_reset(ShutdownCause reason)
-{
-    MachineClass *mc;
-
-    mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL;
-
-    cpu_synchronize_all_states();
-
-    if (mc && mc->reset) {
-        mc->reset(current_machine);
-    } else {
-        qemu_devices_reset();
-    }
-    if (reason && reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) {
-        qapi_event_send_reset(shutdown_caused_by_guest(reason), reason);
-    }
-    cpu_synchronize_all_post_reset();
-}
-
-/*
- * Wake the VM after suspend.
- */
-static void qemu_system_wakeup(void)
-{
-    MachineClass *mc;
-
-    mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL;
-
-    if (mc && mc->wakeup) {
-        mc->wakeup(current_machine);
-    }
-}
-
-void qemu_system_guest_panicked(GuestPanicInformation *info)
-{
-    qemu_log_mask(LOG_GUEST_ERROR, "Guest crashed");
-
-    if (current_cpu) {
-        current_cpu->crash_occurred = true;
-    }
-    qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE,
-                                   !!info, info);
-    vm_stop(RUN_STATE_GUEST_PANICKED);
-    if (!no_shutdown) {
-        qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_POWEROFF,
-                                       !!info, info);
-        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_PANIC);
-    }
-
-    if (info) {
-        if (info->type == GUEST_PANIC_INFORMATION_TYPE_HYPER_V) {
-            qemu_log_mask(LOG_GUEST_ERROR, "\nHV crash parameters: (%#"PRIx64
-                          " %#"PRIx64" %#"PRIx64" %#"PRIx64" %#"PRIx64")\n",
-                          info->u.hyper_v.arg1,
-                          info->u.hyper_v.arg2,
-                          info->u.hyper_v.arg3,
-                          info->u.hyper_v.arg4,
-                          info->u.hyper_v.arg5);
-        } else if (info->type == GUEST_PANIC_INFORMATION_TYPE_S390) {
-            qemu_log_mask(LOG_GUEST_ERROR, " on cpu %d: %s\n"
-                          "PSW: 0x%016" PRIx64 " 0x%016" PRIx64"\n",
-                          info->u.s390.core,
-                          S390CrashReason_str(info->u.s390.reason),
-                          info->u.s390.psw_mask,
-                          info->u.s390.psw_addr);
-        }
-        qapi_free_GuestPanicInformation(info);
-    }
-}
-
-void qemu_system_guest_crashloaded(GuestPanicInformation *info)
-{
-    qemu_log_mask(LOG_GUEST_ERROR, "Guest crash loaded");
-
-    qapi_event_send_guest_crashloaded(GUEST_PANIC_ACTION_RUN,
-                                   !!info, info);
-
-    if (info) {
-        qapi_free_GuestPanicInformation(info);
-    }
-}
-
-void qemu_system_reset_request(ShutdownCause reason)
-{
-    if (no_reboot && reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) {
-        shutdown_requested = reason;
-    } else {
-        reset_requested = reason;
-    }
-    cpu_stop_current();
-    qemu_notify_event();
-}
-
-static void qemu_system_suspend(void)
-{
-    pause_all_vcpus();
-    notifier_list_notify(&suspend_notifiers, NULL);
-    runstate_set(RUN_STATE_SUSPENDED);
-    qapi_event_send_suspend();
-}
-
-void qemu_system_suspend_request(void)
-{
-    if (runstate_check(RUN_STATE_SUSPENDED)) {
-        return;
-    }
-    suspend_requested = 1;
-    cpu_stop_current();
-    qemu_notify_event();
-}
-
-void qemu_register_suspend_notifier(Notifier *notifier)
-{
-    notifier_list_add(&suspend_notifiers, notifier);
-}
-
-void qemu_system_wakeup_request(WakeupReason reason, Error **errp)
-{
-    trace_system_wakeup_request(reason);
-
-    if (!runstate_check(RUN_STATE_SUSPENDED)) {
-        error_setg(errp,
-                   "Unable to wake up: guest is not in suspended state");
-        return;
-    }
-    if (!(wakeup_reason_mask & (1 << reason))) {
-        return;
-    }
-    runstate_set(RUN_STATE_RUNNING);
-    wakeup_reason = reason;
-    qemu_notify_event();
-}
-
-void qemu_system_wakeup_enable(WakeupReason reason, bool enabled)
-{
-    if (enabled) {
-        wakeup_reason_mask |= (1 << reason);
-    } else {
-        wakeup_reason_mask &= ~(1 << reason);
-    }
-}
-
-void qemu_register_wakeup_notifier(Notifier *notifier)
-{
-    notifier_list_add(&wakeup_notifiers, notifier);
-}
-
-void qemu_register_wakeup_support(void)
-{
-    wakeup_suspend_enabled = true;
-}
-
-bool qemu_wakeup_suspend_enabled(void)
-{
-    return wakeup_suspend_enabled;
-}
-
-void qemu_system_killed(int signal, pid_t pid)
-{
-    shutdown_signal = signal;
-    shutdown_pid = pid;
-    no_shutdown = 0;
-
-    /* Cannot call qemu_system_shutdown_request directly because
-     * we are in a signal handler.
-     */
-    shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL;
-    qemu_notify_event();
-}
-
-void qemu_system_shutdown_request(ShutdownCause reason)
-{
-    trace_qemu_system_shutdown_request(reason);
-    replay_shutdown_request(reason);
-    shutdown_requested = reason;
-    qemu_notify_event();
-}
-
-static void qemu_system_powerdown(void)
-{
-    qapi_event_send_powerdown();
-    notifier_list_notify(&powerdown_notifiers, NULL);
-}
-
-static void qemu_system_shutdown(ShutdownCause cause)
-{
-    qapi_event_send_shutdown(shutdown_caused_by_guest(cause), cause);
-    notifier_list_notify(&shutdown_notifiers, &cause);
-}
-
-void qemu_system_powerdown_request(void)
-{
-    trace_qemu_system_powerdown_request();
-    powerdown_requested = 1;
-    qemu_notify_event();
-}
-
-void qemu_register_powerdown_notifier(Notifier *notifier)
-{
-    notifier_list_add(&powerdown_notifiers, notifier);
-}
-
-void qemu_register_shutdown_notifier(Notifier *notifier)
-{
-    notifier_list_add(&shutdown_notifiers, notifier);
-}
-
-void qemu_system_debug_request(void)
-{
-    debug_requested = 1;
-    qemu_notify_event();
-}
-
-static bool main_loop_should_exit(void)
-{
-    RunState r;
-    ShutdownCause request;
-
-    if (qemu_debug_requested()) {
-        vm_stop(RUN_STATE_DEBUG);
-    }
-    if (qemu_suspend_requested()) {
-        qemu_system_suspend();
-    }
-    request = qemu_shutdown_requested();
-    if (request) {
-        qemu_kill_report();
-        qemu_system_shutdown(request);
-        if (no_shutdown) {
-            vm_stop(RUN_STATE_SHUTDOWN);
-        } else {
-            return true;
-        }
-    }
-    request = qemu_reset_requested();
-    if (request) {
-        pause_all_vcpus();
-        qemu_system_reset(request);
-        resume_all_vcpus();
-        /*
-         * runstate can change in pause_all_vcpus()
-         * as iothread mutex is unlocked
-         */
-        if (!runstate_check(RUN_STATE_RUNNING) &&
-                !runstate_check(RUN_STATE_INMIGRATE) &&
-                !runstate_check(RUN_STATE_FINISH_MIGRATE)) {
-            runstate_set(RUN_STATE_PRELAUNCH);
-        }
-    }
-    if (qemu_wakeup_requested()) {
-        pause_all_vcpus();
-        qemu_system_wakeup();
-        notifier_list_notify(&wakeup_notifiers, &wakeup_reason);
-        wakeup_reason = QEMU_WAKEUP_REASON_NONE;
-        resume_all_vcpus();
-        qapi_event_send_wakeup();
-    }
-    if (qemu_powerdown_requested()) {
-        qemu_system_powerdown();
-    }
-    if (qemu_vmstop_requested(&r)) {
-        vm_stop(r);
-    }
-    return false;
-}
-
-void qemu_main_loop(void)
-{
-#ifdef CONFIG_PROFILER
-    int64_t ti;
-#endif
-    while (!main_loop_should_exit()) {
-#ifdef CONFIG_PROFILER
-        ti = profile_getclock();
-#endif
-        main_loop_wait(false);
-#ifdef CONFIG_PROFILER
-        dev_time += profile_getclock() - ti;
-#endif
-    }
-}
-
 static void version(void)
 {
     printf("QEMU emulator version " QEMU_FULL_VERSION "\n"
@@ -2241,21 +1579,6 @@ static MachineClass *machine_parse(const char *name, GSList *machines)
     return mc;
 }
 
-void qemu_add_exit_notifier(Notifier *notify)
-{
-    notifier_list_add(&exit_notifiers, notify);
-}
-
-void qemu_remove_exit_notifier(Notifier *notify)
-{
-    notifier_remove(notify);
-}
-
-static void qemu_run_exit_notifiers(void)
-{
-    notifier_list_notify(&exit_notifiers, NULL);
-}
-
 static const char *pid_file;
 static Notifier qemu_unlink_pidfile_notifier;
 
@@ -3101,39 +2424,6 @@ static void qemu_maybe_daemonize(const char *pid_file)
     qemu_add_exit_notifier(&qemu_unlink_pidfile_notifier);
 }
 
-static void qemu_init_subsystems(void)
-{
-    Error *err;
-
-    os_set_line_buffering();
-
-    module_call_init(MODULE_INIT_TRACE);
-
-    qemu_init_cpu_list();
-    qemu_init_cpu_loop();
-    qemu_mutex_lock_iothread();
-
-    atexit(qemu_run_exit_notifiers);
-
-    module_call_init(MODULE_INIT_QOM);
-    module_call_init(MODULE_INIT_MIGRATION);
-
-    runstate_init();
-    precopy_infrastructure_init();
-    postcopy_infrastructure_init();
-    monitor_init_globals();
-
-    if (qcrypto_init(&err) < 0) {
-        error_reportf_err(err, "cannot initialize crypto: ");
-        exit(1);
-    }
-
-    os_setup_early_signal_handling();
-
-    bdrv_init_with_whitelist();
-    socket_init();
-}
-
 static void qemu_init_displays(void)
 {
     DisplayState *ds;
@@ -4310,43 +3600,3 @@ void qemu_init(int argc, char **argv, char **envp)
     accel_setup_post(current_machine);
     os_setup_post();
 }
-
-void qemu_cleanup(void)
-{
-    gdbserver_cleanup();
-
-    /*
-     * cleaning up the migration object cancels any existing migration
-     * try to do this early so that it also stops using devices.
-     */
-    migration_shutdown();
-
-    /*
-     * We must cancel all block jobs while the block layer is drained,
-     * or cancelling will be affected by throttling and thus may block
-     * for an extended period of time.
-     * vm_shutdown() will bdrv_drain_all(), so we may as well include
-     * it in the drained section.
-     * We do not need to end this section, because we do not want any
-     * requests happening from here on anyway.
-     */
-    bdrv_drain_all_begin();
-
-    /* No more vcpu or device emulation activity beyond this point */
-    vm_shutdown();
-    replay_finish();
-
-    job_cancel_sync_all();
-    bdrv_close_all();
-
-    res_free();
-
-    /* vhost-user must be cleaned up before chardevs.  */
-    tpm_cleanup();
-    net_cleanup();
-    audio_cleanup();
-    monitor_cleanup();
-    qemu_chr_cleanup();
-    user_creatable_cleanup();
-    /* TODO: unref root container, check all devices are ok */
-}
-- 
2.26.2




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

* [PATCH 05/15] vl: extract softmmu/globals.c
  2020-12-02  8:18 [PATCH 00/15] Finish cleaning up qemu_init Paolo Bonzini
                   ` (3 preceding siblings ...)
  2020-12-02  8:18 ` [PATCH 04/15] vl: extract softmmu/runstate.c Paolo Bonzini
@ 2020-12-02  8:18 ` Paolo Bonzini
  2020-12-02  8:18 ` [PATCH 06/15] vl: move all generic initialization out of vl.c Paolo Bonzini
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-02  8:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo

Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/core/machine.c         |  2 ++
 include/exec/cpu-common.h |  3 ++
 include/exec/exec-all.h   |  3 --
 softmmu/globals.c         | 74 +++++++++++++++++++++++++++++++++++++++
 softmmu/meson.build       |  1 +
 softmmu/vl.c              | 45 ++----------------------
 6 files changed, 83 insertions(+), 45 deletions(-)
 create mode 100644 softmmu/globals.c

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 745531c9d9..5659b1f49c 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -213,6 +213,8 @@ GlobalProperty hw_compat_2_1[] = {
 };
 const size_t hw_compat_2_1_len = G_N_ELEMENTS(hw_compat_2_1);
 
+MachineState *current_machine;
+
 static char *machine_get_kernel(Object *obj, Error **errp)
 {
     MachineState *ms = MACHINE(obj);
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index bd5e15dd7d..5a0a2d93e0 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -105,4 +105,7 @@ int ram_block_discard_range(RAMBlock *rb, uint64_t start, size_t length);
 
 #endif
 
+/* vl.c */
+extern int singlestep;
+
 #endif /* CPU_COMMON_H */
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 94fe05daaa..fab573da06 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -676,7 +676,4 @@ hwaddr memory_region_section_get_iotlb(CPUState *cpu,
                                        MemoryRegionSection *section);
 #endif
 
-/* vl.c */
-extern int singlestep;
-
 #endif
diff --git a/softmmu/globals.c b/softmmu/globals.c
new file mode 100644
index 0000000000..e62d9cd8da
--- /dev/null
+++ b/softmmu/globals.c
@@ -0,0 +1,74 @@
+/*
+ * Global variables that (mostly) should not exist
+ *
+ * Copyright (c) 2003-2020 QEMU contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "exec/cpu-common.h"
+#include "hw/display/vga.h"
+#include "hw/i386/pc.h"
+#include "hw/i386/x86.h"
+#include "hw/loader.h"
+#include "hw/xen/xen.h"
+#include "net/net.h"
+#include "sysemu/cpus.h"
+#include "sysemu/sysemu.h"
+
+enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
+int display_opengl;
+const char* keyboard_layout;
+bool enable_mlock;
+bool enable_cpu_pm;
+int nb_nics;
+NICInfo nd_table[MAX_NICS];
+int autostart = 1;
+int vga_interface_type = VGA_NONE;
+Chardev *parallel_hds[MAX_PARALLEL_PORTS];
+int win2k_install_hack;
+int singlestep;
+int fd_bootchk = 1;
+int no_reboot;
+int no_shutdown;
+int graphic_rotate;
+QEMUOptionRom option_rom[MAX_OPTION_ROMS];
+int nb_option_roms;
+int old_param;
+const char *qemu_name;
+int alt_grab;
+int ctrl_grab;
+unsigned int nb_prom_envs;
+const char *prom_envs[MAX_PROM_ENVS];
+int boot_menu;
+bool boot_strict;
+uint8_t *boot_splash_filedata;
+int only_migratable; /* turn it off unless user states otherwise */
+int icount_align_option;
+
+/* The bytes in qemu_uuid are in the order specified by RFC4122, _not_ in the
+ * little-endian "wire format" described in the SMBIOS 2.6 specification.
+ */
+QemuUUID qemu_uuid;
+bool qemu_uuid_set;
+
+uint32_t xen_domid;
+enum xen_mode xen_mode = XEN_EMULATE;
+bool xen_domid_restrict;
diff --git a/softmmu/meson.build b/softmmu/meson.build
index 2a73ebc223..e5865b97cb 100644
--- a/softmmu/meson.build
+++ b/softmmu/meson.build
@@ -4,6 +4,7 @@ specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: [files(
   'cpus.c',
   'cpu-throttle.c',
   'datadir.c',
+  'globals.c',
   'physmem.c',
   'ioport.c',
   'rtc.c',
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 6282ae2101..685d92df5d 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -26,6 +26,7 @@
 #include "qemu-common.h"
 #include "qemu/datadir.h"
 #include "qemu/units.h"
+#include "exec/cpu-common.h"
 #include "hw/boards.h"
 #include "hw/qdev-properties.h"
 #include "qapi/error.h"
@@ -67,6 +68,8 @@
 #include "qemu/log.h"
 #include "sysemu/blockdev.h"
 #include "hw/block/block.h"
+#include "hw/i386/x86.h"
+#include "hw/i386/pc.h"
 #include "migration/misc.h"
 #include "migration/snapshot.h"
 #include "migration/global_state.h"
@@ -139,17 +142,8 @@ static bool preconfig_requested;
 static QemuPluginList plugin_list = QTAILQ_HEAD_INITIALIZER(plugin_list);
 static BlockdevOptionsQueue bdo_queue = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue);
 static bool nographic = false;
-enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
 static int mem_prealloc; /* force preallocation of physical target memory */
-int display_opengl;
-const char* keyboard_layout = NULL;
 static ram_addr_t ram_size;
-bool enable_mlock = false;
-bool enable_cpu_pm = false;
-int nb_nics;
-NICInfo nd_table[MAX_NICS];
-int autostart = 1;
-int vga_interface_type = VGA_NONE;
 static const char *vga_model = NULL;
 static DisplayOptions dpy;
 static int num_serial_hds;
@@ -157,41 +151,10 @@ static Chardev **serial_hds;
 static const char *log_mask;
 static const char *log_file;
 static bool list_data_dirs;
-Chardev *parallel_hds[MAX_PARALLEL_PORTS];
-int win2k_install_hack = 0;
-int singlestep = 0;
-int fd_bootchk = 1;
-int no_reboot;
-int no_shutdown = 0;
-int graphic_rotate = 0;
 static const char *watchdog;
-QEMUOptionRom option_rom[MAX_OPTION_ROMS];
-int nb_option_roms;
-int old_param = 0;
-const char *qemu_name;
-int alt_grab = 0;
-int ctrl_grab = 0;
-unsigned int nb_prom_envs = 0;
-const char *prom_envs[MAX_PROM_ENVS];
-int boot_menu;
-bool boot_strict;
-uint8_t *boot_splash_filedata;
-int only_migratable; /* turn it off unless user states otherwise */
-bool wakeup_suspend_enabled;
-int icount_align_option;
 static const char *qtest_chrdev;
 static const char *qtest_log;
 
-/* The bytes in qemu_uuid are in the order specified by RFC4122, _not_ in the
- * little-endian "wire format" described in the SMBIOS 2.6 specification.
- */
-QemuUUID qemu_uuid;
-bool qemu_uuid_set;
-
-uint32_t xen_domid;
-enum xen_mode xen_mode = XEN_EMULATE;
-bool xen_domid_restrict;
-
 static int has_defaults = 1;
 static int default_serial = 1;
 static int default_parallel = 1;
@@ -799,8 +762,6 @@ static int usb_parse(const char *cmdline)
 /***********************************************************/
 /* machine registration */
 
-MachineState *current_machine;
-
 static MachineClass *find_machine(const char *name, GSList *machines)
 {
     GSList *el;
-- 
2.26.2




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

* [PATCH 06/15] vl: move all generic initialization out of vl.c
  2020-12-02  8:18 [PATCH 00/15] Finish cleaning up qemu_init Paolo Bonzini
                   ` (4 preceding siblings ...)
  2020-12-02  8:18 ` [PATCH 05/15] vl: extract softmmu/globals.c Paolo Bonzini
@ 2020-12-02  8:18 ` Paolo Bonzini
  2020-12-07 14:19   ` Igor Mammedov
  2020-12-02  8:18 ` [PATCH 07/15] chardev: do not use machine_init_done Paolo Bonzini
                   ` (9 subsequent siblings)
  15 siblings, 1 reply; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-02  8:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo

qdev_machine_creation_done is only setting a flag now.  Extend it to
move more code out of vl.c.  Leave only consistency checks and gdbserver
processing in qemu_machine_creation_done.

gdbserver_start can be moved after qdev_machine_creation_done because
it only does listen on the socket and creates some internal data
structures; it does not send any data (e.g. guest state) over the socket.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/core/machine.c      | 47 +++++++++++++++++++++++++++++++++++++++++-
 hw/core/qdev.c         | 12 +++--------
 include/hw/qdev-core.h |  1 +
 softmmu/vl.c           | 37 +--------------------------------
 4 files changed, 51 insertions(+), 46 deletions(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 5659b1f49c..025c4f9749 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -16,16 +16,21 @@
 #include "sysemu/replay.h"
 #include "qemu/units.h"
 #include "hw/boards.h"
+#include "hw/loader.h"
 #include "qapi/error.h"
 #include "qapi/qapi-visit-common.h"
 #include "qapi/visitor.h"
 #include "hw/sysbus.h"
+#include "sysemu/cpus.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/reset.h"
+#include "sysemu/runstate.h"
 #include "sysemu/numa.h"
 #include "qemu/error-report.h"
 #include "sysemu/qtest.h"
 #include "hw/pci/pci.h"
 #include "hw/mem/nvdimm.h"
+#include "migration/global_state.h"
 #include "migration/vmstate.h"
 
 GlobalProperty hw_compat_5_1[] = {
@@ -1186,10 +1191,50 @@ void qemu_remove_machine_init_done_notifier(Notifier *notify)
     notifier_remove(notify);
 }
 
-void qemu_run_machine_init_done_notifiers(void)
+void qdev_machine_creation_done(void)
 {
+    cpu_synchronize_all_post_init();
+
+    if (current_machine->boot_once) {
+        qemu_boot_set(current_machine->boot_once, &error_fatal);
+        qemu_register_reset(restore_boot_order, g_strdup(current_machine->boot_order));
+    }
+
+    /*
+     * ok, initial machine setup is done, starting from now we can
+     * only create hotpluggable devices
+     */
+    qdev_hotplug = true;
+    qdev_assert_realized_properly();
+
+    /* TODO: once all bus devices are qdevified, this should be done
+     * when bus is created by qdev.c */
+    /*
+     * TODO: If we had a main 'reset container' that the whole system
+     * lived in, we could reset that using the multi-phase reset
+     * APIs. For the moment, we just reset the sysbus, which will cause
+     * all devices hanging off it (and all their child buses, recursively)
+     * to be reset. Note that this will *not* reset any Device objects
+     * which are not attached to some part of the qbus tree!
+     */
+    qemu_register_reset(resettable_cold_reset_fn, sysbus_get_default());
+
     machine_init_done = true;
     notifier_list_notify(&machine_init_done_notifiers, NULL);
+
+    if (rom_check_and_register_reset() != 0) {
+        error_report("rom check and register reset failed");
+        exit(1);
+    }
+
+    replay_start();
+
+    /* This checkpoint is required by replay to separate prior clock
+       reading from the other reads, because timer polling functions query
+       clock values from the log. */
+    replay_checkpoint(CHECKPOINT_RESET);
+    qemu_system_reset(SHUTDOWN_CAUSE_NONE);
+    register_global_state();
 }
 
 static const TypeInfo machine_info = {
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 262bca716f..bc5df8ce69 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -413,7 +413,7 @@ void qdev_unrealize(DeviceState *dev)
     object_property_set_bool(OBJECT(dev), "realized", false, &error_abort);
 }
 
-static int qdev_assert_realized_properly(Object *obj, void *opaque)
+static int qdev_assert_realized_properly_cb(Object *obj, void *opaque)
 {
     DeviceState *dev = DEVICE(object_dynamic_cast(obj, TYPE_DEVICE));
     DeviceClass *dc;
@@ -426,16 +426,10 @@ static int qdev_assert_realized_properly(Object *obj, void *opaque)
     return 0;
 }
 
-void qdev_machine_creation_done(void)
+void qdev_assert_realized_properly(void)
 {
-    /*
-     * ok, initial machine setup is done, starting from now we can
-     * only create hotpluggable devices
-     */
-    qdev_hotplug = true;
-
     object_child_foreach_recursive(object_get_root(),
-                                   qdev_assert_realized_properly, NULL);
+                                   qdev_assert_realized_properly_cb, NULL);
 }
 
 bool qdev_machine_modified(void)
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index b77a2f1da7..6446846752 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -815,6 +815,7 @@ const VMStateDescription *qdev_get_vmsd(DeviceState *dev);
 
 const char *qdev_fw_name(DeviceState *dev);
 
+void qdev_assert_realized_properly(void);
 Object *qdev_get_machine(void);
 
 /* FIXME: make this a link<> */
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 685d92df5d..d8af26c281 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -72,7 +72,6 @@
 #include "hw/i386/pc.h"
 #include "migration/misc.h"
 #include "migration/snapshot.h"
-#include "migration/global_state.h"
 #include "sysemu/tpm.h"
 #include "sysemu/dma.h"
 #include "hw/audio/soundhw.h"
@@ -2465,8 +2464,6 @@ static void qemu_create_cli_devices(void)
 
 static void qemu_machine_creation_done(void)
 {
-    cpu_synchronize_all_post_init();
-
     /* Did we create any drives that we failed to create a device for? */
     drive_check_orphaned();
 
@@ -2484,43 +2481,11 @@ static void qemu_machine_creation_done(void)
 
     qdev_prop_check_globals();
 
-    if (current_machine->boot_once) {
-        qemu_boot_set(current_machine->boot_once, &error_fatal);
-        qemu_register_reset(restore_boot_order, g_strdup(current_machine->boot_order));
-    }
-
-    if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
-        exit(1);
-    }
-
     qdev_machine_creation_done();
 
-    /* TODO: once all bus devices are qdevified, this should be done
-     * when bus is created by qdev.c */
-    /*
-     * TODO: If we had a main 'reset container' that the whole system
-     * lived in, we could reset that using the multi-phase reset
-     * APIs. For the moment, we just reset the sysbus, which will cause
-     * all devices hanging off it (and all their child buses, recursively)
-     * to be reset. Note that this will *not* reset any Device objects
-     * which are not attached to some part of the qbus tree!
-     */
-    qemu_register_reset(resettable_cold_reset_fn, sysbus_get_default());
-    qemu_run_machine_init_done_notifiers();
-
-    if (rom_check_and_register_reset() != 0) {
-        error_report("rom check and register reset failed");
+    if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
         exit(1);
     }
-
-    replay_start();
-
-    /* This checkpoint is required by replay to separate prior clock
-       reading from the other reads, because timer polling functions query
-       clock values from the log. */
-    replay_checkpoint(CHECKPOINT_RESET);
-    qemu_system_reset(SHUTDOWN_CAUSE_NONE);
-    register_global_state();
 }
 
 void qmp_x_exit_preconfig(Error **errp)
-- 
2.26.2




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

* [PATCH 07/15] chardev: do not use machine_init_done
  2020-12-02  8:18 [PATCH 00/15] Finish cleaning up qemu_init Paolo Bonzini
                   ` (5 preceding siblings ...)
  2020-12-02  8:18 ` [PATCH 06/15] vl: move all generic initialization out of vl.c Paolo Bonzini
@ 2020-12-02  8:18 ` Paolo Bonzini
  2020-12-07 15:15   ` Igor Mammedov
  2020-12-02  8:18 ` [PATCH 08/15] machine: introduce MachineInitPhase Paolo Bonzini
                   ` (8 subsequent siblings)
  15 siblings, 1 reply; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-02  8:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo

machine_init_done is not the right flag to check when preconfig
is taken into account; for example "./qemu-system-x86_64 -serial
mon:stdio -preconfig" does not print the QEMU monitor header until after
exit_preconfig.  Add back a custom bool for mux character devices.  This
partially undoes commit c7278b4355 ("chardev: introduce chr_machine_done
hook", 2018-03-12), cut keeps the cleaner logic using a function pointer
in ChardevClass.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 chardev/char-mux.c        | 38 ++++++++++++++++++---
 chardev/chardev-sysemu.c  | 69 ---------------------------------------
 chardev/meson.build       |  2 +-
 hw/core/machine.c         |  2 +-
 include/chardev/char.h    |  6 ++--
 include/sysemu/sysemu.h   |  2 --
 softmmu/vl.c              |  3 ++
 stubs/machine-init-done.c |  8 -----
 stubs/meson.build         |  1 -
 9 files changed, 43 insertions(+), 88 deletions(-)
 delete mode 100644 chardev/chardev-sysemu.c
 delete mode 100644 stubs/machine-init-done.c

diff --git a/chardev/char-mux.c b/chardev/char-mux.c
index 6f980bb836..72beef29d2 100644
--- a/chardev/char-mux.c
+++ b/chardev/char-mux.c
@@ -33,6 +33,13 @@
 
 /* MUX driver for serial I/O splitting */
 
+/*
+ * Set to false by suspend_mux_open.  Open events are delayed until
+ * resume_mux_open.  Usually suspend_mux_open is called before
+ * command line processing and resume_mux_open afterwards.
+ */
+static bool muxes_opened = true;
+
 /* Called with chr_write_lock held.  */
 static int mux_chr_write(Chardev *chr, const uint8_t *buf, int len)
 {
@@ -237,7 +244,7 @@ void mux_chr_send_all_event(Chardev *chr, QEMUChrEvent event)
     MuxChardev *d = MUX_CHARDEV(chr);
     int i;
 
-    if (!machine_init_done) {
+    if (!muxes_opened) {
         return;
     }
 
@@ -328,7 +335,7 @@ static void qemu_chr_open_mux(Chardev *chr,
     /* only default to opened state if we've realized the initial
      * set of muxes
      */
-    *be_opened = machine_init_done;
+    *be_opened = muxes_opened;
     qemu_chr_fe_init(&d->chr, drv, errp);
 }
 
@@ -360,19 +367,42 @@ static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend *backend,
  * mux will receive CHR_EVENT_OPENED notifications for the BE
  * immediately.
  */
-static int open_muxes(Chardev *chr)
+static void open_muxes(Chardev *chr)
 {
     /* send OPENED to all already-attached FEs */
     mux_chr_send_all_event(chr, CHR_EVENT_OPENED);
+
     /*
      * mark mux as OPENED so any new FEs will immediately receive
      * OPENED event
      */
     chr->be_open = 1;
+}
+
+void suspend_mux_open(void)
+{
+    muxes_opened = false;
+}
+
+static int chardev_options_parsed_cb(Object *child, void *opaque)
+{
+    Chardev *chr = (Chardev *)child;
+    ChardevClass *class = CHARDEV_GET_CLASS(chr);
+
+    if (!chr->be_open && class->chr_options_parsed) {
+        class->chr_options_parsed(chr);
+    }
 
     return 0;
 }
 
+void resume_mux_open(void)
+{
+    muxes_opened = true;
+    object_child_foreach(get_chardevs_root(),
+                         chardev_options_parsed_cb, NULL);
+}
+
 static void char_mux_class_init(ObjectClass *oc, void *data)
 {
     ChardevClass *cc = CHARDEV_CLASS(oc);
@@ -383,7 +413,7 @@ static void char_mux_class_init(ObjectClass *oc, void *data)
     cc->chr_accept_input = mux_chr_accept_input;
     cc->chr_add_watch = mux_chr_add_watch;
     cc->chr_be_event = mux_chr_be_event;
-    cc->chr_machine_done = open_muxes;
+    cc->chr_options_parsed = open_muxes;
     cc->chr_update_read_handler = mux_chr_update_read_handlers;
 }
 
diff --git a/chardev/chardev-sysemu.c b/chardev/chardev-sysemu.c
deleted file mode 100644
index eecdc615ee..0000000000
--- a/chardev/chardev-sysemu.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * QEMU System Emulator
- *
- * Copyright (c) 2003-2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-#include "sysemu/sysemu.h"
-#include "chardev/char.h"
-#include "qemu/error-report.h"
-#include "chardev-internal.h"
-
-static int chardev_machine_done_notify_one(Object *child, void *opaque)
-{
-    Chardev *chr = (Chardev *)child;
-    ChardevClass *class = CHARDEV_GET_CLASS(chr);
-
-    if (class->chr_machine_done) {
-        return class->chr_machine_done(chr);
-    }
-
-    return 0;
-}
-
-static void chardev_machine_done_hook(Notifier *notifier, void *unused)
-{
-    int ret = object_child_foreach(get_chardevs_root(),
-                                   chardev_machine_done_notify_one, NULL);
-
-    if (ret) {
-        error_report("Failed to call chardev machine_done hooks");
-        exit(1);
-    }
-}
-
-
-static Notifier chardev_machine_done_notify = {
-    .notify = chardev_machine_done_hook,
-};
-
-static void register_types(void)
-{
-    /*
-     * This must be done after machine init, since we register FEs with muxes
-     * as part of realize functions like serial_isa_realizefn when -nographic
-     * is specified.
-     */
-    qemu_add_machine_init_done_notifier(&chardev_machine_done_notify);
-}
-
-type_init(register_types);
diff --git a/chardev/meson.build b/chardev/meson.build
index 859d8b04d4..4e19722c5e 100644
--- a/chardev/meson.build
+++ b/chardev/meson.build
@@ -25,7 +25,7 @@ chardev_ss.add(when: 'CONFIG_WIN32', if_true: files(
 
 chardev_ss = chardev_ss.apply(config_host, strict: false)
 
-softmmu_ss.add(files('chardev-sysemu.c', 'msmouse.c', 'wctablet.c', 'testdev.c'))
+softmmu_ss.add(files('msmouse.c', 'wctablet.c', 'testdev.c'))
 
 chardev_modules = {}
 
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 025c4f9749..40876ddd8e 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -1176,7 +1176,7 @@ void machine_run_board_init(MachineState *machine)
 static NotifierList machine_init_done_notifiers =
     NOTIFIER_LIST_INITIALIZER(machine_init_done_notifiers);
 
-bool machine_init_done;
+static bool machine_init_done;
 
 void qemu_add_machine_init_done_notifier(Notifier *notify)
 {
diff --git a/include/chardev/char.h b/include/chardev/char.h
index db42f0a8c6..4181a2784a 100644
--- a/include/chardev/char.h
+++ b/include/chardev/char.h
@@ -270,8 +270,7 @@ struct ChardevClass {
     void (*chr_set_echo)(Chardev *chr, bool echo);
     void (*chr_set_fe_open)(Chardev *chr, int fe_open);
     void (*chr_be_event)(Chardev *s, QEMUChrEvent event);
-    /* Return 0 if succeeded, 1 if failed */
-    int (*chr_machine_done)(Chardev *chr);
+    void (*chr_options_parsed)(Chardev *chr);
 };
 
 Chardev *qemu_chardev_new(const char *id, const char *typename,
@@ -283,6 +282,9 @@ extern int term_escape_char;
 GSource *qemu_chr_timeout_add_ms(Chardev *chr, guint ms,
                                  GSourceFunc func, void *private);
 
+void suspend_mux_open(void);
+void resume_mux_open(void);
+
 /* console.c */
 void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend, Error **errp);
 
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 0e7b405d22..9b47cdca55 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -16,8 +16,6 @@ extern bool qemu_uuid_set;
 void qemu_add_exit_notifier(Notifier *notify);
 void qemu_remove_exit_notifier(Notifier *notify);
 
-extern bool machine_init_done;
-
 void qemu_run_machine_init_done_notifiers(void);
 void qemu_add_machine_init_done_notifier(Notifier *notify);
 void qemu_remove_machine_init_done_notifier(Notifier *notify);
diff --git a/softmmu/vl.c b/softmmu/vl.c
index d8af26c281..8e18c52f6e 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -3462,6 +3462,8 @@ void qemu_init(int argc, char **argv, char **envp)
 
     qemu_create_machine(select_machine());
 
+    suspend_mux_open();
+
     qemu_disable_default_devices();
     qemu_create_default_devices();
     qemu_create_early_backends();
@@ -3525,4 +3527,5 @@ void qemu_init(int argc, char **argv, char **envp)
     }
     accel_setup_post(current_machine);
     os_setup_post();
+    resume_mux_open();
 }
diff --git a/stubs/machine-init-done.c b/stubs/machine-init-done.c
deleted file mode 100644
index cd8e81392d..0000000000
--- a/stubs/machine-init-done.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "qemu/osdep.h"
-#include "sysemu/sysemu.h"
-
-bool machine_init_done = true;
-
-void qemu_add_machine_init_done_notifier(Notifier *notify)
-{
-}
diff --git a/stubs/meson.build b/stubs/meson.build
index cc56c83063..80b1d81a31 100644
--- a/stubs/meson.build
+++ b/stubs/meson.build
@@ -21,7 +21,6 @@ stub_ss.add(files('iothread-lock.c'))
 stub_ss.add(files('isa-bus.c'))
 stub_ss.add(files('is-daemonized.c'))
 stub_ss.add(when: 'CONFIG_LINUX_AIO', if_true: files('linux-aio.c'))
-stub_ss.add(files('machine-init-done.c'))
 stub_ss.add(files('migr-blocker.c'))
 stub_ss.add(files('monitor.c'))
 stub_ss.add(files('monitor-core.c'))
-- 
2.26.2




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

* [PATCH 08/15] machine: introduce MachineInitPhase
  2020-12-02  8:18 [PATCH 00/15] Finish cleaning up qemu_init Paolo Bonzini
                   ` (6 preceding siblings ...)
  2020-12-02  8:18 ` [PATCH 07/15] chardev: do not use machine_init_done Paolo Bonzini
@ 2020-12-02  8:18 ` Paolo Bonzini
  2020-12-07 15:28   ` Igor Mammedov
  2020-12-02  8:18 ` [PATCH 09/15] machine: record whether nvdimm= was set Paolo Bonzini
                   ` (7 subsequent siblings)
  15 siblings, 1 reply; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-02  8:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo

Generalize the qdev_hotplug variable to the different phases of
machine initialization.  We would like to allow different
monitor commands depending on the phase.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/core/machine-qmp-cmds.c |  6 +++---
 hw/core/machine.c          |  8 +++-----
 hw/core/qdev.c             | 16 ++++++++++++++--
 hw/pci/pci.c               |  2 +-
 hw/usb/core.c              |  2 +-
 hw/virtio/virtio-iommu.c   |  2 +-
 include/hw/qdev-core.h     | 32 +++++++++++++++++++++++++++++++-
 monitor/hmp.c              |  2 +-
 softmmu/qdev-monitor.c     | 24 +++++++++++++-----------
 softmmu/vl.c               |  9 ++++-----
 ui/console.c               |  2 +-
 11 files changed, 73 insertions(+), 32 deletions(-)

diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
index cb9387c5f5..87f14140a3 100644
--- a/hw/core/machine-qmp-cmds.c
+++ b/hw/core/machine-qmp-cmds.c
@@ -286,9 +286,9 @@ HotpluggableCPUList *qmp_query_hotpluggable_cpus(Error **errp)
 
 void qmp_set_numa_node(NumaOptions *cmd, Error **errp)
 {
-    if (qdev_hotplug) {
-         error_setg(errp, "The command is permitted only before the machine has been created");
-         return;
+    if (phase_check(PHASE_MACHINE_INITIALIZED)) {
+        error_setg(errp, "The command is permitted only before the machine has been created");
+        return;
     }
 
     set_numa_options(MACHINE(qdev_get_machine()), cmd, errp);
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 40876ddd8e..2c0bc15143 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -1171,17 +1171,16 @@ void machine_run_board_init(MachineState *machine)
     }
 
     machine_class->init(machine);
+    phase_advance(PHASE_MACHINE_INITIALIZED);
 }
 
 static NotifierList machine_init_done_notifiers =
     NOTIFIER_LIST_INITIALIZER(machine_init_done_notifiers);
 
-static bool machine_init_done;
-
 void qemu_add_machine_init_done_notifier(Notifier *notify)
 {
     notifier_list_add(&machine_init_done_notifiers, notify);
-    if (machine_init_done) {
+    if (phase_check(PHASE_MACHINE_READY)) {
         notify->notify(notify, NULL);
     }
 }
@@ -1204,7 +1203,7 @@ void qdev_machine_creation_done(void)
      * ok, initial machine setup is done, starting from now we can
      * only create hotpluggable devices
      */
-    qdev_hotplug = true;
+    phase_advance(PHASE_MACHINE_READY);
     qdev_assert_realized_properly();
 
     /* TODO: once all bus devices are qdevified, this should be done
@@ -1219,7 +1218,6 @@ void qdev_machine_creation_done(void)
      */
     qemu_register_reset(resettable_cold_reset_fn, sysbus_get_default());
 
-    machine_init_done = true;
     notifier_list_notify(&machine_init_done_notifiers, NULL);
 
     if (rom_check_and_register_reset() != 0) {
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index bc5df8ce69..beb35879c6 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -41,7 +41,6 @@
 #include "migration/vmstate.h"
 #include "trace.h"
 
-bool qdev_hotplug = false;
 static bool qdev_hot_added = false;
 bool qdev_hot_removed = false;
 
@@ -1023,7 +1022,7 @@ static void device_initfn(Object *obj)
 {
     DeviceState *dev = DEVICE(obj);
 
-    if (qdev_hotplug) {
+    if (phase_check(PHASE_MACHINE_READY)) {
         dev->hotplugged = 1;
         qdev_hot_added = true;
     }
@@ -1267,6 +1266,19 @@ Object *qdev_get_machine(void)
     return dev;
 }
 
+static MachineInitPhase machine_phase;
+
+bool phase_check(MachineInitPhase phase)
+{
+    return machine_phase >= phase;
+}
+
+void phase_advance(MachineInitPhase phase)
+{
+    assert(machine_phase == phase - 1);
+    machine_phase = phase;
+}
+
 static const TypeInfo device_type_info = {
     .name = TYPE_DEVICE,
     .parent = TYPE_OBJECT,
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 9424231542..d4349ea577 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1062,7 +1062,7 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev,
     address_space_init(&pci_dev->bus_master_as,
                        &pci_dev->bus_master_container_region, pci_dev->name);
 
-    if (qdev_hotplug) {
+    if (phase_check(PHASE_MACHINE_READY)) {
         pci_init_bus_master(pci_dev);
     }
     pci_dev->irq_state = 0;
diff --git a/hw/usb/core.c b/hw/usb/core.c
index 5234dcc73f..e960036f4d 100644
--- a/hw/usb/core.c
+++ b/hw/usb/core.c
@@ -97,7 +97,7 @@ void usb_wakeup(USBEndpoint *ep, unsigned int stream)
     USBDevice *dev = ep->dev;
     USBBus *bus = usb_bus_from_device(dev);
 
-    if (!qdev_hotplug) {
+    if (!phase_check(PHASE_MACHINE_READY)) {
         /*
          * This is machine init cold plug.  No need to wakeup anyone,
          * all devices will be reset anyway.  And trying to wakeup can
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index fc5c75d693..8370fd80d7 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -928,7 +928,7 @@ static int virtio_iommu_set_page_size_mask(IOMMUMemoryRegion *mr,
      * accept it. Having a different masks is possible but the guest will use
      * sub-optimal block sizes, so warn about it.
      */
-    if (qdev_hotplug) {
+    if (phase_check(PHASE_MACHINE_READY)) {
         int new_granule = ctz64(new_mask);
         int cur_granule = ctz64(cur_mask);
 
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 6446846752..12612ed682 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -821,7 +821,6 @@ Object *qdev_get_machine(void);
 /* FIXME: make this a link<> */
 bool qdev_set_parent_bus(DeviceState *dev, BusState *bus, Error **errp);
 
-extern bool qdev_hotplug;
 extern bool qdev_hot_removed;
 
 char *qdev_get_dev_path(DeviceState *dev);
@@ -847,4 +846,35 @@ void device_listener_unregister(DeviceListener *listener);
  */
 bool qdev_should_hide_device(QemuOpts *opts);
 
+typedef enum MachineInitPhase {
+    /* current_machine is NULL.  */
+    PHASE_NO_MACHINE,
+
+    /* current_machine is not NULL, but current_machine->accel is NULL.  */
+    PHASE_MACHINE_CREATED,
+
+    /*
+     * current_machine->accel is not NULL, but the machine properties have
+     * not been validated and machine_class->init has not yet been called.
+     */
+    PHASE_ACCEL_CREATED,
+
+    /*
+     * machine_class->init has been called, thus creating any embedded
+     * devices and validating machine properties.  Devices created at
+     * this time are considered to be cold-plugged.
+     */
+    PHASE_MACHINE_INITIALIZED,
+
+    /*
+     * QEMU is ready to start CPUs and devices created at this time
+     * are considered to be hot-plugged.  The monitor is not restricted
+     * to "preconfig" commands.
+     */
+    PHASE_MACHINE_READY,
+} MachineInitPhase;
+
+extern bool phase_check(MachineInitPhase phase);
+extern void phase_advance(MachineInitPhase phase);
+
 #endif
diff --git a/monitor/hmp.c b/monitor/hmp.c
index f2fe192d69..6c0b33a0b1 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -216,7 +216,7 @@ static bool cmd_can_preconfig(const HMPCommand *cmd)
 
 static bool cmd_available(const HMPCommand *cmd)
 {
-    return qdev_hotplug || cmd_can_preconfig(cmd);
+    return phase_check(PHASE_MACHINE_READY) || cmd_can_preconfig(cmd);
 }
 
 static void help_cmd_dump_one(Monitor *mon,
diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
index e967d13bd0..184fe317af 100644
--- a/softmmu/qdev-monitor.c
+++ b/softmmu/qdev-monitor.c
@@ -244,7 +244,7 @@ static DeviceClass *qdev_get_device_class(const char **driver, Error **errp)
 
     dc = DEVICE_CLASS(oc);
     if (!dc->user_creatable ||
-        (qdev_hotplug && !dc->hotpluggable)) {
+        (phase_check(PHASE_MACHINE_READY) && !dc->hotpluggable)) {
         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "driver",
                    "pluggable device type");
         return NULL;
@@ -637,7 +637,7 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
     }
     hide = should_hide_device(opts);
 
-    if ((hide || qdev_hotplug) && bus && !qbus_is_hotpluggable(bus)) {
+    if ((hide || phase_check(PHASE_MACHINE_READY)) && bus && !qbus_is_hotpluggable(bus)) {
         error_setg(errp, QERR_BUS_NO_HOTPLUG, bus->name);
         return NULL;
     }
@@ -655,15 +655,17 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
     dev = qdev_new(driver);
 
     /* Check whether the hotplug is allowed by the machine */
-    if (qdev_hotplug && !qdev_hotplug_allowed(dev, errp)) {
-        goto err_del_dev;
-    }
+    if (phase_check(PHASE_MACHINE_READY)) {
+        if (!qdev_hotplug_allowed(dev, errp)) {
+            goto err_del_dev;
+        }
 
-    if (!bus && qdev_hotplug && !qdev_get_machine_hotplug_handler(dev)) {
-        /* No bus, no machine hotplug handler --> device is not hotpluggable */
-        error_setg(errp, "Device '%s' can not be hotplugged on this machine",
-                   driver);
-        goto err_del_dev;
+        if (!bus && !qdev_get_machine_hotplug_handler(dev)) {
+            /* No bus, no machine hotplug handler --> device is not hotpluggable */
+            error_setg(errp, "Device '%s' can not be hotplugged on this machine",
+                       driver);
+            goto err_del_dev;
+        }
     }
 
     qdev_set_id(dev, qemu_opts_id(opts));
@@ -1001,7 +1003,7 @@ int qemu_global_option(const char *str)
 
 bool qmp_command_available(const QmpCommand *cmd, Error **errp)
 {
-    if (!qdev_hotplug &&
+    if (!phase_check(PHASE_MACHINE_READY) &&
         !(cmd->options & QCO_ALLOW_PRECONFIG)) {
         error_setg(errp, "The command '%s' is permitted only after machine initialization has completed",
                    cmd->name);
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 8e18c52f6e..4fece1b9db 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -2406,10 +2406,6 @@ static void qemu_init_displays(void)
     }
 }
 
-/*
- * Called after leaving preconfig state.  From here on runstate is
- * RUN_STATE_PRELAUNCH or RUN_STATE_INMIGRATE.
- */
 static void qemu_init_board(void)
 {
     MachineClass *machine_class = MACHINE_GET_CLASS(current_machine);
@@ -2424,6 +2420,7 @@ static void qemu_init_board(void)
         exit(1);
     }
 
+    /* From here on we enter MACHINE_PHASE_INITIALIZED.  */
     machine_run_board_init(current_machine);
 
     /*
@@ -2490,7 +2487,7 @@ static void qemu_machine_creation_done(void)
 
 void qmp_x_exit_preconfig(Error **errp)
 {
-    if (qdev_hotplug) {
+    if (phase_check(PHASE_MACHINE_INITIALIZED)) {
         error_setg(errp, "The command is permitted only before machine initialization");
         return;
     }
@@ -3469,12 +3466,14 @@ void qemu_init(int argc, char **argv, char **envp)
     qemu_create_early_backends();
 
     qemu_apply_machine_options();
+    phase_advance(PHASE_MACHINE_CREATED);
 
     /*
      * Note: uses machine properties such as kernel-irqchip, must run
      * after machine_set_property().
      */
     configure_accelerators(argv[0]);
+    phase_advance(PHASE_ACCEL_CREATED);
 
     /*
      * Beware, QOM objects created before this point miss global and
diff --git a/ui/console.c b/ui/console.c
index 53dee8e26b..89f625116d 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1345,7 +1345,7 @@ static QemuConsole *new_console(DisplayState *ds, console_type_t console_type,
     if (QTAILQ_EMPTY(&consoles)) {
         s->index = 0;
         QTAILQ_INSERT_TAIL(&consoles, s, next);
-    } else if (console_type != GRAPHIC_CONSOLE || qdev_hotplug) {
+    } else if (console_type != GRAPHIC_CONSOLE || phase_check(PHASE_MACHINE_READY)) {
         QemuConsole *last = QTAILQ_LAST(&consoles);
         s->index = last->index + 1;
         QTAILQ_INSERT_TAIL(&consoles, s, next);
-- 
2.26.2




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

* [PATCH 09/15] machine: record whether nvdimm= was set
  2020-12-02  8:18 [PATCH 00/15] Finish cleaning up qemu_init Paolo Bonzini
                   ` (7 preceding siblings ...)
  2020-12-02  8:18 ` [PATCH 08/15] machine: introduce MachineInitPhase Paolo Bonzini
@ 2020-12-02  8:18 ` Paolo Bonzini
  2020-12-07 15:40   ` Igor Mammedov
  2020-12-02  8:18 ` [PATCH 10/15] vl: make qemu_get_machine_opts static Paolo Bonzini
                   ` (6 subsequent siblings)
  15 siblings, 1 reply; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-02  8:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo

This is needed for SPAPR which has different defaults than everyone else.
Right now it looks at the -machine QemuOpts, but those will go away.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/core/machine.c       | 1 +
 include/hw/mem/nvdimm.h | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 2c0bc15143..94992fa1c0 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -455,6 +455,7 @@ static void machine_set_nvdimm(Object *obj, bool value, Error **errp)
 {
     MachineState *ms = MACHINE(obj);
 
+    ms->nvdimms_state->has_is_enabled = true;
     ms->nvdimms_state->is_enabled = value;
 }
 
diff --git a/include/hw/mem/nvdimm.h b/include/hw/mem/nvdimm.h
index c699842dd0..14c101c180 100644
--- a/include/hw/mem/nvdimm.h
+++ b/include/hw/mem/nvdimm.h
@@ -129,7 +129,7 @@ typedef struct NvdimmFitBuffer NvdimmFitBuffer;
 
 struct NVDIMMState {
     /* detect if NVDIMM support is enabled. */
-    bool is_enabled;
+    bool has_is_enabled, is_enabled;
 
     /* the data of the fw_cfg file NVDIMM_DSM_MEM_FILE. */
     GArray *dsm_mem;
-- 
2.26.2




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

* [PATCH 10/15] vl: make qemu_get_machine_opts static
  2020-12-02  8:18 [PATCH 00/15] Finish cleaning up qemu_init Paolo Bonzini
                   ` (8 preceding siblings ...)
  2020-12-02  8:18 ` [PATCH 09/15] machine: record whether nvdimm= was set Paolo Bonzini
@ 2020-12-02  8:18 ` Paolo Bonzini
  2020-12-07 16:07   ` Igor Mammedov
  2020-12-08  2:16   ` [PATCH 10/15] vl: make qemu_get_machine_opts static Daniel Henrique Barboza
  2020-12-02  8:18 ` [PATCH 11/15] qtest: add a QOM object for qtest Paolo Bonzini
                   ` (5 subsequent siblings)
  15 siblings, 2 replies; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-02  8:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo

Machine options can be retrieved as properties of the machine object.
Encourage that by removing the "easy" accessor to machine options.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 accel/kvm/kvm-all.c     | 11 ++++-------
 hw/arm/boot.c           |  2 +-
 hw/microblaze/boot.c    |  9 ++++-----
 hw/nios2/boot.c         |  9 ++++-----
 hw/ppc/e500.c           |  5 ++---
 hw/ppc/spapr_nvdimm.c   |  4 ++--
 hw/ppc/virtex_ml507.c   |  2 +-
 hw/riscv/sifive_u.c     |  6 ++----
 hw/riscv/virt.c         |  6 ++----
 hw/xtensa/xtfpga.c      |  9 ++++-----
 include/sysemu/sysemu.h |  2 --
 softmmu/device_tree.c   |  2 +-
 softmmu/vl.c            |  2 +-
 13 files changed, 28 insertions(+), 41 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index baaa54249d..666b9ab96c 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -2013,7 +2013,6 @@ static int kvm_init(MachineState *ms)
     const KVMCapabilityInfo *missing_cap;
     int ret;
     int type = 0;
-    const char *kvm_type;
     uint64_t dirty_log_manual_caps;
 
     s = KVM_STATE(ms->accelerator);
@@ -2069,13 +2068,11 @@ static int kvm_init(MachineState *ms)
     }
     s->as = g_new0(struct KVMAs, s->nr_as);
 
-    kvm_type = qemu_opt_get(qemu_get_machine_opts(), "kvm-type");
-    if (mc->kvm_type) {
+    if (object_property_find(OBJECT(current_machine), "kvm-type")) {
+        g_autofree char *kvm_type = object_property_get_str(OBJECT(current_machine),
+                                                            "kvm-type",
+                                                            &error_abort);
         type = mc->kvm_type(ms, kvm_type);
-    } else if (kvm_type) {
-        ret = -EINVAL;
-        fprintf(stderr, "Invalid argument kvm-type=%s\n", kvm_type);
-        goto err;
     }
 
     do {
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 4d9d47ba1c..e56c42ac22 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -1299,7 +1299,7 @@ void arm_load_kernel(ARMCPU *cpu, MachineState *ms, struct arm_boot_info *info)
     info->kernel_filename = ms->kernel_filename;
     info->kernel_cmdline = ms->kernel_cmdline;
     info->initrd_filename = ms->initrd_filename;
-    info->dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
+    info->dtb_filename = ms->dtb;
     info->dtb_limit = 0;
 
     /* Load the kernel.  */
diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c
index 6715ba2ff9..caaba1aa4c 100644
--- a/hw/microblaze/boot.c
+++ b/hw/microblaze/boot.c
@@ -34,6 +34,7 @@
 #include "sysemu/device_tree.h"
 #include "sysemu/reset.h"
 #include "sysemu/sysemu.h"
+#include "hw/boards.h"
 #include "hw/loader.h"
 #include "elf.h"
 #include "qemu/cutils.h"
@@ -116,16 +117,14 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
                             const char *dtb_filename,
                             void (*machine_cpu_reset)(MicroBlazeCPU *))
 {
-    QemuOpts *machine_opts;
     const char *kernel_filename;
     const char *kernel_cmdline;
     const char *dtb_arg;
     char *filename = NULL;
 
-    machine_opts = qemu_get_machine_opts();
-    kernel_filename = qemu_opt_get(machine_opts, "kernel");
-    kernel_cmdline = qemu_opt_get(machine_opts, "append");
-    dtb_arg = qemu_opt_get(machine_opts, "dtb");
+    kernel_filename = current_machine->kernel_filename;
+    kernel_cmdline = current_machine->kernel_cmdline;
+    dtb_arg = current_machine->dtb;
     /* default to pcbios dtb as passed by machine_init */
     if (!dtb_arg && dtb_filename) {
         filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, dtb_filename);
diff --git a/hw/nios2/boot.c b/hw/nios2/boot.c
index 95a8697906..d9969ac148 100644
--- a/hw/nios2/boot.c
+++ b/hw/nios2/boot.c
@@ -39,6 +39,7 @@
 #include "sysemu/device_tree.h"
 #include "sysemu/reset.h"
 #include "sysemu/sysemu.h"
+#include "hw/boards.h"
 #include "hw/loader.h"
 #include "elf.h"
 
@@ -120,16 +121,14 @@ void nios2_load_kernel(Nios2CPU *cpu, hwaddr ddr_base,
                             const char *dtb_filename,
                             void (*machine_cpu_reset)(Nios2CPU *))
 {
-    QemuOpts *machine_opts;
     const char *kernel_filename;
     const char *kernel_cmdline;
     const char *dtb_arg;
     char *filename = NULL;
 
-    machine_opts = qemu_get_machine_opts();
-    kernel_filename = qemu_opt_get(machine_opts, "kernel");
-    kernel_cmdline = qemu_opt_get(machine_opts, "append");
-    dtb_arg = qemu_opt_get(machine_opts, "dtb");
+    kernel_filename = current_machine->kernel_filename;
+    kernel_cmdline = current_machine->kernel_cmdline;
+    dtb_arg = current_machine->dtb;
     /* default to pcbios dtb as passed by machine_init */
     if (!dtb_arg) {
         filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, dtb_filename);
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 6a64eb31ab..41dad2e583 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -343,9 +343,8 @@ static int ppce500_load_device_tree(PPCE500MachineState *pms,
             pmc->pci_pio_base >> 32, pmc->pci_pio_base,
             0x0, 0x10000,
         };
-    QemuOpts *machine_opts = qemu_get_machine_opts();
-    const char *dtb_file = qemu_opt_get(machine_opts, "dtb");
-    const char *toplevel_compat = qemu_opt_get(machine_opts, "dt_compatible");
+    const char *dtb_file = machine->dtb;
+    const char *toplevel_compat = machine->dt_compatible;
 
     if (dtb_file) {
         char *filename;
diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
index a833a63b5e..84715a4d78 100644
--- a/hw/ppc/spapr_nvdimm.c
+++ b/hw/ppc/spapr_nvdimm.c
@@ -38,7 +38,6 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
 {
     const MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev);
     const MachineState *ms = MACHINE(hotplug_dev);
-    const char *nvdimm_opt = qemu_opt_get(qemu_get_machine_opts(), "nvdimm");
     g_autofree char *uuidstr = NULL;
     QemuUUID uuid;
     int ret;
@@ -57,10 +56,11 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
      * ensure that, if the user sets nvdimm=off, we error out
      * regardless of being 5.1 or newer.
      */
-    if (!ms->nvdimms_state->is_enabled && nvdimm_opt) {
+    if (!ms->nvdimms_state->is_enabled && ms->nvdimms_state->has_is_enabled) {
         error_setg(errp, "nvdimm device found but 'nvdimm=off' was set");
         return false;
     }
+    ms->nvdimms_state->is_enabled = true;
 
     if (object_property_get_int(OBJECT(nvdimm), NVDIMM_LABEL_SIZE_PROP,
                                 &error_abort) == 0) {
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index 7f1bca928c..07fe49da0d 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -152,7 +152,7 @@ static int xilinx_load_device_tree(hwaddr addr,
     int r;
     const char *dtb_filename;
 
-    dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
+    dtb_filename = current_machine->dtb;
     if (dtb_filename) {
         fdt = load_device_tree(dtb_filename, &fdt_size);
         if (!fdt) {
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 2f19a9cda2..e7f6dc5fb3 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -100,14 +100,12 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
     int cpu;
     uint32_t *cells;
     char *nodename;
-    const char *dtb_filename;
     char ethclk_names[] = "pclk\0hclk";
     uint32_t plic_phandle, prci_phandle, gpio_phandle, phandle = 1;
     uint32_t hfclk_phandle, rtcclk_phandle, phy_phandle;
 
-    dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
-    if (dtb_filename) {
-        fdt = s->fdt = load_device_tree(dtb_filename, &s->fdt_size);
+    if (ms->dtb) {
+        fdt = s->fdt = load_device_tree(ms->dtb, &s->fdt_size);
         if (!fdt) {
             error_report("load_device_tree() failed");
             exit(1);
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 25cea7aa67..3cc18a76e7 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -181,7 +181,6 @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
 {
     void *fdt;
     int i, cpu, socket;
-    const char *dtb_filename;
     MachineState *mc = MACHINE(s);
     uint64_t addr, size;
     uint32_t *clint_cells, *plic_cells;
@@ -195,9 +194,8 @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
     hwaddr flashsize = virt_memmap[VIRT_FLASH].size / 2;
     hwaddr flashbase = virt_memmap[VIRT_FLASH].base;
 
-    dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
-    if (dtb_filename) {
-        fdt = s->fdt = load_device_tree(dtb_filename, &s->fdt_size);
+    if (mc->dtb) {
+        fdt = s->fdt = load_device_tree(mc->dtb, &s->fdt_size);
         if (!fdt) {
             error_report("load_device_tree() failed");
             exit(1);
diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
index b1470b88e6..7be53f1895 100644
--- a/hw/xtensa/xtfpga.c
+++ b/hw/xtensa/xtfpga.c
@@ -233,11 +233,10 @@ static void xtfpga_init(const XtfpgaBoardDesc *board, MachineState *machine)
     qemu_irq *extints;
     DriveInfo *dinfo;
     PFlashCFI01 *flash = NULL;
-    QemuOpts *machine_opts = qemu_get_machine_opts();
-    const char *kernel_filename = qemu_opt_get(machine_opts, "kernel");
-    const char *kernel_cmdline = qemu_opt_get(machine_opts, "append");
-    const char *dtb_filename = qemu_opt_get(machine_opts, "dtb");
-    const char *initrd_filename = qemu_opt_get(machine_opts, "initrd");
+    const char *kernel_filename = machine->kernel_filename;
+    const char *kernel_cmdline = machine->kernel_cmdline;
+    const char *dtb_filename = machine->dtb;
+    const char *initrd_filename = machine->initrd_filename;
     const unsigned system_io_size = 224 * MiB;
     uint32_t freq = 10000000;
     int n;
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 9b47cdca55..e8f463ff30 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -104,8 +104,6 @@ typedef void QEMUBootSetHandler(void *opaque, const char *boot_order,
 void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque);
 void qemu_boot_set(const char *boot_order, Error **errp);
 
-QemuOpts *qemu_get_machine_opts(void);
-
 bool defaults_enabled(void);
 
 void qemu_init(int argc, char **argv, char **envp);
diff --git a/softmmu/device_tree.c b/softmmu/device_tree.c
index b335dae707..b9a3ddc518 100644
--- a/softmmu/device_tree.c
+++ b/softmmu/device_tree.c
@@ -526,7 +526,7 @@ int qemu_fdt_add_subnode(void *fdt, const char *name)
 
 void qemu_fdt_dumpdtb(void *fdt, int size)
 {
-    const char *dumpdtb = qemu_opt_get(qemu_get_machine_opts(), "dumpdtb");
+    const char *dumpdtb = current_machine->dumpdtb;
 
     if (dumpdtb) {
         /* Dump the dtb to a file and quit */
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 4fece1b9db..0f7222af31 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -481,7 +481,7 @@ static QemuOptsList qemu_fw_cfg_opts = {
  *
  * Returns: machine options (never null).
  */
-QemuOpts *qemu_get_machine_opts(void)
+static QemuOpts *qemu_get_machine_opts(void)
 {
     return qemu_find_opts_singleton("machine");
 }
-- 
2.26.2




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

* [PATCH 11/15] qtest: add a QOM object for qtest
  2020-12-02  8:18 [PATCH 00/15] Finish cleaning up qemu_init Paolo Bonzini
                   ` (9 preceding siblings ...)
  2020-12-02  8:18 ` [PATCH 10/15] vl: make qemu_get_machine_opts static Paolo Bonzini
@ 2020-12-02  8:18 ` Paolo Bonzini
  2020-12-07 16:24   ` Igor Mammedov
  2020-12-02  8:18 ` [PATCH 12/15] plugin: propagate errors Paolo Bonzini
                   ` (4 subsequent siblings)
  15 siblings, 1 reply; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-02  8:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo

The qtest server right now can only be created using the -qtest
and -qtest-log options.  Allow an alternative way to create it
using "-object qtest,chardev=...,log=...".

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 softmmu/qtest.c | 144 ++++++++++++++++++++++++++++++++++++++++++++----
 softmmu/vl.c    |   5 +-
 2 files changed, 135 insertions(+), 14 deletions(-)

diff --git a/softmmu/qtest.c b/softmmu/qtest.c
index 7965dc9a16..d255c9681a 100644
--- a/softmmu/qtest.c
+++ b/softmmu/qtest.c
@@ -27,6 +27,8 @@
 #include "qemu/error-report.h"
 #include "qemu/module.h"
 #include "qemu/cutils.h"
+#include "qapi/qmp/qerror.h"
+#include "qom/object_interfaces.h"
 #include CONFIG_DEVICES
 #ifdef CONFIG_PSERIES
 #include "hw/ppc/spapr_rtas.h"
@@ -849,18 +851,9 @@ static void qtest_event(void *opaque, QEMUChrEvent event)
         break;
     }
 }
-void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **errp)
-{
-    Chardev *chr;
-
-    chr = qemu_chr_new("qtest", qtest_chrdev, NULL);
-
-    if (chr == NULL) {
-        error_setg(errp, "Failed to initialize device for qtest: \"%s\"",
-                   qtest_chrdev);
-        return;
-    }
 
+static bool qtest_server_start(Chardev *chr, const char *qtest_log, Error **errp)
+{
     if (qtest_log) {
         if (strcmp(qtest_log, "none") != 0) {
             qtest_log_fp = fopen(qtest_log, "w+");
@@ -869,7 +862,9 @@ void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **
         qtest_log_fp = stderr;
     }
 
-    qemu_chr_fe_init(&qtest_chr, chr, errp);
+    if (!qemu_chr_fe_init(&qtest_chr, chr, errp)) {
+        return false;
+    }
     qemu_chr_fe_set_handlers(&qtest_chr, qtest_can_read, qtest_read,
                              qtest_event, NULL, &qtest_chr, NULL, true);
     qemu_chr_fe_set_echo(&qtest_chr, true);
@@ -879,8 +874,25 @@ void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **
     if (!qtest_server_send) {
         qtest_server_set_send_handler(qtest_server_char_be_send, &qtest_chr);
     }
+    return true;
+}
+
+void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **errp)
+{
+    Chardev *chr;
+
+    chr = qemu_chr_new("qtest", qtest_chrdev, NULL);
+
+    if (chr == NULL) {
+        error_setg(errp, "Failed to initialize device for qtest: \"%s\"",
+                   qtest_chrdev);
+        return;
+    }
+
+    qtest_server_start(chr, qtest_log, errp);
 }
 
+
 void qtest_server_set_send_handler(void (*send)(void*, const char*),
                                    void *opaque)
 {
@@ -905,3 +917,111 @@ void qtest_server_inproc_recv(void *dummy, const char *buf)
         g_string_truncate(gstr, 0);
     }
 }
+
+#define TYPE_QTEST "qtest"
+
+OBJECT_DECLARE_SIMPLE_TYPE(QTest, QTEST)
+
+struct QTest {
+    Object parent;
+
+    bool complete;
+    char *chr_name;
+    Chardev *chr;
+    char *log;
+};
+
+static void qtest_complete(UserCreatable *uc, Error **errp)
+{
+    QTest *q = QTEST(uc);
+    if (qtest_driver()) {
+        error_setg(errp, "Only one instance of qtest can be created");
+        return;
+    }
+    if (!q->chr_name) {
+        error_setg(errp, "No backend specified");
+        return;
+    }
+
+    if (!qtest_server_start(q->chr, q->log, errp)) {
+        return;
+    }
+    q->complete = true;
+}
+
+static void qtest_set_log(Object *obj, const char *value, Error **errp)
+{
+    QTest *q = QTEST(obj);
+
+    if (q->complete) {
+        error_setg(errp, QERR_PERMISSION_DENIED);
+    } else {
+        g_free(q->log);
+        q->log = g_strdup(value);
+    }
+}
+
+static char *qtest_get_log(Object *obj, Error **errp)
+{
+    QTest *q = QTEST(obj);
+
+    return g_strdup(q->log);
+}
+
+static void qtest_set_chardev(Object *obj, const char *value, Error **errp)
+{
+    QTest *q = QTEST(obj);
+    Chardev *chr;
+
+    if (q->complete) {
+        error_setg(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    chr = qemu_chr_find(value);
+    if (!chr) {
+        error_setg(errp, "Cannot find character device '%s'", value);
+        return;
+    }
+
+    g_free(q->chr_name);
+    q->chr_name = g_strdup(value);
+    q->chr = chr;
+}
+
+static char *qtest_get_chardev(Object *obj, Error **errp)
+{
+    QTest *q = QTEST(obj);
+
+    return g_strdup(q->chr_name);
+}
+
+static void qtest_class_init(ObjectClass *oc, void *data)
+{
+    UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
+
+    ucc->complete = qtest_complete;
+
+    object_class_property_add_str(oc, "chardev",
+                                  qtest_get_chardev, qtest_set_chardev);
+    object_class_property_add_str(oc, "log",
+                                  qtest_get_log, qtest_set_log);
+}
+
+static const TypeInfo qtest_info = {
+    .name = TYPE_QTEST,
+    .parent = TYPE_OBJECT,
+    .class_init = qtest_class_init,
+    .instance_size = sizeof(QTest),
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_USER_CREATABLE },
+        { }
+    }
+};
+
+static void register_types(void)
+{
+    type_register_static(&qtest_info);
+}
+
+type_init(register_types);
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 0f7222af31..e5f3c42049 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -1685,8 +1685,9 @@ static bool object_create_early(const char *type, QemuOpts *opts)
      * add one, state the reason in a comment!
      */
 
-    /* Reason: rng-egd property "chardev" */
-    if (g_str_equal(type, "rng-egd")) {
+    /* Reason: property "chardev" */
+    if (g_str_equal(type, "rng-egd") ||
+        g_str_equal(type, "qtest")) {
         return false;
     }
 
-- 
2.26.2




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

* [PATCH 12/15] plugin: propagate errors
  2020-12-02  8:18 [PATCH 00/15] Finish cleaning up qemu_init Paolo Bonzini
                   ` (10 preceding siblings ...)
  2020-12-02  8:18 ` [PATCH 11/15] qtest: add a QOM object for qtest Paolo Bonzini
@ 2020-12-02  8:18 ` Paolo Bonzini
  2020-12-02 11:33   ` Alex Bennée
  2020-12-07 16:53   ` Igor Mammedov
  2020-12-02  8:18 ` [PATCH 13/15] memory: allow creating MemoryRegions before accelerators Paolo Bonzini
                   ` (3 subsequent siblings)
  15 siblings, 2 replies; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-02  8:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo, Alex Bennée

qemu_finish_machine_init currently can only exit QEMU if it fails.
Prepare for giving it proper error propagation, and possibly for
adding a plugin_add monitor command that calls an accelerator
method.

While at it, make all errors from plugin_load look the same.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/plugin.h |  4 ++--
 linux-user/main.c     |  4 +---
 plugins/loader.c      | 34 +++++++++++++++++-----------------
 softmmu/vl.c          |  4 +---
 4 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
index ab790ad105..841deed79c 100644
--- a/include/qemu/plugin.h
+++ b/include/qemu/plugin.h
@@ -45,7 +45,7 @@ static inline void qemu_plugin_add_opts(void)
 }
 
 void qemu_plugin_opt_parse(const char *optarg, QemuPluginList *head);
-int qemu_plugin_load_list(QemuPluginList *head);
+int qemu_plugin_load_list(QemuPluginList *head, Error **errp);
 
 union qemu_plugin_cb_sig {
     qemu_plugin_simple_cb_t          simple;
@@ -199,7 +199,7 @@ static inline void qemu_plugin_opt_parse(const char *optarg,
     exit(1);
 }
 
-static inline int qemu_plugin_load_list(QemuPluginList *head)
+static inline int qemu_plugin_load_list(QemuPluginList *head, Error **errp)
 {
     return 0;
 }
diff --git a/linux-user/main.c b/linux-user/main.c
index 24d1eb73ad..750a01118f 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -671,9 +671,7 @@ int main(int argc, char **argv, char **envp)
         exit(1);
     }
     trace_init_file();
-    if (qemu_plugin_load_list(&plugins)) {
-        exit(1);
-    }
+    qemu_plugin_load_list(&plugins, &error_fatal);
 
     /* Zero out regs */
     memset(regs, 0, sizeof(struct target_pt_regs));
diff --git a/plugins/loader.c b/plugins/loader.c
index 8ac5dbc20f..5cb9794fda 100644
--- a/plugins/loader.c
+++ b/plugins/loader.c
@@ -150,7 +150,7 @@ static uint64_t xorshift64star(uint64_t x)
     return x * UINT64_C(2685821657736338717);
 }
 
-static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info)
+static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info, Error **errp)
 {
     qemu_plugin_install_func_t install;
     struct qemu_plugin_ctx *ctx;
@@ -163,37 +163,37 @@ static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info)
 
     ctx->handle = g_module_open(desc->path, G_MODULE_BIND_LOCAL);
     if (ctx->handle == NULL) {
-        error_report("%s: %s", __func__, g_module_error());
+        error_setg(errp, "Could not load plugin %s: %s", desc->path, g_module_error());
         goto err_dlopen;
     }
 
     if (!g_module_symbol(ctx->handle, "qemu_plugin_install", &sym)) {
-        error_report("%s: %s", __func__, g_module_error());
+        error_setg(errp, "Could not load plugin %s: %s", desc->path, g_module_error());
         goto err_symbol;
     }
     install = (qemu_plugin_install_func_t) sym;
     /* symbol was found; it could be NULL though */
     if (install == NULL) {
-        error_report("%s: %s: qemu_plugin_install is NULL",
-                     __func__, desc->path);
+        error_setg(errp, "Could not load plugin %s: qemu_plugin_install is NULL",
+                   desc->path);
         goto err_symbol;
     }
 
     if (!g_module_symbol(ctx->handle, "qemu_plugin_version", &sym)) {
-        error_report("TCG plugin %s does not declare API version %s",
-                     desc->path, g_module_error());
+        error_setg(errp, "Could not load plugin %s: plugin does not declare API version %s",
+                   desc->path, g_module_error());
         goto err_symbol;
     } else {
         int version = *(int *)sym;
         if (version < QEMU_PLUGIN_MIN_VERSION) {
-            error_report("TCG plugin %s requires API version %d, but "
-                         "this QEMU supports only a minimum version of %d",
-                         desc->path, version, QEMU_PLUGIN_MIN_VERSION);
+            error_setg(errp, "Could not load plugin %s: plugin requires API version %d, but "
+                       "this QEMU supports only a minimum version of %d",
+                       desc->path, version, QEMU_PLUGIN_MIN_VERSION);
             goto err_symbol;
         } else if (version > QEMU_PLUGIN_VERSION) {
-            error_report("TCG plugin %s requires API version %d, but "
-                         "this QEMU supports only up to version %d",
-                         desc->path, version, QEMU_PLUGIN_VERSION);
+            error_setg(errp, "Could not load plugin %s: plugin requires API version %d, but "
+                       "this QEMU supports only up to version %d",
+                       desc->path, version, QEMU_PLUGIN_VERSION);
             goto err_symbol;
         }
     }
@@ -220,8 +220,8 @@ static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info)
     rc = install(ctx->id, info, desc->argc, desc->argv);
     ctx->installing = false;
     if (rc) {
-        error_report("%s: qemu_plugin_install returned error code %d",
-                     __func__, rc);
+        error_setg(errp, "Could not load plugin %s: qemu_plugin_install returned error code %d",
+                   desc->path, rc);
         /*
          * we cannot rely on the plugin doing its own cleanup, so
          * call a full uninstall if the plugin did not yet call it.
@@ -263,7 +263,7 @@ static void plugin_desc_free(struct qemu_plugin_desc *desc)
  * Note: the descriptor of each successfully installed plugin is removed
  * from the list given by @head.
  */
-int qemu_plugin_load_list(QemuPluginList *head)
+int qemu_plugin_load_list(QemuPluginList *head, Error **errp)
 {
     struct qemu_plugin_desc *desc, *next;
     g_autofree qemu_info_t *info = g_new0(qemu_info_t, 1);
@@ -283,7 +283,7 @@ int qemu_plugin_load_list(QemuPluginList *head)
     QTAILQ_FOREACH_SAFE(desc, head, entry, next) {
         int err;
 
-        err = plugin_load(desc, info);
+        err = plugin_load(desc, info, errp);
         if (err) {
             return err;
         }
diff --git a/softmmu/vl.c b/softmmu/vl.c
index e5f3c42049..0f63d80472 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -2417,9 +2417,7 @@ static void qemu_init_board(void)
     }
 
     /* process plugin before CPUs are created, but once -smp has been parsed */
-    if (qemu_plugin_load_list(&plugin_list)) {
-        exit(1);
-    }
+    qemu_plugin_load_list(&plugin_list, &error_fatal);
 
     /* From here on we enter MACHINE_PHASE_INITIALIZED.  */
     machine_run_board_init(current_machine);
-- 
2.26.2




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

* [PATCH 13/15] memory: allow creating MemoryRegions before accelerators
  2020-12-02  8:18 [PATCH 00/15] Finish cleaning up qemu_init Paolo Bonzini
                   ` (11 preceding siblings ...)
  2020-12-02  8:18 ` [PATCH 12/15] plugin: propagate errors Paolo Bonzini
@ 2020-12-02  8:18 ` Paolo Bonzini
  2020-12-07 16:38   ` Igor Mammedov
  2020-12-07 17:06   ` Igor Mammedov
  2020-12-02  8:18 ` [PATCH 14/15] null-machine: do not create a default memdev Paolo Bonzini
                   ` (2 subsequent siblings)
  15 siblings, 2 replies; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-02  8:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo

Compute the DIRTY_MEMORY_CODE bit in memory_region_get_dirty_log_mask
instead of memory_region_init_*.  This makes it possible to allocate
memory backend objects at any time.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 softmmu/memory.c | 12 ++++++------
 softmmu/vl.c     |  6 +-----
 2 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/softmmu/memory.c b/softmmu/memory.c
index 11ca94d037..89a4723fe5 100644
--- a/softmmu/memory.c
+++ b/softmmu/memory.c
@@ -1548,7 +1548,6 @@ void memory_region_init_ram_shared_nomigrate(MemoryRegion *mr,
     mr->terminates = true;
     mr->destructor = memory_region_destructor_ram;
     mr->ram_block = qemu_ram_alloc(size, share, mr, &err);
-    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
     if (err) {
         mr->size = int128_zero();
         object_unparent(OBJECT(mr));
@@ -1573,7 +1572,6 @@ void memory_region_init_resizeable_ram(MemoryRegion *mr,
     mr->destructor = memory_region_destructor_ram;
     mr->ram_block = qemu_ram_alloc_resizeable(size, max_size, resized,
                                               mr, &err);
-    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
     if (err) {
         mr->size = int128_zero();
         object_unparent(OBJECT(mr));
@@ -1598,7 +1596,6 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
     mr->destructor = memory_region_destructor_ram;
     mr->align = align;
     mr->ram_block = qemu_ram_alloc_from_file(size, mr, ram_flags, path, &err);
-    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
     if (err) {
         mr->size = int128_zero();
         object_unparent(OBJECT(mr));
@@ -1622,7 +1619,6 @@ void memory_region_init_ram_from_fd(MemoryRegion *mr,
     mr->ram_block = qemu_ram_alloc_from_fd(size, mr,
                                            share ? RAM_SHARED : 0,
                                            fd, &err);
-    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
     if (err) {
         mr->size = int128_zero();
         object_unparent(OBJECT(mr));
@@ -1641,7 +1637,6 @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
     mr->ram = true;
     mr->terminates = true;
     mr->destructor = memory_region_destructor_ram;
-    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
 
     /* qemu_ram_alloc_from_ptr cannot fail with ptr != NULL.  */
     assert(ptr != NULL);
@@ -1661,7 +1656,7 @@ void memory_region_init_ram_device_ptr(MemoryRegion *mr,
     mr->ops = &ram_device_mem_ops;
     mr->opaque = mr;
     mr->destructor = memory_region_destructor_ram;
-    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
+
     /* qemu_ram_alloc_from_ptr cannot fail with ptr != NULL.  */
     assert(ptr != NULL);
     mr->ram_block = qemu_ram_alloc_from_ptr(size, ptr, mr, &error_fatal);
@@ -1819,6 +1814,11 @@ uint8_t memory_region_get_dirty_log_mask(MemoryRegion *mr)
                              memory_region_is_iommu(mr))) {
         mask |= (1 << DIRTY_MEMORY_MIGRATION);
     }
+
+    if (tcg_enabled() && rb) {
+        /* TCG only cares about dirty memory logging for RAM, not IOMMU.  */
+        mask |= (1 << DIRTY_MEMORY_CODE);
+    }
     return mask;
 }
 
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 0f63d80472..023c16245b 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -1715,11 +1715,7 @@ static bool object_create_early(const char *type, QemuOpts *opts)
         return false;
     }
 
-    /* Memory allocation by backends needs to be done
-     * after configure_accelerator() (due to the tcg_enabled()
-     * checks at memory_region_init_*()).
-     *
-     * Also, allocation of large amounts of memory may delay
+    /* Allocation of large amounts of memory may delay
      * chardev initialization for too long, and trigger timeouts
      * on software that waits for a monitor socket to be created
      * (e.g. libvirt).
-- 
2.26.2




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

* [PATCH 14/15] null-machine: do not create a default memdev
  2020-12-02  8:18 [PATCH 00/15] Finish cleaning up qemu_init Paolo Bonzini
                   ` (12 preceding siblings ...)
  2020-12-02  8:18 ` [PATCH 13/15] memory: allow creating MemoryRegions before accelerators Paolo Bonzini
@ 2020-12-02  8:18 ` Paolo Bonzini
  2020-12-07 16:43   ` Igor Mammedov
  2020-12-02  8:18 ` [PATCH 15/15] monitor: allow quitting while in preconfig state Paolo Bonzini
  2020-12-07 14:12 ` [PATCH 00/15] Finish cleaning up qemu_init no-reply
  15 siblings, 1 reply; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-02  8:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo

The default RAM size is 0, so no RAM will be created anyway.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/core/null-machine.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/core/null-machine.c b/hw/core/null-machine.c
index 7e693523d7..c40badf5bc 100644
--- a/hw/core/null-machine.c
+++ b/hw/core/null-machine.c
@@ -49,7 +49,7 @@ static void machine_none_machine_init(MachineClass *mc)
     mc->init = machine_none_init;
     mc->max_cpus = 1;
     mc->default_ram_size = 0;
-    mc->default_ram_id = "ram";
+    mc->default_ram_id = NULL;
     mc->no_serial = 1;
     mc->no_parallel = 1;
     mc->no_floppy = 1;
-- 
2.26.2




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

* [PATCH 15/15] monitor: allow quitting while in preconfig state
  2020-12-02  8:18 [PATCH 00/15] Finish cleaning up qemu_init Paolo Bonzini
                   ` (13 preceding siblings ...)
  2020-12-02  8:18 ` [PATCH 14/15] null-machine: do not create a default memdev Paolo Bonzini
@ 2020-12-02  8:18 ` Paolo Bonzini
  2020-12-07 16:45   ` Igor Mammedov
  2020-12-07 14:12 ` [PATCH 00/15] Finish cleaning up qemu_init no-reply
  15 siblings, 1 reply; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-02  8:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: imammedo

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hmp-commands.hx   | 1 +
 qapi/control.json | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index ff2d7aa8f3..d192afa652 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -45,6 +45,7 @@ ERST
         .params     = "",
         .help       = "quit the emulator",
         .cmd        = hmp_quit,
+        .flags      = "p",
     },
 
 SRST
diff --git a/qapi/control.json b/qapi/control.json
index 134f842baf..1ebc450aad 100644
--- a/qapi/control.json
+++ b/qapi/control.json
@@ -219,7 +219,8 @@
 # -> { "execute": "quit" }
 # <- { "return": {} }
 ##
-{ 'command': 'quit' }
+{ 'command': 'quit',
+  'allow-preconfig': true }
 
 ##
 # @MonitorMode:
-- 
2.26.2



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

* Re: [PATCH 12/15] plugin: propagate errors
  2020-12-02  8:18 ` [PATCH 12/15] plugin: propagate errors Paolo Bonzini
@ 2020-12-02 11:33   ` Alex Bennée
  2020-12-07 16:53   ` Igor Mammedov
  1 sibling, 0 replies; 50+ messages in thread
From: Alex Bennée @ 2020-12-02 11:33 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: imammedo, qemu-devel


Paolo Bonzini <pbonzini@redhat.com> writes:

> qemu_finish_machine_init currently can only exit QEMU if it fails.
> Prepare for giving it proper error propagation, and possibly for
> adding a plugin_add monitor command that calls an accelerator
> method.
>
> While at it, make all errors from plugin_load look the same.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Acked-by: Alex Bennée <alex.bennee@linaro.org>

-- 
Alex Bennée


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

* Re: [PATCH 01/15] remove preconfig state
  2020-12-02  8:18 ` [PATCH 01/15] remove preconfig state Paolo Bonzini
@ 2020-12-07 13:57   ` Igor Mammedov
  2020-12-07 14:11     ` Paolo Bonzini
  0 siblings, 1 reply; 50+ messages in thread
From: Igor Mammedov @ 2020-12-07 13:57 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On Wed,  2 Dec 2020 03:18:40 -0500
Paolo Bonzini <pbonzini@redhat.com> wrote:

> The preconfig state is only used if -incoming is not specified, which
> makes the RunState state machine more tricky than it need be.  However
> there is already an equivalent condition which works even with -incoming,
> namely qdev_hotplug.  Use it instead of a separate runstate.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  hw/core/machine-qmp-cmds.c    |  5 ++---
>  include/qapi/qmp/dispatch.h   |  1 +
>  monitor/hmp.c                 |  7 ++++---
>  monitor/qmp-cmds.c            |  5 ++---
>  qapi/qmp-dispatch.c           |  5 +----
>  qapi/run-state.json           |  5 +----
>  softmmu/qdev-monitor.c        | 12 ++++++++++++
>  softmmu/vl.c                  | 13 ++-----------
>  stubs/meson.build             |  1 +
>  stubs/qmp-command-available.c |  7 +++++++
>  tests/qtest/qmp-test.c        |  2 +-
>  11 files changed, 34 insertions(+), 29 deletions(-)
>  create mode 100644 stubs/qmp-command-available.c
> 
> diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
> index 5362c80a18..cb9387c5f5 100644
> --- a/hw/core/machine-qmp-cmds.c
> +++ b/hw/core/machine-qmp-cmds.c
> @@ -286,9 +286,8 @@ HotpluggableCPUList *qmp_query_hotpluggable_cpus(Error **errp)
>  
>  void qmp_set_numa_node(NumaOptions *cmd, Error **errp)
>  {
> -    if (!runstate_check(RUN_STATE_PRECONFIG)) {
> -        error_setg(errp, "The command is permitted only in '%s' state",
> -                   RunState_str(RUN_STATE_PRECONFIG));
> +    if (qdev_hotplug) {
it's too late for qmp_set_numa_node(), but given it's temporary
and patch 8/15 changes it to correct state it should be fine.
so

  Reviewed-by: Igor Mammedov <imammedo@redhat.com>


> +         error_setg(errp, "The command is permitted only before the machine has been created");
>           return;
>      }
>  
> diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
> index af8d96c570..1486cac3ef 100644
> --- a/include/qapi/qmp/dispatch.h
> +++ b/include/qapi/qmp/dispatch.h
> @@ -48,6 +48,7 @@ void qmp_disable_command(QmpCommandList *cmds, const char *name);
>  void qmp_enable_command(QmpCommandList *cmds, const char *name);
>  
>  bool qmp_command_is_enabled(const QmpCommand *cmd);
> +bool qmp_command_available(const QmpCommand *cmd, Error **errp);
>  const char *qmp_command_name(const QmpCommand *cmd);
>  bool qmp_has_success_response(const QmpCommand *cmd);
>  QDict *qmp_error_response(Error *err);
> diff --git a/monitor/hmp.c b/monitor/hmp.c
> index d40f4f4391..f2fe192d69 100644
> --- a/monitor/hmp.c
> +++ b/monitor/hmp.c
> @@ -24,6 +24,7 @@
>  
>  #include "qemu/osdep.h"
>  #include <dirent.h>
> +#include "hw/qdev-core.h"
>  #include "monitor-internal.h"
>  #include "qapi/error.h"
>  #include "qapi/qmp/qdict.h"
> @@ -215,7 +216,7 @@ static bool cmd_can_preconfig(const HMPCommand *cmd)
>  
>  static bool cmd_available(const HMPCommand *cmd)
>  {
> -    return !runstate_check(RUN_STATE_PRECONFIG) || cmd_can_preconfig(cmd);
> +    return qdev_hotplug || cmd_can_preconfig(cmd);
>  }
>  
>  static void help_cmd_dump_one(Monitor *mon,
> @@ -658,8 +659,8 @@ static const HMPCommand *monitor_parse_command(MonitorHMP *hmp_mon,
>          return NULL;
>      }
>      if (!cmd_available(cmd)) {
> -        monitor_printf(mon, "Command '%.*s' not available with -preconfig "
> -                            "until after exit_preconfig.\n",
> +        monitor_printf(mon, "Command '%.*s' not available "
> +                            "until machine initialization has completed.\n",
>                         (int)(p - cmdp_start), cmdp_start);
>          return NULL;
>      }
> diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
> index 6299c0c8c7..501a3024c7 100644
> --- a/monitor/qmp-cmds.c
> +++ b/monitor/qmp-cmds.c
> @@ -104,9 +104,8 @@ void qmp_system_powerdown(Error **errp)
>  
>  void qmp_x_exit_preconfig(Error **errp)
>  {
> -    if (!runstate_check(RUN_STATE_PRECONFIG)) {
> -        error_setg(errp, "The command is permitted only in '%s' state",
> -                   RunState_str(RUN_STATE_PRECONFIG));
> +    if (qdev_hotplug) {
> +        error_setg(errp, "The command is permitted only before machine initialization");
>          return;
>      }
>      qemu_exit_preconfig_request();
> diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
> index 9a2d7dd29a..0a2b20a4e4 100644
> --- a/qapi/qmp-dispatch.c
> +++ b/qapi/qmp-dispatch.c
> @@ -167,10 +167,7 @@ QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request,
>          goto out;
>      }
>  
> -    if (runstate_check(RUN_STATE_PRECONFIG) &&
> -        !(cmd->options & QCO_ALLOW_PRECONFIG)) {
> -        error_setg(&err, "The command '%s' isn't permitted in '%s' state",
> -                   cmd->name, RunState_str(RUN_STATE_PRECONFIG));
> +    if (!qmp_command_available(cmd, &err)) {
>          goto out;
>      }
>  
> diff --git a/qapi/run-state.json b/qapi/run-state.json
> index 964c8ef391..38194b0e44 100644
> --- a/qapi/run-state.json
> +++ b/qapi/run-state.json
> @@ -50,15 +50,12 @@
>  # @colo: guest is paused to save/restore VM state under colo checkpoint,
>  #        VM can not get into this state unless colo capability is enabled
>  #        for migration. (since 2.8)
> -# @preconfig: QEMU is paused before board specific init callback is executed.
> -#             The state is reachable only if the --preconfig CLI option is used.
> -#             (Since 3.0)
>  ##
>  { 'enum': 'RunState',
>    'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused',
>              'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm',
>              'running', 'save-vm', 'shutdown', 'suspended', 'watchdog',
> -            'guest-panicked', 'colo', 'preconfig' ] }
> +            'guest-panicked', 'colo' ] }
>  
>  ##
>  # @ShutdownCause:
> diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
> index d060e765da..e967d13bd0 100644
> --- a/softmmu/qdev-monitor.c
> +++ b/softmmu/qdev-monitor.c
> @@ -25,6 +25,7 @@
>  #include "sysemu/arch_init.h"
>  #include "qapi/error.h"
>  #include "qapi/qapi-commands-qdev.h"
> +#include "qapi/qmp/dispatch.h"
>  #include "qapi/qmp/qdict.h"
>  #include "qapi/qmp/qerror.h"
>  #include "qemu/config-file.h"
> @@ -997,3 +998,14 @@ int qemu_global_option(const char *str)
>  
>      return 0;
>  }
> +
> +bool qmp_command_available(const QmpCommand *cmd, Error **errp)
> +{
> +    if (!qdev_hotplug &&
> +        !(cmd->options & QCO_ALLOW_PRECONFIG)) {
> +        error_setg(errp, "The command '%s' is permitted only after machine initialization has completed",
> +                   cmd->name);
> +        return false;
> +    }
> +    return true;
> +}
> diff --git a/softmmu/vl.c b/softmmu/vl.c
> index 7146fbe219..ab2210bc79 100644
> --- a/softmmu/vl.c
> +++ b/softmmu/vl.c
> @@ -557,7 +557,7 @@ static int default_driver_check(void *opaque, QemuOpts *opts, Error **errp)
>  /***********************************************************/
>  /* QEMU state */
>  
> -static RunState current_run_state = RUN_STATE_PRECONFIG;
> +static RunState current_run_state = RUN_STATE_PRELAUNCH;
>  
>  /* We use RUN_STATE__MAX but any invalid value will do */
>  static RunState vmstop_requested = RUN_STATE__MAX;
> @@ -569,13 +569,7 @@ typedef struct {
>  } RunStateTransition;
>  
>  static const RunStateTransition runstate_transitions_def[] = {
> -    /*     from      ->     to      */
> -    { RUN_STATE_PRECONFIG, RUN_STATE_PRELAUNCH },
> -      /* Early switch to inmigrate state to allow  -incoming CLI option work
> -       * as it used to. TODO: delay actual switching to inmigrate state to
> -       * the point after machine is built and remove this hack.
> -       */
> -    { RUN_STATE_PRECONFIG, RUN_STATE_INMIGRATE },
> +    { RUN_STATE_PRELAUNCH, RUN_STATE_INMIGRATE },
>  
>      { RUN_STATE_DEBUG, RUN_STATE_RUNNING },
>      { RUN_STATE_DEBUG, RUN_STATE_FINISH_MIGRATE },
> @@ -1471,9 +1465,6 @@ static bool main_loop_should_exit(void)
>      ShutdownCause request;
>  
>      if (preconfig_exit_requested) {
> -        if (runstate_check(RUN_STATE_PRECONFIG)) {
> -            runstate_set(RUN_STATE_PRELAUNCH);
> -        }
>          preconfig_exit_requested = false;
>          return true;
>      }
> diff --git a/stubs/meson.build b/stubs/meson.build
> index 82b7ba60ab..cc56c83063 100644
> --- a/stubs/meson.build
> +++ b/stubs/meson.build
> @@ -29,6 +29,7 @@ stub_ss.add(files('pci-bus.c'))
>  stub_ss.add(files('pci-host-piix.c'))
>  stub_ss.add(files('qemu-timer-notify-cb.c'))
>  stub_ss.add(files('qmp_memory_device.c'))
> +stub_ss.add(files('qmp-command-available.c'))
>  stub_ss.add(files('qtest.c'))
>  stub_ss.add(files('ram-block.c'))
>  stub_ss.add(files('ramfb.c'))
> diff --git a/stubs/qmp-command-available.c b/stubs/qmp-command-available.c
> new file mode 100644
> index 0000000000..46540af7bf
> --- /dev/null
> +++ b/stubs/qmp-command-available.c
> @@ -0,0 +1,7 @@
> +#include "qemu/osdep.h"
> +#include "qapi/qmp/dispatch.h"
> +
> +bool qmp_command_available(const QmpCommand *cmd, Error **errp)
> +{
> +    return true;
> +}
> diff --git a/tests/qtest/qmp-test.c b/tests/qtest/qmp-test.c
> index eb1cd8abb8..11614bf63f 100644
> --- a/tests/qtest/qmp-test.c
> +++ b/tests/qtest/qmp-test.c
> @@ -295,7 +295,7 @@ static void test_qmp_preconfig(void)
>      rsp = qtest_qmp(qs, "{ 'execute': 'query-status' }");
>      ret = qdict_get_qdict(rsp, "return");
>      g_assert(ret);
> -    g_assert_cmpstr(qdict_get_try_str(ret, "status"), ==, "preconfig");
> +    g_assert_cmpstr(qdict_get_try_str(ret, "status"), ==, "prelaunch");
>      qobject_unref(rsp);
>  
>      /* exit preconfig state */



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

* Re: [PATCH 02/15] vl: remove separate preconfig main_loop
  2020-12-02  8:18 ` [PATCH 02/15] vl: remove separate preconfig main_loop Paolo Bonzini
@ 2020-12-07 14:02   ` Igor Mammedov
  0 siblings, 0 replies; 50+ messages in thread
From: Igor Mammedov @ 2020-12-07 14:02 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On Wed,  2 Dec 2020 03:18:41 -0500
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Move post-preconfig initialization to the x-exit-preconfig.  If preconfig
> is not requested, just exit preconfig mode immediately with the QMP
> command.
> 
> As a result, the preconfig loop will run with accel_setup_post
> and os_setup_post restrictions (xen_restrict, chroot, etc.)
> already done.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Reviewed-by: Igor Mammedov <imammedo@redhat.com>

> ---
>  include/sysemu/runstate.h |  1 -
>  monitor/qmp-cmds.c        |  9 ----
>  softmmu/vl.c              | 95 +++++++++++++++++----------------------
>  3 files changed, 41 insertions(+), 64 deletions(-)
> 
> diff --git a/include/sysemu/runstate.h b/include/sysemu/runstate.h
> index f760094858..e557f470d4 100644
> --- a/include/sysemu/runstate.h
> +++ b/include/sysemu/runstate.h
> @@ -41,7 +41,6 @@ typedef enum WakeupReason {
>      QEMU_WAKEUP_REASON_OTHER,
>  } WakeupReason;
>  
> -void qemu_exit_preconfig_request(void);
>  void qemu_system_reset_request(ShutdownCause reason);
>  void qemu_system_suspend_request(void);
>  void qemu_register_suspend_notifier(Notifier *notifier);
> diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
> index 501a3024c7..7ced7eb3e8 100644
> --- a/monitor/qmp-cmds.c
> +++ b/monitor/qmp-cmds.c
> @@ -102,15 +102,6 @@ void qmp_system_powerdown(Error **errp)
>      qemu_system_powerdown_request();
>  }
>  
> -void qmp_x_exit_preconfig(Error **errp)
> -{
> -    if (qdev_hotplug) {
> -        error_setg(errp, "The command is permitted only before machine initialization");
> -        return;
> -    }
> -    qemu_exit_preconfig_request();
> -}
> -
>  void qmp_cont(Error **errp)
>  {
>      BlockBackend *blk;
> diff --git a/softmmu/vl.c b/softmmu/vl.c
> index ab2210bc79..abbbb83e1a 100644
> --- a/softmmu/vl.c
> +++ b/softmmu/vl.c
> @@ -1151,7 +1151,6 @@ static pid_t shutdown_pid;
>  static int powerdown_requested;
>  static int debug_requested;
>  static int suspend_requested;
> -static bool preconfig_exit_requested = true;
>  static WakeupReason wakeup_reason;
>  static NotifierList powerdown_notifiers =
>      NOTIFIER_LIST_INITIALIZER(powerdown_notifiers);
> @@ -1238,11 +1237,6 @@ static int qemu_debug_requested(void)
>      return r;
>  }
>  
> -void qemu_exit_preconfig_request(void)
> -{
> -    preconfig_exit_requested = true;
> -}
> -
>  /*
>   * Reset the VM. Issue an event unless @reason is SHUTDOWN_CAUSE_NONE.
>   */
> @@ -1464,10 +1458,6 @@ static bool main_loop_should_exit(void)
>      RunState r;
>      ShutdownCause request;
>  
> -    if (preconfig_exit_requested) {
> -        preconfig_exit_requested = false;
> -        return true;
> -    }
>      if (qemu_debug_requested()) {
>          vm_stop(RUN_STATE_DEBUG);
>      }
> @@ -3283,6 +3273,43 @@ static void qemu_machine_creation_done(void)
>      register_global_state();
>  }
>  
> +void qmp_x_exit_preconfig(Error **errp)
> +{
> +    if (qdev_hotplug) {
> +        error_setg(errp, "The command is permitted only before machine initialization");
> +        return;
> +    }
> +
> +    qemu_init_board();
> +    qemu_create_cli_devices();
> +    qemu_machine_creation_done();
> +
> +    if (loadvm) {
> +        Error *local_err = NULL;
> +        if (load_snapshot(loadvm, &local_err) < 0) {
> +            error_report_err(local_err);
> +            autostart = 0;
> +            exit(1);
> +        }
> +    }
> +    if (replay_mode != REPLAY_MODE_NONE) {
> +        replay_vmstate_init();
> +    }
> +
> +    if (incoming) {
> +        Error *local_err = NULL;
> +        if (strcmp(incoming, "defer") != 0) {
> +            qmp_migrate_incoming(incoming, &local_err);
> +            if (local_err) {
> +                error_reportf_err(local_err, "-incoming %s: ", incoming);
> +                exit(1);
> +            }
> +        }
> +    } else if (autostart) {
> +        qmp_cont(NULL);
> +    }
> +}
> +
>  void qemu_init(int argc, char **argv, char **envp)
>  {
>      QemuOpts *opts;
> @@ -3847,7 +3874,6 @@ void qemu_init(int argc, char **argv, char **envp)
>                  }
>                  break;
>              case QEMU_OPTION_preconfig:
> -                preconfig_exit_requested = false;
>                  preconfig_requested = true;
>                  break;
>              case QEMU_OPTION_enable_kvm:
> @@ -4272,57 +4298,18 @@ void qemu_init(int argc, char **argv, char **envp)
>      qemu_resolve_machine_memdev();
>      parse_numa_opts(current_machine);
>  
> -    if (preconfig_requested) {
> -        qemu_init_displays();
> -    }
> -
> -    /* do monitor/qmp handling at preconfig state if requested */
> -    qemu_main_loop();
> -
> -    qemu_init_board();
> -
> -    qemu_create_cli_devices();
> -
> -    /* initialize displays after all errors have been reported */
> -    if (!preconfig_requested) {
> -        qemu_init_displays();
> -    }
> -    qemu_machine_creation_done();
> -
> -    if (loadvm) {
> -        Error *local_err = NULL;
> -        if (load_snapshot(loadvm, &local_err) < 0) {
> -            error_report_err(local_err);
> -            autostart = 0;
> -            exit(1);
> -        }
> -    }
> -    if (replay_mode != REPLAY_MODE_NONE) {
> -        replay_vmstate_init();
> -    }
> -
>      if (vmstate_dump_file) {
>          /* dump and exit */
>          dump_vmstate_json_to_file(vmstate_dump_file);
>          exit(0);
>      }
> -    if (incoming) {
> -        Error *local_err = NULL;
> -        if (strcmp(incoming, "defer") != 0) {
> -            qmp_migrate_incoming(incoming, &local_err);
> -            if (local_err) {
> -                error_reportf_err(local_err, "-incoming %s: ", incoming);
> -                exit(1);
> -            }
> -        }
> -    } else if (autostart) {
> -        qmp_cont(NULL);
> -    }
>  
> +    qemu_init_displays();
> +    if (!preconfig_requested) {
> +        qmp_x_exit_preconfig(&error_fatal);
> +    }
>      accel_setup_post(current_machine);
>      os_setup_post();
> -
> -    return;
>  }
>  
>  void qemu_cleanup(void)



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

* Re: [PATCH 01/15] remove preconfig state
  2020-12-07 13:57   ` Igor Mammedov
@ 2020-12-07 14:11     ` Paolo Bonzini
  2020-12-07 15:14       ` Igor Mammedov
  0 siblings, 1 reply; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-07 14:11 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 10499 bytes --]

Il lun 7 dic 2020, 14:57 Igor Mammedov <imammedo@redhat.com> ha scritto:

> On Wed,  2 Dec 2020 03:18:40 -0500
> Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> > The preconfig state is only used if -incoming is not specified, which
> > makes the RunState state machine more tricky than it need be.  However
> > there is already an equivalent condition which works even with -incoming,
> > namely qdev_hotplug.  Use it instead of a separate runstate.
> >
> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> > ---
> >  hw/core/machine-qmp-cmds.c    |  5 ++---
> >  include/qapi/qmp/dispatch.h   |  1 +
> >  monitor/hmp.c                 |  7 ++++---
> >  monitor/qmp-cmds.c            |  5 ++---
> >  qapi/qmp-dispatch.c           |  5 +----
> >  qapi/run-state.json           |  5 +----
> >  softmmu/qdev-monitor.c        | 12 ++++++++++++
> >  softmmu/vl.c                  | 13 ++-----------
> >  stubs/meson.build             |  1 +
> >  stubs/qmp-command-available.c |  7 +++++++
> >  tests/qtest/qmp-test.c        |  2 +-
> >  11 files changed, 34 insertions(+), 29 deletions(-)
> >  create mode 100644 stubs/qmp-command-available.c
> >
> > diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
> > index 5362c80a18..cb9387c5f5 100644
> > --- a/hw/core/machine-qmp-cmds.c
> > +++ b/hw/core/machine-qmp-cmds.c
> > @@ -286,9 +286,8 @@ HotpluggableCPUList
> *qmp_query_hotpluggable_cpus(Error **errp)
> >
> >  void qmp_set_numa_node(NumaOptions *cmd, Error **errp)
> >  {
> > -    if (!runstate_check(RUN_STATE_PRECONFIG)) {
> > -        error_setg(errp, "The command is permitted only in '%s' state",
> > -                   RunState_str(RUN_STATE_PRECONFIG));
> > +    if (qdev_hotplug) {
> it's too late for qmp_set_numa_node(), but given it's temporary
> and patch 8/15 changes it to correct state it should be fine.
> so
>
>   Reviewed-by: Igor Mammedov <imammedo@redhat.com>
>

It's too late according to the fine grained distinction of phases that will
be introduced later. For the two phases that are possible with current QEMU
(before or after preconfig) it should be indistinguishable, right?

Paolo


>
> > +         error_setg(errp, "The command is permitted only before the
> machine has been created");
> >           return;
> >      }
> >
> > diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
> > index af8d96c570..1486cac3ef 100644
> > --- a/include/qapi/qmp/dispatch.h
> > +++ b/include/qapi/qmp/dispatch.h
> > @@ -48,6 +48,7 @@ void qmp_disable_command(QmpCommandList *cmds, const
> char *name);
> >  void qmp_enable_command(QmpCommandList *cmds, const char *name);
> >
> >  bool qmp_command_is_enabled(const QmpCommand *cmd);
> > +bool qmp_command_available(const QmpCommand *cmd, Error **errp);
> >  const char *qmp_command_name(const QmpCommand *cmd);
> >  bool qmp_has_success_response(const QmpCommand *cmd);
> >  QDict *qmp_error_response(Error *err);
> > diff --git a/monitor/hmp.c b/monitor/hmp.c
> > index d40f4f4391..f2fe192d69 100644
> > --- a/monitor/hmp.c
> > +++ b/monitor/hmp.c
> > @@ -24,6 +24,7 @@
> >
> >  #include "qemu/osdep.h"
> >  #include <dirent.h>
> > +#include "hw/qdev-core.h"
> >  #include "monitor-internal.h"
> >  #include "qapi/error.h"
> >  #include "qapi/qmp/qdict.h"
> > @@ -215,7 +216,7 @@ static bool cmd_can_preconfig(const HMPCommand *cmd)
> >
> >  static bool cmd_available(const HMPCommand *cmd)
> >  {
> > -    return !runstate_check(RUN_STATE_PRECONFIG) ||
> cmd_can_preconfig(cmd);
> > +    return qdev_hotplug || cmd_can_preconfig(cmd);
> >  }
> >
> >  static void help_cmd_dump_one(Monitor *mon,
> > @@ -658,8 +659,8 @@ static const HMPCommand
> *monitor_parse_command(MonitorHMP *hmp_mon,
> >          return NULL;
> >      }
> >      if (!cmd_available(cmd)) {
> > -        monitor_printf(mon, "Command '%.*s' not available with
> -preconfig "
> > -                            "until after exit_preconfig.\n",
> > +        monitor_printf(mon, "Command '%.*s' not available "
> > +                            "until machine initialization has
> completed.\n",
> >                         (int)(p - cmdp_start), cmdp_start);
> >          return NULL;
> >      }
> > diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
> > index 6299c0c8c7..501a3024c7 100644
> > --- a/monitor/qmp-cmds.c
> > +++ b/monitor/qmp-cmds.c
> > @@ -104,9 +104,8 @@ void qmp_system_powerdown(Error **errp)
> >
> >  void qmp_x_exit_preconfig(Error **errp)
> >  {
> > -    if (!runstate_check(RUN_STATE_PRECONFIG)) {
> > -        error_setg(errp, "The command is permitted only in '%s' state",
> > -                   RunState_str(RUN_STATE_PRECONFIG));
> > +    if (qdev_hotplug) {
> > +        error_setg(errp, "The command is permitted only before machine
> initialization");
> >          return;
> >      }
> >      qemu_exit_preconfig_request();
> > diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
> > index 9a2d7dd29a..0a2b20a4e4 100644
> > --- a/qapi/qmp-dispatch.c
> > +++ b/qapi/qmp-dispatch.c
> > @@ -167,10 +167,7 @@ QDict *qmp_dispatch(const QmpCommandList *cmds,
> QObject *request,
> >          goto out;
> >      }
> >
> > -    if (runstate_check(RUN_STATE_PRECONFIG) &&
> > -        !(cmd->options & QCO_ALLOW_PRECONFIG)) {
> > -        error_setg(&err, "The command '%s' isn't permitted in '%s'
> state",
> > -                   cmd->name, RunState_str(RUN_STATE_PRECONFIG));
> > +    if (!qmp_command_available(cmd, &err)) {
> >          goto out;
> >      }
> >
> > diff --git a/qapi/run-state.json b/qapi/run-state.json
> > index 964c8ef391..38194b0e44 100644
> > --- a/qapi/run-state.json
> > +++ b/qapi/run-state.json
> > @@ -50,15 +50,12 @@
> >  # @colo: guest is paused to save/restore VM state under colo checkpoint,
> >  #        VM can not get into this state unless colo capability is
> enabled
> >  #        for migration. (since 2.8)
> > -# @preconfig: QEMU is paused before board specific init callback is
> executed.
> > -#             The state is reachable only if the --preconfig CLI option
> is used.
> > -#             (Since 3.0)
> >  ##
> >  { 'enum': 'RunState',
> >    'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error',
> 'paused',
> >              'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm',
> >              'running', 'save-vm', 'shutdown', 'suspended', 'watchdog',
> > -            'guest-panicked', 'colo', 'preconfig' ] }
> > +            'guest-panicked', 'colo' ] }
> >
> >  ##
> >  # @ShutdownCause:
> > diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
> > index d060e765da..e967d13bd0 100644
> > --- a/softmmu/qdev-monitor.c
> > +++ b/softmmu/qdev-monitor.c
> > @@ -25,6 +25,7 @@
> >  #include "sysemu/arch_init.h"
> >  #include "qapi/error.h"
> >  #include "qapi/qapi-commands-qdev.h"
> > +#include "qapi/qmp/dispatch.h"
> >  #include "qapi/qmp/qdict.h"
> >  #include "qapi/qmp/qerror.h"
> >  #include "qemu/config-file.h"
> > @@ -997,3 +998,14 @@ int qemu_global_option(const char *str)
> >
> >      return 0;
> >  }
> > +
> > +bool qmp_command_available(const QmpCommand *cmd, Error **errp)
> > +{
> > +    if (!qdev_hotplug &&
> > +        !(cmd->options & QCO_ALLOW_PRECONFIG)) {
> > +        error_setg(errp, "The command '%s' is permitted only after
> machine initialization has completed",
> > +                   cmd->name);
> > +        return false;
> > +    }
> > +    return true;
> > +}
> > diff --git a/softmmu/vl.c b/softmmu/vl.c
> > index 7146fbe219..ab2210bc79 100644
> > --- a/softmmu/vl.c
> > +++ b/softmmu/vl.c
> > @@ -557,7 +557,7 @@ static int default_driver_check(void *opaque,
> QemuOpts *opts, Error **errp)
> >  /***********************************************************/
> >  /* QEMU state */
> >
> > -static RunState current_run_state = RUN_STATE_PRECONFIG;
> > +static RunState current_run_state = RUN_STATE_PRELAUNCH;
> >
> >  /* We use RUN_STATE__MAX but any invalid value will do */
> >  static RunState vmstop_requested = RUN_STATE__MAX;
> > @@ -569,13 +569,7 @@ typedef struct {
> >  } RunStateTransition;
> >
> >  static const RunStateTransition runstate_transitions_def[] = {
> > -    /*     from      ->     to      */
> > -    { RUN_STATE_PRECONFIG, RUN_STATE_PRELAUNCH },
> > -      /* Early switch to inmigrate state to allow  -incoming CLI option
> work
> > -       * as it used to. TODO: delay actual switching to inmigrate state
> to
> > -       * the point after machine is built and remove this hack.
> > -       */
> > -    { RUN_STATE_PRECONFIG, RUN_STATE_INMIGRATE },
> > +    { RUN_STATE_PRELAUNCH, RUN_STATE_INMIGRATE },
> >
> >      { RUN_STATE_DEBUG, RUN_STATE_RUNNING },
> >      { RUN_STATE_DEBUG, RUN_STATE_FINISH_MIGRATE },
> > @@ -1471,9 +1465,6 @@ static bool main_loop_should_exit(void)
> >      ShutdownCause request;
> >
> >      if (preconfig_exit_requested) {
> > -        if (runstate_check(RUN_STATE_PRECONFIG)) {
> > -            runstate_set(RUN_STATE_PRELAUNCH);
> > -        }
> >          preconfig_exit_requested = false;
> >          return true;
> >      }
> > diff --git a/stubs/meson.build b/stubs/meson.build
> > index 82b7ba60ab..cc56c83063 100644
> > --- a/stubs/meson.build
> > +++ b/stubs/meson.build
> > @@ -29,6 +29,7 @@ stub_ss.add(files('pci-bus.c'))
> >  stub_ss.add(files('pci-host-piix.c'))
> >  stub_ss.add(files('qemu-timer-notify-cb.c'))
> >  stub_ss.add(files('qmp_memory_device.c'))
> > +stub_ss.add(files('qmp-command-available.c'))
> >  stub_ss.add(files('qtest.c'))
> >  stub_ss.add(files('ram-block.c'))
> >  stub_ss.add(files('ramfb.c'))
> > diff --git a/stubs/qmp-command-available.c
> b/stubs/qmp-command-available.c
> > new file mode 100644
> > index 0000000000..46540af7bf
> > --- /dev/null
> > +++ b/stubs/qmp-command-available.c
> > @@ -0,0 +1,7 @@
> > +#include "qemu/osdep.h"
> > +#include "qapi/qmp/dispatch.h"
> > +
> > +bool qmp_command_available(const QmpCommand *cmd, Error **errp)
> > +{
> > +    return true;
> > +}
> > diff --git a/tests/qtest/qmp-test.c b/tests/qtest/qmp-test.c
> > index eb1cd8abb8..11614bf63f 100644
> > --- a/tests/qtest/qmp-test.c
> > +++ b/tests/qtest/qmp-test.c
> > @@ -295,7 +295,7 @@ static void test_qmp_preconfig(void)
> >      rsp = qtest_qmp(qs, "{ 'execute': 'query-status' }");
> >      ret = qdict_get_qdict(rsp, "return");
> >      g_assert(ret);
> > -    g_assert_cmpstr(qdict_get_try_str(ret, "status"), ==, "preconfig");
> > +    g_assert_cmpstr(qdict_get_try_str(ret, "status"), ==, "prelaunch");
> >      qobject_unref(rsp);
> >
> >      /* exit preconfig state */
>
>

[-- Attachment #2: Type: text/html, Size: 13932 bytes --]

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

* Re: [PATCH 00/15] Finish cleaning up qemu_init
  2020-12-02  8:18 [PATCH 00/15] Finish cleaning up qemu_init Paolo Bonzini
                   ` (14 preceding siblings ...)
  2020-12-02  8:18 ` [PATCH 15/15] monitor: allow quitting while in preconfig state Paolo Bonzini
@ 2020-12-07 14:12 ` no-reply
  15 siblings, 0 replies; 50+ messages in thread
From: no-reply @ 2020-12-07 14:12 UTC (permalink / raw)
  To: pbonzini; +Cc: imammedo, qemu-devel

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



Hi,

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

Type: series
Message-id: 20201202081854.4126071-1-pbonzini@redhat.com
Subject: [PATCH 00/15] Finish cleaning up qemu_init

=== 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/20201202081854.4126071-1-pbonzini@redhat.com -> patchew/20201202081854.4126071-1-pbonzini@redhat.com
 - [tag update]      patchew/20201207084042.7690-1-cfontana@suse.de -> patchew/20201207084042.7690-1-cfontana@suse.de
Switched to a new branch 'test'
450811f monitor: allow quitting while in preconfig state
dce3fd5 null-machine: do not create a default memdev
e52482a memory: allow creating MemoryRegions before accelerators
e951562 plugin: propagate errors
c29889b qtest: add a QOM object for qtest
f7526bf vl: make qemu_get_machine_opts static
5f1f6d1 machine: record whether nvdimm= was set
8e65049 machine: introduce MachineInitPhase
7c4cb1c chardev: do not use machine_init_done
0f1597f vl: move all generic initialization out of vl.c
c55f69e vl: extract softmmu/globals.c
6df0eeb vl: extract softmmu/runstate.c
1c6bebb vl: allow -incoming defer with -preconfig
893660d vl: remove separate preconfig main_loop
a028d58 remove preconfig state

=== OUTPUT BEGIN ===
1/15 Checking commit a028d58a8e83 (remove preconfig state)
ERROR: suspect code indent for conditional statements (4, 9)
#27: FILE: hw/core/machine-qmp-cmds.c:289:
+    if (qdev_hotplug) {
+         error_setg(errp, "The command is permitted only before the machine has been created");

ERROR: line over 90 characters
#28: FILE: hw/core/machine-qmp-cmds.c:290:
+         error_setg(errp, "The command is permitted only before the machine has been created");

WARNING: line over 80 characters
#88: FILE: monitor/qmp-cmds.c:108:
+        error_setg(errp, "The command is permitted only before machine initialization");

ERROR: line over 90 characters
#150: FILE: softmmu/qdev-monitor.c:1006:
+        error_setg(errp, "The command '%s' is permitted only after machine initialization has completed",

WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#207: 
new file mode 100644

total: 3 errors, 2 warnings, 155 lines checked

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

2/15 Checking commit 893660defe11 (vl: remove separate preconfig main_loop)
WARNING: line over 80 characters
#93: FILE: softmmu/vl.c:3279:
+        error_setg(errp, "The command is permitted only before machine initialization");

total: 0 errors, 1 warnings, 161 lines checked

Patch 2/15 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
3/15 Checking commit 1c6bebbd00e1 (vl: allow -incoming defer with -preconfig)
4/15 Checking commit 6df0eeb3c804 (vl: extract softmmu/runstate.c)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#46: 
new file mode 100644

WARNING: Block comments use a leading /* on a separate line
#422: FILE: softmmu/runstate.c:372:
+            /* This happens for eg ^C at the terminal, so it's worth

ERROR: Don't use '#' flag of printf format ('%#') in format strings, use '0x' prefix instead
#532: FILE: softmmu/runstate.c:482:
+            qemu_log_mask(LOG_GUEST_ERROR, "\nHV crash parameters: (%#"PRIx64

ERROR: Don't use '#' flag of printf format ('%#') in format strings, use '0x' prefix instead
#533: FILE: softmmu/runstate.c:483:
+                          " %#"PRIx64" %#"PRIx64" %#"PRIx64" %#"PRIx64")\n",

ERROR: Don't use '#' flag of printf format ('%#') in format strings, use '0x' prefix instead
#533: FILE: softmmu/runstate.c:483:
+                          " %#"PRIx64" %#"PRIx64" %#"PRIx64" %#"PRIx64")\n",

ERROR: Don't use '#' flag of printf format ('%#') in format strings, use '0x' prefix instead
#533: FILE: softmmu/runstate.c:483:
+                          " %#"PRIx64" %#"PRIx64" %#"PRIx64" %#"PRIx64")\n",

ERROR: Don't use '#' flag of printf format ('%#') in format strings, use '0x' prefix instead
#533: FILE: softmmu/runstate.c:483:
+                          " %#"PRIx64" %#"PRIx64" %#"PRIx64" %#"PRIx64")\n",

WARNING: Block comments use a leading /* on a separate line
#646: FILE: softmmu/runstate.c:596:
+    /* Cannot call qemu_system_shutdown_request directly because

total: 5 errors, 3 warnings, 1585 lines checked

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

5/15 Checking commit c55f69ec8bed (vl: extract softmmu/globals.c)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#50: 
new file mode 100644

ERROR: "foo* bar" should be "foo *bar"
#92: FILE: softmmu/globals.c:38:
+const char* keyboard_layout;

WARNING: Block comments use a leading /* on a separate line
#120: FILE: softmmu/globals.c:66:
+/* The bytes in qemu_uuid are in the order specified by RFC4122, _not_ in the

total: 1 errors, 2 warnings, 184 lines checked

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

6/15 Checking commit 0f1597fd687a (vl: move all generic initialization out of vl.c)
WARNING: line over 80 characters
#56: FILE: hw/core/machine.c:1200:
+        qemu_register_reset(restore_boot_order, g_strdup(current_machine->boot_order));

WARNING: Block comments use a leading /* on a separate line
#66: FILE: hw/core/machine.c:1210:
+    /* TODO: once all bus devices are qdevified, this should be done

WARNING: Block comments use a trailing */ on a separate line
#67: FILE: hw/core/machine.c:1211:
+     * when bus is created by qdev.c */

WARNING: Block comments use a leading /* on a separate line
#88: FILE: hw/core/machine.c:1232:
+    /* This checkpoint is required by replay to separate prior clock

WARNING: Block comments use * on subsequent lines
#89: FILE: hw/core/machine.c:1233:
+    /* This checkpoint is required by replay to separate prior clock
+       reading from the other reads, because timer polling functions query

WARNING: Block comments use a trailing */ on a separate line
#90: FILE: hw/core/machine.c:1234:
+       clock values from the log. */

total: 0 errors, 6 warnings, 164 lines checked

Patch 6/15 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
7/15 Checking commit 7c4cb1ca1ada (chardev: do not use machine_init_done)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#109: 
deleted file mode 100644

total: 0 errors, 1 warnings, 142 lines checked

Patch 7/15 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
8/15 Checking commit 8e65049a2eac (machine: introduce MachineInitPhase)
ERROR: line over 90 characters
#27: FILE: hw/core/machine-qmp-cmds.c:290:
+        error_setg(errp, "The command is permitted only before the machine has been created");

WARNING: line over 80 characters
#232: FILE: softmmu/qdev-monitor.c:640:
+    if ((hide || phase_check(PHASE_MACHINE_READY)) && bus && !qbus_is_hotpluggable(bus)) {

WARNING: line over 80 characters
#254: FILE: softmmu/qdev-monitor.c:664:
+            /* No bus, no machine hotplug handler --> device is not hotpluggable */

WARNING: line over 80 characters
#255: FILE: softmmu/qdev-monitor.c:665:
+            error_setg(errp, "Device '%s' can not be hotplugged on this machine",

WARNING: line over 80 characters
#327: FILE: ui/console.c:1348:
+    } else if (console_type != GRAPHIC_CONSOLE || phase_check(PHASE_MACHINE_READY)) {

total: 1 errors, 4 warnings, 250 lines checked

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

9/15 Checking commit 5f1f6d1df6e6 (machine: record whether nvdimm= was set)
10/15 Checking commit f7526bf54d78 (vl: make qemu_get_machine_opts static)
WARNING: line over 80 characters
#33: FILE: accel/kvm/kvm-all.c:2072:
+        g_autofree char *kvm_type = object_property_get_str(OBJECT(current_machine),

total: 0 errors, 1 warnings, 195 lines checked

Patch 10/15 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
11/15 Checking commit c29889b0f815 (qtest: add a QOM object for qtest)
WARNING: line over 80 characters
#33: FILE: softmmu/qtest.c:855:
+static bool qtest_server_start(Chardev *chr, const char *qtest_log, Error **errp)

total: 0 errors, 1 warnings, 190 lines checked

Patch 11/15 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
12/15 Checking commit e9515620c1bb (plugin: propagate errors)
ERROR: line over 90 characters
#64: FILE: plugins/loader.c:153:
+static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info, Error **errp)

WARNING: line over 80 characters
#73: FILE: plugins/loader.c:166:
+        error_setg(errp, "Could not load plugin %s: %s", desc->path, g_module_error());

WARNING: line over 80 characters
#79: FILE: plugins/loader.c:171:
+        error_setg(errp, "Could not load plugin %s: %s", desc->path, g_module_error());

WARNING: line over 80 characters
#87: FILE: plugins/loader.c:177:
+        error_setg(errp, "Could not load plugin %s: qemu_plugin_install is NULL",

ERROR: line over 90 characters
#95: FILE: plugins/loader.c:183:
+        error_setg(errp, "Could not load plugin %s: plugin does not declare API version %s",

ERROR: line over 90 characters
#104: FILE: plugins/loader.c:189:
+            error_setg(errp, "Could not load plugin %s: plugin requires API version %d, but "

ERROR: line over 90 characters
#112: FILE: plugins/loader.c:194:
+            error_setg(errp, "Could not load plugin %s: plugin requires API version %d, but "

ERROR: line over 90 characters
#124: FILE: plugins/loader.c:223:
+        error_setg(errp, "Could not load plugin %s: qemu_plugin_install returned error code %d",

total: 5 errors, 3 warnings, 119 lines checked

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

13/15 Checking commit e52482a2d2ad (memory: allow creating MemoryRegions before accelerators)
WARNING: Block comments use a leading /* on a separate line
#93: FILE: softmmu/vl.c:1718:
+    /* Allocation of large amounts of memory may delay

total: 0 errors, 1 warnings, 66 lines checked

Patch 13/15 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
14/15 Checking commit dce3fd5895a3 (null-machine: do not create a default memdev)
15/15 Checking commit 450811f89668 (monitor: allow quitting while in preconfig state)
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20201202081854.4126071-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] 50+ messages in thread

* Re: [PATCH 06/15] vl: move all generic initialization out of vl.c
  2020-12-02  8:18 ` [PATCH 06/15] vl: move all generic initialization out of vl.c Paolo Bonzini
@ 2020-12-07 14:19   ` Igor Mammedov
  0 siblings, 0 replies; 50+ messages in thread
From: Igor Mammedov @ 2020-12-07 14:19 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On Wed,  2 Dec 2020 03:18:45 -0500
Paolo Bonzini <pbonzini@redhat.com> wrote:

> qdev_machine_creation_done is only setting a flag now.  Extend it to
> move more code out of vl.c.  Leave only consistency checks and gdbserver
> processing in qemu_machine_creation_done.
> 
> gdbserver_start can be moved after qdev_machine_creation_done because
> it only does listen on the socket and creates some internal data
> structures; it does not send any data (e.g. guest state) over the socket.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Reviewed-by: Igor Mammedov <imammedo@redhat.com>

> ---
>  hw/core/machine.c      | 47 +++++++++++++++++++++++++++++++++++++++++-
>  hw/core/qdev.c         | 12 +++--------
>  include/hw/qdev-core.h |  1 +
>  softmmu/vl.c           | 37 +--------------------------------
>  4 files changed, 51 insertions(+), 46 deletions(-)
> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 5659b1f49c..025c4f9749 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -16,16 +16,21 @@
>  #include "sysemu/replay.h"
>  #include "qemu/units.h"
>  #include "hw/boards.h"
> +#include "hw/loader.h"
>  #include "qapi/error.h"
>  #include "qapi/qapi-visit-common.h"
>  #include "qapi/visitor.h"
>  #include "hw/sysbus.h"
> +#include "sysemu/cpus.h"
>  #include "sysemu/sysemu.h"
> +#include "sysemu/reset.h"
> +#include "sysemu/runstate.h"
>  #include "sysemu/numa.h"
>  #include "qemu/error-report.h"
>  #include "sysemu/qtest.h"
>  #include "hw/pci/pci.h"
>  #include "hw/mem/nvdimm.h"
> +#include "migration/global_state.h"
>  #include "migration/vmstate.h"
>  
>  GlobalProperty hw_compat_5_1[] = {
> @@ -1186,10 +1191,50 @@ void qemu_remove_machine_init_done_notifier(Notifier *notify)
>      notifier_remove(notify);
>  }
>  
> -void qemu_run_machine_init_done_notifiers(void)
> +void qdev_machine_creation_done(void)
>  {
> +    cpu_synchronize_all_post_init();
> +
> +    if (current_machine->boot_once) {
> +        qemu_boot_set(current_machine->boot_once, &error_fatal);
> +        qemu_register_reset(restore_boot_order, g_strdup(current_machine->boot_order));
> +    }
> +
> +    /*
> +     * ok, initial machine setup is done, starting from now we can
> +     * only create hotpluggable devices
> +     */
> +    qdev_hotplug = true;
> +    qdev_assert_realized_properly();
> +
> +    /* TODO: once all bus devices are qdevified, this should be done
> +     * when bus is created by qdev.c */
> +    /*
> +     * TODO: If we had a main 'reset container' that the whole system
> +     * lived in, we could reset that using the multi-phase reset
> +     * APIs. For the moment, we just reset the sysbus, which will cause
> +     * all devices hanging off it (and all their child buses, recursively)
> +     * to be reset. Note that this will *not* reset any Device objects
> +     * which are not attached to some part of the qbus tree!
> +     */
> +    qemu_register_reset(resettable_cold_reset_fn, sysbus_get_default());
> +
>      machine_init_done = true;
>      notifier_list_notify(&machine_init_done_notifiers, NULL);
> +
> +    if (rom_check_and_register_reset() != 0) {
> +        error_report("rom check and register reset failed");
> +        exit(1);
> +    }
> +
> +    replay_start();
> +
> +    /* This checkpoint is required by replay to separate prior clock
> +       reading from the other reads, because timer polling functions query
> +       clock values from the log. */
> +    replay_checkpoint(CHECKPOINT_RESET);
> +    qemu_system_reset(SHUTDOWN_CAUSE_NONE);
> +    register_global_state();
>  }
>  
>  static const TypeInfo machine_info = {
> diff --git a/hw/core/qdev.c b/hw/core/qdev.c
> index 262bca716f..bc5df8ce69 100644
> --- a/hw/core/qdev.c
> +++ b/hw/core/qdev.c
> @@ -413,7 +413,7 @@ void qdev_unrealize(DeviceState *dev)
>      object_property_set_bool(OBJECT(dev), "realized", false, &error_abort);
>  }
>  
> -static int qdev_assert_realized_properly(Object *obj, void *opaque)
> +static int qdev_assert_realized_properly_cb(Object *obj, void *opaque)
>  {
>      DeviceState *dev = DEVICE(object_dynamic_cast(obj, TYPE_DEVICE));
>      DeviceClass *dc;
> @@ -426,16 +426,10 @@ static int qdev_assert_realized_properly(Object *obj, void *opaque)
>      return 0;
>  }
>  
> -void qdev_machine_creation_done(void)
> +void qdev_assert_realized_properly(void)
>  {
> -    /*
> -     * ok, initial machine setup is done, starting from now we can
> -     * only create hotpluggable devices
> -     */
> -    qdev_hotplug = true;
> -
>      object_child_foreach_recursive(object_get_root(),
> -                                   qdev_assert_realized_properly, NULL);
> +                                   qdev_assert_realized_properly_cb, NULL);
>  }
>  
>  bool qdev_machine_modified(void)
> diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> index b77a2f1da7..6446846752 100644
> --- a/include/hw/qdev-core.h
> +++ b/include/hw/qdev-core.h
> @@ -815,6 +815,7 @@ const VMStateDescription *qdev_get_vmsd(DeviceState *dev);
>  
>  const char *qdev_fw_name(DeviceState *dev);
>  
> +void qdev_assert_realized_properly(void);
>  Object *qdev_get_machine(void);
>  
>  /* FIXME: make this a link<> */
> diff --git a/softmmu/vl.c b/softmmu/vl.c
> index 685d92df5d..d8af26c281 100644
> --- a/softmmu/vl.c
> +++ b/softmmu/vl.c
> @@ -72,7 +72,6 @@
>  #include "hw/i386/pc.h"
>  #include "migration/misc.h"
>  #include "migration/snapshot.h"
> -#include "migration/global_state.h"
>  #include "sysemu/tpm.h"
>  #include "sysemu/dma.h"
>  #include "hw/audio/soundhw.h"
> @@ -2465,8 +2464,6 @@ static void qemu_create_cli_devices(void)
>  
>  static void qemu_machine_creation_done(void)
>  {
> -    cpu_synchronize_all_post_init();
> -
>      /* Did we create any drives that we failed to create a device for? */
>      drive_check_orphaned();
>  
> @@ -2484,43 +2481,11 @@ static void qemu_machine_creation_done(void)
>  
>      qdev_prop_check_globals();
>  
> -    if (current_machine->boot_once) {
> -        qemu_boot_set(current_machine->boot_once, &error_fatal);
> -        qemu_register_reset(restore_boot_order, g_strdup(current_machine->boot_order));
> -    }
> -
> -    if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
> -        exit(1);
> -    }
> -
>      qdev_machine_creation_done();
>  
> -    /* TODO: once all bus devices are qdevified, this should be done
> -     * when bus is created by qdev.c */
> -    /*
> -     * TODO: If we had a main 'reset container' that the whole system
> -     * lived in, we could reset that using the multi-phase reset
> -     * APIs. For the moment, we just reset the sysbus, which will cause
> -     * all devices hanging off it (and all their child buses, recursively)
> -     * to be reset. Note that this will *not* reset any Device objects
> -     * which are not attached to some part of the qbus tree!
> -     */
> -    qemu_register_reset(resettable_cold_reset_fn, sysbus_get_default());
> -    qemu_run_machine_init_done_notifiers();
> -
> -    if (rom_check_and_register_reset() != 0) {
> -        error_report("rom check and register reset failed");
> +    if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
>          exit(1);
>      }
> -
> -    replay_start();
> -
> -    /* This checkpoint is required by replay to separate prior clock
> -       reading from the other reads, because timer polling functions query
> -       clock values from the log. */
> -    replay_checkpoint(CHECKPOINT_RESET);
> -    qemu_system_reset(SHUTDOWN_CAUSE_NONE);
> -    register_global_state();
>  }
>  
>  void qmp_x_exit_preconfig(Error **errp)



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

* Re: [PATCH 01/15] remove preconfig state
  2020-12-07 14:11     ` Paolo Bonzini
@ 2020-12-07 15:14       ` Igor Mammedov
  0 siblings, 0 replies; 50+ messages in thread
From: Igor Mammedov @ 2020-12-07 15:14 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On Mon, 7 Dec 2020 15:11:34 +0100
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il lun 7 dic 2020, 14:57 Igor Mammedov <imammedo@redhat.com> ha scritto:
> 
> > On Wed,  2 Dec 2020 03:18:40 -0500
> > Paolo Bonzini <pbonzini@redhat.com> wrote:
> >  
> > > The preconfig state is only used if -incoming is not specified, which
> > > makes the RunState state machine more tricky than it need be.  However
> > > there is already an equivalent condition which works even with -incoming,
> > > namely qdev_hotplug.  Use it instead of a separate runstate.
> > >
> > > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> > > ---
> > >  hw/core/machine-qmp-cmds.c    |  5 ++---
> > >  include/qapi/qmp/dispatch.h   |  1 +
> > >  monitor/hmp.c                 |  7 ++++---
> > >  monitor/qmp-cmds.c            |  5 ++---
> > >  qapi/qmp-dispatch.c           |  5 +----
> > >  qapi/run-state.json           |  5 +----
> > >  softmmu/qdev-monitor.c        | 12 ++++++++++++
> > >  softmmu/vl.c                  | 13 ++-----------
> > >  stubs/meson.build             |  1 +
> > >  stubs/qmp-command-available.c |  7 +++++++
> > >  tests/qtest/qmp-test.c        |  2 +-
> > >  11 files changed, 34 insertions(+), 29 deletions(-)
> > >  create mode 100644 stubs/qmp-command-available.c
> > >
> > > diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
> > > index 5362c80a18..cb9387c5f5 100644
> > > --- a/hw/core/machine-qmp-cmds.c
> > > +++ b/hw/core/machine-qmp-cmds.c
> > > @@ -286,9 +286,8 @@ HotpluggableCPUList  
> > *qmp_query_hotpluggable_cpus(Error **errp)  
> > >
> > >  void qmp_set_numa_node(NumaOptions *cmd, Error **errp)
> > >  {
> > > -    if (!runstate_check(RUN_STATE_PRECONFIG)) {
> > > -        error_setg(errp, "The command is permitted only in '%s' state",
> > > -                   RunState_str(RUN_STATE_PRECONFIG));
> > > +    if (qdev_hotplug) {  
> > it's too late for qmp_set_numa_node(), but given it's temporary
> > and patch 8/15 changes it to correct state it should be fine.
> > so
> >
> >   Reviewed-by: Igor Mammedov <imammedo@redhat.com>
> >  
> 
> It's too late according to the fine grained distinction of phases that will
> be introduced later. For the two phases that are possible with current QEMU
> (before or after preconfig) it should be indistinguishable, right?
yep, it doesn't break anything and 8/15 makes sure that command ends up at
correct phase.

> 
> Paolo
> 
> 
> >  
> > > +         error_setg(errp, "The command is permitted only before the  
> > machine has been created");  
> > >           return;
> > >      }
> > >
> > > diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
> > > index af8d96c570..1486cac3ef 100644
> > > --- a/include/qapi/qmp/dispatch.h
> > > +++ b/include/qapi/qmp/dispatch.h
> > > @@ -48,6 +48,7 @@ void qmp_disable_command(QmpCommandList *cmds, const  
> > char *name);  
> > >  void qmp_enable_command(QmpCommandList *cmds, const char *name);
> > >
> > >  bool qmp_command_is_enabled(const QmpCommand *cmd);
> > > +bool qmp_command_available(const QmpCommand *cmd, Error **errp);
> > >  const char *qmp_command_name(const QmpCommand *cmd);
> > >  bool qmp_has_success_response(const QmpCommand *cmd);
> > >  QDict *qmp_error_response(Error *err);
> > > diff --git a/monitor/hmp.c b/monitor/hmp.c
> > > index d40f4f4391..f2fe192d69 100644
> > > --- a/monitor/hmp.c
> > > +++ b/monitor/hmp.c
> > > @@ -24,6 +24,7 @@
> > >
> > >  #include "qemu/osdep.h"
> > >  #include <dirent.h>
> > > +#include "hw/qdev-core.h"
> > >  #include "monitor-internal.h"
> > >  #include "qapi/error.h"
> > >  #include "qapi/qmp/qdict.h"
> > > @@ -215,7 +216,7 @@ static bool cmd_can_preconfig(const HMPCommand *cmd)
> > >
> > >  static bool cmd_available(const HMPCommand *cmd)
> > >  {
> > > -    return !runstate_check(RUN_STATE_PRECONFIG) ||  
> > cmd_can_preconfig(cmd);  
> > > +    return qdev_hotplug || cmd_can_preconfig(cmd);
> > >  }
> > >
> > >  static void help_cmd_dump_one(Monitor *mon,
> > > @@ -658,8 +659,8 @@ static const HMPCommand  
> > *monitor_parse_command(MonitorHMP *hmp_mon,  
> > >          return NULL;
> > >      }
> > >      if (!cmd_available(cmd)) {
> > > -        monitor_printf(mon, "Command '%.*s' not available with  
> > -preconfig "  
> > > -                            "until after exit_preconfig.\n",
> > > +        monitor_printf(mon, "Command '%.*s' not available "
> > > +                            "until machine initialization has  
> > completed.\n",  
> > >                         (int)(p - cmdp_start), cmdp_start);
> > >          return NULL;
> > >      }
> > > diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
> > > index 6299c0c8c7..501a3024c7 100644
> > > --- a/monitor/qmp-cmds.c
> > > +++ b/monitor/qmp-cmds.c
> > > @@ -104,9 +104,8 @@ void qmp_system_powerdown(Error **errp)
> > >
> > >  void qmp_x_exit_preconfig(Error **errp)
> > >  {
> > > -    if (!runstate_check(RUN_STATE_PRECONFIG)) {
> > > -        error_setg(errp, "The command is permitted only in '%s' state",
> > > -                   RunState_str(RUN_STATE_PRECONFIG));
> > > +    if (qdev_hotplug) {
> > > +        error_setg(errp, "The command is permitted only before machine  
> > initialization");  
> > >          return;
> > >      }
> > >      qemu_exit_preconfig_request();
> > > diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
> > > index 9a2d7dd29a..0a2b20a4e4 100644
> > > --- a/qapi/qmp-dispatch.c
> > > +++ b/qapi/qmp-dispatch.c
> > > @@ -167,10 +167,7 @@ QDict *qmp_dispatch(const QmpCommandList *cmds,  
> > QObject *request,  
> > >          goto out;
> > >      }
> > >
> > > -    if (runstate_check(RUN_STATE_PRECONFIG) &&
> > > -        !(cmd->options & QCO_ALLOW_PRECONFIG)) {
> > > -        error_setg(&err, "The command '%s' isn't permitted in '%s'  
> > state",  
> > > -                   cmd->name, RunState_str(RUN_STATE_PRECONFIG));
> > > +    if (!qmp_command_available(cmd, &err)) {
> > >          goto out;
> > >      }
> > >
> > > diff --git a/qapi/run-state.json b/qapi/run-state.json
> > > index 964c8ef391..38194b0e44 100644
> > > --- a/qapi/run-state.json
> > > +++ b/qapi/run-state.json
> > > @@ -50,15 +50,12 @@
> > >  # @colo: guest is paused to save/restore VM state under colo checkpoint,
> > >  #        VM can not get into this state unless colo capability is  
> > enabled  
> > >  #        for migration. (since 2.8)
> > > -# @preconfig: QEMU is paused before board specific init callback is  
> > executed.  
> > > -#             The state is reachable only if the --preconfig CLI option  
> > is used.  
> > > -#             (Since 3.0)
> > >  ##
> > >  { 'enum': 'RunState',
> > >    'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error',  
> > 'paused',  
> > >              'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm',
> > >              'running', 'save-vm', 'shutdown', 'suspended', 'watchdog',
> > > -            'guest-panicked', 'colo', 'preconfig' ] }
> > > +            'guest-panicked', 'colo' ] }
> > >
> > >  ##
> > >  # @ShutdownCause:
> > > diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
> > > index d060e765da..e967d13bd0 100644
> > > --- a/softmmu/qdev-monitor.c
> > > +++ b/softmmu/qdev-monitor.c
> > > @@ -25,6 +25,7 @@
> > >  #include "sysemu/arch_init.h"
> > >  #include "qapi/error.h"
> > >  #include "qapi/qapi-commands-qdev.h"
> > > +#include "qapi/qmp/dispatch.h"
> > >  #include "qapi/qmp/qdict.h"
> > >  #include "qapi/qmp/qerror.h"
> > >  #include "qemu/config-file.h"
> > > @@ -997,3 +998,14 @@ int qemu_global_option(const char *str)
> > >
> > >      return 0;
> > >  }
> > > +
> > > +bool qmp_command_available(const QmpCommand *cmd, Error **errp)
> > > +{
> > > +    if (!qdev_hotplug &&
> > > +        !(cmd->options & QCO_ALLOW_PRECONFIG)) {
> > > +        error_setg(errp, "The command '%s' is permitted only after  
> > machine initialization has completed",  
> > > +                   cmd->name);
> > > +        return false;
> > > +    }
> > > +    return true;
> > > +}
> > > diff --git a/softmmu/vl.c b/softmmu/vl.c
> > > index 7146fbe219..ab2210bc79 100644
> > > --- a/softmmu/vl.c
> > > +++ b/softmmu/vl.c
> > > @@ -557,7 +557,7 @@ static int default_driver_check(void *opaque,  
> > QemuOpts *opts, Error **errp)  
> > >  /***********************************************************/
> > >  /* QEMU state */
> > >
> > > -static RunState current_run_state = RUN_STATE_PRECONFIG;
> > > +static RunState current_run_state = RUN_STATE_PRELAUNCH;
> > >
> > >  /* We use RUN_STATE__MAX but any invalid value will do */
> > >  static RunState vmstop_requested = RUN_STATE__MAX;
> > > @@ -569,13 +569,7 @@ typedef struct {
> > >  } RunStateTransition;
> > >
> > >  static const RunStateTransition runstate_transitions_def[] = {
> > > -    /*     from      ->     to      */
> > > -    { RUN_STATE_PRECONFIG, RUN_STATE_PRELAUNCH },
> > > -      /* Early switch to inmigrate state to allow  -incoming CLI option  
> > work  
> > > -       * as it used to. TODO: delay actual switching to inmigrate state  
> > to  
> > > -       * the point after machine is built and remove this hack.
> > > -       */
> > > -    { RUN_STATE_PRECONFIG, RUN_STATE_INMIGRATE },
> > > +    { RUN_STATE_PRELAUNCH, RUN_STATE_INMIGRATE },
> > >
> > >      { RUN_STATE_DEBUG, RUN_STATE_RUNNING },
> > >      { RUN_STATE_DEBUG, RUN_STATE_FINISH_MIGRATE },
> > > @@ -1471,9 +1465,6 @@ static bool main_loop_should_exit(void)
> > >      ShutdownCause request;
> > >
> > >      if (preconfig_exit_requested) {
> > > -        if (runstate_check(RUN_STATE_PRECONFIG)) {
> > > -            runstate_set(RUN_STATE_PRELAUNCH);
> > > -        }
> > >          preconfig_exit_requested = false;
> > >          return true;
> > >      }
> > > diff --git a/stubs/meson.build b/stubs/meson.build
> > > index 82b7ba60ab..cc56c83063 100644
> > > --- a/stubs/meson.build
> > > +++ b/stubs/meson.build
> > > @@ -29,6 +29,7 @@ stub_ss.add(files('pci-bus.c'))
> > >  stub_ss.add(files('pci-host-piix.c'))
> > >  stub_ss.add(files('qemu-timer-notify-cb.c'))
> > >  stub_ss.add(files('qmp_memory_device.c'))
> > > +stub_ss.add(files('qmp-command-available.c'))
> > >  stub_ss.add(files('qtest.c'))
> > >  stub_ss.add(files('ram-block.c'))
> > >  stub_ss.add(files('ramfb.c'))
> > > diff --git a/stubs/qmp-command-available.c  
> > b/stubs/qmp-command-available.c  
> > > new file mode 100644
> > > index 0000000000..46540af7bf
> > > --- /dev/null
> > > +++ b/stubs/qmp-command-available.c
> > > @@ -0,0 +1,7 @@
> > > +#include "qemu/osdep.h"
> > > +#include "qapi/qmp/dispatch.h"
> > > +
> > > +bool qmp_command_available(const QmpCommand *cmd, Error **errp)
> > > +{
> > > +    return true;
> > > +}
> > > diff --git a/tests/qtest/qmp-test.c b/tests/qtest/qmp-test.c
> > > index eb1cd8abb8..11614bf63f 100644
> > > --- a/tests/qtest/qmp-test.c
> > > +++ b/tests/qtest/qmp-test.c
> > > @@ -295,7 +295,7 @@ static void test_qmp_preconfig(void)
> > >      rsp = qtest_qmp(qs, "{ 'execute': 'query-status' }");
> > >      ret = qdict_get_qdict(rsp, "return");
> > >      g_assert(ret);
> > > -    g_assert_cmpstr(qdict_get_try_str(ret, "status"), ==, "preconfig");
> > > +    g_assert_cmpstr(qdict_get_try_str(ret, "status"), ==, "prelaunch");
> > >      qobject_unref(rsp);
> > >
> > >      /* exit preconfig state */  
> >
> >  



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

* Re: [PATCH 07/15] chardev: do not use machine_init_done
  2020-12-02  8:18 ` [PATCH 07/15] chardev: do not use machine_init_done Paolo Bonzini
@ 2020-12-07 15:15   ` Igor Mammedov
  0 siblings, 0 replies; 50+ messages in thread
From: Igor Mammedov @ 2020-12-07 15:15 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On Wed,  2 Dec 2020 03:18:46 -0500
Paolo Bonzini <pbonzini@redhat.com> wrote:

> machine_init_done is not the right flag to check when preconfig
> is taken into account; for example "./qemu-system-x86_64 -serial
> mon:stdio -preconfig" does not print the QEMU monitor header until after
> exit_preconfig.  Add back a custom bool for mux character devices.  This
> partially undoes commit c7278b4355 ("chardev: introduce chr_machine_done
> hook", 2018-03-12), cut keeps the cleaner logic using a function pointer
                      ^^^
did you mean
s/cut/but/

> in ChardevClass.

Reviewed-by: Igor Mammedov <imammedo@redhat.com>


> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  chardev/char-mux.c        | 38 ++++++++++++++++++---
>  chardev/chardev-sysemu.c  | 69 ---------------------------------------
>  chardev/meson.build       |  2 +-
>  hw/core/machine.c         |  2 +-
>  include/chardev/char.h    |  6 ++--
>  include/sysemu/sysemu.h   |  2 --
>  softmmu/vl.c              |  3 ++
>  stubs/machine-init-done.c |  8 -----
>  stubs/meson.build         |  1 -
>  9 files changed, 43 insertions(+), 88 deletions(-)
>  delete mode 100644 chardev/chardev-sysemu.c
>  delete mode 100644 stubs/machine-init-done.c
> 
> diff --git a/chardev/char-mux.c b/chardev/char-mux.c
> index 6f980bb836..72beef29d2 100644
> --- a/chardev/char-mux.c
> +++ b/chardev/char-mux.c
> @@ -33,6 +33,13 @@
>  
>  /* MUX driver for serial I/O splitting */
>  
> +/*
> + * Set to false by suspend_mux_open.  Open events are delayed until
> + * resume_mux_open.  Usually suspend_mux_open is called before
> + * command line processing and resume_mux_open afterwards.
> + */
> +static bool muxes_opened = true;
> +
>  /* Called with chr_write_lock held.  */
>  static int mux_chr_write(Chardev *chr, const uint8_t *buf, int len)
>  {
> @@ -237,7 +244,7 @@ void mux_chr_send_all_event(Chardev *chr, QEMUChrEvent event)
>      MuxChardev *d = MUX_CHARDEV(chr);
>      int i;
>  
> -    if (!machine_init_done) {
> +    if (!muxes_opened) {
>          return;
>      }
>  
> @@ -328,7 +335,7 @@ static void qemu_chr_open_mux(Chardev *chr,
>      /* only default to opened state if we've realized the initial
>       * set of muxes
>       */
> -    *be_opened = machine_init_done;
> +    *be_opened = muxes_opened;
>      qemu_chr_fe_init(&d->chr, drv, errp);
>  }
>  
> @@ -360,19 +367,42 @@ static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend *backend,
>   * mux will receive CHR_EVENT_OPENED notifications for the BE
>   * immediately.
>   */
> -static int open_muxes(Chardev *chr)
> +static void open_muxes(Chardev *chr)
>  {
>      /* send OPENED to all already-attached FEs */
>      mux_chr_send_all_event(chr, CHR_EVENT_OPENED);
> +
>      /*
>       * mark mux as OPENED so any new FEs will immediately receive
>       * OPENED event
>       */
>      chr->be_open = 1;
> +}
> +
> +void suspend_mux_open(void)
> +{
> +    muxes_opened = false;
> +}
> +
> +static int chardev_options_parsed_cb(Object *child, void *opaque)
> +{
> +    Chardev *chr = (Chardev *)child;
> +    ChardevClass *class = CHARDEV_GET_CLASS(chr);
> +
> +    if (!chr->be_open && class->chr_options_parsed) {
> +        class->chr_options_parsed(chr);
> +    }
>  
>      return 0;
>  }
>  
> +void resume_mux_open(void)
> +{
> +    muxes_opened = true;
> +    object_child_foreach(get_chardevs_root(),
> +                         chardev_options_parsed_cb, NULL);
> +}
> +
>  static void char_mux_class_init(ObjectClass *oc, void *data)
>  {
>      ChardevClass *cc = CHARDEV_CLASS(oc);
> @@ -383,7 +413,7 @@ static void char_mux_class_init(ObjectClass *oc, void *data)
>      cc->chr_accept_input = mux_chr_accept_input;
>      cc->chr_add_watch = mux_chr_add_watch;
>      cc->chr_be_event = mux_chr_be_event;
> -    cc->chr_machine_done = open_muxes;
> +    cc->chr_options_parsed = open_muxes;
>      cc->chr_update_read_handler = mux_chr_update_read_handlers;
>  }
>  
> diff --git a/chardev/chardev-sysemu.c b/chardev/chardev-sysemu.c
> deleted file mode 100644
> index eecdc615ee..0000000000
> --- a/chardev/chardev-sysemu.c
> +++ /dev/null
> @@ -1,69 +0,0 @@
> -/*
> - * QEMU System Emulator
> - *
> - * Copyright (c) 2003-2008 Fabrice Bellard
> - *
> - * Permission is hereby granted, free of charge, to any person obtaining a copy
> - * of this software and associated documentation files (the "Software"), to deal
> - * in the Software without restriction, including without limitation the rights
> - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> - * copies of the Software, and to permit persons to whom the Software is
> - * furnished to do so, subject to the following conditions:
> - *
> - * The above copyright notice and this permission notice shall be included in
> - * all copies or substantial portions of the Software.
> - *
> - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> - * THE SOFTWARE.
> - */
> -
> -#include "qemu/osdep.h"
> -#include "sysemu/sysemu.h"
> -#include "chardev/char.h"
> -#include "qemu/error-report.h"
> -#include "chardev-internal.h"
> -
> -static int chardev_machine_done_notify_one(Object *child, void *opaque)
> -{
> -    Chardev *chr = (Chardev *)child;
> -    ChardevClass *class = CHARDEV_GET_CLASS(chr);
> -
> -    if (class->chr_machine_done) {
> -        return class->chr_machine_done(chr);
> -    }
> -
> -    return 0;
> -}
> -
> -static void chardev_machine_done_hook(Notifier *notifier, void *unused)
> -{
> -    int ret = object_child_foreach(get_chardevs_root(),
> -                                   chardev_machine_done_notify_one, NULL);
> -
> -    if (ret) {
> -        error_report("Failed to call chardev machine_done hooks");
> -        exit(1);
> -    }
> -}
> -
> -
> -static Notifier chardev_machine_done_notify = {
> -    .notify = chardev_machine_done_hook,
> -};
> -
> -static void register_types(void)
> -{
> -    /*
> -     * This must be done after machine init, since we register FEs with muxes
> -     * as part of realize functions like serial_isa_realizefn when -nographic
> -     * is specified.
> -     */
> -    qemu_add_machine_init_done_notifier(&chardev_machine_done_notify);
> -}
> -
> -type_init(register_types);
> diff --git a/chardev/meson.build b/chardev/meson.build
> index 859d8b04d4..4e19722c5e 100644
> --- a/chardev/meson.build
> +++ b/chardev/meson.build
> @@ -25,7 +25,7 @@ chardev_ss.add(when: 'CONFIG_WIN32', if_true: files(
>  
>  chardev_ss = chardev_ss.apply(config_host, strict: false)
>  
> -softmmu_ss.add(files('chardev-sysemu.c', 'msmouse.c', 'wctablet.c', 'testdev.c'))
> +softmmu_ss.add(files('msmouse.c', 'wctablet.c', 'testdev.c'))
>  
>  chardev_modules = {}
>  
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 025c4f9749..40876ddd8e 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -1176,7 +1176,7 @@ void machine_run_board_init(MachineState *machine)
>  static NotifierList machine_init_done_notifiers =
>      NOTIFIER_LIST_INITIALIZER(machine_init_done_notifiers);
>  
> -bool machine_init_done;
> +static bool machine_init_done;
>  
>  void qemu_add_machine_init_done_notifier(Notifier *notify)
>  {
> diff --git a/include/chardev/char.h b/include/chardev/char.h
> index db42f0a8c6..4181a2784a 100644
> --- a/include/chardev/char.h
> +++ b/include/chardev/char.h
> @@ -270,8 +270,7 @@ struct ChardevClass {
>      void (*chr_set_echo)(Chardev *chr, bool echo);
>      void (*chr_set_fe_open)(Chardev *chr, int fe_open);
>      void (*chr_be_event)(Chardev *s, QEMUChrEvent event);
> -    /* Return 0 if succeeded, 1 if failed */
> -    int (*chr_machine_done)(Chardev *chr);
> +    void (*chr_options_parsed)(Chardev *chr);
>  };
>  
>  Chardev *qemu_chardev_new(const char *id, const char *typename,
> @@ -283,6 +282,9 @@ extern int term_escape_char;
>  GSource *qemu_chr_timeout_add_ms(Chardev *chr, guint ms,
>                                   GSourceFunc func, void *private);
>  
> +void suspend_mux_open(void);
> +void resume_mux_open(void);
> +
>  /* console.c */
>  void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend, Error **errp);
>  
> diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
> index 0e7b405d22..9b47cdca55 100644
> --- a/include/sysemu/sysemu.h
> +++ b/include/sysemu/sysemu.h
> @@ -16,8 +16,6 @@ extern bool qemu_uuid_set;
>  void qemu_add_exit_notifier(Notifier *notify);
>  void qemu_remove_exit_notifier(Notifier *notify);
>  
> -extern bool machine_init_done;
> -
>  void qemu_run_machine_init_done_notifiers(void);
>  void qemu_add_machine_init_done_notifier(Notifier *notify);
>  void qemu_remove_machine_init_done_notifier(Notifier *notify);
> diff --git a/softmmu/vl.c b/softmmu/vl.c
> index d8af26c281..8e18c52f6e 100644
> --- a/softmmu/vl.c
> +++ b/softmmu/vl.c
> @@ -3462,6 +3462,8 @@ void qemu_init(int argc, char **argv, char **envp)
>  
>      qemu_create_machine(select_machine());
>  
> +    suspend_mux_open();
> +
>      qemu_disable_default_devices();
>      qemu_create_default_devices();
>      qemu_create_early_backends();
> @@ -3525,4 +3527,5 @@ void qemu_init(int argc, char **argv, char **envp)
>      }
>      accel_setup_post(current_machine);
>      os_setup_post();
> +    resume_mux_open();
>  }
> diff --git a/stubs/machine-init-done.c b/stubs/machine-init-done.c
> deleted file mode 100644
> index cd8e81392d..0000000000
> --- a/stubs/machine-init-done.c
> +++ /dev/null
> @@ -1,8 +0,0 @@
> -#include "qemu/osdep.h"
> -#include "sysemu/sysemu.h"
> -
> -bool machine_init_done = true;
> -
> -void qemu_add_machine_init_done_notifier(Notifier *notify)
> -{
> -}
> diff --git a/stubs/meson.build b/stubs/meson.build
> index cc56c83063..80b1d81a31 100644
> --- a/stubs/meson.build
> +++ b/stubs/meson.build
> @@ -21,7 +21,6 @@ stub_ss.add(files('iothread-lock.c'))
>  stub_ss.add(files('isa-bus.c'))
>  stub_ss.add(files('is-daemonized.c'))
>  stub_ss.add(when: 'CONFIG_LINUX_AIO', if_true: files('linux-aio.c'))
> -stub_ss.add(files('machine-init-done.c'))
>  stub_ss.add(files('migr-blocker.c'))
>  stub_ss.add(files('monitor.c'))
>  stub_ss.add(files('monitor-core.c'))



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

* Re: [PATCH 08/15] machine: introduce MachineInitPhase
  2020-12-02  8:18 ` [PATCH 08/15] machine: introduce MachineInitPhase Paolo Bonzini
@ 2020-12-07 15:28   ` Igor Mammedov
  0 siblings, 0 replies; 50+ messages in thread
From: Igor Mammedov @ 2020-12-07 15:28 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On Wed,  2 Dec 2020 03:18:47 -0500
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Generalize the qdev_hotplug variable to the different phases of
> machine initialization.  We would like to allow different
> monitor commands depending on the phase.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Reviewed-by: Igor Mammedov <imammedo@redhat.com>

> ---
>  hw/core/machine-qmp-cmds.c |  6 +++---
>  hw/core/machine.c          |  8 +++-----
>  hw/core/qdev.c             | 16 ++++++++++++++--
>  hw/pci/pci.c               |  2 +-
>  hw/usb/core.c              |  2 +-
>  hw/virtio/virtio-iommu.c   |  2 +-
>  include/hw/qdev-core.h     | 32 +++++++++++++++++++++++++++++++-
>  monitor/hmp.c              |  2 +-
>  softmmu/qdev-monitor.c     | 24 +++++++++++++-----------
>  softmmu/vl.c               |  9 ++++-----
>  ui/console.c               |  2 +-
>  11 files changed, 73 insertions(+), 32 deletions(-)
> 
> diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
> index cb9387c5f5..87f14140a3 100644
> --- a/hw/core/machine-qmp-cmds.c
> +++ b/hw/core/machine-qmp-cmds.c
> @@ -286,9 +286,9 @@ HotpluggableCPUList *qmp_query_hotpluggable_cpus(Error **errp)
>  
>  void qmp_set_numa_node(NumaOptions *cmd, Error **errp)
>  {
> -    if (qdev_hotplug) {
> -         error_setg(errp, "The command is permitted only before the machine has been created");
> -         return;
> +    if (phase_check(PHASE_MACHINE_INITIALIZED)) {
> +        error_setg(errp, "The command is permitted only before the machine has been created");
> +        return;
>      }
>  
>      set_numa_options(MACHINE(qdev_get_machine()), cmd, errp);
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 40876ddd8e..2c0bc15143 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -1171,17 +1171,16 @@ void machine_run_board_init(MachineState *machine)
>      }
>  
>      machine_class->init(machine);
> +    phase_advance(PHASE_MACHINE_INITIALIZED);
>  }
>  
>  static NotifierList machine_init_done_notifiers =
>      NOTIFIER_LIST_INITIALIZER(machine_init_done_notifiers);
>  
> -static bool machine_init_done;
> -
>  void qemu_add_machine_init_done_notifier(Notifier *notify)
>  {
>      notifier_list_add(&machine_init_done_notifiers, notify);
> -    if (machine_init_done) {
> +    if (phase_check(PHASE_MACHINE_READY)) {
>          notify->notify(notify, NULL);
>      }
>  }
> @@ -1204,7 +1203,7 @@ void qdev_machine_creation_done(void)
>       * ok, initial machine setup is done, starting from now we can
>       * only create hotpluggable devices
>       */
> -    qdev_hotplug = true;
> +    phase_advance(PHASE_MACHINE_READY);
>      qdev_assert_realized_properly();
>  
>      /* TODO: once all bus devices are qdevified, this should be done
> @@ -1219,7 +1218,6 @@ void qdev_machine_creation_done(void)
>       */
>      qemu_register_reset(resettable_cold_reset_fn, sysbus_get_default());
>  
> -    machine_init_done = true;
>      notifier_list_notify(&machine_init_done_notifiers, NULL);
>  
>      if (rom_check_and_register_reset() != 0) {
> diff --git a/hw/core/qdev.c b/hw/core/qdev.c
> index bc5df8ce69..beb35879c6 100644
> --- a/hw/core/qdev.c
> +++ b/hw/core/qdev.c
> @@ -41,7 +41,6 @@
>  #include "migration/vmstate.h"
>  #include "trace.h"
>  
> -bool qdev_hotplug = false;
>  static bool qdev_hot_added = false;
>  bool qdev_hot_removed = false;
>  
> @@ -1023,7 +1022,7 @@ static void device_initfn(Object *obj)
>  {
>      DeviceState *dev = DEVICE(obj);
>  
> -    if (qdev_hotplug) {
> +    if (phase_check(PHASE_MACHINE_READY)) {
>          dev->hotplugged = 1;
>          qdev_hot_added = true;
>      }
> @@ -1267,6 +1266,19 @@ Object *qdev_get_machine(void)
>      return dev;
>  }
>  
> +static MachineInitPhase machine_phase;
> +
> +bool phase_check(MachineInitPhase phase)
> +{
> +    return machine_phase >= phase;
> +}
> +
> +void phase_advance(MachineInitPhase phase)
> +{
> +    assert(machine_phase == phase - 1);
> +    machine_phase = phase;
> +}
> +
>  static const TypeInfo device_type_info = {
>      .name = TYPE_DEVICE,
>      .parent = TYPE_OBJECT,
> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> index 9424231542..d4349ea577 100644
> --- a/hw/pci/pci.c
> +++ b/hw/pci/pci.c
> @@ -1062,7 +1062,7 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev,
>      address_space_init(&pci_dev->bus_master_as,
>                         &pci_dev->bus_master_container_region, pci_dev->name);
>  
> -    if (qdev_hotplug) {
> +    if (phase_check(PHASE_MACHINE_READY)) {
>          pci_init_bus_master(pci_dev);
>      }
>      pci_dev->irq_state = 0;
> diff --git a/hw/usb/core.c b/hw/usb/core.c
> index 5234dcc73f..e960036f4d 100644
> --- a/hw/usb/core.c
> +++ b/hw/usb/core.c
> @@ -97,7 +97,7 @@ void usb_wakeup(USBEndpoint *ep, unsigned int stream)
>      USBDevice *dev = ep->dev;
>      USBBus *bus = usb_bus_from_device(dev);
>  
> -    if (!qdev_hotplug) {
> +    if (!phase_check(PHASE_MACHINE_READY)) {
>          /*
>           * This is machine init cold plug.  No need to wakeup anyone,
>           * all devices will be reset anyway.  And trying to wakeup can
> diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
> index fc5c75d693..8370fd80d7 100644
> --- a/hw/virtio/virtio-iommu.c
> +++ b/hw/virtio/virtio-iommu.c
> @@ -928,7 +928,7 @@ static int virtio_iommu_set_page_size_mask(IOMMUMemoryRegion *mr,
>       * accept it. Having a different masks is possible but the guest will use
>       * sub-optimal block sizes, so warn about it.
>       */
> -    if (qdev_hotplug) {
> +    if (phase_check(PHASE_MACHINE_READY)) {
>          int new_granule = ctz64(new_mask);
>          int cur_granule = ctz64(cur_mask);
>  
> diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> index 6446846752..12612ed682 100644
> --- a/include/hw/qdev-core.h
> +++ b/include/hw/qdev-core.h
> @@ -821,7 +821,6 @@ Object *qdev_get_machine(void);
>  /* FIXME: make this a link<> */
>  bool qdev_set_parent_bus(DeviceState *dev, BusState *bus, Error **errp);
>  
> -extern bool qdev_hotplug;
>  extern bool qdev_hot_removed;
>  
>  char *qdev_get_dev_path(DeviceState *dev);
> @@ -847,4 +846,35 @@ void device_listener_unregister(DeviceListener *listener);
>   */
>  bool qdev_should_hide_device(QemuOpts *opts);
>  
> +typedef enum MachineInitPhase {
> +    /* current_machine is NULL.  */
> +    PHASE_NO_MACHINE,
> +
> +    /* current_machine is not NULL, but current_machine->accel is NULL.  */
> +    PHASE_MACHINE_CREATED,
> +
> +    /*
> +     * current_machine->accel is not NULL, but the machine properties have
> +     * not been validated and machine_class->init has not yet been called.
> +     */
> +    PHASE_ACCEL_CREATED,
> +
> +    /*
> +     * machine_class->init has been called, thus creating any embedded
> +     * devices and validating machine properties.  Devices created at
> +     * this time are considered to be cold-plugged.
> +     */
> +    PHASE_MACHINE_INITIALIZED,
> +
> +    /*
> +     * QEMU is ready to start CPUs and devices created at this time
> +     * are considered to be hot-plugged.  The monitor is not restricted
> +     * to "preconfig" commands.
> +     */
> +    PHASE_MACHINE_READY,
> +} MachineInitPhase;
> +
> +extern bool phase_check(MachineInitPhase phase);
> +extern void phase_advance(MachineInitPhase phase);
> +
>  #endif
> diff --git a/monitor/hmp.c b/monitor/hmp.c
> index f2fe192d69..6c0b33a0b1 100644
> --- a/monitor/hmp.c
> +++ b/monitor/hmp.c
> @@ -216,7 +216,7 @@ static bool cmd_can_preconfig(const HMPCommand *cmd)
>  
>  static bool cmd_available(const HMPCommand *cmd)
>  {
> -    return qdev_hotplug || cmd_can_preconfig(cmd);
> +    return phase_check(PHASE_MACHINE_READY) || cmd_can_preconfig(cmd);
>  }
>  
>  static void help_cmd_dump_one(Monitor *mon,
> diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
> index e967d13bd0..184fe317af 100644
> --- a/softmmu/qdev-monitor.c
> +++ b/softmmu/qdev-monitor.c
> @@ -244,7 +244,7 @@ static DeviceClass *qdev_get_device_class(const char **driver, Error **errp)
>  
>      dc = DEVICE_CLASS(oc);
>      if (!dc->user_creatable ||
> -        (qdev_hotplug && !dc->hotpluggable)) {
> +        (phase_check(PHASE_MACHINE_READY) && !dc->hotpluggable)) {
>          error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "driver",
>                     "pluggable device type");
>          return NULL;
> @@ -637,7 +637,7 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
>      }
>      hide = should_hide_device(opts);
>  
> -    if ((hide || qdev_hotplug) && bus && !qbus_is_hotpluggable(bus)) {
> +    if ((hide || phase_check(PHASE_MACHINE_READY)) && bus && !qbus_is_hotpluggable(bus)) {
>          error_setg(errp, QERR_BUS_NO_HOTPLUG, bus->name);
>          return NULL;
>      }
> @@ -655,15 +655,17 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
>      dev = qdev_new(driver);
>  
>      /* Check whether the hotplug is allowed by the machine */
> -    if (qdev_hotplug && !qdev_hotplug_allowed(dev, errp)) {
> -        goto err_del_dev;
> -    }
> +    if (phase_check(PHASE_MACHINE_READY)) {
> +        if (!qdev_hotplug_allowed(dev, errp)) {
> +            goto err_del_dev;
> +        }
>  
> -    if (!bus && qdev_hotplug && !qdev_get_machine_hotplug_handler(dev)) {
> -        /* No bus, no machine hotplug handler --> device is not hotpluggable */
> -        error_setg(errp, "Device '%s' can not be hotplugged on this machine",
> -                   driver);
> -        goto err_del_dev;
> +        if (!bus && !qdev_get_machine_hotplug_handler(dev)) {
> +            /* No bus, no machine hotplug handler --> device is not hotpluggable */
> +            error_setg(errp, "Device '%s' can not be hotplugged on this machine",
> +                       driver);
> +            goto err_del_dev;
> +        }
>      }
>  
>      qdev_set_id(dev, qemu_opts_id(opts));
> @@ -1001,7 +1003,7 @@ int qemu_global_option(const char *str)
>  
>  bool qmp_command_available(const QmpCommand *cmd, Error **errp)
>  {
> -    if (!qdev_hotplug &&
> +    if (!phase_check(PHASE_MACHINE_READY) &&
>          !(cmd->options & QCO_ALLOW_PRECONFIG)) {
>          error_setg(errp, "The command '%s' is permitted only after machine initialization has completed",
>                     cmd->name);
> diff --git a/softmmu/vl.c b/softmmu/vl.c
> index 8e18c52f6e..4fece1b9db 100644
> --- a/softmmu/vl.c
> +++ b/softmmu/vl.c
> @@ -2406,10 +2406,6 @@ static void qemu_init_displays(void)
>      }
>  }
>  
> -/*
> - * Called after leaving preconfig state.  From here on runstate is
> - * RUN_STATE_PRELAUNCH or RUN_STATE_INMIGRATE.
> - */
>  static void qemu_init_board(void)
>  {
>      MachineClass *machine_class = MACHINE_GET_CLASS(current_machine);
> @@ -2424,6 +2420,7 @@ static void qemu_init_board(void)
>          exit(1);
>      }
>  
> +    /* From here on we enter MACHINE_PHASE_INITIALIZED.  */
>      machine_run_board_init(current_machine);
>  
>      /*
> @@ -2490,7 +2487,7 @@ static void qemu_machine_creation_done(void)
>  
>  void qmp_x_exit_preconfig(Error **errp)
>  {
> -    if (qdev_hotplug) {
> +    if (phase_check(PHASE_MACHINE_INITIALIZED)) {
>          error_setg(errp, "The command is permitted only before machine initialization");
>          return;
>      }
> @@ -3469,12 +3466,14 @@ void qemu_init(int argc, char **argv, char **envp)
>      qemu_create_early_backends();
>  
>      qemu_apply_machine_options();
> +    phase_advance(PHASE_MACHINE_CREATED);
>  
>      /*
>       * Note: uses machine properties such as kernel-irqchip, must run
>       * after machine_set_property().
>       */
>      configure_accelerators(argv[0]);
> +    phase_advance(PHASE_ACCEL_CREATED);
>  
>      /*
>       * Beware, QOM objects created before this point miss global and
> diff --git a/ui/console.c b/ui/console.c
> index 53dee8e26b..89f625116d 100644
> --- a/ui/console.c
> +++ b/ui/console.c
> @@ -1345,7 +1345,7 @@ static QemuConsole *new_console(DisplayState *ds, console_type_t console_type,
>      if (QTAILQ_EMPTY(&consoles)) {
>          s->index = 0;
>          QTAILQ_INSERT_TAIL(&consoles, s, next);
> -    } else if (console_type != GRAPHIC_CONSOLE || qdev_hotplug) {
> +    } else if (console_type != GRAPHIC_CONSOLE || phase_check(PHASE_MACHINE_READY)) {
>          QemuConsole *last = QTAILQ_LAST(&consoles);
>          s->index = last->index + 1;
>          QTAILQ_INSERT_TAIL(&consoles, s, next);



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

* Re: [PATCH 09/15] machine: record whether nvdimm= was set
  2020-12-02  8:18 ` [PATCH 09/15] machine: record whether nvdimm= was set Paolo Bonzini
@ 2020-12-07 15:40   ` Igor Mammedov
  0 siblings, 0 replies; 50+ messages in thread
From: Igor Mammedov @ 2020-12-07 15:40 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On Wed,  2 Dec 2020 03:18:48 -0500
Paolo Bonzini <pbonzini@redhat.com> wrote:

> This is needed for SPAPR which has different defaults than everyone else.
> Right now it looks at the -machine QemuOpts, but those will go away.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  hw/core/machine.c       | 1 +
>  include/hw/mem/nvdimm.h | 2 +-
>  2 files changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index 2c0bc15143..94992fa1c0 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -455,6 +455,7 @@ static void machine_set_nvdimm(Object *obj, bool value, Error **errp)
>  {
>      MachineState *ms = MACHINE(obj);
>  
> +    ms->nvdimms_state->has_is_enabled = true;
naming looks like QAPI style we use for optional fields, it might be confusing.

maybe something like "user_set_is_enabled" would be better?

(sometimes I wish for QOM properties to have 'set' flag, so we can distinguish
if value is a default one or were set later on)

>      ms->nvdimms_state->is_enabled = value;
>  }
>  
> diff --git a/include/hw/mem/nvdimm.h b/include/hw/mem/nvdimm.h
> index c699842dd0..14c101c180 100644
> --- a/include/hw/mem/nvdimm.h
> +++ b/include/hw/mem/nvdimm.h
> @@ -129,7 +129,7 @@ typedef struct NvdimmFitBuffer NvdimmFitBuffer;
>  
>  struct NVDIMMState {
>      /* detect if NVDIMM support is enabled. */
> -    bool is_enabled;
> +    bool has_is_enabled, is_enabled;
>  
>      /* the data of the fw_cfg file NVDIMM_DSM_MEM_FILE. */
>      GArray *dsm_mem;



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

* Re: [PATCH 10/15] vl: make qemu_get_machine_opts static
  2020-12-02  8:18 ` [PATCH 10/15] vl: make qemu_get_machine_opts static Paolo Bonzini
@ 2020-12-07 16:07   ` Igor Mammedov
  2020-12-07 16:38     ` Paolo Bonzini
  2020-12-08  2:32     ` Daniel Henrique Barboza
  2020-12-08  2:16   ` [PATCH 10/15] vl: make qemu_get_machine_opts static Daniel Henrique Barboza
  1 sibling, 2 replies; 50+ messages in thread
From: Igor Mammedov @ 2020-12-07 16:07 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: danielhb413, qemu-devel, david

On Wed,  2 Dec 2020 03:18:49 -0500
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Machine options can be retrieved as properties of the machine object.
> Encourage that by removing the "easy" accessor to machine options.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  accel/kvm/kvm-all.c     | 11 ++++-------
>  hw/arm/boot.c           |  2 +-
>  hw/microblaze/boot.c    |  9 ++++-----
>  hw/nios2/boot.c         |  9 ++++-----
>  hw/ppc/e500.c           |  5 ++---
>  hw/ppc/spapr_nvdimm.c   |  4 ++--
>  hw/ppc/virtex_ml507.c   |  2 +-
>  hw/riscv/sifive_u.c     |  6 ++----
>  hw/riscv/virt.c         |  6 ++----
>  hw/xtensa/xtfpga.c      |  9 ++++-----
>  include/sysemu/sysemu.h |  2 --
>  softmmu/device_tree.c   |  2 +-
>  softmmu/vl.c            |  2 +-
>  13 files changed, 28 insertions(+), 41 deletions(-)
> 
[...]
> diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
> index a833a63b5e..84715a4d78 100644
> --- a/hw/ppc/spapr_nvdimm.c
> +++ b/hw/ppc/spapr_nvdimm.c
> @@ -38,7 +38,6 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
>  {
>      const MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev);
>      const MachineState *ms = MACHINE(hotplug_dev);
> -    const char *nvdimm_opt = qemu_opt_get(qemu_get_machine_opts(), "nvdimm");
>      g_autofree char *uuidstr = NULL;
>      QemuUUID uuid;
>      int ret;
> @@ -57,10 +56,11 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
>       * ensure that, if the user sets nvdimm=off, we error out
>       * regardless of being 5.1 or newer.
>       */
> -    if (!ms->nvdimms_state->is_enabled && nvdimm_opt) {
> +    if (!ms->nvdimms_state->is_enabled && ms->nvdimms_state->has_is_enabled) {
>          error_setg(errp, "nvdimm device found but 'nvdimm=off' was set");
>          return false;
>      }
> +    ms->nvdimms_state->is_enabled = true;

it looks like nvdimm is always enabled since 5.0 and there is no way to disable it
how about dropping 9/15 and just error out is it's not enabled, something like:

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index b7e0894019..d63f095bff 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2668,6 +2668,7 @@ static void spapr_machine_init(MachineState *machine)
     char *filename;
     Error *resize_hpt_err = NULL;
+    if (mc->nvdimm_supported) { // by default it is always enabled
+        ms->nvdimms_state->is_enabled = true;
+    }
     msi_nonbroken = true;
 
     QLIST_INIT(&spapr->phbs);
diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
index a833a63b5e..b11c85dbaa 100644
--- a/hw/ppc/spapr_nvdimm.c
+++ b/hw/ppc/spapr_nvdimm.c
@@ -57,7 +57,7 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
      * ensure that, if the user sets nvdimm=off, we error out
      * regardless of being 5.1 or newer.
      */
-    if (!ms->nvdimms_state->is_enabled && nvdimm_opt) {
+    if (!ms->nvdimms_state->is_enabled) {
         error_setg(errp, "nvdimm device found but 'nvdimm=off' was set");
         return false;
     }

if I didn't miss something, that way we do not abuse nvdimm_opt and still
have nvdimm enabled by default and error out if it turns to disabled for whatever reason.


>      if (object_property_get_int(OBJECT(nvdimm), NVDIMM_LABEL_SIZE_PROP,
>                                  &error_abort) == 0) {
[...]

 



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

* Re: [PATCH 11/15] qtest: add a QOM object for qtest
  2020-12-02  8:18 ` [PATCH 11/15] qtest: add a QOM object for qtest Paolo Bonzini
@ 2020-12-07 16:24   ` Igor Mammedov
  2020-12-07 16:43     ` Paolo Bonzini
  0 siblings, 1 reply; 50+ messages in thread
From: Igor Mammedov @ 2020-12-07 16:24 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On Wed,  2 Dec 2020 03:18:50 -0500
Paolo Bonzini <pbonzini@redhat.com> wrote:

> The qtest server right now can only be created using the -qtest
> and -qtest-log options.  Allow an alternative way to create it
> using "-object qtest,chardev=...,log=...".
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  softmmu/qtest.c | 144 ++++++++++++++++++++++++++++++++++++++++++++----
>  softmmu/vl.c    |   5 +-
>  2 files changed, 135 insertions(+), 14 deletions(-)
> 
> diff --git a/softmmu/qtest.c b/softmmu/qtest.c
> index 7965dc9a16..d255c9681a 100644
> --- a/softmmu/qtest.c
> +++ b/softmmu/qtest.c
> @@ -27,6 +27,8 @@
>  #include "qemu/error-report.h"
>  #include "qemu/module.h"
>  #include "qemu/cutils.h"
> +#include "qapi/qmp/qerror.h"
> +#include "qom/object_interfaces.h"
>  #include CONFIG_DEVICES
>  #ifdef CONFIG_PSERIES
>  #include "hw/ppc/spapr_rtas.h"
> @@ -849,18 +851,9 @@ static void qtest_event(void *opaque, QEMUChrEvent event)
>          break;
>      }
>  }
> -void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **errp)
> -{
> -    Chardev *chr;
> -
> -    chr = qemu_chr_new("qtest", qtest_chrdev, NULL);
> -
> -    if (chr == NULL) {
> -        error_setg(errp, "Failed to initialize device for qtest: \"%s\"",
> -                   qtest_chrdev);
> -        return;
> -    }
>  
> +static bool qtest_server_start(Chardev *chr, const char *qtest_log, Error **errp)
> +{
>      if (qtest_log) {
>          if (strcmp(qtest_log, "none") != 0) {
>              qtest_log_fp = fopen(qtest_log, "w+");
> @@ -869,7 +862,9 @@ void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **
>          qtest_log_fp = stderr;
>      }
>  
> -    qemu_chr_fe_init(&qtest_chr, chr, errp);
> +    if (!qemu_chr_fe_init(&qtest_chr, chr, errp)) {
> +        return false;
> +    }
>      qemu_chr_fe_set_handlers(&qtest_chr, qtest_can_read, qtest_read,
>                               qtest_event, NULL, &qtest_chr, NULL, true);
>      qemu_chr_fe_set_echo(&qtest_chr, true);
> @@ -879,8 +874,25 @@ void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **
>      if (!qtest_server_send) {
>          qtest_server_set_send_handler(qtest_server_char_be_send, &qtest_chr);
>      }
> +    return true;
> +}
> +
> +void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **errp)
> +{
> +    Chardev *chr;
> +
> +    chr = qemu_chr_new("qtest", qtest_chrdev, NULL);
> +
> +    if (chr == NULL) {
> +        error_setg(errp, "Failed to initialize device for qtest: \"%s\"",
> +                   qtest_chrdev);
> +        return;
> +    }
> +
> +    qtest_server_start(chr, qtest_log, errp);

why not create qtest object here instead of trying to preserve old way,
or create it directly at the place that calls qtest_server_init()?

>  }
>  
> +
>  void qtest_server_set_send_handler(void (*send)(void*, const char*),
>                                     void *opaque)
>  {
> @@ -905,3 +917,111 @@ void qtest_server_inproc_recv(void *dummy, const char *buf)
>          g_string_truncate(gstr, 0);
>      }
>  }
> +
> +#define TYPE_QTEST "qtest"
> +
> +OBJECT_DECLARE_SIMPLE_TYPE(QTest, QTEST)
> +
> +struct QTest {
> +    Object parent;
> +
> +    bool complete;
> +    char *chr_name;
> +    Chardev *chr;
> +    char *log;
> +};
> +
> +static void qtest_complete(UserCreatable *uc, Error **errp)
> +{
> +    QTest *q = QTEST(uc);
> +    if (qtest_driver()) {
> +        error_setg(errp, "Only one instance of qtest can be created");
> +        return;
> +    }
> +    if (!q->chr_name) {
> +        error_setg(errp, "No backend specified");
> +        return;
> +    }
> +
> +    if (!qtest_server_start(q->chr, q->log, errp)) {
> +        return;
> +    }
> +    q->complete = true;
> +}
> +
> +static void qtest_set_log(Object *obj, const char *value, Error **errp)
> +{
> +    QTest *q = QTEST(obj);
> +
> +    if (q->complete) {
> +        error_setg(errp, QERR_PERMISSION_DENIED);
> +    } else {
> +        g_free(q->log);
> +        q->log = g_strdup(value);
> +    }
> +}
> +
> +static char *qtest_get_log(Object *obj, Error **errp)
> +{
> +    QTest *q = QTEST(obj);
> +
> +    return g_strdup(q->log);
> +}
> +
> +static void qtest_set_chardev(Object *obj, const char *value, Error **errp)
> +{
> +    QTest *q = QTEST(obj);
> +    Chardev *chr;
> +
> +    if (q->complete) {
> +        error_setg(errp, QERR_PERMISSION_DENIED);
> +        return;
> +    }
> +
> +    chr = qemu_chr_find(value);
> +    if (!chr) {
> +        error_setg(errp, "Cannot find character device '%s'", value);
> +        return;
> +    }
> +
> +    g_free(q->chr_name);
> +    q->chr_name = g_strdup(value);
> +    q->chr = chr;
> +}
> +
> +static char *qtest_get_chardev(Object *obj, Error **errp)
> +{
> +    QTest *q = QTEST(obj);
> +
> +    return g_strdup(q->chr_name);
> +}
> +
> +static void qtest_class_init(ObjectClass *oc, void *data)
> +{
> +    UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
> +
> +    ucc->complete = qtest_complete;
> +
> +    object_class_property_add_str(oc, "chardev",
> +                                  qtest_get_chardev, qtest_set_chardev);
> +    object_class_property_add_str(oc, "log",
> +                                  qtest_get_log, qtest_set_log);
> +}
> +
> +static const TypeInfo qtest_info = {
> +    .name = TYPE_QTEST,
> +    .parent = TYPE_OBJECT,
> +    .class_init = qtest_class_init,
> +    .instance_size = sizeof(QTest),
> +    .interfaces = (InterfaceInfo[]) {
> +        { TYPE_USER_CREATABLE },
> +        { }
> +    }
> +};
> +
> +static void register_types(void)
> +{
> +    type_register_static(&qtest_info);
> +}
> +
> +type_init(register_types);
> diff --git a/softmmu/vl.c b/softmmu/vl.c
> index 0f7222af31..e5f3c42049 100644
> --- a/softmmu/vl.c
> +++ b/softmmu/vl.c
> @@ -1685,8 +1685,9 @@ static bool object_create_early(const char *type, QemuOpts *opts)
>       * add one, state the reason in a comment!
>       */
>  
> -    /* Reason: rng-egd property "chardev" */
> -    if (g_str_equal(type, "rng-egd")) {
> +    /* Reason: property "chardev" */
> +    if (g_str_equal(type, "rng-egd") ||
> +        g_str_equal(type, "qtest")) {
>          return false;
>      }
>  



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

* Re: [PATCH 10/15] vl: make qemu_get_machine_opts static
  2020-12-07 16:07   ` Igor Mammedov
@ 2020-12-07 16:38     ` Paolo Bonzini
  2020-12-08  2:32     ` Daniel Henrique Barboza
  1 sibling, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-07 16:38 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: danielhb413, qemu-devel, david

On 07/12/20 17:07, Igor Mammedov wrote:
> On Wed,  2 Dec 2020 03:18:49 -0500
> Paolo Bonzini <pbonzini@redhat.com> wrote:
> 
>> Machine options can be retrieved as properties of the machine object.
>> Encourage that by removing the "easy" accessor to machine options.
>>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>>   accel/kvm/kvm-all.c     | 11 ++++-------
>>   hw/arm/boot.c           |  2 +-
>>   hw/microblaze/boot.c    |  9 ++++-----
>>   hw/nios2/boot.c         |  9 ++++-----
>>   hw/ppc/e500.c           |  5 ++---
>>   hw/ppc/spapr_nvdimm.c   |  4 ++--
>>   hw/ppc/virtex_ml507.c   |  2 +-
>>   hw/riscv/sifive_u.c     |  6 ++----
>>   hw/riscv/virt.c         |  6 ++----
>>   hw/xtensa/xtfpga.c      |  9 ++++-----
>>   include/sysemu/sysemu.h |  2 --
>>   softmmu/device_tree.c   |  2 +-
>>   softmmu/vl.c            |  2 +-
>>   13 files changed, 28 insertions(+), 41 deletions(-)
>>
> [...]
>> diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
>> index a833a63b5e..84715a4d78 100644
>> --- a/hw/ppc/spapr_nvdimm.c
>> +++ b/hw/ppc/spapr_nvdimm.c
>> @@ -38,7 +38,6 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
>>   {
>>       const MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev);
>>       const MachineState *ms = MACHINE(hotplug_dev);
>> -    const char *nvdimm_opt = qemu_opt_get(qemu_get_machine_opts(), "nvdimm");
>>       g_autofree char *uuidstr = NULL;
>>       QemuUUID uuid;
>>       int ret;
>> @@ -57,10 +56,11 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
>>        * ensure that, if the user sets nvdimm=off, we error out
>>        * regardless of being 5.1 or newer.
>>        */
>> -    if (!ms->nvdimms_state->is_enabled && nvdimm_opt) {
>> +    if (!ms->nvdimms_state->is_enabled && ms->nvdimms_state->has_is_enabled) {
>>           error_setg(errp, "nvdimm device found but 'nvdimm=off' was set");
>>           return false;
>>       }
>> +    ms->nvdimms_state->is_enabled = true;
> 
> it looks like nvdimm is always enabled since 5.0 and there is no way to disable it
> how about dropping 9/15 and just error out is it's not enabled, something like:
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index b7e0894019..d63f095bff 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -2668,6 +2668,7 @@ static void spapr_machine_init(MachineState *machine)
>       char *filename;
>       Error *resize_hpt_err = NULL;
> +    if (mc->nvdimm_supported) { // by default it is always enabled
> +        ms->nvdimms_state->is_enabled = true;
> +    }
>       msi_nonbroken = true;
>   
>       QLIST_INIT(&spapr->phbs);
> diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
> index a833a63b5e..b11c85dbaa 100644
> --- a/hw/ppc/spapr_nvdimm.c
> +++ b/hw/ppc/spapr_nvdimm.c
> @@ -57,7 +57,7 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
>        * ensure that, if the user sets nvdimm=off, we error out
>        * regardless of being 5.1 or newer.
>        */
> -    if (!ms->nvdimms_state->is_enabled && nvdimm_opt) {
> +    if (!ms->nvdimms_state->is_enabled) {
>           error_setg(errp, "nvdimm device found but 'nvdimm=off' was set");
>           return false;
>       }
> 
> if I didn't miss something, that way we do not abuse nvdimm_opt and still
> have nvdimm enabled by default and error out if it turns to disabled for whatever reason.

Yes, this looks correct.  I see you have already CCed Daniel and David.

Paolo



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

* Re: [PATCH 13/15] memory: allow creating MemoryRegions before accelerators
  2020-12-02  8:18 ` [PATCH 13/15] memory: allow creating MemoryRegions before accelerators Paolo Bonzini
@ 2020-12-07 16:38   ` Igor Mammedov
  2020-12-07 16:40     ` Paolo Bonzini
  2020-12-07 17:06   ` Igor Mammedov
  1 sibling, 1 reply; 50+ messages in thread
From: Igor Mammedov @ 2020-12-07 16:38 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On Wed,  2 Dec 2020 03:18:52 -0500
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Compute the DIRTY_MEMORY_CODE bit in memory_region_get_dirty_log_mask
> instead of memory_region_init_*.  This makes it possible to allocate
> memory backend objects at any time.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  softmmu/memory.c | 12 ++++++------
>  softmmu/vl.c     |  6 +-----
>  2 files changed, 7 insertions(+), 11 deletions(-)
> 
> diff --git a/softmmu/memory.c b/softmmu/memory.c
> index 11ca94d037..89a4723fe5 100644
> --- a/softmmu/memory.c
> +++ b/softmmu/memory.c
> @@ -1548,7 +1548,6 @@ void memory_region_init_ram_shared_nomigrate(MemoryRegion *mr,
>      mr->terminates = true;
>      mr->destructor = memory_region_destructor_ram;
>      mr->ram_block = qemu_ram_alloc(size, share, mr, &err);
> -    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
>      if (err) {
>          mr->size = int128_zero();
>          object_unparent(OBJECT(mr));
> @@ -1573,7 +1572,6 @@ void memory_region_init_resizeable_ram(MemoryRegion *mr,
>      mr->destructor = memory_region_destructor_ram;
>      mr->ram_block = qemu_ram_alloc_resizeable(size, max_size, resized,
>                                                mr, &err);
> -    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
>      if (err) {
>          mr->size = int128_zero();
>          object_unparent(OBJECT(mr));
> @@ -1598,7 +1596,6 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
>      mr->destructor = memory_region_destructor_ram;
>      mr->align = align;
>      mr->ram_block = qemu_ram_alloc_from_file(size, mr, ram_flags, path, &err);
> -    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
>      if (err) {
>          mr->size = int128_zero();
>          object_unparent(OBJECT(mr));
> @@ -1622,7 +1619,6 @@ void memory_region_init_ram_from_fd(MemoryRegion *mr,
>      mr->ram_block = qemu_ram_alloc_from_fd(size, mr,
>                                             share ? RAM_SHARED : 0,
>                                             fd, &err);
> -    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
>      if (err) {
>          mr->size = int128_zero();
>          object_unparent(OBJECT(mr));
> @@ -1641,7 +1637,6 @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
>      mr->ram = true;
>      mr->terminates = true;
>      mr->destructor = memory_region_destructor_ram;
> -    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
>  
>      /* qemu_ram_alloc_from_ptr cannot fail with ptr != NULL.  */
>      assert(ptr != NULL);
> @@ -1661,7 +1656,7 @@ void memory_region_init_ram_device_ptr(MemoryRegion *mr,
>      mr->ops = &ram_device_mem_ops;
>      mr->opaque = mr;
>      mr->destructor = memory_region_destructor_ram;
> -    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
> +
>      /* qemu_ram_alloc_from_ptr cannot fail with ptr != NULL.  */
>      assert(ptr != NULL);
>      mr->ram_block = qemu_ram_alloc_from_ptr(size, ptr, mr, &error_fatal);
> @@ -1819,6 +1814,11 @@ uint8_t memory_region_get_dirty_log_mask(MemoryRegion *mr)
>                               memory_region_is_iommu(mr))) {
>          mask |= (1 << DIRTY_MEMORY_MIGRATION);
>      }
> +
> +    if (tcg_enabled() && rb) {
> +        /* TCG only cares about dirty memory logging for RAM, not IOMMU.  */
> +        mask |= (1 << DIRTY_MEMORY_CODE);
> +    }
>      return mask;
>  }

Is following also necessary?:

diff --git a/softmmu/memory.c b/softmmu/memory.c
index 11ca94d037..f1de42e50f 100644
--- a/softmmu/memory.c
+++ b/softmmu/memory.c
@@ -2033,7 +2033,8 @@ void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client)
     }
 
     memory_region_transaction_begin();
-    mr->dirty_log_mask = (mr->dirty_log_mask & ~mask) | (log * mask);
+    mr->dirty_log_mask = (memory_region_get_dirty_log_mask(mr) & ~mask) |
+                         (log * mask);
     memory_region_update_pending |= mr->enabled;
     memory_region_transaction_commit();
 }

>  
> diff --git a/softmmu/vl.c b/softmmu/vl.c
> index 0f63d80472..023c16245b 100644
> --- a/softmmu/vl.c
> +++ b/softmmu/vl.c
> @@ -1715,11 +1715,7 @@ static bool object_create_early(const char *type, QemuOpts *opts)
>          return false;
>      }
>  
> -    /* Memory allocation by backends needs to be done
> -     * after configure_accelerator() (due to the tcg_enabled()
> -     * checks at memory_region_init_*()).
> -     *
> -     * Also, allocation of large amounts of memory may delay
> +    /* Allocation of large amounts of memory may delay
>       * chardev initialization for too long, and trigger timeouts
>       * on software that waits for a monitor socket to be created
>       * (e.g. libvirt).



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

* Re: [PATCH 13/15] memory: allow creating MemoryRegions before accelerators
  2020-12-07 16:38   ` Igor Mammedov
@ 2020-12-07 16:40     ` Paolo Bonzini
  0 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-07 16:40 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: qemu-devel

On 07/12/20 17:38, Igor Mammedov wrote:
> On Wed,  2 Dec 2020 03:18:52 -0500
> Paolo Bonzini <pbonzini@redhat.com> wrote:
> 
>> Compute the DIRTY_MEMORY_CODE bit in memory_region_get_dirty_log_mask
>> instead of memory_region_init_*.  This makes it possible to allocate
>> memory backend objects at any time.
>>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>>   softmmu/memory.c | 12 ++++++------
>>   softmmu/vl.c     |  6 +-----
>>   2 files changed, 7 insertions(+), 11 deletions(-)
>>
>> diff --git a/softmmu/memory.c b/softmmu/memory.c
>> index 11ca94d037..89a4723fe5 100644
>> --- a/softmmu/memory.c
>> +++ b/softmmu/memory.c
>> @@ -1548,7 +1548,6 @@ void memory_region_init_ram_shared_nomigrate(MemoryRegion *mr,
>>       mr->terminates = true;
>>       mr->destructor = memory_region_destructor_ram;
>>       mr->ram_block = qemu_ram_alloc(size, share, mr, &err);
>> -    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
>>       if (err) {
>>           mr->size = int128_zero();
>>           object_unparent(OBJECT(mr));
>> @@ -1573,7 +1572,6 @@ void memory_region_init_resizeable_ram(MemoryRegion *mr,
>>       mr->destructor = memory_region_destructor_ram;
>>       mr->ram_block = qemu_ram_alloc_resizeable(size, max_size, resized,
>>                                                 mr, &err);
>> -    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
>>       if (err) {
>>           mr->size = int128_zero();
>>           object_unparent(OBJECT(mr));
>> @@ -1598,7 +1596,6 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
>>       mr->destructor = memory_region_destructor_ram;
>>       mr->align = align;
>>       mr->ram_block = qemu_ram_alloc_from_file(size, mr, ram_flags, path, &err);
>> -    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
>>       if (err) {
>>           mr->size = int128_zero();
>>           object_unparent(OBJECT(mr));
>> @@ -1622,7 +1619,6 @@ void memory_region_init_ram_from_fd(MemoryRegion *mr,
>>       mr->ram_block = qemu_ram_alloc_from_fd(size, mr,
>>                                              share ? RAM_SHARED : 0,
>>                                              fd, &err);
>> -    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
>>       if (err) {
>>           mr->size = int128_zero();
>>           object_unparent(OBJECT(mr));
>> @@ -1641,7 +1637,6 @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
>>       mr->ram = true;
>>       mr->terminates = true;
>>       mr->destructor = memory_region_destructor_ram;
>> -    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
>>   
>>       /* qemu_ram_alloc_from_ptr cannot fail with ptr != NULL.  */
>>       assert(ptr != NULL);
>> @@ -1661,7 +1656,7 @@ void memory_region_init_ram_device_ptr(MemoryRegion *mr,
>>       mr->ops = &ram_device_mem_ops;
>>       mr->opaque = mr;
>>       mr->destructor = memory_region_destructor_ram;
>> -    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
>> +
>>       /* qemu_ram_alloc_from_ptr cannot fail with ptr != NULL.  */
>>       assert(ptr != NULL);
>>       mr->ram_block = qemu_ram_alloc_from_ptr(size, ptr, mr, &error_fatal);
>> @@ -1819,6 +1814,11 @@ uint8_t memory_region_get_dirty_log_mask(MemoryRegion *mr)
>>                                memory_region_is_iommu(mr))) {
>>           mask |= (1 << DIRTY_MEMORY_MIGRATION);
>>       }
>> +
>> +    if (tcg_enabled() && rb) {
>> +        /* TCG only cares about dirty memory logging for RAM, not IOMMU.  */
>> +        mask |= (1 << DIRTY_MEMORY_CODE);
>> +    }
>>       return mask;
>>   }
> 
> Is following also necessary?:
> 
> diff --git a/softmmu/memory.c b/softmmu/memory.c
> index 11ca94d037..f1de42e50f 100644
> --- a/softmmu/memory.c
> +++ b/softmmu/memory.c
> @@ -2033,7 +2033,8 @@ void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client)
>       }
>   
>       memory_region_transaction_begin();
> -    mr->dirty_log_mask = (mr->dirty_log_mask & ~mask) | (log * mask);
> +    mr->dirty_log_mask = (memory_region_get_dirty_log_mask(mr) & ~mask) |
> +                         (log * mask);
>       memory_region_update_pending |= mr->enabled;
>       memory_region_transaction_commit();
>   }

No, 1 << DIRTY_MEMORY_CODE moves altogether from mr->dirty_log_mask to 
being only in the return value of memory_region_get_dirty_log_mask.

Paolo

>>   
>> diff --git a/softmmu/vl.c b/softmmu/vl.c
>> index 0f63d80472..023c16245b 100644
>> --- a/softmmu/vl.c
>> +++ b/softmmu/vl.c
>> @@ -1715,11 +1715,7 @@ static bool object_create_early(const char *type, QemuOpts *opts)
>>           return false;
>>       }
>>   
>> -    /* Memory allocation by backends needs to be done
>> -     * after configure_accelerator() (due to the tcg_enabled()
>> -     * checks at memory_region_init_*()).
>> -     *
>> -     * Also, allocation of large amounts of memory may delay
>> +    /* Allocation of large amounts of memory may delay
>>        * chardev initialization for too long, and trigger timeouts
>>        * on software that waits for a monitor socket to be created
>>        * (e.g. libvirt).
> 



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

* Re: [PATCH 11/15] qtest: add a QOM object for qtest
  2020-12-07 16:24   ` Igor Mammedov
@ 2020-12-07 16:43     ` Paolo Bonzini
  2020-12-07 16:57       ` Igor Mammedov
  0 siblings, 1 reply; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-07 16:43 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: qemu-devel

On 07/12/20 17:24, Igor Mammedov wrote:
>> +void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **errp)
>> +{
>> +    Chardev *chr;
>> +
>> +    chr = qemu_chr_new("qtest", qtest_chrdev, NULL);
>> +
>> +    if (chr == NULL) {
>> +        error_setg(errp, "Failed to initialize device for qtest: \"%s\"",
>> +                   qtest_chrdev);
>> +        return;
>> +    }
>> +
>> +    qtest_server_start(chr, qtest_log, errp);
> why not create qtest object here instead of trying to preserve old way,
> or create it directly at the place that calls qtest_server_init()?

Because I wasn't sure of where to put it in the QOM object tree.  So I 
punted and left it for later.

Paolo



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

* Re: [PATCH 14/15] null-machine: do not create a default memdev
  2020-12-02  8:18 ` [PATCH 14/15] null-machine: do not create a default memdev Paolo Bonzini
@ 2020-12-07 16:43   ` Igor Mammedov
  2020-12-11 23:24     ` Paolo Bonzini
  0 siblings, 1 reply; 50+ messages in thread
From: Igor Mammedov @ 2020-12-07 16:43 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On Wed,  2 Dec 2020 03:18:53 -0500
Paolo Bonzini <pbonzini@redhat.com> wrote:

> The default RAM size is 0, so no RAM will be created anyway.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  hw/core/null-machine.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/core/null-machine.c b/hw/core/null-machine.c
> index 7e693523d7..c40badf5bc 100644
> --- a/hw/core/null-machine.c
> +++ b/hw/core/null-machine.c
> @@ -49,7 +49,7 @@ static void machine_none_machine_init(MachineClass *mc)
>      mc->init = machine_none_init;
>      mc->max_cpus = 1;
>      mc->default_ram_size = 0;
> -    mc->default_ram_id = "ram";
> +    mc->default_ram_id = NULL;

probably that will break:

 QEMU -m X -M none


maybe there is  a bug over there but
    "mc->default_ram_size = 0"
above, should result in
    current_machine->ram_size == 0
in case user hasn't provided "-m"
and hence memdev shouldn't be created

>      mc->no_serial = 1;
>      mc->no_parallel = 1;
>      mc->no_floppy = 1;



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

* Re: [PATCH 15/15] monitor: allow quitting while in preconfig state
  2020-12-02  8:18 ` [PATCH 15/15] monitor: allow quitting while in preconfig state Paolo Bonzini
@ 2020-12-07 16:45   ` Igor Mammedov
  0 siblings, 0 replies; 50+ messages in thread
From: Igor Mammedov @ 2020-12-07 16:45 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On Wed,  2 Dec 2020 03:18:54 -0500
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Reviewed-by: Igor Mammedov <imammedo@redhat.com>

> ---
>  hmp-commands.hx   | 1 +
>  qapi/control.json | 3 ++-
>  2 files changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index ff2d7aa8f3..d192afa652 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -45,6 +45,7 @@ ERST
>          .params     = "",
>          .help       = "quit the emulator",
>          .cmd        = hmp_quit,
> +        .flags      = "p",
>      },
>  
>  SRST
> diff --git a/qapi/control.json b/qapi/control.json
> index 134f842baf..1ebc450aad 100644
> --- a/qapi/control.json
> +++ b/qapi/control.json
> @@ -219,7 +219,8 @@
>  # -> { "execute": "quit" }
>  # <- { "return": {} }
>  ##
> -{ 'command': 'quit' }
> +{ 'command': 'quit',
> +  'allow-preconfig': true }
>  
>  ##
>  # @MonitorMode:



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

* Re: [PATCH 12/15] plugin: propagate errors
  2020-12-02  8:18 ` [PATCH 12/15] plugin: propagate errors Paolo Bonzini
  2020-12-02 11:33   ` Alex Bennée
@ 2020-12-07 16:53   ` Igor Mammedov
  1 sibling, 0 replies; 50+ messages in thread
From: Igor Mammedov @ 2020-12-07 16:53 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Alex Bennée, qemu-devel

On Wed,  2 Dec 2020 03:18:51 -0500
Paolo Bonzini <pbonzini@redhat.com> wrote:

> qemu_finish_machine_init currently can only exit QEMU if it fails.
> Prepare for giving it proper error propagation, and possibly for
> adding a plugin_add monitor command that calls an accelerator
> method.
> 
> While at it, make all errors from plugin_load look the same.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Reviewed-by: Igor Mammedov <imammedo@redhat.com>

> ---
>  include/qemu/plugin.h |  4 ++--
>  linux-user/main.c     |  4 +---
>  plugins/loader.c      | 34 +++++++++++++++++-----------------
>  softmmu/vl.c          |  4 +---
>  4 files changed, 21 insertions(+), 25 deletions(-)
> 
> diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
> index ab790ad105..841deed79c 100644
> --- a/include/qemu/plugin.h
> +++ b/include/qemu/plugin.h
> @@ -45,7 +45,7 @@ static inline void qemu_plugin_add_opts(void)
>  }
>  
>  void qemu_plugin_opt_parse(const char *optarg, QemuPluginList *head);
> -int qemu_plugin_load_list(QemuPluginList *head);
> +int qemu_plugin_load_list(QemuPluginList *head, Error **errp);
>  
>  union qemu_plugin_cb_sig {
>      qemu_plugin_simple_cb_t          simple;
> @@ -199,7 +199,7 @@ static inline void qemu_plugin_opt_parse(const char *optarg,
>      exit(1);
>  }
>  
> -static inline int qemu_plugin_load_list(QemuPluginList *head)
> +static inline int qemu_plugin_load_list(QemuPluginList *head, Error **errp)
>  {
>      return 0;
>  }
> diff --git a/linux-user/main.c b/linux-user/main.c
> index 24d1eb73ad..750a01118f 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -671,9 +671,7 @@ int main(int argc, char **argv, char **envp)
>          exit(1);
>      }
>      trace_init_file();
> -    if (qemu_plugin_load_list(&plugins)) {
> -        exit(1);
> -    }
> +    qemu_plugin_load_list(&plugins, &error_fatal);
>  
>      /* Zero out regs */
>      memset(regs, 0, sizeof(struct target_pt_regs));
> diff --git a/plugins/loader.c b/plugins/loader.c
> index 8ac5dbc20f..5cb9794fda 100644
> --- a/plugins/loader.c
> +++ b/plugins/loader.c
> @@ -150,7 +150,7 @@ static uint64_t xorshift64star(uint64_t x)
>      return x * UINT64_C(2685821657736338717);
>  }
>  
> -static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info)
> +static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info, Error **errp)
>  {
>      qemu_plugin_install_func_t install;
>      struct qemu_plugin_ctx *ctx;
> @@ -163,37 +163,37 @@ static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info)
>  
>      ctx->handle = g_module_open(desc->path, G_MODULE_BIND_LOCAL);
>      if (ctx->handle == NULL) {
> -        error_report("%s: %s", __func__, g_module_error());
> +        error_setg(errp, "Could not load plugin %s: %s", desc->path, g_module_error());
>          goto err_dlopen;
>      }
>  
>      if (!g_module_symbol(ctx->handle, "qemu_plugin_install", &sym)) {
> -        error_report("%s: %s", __func__, g_module_error());
> +        error_setg(errp, "Could not load plugin %s: %s", desc->path, g_module_error());
>          goto err_symbol;
>      }
>      install = (qemu_plugin_install_func_t) sym;
>      /* symbol was found; it could be NULL though */
>      if (install == NULL) {
> -        error_report("%s: %s: qemu_plugin_install is NULL",
> -                     __func__, desc->path);
> +        error_setg(errp, "Could not load plugin %s: qemu_plugin_install is NULL",
> +                   desc->path);
>          goto err_symbol;
>      }
>  
>      if (!g_module_symbol(ctx->handle, "qemu_plugin_version", &sym)) {
> -        error_report("TCG plugin %s does not declare API version %s",
> -                     desc->path, g_module_error());
> +        error_setg(errp, "Could not load plugin %s: plugin does not declare API version %s",
> +                   desc->path, g_module_error());
>          goto err_symbol;
>      } else {
>          int version = *(int *)sym;
>          if (version < QEMU_PLUGIN_MIN_VERSION) {
> -            error_report("TCG plugin %s requires API version %d, but "
> -                         "this QEMU supports only a minimum version of %d",
> -                         desc->path, version, QEMU_PLUGIN_MIN_VERSION);
> +            error_setg(errp, "Could not load plugin %s: plugin requires API version %d, but "
> +                       "this QEMU supports only a minimum version of %d",
> +                       desc->path, version, QEMU_PLUGIN_MIN_VERSION);
>              goto err_symbol;
>          } else if (version > QEMU_PLUGIN_VERSION) {
> -            error_report("TCG plugin %s requires API version %d, but "
> -                         "this QEMU supports only up to version %d",
> -                         desc->path, version, QEMU_PLUGIN_VERSION);
> +            error_setg(errp, "Could not load plugin %s: plugin requires API version %d, but "
> +                       "this QEMU supports only up to version %d",
> +                       desc->path, version, QEMU_PLUGIN_VERSION);
>              goto err_symbol;
>          }
>      }
> @@ -220,8 +220,8 @@ static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info)
>      rc = install(ctx->id, info, desc->argc, desc->argv);
>      ctx->installing = false;
>      if (rc) {
> -        error_report("%s: qemu_plugin_install returned error code %d",
> -                     __func__, rc);
> +        error_setg(errp, "Could not load plugin %s: qemu_plugin_install returned error code %d",
> +                   desc->path, rc);
>          /*
>           * we cannot rely on the plugin doing its own cleanup, so
>           * call a full uninstall if the plugin did not yet call it.
> @@ -263,7 +263,7 @@ static void plugin_desc_free(struct qemu_plugin_desc *desc)
>   * Note: the descriptor of each successfully installed plugin is removed
>   * from the list given by @head.
>   */
> -int qemu_plugin_load_list(QemuPluginList *head)
> +int qemu_plugin_load_list(QemuPluginList *head, Error **errp)
>  {
>      struct qemu_plugin_desc *desc, *next;
>      g_autofree qemu_info_t *info = g_new0(qemu_info_t, 1);
> @@ -283,7 +283,7 @@ int qemu_plugin_load_list(QemuPluginList *head)
>      QTAILQ_FOREACH_SAFE(desc, head, entry, next) {
>          int err;
>  
> -        err = plugin_load(desc, info);
> +        err = plugin_load(desc, info, errp);
>          if (err) {
>              return err;
>          }
> diff --git a/softmmu/vl.c b/softmmu/vl.c
> index e5f3c42049..0f63d80472 100644
> --- a/softmmu/vl.c
> +++ b/softmmu/vl.c
> @@ -2417,9 +2417,7 @@ static void qemu_init_board(void)
>      }
>  
>      /* process plugin before CPUs are created, but once -smp has been parsed */
> -    if (qemu_plugin_load_list(&plugin_list)) {
> -        exit(1);
> -    }
> +    qemu_plugin_load_list(&plugin_list, &error_fatal);
>  
>      /* From here on we enter MACHINE_PHASE_INITIALIZED.  */
>      machine_run_board_init(current_machine);



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

* Re: [PATCH 11/15] qtest: add a QOM object for qtest
  2020-12-07 16:43     ` Paolo Bonzini
@ 2020-12-07 16:57       ` Igor Mammedov
  2020-12-07 17:22         ` Paolo Bonzini
  0 siblings, 1 reply; 50+ messages in thread
From: Igor Mammedov @ 2020-12-07 16:57 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On Mon, 7 Dec 2020 17:43:16 +0100
Paolo Bonzini <pbonzini@redhat.com> wrote:

> On 07/12/20 17:24, Igor Mammedov wrote:
> >> +void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **errp)
> >> +{
> >> +    Chardev *chr;
> >> +
> >> +    chr = qemu_chr_new("qtest", qtest_chrdev, NULL);
> >> +
> >> +    if (chr == NULL) {
> >> +        error_setg(errp, "Failed to initialize device for qtest: \"%s\"",
> >> +                   qtest_chrdev);
> >> +        return;
> >> +    }
> >> +
> >> +    qtest_server_start(chr, qtest_log, errp);  
> > why not create qtest object here instead of trying to preserve old way,
> > or create it directly at the place that calls qtest_server_init()?  
> 
> Because I wasn't sure of where to put it in the QOM object tree.  So I 
> punted and left it for later.

but you implicitly decided where it should be (with -object qtest),
it goes to /objects.
So I'd wouldn't put anywhere else to be consistent.

> 
> Paolo
> 



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

* Re: [PATCH 13/15] memory: allow creating MemoryRegions before accelerators
  2020-12-02  8:18 ` [PATCH 13/15] memory: allow creating MemoryRegions before accelerators Paolo Bonzini
  2020-12-07 16:38   ` Igor Mammedov
@ 2020-12-07 17:06   ` Igor Mammedov
  1 sibling, 0 replies; 50+ messages in thread
From: Igor Mammedov @ 2020-12-07 17:06 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On Wed,  2 Dec 2020 03:18:52 -0500
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Compute the DIRTY_MEMORY_CODE bit in memory_region_get_dirty_log_mask
> instead of memory_region_init_*.  This makes it possible to allocate
> memory backend objects at any time.

Reviewed-by: Igor Mammedov <imammedo@redhat.com>

> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  softmmu/memory.c | 12 ++++++------
>  softmmu/vl.c     |  6 +-----
>  2 files changed, 7 insertions(+), 11 deletions(-)
> 
> diff --git a/softmmu/memory.c b/softmmu/memory.c
> index 11ca94d037..89a4723fe5 100644
> --- a/softmmu/memory.c
> +++ b/softmmu/memory.c
> @@ -1548,7 +1548,6 @@ void memory_region_init_ram_shared_nomigrate(MemoryRegion *mr,
>      mr->terminates = true;
>      mr->destructor = memory_region_destructor_ram;
>      mr->ram_block = qemu_ram_alloc(size, share, mr, &err);
> -    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
>      if (err) {
>          mr->size = int128_zero();
>          object_unparent(OBJECT(mr));
> @@ -1573,7 +1572,6 @@ void memory_region_init_resizeable_ram(MemoryRegion *mr,
>      mr->destructor = memory_region_destructor_ram;
>      mr->ram_block = qemu_ram_alloc_resizeable(size, max_size, resized,
>                                                mr, &err);
> -    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
>      if (err) {
>          mr->size = int128_zero();
>          object_unparent(OBJECT(mr));
> @@ -1598,7 +1596,6 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
>      mr->destructor = memory_region_destructor_ram;
>      mr->align = align;
>      mr->ram_block = qemu_ram_alloc_from_file(size, mr, ram_flags, path, &err);
> -    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
>      if (err) {
>          mr->size = int128_zero();
>          object_unparent(OBJECT(mr));
> @@ -1622,7 +1619,6 @@ void memory_region_init_ram_from_fd(MemoryRegion *mr,
>      mr->ram_block = qemu_ram_alloc_from_fd(size, mr,
>                                             share ? RAM_SHARED : 0,
>                                             fd, &err);
> -    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
>      if (err) {
>          mr->size = int128_zero();
>          object_unparent(OBJECT(mr));
> @@ -1641,7 +1637,6 @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
>      mr->ram = true;
>      mr->terminates = true;
>      mr->destructor = memory_region_destructor_ram;
> -    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
>  
>      /* qemu_ram_alloc_from_ptr cannot fail with ptr != NULL.  */
>      assert(ptr != NULL);
> @@ -1661,7 +1656,7 @@ void memory_region_init_ram_device_ptr(MemoryRegion *mr,
>      mr->ops = &ram_device_mem_ops;
>      mr->opaque = mr;
>      mr->destructor = memory_region_destructor_ram;
> -    mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
> +
>      /* qemu_ram_alloc_from_ptr cannot fail with ptr != NULL.  */
>      assert(ptr != NULL);
>      mr->ram_block = qemu_ram_alloc_from_ptr(size, ptr, mr, &error_fatal);
> @@ -1819,6 +1814,11 @@ uint8_t memory_region_get_dirty_log_mask(MemoryRegion *mr)
>                               memory_region_is_iommu(mr))) {
>          mask |= (1 << DIRTY_MEMORY_MIGRATION);
>      }
> +
> +    if (tcg_enabled() && rb) {
> +        /* TCG only cares about dirty memory logging for RAM, not IOMMU.  */
> +        mask |= (1 << DIRTY_MEMORY_CODE);
> +    }
>      return mask;
>  }
>  
> diff --git a/softmmu/vl.c b/softmmu/vl.c
> index 0f63d80472..023c16245b 100644
> --- a/softmmu/vl.c
> +++ b/softmmu/vl.c
> @@ -1715,11 +1715,7 @@ static bool object_create_early(const char *type, QemuOpts *opts)
>          return false;
>      }
>  
> -    /* Memory allocation by backends needs to be done
> -     * after configure_accelerator() (due to the tcg_enabled()
> -     * checks at memory_region_init_*()).
> -     *
> -     * Also, allocation of large amounts of memory may delay
> +    /* Allocation of large amounts of memory may delay
>       * chardev initialization for too long, and trigger timeouts
>       * on software that waits for a monitor socket to be created
>       * (e.g. libvirt).



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

* Re: [PATCH 11/15] qtest: add a QOM object for qtest
  2020-12-07 16:57       ` Igor Mammedov
@ 2020-12-07 17:22         ` Paolo Bonzini
  2020-12-08 11:11           ` Igor Mammedov
  0 siblings, 1 reply; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-07 17:22 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1403 bytes --]

Il lun 7 dic 2020, 17:57 Igor Mammedov <imammedo@redhat.com> ha scritto:

> On Mon, 7 Dec 2020 17:43:16 +0100
> Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> > On 07/12/20 17:24, Igor Mammedov wrote:
> > >> +void qtest_server_init(const char *qtest_chrdev, const char
> *qtest_log, Error **errp)
> > >> +{
> > >> +    Chardev *chr;
> > >> +
> > >> +    chr = qemu_chr_new("qtest", qtest_chrdev, NULL);
> > >> +
> > >> +    if (chr == NULL) {
> > >> +        error_setg(errp, "Failed to initialize device for qtest:
> \"%s\"",
> > >> +                   qtest_chrdev);
> > >> +        return;
> > >> +    }
> > >> +
> > >> +    qtest_server_start(chr, qtest_log, errp);
> > > why not create qtest object here instead of trying to preserve old way,
> > > or create it directly at the place that calls qtest_server_init()?
> >
> > Because I wasn't sure of where to put it in the QOM object tree.  So I
> > punted and left it for later.
>
> but you implicitly decided where it should be (with -object qtest),
> it goes to /objects.
> So I'd wouldn't put anywhere else to be consistent.
>

No, /objects is for stuff created with -object exclusively. I suppose I
could have the "well-known path" be /machine/qtest, and it would be either
a child (for -qtest) or a link to /objects/some-id (for -object qtest).
Should I implement that (as a separate patch on top of this one)?

Paolo



> >
> > Paolo
> >
>
>

[-- Attachment #2: Type: text/html, Size: 2402 bytes --]

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

* Re: [PATCH 10/15] vl: make qemu_get_machine_opts static
  2020-12-02  8:18 ` [PATCH 10/15] vl: make qemu_get_machine_opts static Paolo Bonzini
  2020-12-07 16:07   ` Igor Mammedov
@ 2020-12-08  2:16   ` Daniel Henrique Barboza
  2020-12-08  8:13     ` Paolo Bonzini
  1 sibling, 1 reply; 50+ messages in thread
From: Daniel Henrique Barboza @ 2020-12-08  2:16 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: imammedo, David Gibson



On 12/2/20 5:18 AM, Paolo Bonzini wrote:
> Machine options can be retrieved as properties of the machine object.
> Encourage that by removing the "easy" accessor to machine options.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>   accel/kvm/kvm-all.c     | 11 ++++-------
>   hw/arm/boot.c           |  2 +-
>   hw/microblaze/boot.c    |  9 ++++-----
>   hw/nios2/boot.c         |  9 ++++-----
>   hw/ppc/e500.c           |  5 ++---
>   hw/ppc/spapr_nvdimm.c   |  4 ++--
>   hw/ppc/virtex_ml507.c   |  2 +-
>   hw/riscv/sifive_u.c     |  6 ++----
>   hw/riscv/virt.c         |  6 ++----
>   hw/xtensa/xtfpga.c      |  9 ++++-----
>   include/sysemu/sysemu.h |  2 --
>   softmmu/device_tree.c   |  2 +-
>   softmmu/vl.c            |  2 +-
>   13 files changed, 28 insertions(+), 41 deletions(-)
> 
> diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
> index baaa54249d..666b9ab96c 100644
> --- a/accel/kvm/kvm-all.c
> +++ b/accel/kvm/kvm-all.c
> @@ -2013,7 +2013,6 @@ static int kvm_init(MachineState *ms)
>       const KVMCapabilityInfo *missing_cap;
>       int ret;
>       int type = 0;
> -    const char *kvm_type;
>       uint64_t dirty_log_manual_caps;
>   
>       s = KVM_STATE(ms->accelerator);
> @@ -2069,13 +2068,11 @@ static int kvm_init(MachineState *ms)
>       }
>       s->as = g_new0(struct KVMAs, s->nr_as);
>   
> -    kvm_type = qemu_opt_get(qemu_get_machine_opts(), "kvm-type");
> -    if (mc->kvm_type) {
> +    if (object_property_find(OBJECT(current_machine), "kvm-type")) {
> +        g_autofree char *kvm_type = object_property_get_str(OBJECT(current_machine),
> +                                                            "kvm-type",
> +                                                            &error_abort);
>           type = mc->kvm_type(ms, kvm_type);



I'm afraid that this code has unintended consequences for pseries. When starting the VM
with '--enable-kvm' in a Power host I'm getting an error:


$ sudo ./ppc64-softmmu/qemu-system-ppc64 -nographic -nodefaults -machine pseries --enable-kvm
qemu-system-ppc64: Unknown kvm-type specified ''


The reason is that spapr_kvm_type() expects kvm-type to be either NULL (i.e. no option
set, in the previous semantic), "HV" or "PR". This was the case for the previous
qemu_opt_get(), but with object_property_get_str() the absence of the option is
returning kvm_type = ''.

This means that, as far as pseries goes, inserting "kvm-type=" (blank string)
has the same effect:


$ sudo ./ppc64-softmmu/qemu-system-ppc64 -nographic -nodefaults -machine pseries,accel=kvm,kvm-type=
qemu-system-ppc64: Unknown kvm-type specified ''


I investigated object_property_get_str() inner workings a bit and I wasn't able
to find a way for it to return NULL if kvm_type isn't specified.


I see three possible solutions for it:

1) interpret kvm_type='' as if kvm_type=NULL inside spapr_kvm_type():

static int spapr_kvm_type(MachineState *machine, const char *vm_type)
{
     if (!vm_type || strcmp(vm_type, "")) {
         return 0;
     }
(...)


This is kind of ugly because we're validating a "kvm_type=" scenario with it, but
it works.


2) find a way to make object_property_get_str() to return kvm_type = NULL if the
'kvm_type' option is absent  and keep spapr code untouched. I don't have the
knowledge to assess how hard this would be.


3) I can change the pseries logic to add an explicit default value for kvm_type=NULL
or kvm_type='' (i.e. no user input is given). We're already doing that in a sense, but
it's not exposed to the user. I would call it 'auto' and expose it to the user
as default value if no kvm_type is explictly set. This would enhance user experience
a bit and avoid having to deal with a scenario where kvm_type=(blank) is
a valid input.


David, if you think (3) is tolerable let me know and I can send a patch. IMO
this change adds a bit of value regardless of Paolo's change.


Thanks,



DHB



> -    } else if (kvm_type) {
> -        ret = -EINVAL;
> -        fprintf(stderr, "Invalid argument kvm-type=%s\n", kvm_type);
> -        goto err;
>       }
>   
>       do {
> diff --git a/hw/arm/boot.c b/hw/arm/boot.c
> index 4d9d47ba1c..e56c42ac22 100644
> --- a/hw/arm/boot.c
> +++ b/hw/arm/boot.c
> @@ -1299,7 +1299,7 @@ void arm_load_kernel(ARMCPU *cpu, MachineState *ms, struct arm_boot_info *info)
>       info->kernel_filename = ms->kernel_filename;
>       info->kernel_cmdline = ms->kernel_cmdline;
>       info->initrd_filename = ms->initrd_filename;
> -    info->dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
> +    info->dtb_filename = ms->dtb;
>       info->dtb_limit = 0;
>   
>       /* Load the kernel.  */
> diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c
> index 6715ba2ff9..caaba1aa4c 100644
> --- a/hw/microblaze/boot.c
> +++ b/hw/microblaze/boot.c
> @@ -34,6 +34,7 @@
>   #include "sysemu/device_tree.h"
>   #include "sysemu/reset.h"
>   #include "sysemu/sysemu.h"
> +#include "hw/boards.h"
>   #include "hw/loader.h"
>   #include "elf.h"
>   #include "qemu/cutils.h"
> @@ -116,16 +117,14 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
>                               const char *dtb_filename,
>                               void (*machine_cpu_reset)(MicroBlazeCPU *))
>   {
> -    QemuOpts *machine_opts;
>       const char *kernel_filename;
>       const char *kernel_cmdline;
>       const char *dtb_arg;
>       char *filename = NULL;
>   
> -    machine_opts = qemu_get_machine_opts();
> -    kernel_filename = qemu_opt_get(machine_opts, "kernel");
> -    kernel_cmdline = qemu_opt_get(machine_opts, "append");
> -    dtb_arg = qemu_opt_get(machine_opts, "dtb");
> +    kernel_filename = current_machine->kernel_filename;
> +    kernel_cmdline = current_machine->kernel_cmdline;
> +    dtb_arg = current_machine->dtb;
>       /* default to pcbios dtb as passed by machine_init */
>       if (!dtb_arg && dtb_filename) {
>           filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, dtb_filename);
> diff --git a/hw/nios2/boot.c b/hw/nios2/boot.c
> index 95a8697906..d9969ac148 100644
> --- a/hw/nios2/boot.c
> +++ b/hw/nios2/boot.c
> @@ -39,6 +39,7 @@
>   #include "sysemu/device_tree.h"
>   #include "sysemu/reset.h"
>   #include "sysemu/sysemu.h"
> +#include "hw/boards.h"
>   #include "hw/loader.h"
>   #include "elf.h"
>   
> @@ -120,16 +121,14 @@ void nios2_load_kernel(Nios2CPU *cpu, hwaddr ddr_base,
>                               const char *dtb_filename,
>                               void (*machine_cpu_reset)(Nios2CPU *))
>   {
> -    QemuOpts *machine_opts;
>       const char *kernel_filename;
>       const char *kernel_cmdline;
>       const char *dtb_arg;
>       char *filename = NULL;
>   
> -    machine_opts = qemu_get_machine_opts();
> -    kernel_filename = qemu_opt_get(machine_opts, "kernel");
> -    kernel_cmdline = qemu_opt_get(machine_opts, "append");
> -    dtb_arg = qemu_opt_get(machine_opts, "dtb");
> +    kernel_filename = current_machine->kernel_filename;
> +    kernel_cmdline = current_machine->kernel_cmdline;
> +    dtb_arg = current_machine->dtb;
>       /* default to pcbios dtb as passed by machine_init */
>       if (!dtb_arg) {
>           filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, dtb_filename);
> diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
> index 6a64eb31ab..41dad2e583 100644
> --- a/hw/ppc/e500.c
> +++ b/hw/ppc/e500.c
> @@ -343,9 +343,8 @@ static int ppce500_load_device_tree(PPCE500MachineState *pms,
>               pmc->pci_pio_base >> 32, pmc->pci_pio_base,
>               0x0, 0x10000,
>           };
> -    QemuOpts *machine_opts = qemu_get_machine_opts();
> -    const char *dtb_file = qemu_opt_get(machine_opts, "dtb");
> -    const char *toplevel_compat = qemu_opt_get(machine_opts, "dt_compatible");
> +    const char *dtb_file = machine->dtb;
> +    const char *toplevel_compat = machine->dt_compatible;
>   
>       if (dtb_file) {
>           char *filename;
> diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
> index a833a63b5e..84715a4d78 100644
> --- a/hw/ppc/spapr_nvdimm.c
> +++ b/hw/ppc/spapr_nvdimm.c
> @@ -38,7 +38,6 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
>   {
>       const MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev);
>       const MachineState *ms = MACHINE(hotplug_dev);
> -    const char *nvdimm_opt = qemu_opt_get(qemu_get_machine_opts(), "nvdimm");
>       g_autofree char *uuidstr = NULL;
>       QemuUUID uuid;
>       int ret;
> @@ -57,10 +56,11 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
>        * ensure that, if the user sets nvdimm=off, we error out
>        * regardless of being 5.1 or newer.
>        */
> -    if (!ms->nvdimms_state->is_enabled && nvdimm_opt) {
> +    if (!ms->nvdimms_state->is_enabled && ms->nvdimms_state->has_is_enabled) {
>           error_setg(errp, "nvdimm device found but 'nvdimm=off' was set");
>           return false;
>       }
> +    ms->nvdimms_state->is_enabled = true;
>   
>       if (object_property_get_int(OBJECT(nvdimm), NVDIMM_LABEL_SIZE_PROP,
>                                   &error_abort) == 0) {
> diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
> index 7f1bca928c..07fe49da0d 100644
> --- a/hw/ppc/virtex_ml507.c
> +++ b/hw/ppc/virtex_ml507.c
> @@ -152,7 +152,7 @@ static int xilinx_load_device_tree(hwaddr addr,
>       int r;
>       const char *dtb_filename;
>   
> -    dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
> +    dtb_filename = current_machine->dtb;
>       if (dtb_filename) {
>           fdt = load_device_tree(dtb_filename, &fdt_size);
>           if (!fdt) {
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 2f19a9cda2..e7f6dc5fb3 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -100,14 +100,12 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
>       int cpu;
>       uint32_t *cells;
>       char *nodename;
> -    const char *dtb_filename;
>       char ethclk_names[] = "pclk\0hclk";
>       uint32_t plic_phandle, prci_phandle, gpio_phandle, phandle = 1;
>       uint32_t hfclk_phandle, rtcclk_phandle, phy_phandle;
>   
> -    dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
> -    if (dtb_filename) {
> -        fdt = s->fdt = load_device_tree(dtb_filename, &s->fdt_size);
> +    if (ms->dtb) {
> +        fdt = s->fdt = load_device_tree(ms->dtb, &s->fdt_size);
>           if (!fdt) {
>               error_report("load_device_tree() failed");
>               exit(1);
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 25cea7aa67..3cc18a76e7 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -181,7 +181,6 @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
>   {
>       void *fdt;
>       int i, cpu, socket;
> -    const char *dtb_filename;
>       MachineState *mc = MACHINE(s);
>       uint64_t addr, size;
>       uint32_t *clint_cells, *plic_cells;
> @@ -195,9 +194,8 @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
>       hwaddr flashsize = virt_memmap[VIRT_FLASH].size / 2;
>       hwaddr flashbase = virt_memmap[VIRT_FLASH].base;
>   
> -    dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
> -    if (dtb_filename) {
> -        fdt = s->fdt = load_device_tree(dtb_filename, &s->fdt_size);
> +    if (mc->dtb) {
> +        fdt = s->fdt = load_device_tree(mc->dtb, &s->fdt_size);
>           if (!fdt) {
>               error_report("load_device_tree() failed");
>               exit(1);
> diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
> index b1470b88e6..7be53f1895 100644
> --- a/hw/xtensa/xtfpga.c
> +++ b/hw/xtensa/xtfpga.c
> @@ -233,11 +233,10 @@ static void xtfpga_init(const XtfpgaBoardDesc *board, MachineState *machine)
>       qemu_irq *extints;
>       DriveInfo *dinfo;
>       PFlashCFI01 *flash = NULL;
> -    QemuOpts *machine_opts = qemu_get_machine_opts();
> -    const char *kernel_filename = qemu_opt_get(machine_opts, "kernel");
> -    const char *kernel_cmdline = qemu_opt_get(machine_opts, "append");
> -    const char *dtb_filename = qemu_opt_get(machine_opts, "dtb");
> -    const char *initrd_filename = qemu_opt_get(machine_opts, "initrd");
> +    const char *kernel_filename = machine->kernel_filename;
> +    const char *kernel_cmdline = machine->kernel_cmdline;
> +    const char *dtb_filename = machine->dtb;
> +    const char *initrd_filename = machine->initrd_filename;
>       const unsigned system_io_size = 224 * MiB;
>       uint32_t freq = 10000000;
>       int n;
> diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
> index 9b47cdca55..e8f463ff30 100644
> --- a/include/sysemu/sysemu.h
> +++ b/include/sysemu/sysemu.h
> @@ -104,8 +104,6 @@ typedef void QEMUBootSetHandler(void *opaque, const char *boot_order,
>   void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque);
>   void qemu_boot_set(const char *boot_order, Error **errp);
>   
> -QemuOpts *qemu_get_machine_opts(void);
> -
>   bool defaults_enabled(void);
>   
>   void qemu_init(int argc, char **argv, char **envp);
> diff --git a/softmmu/device_tree.c b/softmmu/device_tree.c
> index b335dae707..b9a3ddc518 100644
> --- a/softmmu/device_tree.c
> +++ b/softmmu/device_tree.c
> @@ -526,7 +526,7 @@ int qemu_fdt_add_subnode(void *fdt, const char *name)
>   
>   void qemu_fdt_dumpdtb(void *fdt, int size)
>   {
> -    const char *dumpdtb = qemu_opt_get(qemu_get_machine_opts(), "dumpdtb");
> +    const char *dumpdtb = current_machine->dumpdtb;
>   
>       if (dumpdtb) {
>           /* Dump the dtb to a file and quit */
> diff --git a/softmmu/vl.c b/softmmu/vl.c
> index 4fece1b9db..0f7222af31 100644
> --- a/softmmu/vl.c
> +++ b/softmmu/vl.c
> @@ -481,7 +481,7 @@ static QemuOptsList qemu_fw_cfg_opts = {
>    *
>    * Returns: machine options (never null).
>    */
> -QemuOpts *qemu_get_machine_opts(void)
> +static QemuOpts *qemu_get_machine_opts(void)
>   {
>       return qemu_find_opts_singleton("machine");
>   }
> 


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

* Re: [PATCH 10/15] vl: make qemu_get_machine_opts static
  2020-12-07 16:07   ` Igor Mammedov
  2020-12-07 16:38     ` Paolo Bonzini
@ 2020-12-08  2:32     ` Daniel Henrique Barboza
  2020-12-08 10:55       ` Igor Mammedov
  2020-12-08 11:05       ` [PATCH] ppc/spapr: cleanup -machine pseries,nvdimm=X handling Igor Mammedov
  1 sibling, 2 replies; 50+ messages in thread
From: Daniel Henrique Barboza @ 2020-12-08  2:32 UTC (permalink / raw)
  To: Igor Mammedov, Paolo Bonzini; +Cc: qemu-devel, david



On 12/7/20 1:07 PM, Igor Mammedov wrote:
> On Wed,  2 Dec 2020 03:18:49 -0500
> Paolo Bonzini <pbonzini@redhat.com> wrote:
> 
>> Machine options can be retrieved as properties of the machine object.
>> Encourage that by removing the "easy" accessor to machine options.
>>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>>   accel/kvm/kvm-all.c     | 11 ++++-------
>>   hw/arm/boot.c           |  2 +-
>>   hw/microblaze/boot.c    |  9 ++++-----
>>   hw/nios2/boot.c         |  9 ++++-----
>>   hw/ppc/e500.c           |  5 ++---
>>   hw/ppc/spapr_nvdimm.c   |  4 ++--
>>   hw/ppc/virtex_ml507.c   |  2 +-
>>   hw/riscv/sifive_u.c     |  6 ++----
>>   hw/riscv/virt.c         |  6 ++----
>>   hw/xtensa/xtfpga.c      |  9 ++++-----
>>   include/sysemu/sysemu.h |  2 --
>>   softmmu/device_tree.c   |  2 +-
>>   softmmu/vl.c            |  2 +-
>>   13 files changed, 28 insertions(+), 41 deletions(-)
>>
> [...]
>> diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
>> index a833a63b5e..84715a4d78 100644
>> --- a/hw/ppc/spapr_nvdimm.c
>> +++ b/hw/ppc/spapr_nvdimm.c
>> @@ -38,7 +38,6 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
>>   {
>>       const MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev);
>>       const MachineState *ms = MACHINE(hotplug_dev);
>> -    const char *nvdimm_opt = qemu_opt_get(qemu_get_machine_opts(), "nvdimm");
>>       g_autofree char *uuidstr = NULL;
>>       QemuUUID uuid;
>>       int ret;
>> @@ -57,10 +56,11 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
>>        * ensure that, if the user sets nvdimm=off, we error out
>>        * regardless of being 5.1 or newer.
>>        */
>> -    if (!ms->nvdimms_state->is_enabled && nvdimm_opt) {
>> +    if (!ms->nvdimms_state->is_enabled && ms->nvdimms_state->has_is_enabled) {
>>           error_setg(errp, "nvdimm device found but 'nvdimm=off' was set");
>>           return false;
>>       }
>> +    ms->nvdimms_state->is_enabled = true;
> 
> it looks like nvdimm is always enabled since 5.0 and there is no way to disable it


I'm not sure I'm following this statement. Testing here with all patches
up to this one applied, in a x86 machine:


$ sudo ./x86_64-softmmu/qemu-system-x86_64 -M pc,nvdimm=off -object memory-backend-file,id=mem0,size=1G,mem-path=/tmp/aa -device nvdimm,id=dimm0,memdev=mem0
qemu-system-x86_64: -device nvdimm,id=dimm0,memdev=mem0: nvdimm is not enabled: missing 'nvdimm' in '-M'
$
$ sudo ./x86_64-softmmu/qemu-system-x86_64 -M pc -object memory-backend-file,id=mem0,size=1G,mem-path=/tmp/aa -device nvdimm,id=dimm0,memdev=mem0
qemu-system-x86_64: -device nvdimm,id=dimm0,memdev=mem0: nvdimm is not enabled: missing 'nvdimm' in '-M'
$

This is the x86 NVDIMM behavior I considered when patching pseries NVDIMM support.
As Paolo mentioned in patch 09, pseries has different default values. We screwed
it up when pushing the first version of pseries NVDIMM support and we ended up
enabling it by default, as opposed to disabling it by default like x86. One release
later people complained that we weren't honoring 'nvdimm=off' to disable NVDIMM
support. The path of less pain that I chose was to at the very least disable
the support when "nvdimm=off" was specified by the user.





> how about dropping 9/15 and just error out is it's not enabled, something like:
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index b7e0894019..d63f095bff 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -2668,6 +2668,7 @@ static void spapr_machine_init(MachineState *machine)
>       char *filename;
>       Error *resize_hpt_err = NULL;
> +    if (mc->nvdimm_supported) { // by default it is always enabled
> +        ms->nvdimms_state->is_enabled = true;
> +    }
>       msi_nonbroken = true;
>   
>       QLIST_INIT(&spapr->phbs);
> diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
> index a833a63b5e..b11c85dbaa 100644
> --- a/hw/ppc/spapr_nvdimm.c
> +++ b/hw/ppc/spapr_nvdimm.c
> @@ -57,7 +57,7 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
>        * ensure that, if the user sets nvdimm=off, we error out
>        * regardless of being 5.1 or newer.
>        */
> -    if (!ms->nvdimms_state->is_enabled && nvdimm_opt) {
> +    if (!ms->nvdimms_state->is_enabled) {
>           error_setg(errp, "nvdimm device found but 'nvdimm=off' was set");
>           return false;
>       }
> 
> if I didn't miss something, that way we do not abuse nvdimm_opt and still
> have nvdimm enabled by default and error out if it turns to disabled for whatever reason.


Just tried this out. This doesn't disable the NVDIMM support when passing 'nvdimm=off'
machine option.


As far pseries NVDIMM support goes, we'll need patch 09 and to consider nvdimm_opt
to keep the same behavior we already have today, like Paolo is already doing in
this patch.



Thanks,


DHB

> 
> 
>>       if (object_property_get_int(OBJECT(nvdimm), NVDIMM_LABEL_SIZE_PROP,
>>                                   &error_abort) == 0) {
> [...]
> 
>   
> 


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

* Re: [PATCH 10/15] vl: make qemu_get_machine_opts static
  2020-12-08  2:16   ` [PATCH 10/15] vl: make qemu_get_machine_opts static Daniel Henrique Barboza
@ 2020-12-08  8:13     ` Paolo Bonzini
  0 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-08  8:13 UTC (permalink / raw)
  To: Daniel Henrique Barboza, qemu-devel; +Cc: imammedo, David Gibson

On 08/12/20 03:16, Daniel Henrique Barboza wrote:
> 2) find a way to make object_property_get_str() to return kvm_type =
>  NULL if the 'kvm_type' option is absent  and keep spapr code
> untouched. I don't have the knowledge to assess how hard this would
> be.
> 
> 3) I can change the pseries logic to add an explicit default value
> for kvm_type=NULL or kvm_type='' (i.e. no user input is given). We're
> already doing that in a sense, but it's not exposed to the user. I
> would call it 'auto' and expose it to the user as default value if no
> kvm_type is explictly set. This would enhance user experience a bit
> and avoid having to deal with a scenario where kvm_type=(blank) is a
> valid input.
> 
> 
> David, if you think (3) is tolerable let me know and I can send a
> patch. IMO this change adds a bit of value regardless of Paolo's
> change.

Yes, I agree that (3) is a good idea.  If you send a patch I can 
integrate it in the series.

Paolo



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

* Re: [PATCH 10/15] vl: make qemu_get_machine_opts static
  2020-12-08  2:32     ` Daniel Henrique Barboza
@ 2020-12-08 10:55       ` Igor Mammedov
  2020-12-08 11:05       ` [PATCH] ppc/spapr: cleanup -machine pseries,nvdimm=X handling Igor Mammedov
  1 sibling, 0 replies; 50+ messages in thread
From: Igor Mammedov @ 2020-12-08 10:55 UTC (permalink / raw)
  To: Daniel Henrique Barboza; +Cc: Paolo Bonzini, qemu-devel, david

On Mon, 7 Dec 2020 23:32:55 -0300
Daniel Henrique Barboza <danielhb413@gmail.com> wrote:

> On 12/7/20 1:07 PM, Igor Mammedov wrote:
> > On Wed,  2 Dec 2020 03:18:49 -0500
> > Paolo Bonzini <pbonzini@redhat.com> wrote:
> >   
> >> Machine options can be retrieved as properties of the machine object.
> >> Encourage that by removing the "easy" accessor to machine options.
> >>
> >> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> >> ---
> >>   accel/kvm/kvm-all.c     | 11 ++++-------
> >>   hw/arm/boot.c           |  2 +-
> >>   hw/microblaze/boot.c    |  9 ++++-----
> >>   hw/nios2/boot.c         |  9 ++++-----
> >>   hw/ppc/e500.c           |  5 ++---
> >>   hw/ppc/spapr_nvdimm.c   |  4 ++--
> >>   hw/ppc/virtex_ml507.c   |  2 +-
> >>   hw/riscv/sifive_u.c     |  6 ++----
> >>   hw/riscv/virt.c         |  6 ++----
> >>   hw/xtensa/xtfpga.c      |  9 ++++-----
> >>   include/sysemu/sysemu.h |  2 --
> >>   softmmu/device_tree.c   |  2 +-
> >>   softmmu/vl.c            |  2 +-
> >>   13 files changed, 28 insertions(+), 41 deletions(-)
> >>  
> > [...]  
> >> diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
> >> index a833a63b5e..84715a4d78 100644
> >> --- a/hw/ppc/spapr_nvdimm.c
> >> +++ b/hw/ppc/spapr_nvdimm.c
> >> @@ -38,7 +38,6 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
> >>   {
> >>       const MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev);
> >>       const MachineState *ms = MACHINE(hotplug_dev);
> >> -    const char *nvdimm_opt = qemu_opt_get(qemu_get_machine_opts(), "nvdimm");
> >>       g_autofree char *uuidstr = NULL;
> >>       QemuUUID uuid;
> >>       int ret;
> >> @@ -57,10 +56,11 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
> >>        * ensure that, if the user sets nvdimm=off, we error out
> >>        * regardless of being 5.1 or newer.
> >>        */
> >> -    if (!ms->nvdimms_state->is_enabled && nvdimm_opt) {
> >> +    if (!ms->nvdimms_state->is_enabled && ms->nvdimms_state->has_is_enabled) {
> >>           error_setg(errp, "nvdimm device found but 'nvdimm=off' was set");
> >>           return false;
> >>       }
> >> +    ms->nvdimms_state->is_enabled = true;  
> > 
> > it looks like nvdimm is always enabled since 5.0 and there is no way to disable it  
> 
> 
> I'm not sure I'm following this statement. Testing here with all patches
> up to this one applied, in a x86 machine:
> 
> 
> $ sudo ./x86_64-softmmu/qemu-system-x86_64 -M pc,nvdimm=off -object memory-backend-file,id=mem0,size=1G,mem-path=/tmp/aa -device nvdimm,id=dimm0,memdev=mem0
> qemu-system-x86_64: -device nvdimm,id=dimm0,memdev=mem0: nvdimm is not enabled: missing 'nvdimm' in '-M'
> $
> $ sudo ./x86_64-softmmu/qemu-system-x86_64 -M pc -object memory-backend-file,id=mem0,size=1G,mem-path=/tmp/aa -device nvdimm,id=dimm0,memdev=mem0
> qemu-system-x86_64: -device nvdimm,id=dimm0,memdev=mem0: nvdimm is not enabled: missing 'nvdimm' in '-M'
> $
> 
> This is the x86 NVDIMM behavior I considered when patching pseries NVDIMM support.
> As Paolo mentioned in patch 09, pseries has different default values. We screwed
> it up when pushing the first version of pseries NVDIMM support and we ended up
> enabling it by default, as opposed to disabling it by default like x86. One release
> later people complained that we weren't honoring 'nvdimm=off' to disable NVDIMM
> support. The path of less pain that I chose was to at the very least disable
> the support when "nvdimm=off" was specified by the user.
> 
> 
> 
> 
> 
> > how about dropping 9/15 and just error out is it's not enabled, something like:
> > 
> > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > index b7e0894019..d63f095bff 100644
> > --- a/hw/ppc/spapr.c
> > +++ b/hw/ppc/spapr.c
> > @@ -2668,6 +2668,7 @@ static void spapr_machine_init(MachineState *machine)
> >       char *filename;
> >       Error *resize_hpt_err = NULL;
> > +    if (mc->nvdimm_supported) { // by default it is always enabled
> > +        ms->nvdimms_state->is_enabled = true;
> > +    }
> >       msi_nonbroken = true;
> >   
> >       QLIST_INIT(&spapr->phbs);
> > diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
> > index a833a63b5e..b11c85dbaa 100644
> > --- a/hw/ppc/spapr_nvdimm.c
> > +++ b/hw/ppc/spapr_nvdimm.c
> > @@ -57,7 +57,7 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
> >        * ensure that, if the user sets nvdimm=off, we error out
> >        * regardless of being 5.1 or newer.
> >        */
> > -    if (!ms->nvdimms_state->is_enabled && nvdimm_opt) {
> > +    if (!ms->nvdimms_state->is_enabled) {
> >           error_setg(errp, "nvdimm device found but 'nvdimm=off' was set");
> >           return false;
> >       }
> > 
> > if I didn't miss something, that way we do not abuse nvdimm_opt and still
> > have nvdimm enabled by default and error out if it turns to disabled for whatever reason.  
> 
> 
> Just tried this out. This doesn't disable the NVDIMM support when passing 'nvdimm=off'
> machine option.

that's not really working, but rather idea (spapr_machine_init is too late for the task).
I'll post a path that should do the job in a minute.

> 
> As far pseries NVDIMM support goes, we'll need patch 09 and to consider nvdimm_opt
> to keep the same behavior we already have today, like Paolo is already doing in
> this patch.
> 
> 
> 
> Thanks,
> 
> 
> DHB
> 
> > 
> >   
> >>       if (object_property_get_int(OBJECT(nvdimm), NVDIMM_LABEL_SIZE_PROP,
> >>                                   &error_abort) == 0) {  
> > [...]
> > 
> >   
> >   
> 



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

* [PATCH] ppc/spapr: cleanup -machine pseries,nvdimm=X handling
  2020-12-08  2:32     ` Daniel Henrique Barboza
  2020-12-08 10:55       ` Igor Mammedov
@ 2020-12-08 11:05       ` Igor Mammedov
  2020-12-08 16:46         ` [PATCH v2] " Igor Mammedov
  1 sibling, 1 reply; 50+ messages in thread
From: Igor Mammedov @ 2020-12-08 11:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: danielhb413, david

Since NVDIMM support was introduced on pseries machine,
it ignored machine's nvdimm=on|off option and effectively
was always enabled on machines that support NVDIMM.
Later on commit
  (28f5a716212 ppc/spapr_nvdimm: do not enable support with 'nvdimm=off')
makes QEMU error out in case user explicitly set 'nvdimm=off'
on CLI by peeking at machine_opts.

However that's a bit hacking and going away (in world where
machine configured over QMP) and it also leaves
  nvdimms_state->is_enabled
in inconsistent state (false) even when it should be set true
by default.

Instead of using on machine_opts, implement per machine
"nvdimm enabled" default handling and set default enabled value
at machine class init time (which is set to true for pseries)
and properly handle it generic machine code.
That way pseries will have, nvdimm enabled by default and
will honor user provided 'nvdimm=on|off'.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
PS:
Patch should be applied on top of:
  [PATCH 08/15] machine: introduce MachineInitPhase
---
 include/hw/boards.h   |  1 +
 hw/core/machine.c     |  1 +
 hw/ppc/spapr.c        |  8 ++++++++
 hw/ppc/spapr_nvdimm.c | 14 +-------------
 4 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/include/hw/boards.h b/include/hw/boards.h
index b9233af54a..1730f151aa 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -206,6 +206,7 @@ struct MachineClass {
     bool ignore_boot_device_suffixes;
     bool smbus_no_migration_support;
     bool nvdimm_supported;
+    bool nvdimm_enabled_default;
     bool numa_mem_supported;
     bool auto_enable_numa;
     const char *default_ram_id;
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 2c0bc15143..12f04bed58 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -893,6 +893,7 @@ static void machine_initfn(Object *obj)
         Object *obj = OBJECT(ms);
 
         ms->nvdimms_state = g_new0(NVDIMMState, 1);
+        ms->nvdimms_state->is_enabled = mc->nvdimm_enabled_default;
         object_property_add_bool(obj, "nvdimm",
                                  machine_get_nvdimm, machine_set_nvdimm);
         object_property_set_description(obj, "nvdimm",
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index b7e0894019..5a0cf79bbe 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -4413,6 +4413,14 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
     mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power9_v2.0");
     mc->has_hotpluggable_cpus = true;
     mc->nvdimm_supported = true;
+    /*
+     * NVDIMM support went live in 5.1 without considering that, in
+     * other archs, the user needs to enable NVDIMM support with the
+     * 'nvdimm' machine option and the default behavior is NVDIMM
+     * support disabled. It is too late to roll back to the standard
+     * behavior without breaking 5.1 guests.
+     */
+    mc->nvdimm_enabled_default = true;
     smc->resize_hpt_default = SPAPR_RESIZE_HPT_ENABLED;
     fwc->get_dev_path = spapr_get_fw_dev_path;
     nc->nmi_monitor_handler = spapr_nmi;
diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
index a833a63b5e..66cd3dc13f 100644
--- a/hw/ppc/spapr_nvdimm.c
+++ b/hw/ppc/spapr_nvdimm.c
@@ -27,10 +27,8 @@
 #include "hw/ppc/spapr_nvdimm.h"
 #include "hw/mem/nvdimm.h"
 #include "qemu/nvdimm-utils.h"
-#include "qemu/option.h"
 #include "hw/ppc/fdt.h"
 #include "qemu/range.h"
-#include "sysemu/sysemu.h"
 #include "hw/ppc/spapr_numa.h"
 
 bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
@@ -38,7 +36,6 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
 {
     const MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev);
     const MachineState *ms = MACHINE(hotplug_dev);
-    const char *nvdimm_opt = qemu_opt_get(qemu_get_machine_opts(), "nvdimm");
     g_autofree char *uuidstr = NULL;
     QemuUUID uuid;
     int ret;
@@ -48,16 +45,7 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
         return false;
     }
 
-    /*
-     * NVDIMM support went live in 5.1 without considering that, in
-     * other archs, the user needs to enable NVDIMM support with the
-     * 'nvdimm' machine option and the default behavior is NVDIMM
-     * support disabled. It is too late to roll back to the standard
-     * behavior without breaking 5.1 guests. What we can do is to
-     * ensure that, if the user sets nvdimm=off, we error out
-     * regardless of being 5.1 or newer.
-     */
-    if (!ms->nvdimms_state->is_enabled && nvdimm_opt) {
+    if (!ms->nvdimms_state->is_enabled) {
         error_setg(errp, "nvdimm device found but 'nvdimm=off' was set");
         return false;
     }
-- 
2.27.0



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

* Re: [PATCH 11/15] qtest: add a QOM object for qtest
  2020-12-07 17:22         ` Paolo Bonzini
@ 2020-12-08 11:11           ` Igor Mammedov
  0 siblings, 0 replies; 50+ messages in thread
From: Igor Mammedov @ 2020-12-08 11:11 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On Mon, 7 Dec 2020 18:22:55 +0100
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il lun 7 dic 2020, 17:57 Igor Mammedov <imammedo@redhat.com> ha scritto:
> 
> > On Mon, 7 Dec 2020 17:43:16 +0100
> > Paolo Bonzini <pbonzini@redhat.com> wrote:
> >  
> > > On 07/12/20 17:24, Igor Mammedov wrote:  
> > > >> +void qtest_server_init(const char *qtest_chrdev, const char  
> > *qtest_log, Error **errp)  
> > > >> +{
> > > >> +    Chardev *chr;
> > > >> +
> > > >> +    chr = qemu_chr_new("qtest", qtest_chrdev, NULL);
> > > >> +
> > > >> +    if (chr == NULL) {
> > > >> +        error_setg(errp, "Failed to initialize device for qtest:  
> > \"%s\"",  
> > > >> +                   qtest_chrdev);
> > > >> +        return;
> > > >> +    }
> > > >> +
> > > >> +    qtest_server_start(chr, qtest_log, errp);  
> > > > why not create qtest object here instead of trying to preserve old way,
> > > > or create it directly at the place that calls qtest_server_init()?  
> > >
> > > Because I wasn't sure of where to put it in the QOM object tree.  So I
> > > punted and left it for later.  
> >
> > but you implicitly decided where it should be (with -object qtest),
> > it goes to /objects.
> > So I'd wouldn't put anywhere else to be consistent.
> >  
> 
> No, /objects is for stuff created with -object exclusively. I suppose I
> could have the "well-known path" be /machine/qtest, and it would be either
> a child (for -qtest) or a link to /objects/some-id (for -object qtest).
> Should I implement that (as a separate patch on top of this one)?
yes

> 
> Paolo
> 
> 
> 
> > >
> > > Paolo
> > >  
> >
> >  



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

* [PATCH v2] ppc/spapr: cleanup -machine pseries,nvdimm=X handling
  2020-12-08 11:05       ` [PATCH] ppc/spapr: cleanup -machine pseries,nvdimm=X handling Igor Mammedov
@ 2020-12-08 16:46         ` Igor Mammedov
  2020-12-08 17:24           ` Daniel Henrique Barboza
  0 siblings, 1 reply; 50+ messages in thread
From: Igor Mammedov @ 2020-12-08 16:46 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, danielhb413, david

Since NVDIMM support was introduced on pseries machine,
it ignored machine's nvdimm=on|off option and effectively
was always enabled on machines that support NVDIMM.
Later on commit
  (28f5a716212 ppc/spapr_nvdimm: do not enable support with 'nvdimm=off')
makes QEMU error out in case user explicitly set 'nvdimm=off'
on CLI by peeking at machine_opts.

However that's a workaround and leaves 'nvdimms_state->is_enabled'
in inconsistent state (false) when it should be set true
by default.

Instead of using on machine_opts, set default to true for pseries
machine in initfn time. If user sets manually 'nvdimm=off'
it will overwrite default value to false and QEMU will error
as expected without need to peek into machine_opts.

That way pseries will have, nvdimm enabled by default and
will honor user provided 'nvdimm=on|off'.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
CC: danielhb413@gmail.com
CC: david@gibson.dropbear.id.au
CC: pbonzini@redhat.com

v2:
  - simplify a bit more by using spapr_instance_init() to set
    default value instead of doing it in generic machine code

PS:
Patch should be applied on top of:
  [PATCH 08/15] machine: introduce MachineInitPhase
---
 hw/ppc/spapr.c        | 13 +++++++++++++
 hw/ppc/spapr_nvdimm.c | 14 +-------------
 2 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index b7e0894019..803a6f52a2 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3267,6 +3267,19 @@ static void spapr_instance_init(Object *obj)
 {
     SpaprMachineState *spapr = SPAPR_MACHINE(obj);
     SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+    MachineState *ms = MACHINE(spapr);
+    MachineClass *mc = MACHINE_GET_CLASS(ms);
+
+    /*
+     * NVDIMM support went live in 5.1 without considering that, in
+     * other archs, the user needs to enable NVDIMM support with the
+     * 'nvdimm' machine option and the default behavior is NVDIMM
+     * support disabled. It is too late to roll back to the standard
+     * behavior without breaking 5.1 guests.
+     */
+    if (mc->nvdimm_supported) {
+        ms->nvdimms_state->is_enabled = true;
+    }
 
     spapr->htab_fd = -1;
     spapr->use_hotplug_event_source = true;
diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
index a833a63b5e..66cd3dc13f 100644
--- a/hw/ppc/spapr_nvdimm.c
+++ b/hw/ppc/spapr_nvdimm.c
@@ -27,10 +27,8 @@
 #include "hw/ppc/spapr_nvdimm.h"
 #include "hw/mem/nvdimm.h"
 #include "qemu/nvdimm-utils.h"
-#include "qemu/option.h"
 #include "hw/ppc/fdt.h"
 #include "qemu/range.h"
-#include "sysemu/sysemu.h"
 #include "hw/ppc/spapr_numa.h"
 
 bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
@@ -38,7 +36,6 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
 {
     const MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev);
     const MachineState *ms = MACHINE(hotplug_dev);
-    const char *nvdimm_opt = qemu_opt_get(qemu_get_machine_opts(), "nvdimm");
     g_autofree char *uuidstr = NULL;
     QemuUUID uuid;
     int ret;
@@ -48,16 +45,7 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
         return false;
     }
 
-    /*
-     * NVDIMM support went live in 5.1 without considering that, in
-     * other archs, the user needs to enable NVDIMM support with the
-     * 'nvdimm' machine option and the default behavior is NVDIMM
-     * support disabled. It is too late to roll back to the standard
-     * behavior without breaking 5.1 guests. What we can do is to
-     * ensure that, if the user sets nvdimm=off, we error out
-     * regardless of being 5.1 or newer.
-     */
-    if (!ms->nvdimms_state->is_enabled && nvdimm_opt) {
+    if (!ms->nvdimms_state->is_enabled) {
         error_setg(errp, "nvdimm device found but 'nvdimm=off' was set");
         return false;
     }
-- 
2.27.0



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

* Re: [PATCH v2] ppc/spapr: cleanup -machine pseries,nvdimm=X handling
  2020-12-08 16:46         ` [PATCH v2] " Igor Mammedov
@ 2020-12-08 17:24           ` Daniel Henrique Barboza
  2020-12-08 18:35             ` Igor Mammedov
  0 siblings, 1 reply; 50+ messages in thread
From: Daniel Henrique Barboza @ 2020-12-08 17:24 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel; +Cc: pbonzini, david



On 12/8/20 1:46 PM, Igor Mammedov wrote:
> Since NVDIMM support was introduced on pseries machine,
> it ignored machine's nvdimm=on|off option and effectively
> was always enabled on machines that support NVDIMM.
> Later on commit
>    (28f5a716212 ppc/spapr_nvdimm: do not enable support with 'nvdimm=off')
> makes QEMU error out in case user explicitly set 'nvdimm=off'
> on CLI by peeking at machine_opts.
> 
> However that's a workaround and leaves 'nvdimms_state->is_enabled'
> in inconsistent state (false) when it should be set true
> by default.
> 
> Instead of using on machine_opts, set default to true for pseries
> machine in initfn time. If user sets manually 'nvdimm=off'
> it will overwrite default value to false and QEMU will error
> as expected without need to peek into machine_opts.
> 
> That way pseries will have, nvdimm enabled by default and

nit: extra ',' here

> will honor user provided 'nvdimm=on|off'.

I believe it's plausible to add a:

Fixes: 28f5a716212 ("ppc/spapr_nvdimm: do not enable support with 'nvdimm=off'")

To indicate that this is amending my commit you mentioned up there.


> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---

Thanks for taking the time patching this up. Tested on top of Patch 08 in a
Power 9 host and it works as intended.

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Tested-by: Daniel Henrique Barboza <danielhb413@gmail.com>


ps: I'm assuming that that this is deprecating Paolo's patch:

"[PATCH 09/15] machine: record whether nvdimm= was set"

and also the chunks of Patch 10/15 that are changing spapr_nvdimm.c. If that's
not the case, let me know and I'll re-test.



Thanks,


DHB



> CC: danielhb413@gmail.com
> CC: david@gibson.dropbear.id.au
> CC: pbonzini@redhat.com
> 
> v2:
>    - simplify a bit more by using spapr_instance_init() to set
>      default value instead of doing it in generic machine code
> 
> PS:
> Patch should be applied on top of:
>    [PATCH 08/15] machine: introduce MachineInitPhase
> ---
>   hw/ppc/spapr.c        | 13 +++++++++++++
>   hw/ppc/spapr_nvdimm.c | 14 +-------------
>   2 files changed, 14 insertions(+), 13 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index b7e0894019..803a6f52a2 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -3267,6 +3267,19 @@ static void spapr_instance_init(Object *obj)
>   {
>       SpaprMachineState *spapr = SPAPR_MACHINE(obj);
>       SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
> +    MachineState *ms = MACHINE(spapr);
> +    MachineClass *mc = MACHINE_GET_CLASS(ms);
> +
> +    /*
> +     * NVDIMM support went live in 5.1 without considering that, in
> +     * other archs, the user needs to enable NVDIMM support with the
> +     * 'nvdimm' machine option and the default behavior is NVDIMM
> +     * support disabled. It is too late to roll back to the standard
> +     * behavior without breaking 5.1 guests.
> +     */
> +    if (mc->nvdimm_supported) {
> +        ms->nvdimms_state->is_enabled = true;
> +    }
>   
>       spapr->htab_fd = -1;
>       spapr->use_hotplug_event_source = true;
> diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
> index a833a63b5e..66cd3dc13f 100644
> --- a/hw/ppc/spapr_nvdimm.c
> +++ b/hw/ppc/spapr_nvdimm.c
> @@ -27,10 +27,8 @@
>   #include "hw/ppc/spapr_nvdimm.h"
>   #include "hw/mem/nvdimm.h"
>   #include "qemu/nvdimm-utils.h"
> -#include "qemu/option.h"
>   #include "hw/ppc/fdt.h"
>   #include "qemu/range.h"
> -#include "sysemu/sysemu.h"
>   #include "hw/ppc/spapr_numa.h"
>   
>   bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
> @@ -38,7 +36,6 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
>   {
>       const MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev);
>       const MachineState *ms = MACHINE(hotplug_dev);
> -    const char *nvdimm_opt = qemu_opt_get(qemu_get_machine_opts(), "nvdimm");
>       g_autofree char *uuidstr = NULL;
>       QemuUUID uuid;
>       int ret;
> @@ -48,16 +45,7 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
>           return false;
>       }
>   
> -    /*
> -     * NVDIMM support went live in 5.1 without considering that, in
> -     * other archs, the user needs to enable NVDIMM support with the
> -     * 'nvdimm' machine option and the default behavior is NVDIMM
> -     * support disabled. It is too late to roll back to the standard
> -     * behavior without breaking 5.1 guests. What we can do is to
> -     * ensure that, if the user sets nvdimm=off, we error out
> -     * regardless of being 5.1 or newer.
> -     */
> -    if (!ms->nvdimms_state->is_enabled && nvdimm_opt) {
> +    if (!ms->nvdimms_state->is_enabled) {
>           error_setg(errp, "nvdimm device found but 'nvdimm=off' was set");
>           return false;
>       }
> 


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

* Re: [PATCH v2] ppc/spapr: cleanup -machine pseries,nvdimm=X handling
  2020-12-08 17:24           ` Daniel Henrique Barboza
@ 2020-12-08 18:35             ` Igor Mammedov
  0 siblings, 0 replies; 50+ messages in thread
From: Igor Mammedov @ 2020-12-08 18:35 UTC (permalink / raw)
  To: Daniel Henrique Barboza; +Cc: pbonzini, qemu-devel, david

On Tue, 8 Dec 2020 14:24:22 -0300
Daniel Henrique Barboza <danielhb413@gmail.com> wrote:

> On 12/8/20 1:46 PM, Igor Mammedov wrote:
> > Since NVDIMM support was introduced on pseries machine,
> > it ignored machine's nvdimm=on|off option and effectively
> > was always enabled on machines that support NVDIMM.
> > Later on commit
> >    (28f5a716212 ppc/spapr_nvdimm: do not enable support with 'nvdimm=off')
> > makes QEMU error out in case user explicitly set 'nvdimm=off'
> > on CLI by peeking at machine_opts.
> > 
> > However that's a workaround and leaves 'nvdimms_state->is_enabled'
> > in inconsistent state (false) when it should be set true
> > by default.
> > 
> > Instead of using on machine_opts, set default to true for pseries
> > machine in initfn time. If user sets manually 'nvdimm=off'
> > it will overwrite default value to false and QEMU will error
> > as expected without need to peek into machine_opts.
> > 
> > That way pseries will have, nvdimm enabled by default and  
> 
> nit: extra ',' here
> 
> > will honor user provided 'nvdimm=on|off'.  
> 
> I believe it's plausible to add a:
> 
> Fixes: 28f5a716212 ("ppc/spapr_nvdimm: do not enable support with 'nvdimm=off'")
> 
> To indicate that this is amending my commit you mentioned up there.
> 
> 
> > 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---  
> 
> Thanks for taking the time patching this up. Tested on top of Patch 08 in a
> Power 9 host and it works as intended.
> 
> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
> Tested-by: Daniel Henrique Barboza <danielhb413@gmail.com>
> 
> 
> ps: I'm assuming that that this is deprecating Paolo's patch:
> 
> "[PATCH 09/15] machine: record whether nvdimm= was set"
> 
> and also the chunks of Patch 10/15 that are changing spapr_nvdimm.c. If that's
> not the case, let me know and I'll re-test.

yes, it does deprecate those.
And it is based on this series, so I'd expect Paolo to incorporate it,
to avoid churn/conflicts.

> 
> 
> 
> Thanks,
> 
> 
> DHB
> 
> 
> 
> > CC: danielhb413@gmail.com
> > CC: david@gibson.dropbear.id.au
> > CC: pbonzini@redhat.com
> > 
> > v2:
> >    - simplify a bit more by using spapr_instance_init() to set
> >      default value instead of doing it in generic machine code
> > 
> > PS:
> > Patch should be applied on top of:
> >    [PATCH 08/15] machine: introduce MachineInitPhase
> > ---
> >   hw/ppc/spapr.c        | 13 +++++++++++++
> >   hw/ppc/spapr_nvdimm.c | 14 +-------------
> >   2 files changed, 14 insertions(+), 13 deletions(-)
> > 
> > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > index b7e0894019..803a6f52a2 100644
> > --- a/hw/ppc/spapr.c
> > +++ b/hw/ppc/spapr.c
> > @@ -3267,6 +3267,19 @@ static void spapr_instance_init(Object *obj)
> >   {
> >       SpaprMachineState *spapr = SPAPR_MACHINE(obj);
> >       SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
> > +    MachineState *ms = MACHINE(spapr);
> > +    MachineClass *mc = MACHINE_GET_CLASS(ms);
> > +
> > +    /*
> > +     * NVDIMM support went live in 5.1 without considering that, in
> > +     * other archs, the user needs to enable NVDIMM support with the
> > +     * 'nvdimm' machine option and the default behavior is NVDIMM
> > +     * support disabled. It is too late to roll back to the standard
> > +     * behavior without breaking 5.1 guests.
> > +     */
> > +    if (mc->nvdimm_supported) {
> > +        ms->nvdimms_state->is_enabled = true;
> > +    }
> >   
> >       spapr->htab_fd = -1;
> >       spapr->use_hotplug_event_source = true;
> > diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c
> > index a833a63b5e..66cd3dc13f 100644
> > --- a/hw/ppc/spapr_nvdimm.c
> > +++ b/hw/ppc/spapr_nvdimm.c
> > @@ -27,10 +27,8 @@
> >   #include "hw/ppc/spapr_nvdimm.h"
> >   #include "hw/mem/nvdimm.h"
> >   #include "qemu/nvdimm-utils.h"
> > -#include "qemu/option.h"
> >   #include "hw/ppc/fdt.h"
> >   #include "qemu/range.h"
> > -#include "sysemu/sysemu.h"
> >   #include "hw/ppc/spapr_numa.h"
> >   
> >   bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
> > @@ -38,7 +36,6 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
> >   {
> >       const MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev);
> >       const MachineState *ms = MACHINE(hotplug_dev);
> > -    const char *nvdimm_opt = qemu_opt_get(qemu_get_machine_opts(), "nvdimm");
> >       g_autofree char *uuidstr = NULL;
> >       QemuUUID uuid;
> >       int ret;
> > @@ -48,16 +45,7 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
> >           return false;
> >       }
> >   
> > -    /*
> > -     * NVDIMM support went live in 5.1 without considering that, in
> > -     * other archs, the user needs to enable NVDIMM support with the
> > -     * 'nvdimm' machine option and the default behavior is NVDIMM
> > -     * support disabled. It is too late to roll back to the standard
> > -     * behavior without breaking 5.1 guests. What we can do is to
> > -     * ensure that, if the user sets nvdimm=off, we error out
> > -     * regardless of being 5.1 or newer.
> > -     */
> > -    if (!ms->nvdimms_state->is_enabled && nvdimm_opt) {
> > +    if (!ms->nvdimms_state->is_enabled) {
> >           error_setg(errp, "nvdimm device found but 'nvdimm=off' was set");
> >           return false;
> >       }
> >   
> 



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

* Re: [PATCH 14/15] null-machine: do not create a default memdev
  2020-12-07 16:43   ` Igor Mammedov
@ 2020-12-11 23:24     ` Paolo Bonzini
  2020-12-14 11:53       ` Igor Mammedov
  0 siblings, 1 reply; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-11 23:24 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: qemu-devel

On 07/12/20 17:43, Igor Mammedov wrote:
>>       mc->default_ram_size = 0;
>> -    mc->default_ram_id = "ram";
>> +    mc->default_ram_id = NULL;
> probably that will break:
> 
>   QEMU -m X -M none

No, it works.  "-m" is simply ignored, because the default memdev is 
created here:

     if (machine_class->default_ram_id && current_machine->ram_size &&
         numa_uses_legacy_mem() && !current_machine->ram_memdev_id) {
         create_default_memdev(current_machine, mem_path);
     }

and is thus skipped for -M none.

Paolo

> 
> maybe there is  a bug over there but
>      "mc->default_ram_size = 0"
> above, should result in
>      current_machine->ram_size == 0
> in case user hasn't provided "-m"
> and hence memdev shouldn't be created
> 



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

* Re: [PATCH 14/15] null-machine: do not create a default memdev
  2020-12-11 23:24     ` Paolo Bonzini
@ 2020-12-14 11:53       ` Igor Mammedov
  2020-12-14 13:24         ` Paolo Bonzini
  0 siblings, 1 reply; 50+ messages in thread
From: Igor Mammedov @ 2020-12-14 11:53 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On Sat, 12 Dec 2020 00:24:25 +0100
Paolo Bonzini <pbonzini@redhat.com> wrote:

> On 07/12/20 17:43, Igor Mammedov wrote:
> >>       mc->default_ram_size = 0;
> >> -    mc->default_ram_id = "ram";
> >> +    mc->default_ram_id = NULL;  
> > probably that will break:
> > 
> >   QEMU -m X -M none  
> 
> No, it works.  "-m" is simply ignored, because the default memdev is 
> created here:
you mean it doesn't explode.
By default with current code memdev should not be created, 
but it is created if users asks for it with -m.
This patch breaks the later.

I'm not sure that any RAM on null machine is of any use at all
but the if we decide to get rid of it completely, then we need
to clean up
    /* RAM at address zero */                                                    
    if (mch->ram) {                                                              
        memory_region_add_subregion(get_system_memory(), 0, mch->ram);           
    }   
and commit title/message should match what patch does and why.


>      if (machine_class->default_ram_id && current_machine->ram_size &&
>          numa_uses_legacy_mem() && !current_machine->ram_memdev_id) {
>          create_default_memdev(current_machine, mem_path);
>      }
> 
> and is thus skipped for -M none.
> 
> Paolo
> 
> > 
> > maybe there is  a bug over there but
> >      "mc->default_ram_size = 0"
> > above, should result in
> >      current_machine->ram_size == 0
> > in case user hasn't provided "-m"
> > and hence memdev shouldn't be created
> >   
> 



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

* Re: [PATCH 14/15] null-machine: do not create a default memdev
  2020-12-14 11:53       ` Igor Mammedov
@ 2020-12-14 13:24         ` Paolo Bonzini
  0 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2020-12-14 13:24 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: qemu-devel

On 14/12/20 12:53, Igor Mammedov wrote:
> On Sat, 12 Dec 2020 00:24:25 +0100
> Paolo Bonzini <pbonzini@redhat.com> wrote:
> 
>> On 07/12/20 17:43, Igor Mammedov wrote:
>>>>        mc->default_ram_size = 0;
>>>> -    mc->default_ram_id = "ram";
>>>> +    mc->default_ram_id = NULL;
>>> probably that will break:
>>>
>>>    QEMU -m X -M none
>>
>> No, it works.  "-m" is simply ignored, because the default memdev is
>> created here:
> you mean it doesn't explode.
> By default with current code memdev should not be created,
> but it is created if users asks for it with -m.

Oh ok, got it.  I'll leave this patch aside for now and later, when I 
get round to posting the ram_memdev_id cleanup, try to remember why I 
added it.

> I'm not sure that any RAM on null machine is of any use at all
> but the if we decide to get rid of it completely, then we need
> to clean up
>      /* RAM at address zero */
>      if (mch->ram) {
>          memory_region_add_subregion(get_system_memory(), 0, mch->ram);
>      }

This would still be needed because you _can_ get a non-null mch->ram 
(via "-M memdev") even if mc->default_ram_id == NULL.

Paolo

> and commit title/message should match what patch does and why.
> 
> 
>>       if (machine_class->default_ram_id && current_machine->ram_size &&
>>           numa_uses_legacy_mem() && !current_machine->ram_memdev_id) {
>>           create_default_memdev(current_machine, mem_path);
>>       }
>>
>> and is thus skipped for -M none.
>>
>> Paolo
>>
>>>
>>> maybe there is  a bug over there but
>>>       "mc->default_ram_size = 0"
>>> above, should result in
>>>       current_machine->ram_size == 0
>>> in case user hasn't provided "-m"
>>> and hence memdev shouldn't be created
>>>    
>>
> 



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

end of thread, other threads:[~2020-12-14 13:26 UTC | newest]

Thread overview: 50+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-02  8:18 [PATCH 00/15] Finish cleaning up qemu_init Paolo Bonzini
2020-12-02  8:18 ` [PATCH 01/15] remove preconfig state Paolo Bonzini
2020-12-07 13:57   ` Igor Mammedov
2020-12-07 14:11     ` Paolo Bonzini
2020-12-07 15:14       ` Igor Mammedov
2020-12-02  8:18 ` [PATCH 02/15] vl: remove separate preconfig main_loop Paolo Bonzini
2020-12-07 14:02   ` Igor Mammedov
2020-12-02  8:18 ` [PATCH 03/15] vl: allow -incoming defer with -preconfig Paolo Bonzini
2020-12-02  8:18 ` [PATCH 04/15] vl: extract softmmu/runstate.c Paolo Bonzini
2020-12-02  8:18 ` [PATCH 05/15] vl: extract softmmu/globals.c Paolo Bonzini
2020-12-02  8:18 ` [PATCH 06/15] vl: move all generic initialization out of vl.c Paolo Bonzini
2020-12-07 14:19   ` Igor Mammedov
2020-12-02  8:18 ` [PATCH 07/15] chardev: do not use machine_init_done Paolo Bonzini
2020-12-07 15:15   ` Igor Mammedov
2020-12-02  8:18 ` [PATCH 08/15] machine: introduce MachineInitPhase Paolo Bonzini
2020-12-07 15:28   ` Igor Mammedov
2020-12-02  8:18 ` [PATCH 09/15] machine: record whether nvdimm= was set Paolo Bonzini
2020-12-07 15:40   ` Igor Mammedov
2020-12-02  8:18 ` [PATCH 10/15] vl: make qemu_get_machine_opts static Paolo Bonzini
2020-12-07 16:07   ` Igor Mammedov
2020-12-07 16:38     ` Paolo Bonzini
2020-12-08  2:32     ` Daniel Henrique Barboza
2020-12-08 10:55       ` Igor Mammedov
2020-12-08 11:05       ` [PATCH] ppc/spapr: cleanup -machine pseries,nvdimm=X handling Igor Mammedov
2020-12-08 16:46         ` [PATCH v2] " Igor Mammedov
2020-12-08 17:24           ` Daniel Henrique Barboza
2020-12-08 18:35             ` Igor Mammedov
2020-12-08  2:16   ` [PATCH 10/15] vl: make qemu_get_machine_opts static Daniel Henrique Barboza
2020-12-08  8:13     ` Paolo Bonzini
2020-12-02  8:18 ` [PATCH 11/15] qtest: add a QOM object for qtest Paolo Bonzini
2020-12-07 16:24   ` Igor Mammedov
2020-12-07 16:43     ` Paolo Bonzini
2020-12-07 16:57       ` Igor Mammedov
2020-12-07 17:22         ` Paolo Bonzini
2020-12-08 11:11           ` Igor Mammedov
2020-12-02  8:18 ` [PATCH 12/15] plugin: propagate errors Paolo Bonzini
2020-12-02 11:33   ` Alex Bennée
2020-12-07 16:53   ` Igor Mammedov
2020-12-02  8:18 ` [PATCH 13/15] memory: allow creating MemoryRegions before accelerators Paolo Bonzini
2020-12-07 16:38   ` Igor Mammedov
2020-12-07 16:40     ` Paolo Bonzini
2020-12-07 17:06   ` Igor Mammedov
2020-12-02  8:18 ` [PATCH 14/15] null-machine: do not create a default memdev Paolo Bonzini
2020-12-07 16:43   ` Igor Mammedov
2020-12-11 23:24     ` Paolo Bonzini
2020-12-14 11:53       ` Igor Mammedov
2020-12-14 13:24         ` Paolo Bonzini
2020-12-02  8:18 ` [PATCH 15/15] monitor: allow quitting while in preconfig state Paolo Bonzini
2020-12-07 16:45   ` Igor Mammedov
2020-12-07 14:12 ` [PATCH 00/15] Finish cleaning up qemu_init no-reply

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.