Skip to contentSkip to conversation

Replace has_dynamic_sysbus with device type whitelist

RFC In review Eduardo Habkost 4 participants 14 messages Mar 23, 2017 – Mar 24, 2017

lore
Share & tools
lore
#0 lore raw

cover Replace has_dynamic_sysbus with device type whitelist

Summary
-------

This series replaces the existing has_dynamic_sysbus flag (that makes the machine accept every single sysbus device type on the command-line) with a short whitelist.

This will be helpful when implementing the new query-device-slots command, because each machine type will include only the sysbus devices it really supports, instead of including a catch-all TYPE_SYS_BUS_DEVICE "slot".

Most of the machines already have an internal whitelist implemented using foreach_dynamic_sysbus_device(), so we just encode the existing behavior inside the new MachineClass field.

Caveat: q35
-----------

The only problematic case is q35, that accepts all sysbus device types. In this case, instead of adding TYPE_SYS_BUS_DEVICE to the whitelist, I'm adding the existing list of existing sysbus device types to keep compatibility. After that, we can gradually and carefully remove unnecessary entries from the q35 whitelist.

Issue: xen_set_dynamic_sysbus() hack
------------------------------------

We still have an obstacle to get around: the callers of qdev_set_id() outside qdev_device_add() are breaking foreach_dynamic_sysbus_device(), and xen_set_dynamic_sysbus() is a workaround for that bug. We now need to fix that bug to be able to remove the xen_set_dynamic_sysbus() hack. This means the first patch of this series will probably break Xen, until we fix that bug.

Eduardo Habkost (4):
[UNTESTED] xen: Don't force has_dynamic_sysbus on machine class
machine: Replace has_dynamic_sysbus with a whitelist
q35: Remove ioapic devices from sysbus whitelist
q35: Remove fw_cfg* from sysbus whitelist

 include/hw/arm/sysbus-fdt.h |  7 +++++++
 include/hw/boards.h         |  3 ++-
 hw/arm/sysbus-fdt.c         | 10 ++++++++++
 hw/arm/virt.c               |  4 +++-
 hw/core/machine.c           | 43 +++++++++++++++++++++++++++++--------------
 hw/i386/pc_q35.c            | 25 ++++++++++++++++++++++++-
 hw/ppc/e500plat.c           |  4 +++-
 hw/ppc/spapr.c              |  2 +-
 hw/xen/xen_backend.c        | 11 -----------
 9 files changed, 79 insertions(+), 30 deletions(-)
Signature · 1 line
2.11.0.259.g40922b1
#1 lore raw

RFC 1/4 xen: Don't force has_dynamic_sysbus on machine class

The xen-backend devices created by the Xen code are not supposed to be treated as dynamic sysbus devices. This is an attempt to change that and see what happens, but I couldn't test it because I don't have a Xen host set up.

If this patch breaks anything, this means we have a bug in foreach_dynamic_sysbus_device(), which is supposed to return only devices created using -device.

The original code that sets has_dynamic_sysbus was added by commit 3a6c9172ac5951e6dac2b3f6cbce3cfccdec5894, but I don't see any comment explaining why it was necessary.

Cc Juergen Gross <[email protected]>
Cc Stefano Stabellini <[email protected]>
---
 hw/xen/xen_backend.c | 11 -----------
 1 file changed, 11 deletions(-)
hw/xen/xen_backend.c +0 -11
index 6c21c37d68..4607d6d3ee 100644
@@ -550,15 +550,6 @@ err:
     return -1;
 }
 
-static void xen_set_dynamic_sysbus(void)
-{
-    Object *machine = qdev_get_machine();
-    ObjectClass *oc = object_get_class(machine);
-    MachineClass *mc = MACHINE_CLASS(oc);
-
-    mc->has_dynamic_sysbus = true;
-}
-
 int xen_be_register(const char *type, struct XenDevOps *ops)
 {
     char path[50];
@@ -580,8 +571,6 @@ int xen_be_register(const char *type, struct XenDevOps *ops)
 
 void xen_be_register_common(void)
 {
-    xen_set_dynamic_sysbus();
-
     xen_be_register("console", &xen_console_ops);
     xen_be_register("vkbd", &xen_kbdmouse_ops);
     xen_be_register("qdisk", &xen_blkdev_ops);
Signature · 1 line
2.11.0.259.g40922b1
#2 lore raw

Re: [Qemu-devel] [RFC 1/4] [UNTESTED] xen: Don't force has_dynamic_sysbus on machine class

Quoted 5 lines · Eduardo Habkost

The xen-backend devices created by the Xen code are not supposed to be treated as dynamic sysbus devices. This is an attempt to change that and see what happens, but I couldn't test it because I don't have a Xen host set up.

Quoted 7 lines

If this patch breaks anything, this means we have a bug in foreach_dynamic_sysbus_device(), which is supposed to return only devices created using -device.

The original code that sets has_dynamic_sysbus was added by commit 3a6c9172ac5951e6dac2b3f6cbce3cfccdec5894, but I don't see any comment explaining why it was necessary.

xen-backend devices are created via qmp commands when attaching new pv-devices to a domain. They can be dynamically removed, too. Setting has_dynamic_sysbus was necessary to support this feature.

So just removing it will break Xen.

NAK as a standalone patch.

Juergen

Quoted 38 lines
Cc Juergen Gross <[email protected]>
Cc Stefano Stabellini <[email protected]>
---
 hw/xen/xen_backend.c | 11 -----------
 1 file changed, 11 deletions(-)
hw/xen/xen_backend.c +0 -11
index 6c21c37d68..4607d6d3ee 100644
@@ -550,15 +550,6 @@ err:
     return -1;
 }
 
-static void xen_set_dynamic_sysbus(void)
-{
-    Object *machine = qdev_get_machine();
-    ObjectClass *oc = object_get_class(machine);
-    MachineClass *mc = MACHINE_CLASS(oc);
-
-    mc->has_dynamic_sysbus = true;
-}
-
 int xen_be_register(const char *type, struct XenDevOps *ops)
 {
     char path[50];
@@ -580,8 +571,6 @@ int xen_be_register(const char *type, struct XenDevOps *ops)
 
 void xen_be_register_common(void)
 {
-    xen_set_dynamic_sysbus();
-
     xen_be_register("console", &xen_console_ops);
     xen_be_register("vkbd", &xen_kbdmouse_ops);
     xen_be_register("qdisk", &xen_blkdev_ops);
#3 lore raw

Re: [Qemu-devel] [RFC 1/4] [UNTESTED] xen: Don't force has_dynamic_sysbus on machine class

Quoted 10 lines · Juergen Gross
Quoted 9 lines · Eduardo Habkost

The xen-backend devices created by the Xen code are not supposed to be treated as dynamic sysbus devices. This is an attempt to change that and see what happens, but I couldn't test it because I don't have a Xen host set up.

If this patch breaks anything, this means we have a bug in foreach_dynamic_sysbus_device(), which is supposed to return only devices created using -device.

Quoted 7 lines
Quoted 3 lines

The original code that sets has_dynamic_sysbus was added by commit 3a6c9172ac5951e6dac2b3f6cbce3cfccdec5894, but I don't see any comment explaining why it was necessary.

xen-backend devices are created via qmp commands when attaching new pv-devices to a domain. They can be dynamically removed, too. Setting has_dynamic_sysbus was necessary to support this feature.

This seems like it ought to be handled by marking the xen-backend devices as being ok-to-dynamically-create somehow, not by marking the machine as supporting dynamic-sysbus (which it doesn't). Maybe we don't have the necessary support code to do that though?

thanks
-- PMM

#4 lore raw

Re: [Qemu-devel] [RFC 1/4] [UNTESTED] xen: Don't force has_dynamic_sysbus on machine class

Quoted 15 lines · Peter Maydell
Quoted 14 lines · Juergen Gross
Quoted 12 lines · Eduardo Habkost

The xen-backend devices created by the Xen code are not supposed to be treated as dynamic sysbus devices. This is an attempt to change that and see what happens, but I couldn't test it because I don't have a Xen host set up.

If this patch breaks anything, this means we have a bug in foreach_dynamic_sysbus_device(), which is supposed to return only devices created using -device.

The original code that sets has_dynamic_sysbus was added by commit 3a6c9172ac5951e6dac2b3f6cbce3cfccdec5894, but I don't see any comment explaining why it was necessary.

Quoted 8 lines
Quoted 3 lines

xen-backend devices are created via qmp commands when attaching new pv-devices to a domain. They can be dynamically removed, too. Setting has_dynamic_sysbus was necessary to support this feature.

This seems like it ought to be handled by marking the xen-backend devices as being ok-to-dynamically-create somehow, not by marking the machine as supporting dynamic-sysbus (which it doesn't). Maybe we don't have the necessary support code to do that though?

When writing the patches I couldn't find a way to do it differently. OTOH I'm not so deep in qemu internals I'd be able to add the needed support.

I'd be happy to test any patch, though.

Juergen

#5 lore raw

Re: [Qemu-devel] [RFC 1/4] [UNTESTED] xen: Don't force has_dynamic_sysbus on machine class

Quoted 25 lines · Juergen Gross
Quoted 15 lines · Peter Maydell
Quoted 14 lines · Juergen Gross
Quoted 12 lines · Eduardo Habkost

The xen-backend devices created by the Xen code are not supposed to be treated as dynamic sysbus devices. This is an attempt to change that and see what happens, but I couldn't test it because I don't have a Xen host set up.

If this patch breaks anything, this means we have a bug in foreach_dynamic_sysbus_device(), which is supposed to return only devices created using -device.

The original code that sets has_dynamic_sysbus was added by commit 3a6c9172ac5951e6dac2b3f6cbce3cfccdec5894, but I don't see any comment explaining why it was necessary.

Quoted 8 lines
Quoted 3 lines

xen-backend devices are created via qmp commands when attaching new pv-devices to a domain. They can be dynamically removed, too. Setting has_dynamic_sysbus was necessary to support this feature.

This seems like it ought to be handled by marking the xen-backend devices as being ok-to-dynamically-create somehow, not by marking the machine as supporting dynamic-sysbus (which it doesn't). Maybe we don't have the necessary support code to do that though?

Quoted 5 lines

When writing the patches I couldn't find a way to do it differently. OTOH I'm not so deep in qemu internals I'd be able to add the needed support.

I'd be happy to test any patch, though.

If xen-backend devices are created via QMP commands, then has_dynamic_sysbus is (currently) really needed, although I would have preferred to set it on all x86 machines instead of changing MachineClass::has_dynamic_sysbus outside class_init.

But with the new whitelist implemented by this series, we could simply include xen-backend in the whitelist for the machines that can be used with Xen, and get rid of xen_set_dynamic_sysbus().

I assume plugging/unplugging xen-backend devices apply to both xen{pv,fv} and pc,accel=xen, right? Do we need to make it work with "-machine none,accel=xen" and "-machine isapc" too?

Signature · 1 line
Eduardo
#6 lore raw

Re: [Qemu-devel] [RFC 1/4] [UNTESTED] xen: Don't force has_dynamic_sysbus on machine class

Quoted 37 lines · Eduardo Habkost
Quoted 25 lines · Juergen Gross
Quoted 15 lines · Peter Maydell
Quoted 14 lines · Juergen Gross
Quoted 12 lines · Eduardo Habkost

The xen-backend devices created by the Xen code are not supposed to be treated as dynamic sysbus devices. This is an attempt to change that and see what happens, but I couldn't test it because I don't have a Xen host set up.

If this patch breaks anything, this means we have a bug in foreach_dynamic_sysbus_device(), which is supposed to return only devices created using -device.

The original code that sets has_dynamic_sysbus was added by commit 3a6c9172ac5951e6dac2b3f6cbce3cfccdec5894, but I don't see any comment explaining why it was necessary.

Quoted 8 lines
Quoted 3 lines

xen-backend devices are created via qmp commands when attaching new pv-devices to a domain. They can be dynamically removed, too. Setting has_dynamic_sysbus was necessary to support this feature.

This seems like it ought to be handled by marking the xen-backend devices as being ok-to-dynamically-create somehow, not by marking the machine as supporting dynamic-sysbus (which it doesn't). Maybe we don't have the necessary support code to do that though?

Quoted 5 lines

When writing the patches I couldn't find a way to do it differently. OTOH I'm not so deep in qemu internals I'd be able to add the needed support.

I'd be happy to test any patch, though.

If xen-backend devices are created via QMP commands, then has_dynamic_sysbus is (currently) really needed, although I would have preferred to set it on all x86 machines instead of changing MachineClass::has_dynamic_sysbus outside class_init.

Quoted 7 lines

But with the new whitelist implemented by this series, we could simply include xen-backend in the whitelist for the machines that can be used with Xen, and get rid of xen_set_dynamic_sysbus().

I assume plugging/unplugging xen-backend devices apply to both xen{pv,fv} and pc,accel=xen, right? Do we need to make it work with "-machine none,accel=xen" and "-machine isapc" too?

AFAIK -xenpv, -xenfv and -pc,accel=xen are the only machine types to support. Wouldn't it make sense to do the whitelisting in xen_be_register_common() in spite of setting has_dynamic_sysbus?

Juergen

#7 lore raw

Re: [Qemu-devel] [RFC 1/4] [UNTESTED] xen: Don't force has_dynamic_sysbus on machine class

Quoted 42 lines · Juergen Gross
Quoted 41 lines · Eduardo Habkost
Quoted 25 lines · Juergen Gross
Quoted 15 lines · Peter Maydell
Quoted 14 lines · Juergen Gross
Quoted 12 lines · Eduardo Habkost

The xen-backend devices created by the Xen code are not supposed to be treated as dynamic sysbus devices. This is an attempt to change that and see what happens, but I couldn't test it because I don't have a Xen host set up.

If this patch breaks anything, this means we have a bug in foreach_dynamic_sysbus_device(), which is supposed to return only devices created using -device.

The original code that sets has_dynamic_sysbus was added by commit 3a6c9172ac5951e6dac2b3f6cbce3cfccdec5894, but I don't see any comment explaining why it was necessary.

Quoted 8 lines
Quoted 3 lines

xen-backend devices are created via qmp commands when attaching new pv-devices to a domain. They can be dynamically removed, too. Setting has_dynamic_sysbus was necessary to support this feature.

This seems like it ought to be handled by marking the xen-backend devices as being ok-to-dynamically-create somehow, not by marking the machine as supporting dynamic-sysbus (which it doesn't). Maybe we don't have the necessary support code to do that though?

Quoted 5 lines

When writing the patches I couldn't find a way to do it differently. OTOH I'm not so deep in qemu internals I'd be able to add the needed support.

I'd be happy to test any patch, though.

If xen-backend devices are created via QMP commands, then has_dynamic_sysbus is (currently) really needed, although I would have preferred to set it on all x86 machines instead of changing MachineClass::has_dynamic_sysbus outside class_init.

But with the new whitelist implemented by this series, we could simply include xen-backend in the whitelist for the machines that can be used with Xen, and get rid of xen_set_dynamic_sysbus().

Quoted 7 lines
Quoted 3 lines

I assume plugging/unplugging xen-backend devices apply to both xen{pv,fv} and pc,accel=xen, right? Do we need to make it work with "-machine none,accel=xen" and "-machine isapc" too?

AFAIK -xenpv, -xenfv and -pc,accel=xen are the only machine types to support. Wouldn't it make sense to do the whitelisting in xen_be_register_common() in spite of setting has_dynamic_sysbus?

It would, but that would mean we would make the whitelisting mechanism more complex: in addition to the static per-machine-class whitelist, we would need a runtime whitelist.

This would make the interface for querying available/supported device types more complex and messier, and I would like to avoid that.

Signature · 1 line
Eduardo
#8 lore raw

Re: [Qemu-devel] [RFC 1/4] [UNTESTED] xen: Don't force has_dynamic_sysbus on machine class

Quoted 51 lines · Eduardo Habkost
Quoted 42 lines · Juergen Gross
Quoted 41 lines · Eduardo Habkost
Quoted 25 lines · Juergen Gross
Quoted 15 lines · Peter Maydell
Quoted 14 lines · Juergen Gross
Quoted 12 lines · Eduardo Habkost

The xen-backend devices created by the Xen code are not supposed to be treated as dynamic sysbus devices. This is an attempt to change that and see what happens, but I couldn't test it because I don't have a Xen host set up.

If this patch breaks anything, this means we have a bug in foreach_dynamic_sysbus_device(), which is supposed to return only devices created using -device.

The original code that sets has_dynamic_sysbus was added by commit 3a6c9172ac5951e6dac2b3f6cbce3cfccdec5894, but I don't see any comment explaining why it was necessary.

Quoted 8 lines
Quoted 3 lines

xen-backend devices are created via qmp commands when attaching new pv-devices to a domain. They can be dynamically removed, too. Setting has_dynamic_sysbus was necessary to support this feature.

This seems like it ought to be handled by marking the xen-backend devices as being ok-to-dynamically-create somehow, not by marking the machine as supporting dynamic-sysbus (which it doesn't). Maybe we don't have the necessary support code to do that though?

Quoted 5 lines

When writing the patches I couldn't find a way to do it differently. OTOH I'm not so deep in qemu internals I'd be able to add the needed support.

I'd be happy to test any patch, though.

If xen-backend devices are created via QMP commands, then has_dynamic_sysbus is (currently) really needed, although I would have preferred to set it on all x86 machines instead of changing MachineClass::has_dynamic_sysbus outside class_init.

But with the new whitelist implemented by this series, we could simply include xen-backend in the whitelist for the machines that can be used with Xen, and get rid of xen_set_dynamic_sysbus().

Quoted 7 lines
Quoted 3 lines

I assume plugging/unplugging xen-backend devices apply to both xen{pv,fv} and pc,accel=xen, right? Do we need to make it work with "-machine none,accel=xen" and "-machine isapc" too?

AFAIK -xenpv, -xenfv and -pc,accel=xen are the only machine types to support. Wouldn't it make sense to do the whitelisting in xen_be_register_common() in spite of setting has_dynamic_sysbus?

Quoted 8 lines

It would, but that would mean we would make the whitelisting mechanism more complex: in addition to the static per-machine-class whitelist, we would need a runtime whitelist.

This would make the interface for querying available/supported device types more complex and messier, and I would like to avoid that.

Okay, understood. And I suppose you don't want to add the Xen devices to the per-machine-class whitelist (after all my patch did the same with the has_dynamic_sysbus flag) on demand.

Either way is fine with me.

Juergen

#9 lore raw

Re: [Qemu-devel] [RFC 1/4] [UNTESTED] xen: Don't force has_dynamic_sysbus on machine class

In reply to Peter Maydell
Quoted 15 lines · Peter Maydell
Quoted 14 lines · Juergen Gross
Quoted 12 lines · Eduardo Habkost

The xen-backend devices created by the Xen code are not supposed to be treated as dynamic sysbus devices. This is an attempt to change that and see what happens, but I couldn't test it because I don't have a Xen host set up.

If this patch breaks anything, this means we have a bug in foreach_dynamic_sysbus_device(), which is supposed to return only devices created using -device.

The original code that sets has_dynamic_sysbus was added by commit 3a6c9172ac5951e6dac2b3f6cbce3cfccdec5894, but I don't see any comment explaining why it was necessary.

Quoted 8 lines
Quoted 3 lines

xen-backend devices are created via qmp commands when attaching new pv-devices to a domain. They can be dynamically removed, too. Setting has_dynamic_sysbus was necessary to support this feature.

This seems like it ought to be handled by marking the xen-backend devices as being ok-to-dynamically-create somehow, not by marking the machine as supporting dynamic-sysbus (which it doesn't). Maybe we don't have the necessary support code to do that though?

Do the xen devices have to be sysbus devices? If no, I think you could change them to be of type TYPE_DEVICE nowadays - TYPE_DEVICE can be instantiated with "-device" nowadays, too. That's what we do with the spapr-rng device for example (see hw/ppc/spapr_rng.c).

Thomas

#10 lore raw

RFC 2/4 machine: Replace has_dynamic_sysbus with a whitelist

In reply to Eduardo Habkost

Replace the existing has_dynamic_sysbus flag, that makes the machine accept every single sysbus device type on the command-line, with a short whitelist.

Most of the machines already have an internal whitelist implemented using foreach_dynamic_sysbus_device(), so we just encode the existing behavior inside the new MachineClass field.

The only problematic case is q35, that accepts all sysbus device types. In this case, instad of adding TYPE_SYS_BUS_DEVICE to the whitelist, add the existing list of existing sysbus device types to keep compatibility. After that, we can gradually and carefully remove unnecessary entries from the q35 whitelist.

---
 include/hw/arm/sysbus-fdt.h |  7 +++++++
 include/hw/boards.h         |  3 ++-
 hw/arm/sysbus-fdt.c         | 10 ++++++++++
 hw/arm/virt.c               |  4 +++-
 hw/core/machine.c           | 43 +++++++++++++++++++++++++++++--------------
 hw/i386/pc_q35.c            | 29 ++++++++++++++++++++++++++++-
 hw/ppc/e500plat.c           |  4 +++-
 hw/ppc/spapr.c              |  2 +-
 8 files changed, 83 insertions(+), 19 deletions(-)
include/hw/arm/sysbus-fdt.h +7 -0
index e15bb81807..071124e13d 100644
@@ -57,4 +57,11 @@ typedef struct {
  */
 void arm_register_platform_bus_fdt_creator(ARMPlatformBusFDTParams *fdt_params);
 
+/**
+ * arm_register_fdt_sysbus_whitelist - register supported sysbus device types
+ *
+ * Add supported dynamic sysbus device types to machine class.
+ */
+void arm_register_fdt_sysbus_whitelist(MachineClass *mc);
+
 #endif
include/hw/boards.h +2 -1
index 269d0ba399..6576f6a5b0 100644
@@ -42,6 +42,7 @@ bool machine_dump_guest_core(MachineState *machine);
 bool machine_mem_merge(MachineState *machine);
 void machine_register_compat_props(MachineState *machine);
 HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine);
+void machine_class_add_sysbus_whitelist(MachineClass *mc, const char *type);
 
 /**
  * CPUArchId:
@@ -121,7 +122,6 @@ struct MachineClass {
         no_floppy:1,
         no_cdrom:1,
         no_sdcard:1,
-        has_dynamic_sysbus:1,
         pci_allow_0_address:1,
         legacy_fw_cfg_order:1;
     int is_default;
@@ -135,6 +135,7 @@ struct MachineClass {
     bool rom_file_has_mr;
     int minimum_page_bits;
     bool has_hotpluggable_cpus;
+    strList *dynamic_sysbus_whitelist;
 
     HotplugHandler *(*get_hotplug_handler)(MachineState *machine,
                                            DeviceState *dev);
hw/arm/sysbus-fdt.c +10 -0
index d68e3dcdbd..29573a4412 100644
@@ -29,6 +29,7 @@
 #include <linux/vfio.h>
 #endif
 #include "hw/arm/sysbus-fdt.h"
+#include "hw/boards.h"
 #include "qemu/error-report.h"
 #include "sysemu/device_tree.h"
 #include "hw/platform-bus.h"
@@ -424,6 +425,15 @@ static const NodeCreationPair add_fdt_node_functions[] = {
     {"", NULL}, /* last element */
 };
 
+void arm_register_fdt_sysbus_whitelist(MachineClass *mc)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(add_fdt_node_functions); i++) {
+        machine_class_add_sysbus_whitelist(mc, add_fdt_node_functions[i].typename);
+    }
+}
+
 /* Generic Code */
 
 /**
hw/arm/virt.c +3 -1
index 5f62a0321e..293710a6ea 100644
@@ -52,6 +52,8 @@
 #include "hw/arm/fdt.h"
 #include "hw/intc/arm_gic.h"
 #include "hw/intc/arm_gicv3_common.h"
+#include "hw/vfio/vfio-calxeda-xgmac.h"
+#include "hw/vfio/vfio-amd-xgbe.h"
 #include "kvm_arm.h"
 #include "hw/smbios/smbios.h"
 #include "qapi/visitor.h"
@@ -1528,7 +1530,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
      * configuration of the particular instance.
      */
     mc->max_cpus = 255;
-    mc->has_dynamic_sysbus = true;
+    arm_register_fdt_sysbus_whitelist(mc);
     mc->block_default_type = IF_VIRTIO;
     mc->no_cdrom = 1;
     mc->pci_allow_0_address = true;
hw/core/machine.c +29 -14

58 lines not on this page · raw message

hw/i386/pc_q35.c +28 -1
index dd792a8547..ea039540d8 100644
@@ -297,7 +297,34 @@ static void pc_q35_machine_options(MachineClass *m)
     m->default_machine_opts = "firmware=bios-256k.bin";
     m->default_display = "std";
     m->no_floppy = 1;
-    m->has_dynamic_sysbus = true;
+    /* The following whitelist is based on the set of available
+     * sysbus devices when has_dynamic_sysbus was replaced with
+     * a whitelist. Not every single device in this list is really
+     * supposed to be supported, but they are kept here for compatibility.
+     * We can gradually remove unnecessary devices from the whitelist.
+     */
+    machine_class_add_sysbus_whitelist(m, "allwinner-ahci");
+    machine_class_add_sysbus_whitelist(m, "amd-iommu");
+    machine_class_add_sysbus_whitelist(m, "cfi.pflash01");
+    machine_class_add_sysbus_whitelist(m, "esp");
+    machine_class_add_sysbus_whitelist(m, "fw_cfg_io");
+    machine_class_add_sysbus_whitelist(m, "fw_cfg_mem");
+    machine_class_add_sysbus_whitelist(m, "generic-sdhci");
+    machine_class_add_sysbus_whitelist(m, "hpet");
+    machine_class_add_sysbus_whitelist(m, "intel-iommu");
+    machine_class_add_sysbus_whitelist(m, "ioapic");
+    machine_class_add_sysbus_whitelist(m, "isabus-bridge");
+    machine_class_add_sysbus_whitelist(m, "kvm-ioapic");
+    machine_class_add_sysbus_whitelist(m, "kvmclock");
+    machine_class_add_sysbus_whitelist(m, "kvmvapic");
+    machine_class_add_sysbus_whitelist(m, "SUNW,fdtwo");
+    machine_class_add_sysbus_whitelist(m, "sysbus-ahci");
+    machine_class_add_sysbus_whitelist(m, "sysbus-fdc");
+    machine_class_add_sysbus_whitelist(m, "sysbus-ohci");
+    machine_class_add_sysbus_whitelist(m, "unimplemented-device");
+    machine_class_add_sysbus_whitelist(m, "virtio-mmio");
+    machine_class_add_sysbus_whitelist(m, "xen-backend");
+    machine_class_add_sysbus_whitelist(m, "xen-sysdev");
     m->max_cpus = 288;
 }
 
hw/ppc/e500plat.c +3 -1
index 94b454551f..3abed05add 100644
@@ -12,7 +12,9 @@
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "e500.h"
+#include "hw/net/fsl_etsec/etsec.h"
 #include "hw/boards.h"
+#include "hw/sysbus.h"
 #include "sysemu/device_tree.h"
 #include "sysemu/kvm.h"
 #include "hw/pci/pci.h"
@@ -63,7 +65,7 @@ static void e500plat_machine_init(MachineClass *mc)
     mc->desc = "generic paravirt e500 platform";
     mc->init = e500plat_init;
     mc->max_cpus = 32;
-    mc->has_dynamic_sysbus = true;
+    machine_class_add_sysbus_whitelist(mc, TYPE_ETSEC_COMMON);
 }
 
 DEFINE_MACHINE("ppce500", e500plat_machine_init)
hw/ppc/spapr.c +1 -1
index 6ee566d658..db56d0a653 100644
@@ -3070,7 +3070,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
     mc->default_boot_order = "";
     mc->default_ram_size = 512 * M_BYTE;
     mc->kvm_type = spapr_kvm_type;
-    mc->has_dynamic_sysbus = true;
+    machine_class_add_sysbus_whitelist(mc, TYPE_SPAPR_PCI_HOST_BRIDGE);
     mc->pci_allow_0_address = true;
     mc->get_hotplug_handler = spapr_get_hotplug_handler;
     hc->pre_plug = spapr_machine_device_pre_plug;
Signature · 1 line
2.11.0.259.g40922b1
#11 lore raw

RFC 3/4 q35: Remove ioapic devices from sysbus whitelist

In reply to Eduardo Habkost

An ioapic device is always created by the q35 machine, so "-device ioapic" and "-device kvm-ioapic" never worked before. Remove it from the sysbus whitelist.

---
 hw/i386/pc_q35.c | 2 --
 1 file changed, 2 deletions(-)
hw/i386/pc_q35.c +0 -2
index ea039540d8..94a3069e16 100644
@@ -312,9 +312,7 @@ static void pc_q35_machine_options(MachineClass *m)
     machine_class_add_sysbus_whitelist(m, "generic-sdhci");
     machine_class_add_sysbus_whitelist(m, "hpet");
     machine_class_add_sysbus_whitelist(m, "intel-iommu");
-    machine_class_add_sysbus_whitelist(m, "ioapic");
     machine_class_add_sysbus_whitelist(m, "isabus-bridge");
-    machine_class_add_sysbus_whitelist(m, "kvm-ioapic");
     machine_class_add_sysbus_whitelist(m, "kvmclock");
     machine_class_add_sysbus_whitelist(m, "kvmvapic");
     machine_class_add_sysbus_whitelist(m, "SUNW,fdtwo");
Signature · 1 line
2.11.0.259.g40922b1
#12 lore raw

RFC 4/4 q35: Remove fw_cfg* from sysbus whitelist

In reply to Eduardo Habkost

fw_cfg devices are supposed to be created by the q35 board code, and not manually using -device. Remove them from the whitelist.

---
 hw/i386/pc_q35.c | 2 --
 1 file changed, 2 deletions(-)
hw/i386/pc_q35.c +0 -2
index 94a3069e16..91d7f67e48 100644
@@ -307,8 +307,6 @@ static void pc_q35_machine_options(MachineClass *m)
     machine_class_add_sysbus_whitelist(m, "amd-iommu");
     machine_class_add_sysbus_whitelist(m, "cfi.pflash01");
     machine_class_add_sysbus_whitelist(m, "esp");
-    machine_class_add_sysbus_whitelist(m, "fw_cfg_io");
-    machine_class_add_sysbus_whitelist(m, "fw_cfg_mem");
     machine_class_add_sysbus_whitelist(m, "generic-sdhci");
     machine_class_add_sysbus_whitelist(m, "hpet");
     machine_class_add_sysbus_whitelist(m, "intel-iommu");
Signature · 1 line
2.11.0.259.g40922b1
#13 lore raw
In reply to Eduardo Habkost
Quoted 42 lines · Eduardo Habkost

Summary
-------

This series replaces the existing has_dynamic_sysbus flag (that makes the machine accept every single sysbus device type on the command-line) with a short whitelist.

This will be helpful when implementing the new query-device-slots command, because each machine type will include only the sysbus devices it really supports, instead of including a catch-all TYPE_SYS_BUS_DEVICE "slot".

Most of the machines already have an internal whitelist implemented using foreach_dynamic_sysbus_device(), so we just encode the existing behavior inside the new MachineClass field.

Caveat: q35
-----------

The only problematic case is q35, that accepts all sysbus device types. In this case, instead of adding TYPE_SYS_BUS_DEVICE to the whitelist, I'm adding the existing list of existing sysbus device types to keep compatibility. After that, we can gradually and carefully remove unnecessary entries from the q35 whitelist.

Issue: xen_set_dynamic_sysbus() hack
------------------------------------

We still have an obstacle to get around: the callers of qdev_set_id() outside qdev_device_add() are breaking foreach_dynamic_sysbus_device(), and xen_set_dynamic_sysbus() is a workaround for that bug. We now need to fix that bug to be able to remove the xen_set_dynamic_sysbus() hack. This means the first patch of this series will probably break Xen, until we fix that bug.

Eduardo Habkost (4):
[UNTESTED] xen: Don't force has_dynamic_sysbus on machine class
machine: Replace has_dynamic_sysbus with a whitelist
q35: Remove ioapic devices from sysbus whitelist
q35: Remove fw_cfg* from sysbus whitelist

Quoted 11 lines
 include/hw/arm/sysbus-fdt.h |  7 +++++++
 include/hw/boards.h         |  3 ++-
 hw/arm/sysbus-fdt.c         | 10 ++++++++++
 hw/arm/virt.c               |  4 +++-
 hw/core/machine.c           | 43 +++++++++++++++++++++++++++++--------------
 hw/i386/pc_q35.c            | 25 ++++++++++++++++++++++++-
 hw/ppc/e500plat.c           |  4 +++-
 hw/ppc/spapr.c              |  2 +-
 hw/xen/xen_backend.c        | 11 -----------
 9 files changed, 79 insertions(+), 30 deletions(-)

This seems to break Xen. I got:

qemu-system-i386: Option '-device xen-backend' cannot be handled by this machine

when using qemu as Xen backend driver.

Juergen