diff options
205 files changed, 1410 insertions, 821 deletions
diff --git a/configs/devices/mips-softmmu/common.mak b/configs/devices/mips-softmmu/common.mak index 416161f..88aff94 100644 --- a/configs/devices/mips-softmmu/common.mak +++ b/configs/devices/mips-softmmu/common.mak @@ -17,9 +17,7 @@ CONFIG_I8254=y CONFIG_PCSPK=y CONFIG_PCKBD=y CONFIG_FDC=y -CONFIG_ACPI=y CONFIG_ACPI_PIIX4=y -CONFIG_APM=y CONFIG_I8257=y CONFIG_PIIX4=y CONFIG_IDE_ISA=y @@ -32,6 +30,5 @@ CONFIG_MIPS_ITU=y CONFIG_MALTA=y CONFIG_PCNET_PCI=y CONFIG_MIPSSIM=y -CONFIG_ACPI_SMBUS=y CONFIG_SMBUS_EEPROM=y CONFIG_TEST_DEVICES=y diff --git a/docs/devel/style.rst b/docs/devel/style.rst index 7ddd42b..68aa776 100644 --- a/docs/devel/style.rst +++ b/docs/devel/style.rst @@ -293,6 +293,13 @@ that QEMU depends on. Do not include "qemu/osdep.h" from header files since the .c file will have already included it. +Headers should normally include everything they need beyond osdep.h. +If exceptions are needed for some reason, they must be documented in +the header. If all that's needed from a header is typedefs, consider +putting those into qemu/typedefs.h instead of including the header. + +Cyclic inclusion is forbidden. + C types ======= diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig index 3703aca..1f7803f 100644 --- a/hw/acpi/Kconfig +++ b/hw/acpi/Kconfig @@ -9,13 +9,14 @@ config ACPI_X86 select ACPI_CPU_HOTPLUG select ACPI_MEMORY_HOTPLUG select ACPI_HMAT - select ACPI_PIIX4 select ACPI_PCIHP select ACPI_ERST -config ACPI_X86_ICH +config ACPI_ICH9 bool + select ACPI_SMBUS select ACPI_X86 + select APM config ACPI_CPU_HOTPLUG bool @@ -30,7 +31,9 @@ config ACPI_NVDIMM config ACPI_PIIX4 bool - depends on ACPI + select ACPI + select ACPI_SMBUS + select APM config ACPI_PCIHP bool diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 42feb4d..ea331a2 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -2030,7 +2030,7 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms, 0, socket_id, NULL, 0); } - if (mc->smp_props.clusters_supported) { + if (mc->smp_props.clusters_supported && mc->smp_props.has_clusters) { if (cpus->cpus[n].props.cluster_id != cluster_id) { assert(cpus->cpus[n].props.cluster_id > cluster_id); cluster_id = cpus->cpus[n].props.cluster_id; diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c index 53654f8..ff14c3f 100644 --- a/hw/acpi/cpu_hotplug.c +++ b/hw/acpi/cpu_hotplug.c @@ -52,6 +52,9 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = { .endianness = DEVICE_LITTLE_ENDIAN, .valid = { .min_access_size = 1, + .max_access_size = 4, + }, + .impl = { .max_access_size = 1, }, }; diff --git a/hw/acpi/erst.c b/hw/acpi/erst.c index aefcc03..35007d8 100644 --- a/hw/acpi/erst.c +++ b/hw/acpi/erst.c @@ -14,7 +14,7 @@ #include "hw/qdev-core.h" #include "exec/memory.h" #include "qom/object.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "qom/object_interfaces.h" #include "qemu/error-report.h" #include "migration/vmstate.h" diff --git a/hw/acpi/meson.build b/hw/acpi/meson.build index 2ed29ae..30054a8 100644 --- a/hw/acpi/meson.build +++ b/hw/acpi/meson.build @@ -22,7 +22,7 @@ acpi_ss.add(when: 'CONFIG_ACPI_PIIX4', if_true: files('piix4.c')) acpi_ss.add(when: 'CONFIG_ACPI_PCIHP', if_true: files('pcihp.c')) acpi_ss.add(when: 'CONFIG_ACPI_PCIHP', if_false: files('acpi-pci-hotplug-stub.c')) acpi_ss.add(when: 'CONFIG_ACPI_VIOT', if_true: files('viot.c')) -acpi_ss.add(when: 'CONFIG_ACPI_X86_ICH', if_true: files('ich9.c', 'ich9_tco.c')) +acpi_ss.add(when: 'CONFIG_ACPI_ICH9', if_true: files('ich9.c', 'ich9_tco.c')) acpi_ss.add(when: 'CONFIG_ACPI_ERST', if_true: files('erst.c')) acpi_ss.add(when: 'CONFIG_IPMI', if_true: files('ipmi.c'), if_false: files('ipmi-stub.c')) acpi_ss.add(when: 'CONFIG_PC', if_false: files('acpi-x86-stub.c')) diff --git a/hw/alpha/alpha_sys.h b/hw/alpha/alpha_sys.h index 2263e82..a303c58 100644 --- a/hw/alpha/alpha_sys.h +++ b/hw/alpha/alpha_sys.h @@ -5,7 +5,6 @@ #include "target/alpha/cpu-qom.h" #include "hw/pci/pci.h" -#include "hw/pci/pci_host.h" #include "hw/boards.h" #include "hw/intc/i8259.h" diff --git a/hw/alpha/pci.c b/hw/alpha/pci.c index 72251fc..7c18297 100644 --- a/hw/alpha/pci.c +++ b/hw/alpha/pci.c @@ -7,6 +7,7 @@ */ #include "qemu/osdep.h" +#include "hw/pci/pci_host.h" #include "alpha_sys.h" #include "qemu/log.h" #include "trace.h" diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c index bd39c8c..49a8055 100644 --- a/hw/alpha/typhoon.c +++ b/hw/alpha/typhoon.c @@ -10,10 +10,10 @@ #include "qemu/module.h" #include "qemu/units.h" #include "qapi/error.h" +#include "hw/pci/pci_host.h" #include "cpu.h" #include "hw/irq.h" #include "alpha_sys.h" -#include "qom/object.h" #define TYPE_TYPHOON_PCI_HOST_BRIDGE "typhoon-pcihost" diff --git a/hw/audio/ac97.c b/hw/audio/ac97.c index be2dd70..364cdfa 100644 --- a/hw/audio/ac97.c +++ b/hw/audio/ac97.c @@ -20,7 +20,7 @@ #include "qemu/osdep.h" #include "hw/audio/soundhw.h" #include "audio/audio.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "qemu/module.h" diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c index 6904589..54cc19a 100644 --- a/hw/audio/es1370.c +++ b/hw/audio/es1370.c @@ -29,7 +29,7 @@ #include "qemu/osdep.h" #include "hw/audio/soundhw.h" #include "audio/audio.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "migration/vmstate.h" #include "qemu/module.h" #include "sysemu/dma.h" diff --git a/hw/audio/via-ac97.c b/hw/audio/via-ac97.c index 6d556f7..d1a856f 100644 --- a/hw/audio/via-ac97.c +++ b/hw/audio/via-ac97.c @@ -11,7 +11,7 @@ #include "qemu/osdep.h" #include "hw/isa/vt82c686.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" static void via_ac97_realize(PCIDevice *pci_dev, Error **errp) { diff --git a/hw/char/serial-pci-multi.c b/hw/char/serial-pci-multi.c index 3a9f96c..f18b8dc 100644 --- a/hw/char/serial-pci-multi.c +++ b/hw/char/serial-pci-multi.c @@ -31,7 +31,7 @@ #include "qapi/error.h" #include "hw/char/serial.h" #include "hw/irq.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" #include "hw/qdev-properties-system.h" #include "migration/vmstate.h" diff --git a/hw/char/serial-pci.c b/hw/char/serial-pci.c index 93d6f99..801b769 100644 --- a/hw/char/serial-pci.c +++ b/hw/char/serial-pci.c @@ -30,7 +30,7 @@ #include "qemu/module.h" #include "hw/char/serial.h" #include "hw/irq.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "qom/object.h" diff --git a/hw/core/machine-smp.c b/hw/core/machine-smp.c index b39ed21..c3dab00 100644 --- a/hw/core/machine-smp.c +++ b/hw/core/machine-smp.c @@ -158,6 +158,8 @@ void machine_parse_smp_config(MachineState *ms, ms->smp.threads = threads; ms->smp.max_cpus = maxcpus; + mc->smp_props.has_clusters = config->has_clusters; + /* sanity-check of the computed topology */ if (sockets * dies * clusters * cores * threads != maxcpus) { g_autofree char *topo_msg = cpu_hierarchy_to_string(ms); diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index 97a968f..54a09fa 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -32,6 +32,7 @@ #include "sysemu/blockdev.h" #include "net/net.h" #include "hw/pci/pci.h" +#include "hw/pci/pcie.h" #include "util/block-helpers.h" static bool check_prop_still_unset(Object *obj, const char *name, diff --git a/hw/display/ati_int.h b/hw/display/ati_int.h index 8acb9c7..e8d3c7a 100644 --- a/hw/display/ati_int.h +++ b/hw/display/ati_int.h @@ -10,7 +10,7 @@ #define ATI_INT_H #include "qemu/timer.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/i2c/bitbang_i2c.h" #include "vga_int.h" #include "qom/object.h" diff --git a/hw/display/bochs-display.c b/hw/display/bochs-display.c index 8ed734b..e7ec268 100644 --- a/hw/display/bochs-display.c +++ b/hw/display/bochs-display.c @@ -8,7 +8,7 @@ #include "qemu/osdep.h" #include "qemu/module.h" #include "qemu/units.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "hw/display/bochs-vbe.h" diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c index 6e8c747..55c32e3 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -39,7 +39,7 @@ #include "sysemu/reset.h" #include "qapi/error.h" #include "trace.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "ui/pixel_ops.h" diff --git a/hw/display/qxl.h b/hw/display/qxl.h index 7894bd5..cd82c7a 100644 --- a/hw/display/qxl.h +++ b/hw/display/qxl.h @@ -1,8 +1,7 @@ #ifndef HW_QXL_H #define HW_QXL_H - -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "vga_int.h" #include "qemu/thread.h" diff --git a/hw/display/sm501.c b/hw/display/sm501.c index 663c37e..52e4258 100644 --- a/hw/display/sm501.c +++ b/hw/display/sm501.c @@ -32,7 +32,7 @@ #include "ui/console.h" #include "hw/sysbus.h" #include "migration/vmstate.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" #include "hw/i2c/i2c.h" #include "hw/display/i2c-ddc.h" diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c index df23dbf..b351b8f 100644 --- a/hw/display/vga-pci.c +++ b/hw/display/vga-pci.c @@ -25,7 +25,7 @@ */ #include "qemu/osdep.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "vga_int.h" diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c index 19c0e20..4380a5e 100644 --- a/hw/display/vhost-user-gpu.c +++ b/hw/display/vhost-user-gpu.c @@ -486,6 +486,15 @@ vhost_user_gpu_guest_notifier_pending(VirtIODevice *vdev, int idx) { VhostUserGPU *g = VHOST_USER_GPU(vdev); + /* + * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 + * as the Marco of configure interrupt's IDX, If this driver does not + * support, the function will return + */ + + if (idx == VIRTIO_CONFIG_IRQ_IDX) { + return false; + } return vhost_virtqueue_pending(&g->vhost->dev, idx); } @@ -494,6 +503,15 @@ vhost_user_gpu_guest_notifier_mask(VirtIODevice *vdev, int idx, bool mask) { VhostUserGPU *g = VHOST_USER_GPU(vdev); + /* + * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 + * as the Marco of configure interrupt's IDX, If this driver does not + * support, the function will return + */ + + if (idx == VIRTIO_CONFIG_IRQ_IDX) { + return; + } vhost_virtqueue_mask(&g->vhost->dev, vdev, idx, mask); } diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c index 53949d2..59ae7f7 100644 --- a/hw/display/vmware_vga.c +++ b/hw/display/vmware_vga.c @@ -29,7 +29,7 @@ #include "qemu/log.h" #include "hw/loader.h" #include "trace.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "qom/object.h" diff --git a/hw/i2c/meson.build b/hw/i2c/meson.build index d3df273..6e7340a 100644 --- a/hw/i2c/meson.build +++ b/hw/i2c/meson.build @@ -2,7 +2,7 @@ i2c_ss = ss.source_set() i2c_ss.add(when: 'CONFIG_I2C', if_true: files('core.c')) i2c_ss.add(when: 'CONFIG_SMBUS', if_true: files('smbus_slave.c', 'smbus_master.c')) i2c_ss.add(when: 'CONFIG_ACPI_SMBUS', if_true: files('pm_smbus.c')) -i2c_ss.add(when: 'CONFIG_ACPI_X86_ICH', if_true: files('smbus_ich9.c')) +i2c_ss.add(when: 'CONFIG_ACPI_ICH9', if_true: files('smbus_ich9.c')) i2c_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_i2c.c')) i2c_ss.add(when: 'CONFIG_BITBANG_I2C', if_true: files('bitbang_i2c.c')) i2c_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_i2c.c')) diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig index d22ac4a..c4fb5b4 100644 --- a/hw/i386/Kconfig +++ b/hw/i386/Kconfig @@ -51,7 +51,6 @@ config PC_PCI bool select APIC select IOAPIC - select APM select PC config PC_ACPI @@ -69,9 +68,9 @@ config I440FX imply E1000_PCI imply VMPORT imply VMMOUSE + select ACPI_PIIX4 select PC_PCI select PC_ACPI - select ACPI_SMBUS select PCI_I440FX select PIIX3 select IDE_PIIX diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index aa15b11..127c4e2 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -27,7 +27,7 @@ #include "acpi-common.h" #include "qemu/bitmap.h" #include "qemu/error-report.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_bridge.h" #include "hw/cxl/cxl.h" #include "hw/core/cpu.h" #include "target/i386/cpu.h" diff --git a/hw/i386/xen/xen_pvdevice.c b/hw/i386/xen/xen_pvdevice.c index 1ea95fa..e62e066 100644 --- a/hw/i386/xen/xen_pvdevice.c +++ b/hw/i386/xen/xen_pvdevice.c @@ -32,7 +32,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qemu/module.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "trace.h" diff --git a/hw/ide/ahci_internal.h b/hw/ide/ahci_internal.h index 109de9e..303fcd7 100644 --- a/hw/ide/ahci_internal.h +++ b/hw/ide/ahci_internal.h @@ -26,7 +26,7 @@ #include "hw/ide/ahci.h" #include "hw/ide/internal.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #define AHCI_MEM_BAR_SIZE 0x1000 #define AHCI_MAX_PORTS 32 diff --git a/hw/ipack/tpci200.c b/hw/ipack/tpci200.c index 1f764fc..6b3edbf 100644 --- a/hw/ipack/tpci200.c +++ b/hw/ipack/tpci200.c @@ -12,7 +12,7 @@ #include "qemu/units.h" #include "hw/ipack/ipack.h" #include "hw/irq.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "migration/vmstate.h" #include "qemu/bitops.h" #include "qemu/module.h" diff --git a/hw/ipmi/pci_ipmi_bt.c b/hw/ipmi/pci_ipmi_bt.c index b6e5273..633931b 100644 --- a/hw/ipmi/pci_ipmi_bt.c +++ b/hw/ipmi/pci_ipmi_bt.c @@ -25,7 +25,7 @@ #include "migration/vmstate.h" #include "qapi/error.h" #include "hw/ipmi/ipmi_bt.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "qom/object.h" #define TYPE_PCI_IPMI_BT "pci-ipmi-bt" diff --git a/hw/ipmi/pci_ipmi_kcs.c b/hw/ipmi/pci_ipmi_kcs.c index de13418..1a58141 100644 --- a/hw/ipmi/pci_ipmi_kcs.c +++ b/hw/ipmi/pci_ipmi_kcs.c @@ -25,7 +25,7 @@ #include "migration/vmstate.h" #include "qapi/error.h" #include "hw/ipmi/ipmi_kcs.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "qom/object.h" #define TYPE_PCI_IPMI_KCS "pci-ipmi-kcs" diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig index 18b5c6b..0156a66 100644 --- a/hw/isa/Kconfig +++ b/hw/isa/Kconfig @@ -52,6 +52,7 @@ config PIIX4 config VT82C686 bool select ISA_SUPERIO + select ACPI select ACPI_SMBUS select SERIAL_ISA select FDC_ISA @@ -77,5 +78,4 @@ config LPC_ICH9 # for ICH9. select I8257 select ISA_BUS - select ACPI_SMBUS - select ACPI_X86_ICH + select ACPI_ICH9 diff --git a/hw/isa/i82378.c b/hw/isa/i82378.c index 2a2ff05..e3322e0 100644 --- a/hw/isa/i82378.c +++ b/hw/isa/i82378.c @@ -18,7 +18,7 @@ */ #include "qemu/osdep.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/irq.h" #include "hw/intc/i8259.h" #include "hw/timer/i8254.h" diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c index 19d0d98..164866c 100644 --- a/hw/mips/gt64xxx_pci.c +++ b/hw/mips/gt64xxx_pci.c @@ -26,7 +26,7 @@ #include "qapi/error.h" #include "qemu/units.h" #include "qemu/log.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/pci/pci_host.h" #include "migration/vmstate.h" #include "hw/intc/i8259.h" diff --git a/hw/misc/pci-testdev.c b/hw/misc/pci-testdev.c index 03845c8..4930313 100644 --- a/hw/misc/pci-testdev.c +++ b/hw/misc/pci-testdev.c @@ -19,7 +19,7 @@ */ #include "qemu/osdep.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" #include "qemu/event_notifier.h" #include "qemu/module.h" diff --git a/hw/misc/pvpanic-pci.c b/hw/misc/pvpanic-pci.c index 99cf7e2..fbcaa50 100644 --- a/hw/misc/pvpanic-pci.c +++ b/hw/misc/pvpanic-pci.c @@ -20,7 +20,7 @@ #include "migration/vmstate.h" #include "hw/misc/pvpanic.h" #include "qom/object.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "standard-headers/linux/pvpanic.h" OBJECT_DECLARE_SIMPLE_TYPE(PVPanicPCIState, PVPANIC_PCI_DEVICE) diff --git a/hw/net/can/can_kvaser_pci.c b/hw/net/can/can_kvaser_pci.c index 94b3a53..2cd90ce 100644 --- a/hw/net/can/can_kvaser_pci.c +++ b/hw/net/can/can_kvaser_pci.c @@ -37,7 +37,7 @@ #include "qapi/error.h" #include "chardev/char.h" #include "hw/irq.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "net/can_emu.h" diff --git a/hw/net/can/can_mioe3680_pci.c b/hw/net/can/can_mioe3680_pci.c index 29dc696..b991877 100644 --- a/hw/net/can/can_mioe3680_pci.c +++ b/hw/net/can/can_mioe3680_pci.c @@ -33,7 +33,7 @@ #include "qapi/error.h" #include "chardev/char.h" #include "hw/irq.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "net/can_emu.h" diff --git a/hw/net/can/can_pcm3680_pci.c b/hw/net/can/can_pcm3680_pci.c index e8e57f4..8ef3e46 100644 --- a/hw/net/can/can_pcm3680_pci.c +++ b/hw/net/can/can_pcm3680_pci.c @@ -33,7 +33,7 @@ #include "qapi/error.h" #include "chardev/char.h" #include "hw/irq.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "net/can_emu.h" diff --git a/hw/net/can/ctucan_pci.c b/hw/net/can/ctucan_pci.c index 50f4ea6..ea079e2 100644 --- a/hw/net/can/ctucan_pci.c +++ b/hw/net/can/ctucan_pci.c @@ -34,7 +34,7 @@ #include "qapi/error.h" #include "chardev/char.h" #include "hw/irq.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "net/can_emu.h" diff --git a/hw/net/e1000.c b/hw/net/e1000.c index e26e0a6..7efb8a4 100644 --- a/hw/net/e1000.c +++ b/hw/net/e1000.c @@ -26,7 +26,7 @@ #include "qemu/osdep.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "net/eth.h" diff --git a/hw/net/e1000x_common.c b/hw/net/e1000x_common.c index a8d9387..2f43e8c 100644 --- a/hw/net/e1000x_common.c +++ b/hw/net/e1000x_common.c @@ -24,7 +24,7 @@ #include "qemu/osdep.h" #include "qemu/units.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "net/net.h" #include "e1000x_common.h" diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c index 679f52f..dc07984 100644 --- a/hw/net/eepro100.c +++ b/hw/net/eepro100.c @@ -42,7 +42,7 @@ #include "qemu/osdep.h" #include "qemu/units.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "net/net.h" diff --git a/hw/net/ne2000-pci.c b/hw/net/ne2000-pci.c index 9e5d108..edc6689 100644 --- a/hw/net/ne2000-pci.c +++ b/hw/net/ne2000-pci.c @@ -24,7 +24,7 @@ #include "qemu/osdep.h" #include "hw/irq.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "ne2000.h" diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c index 1cb1125..2533ea2 100644 --- a/hw/net/net_tx_pkt.c +++ b/hw/net/net_tx_pkt.c @@ -21,7 +21,7 @@ #include "net/checksum.h" #include "net/tap.h" #include "net/net.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" enum { NET_TX_PKT_VHDR_FRAG = 0, diff --git a/hw/net/pcnet-pci.c b/hw/net/pcnet-pci.c index 95d2710..96a302c 100644 --- a/hw/net/pcnet-pci.c +++ b/hw/net/pcnet-pci.c @@ -29,7 +29,7 @@ #include "qemu/osdep.h" #include "hw/irq.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "net/net.h" diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c index 281d43e..cf54ddf 100644 --- a/hw/net/rocker/rocker.c +++ b/hw/net/rocker/rocker.c @@ -16,7 +16,7 @@ */ #include "qemu/osdep.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" #include "hw/qdev-properties-system.h" #include "migration/vmstate.h" diff --git a/hw/net/rocker/rocker_desc.c b/hw/net/rocker/rocker_desc.c index 01845f1..f3068c9 100644 --- a/hw/net/rocker/rocker_desc.c +++ b/hw/net/rocker/rocker_desc.c @@ -16,7 +16,7 @@ #include "qemu/osdep.h" #include "net/net.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "rocker.h" #include "rocker_hw.h" diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c index 700b1b6..5a5aaf8 100644 --- a/hw/net/rtl8139.c +++ b/hw/net/rtl8139.c @@ -53,7 +53,7 @@ #include "qemu/osdep.h" #include <zlib.h> -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "sysemu/dma.h" diff --git a/hw/net/sungem.c b/hw/net/sungem.c index 3684a4d..eb01520 100644 --- a/hw/net/sungem.c +++ b/hw/net/sungem.c @@ -8,7 +8,7 @@ */ #include "qemu/osdep.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "qemu/log.h" diff --git a/hw/net/sunhme.c b/hw/net/sunhme.c index fc34905..1f3d801 100644 --- a/hw/net/sunhme.c +++ b/hw/net/sunhme.c @@ -23,7 +23,7 @@ */ #include "qemu/osdep.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "hw/net/mii.h" diff --git a/hw/net/tulip.c b/hw/net/tulip.c index c2b3b1b..915e5fb 100644 --- a/hw/net/tulip.c +++ b/hw/net/tulip.c @@ -9,7 +9,7 @@ #include "qemu/osdep.h" #include "qemu/log.h" #include "hw/irq.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" #include "hw/nvram/eeprom93xx.h" #include "migration/vmstate.h" diff --git a/hw/net/vhost_net-stub.c b/hw/net/vhost_net-stub.c index 9f7daae..72df6d7 100644 --- a/hw/net/vhost_net-stub.c +++ b/hw/net/vhost_net-stub.c @@ -82,6 +82,15 @@ void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, { } +bool vhost_net_config_pending(VHostNetState *net) +{ + return false; +} + +void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev, bool mask) +{ +} + int vhost_net_notify_migration_done(struct vhost_net *net, char* mac_addr) { return -1; @@ -113,3 +122,8 @@ int vhost_net_virtqueue_restart(VirtIODevice *vdev, NetClientState *nc, { return 0; } + +void vhost_net_save_acked_features(NetClientState *nc) +{ + +} diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index 043058f..c4eecc6 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -144,6 +144,15 @@ uint64_t vhost_net_get_acked_features(VHostNetState *net) return net->dev.acked_features; } +void vhost_net_save_acked_features(NetClientState *nc) +{ +#ifdef CONFIG_VHOST_NET_USER + if (nc->info->type == NET_CLIENT_DRIVER_VHOST_USER) { + vhost_user_save_acked_features(nc); + } +#endif +} + static int vhost_net_get_fd(NetClientState *backend) { switch (backend->info->type) { @@ -478,6 +487,15 @@ void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, vhost_virtqueue_mask(&net->dev, dev, idx, mask); } +bool vhost_net_config_pending(VHostNetState *net) +{ + return vhost_config_pending(&net->dev); +} + +void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev, bool mask) +{ + vhost_config_mask(&net->dev, dev, mask); +} VHostNetState *get_vhost_net(NetClientState *nc) { VHostNetState *vhost_net = 0; diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 9cbdfa5..3ae9090 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -42,7 +42,7 @@ #include "sysemu/sysemu.h" #include "trace.h" #include "monitor/qdev.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "net_rx_pkt.h" #include "hw/virtio/vhost.h" #include "sysemu/qtest.h" @@ -168,20 +168,24 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t *config) if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) { ret = vhost_net_get_config(get_vhost_net(nc->peer), (uint8_t *)&netcfg, n->config_size); - if (ret != -1) { - /* - * Some NIC/kernel combinations present 0 as the mac address. As - * that is not a legal address, try to proceed with the - * address from the QEMU command line in the hope that the - * address has been configured correctly elsewhere - just not - * reported by the device. - */ - if (memcmp(&netcfg.mac, &zero, sizeof(zero)) == 0) { - info_report("Zero hardware mac address detected. Ignoring."); - memcpy(netcfg.mac, n->mac, ETH_ALEN); - } - memcpy(config, &netcfg, n->config_size); + if (ret == -1) { + return; + } + + /* + * Some NIC/kernel combinations present 0 as the mac address. As that + * is not a legal address, try to proceed with the address from the + * QEMU command line in the hope that the address has been configured + * correctly elsewhere - just not reported by the device. + */ + if (memcmp(&netcfg.mac, &zero, sizeof(zero)) == 0) { + info_report("Zero hardware mac address detected. Ignoring."); + memcpy(netcfg.mac, n->mac, ETH_ALEN); } + + netcfg.status |= virtio_tswap16(vdev, + n->status & VIRTIO_NET_S_ANNOUNCE); + memcpy(config, &netcfg, n->config_size); } } @@ -980,6 +984,12 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint64_t features) continue; } vhost_net_ack_features(get_vhost_net(nc->peer), features); + + /* + * keep acked_features in NetVhostUserState up-to-date so it + * can't miss any features configured by guest virtio driver. + */ + vhost_net_save_acked_features(nc->peer); } if (virtio_has_feature(features, VIRTIO_NET_F_CTRL_VLAN)) { @@ -3315,6 +3325,15 @@ static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx) } else { nc = qemu_get_subqueue(n->nic, vq2q(idx)); } + /* + * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 + * as the Marco of configure interrupt's IDX, If this driver does not + * support, the function will return false + */ + + if (idx == VIRTIO_CONFIG_IRQ_IDX) { + return vhost_net_config_pending(get_vhost_net(nc->peer)); + } return vhost_net_virtqueue_pending(get_vhost_net(nc->peer), idx); } @@ -3338,8 +3357,17 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx, } else { nc = qemu_get_subqueue(n->nic, vq2q(idx)); } - vhost_net_virtqueue_mask(get_vhost_net(nc->peer), - vdev, idx, mask); + /* + *Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 + * as the Marco of configure interrupt's IDX, If this driver does not + * support, the function will return + */ + + if (idx == VIRTIO_CONFIG_IRQ_IDX) { + vhost_net_config_mask(get_vhost_net(nc->peer), vdev, mask); + return; + } + vhost_net_virtqueue_mask(get_vhost_net(nc->peer), vdev, idx, mask); } static void virtio_net_set_config_size(VirtIONet *n, uint64_t host_features) diff --git a/hw/net/vmxnet3_defs.h b/hw/net/vmxnet3_defs.h index 7144050..64034af 100644 --- a/hw/net/vmxnet3_defs.h +++ b/hw/net/vmxnet3_defs.h @@ -19,7 +19,7 @@ #include "net/net.h" #include "hw/net/vmxnet3.h" -#include "qom/object.h" +#include "hw/pci/pci_device.h" #define TYPE_VMXNET3 "vmxnet3" typedef struct VMXNET3State VMXNET3State; diff --git a/hw/nvme/nvme.h b/hw/nvme/nvme.h index 7adf042..16da27a 100644 --- a/hw/nvme/nvme.h +++ b/hw/nvme/nvme.h @@ -19,7 +19,7 @@ #define HW_NVME_NVME_H #include "qemu/uuid.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/block/block.h" #include "block/nvme.h" diff --git a/hw/pci-bridge/i82801b11.c b/hw/pci-bridge/i82801b11.c index d9f2248..f3b4a14 100644 --- a/hw/pci-bridge/i82801b11.c +++ b/hw/pci-bridge/i82801b11.c @@ -42,7 +42,7 @@ */ #include "qemu/osdep.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_bridge.h" #include "migration/vmstate.h" #include "qemu/module.h" #include "hw/i386/ich9.h" diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c index c9e817a..870d9ba 100644 --- a/hw/pci-bridge/pci_expander_bridge.c +++ b/hw/pci-bridge/pci_expander_bridge.c @@ -50,7 +50,6 @@ struct PXBBus { }; #define TYPE_PXB_DEVICE "pxb" -typedef struct PXBDev PXBDev; DECLARE_INSTANCE_CHECKER(PXBDev, PXB_DEV, TYPE_PXB_DEVICE) diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c index a57e81e..f04f3ad 100644 --- a/hw/pci-host/bonito.c +++ b/hw/pci-host/bonito.c @@ -42,7 +42,7 @@ #include "qemu/units.h" #include "qapi/error.h" #include "qemu/error-report.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/irq.h" #include "hw/mips/mips.h" #include "hw/pci/pci_host.h" diff --git a/hw/pci-host/dino.c b/hw/pci-host/dino.c index f257c24..e8eaebc 100644 --- a/hw/pci-host/dino.c +++ b/hw/pci-host/dino.c @@ -15,7 +15,7 @@ #include "qemu/units.h" #include "qapi/error.h" #include "hw/irq.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/pci/pci_bus.h" #include "hw/qdev-properties.h" #include "hw/pci-host/dino.h" diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c index 95945ac..8cf318c 100644 --- a/hw/pci-host/grackle.c +++ b/hw/pci-host/grackle.c @@ -25,7 +25,7 @@ #include "qemu/osdep.h" #include "hw/qdev-properties.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/irq.h" #include "qapi/error.h" #include "qemu/module.h" diff --git a/hw/pci-host/mv64361.c b/hw/pci-host/mv64361.c index cc9c4d6..015b92b 100644 --- a/hw/pci-host/mv64361.c +++ b/hw/pci-host/mv64361.c @@ -13,7 +13,7 @@ #include "qapi/error.h" #include "hw/hw.h" #include "hw/sysbus.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/pci/pci_host.h" #include "hw/irq.h" #include "hw/intc/i8259.h" diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c index 89c1b53..568849e 100644 --- a/hw/pci-host/ppce500.c +++ b/hw/pci-host/ppce500.c @@ -19,7 +19,7 @@ #include "hw/ppc/e500-ccsr.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/pci/pci_host.h" #include "qemu/bswap.h" #include "qemu/module.h" diff --git a/hw/pci-host/raven.c b/hw/pci-host/raven.c index 7a105e4..2c96ddf 100644 --- a/hw/pci-host/raven.c +++ b/hw/pci-host/raven.c @@ -28,7 +28,7 @@ #include "qemu/units.h" #include "qemu/log.h" #include "qapi/error.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/pci/pci_bus.h" #include "hw/pci/pci_host.h" #include "hw/qdev-properties.h" diff --git a/hw/pci-host/sh_pci.c b/hw/pci-host/sh_pci.c index 719d6ca..77e7bbc 100644 --- a/hw/pci-host/sh_pci.c +++ b/hw/pci-host/sh_pci.c @@ -26,7 +26,7 @@ #include "hw/sysbus.h" #include "hw/sh4/sh.h" #include "hw/irq.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/pci/pci_host.h" #include "qemu/bswap.h" #include "qemu/module.h" diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index 8396c91..e3abe3c 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -26,7 +26,7 @@ #include "hw/irq.h" #include "hw/qdev-properties.h" #include "qemu/module.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/pci/pci_host.h" #include "hw/pci-host/uninorth.h" #include "trace.h" diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c index f66384f..0d50ea4 100644 --- a/hw/pci-host/versatile.c +++ b/hw/pci-host/versatile.c @@ -12,7 +12,7 @@ #include "hw/sysbus.h" #include "migration/vmstate.h" #include "hw/irq.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/pci/pci_bus.h" #include "hw/pci/pci_host.h" #include "hw/qdev-properties.h" diff --git a/hw/pci/pci-hmp-cmds.c b/hw/pci/pci-hmp-cmds.c index fb7591d..b09fce9 100644 --- a/hw/pci/pci-hmp-cmds.c +++ b/hw/pci/pci-hmp-cmds.c @@ -15,6 +15,7 @@ #include "qemu/osdep.h" #include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "monitor/hmp.h" #include "monitor/monitor.h" #include "pci-internal.h" diff --git a/hw/pci/pcie_host.c b/hw/pci/pcie_host.c index 5abbe83..3717e1a 100644 --- a/hw/pci/pcie_host.c +++ b/hw/pci/pcie_host.c @@ -20,7 +20,7 @@ */ #include "qemu/osdep.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/pci/pcie_host.h" #include "qemu/module.h" diff --git a/hw/pci/pcie_sriov.c b/hw/pci/pcie_sriov.c index 8e3faf1..f0bd72e 100644 --- a/hw/pci/pcie_sriov.c +++ b/hw/pci/pcie_sriov.c @@ -11,7 +11,7 @@ */ #include "qemu/osdep.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/pci/pcie.h" #include "hw/pci/pci_bus.h" #include "hw/qdev-properties.h" diff --git a/hw/pci/slotid_cap.c b/hw/pci/slotid_cap.c index 36d021b..8372d05 100644 --- a/hw/pci/slotid_cap.c +++ b/hw/pci/slotid_cap.c @@ -1,6 +1,6 @@ #include "qemu/osdep.h" #include "hw/pci/slotid_cap.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "qemu/error-report.h" #include "qapi/error.h" diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig index 72a311e..c898021 100644 --- a/hw/ppc/Kconfig +++ b/hw/ppc/Kconfig @@ -76,8 +76,6 @@ config PEGASOS2 select VT82C686 select SMBUS_EEPROM select VOF -# This should come with VT82C686 - select ACPI_X86 config PREP bool diff --git a/hw/ppc/ppc440_pcix.c b/hw/ppc/ppc440_pcix.c index 788d255..f10f93c 100644 --- a/hw/ppc/ppc440_pcix.c +++ b/hw/ppc/ppc440_pcix.c @@ -26,7 +26,7 @@ #include "hw/irq.h" #include "hw/ppc/ppc.h" #include "hw/ppc/ppc4xx.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/pci/pci_host.h" #include "trace.h" #include "qom/object.h" diff --git a/hw/ppc/ppc4xx_pci.c b/hw/ppc/ppc4xx_pci.c index 8642b96..1d4a50f 100644 --- a/hw/ppc/ppc4xx_pci.c +++ b/hw/ppc/ppc4xx_pci.c @@ -29,7 +29,7 @@ #include "migration/vmstate.h" #include "qemu/module.h" #include "sysemu/reset.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/pci/pci_host.h" #include "trace.h" #include "qom/object.h" diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c index 2a76b4e..d8aeee0 100644 --- a/hw/ppc/spapr_pci_vfio.c +++ b/hw/ppc/spapr_pci_vfio.c @@ -22,6 +22,7 @@ #include "hw/ppc/spapr.h" #include "hw/pci-host/spapr.h" #include "hw/pci/msix.h" +#include "hw/pci/pci_device.h" #include "hw/vfio/vfio.h" #include "qemu/error-report.h" diff --git a/hw/rdma/rdma_utils.c b/hw/rdma/rdma_utils.c index 5a7ef63..c948baf 100644 --- a/hw/rdma/rdma_utils.c +++ b/hw/rdma/rdma_utils.c @@ -14,6 +14,7 @@ */ #include "qemu/osdep.h" +#include "hw/pci/pci_device.h" #include "trace.h" #include "rdma_utils.h" diff --git a/hw/rdma/rdma_utils.h b/hw/rdma/rdma_utils.h index 0c6414e..54e4f56 100644 --- a/hw/rdma/rdma_utils.h +++ b/hw/rdma/rdma_utils.h @@ -18,7 +18,6 @@ #define RDMA_UTILS_H #include "qemu/error-report.h" -#include "hw/pci/pci.h" #include "sysemu/dma.h" #define rdma_error_report(fmt, ...) \ diff --git a/hw/rdma/vmw/pvrdma.h b/hw/rdma/vmw/pvrdma.h index d08965d..4cbc10c 100644 --- a/hw/rdma/vmw/pvrdma.h +++ b/hw/rdma/vmw/pvrdma.h @@ -18,8 +18,8 @@ #include "qemu/units.h" #include "qemu/notify.h" -#include "hw/pci/pci.h" #include "hw/pci/msix.h" +#include "hw/pci/pci_device.h" #include "chardev/char-fe.h" #include "hw/net/vmxnet3_defs.h" diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c index 9abe951..69137e0 100644 --- a/hw/s390x/s390-pci-inst.c +++ b/hw/s390x/s390-pci-inst.c @@ -16,6 +16,7 @@ #include "exec/memory-internal.h" #include "qemu/error-report.h" #include "sysemu/hw_accel.h" +#include "hw/pci/pci_device.h" #include "hw/s390x/s390-pci-inst.h" #include "hw/s390x/s390-pci-bus.h" #include "hw/s390x/s390-pci-kvm.h" diff --git a/hw/scsi/esp-pci.c b/hw/scsi/esp-pci.c index 1792f84..2f7f11e 100644 --- a/hw/scsi/esp-pci.c +++ b/hw/scsi/esp-pci.c @@ -24,7 +24,7 @@ */ #include "qemu/osdep.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/irq.h" #include "hw/nvram/eeprom93xx.h" #include "hw/scsi/esp.h" diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c index 5097964..af93557 100644 --- a/hw/scsi/lsi53c895a.c +++ b/hw/scsi/lsi53c895a.c @@ -16,7 +16,7 @@ #include "qemu/osdep.h" #include "hw/irq.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/scsi/scsi.h" #include "migration/vmstate.h" #include "sysemu/dma.h" diff --git a/hw/scsi/mptsas.h b/hw/scsi/mptsas.h index c046497..04e97ce 100644 --- a/hw/scsi/mptsas.h +++ b/hw/scsi/mptsas.h @@ -2,7 +2,7 @@ #define MPTSAS_H #include "mpi.h" -#include "qom/object.h" +#include "hw/pci/pci_device.h" #define MPTSAS_NUM_PORTS 8 #define MPTSAS_MAX_FRAMES 2048 /* Firmware limit at 65535 */ diff --git a/hw/scsi/vhost-scsi-common.c b/hw/scsi/vhost-scsi-common.c index 18ea5dc..a06f01a 100644 --- a/hw/scsi/vhost-scsi-common.c +++ b/hw/scsi/vhost-scsi-common.c @@ -113,6 +113,7 @@ void vhost_scsi_common_stop(VHostSCSICommon *vsc) if (vsc->inflight) { vhost_dev_free_inflight(vsc->inflight); + g_free(vsc->inflight); vsc->inflight = NULL; } diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 6f6e2e3..2b649ca 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -22,6 +22,7 @@ #include "qemu/iov.h" #include "qemu/module.h" #include "sysemu/block-backend.h" +#include "sysemu/dma.h" #include "hw/qdev-properties.h" #include "hw/scsi/scsi.h" #include "scsi/constants.h" diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c index b4243de..4869566 100644 --- a/hw/smbios/smbios.c +++ b/hw/smbios/smbios.c @@ -28,6 +28,7 @@ #include "hw/loader.h" #include "hw/boards.h" #include "hw/pci/pci_bus.h" +#include "hw/pci/pci_device.h" #include "smbios_build.h" /* legacy structures and constants for <= 2.0 machines */ diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h index a173707..2cd821f 100644 --- a/hw/usb/hcd-ehci.h +++ b/hw/usb/hcd-ehci.h @@ -21,9 +21,8 @@ #include "qemu/timer.h" #include "hw/usb.h" #include "sysemu/dma.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/sysbus.h" -#include "qom/object.h" #ifndef EHCI_DEBUG #define EHCI_DEBUG 0 diff --git a/hw/usb/hcd-ohci-pci.c b/hw/usb/hcd-ohci-pci.c index 8e1146b..6b630d3 100644 --- a/hw/usb/hcd-ohci-pci.c +++ b/hw/usb/hcd-ohci-pci.c @@ -23,7 +23,7 @@ #include "qemu/timer.h" #include "hw/usb.h" #include "migration/vmstate.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/sysbus.h" #include "hw/qdev-dma.h" #include "hw/qdev-properties.h" diff --git a/hw/usb/hcd-uhci.h b/hw/usb/hcd-uhci.h index c85ab78..5843af5 100644 --- a/hw/usb/hcd-uhci.h +++ b/hw/usb/hcd-uhci.h @@ -30,7 +30,7 @@ #include "exec/memory.h" #include "qemu/timer.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/usb.h" typedef struct UHCIQueue UHCIQueue; diff --git a/hw/usb/hcd-xhci-pci.h b/hw/usb/hcd-xhci-pci.h index c193f79..08f70ce 100644 --- a/hw/usb/hcd-xhci-pci.h +++ b/hw/usb/hcd-xhci-pci.h @@ -24,6 +24,7 @@ #ifndef HW_USB_HCD_XHCI_PCI_H #define HW_USB_HCD_XHCI_PCI_H +#include "hw/pci/pci_device.h" #include "hw/usb.h" #include "hcd-xhci.h" diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h index 7c236a5..177abcc 100644 --- a/hw/vfio/pci.h +++ b/hw/vfio/pci.h @@ -13,7 +13,7 @@ #define HW_VFIO_VFIO_PCI_H #include "exec/memory.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/vfio/vfio-common.h" #include "qemu/event_notifier.h" #include "qemu/queue.h" diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events index 96da58a..a87c5f3 100644 --- a/hw/virtio/trace-events +++ b/hw/virtio/trace-events @@ -62,6 +62,7 @@ vhost_vdpa_get_features(void *dev, uint64_t features) "dev: %p features: 0x%"PRI vhost_vdpa_set_owner(void *dev) "dev: %p" vhost_vdpa_vq_get_addr(void *dev, void *vq, uint64_t desc_user_addr, uint64_t avail_user_addr, uint64_t used_user_addr) "dev: %p vq: %p desc_user_addr: 0x%"PRIx64" avail_user_addr: 0x%"PRIx64" used_user_addr: 0x%"PRIx64 vhost_vdpa_get_iova_range(void *dev, uint64_t first, uint64_t last) "dev: %p first: 0x%"PRIx64" last: 0x%"PRIx64 +vhost_vdpa_set_config_call(void *dev, int fd)"dev: %p fd: %d" # virtio.c virtqueue_alloc_element(void *elem, size_t sz, unsigned in_num, unsigned out_num) "elem %p size %zd in_num %u out_num %u" diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c index db6ba61..01b41eb 100644 --- a/hw/virtio/vdpa-dev.c +++ b/hw/virtio/vdpa-dev.c @@ -53,6 +53,7 @@ static void vhost_vdpa_device_realize(DeviceState *dev, Error **errp) { VirtIODevice *vdev = VIRTIO_DEVICE(dev); VhostVdpaDevice *v = VHOST_VDPA_DEVICE(vdev); + struct vhost_vdpa_iova_range iova_range; uint16_t max_queue_size; struct vhost_virtqueue *vqs; int i, ret; @@ -108,6 +109,14 @@ static void vhost_vdpa_device_realize(DeviceState *dev, Error **errp) v->dev.backend_features = 0; v->started = false; + ret = vhost_vdpa_get_iova_range(v->vhostfd, &iova_range); + if (ret < 0) { + error_setg(errp, "vhost-vdpa-device: get iova range failed: %s", + strerror(-ret)); + goto free_vqs; + } + v->vdpa.iova_range = iova_range; + ret = vhost_dev_init(&v->dev, &v->vdpa, VHOST_BACKEND_TYPE_VDPA, 0, NULL); if (ret < 0) { error_setg(errp, "vhost-vdpa-device: vhost initialization failed: %s", diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c index d97b179..f504973 100644 --- a/hw/virtio/vhost-user-fs.c +++ b/hw/virtio/vhost-user-fs.c @@ -159,6 +159,15 @@ static void vuf_guest_notifier_mask(VirtIODevice *vdev, int idx, { VHostUserFS *fs = VHOST_USER_FS(vdev); + /* + * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 + * as the Marco of configure interrupt's IDX, If this driver does not + * support, the function will return + */ + + if (idx == VIRTIO_CONFIG_IRQ_IDX) { + return; + } vhost_virtqueue_mask(&fs->vhost_dev, vdev, idx, mask); } @@ -166,6 +175,15 @@ static bool vuf_guest_notifier_pending(VirtIODevice *vdev, int idx) { VHostUserFS *fs = VHOST_USER_FS(vdev); + /* + * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 + * as the Marco of configure interrupt's IDX, If this driver does not + * support, the function will return + */ + + if (idx == VIRTIO_CONFIG_IRQ_IDX) { + return false; + } return vhost_virtqueue_pending(&fs->vhost_dev, idx); } diff --git a/hw/virtio/vhost-user-gpio.c b/hw/virtio/vhost-user-gpio.c index b7b82a1..fe3da32 100644 --- a/hw/virtio/vhost-user-gpio.c +++ b/hw/virtio/vhost-user-gpio.c @@ -191,6 +191,16 @@ static void vu_gpio_guest_notifier_mask(VirtIODevice *vdev, int idx, bool mask) { VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev); + /* + * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 + * as the Marco of configure interrupt's IDX, If this driver does not + * support, the function will return + */ + + if (idx == VIRTIO_CONFIG_IRQ_IDX) { + return; + } + vhost_virtqueue_mask(&gpio->vhost_dev, vdev, idx, mask); } diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c index fd0c33b..542e003 100644 --- a/hw/virtio/vhost-vdpa.c +++ b/hw/virtio/vhost-vdpa.c @@ -378,6 +378,13 @@ static int vhost_vdpa_add_status(struct vhost_dev *dev, uint8_t status) return 0; } +int vhost_vdpa_get_iova_range(int fd, struct vhost_vdpa_iova_range *iova_range) +{ + int ret = ioctl(fd, VHOST_VDPA_GET_IOVA_RANGE, iova_range); + + return ret < 0 ? -errno : 0; +} + /* * The use of this function is for requests that only need to be * applied once. Typically such request occurs at the beginning @@ -512,9 +519,18 @@ static void vhost_vdpa_host_notifiers_uninit(struct vhost_dev *dev, int n) { int i; + /* + * Pack all the changes to the memory regions in a single + * transaction to avoid a few updating of the address space + * topology. + */ + memory_region_transaction_begin(); + for (i = dev->vq_index; i < dev->vq_index + n; i++) { vhost_vdpa_host_notifier_uninit(dev, i); } + + memory_region_transaction_commit(); } static void vhost_vdpa_host_notifiers_init(struct vhost_dev *dev) @@ -527,17 +543,21 @@ static void vhost_vdpa_host_notifiers_init(struct vhost_dev *dev) return; } + /* + * Pack all the changes to the memory regions in a single + * transaction to avoid a few updating of the address space + * topology. + */ + memory_region_transaction_begin(); + for (i = dev->vq_index; i < dev->vq_index + dev->nvqs; i++) { if (vhost_vdpa_host_notifier_init(dev, i)) { - goto err; + vhost_vdpa_host_notifiers_uninit(dev, i - dev->vq_index); + break; } } - return; - -err: - vhost_vdpa_host_notifiers_uninit(dev, i - dev->vq_index); - return; + memory_region_transaction_commit(); } static void vhost_vdpa_svq_cleanup(struct vhost_dev *dev) @@ -716,6 +736,13 @@ static int vhost_vdpa_set_vring_ready(struct vhost_dev *dev) return 0; } +static int vhost_vdpa_set_config_call(struct vhost_dev *dev, + int fd) +{ + trace_vhost_vdpa_set_config_call(dev, fd); + return vhost_vdpa_call(dev, VHOST_VDPA_SET_CONFIG_CALL, &fd); +} + static void vhost_vdpa_dump_config(struct vhost_dev *dev, const uint8_t *config, uint32_t config_len) { @@ -1298,4 +1325,5 @@ const VhostOps vdpa_ops = { .vhost_get_device_id = vhost_vdpa_get_device_id, .vhost_vq_get_addr = vhost_vdpa_vq_get_addr, .vhost_force_iommu = vhost_vdpa_force_iommu, + .vhost_set_config_call = vhost_vdpa_set_config_call, }; diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c index d21c72b..d2b5519 100644 --- a/hw/virtio/vhost-vsock-common.c +++ b/hw/virtio/vhost-vsock-common.c @@ -127,6 +127,15 @@ static void vhost_vsock_common_guest_notifier_mask(VirtIODevice *vdev, int idx, { VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev); + /* + * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 + * as the Marco of configure interrupt's IDX, If this driver does not + * support, the function will return + */ + + if (idx == VIRTIO_CONFIG_IRQ_IDX) { + return; + } vhost_virtqueue_mask(&vvc->vhost_dev, vdev, idx, mask); } @@ -135,6 +144,15 @@ static bool vhost_vsock_common_guest_notifier_pending(VirtIODevice *vdev, { VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev); + /* + * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 + * as the Marco of configure interrupt's IDX, If this driver does not + * support, the function will return + */ + + if (idx == VIRTIO_CONFIG_IRQ_IDX) { + return false; + } return vhost_virtqueue_pending(&vvc->vhost_dev, idx); } diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index fdcd1a8..eb8c4c3 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -1551,7 +1551,7 @@ void vhost_dev_cleanup(struct vhost_dev *hdev) int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev) { BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); - int i, r, e; + int i, r; /* We will pass the notifiers to the kernel, make sure that QEMU * doesn't interfere. @@ -1559,32 +1559,29 @@ int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev) r = virtio_device_grab_ioeventfd(vdev); if (r < 0) { error_report("binding does not support host notifiers"); - goto fail; + return r; } + /* + * Batch all the host notifiers in a single transaction to avoid + * quadratic time complexity in address_space_update_ioeventfds(). + */ + memory_region_transaction_begin(); + for (i = 0; i < hdev->nvqs; ++i) { r = virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), hdev->vq_index + i, true); if (r < 0) { error_report("vhost VQ %d notifier binding failed: %d", i, -r); - goto fail_vq; + memory_region_transaction_commit(); + vhost_dev_disable_notifiers(hdev, vdev); + return r; } } + memory_region_transaction_commit(); + return 0; -fail_vq: - while (--i >= 0) { - e = virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), hdev->vq_index + i, - false); - if (e < 0) { - error_report("vhost VQ %d notifier cleanup error: %d", i, -r); - } - assert (e >= 0); - virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), hdev->vq_index + i); - } - virtio_device_release_ioeventfd(vdev); -fail: - return r; } /* Stop processing guest IO notifications in vhost. @@ -1597,6 +1594,12 @@ void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev) BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); int i, r; + /* + * Batch all the host notifiers in a single transaction to avoid + * quadratic time complexity in address_space_update_ioeventfds(). + */ + memory_region_transaction_begin(); + for (i = 0; i < hdev->nvqs; ++i) { r = virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), hdev->vq_index + i, false); @@ -1604,6 +1607,15 @@ void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev) error_report("vhost VQ %d notifier cleanup failed: %d", i, -r); } assert (r >= 0); + } + + /* + * The transaction expects the ioeventfds to be open when it + * commits. Do it now, before the cleanup loop. + */ + memory_region_transaction_commit(); + + for (i = 0; i < hdev->nvqs; ++i) { virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), hdev->vq_index + i); } virtio_device_release_ioeventfd(vdev); @@ -1640,7 +1652,68 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n, file.index = hdev->vhost_ops->vhost_get_vq_index(hdev, n); r = hdev->vhost_ops->vhost_set_vring_call(hdev, &file); if (r < 0) { - VHOST_OPS_DEBUG(r, "vhost_set_vring_call failed"); + error_report("vhost_set_vring_call failed %d", -r); + } +} + +bool vhost_config_pending(struct vhost_dev *hdev) +{ + assert(hdev->vhost_ops); + if ((hdev->started == false) || + (hdev->vhost_ops->vhost_set_config_call == NULL)) { + return false; + } + + EventNotifier *notifier = + &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier; + return event_notifier_test_and_clear(notifier); +} + +void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev, bool mask) +{ + int fd; + int r; + EventNotifier *notifier = + &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier; + EventNotifier *config_notifier = &vdev->config_notifier; + assert(hdev->vhost_ops); + + if ((hdev->started == false) || + (hdev->vhost_ops->vhost_set_config_call == NULL)) { + return; + } + if (mask) { + assert(vdev->use_guest_notifier_mask); + fd = event_notifier_get_fd(notifier); + } else { + fd = event_notifier_get_fd(config_notifier); + } + r = hdev->vhost_ops->vhost_set_config_call(hdev, fd); + if (r < 0) { + error_report("vhost_set_config_call failed %d", -r); + } +} + +static void vhost_stop_config_intr(struct vhost_dev *dev) +{ + int fd = -1; + assert(dev->vhost_ops); + if (dev->vhost_ops->vhost_set_config_call) { + dev->vhost_ops->vhost_set_config_call(dev, fd); + } +} + +static void vhost_start_config_intr(struct vhost_dev *dev) +{ + int r; + + assert(dev->vhost_ops); + int fd = event_notifier_get_fd(&dev->vdev->config_notifier); + if (dev->vhost_ops->vhost_set_config_call) { + r = dev->vhost_ops->vhost_set_config_call(dev, fd); + if (!r) { + event_notifier_set(&dev->vdev->config_notifier); + } } } @@ -1880,6 +1953,16 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings) } } + r = event_notifier_init( + &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier, 0); + if (r < 0) { + return r; + } + event_notifier_test_and_clear( + &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier); + if (!vdev->use_guest_notifier_mask) { + vhost_config_mask(hdev, vdev, true); + } if (hdev->log_enabled) { uint64_t log_base; @@ -1918,6 +2001,7 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings) vhost_device_iotlb_miss(hdev, vq->used_phys, true); } } + vhost_start_config_intr(hdev); return 0; fail_start: if (vrings) { @@ -1947,6 +2031,9 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings) /* should only be called after backend is connected */ assert(hdev->vhost_ops); + event_notifier_test_and_clear( + &hdev->vqs[VHOST_QUEUE_NUM_CONFIG_INR].masked_config_notifier); + event_notifier_test_and_clear(&vdev->config_notifier); trace_vhost_dev_stop(hdev, vdev->name, vrings); @@ -1969,6 +2056,7 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings) } memory_listener_unregister(&hdev->iommu_listener); } + vhost_stop_config_intr(hdev); vhost_log_put(hdev, true); hdev->started = false; vdev->vhost_started = false; diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c index 97da74e..516425e 100644 --- a/hw/virtio/virtio-crypto.c +++ b/hw/virtio/virtio-crypto.c @@ -1182,6 +1182,15 @@ static void virtio_crypto_guest_notifier_mask(VirtIODevice *vdev, int idx, assert(vcrypto->vhost_started); + /* + * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 + * as the Marco of configure interrupt's IDX, If this driver does not + * support, the function will return + */ + + if (idx == VIRTIO_CONFIG_IRQ_IDX) { + return; + } cryptodev_vhost_virtqueue_mask(vdev, queue, idx, mask); } @@ -1192,6 +1201,15 @@ static bool virtio_crypto_guest_notifier_pending(VirtIODevice *vdev, int idx) assert(vcrypto->vhost_started); + /* + * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 + * as the Marco of configure interrupt's IDX, If this driver does not + * support, the function will return + */ + + if (idx == VIRTIO_CONFIG_IRQ_IDX) { + return false; + } return cryptodev_vhost_virtqueue_pending(vdev, queue, idx); } diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c index d240efe..103260e 100644 --- a/hw/virtio/virtio-mmio.c +++ b/hw/virtio/virtio-mmio.c @@ -670,7 +670,30 @@ static int virtio_mmio_set_guest_notifier(DeviceState *d, int n, bool assign, return 0; } +static int virtio_mmio_set_config_guest_notifier(DeviceState *d, bool assign, + bool with_irqfd) +{ + VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d); + VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); + EventNotifier *notifier = virtio_config_get_guest_notifier(vdev); + int r = 0; + if (assign) { + r = event_notifier_init(notifier, 0); + if (r < 0) { + return r; + } + virtio_config_set_guest_notifier_fd_handler(vdev, assign, with_irqfd); + } else { + virtio_config_set_guest_notifier_fd_handler(vdev, assign, with_irqfd); + event_notifier_cleanup(notifier); + } + if (vdc->guest_notifier_mask && vdev->use_guest_notifier_mask) { + vdc->guest_notifier_mask(vdev, VIRTIO_CONFIG_IRQ_IDX, !assign); + } + return r; +} static int virtio_mmio_set_guest_notifiers(DeviceState *d, int nvqs, bool assign) { @@ -692,6 +715,10 @@ static int virtio_mmio_set_guest_notifiers(DeviceState *d, int nvqs, goto assign_error; } } + r = virtio_mmio_set_config_guest_notifier(d, assign, with_irqfd); + if (r < 0) { + goto assign_error; + } return 0; diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 7063930..247325c 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -784,7 +784,6 @@ static uint32_t virtio_read_config(PCIDevice *pci_dev, } static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy, - unsigned int queue_no, unsigned int vector) { VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector]; @@ -813,112 +812,160 @@ static void kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy, } static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy, - unsigned int queue_no, + EventNotifier *n, unsigned int vector) { VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector]; - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - VirtQueue *vq = virtio_get_queue(vdev, queue_no); - EventNotifier *n = virtio_queue_get_guest_notifier(vq); return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, irqfd->virq); } static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy, - unsigned int queue_no, + EventNotifier *n , unsigned int vector) { - VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); - VirtQueue *vq = virtio_get_queue(vdev, queue_no); - EventNotifier *n = virtio_queue_get_guest_notifier(vq); VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector]; int ret; ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, irqfd->virq); assert(ret == 0); } +static int virtio_pci_get_notifier(VirtIOPCIProxy *proxy, int queue_no, + EventNotifier **n, unsigned int *vector) +{ + VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + VirtQueue *vq; -static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs) + if (queue_no == VIRTIO_CONFIG_IRQ_IDX) { + *n = virtio_config_get_guest_notifier(vdev); + *vector = vdev->config_vector; + } else { + if (!virtio_queue_get_num(vdev, queue_no)) { + return -1; + } + *vector = virtio_queue_vector(vdev, queue_no); + vq = virtio_get_queue(vdev, queue_no); + *n = virtio_queue_get_guest_notifier(vq); + } + return 0; +} + +static int kvm_virtio_pci_vector_use_one(VirtIOPCIProxy *proxy, int queue_no) { + unsigned int vector; + int ret; + EventNotifier *n; PCIDevice *dev = &proxy->pci_dev; VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); - unsigned int vector; - int ret, queue_no; - for (queue_no = 0; queue_no < nvqs; queue_no++) { - if (!virtio_queue_get_num(vdev, queue_no)) { - break; - } - vector = virtio_queue_vector(vdev, queue_no); - if (vector >= msix_nr_vectors_allocated(dev)) { - continue; - } - ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector); + ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); + if (ret < 0) { + return ret; + } + if (vector >= msix_nr_vectors_allocated(dev)) { + return 0; + } + ret = kvm_virtio_pci_vq_vector_use(proxy, vector); + if (ret < 0) { + goto undo; + } + /* + * If guest supports masking, set up irqfd now. + * Otherwise, delay until unmasked in the frontend. + */ + if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { + ret = kvm_virtio_pci_irqfd_use(proxy, n, vector); if (ret < 0) { + kvm_virtio_pci_vq_vector_release(proxy, vector); goto undo; } - /* If guest supports masking, set up irqfd now. - * Otherwise, delay until unmasked in the frontend. - */ - if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { - ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector); - if (ret < 0) { - kvm_virtio_pci_vq_vector_release(proxy, vector); - goto undo; - } - } } - return 0; + return 0; undo: - while (--queue_no >= 0) { - vector = virtio_queue_vector(vdev, queue_no); - if (vector >= msix_nr_vectors_allocated(dev)) { - continue; + + vector = virtio_queue_vector(vdev, queue_no); + if (vector >= msix_nr_vectors_allocated(dev)) { + return ret; + } + if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { + ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); + if (ret < 0) { + return ret; } - if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { - kvm_virtio_pci_irqfd_release(proxy, queue_no, vector); + kvm_virtio_pci_irqfd_release(proxy, n, vector); + } + return ret; +} +static int kvm_virtio_pci_vector_vq_use(VirtIOPCIProxy *proxy, int nvqs) +{ + int queue_no; + int ret = 0; + VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + + for (queue_no = 0; queue_no < nvqs; queue_no++) { + if (!virtio_queue_get_num(vdev, queue_no)) { + return -1; } - kvm_virtio_pci_vq_vector_release(proxy, vector); + ret = kvm_virtio_pci_vector_use_one(proxy, queue_no); } return ret; } -static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs) +static int kvm_virtio_pci_vector_config_use(VirtIOPCIProxy *proxy) +{ + return kvm_virtio_pci_vector_use_one(proxy, VIRTIO_CONFIG_IRQ_IDX); +} + +static void kvm_virtio_pci_vector_release_one(VirtIOPCIProxy *proxy, + int queue_no) { - PCIDevice *dev = &proxy->pci_dev; VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); unsigned int vector; - int queue_no; + EventNotifier *n; + int ret; VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); + PCIDevice *dev = &proxy->pci_dev; + + ret = virtio_pci_get_notifier(proxy, queue_no, &n, &vector); + if (ret < 0) { + return; + } + if (vector >= msix_nr_vectors_allocated(dev)) { + return; + } + if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { + kvm_virtio_pci_irqfd_release(proxy, n, vector); + } + kvm_virtio_pci_vq_vector_release(proxy, vector); +} + +static void kvm_virtio_pci_vector_vq_release(VirtIOPCIProxy *proxy, int nvqs) +{ + int queue_no; + VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); for (queue_no = 0; queue_no < nvqs; queue_no++) { if (!virtio_queue_get_num(vdev, queue_no)) { break; } - vector = virtio_queue_vector(vdev, queue_no); - if (vector >= msix_nr_vectors_allocated(dev)) { - continue; - } - /* If guest supports masking, clean up irqfd now. - * Otherwise, it was cleaned when masked in the frontend. - */ - if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { - kvm_virtio_pci_irqfd_release(proxy, queue_no, vector); - } - kvm_virtio_pci_vq_vector_release(proxy, vector); + kvm_virtio_pci_vector_release_one(proxy, queue_no); } } -static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy, +static void kvm_virtio_pci_vector_config_release(VirtIOPCIProxy *proxy) +{ + kvm_virtio_pci_vector_release_one(proxy, VIRTIO_CONFIG_IRQ_IDX); +} + +static int virtio_pci_one_vector_unmask(VirtIOPCIProxy *proxy, unsigned int queue_no, unsigned int vector, - MSIMessage msg) + MSIMessage msg, + EventNotifier *n) { VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); - VirtQueue *vq = virtio_get_queue(vdev, queue_no); - EventNotifier *n = virtio_queue_get_guest_notifier(vq); VirtIOIRQFD *irqfd; int ret = 0; @@ -945,14 +992,15 @@ static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy, event_notifier_set(n); } } else { - ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector); + ret = kvm_virtio_pci_irqfd_use(proxy, n, vector); } return ret; } -static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy, +static void virtio_pci_one_vector_mask(VirtIOPCIProxy *proxy, unsigned int queue_no, - unsigned int vector) + unsigned int vector, + EventNotifier *n) { VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); @@ -963,7 +1011,7 @@ static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy, if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) { k->guest_notifier_mask(vdev, queue_no, true); } else { - kvm_virtio_pci_irqfd_release(proxy, queue_no, vector); + kvm_virtio_pci_irqfd_release(proxy, n, vector); } } @@ -973,6 +1021,7 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector, VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev); VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); VirtQueue *vq = virtio_vector_first_queue(vdev, vector); + EventNotifier *n; int ret, index, unmasked = 0; while (vq) { @@ -981,7 +1030,8 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector, break; } if (index < proxy->nvqs_with_notifiers) { - ret = virtio_pci_vq_vector_unmask(proxy, index, vector, msg); + n = virtio_queue_get_guest_notifier(vq); + ret = virtio_pci_one_vector_unmask(proxy, index, vector, msg, n); if (ret < 0) { goto undo; } @@ -989,15 +1039,26 @@ static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector, } vq = virtio_vector_next_queue(vq); } - + /* unmask config intr */ + if (vector == vdev->config_vector) { + n = virtio_config_get_guest_notifier(vdev); + ret = virtio_pci_one_vector_unmask(proxy, VIRTIO_CONFIG_IRQ_IDX, vector, + msg, n); + if (ret < 0) { + goto undo_config; + } + } return 0; - +undo_config: + n = virtio_config_get_guest_notifier(vdev); + virtio_pci_one_vector_mask(proxy, VIRTIO_CONFIG_IRQ_IDX, vector, n); undo: vq = virtio_vector_first_queue(vdev, vector); while (vq && unmasked >= 0) { index = virtio_get_queue_index(vq); if (index < proxy->nvqs_with_notifiers) { - virtio_pci_vq_vector_mask(proxy, index, vector); + n = virtio_queue_get_guest_notifier(vq); + virtio_pci_one_vector_mask(proxy, index, vector, n); --unmasked; } vq = virtio_vector_next_queue(vq); @@ -1010,18 +1071,25 @@ static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector) VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev); VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); VirtQueue *vq = virtio_vector_first_queue(vdev, vector); + EventNotifier *n; int index; while (vq) { index = virtio_get_queue_index(vq); + n = virtio_queue_get_guest_notifier(vq); if (!virtio_queue_get_num(vdev, index)) { break; } if (index < proxy->nvqs_with_notifiers) { - virtio_pci_vq_vector_mask(proxy, index, vector); + virtio_pci_one_vector_mask(proxy, index, vector, n); } vq = virtio_vector_next_queue(vq); } + + if (vector == vdev->config_vector) { + n = virtio_config_get_guest_notifier(vdev); + virtio_pci_one_vector_mask(proxy, VIRTIO_CONFIG_IRQ_IDX, vector, n); + } } static void virtio_pci_vector_poll(PCIDevice *dev, @@ -1034,19 +1102,17 @@ static void virtio_pci_vector_poll(PCIDevice *dev, int queue_no; unsigned int vector; EventNotifier *notifier; - VirtQueue *vq; + int ret; for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) { - if (!virtio_queue_get_num(vdev, queue_no)) { + ret = virtio_pci_get_notifier(proxy, queue_no, ¬ifier, &vector); + if (ret < 0) { break; } - vector = virtio_queue_vector(vdev, queue_no); if (vector < vector_start || vector >= vector_end || !msix_is_masked(dev, vector)) { continue; } - vq = virtio_get_queue(vdev, queue_no); - notifier = virtio_queue_get_guest_notifier(vq); if (k->guest_notifier_pending) { if (k->guest_notifier_pending(vdev, queue_no)) { msix_set_pending(dev, vector); @@ -1055,6 +1121,34 @@ static void virtio_pci_vector_poll(PCIDevice *dev, msix_set_pending(dev, vector); } } + /* poll the config intr */ + ret = virtio_pci_get_notifier(proxy, VIRTIO_CONFIG_IRQ_IDX, ¬ifier, + &vector); + if (ret < 0) { + return; + } + if (vector < vector_start || vector >= vector_end || + !msix_is_masked(dev, vector)) { + return; + } + if (k->guest_notifier_pending) { + if (k->guest_notifier_pending(vdev, VIRTIO_CONFIG_IRQ_IDX)) { + msix_set_pending(dev, vector); + } + } else if (event_notifier_test_and_clear(notifier)) { + msix_set_pending(dev, vector); + } +} + +void virtio_pci_set_guest_notifier_fd_handler(VirtIODevice *vdev, VirtQueue *vq, + int n, bool assign, + bool with_irqfd) +{ + if (n == VIRTIO_CONFIG_IRQ_IDX) { + virtio_config_set_guest_notifier_fd_handler(vdev, assign, with_irqfd); + } else { + virtio_queue_set_guest_notifier_fd_handler(vq, assign, with_irqfd); + } } static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign, @@ -1063,17 +1157,25 @@ static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign, VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); - VirtQueue *vq = virtio_get_queue(vdev, n); - EventNotifier *notifier = virtio_queue_get_guest_notifier(vq); + VirtQueue *vq = NULL; + EventNotifier *notifier = NULL; + + if (n == VIRTIO_CONFIG_IRQ_IDX) { + notifier = virtio_config_get_guest_notifier(vdev); + } else { + vq = virtio_get_queue(vdev, n); + notifier = virtio_queue_get_guest_notifier(vq); + } if (assign) { int r = event_notifier_init(notifier, 0); if (r < 0) { return r; } - virtio_queue_set_guest_notifier_fd_handler(vq, true, with_irqfd); + virtio_pci_set_guest_notifier_fd_handler(vdev, vq, n, true, with_irqfd); } else { - virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd); + virtio_pci_set_guest_notifier_fd_handler(vdev, vq, n, false, + with_irqfd); event_notifier_cleanup(notifier); } @@ -1116,10 +1218,13 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign) proxy->nvqs_with_notifiers = nvqs; /* Must unset vector notifier while guest notifier is still assigned */ - if ((proxy->vector_irqfd || k->guest_notifier_mask) && !assign) { + if ((proxy->vector_irqfd || + (vdev->use_guest_notifier_mask && k->guest_notifier_mask)) && + !assign) { msix_unset_vector_notifiers(&proxy->pci_dev); if (proxy->vector_irqfd) { - kvm_virtio_pci_vector_release(proxy, nvqs); + kvm_virtio_pci_vector_vq_release(proxy, nvqs); + kvm_virtio_pci_vector_config_release(proxy); g_free(proxy->vector_irqfd); proxy->vector_irqfd = NULL; } @@ -1135,20 +1240,30 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign) goto assign_error; } } - + r = virtio_pci_set_guest_notifier(d, VIRTIO_CONFIG_IRQ_IDX, assign, + with_irqfd); + if (r < 0) { + goto config_assign_error; + } /* Must set vector notifier after guest notifier has been assigned */ - if ((with_irqfd || k->guest_notifier_mask) && assign) { + if ((with_irqfd || + (vdev->use_guest_notifier_mask && k->guest_notifier_mask)) && + assign) { if (with_irqfd) { proxy->vector_irqfd = g_malloc0(sizeof(*proxy->vector_irqfd) * msix_nr_vectors_allocated(&proxy->pci_dev)); - r = kvm_virtio_pci_vector_use(proxy, nvqs); + r = kvm_virtio_pci_vector_vq_use(proxy, nvqs); + if (r < 0) { + goto config_assign_error; + } + r = kvm_virtio_pci_vector_config_use(proxy); if (r < 0) { - goto assign_error; + goto config_error; } } - r = msix_set_vector_notifiers(&proxy->pci_dev, - virtio_pci_vector_unmask, + + r = msix_set_vector_notifiers(&proxy->pci_dev, virtio_pci_vector_unmask, virtio_pci_vector_mask, virtio_pci_vector_poll); if (r < 0) { @@ -1161,15 +1276,23 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign) notifiers_error: if (with_irqfd) { assert(assign); - kvm_virtio_pci_vector_release(proxy, nvqs); + kvm_virtio_pci_vector_vq_release(proxy, nvqs); } - +config_error: + if (with_irqfd) { + kvm_virtio_pci_vector_config_release(proxy); + } +config_assign_error: + virtio_pci_set_guest_notifier(d, VIRTIO_CONFIG_IRQ_IDX, !assign, + with_irqfd); assign_error: /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */ assert(assign); while (--n >= 0) { virtio_pci_set_guest_notifier(d, n, !assign, with_irqfd); } + g_free(proxy->vector_irqfd); + proxy->vector_irqfd = NULL; return r; } diff --git a/hw/virtio/virtio-qmp.c b/hw/virtio/virtio-qmp.c index 8e72826..e4d4bec 100644 --- a/hw/virtio/virtio-qmp.c +++ b/hw/virtio/virtio-qmp.c @@ -10,9 +10,14 @@ */ #include "qemu/osdep.h" -#include "hw/virtio/virtio.h" #include "virtio-qmp.h" +#include "qapi/error.h" +#include "qapi/qapi-commands-virtio.h" +#include "qapi/qapi-commands-qom.h" +#include "qapi/qmp/qobject.h" +#include "qapi/qmp/qjson.h" + #include "standard-headers/linux/virtio_ids.h" #include "standard-headers/linux/vhost_types.h" #include "standard-headers/linux/virtio_blk.h" @@ -657,3 +662,188 @@ VirtioDeviceFeatures *qmp_decode_features(uint16_t device_id, uint64_t bitmap) return features; } + +VirtioInfoList *qmp_x_query_virtio(Error **errp) +{ + VirtioInfoList *list = NULL; + VirtioInfoList *node; + VirtIODevice *vdev; + + QTAILQ_FOREACH(vdev, &virtio_list, next) { + DeviceState *dev = DEVICE(vdev); + Error *err = NULL; + QObject *obj = qmp_qom_get(dev->canonical_path, "realized", &err); + + if (err == NULL) { + GString *is_realized = qobject_to_json_pretty(obj, true); + /* virtio device is NOT realized, remove it from list */ + if (!strncmp(is_realized->str, "false", 4)) { + QTAILQ_REMOVE(&virtio_list, vdev, next); + } else { + node = g_new0(VirtioInfoList, 1); + node->value = g_new(VirtioInfo, 1); + node->value->path = g_strdup(dev->canonical_path); + node->value->name = g_strdup(vdev->name); + QAPI_LIST_PREPEND(list, node->value); + } + g_string_free(is_realized, true); + } + qobject_unref(obj); + } + + return list; +} + +VirtIODevice *qmp_find_virtio_device(const char *path) +{ + VirtIODevice *vdev; + + QTAILQ_FOREACH(vdev, &virtio_list, next) { + DeviceState *dev = DEVICE(vdev); + + if (strcmp(dev->canonical_path, path) != 0) { + continue; + } + + Error *err = NULL; + QObject *obj = qmp_qom_get(dev->canonical_path, "realized", &err); + if (err == NULL) { + GString *is_realized = qobject_to_json_pretty(obj, true); + /* virtio device is NOT realized, remove it from list */ + if (!strncmp(is_realized->str, "false", 4)) { + g_string_free(is_realized, true); + qobject_unref(obj); + QTAILQ_REMOVE(&virtio_list, vdev, next); + return NULL; + } + g_string_free(is_realized, true); + } else { + /* virtio device doesn't exist in QOM tree */ + QTAILQ_REMOVE(&virtio_list, vdev, next); + qobject_unref(obj); + return NULL; + } + /* device exists in QOM tree & is realized */ + qobject_unref(obj); + return vdev; + } + return NULL; +} + +VirtioStatus *qmp_x_query_virtio_status(const char *path, Error **errp) +{ + VirtIODevice *vdev; + VirtioStatus *status; + + vdev = qmp_find_virtio_device(path); + if (vdev == NULL) { + error_setg(errp, "Path %s is not a VirtIODevice", path); + return NULL; + } + + status = g_new0(VirtioStatus, 1); + status->name = g_strdup(vdev->name); + status->device_id = vdev->device_id; + status->vhost_started = vdev->vhost_started; + status->guest_features = qmp_decode_features(vdev->device_id, + vdev->guest_features); + status->host_features = qmp_decode_features(vdev->device_id, + vdev->host_features); + status->backend_features = qmp_decode_features(vdev->device_id, + vdev->backend_features); + + switch (vdev->device_endian) { + case VIRTIO_DEVICE_ENDIAN_LITTLE: + status->device_endian = g_strdup("little"); + break; + case VIRTIO_DEVICE_ENDIAN_BIG: + status->device_endian = g_strdup("big"); + break; + default: + status->device_endian = g_strdup("unknown"); + break; + } + + status->num_vqs = virtio_get_num_queues(vdev); + status->status = qmp_decode_status(vdev->status); + status->isr = vdev->isr; + status->queue_sel = vdev->queue_sel; + status->vm_running = vdev->vm_running; + status->broken = vdev->broken; + status->disabled = vdev->disabled; + status->use_started = vdev->use_started; + status->started = vdev->started; + status->start_on_kick = vdev->start_on_kick; + status->disable_legacy_check = vdev->disable_legacy_check; + status->bus_name = g_strdup(vdev->bus_name); + status->use_guest_notifier_mask = vdev->use_guest_notifier_mask; + + if (vdev->vhost_started) { + VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); + struct vhost_dev *hdev = vdc->get_vhost(vdev); + + status->vhost_dev = g_new0(VhostStatus, 1); + status->vhost_dev->n_mem_sections = hdev->n_mem_sections; + status->vhost_dev->n_tmp_sections = hdev->n_tmp_sections; + status->vhost_dev->nvqs = hdev->nvqs; + status->vhost_dev->vq_index = hdev->vq_index; + status->vhost_dev->features = + qmp_decode_features(vdev->device_id, hdev->features); + status->vhost_dev->acked_features = + qmp_decode_features(vdev->device_id, hdev->acked_features); + status->vhost_dev->backend_features = + qmp_decode_features(vdev->device_id, hdev->backend_features); + status->vhost_dev->protocol_features = + qmp_decode_protocols(hdev->protocol_features); + status->vhost_dev->max_queues = hdev->max_queues; + status->vhost_dev->backend_cap = hdev->backend_cap; + status->vhost_dev->log_enabled = hdev->log_enabled; + status->vhost_dev->log_size = hdev->log_size; + } + + return status; +} + +VirtVhostQueueStatus *qmp_x_query_virtio_vhost_queue_status(const char *path, + uint16_t queue, + Error **errp) +{ + VirtIODevice *vdev; + VirtVhostQueueStatus *status; + + vdev = qmp_find_virtio_device(path); + if (vdev == NULL) { + error_setg(errp, "Path %s is not a VirtIODevice", path); + return NULL; + } + + if (!vdev->vhost_started) { + error_setg(errp, "Error: vhost device has not started yet"); + return NULL; + } + + VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); + struct vhost_dev *hdev = vdc->get_vhost(vdev); + + if (queue < hdev->vq_index || queue >= hdev->vq_index + hdev->nvqs) { + error_setg(errp, "Invalid vhost virtqueue number %d", queue); + return NULL; + } + + status = g_new0(VirtVhostQueueStatus, 1); + status->name = g_strdup(vdev->name); + status->kick = hdev->vqs[queue].kick; + status->call = hdev->vqs[queue].call; + status->desc = (uintptr_t)hdev->vqs[queue].desc; + status->avail = (uintptr_t)hdev->vqs[queue].avail; + status->used = (uintptr_t)hdev->vqs[queue].used; + status->num = hdev->vqs[queue].num; + status->desc_phys = hdev->vqs[queue].desc_phys; + status->desc_size = hdev->vqs[queue].desc_size; + status->avail_phys = hdev->vqs[queue].avail_phys; + status->avail_size = hdev->vqs[queue].avail_size; + status->used_phys = hdev->vqs[queue].used_phys; + status->used_size = hdev->vqs[queue].used_size; + + return status; +} diff --git a/hw/virtio/virtio-qmp.h b/hw/virtio/virtio-qmp.h index 075fc27..8af5f5e 100644 --- a/hw/virtio/virtio-qmp.h +++ b/hw/virtio/virtio-qmp.h @@ -12,7 +12,17 @@ #define HW_VIRTIO_QMP_H #include "qapi/qapi-types-virtio.h" +#include "hw/virtio/virtio.h" +#include "hw/virtio/vhost.h" +#include "qemu/queue.h" + +typedef QTAILQ_HEAD(QmpVirtIODeviceList, VirtIODevice) QmpVirtIODeviceList; + +/* QAPI list of realized VirtIODevices */ +extern QmpVirtIODeviceList virtio_list; + +VirtIODevice *qmp_find_virtio_device(const char *path); VirtioDeviceStatus *qmp_decode_status(uint8_t bitmap); VhostDeviceProtocols *qmp_decode_protocols(uint64_t bitmap); VirtioDeviceFeatures *qmp_decode_features(uint16_t device_id, uint64_t bitmap); diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 289eb71..f35178f 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -13,10 +13,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qapi/qmp/qdict.h" #include "qapi/qapi-commands-virtio.h" -#include "qapi/qapi-commands-qom.h" -#include "qapi/qmp/qjson.h" #include "trace.h" #include "qemu/error-report.h" #include "qemu/log.h" @@ -25,6 +22,7 @@ #include "qom/object_interfaces.h" #include "hw/core/cpu.h" #include "hw/virtio/virtio.h" +#include "hw/virtio/vhost.h" #include "migration/qemu-file-types.h" #include "qemu/atomic.h" #include "hw/virtio/virtio-bus.h" @@ -47,8 +45,7 @@ #include "standard-headers/linux/virtio_mem.h" #include "standard-headers/linux/virtio_vsock.h" -/* QAPI list of realized VirtIODevices */ -static QTAILQ_HEAD(, VirtIODevice) virtio_list; +QmpVirtIODeviceList virtio_list; /* * Maximum size of virtio device config space @@ -3417,7 +3414,14 @@ static void virtio_queue_guest_notifier_read(EventNotifier *n) virtio_irq(vq); } } +static void virtio_config_guest_notifier_read(EventNotifier *n) +{ + VirtIODevice *vdev = container_of(n, VirtIODevice, config_notifier); + if (event_notifier_test_and_clear(n)) { + virtio_notify_config(vdev); + } +} void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign, bool with_irqfd) { @@ -3434,6 +3438,23 @@ void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign, } } +void virtio_config_set_guest_notifier_fd_handler(VirtIODevice *vdev, + bool assign, bool with_irqfd) +{ + EventNotifier *n; + n = &vdev->config_notifier; + if (assign && !with_irqfd) { + event_notifier_set_handler(n, virtio_config_guest_notifier_read); + } else { + event_notifier_set_handler(n, NULL); + } + if (!assign) { + /* Test and clear notifier before closing it,*/ + /* in case poll callback didn't have time to run. */ + virtio_config_guest_notifier_read(n); + } +} + EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq) { return &vq->guest_notifier; @@ -3514,6 +3535,11 @@ EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq) return &vq->host_notifier; } +EventNotifier *virtio_config_get_guest_notifier(VirtIODevice *vdev) +{ + return &vdev->config_notifier; +} + void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled) { vq->host_notifier_enabled = enabled; @@ -3795,191 +3821,6 @@ bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev) return virtio_bus_ioeventfd_enabled(vbus); } -VirtioInfoList *qmp_x_query_virtio(Error **errp) -{ - VirtioInfoList *list = NULL; - VirtioInfoList *node; - VirtIODevice *vdev; - - QTAILQ_FOREACH(vdev, &virtio_list, next) { - DeviceState *dev = DEVICE(vdev); - Error *err = NULL; - QObject *obj = qmp_qom_get(dev->canonical_path, "realized", &err); - - if (err == NULL) { - GString *is_realized = qobject_to_json_pretty(obj, true); - /* virtio device is NOT realized, remove it from list */ - if (!strncmp(is_realized->str, "false", 4)) { - QTAILQ_REMOVE(&virtio_list, vdev, next); - } else { - node = g_new0(VirtioInfoList, 1); - node->value = g_new(VirtioInfo, 1); - node->value->path = g_strdup(dev->canonical_path); - node->value->name = g_strdup(vdev->name); - QAPI_LIST_PREPEND(list, node->value); - } - g_string_free(is_realized, true); - } - qobject_unref(obj); - } - - return list; -} - -static VirtIODevice *virtio_device_find(const char *path) -{ - VirtIODevice *vdev; - - QTAILQ_FOREACH(vdev, &virtio_list, next) { - DeviceState *dev = DEVICE(vdev); - - if (strcmp(dev->canonical_path, path) != 0) { - continue; - } - - Error *err = NULL; - QObject *obj = qmp_qom_get(dev->canonical_path, "realized", &err); - if (err == NULL) { - GString *is_realized = qobject_to_json_pretty(obj, true); - /* virtio device is NOT realized, remove it from list */ - if (!strncmp(is_realized->str, "false", 4)) { - g_string_free(is_realized, true); - qobject_unref(obj); - QTAILQ_REMOVE(&virtio_list, vdev, next); - return NULL; - } - g_string_free(is_realized, true); - } else { - /* virtio device doesn't exist in QOM tree */ - QTAILQ_REMOVE(&virtio_list, vdev, next); - qobject_unref(obj); - return NULL; - } - /* device exists in QOM tree & is realized */ - qobject_unref(obj); - return vdev; - } - return NULL; -} - -VirtioStatus *qmp_x_query_virtio_status(const char *path, Error **errp) -{ - VirtIODevice *vdev; - VirtioStatus *status; - - vdev = virtio_device_find(path); - if (vdev == NULL) { - error_setg(errp, "Path %s is not a VirtIODevice", path); - return NULL; - } - - status = g_new0(VirtioStatus, 1); - status->name = g_strdup(vdev->name); - status->device_id = vdev->device_id; - status->vhost_started = vdev->vhost_started; - status->guest_features = qmp_decode_features(vdev->device_id, - vdev->guest_features); - status->host_features = qmp_decode_features(vdev->device_id, - vdev->host_features); - status->backend_features = qmp_decode_features(vdev->device_id, - vdev->backend_features); - - switch (vdev->device_endian) { - case VIRTIO_DEVICE_ENDIAN_LITTLE: - status->device_endian = g_strdup("little"); - break; - case VIRTIO_DEVICE_ENDIAN_BIG: - status->device_endian = g_strdup("big"); - break; - default: - status->device_endian = g_strdup("unknown"); - break; - } - - status->num_vqs = virtio_get_num_queues(vdev); - status->status = qmp_decode_status(vdev->status); - status->isr = vdev->isr; - status->queue_sel = vdev->queue_sel; - status->vm_running = vdev->vm_running; - status->broken = vdev->broken; - status->disabled = vdev->disabled; - status->use_started = vdev->use_started; - status->started = vdev->started; - status->start_on_kick = vdev->start_on_kick; - status->disable_legacy_check = vdev->disable_legacy_check; - status->bus_name = g_strdup(vdev->bus_name); - status->use_guest_notifier_mask = vdev->use_guest_notifier_mask; - - if (vdev->vhost_started) { - VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); - struct vhost_dev *hdev = vdc->get_vhost(vdev); - - status->vhost_dev = g_new0(VhostStatus, 1); - status->vhost_dev->n_mem_sections = hdev->n_mem_sections; - status->vhost_dev->n_tmp_sections = hdev->n_tmp_sections; - status->vhost_dev->nvqs = hdev->nvqs; - status->vhost_dev->vq_index = hdev->vq_index; - status->vhost_dev->features = - qmp_decode_features(vdev->device_id, hdev->features); - status->vhost_dev->acked_features = - qmp_decode_features(vdev->device_id, hdev->acked_features); - status->vhost_dev->backend_features = - qmp_decode_features(vdev->device_id, hdev->backend_features); - status->vhost_dev->protocol_features = - qmp_decode_protocols(hdev->protocol_features); - status->vhost_dev->max_queues = hdev->max_queues; - status->vhost_dev->backend_cap = hdev->backend_cap; - status->vhost_dev->log_enabled = hdev->log_enabled; - status->vhost_dev->log_size = hdev->log_size; - } - - return status; -} - -VirtVhostQueueStatus *qmp_x_query_virtio_vhost_queue_status(const char *path, - uint16_t queue, - Error **errp) -{ - VirtIODevice *vdev; - VirtVhostQueueStatus *status; - - vdev = virtio_device_find(path); - if (vdev == NULL) { - error_setg(errp, "Path %s is not a VirtIODevice", path); - return NULL; - } - - if (!vdev->vhost_started) { - error_setg(errp, "Error: vhost device has not started yet"); - return NULL; - } - - VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev); - struct vhost_dev *hdev = vdc->get_vhost(vdev); - - if (queue < hdev->vq_index || queue >= hdev->vq_index + hdev->nvqs) { - error_setg(errp, "Invalid vhost virtqueue number %d", queue); - return NULL; - } - - status = g_new0(VirtVhostQueueStatus, 1); - status->name = g_strdup(vdev->name); - status->kick = hdev->vqs[queue].kick; - status->call = hdev->vqs[queue].call; - status->desc = (uintptr_t)hdev->vqs[queue].desc; - status->avail = (uintptr_t)hdev->vqs[queue].avail; - status->used = (uintptr_t)hdev->vqs[queue].used; - status->num = hdev->vqs[queue].num; - status->desc_phys = hdev->vqs[queue].desc_phys; - status->desc_size = hdev->vqs[queue].desc_size; - status->avail_phys = hdev->vqs[queue].avail_phys; - status->avail_size = hdev->vqs[queue].avail_size; - status->used_phys = hdev->vqs[queue].used_phys; - status->used_size = hdev->vqs[queue].used_size; - - return status; -} - VirtQueueStatus *qmp_x_query_virtio_queue_status(const char *path, uint16_t queue, Error **errp) @@ -3987,7 +3828,7 @@ VirtQueueStatus *qmp_x_query_virtio_queue_status(const char *path, VirtIODevice *vdev; VirtQueueStatus *status; - vdev = virtio_device_find(path); + vdev = qmp_find_virtio_device(path); if (vdev == NULL) { error_setg(errp, "Path %s is not a VirtIODevice", path); return NULL; @@ -4080,7 +3921,7 @@ VirtioQueueElement *qmp_x_query_virtio_queue_element(const char *path, VirtQueue *vq; VirtioQueueElement *element = NULL; - vdev = virtio_device_find(path); + vdev = qmp_find_virtio_device(path); if (vdev == NULL) { error_setg(errp, "Path %s is not a VirtIO device", path); return NULL; diff --git a/hw/watchdog/wdt_i6300esb.c b/hw/watchdog/wdt_i6300esb.c index 5693ec6..54c167c 100644 --- a/hw/watchdog/wdt_i6300esb.c +++ b/hw/watchdog/wdt_i6300esb.c @@ -24,7 +24,7 @@ #include "qemu/module.h" #include "qemu/timer.h" #include "sysemu/watchdog.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "migration/vmstate.h" #include "qom/object.h" diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h index e7c4316..cf10fc7 100644 --- a/hw/xen/xen_pt.h +++ b/hw/xen/xen_pt.h @@ -2,7 +2,6 @@ #define XEN_PT_H #include "hw/xen/xen_common.h" -#include "hw/pci/pci.h" #include "xen-host-pci-device.h" #include "qom/object.h" diff --git a/include/exec/plugin-gen.h b/include/exec/plugin-gen.h index 5004728..5f5506f 100644 --- a/include/exec/plugin-gen.h +++ b/include/exec/plugin-gen.h @@ -12,6 +12,7 @@ #ifndef QEMU_PLUGIN_GEN_H #define QEMU_PLUGIN_GEN_H +#include "exec/cpu_ldst.h" #include "qemu/plugin.h" #include "tcg/tcg.h" diff --git a/include/hw/acpi/erst.h b/include/hw/acpi/erst.h index b747fe7..b2ff663 100644 --- a/include/hw/acpi/erst.h +++ b/include/hw/acpi/erst.h @@ -11,6 +11,9 @@ #ifndef HW_ACPI_ERST_H #define HW_ACPI_ERST_H +#include "hw/acpi/bios-linker-loader.h" +#include "qom/object.h" + void build_erst(GArray *table_data, BIOSLinker *linker, Object *erst_dev, const char *oem_id, const char *oem_table_id); diff --git a/include/hw/acpi/piix4.h b/include/hw/acpi/piix4.h index 32686a7..be1f8ea 100644 --- a/include/hw/acpi/piix4.h +++ b/include/hw/acpi/piix4.h @@ -22,7 +22,7 @@ #ifndef HW_ACPI_PIIX4_H #define HW_ACPI_PIIX4_H -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/acpi/acpi.h" #include "hw/acpi/cpu_hotplug.h" #include "hw/acpi/memory_hotplug.h" diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h index a76dc7b..f9240ff 100644 --- a/include/hw/arm/allwinner-a10.h +++ b/include/hw/arm/allwinner-a10.h @@ -4,6 +4,7 @@ #include "qemu/error-report.h" #include "hw/char/serial.h" #include "hw/arm/boot.h" +#include "hw/pci/pci_device.h" #include "hw/timer/allwinner-a10-pit.h" #include "hw/intc/allwinner-a10-pic.h" #include "hw/net/allwinner_emac.h" diff --git a/include/hw/boards.h b/include/hw/boards.h index 8e1a590..6fbbfd5 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -129,11 +129,14 @@ typedef struct { * @prefer_sockets - whether sockets are preferred over cores in smp parsing * @dies_supported - whether dies are supported by the machine * @clusters_supported - whether clusters are supported by the machine + * @has_clusters - whether clusters are explicitly specified in the user + * provided SMP configuration */ typedef struct { bool prefer_sockets; bool dies_supported; bool clusters_supported; + bool has_clusters; } SMPCompatProps; /** diff --git a/include/hw/char/cmsdk-apb-uart.h b/include/hw/char/cmsdk-apb-uart.h index 9daff0e..64b0a3d 100644 --- a/include/hw/char/cmsdk-apb-uart.h +++ b/include/hw/char/cmsdk-apb-uart.h @@ -15,6 +15,7 @@ #include "hw/qdev-properties.h" #include "hw/sysbus.h" #include "chardev/char-fe.h" +#include "qapi/error.h" #include "qom/object.h" #define TYPE_CMSDK_APB_UART "cmsdk-apb-uart" diff --git a/include/hw/char/goldfish_tty.h b/include/hw/char/goldfish_tty.h index 7503d2f..d59733e 100644 --- a/include/hw/char/goldfish_tty.h +++ b/include/hw/char/goldfish_tty.h @@ -12,6 +12,7 @@ #include "qemu/fifo8.h" #include "chardev/char-fe.h" +#include "hw/sysbus.h" #define TYPE_GOLDFISH_TTY "goldfish_tty" OBJECT_DECLARE_SIMPLE_TYPE(GoldfishTTYState, GOLDFISH_TTY) diff --git a/include/hw/char/xilinx_uartlite.h b/include/hw/char/xilinx_uartlite.h index bb32d0f..dd09c06 100644 --- a/include/hw/char/xilinx_uartlite.h +++ b/include/hw/char/xilinx_uartlite.h @@ -17,6 +17,7 @@ #include "hw/qdev-properties.h" #include "hw/sysbus.h" +#include "qapi/error.h" static inline DeviceState *xilinx_uartlite_create(hwaddr addr, qemu_irq irq, diff --git a/include/hw/cris/etraxfs.h b/include/hw/cris/etraxfs.h index 8b01ed6..467b529 100644 --- a/include/hw/cris/etraxfs.h +++ b/include/hw/cris/etraxfs.h @@ -29,6 +29,7 @@ #include "hw/cris/etraxfs_dma.h" #include "hw/qdev-properties.h" #include "hw/sysbus.h" +#include "qapi/error.h" DeviceState *etraxfs_eth_init(NICInfo *nd, hwaddr base, int phyaddr, struct etraxfs_dma_client *dma_out, diff --git a/include/hw/cxl/cxl.h b/include/hw/cxl/cxl.h index 38e0e27..b161be5 100644 --- a/include/hw/cxl/cxl.h +++ b/include/hw/cxl/cxl.h @@ -13,7 +13,6 @@ #include "qapi/qapi-types-machine.h" #include "qapi/qapi-visit-machine.h" -#include "hw/pci/pci_bridge.h" #include "hw/pci/pci_host.h" #include "cxl_pci.h" #include "cxl_component.h" @@ -24,10 +23,12 @@ #define CXL_WINDOW_MAX 10 +typedef struct PXBDev PXBDev; + typedef struct CXLFixedWindow { uint64_t size; char **targets; - struct PXBDev *target_hbs[8]; + PXBDev *target_hbs[8]; uint8_t num_targets; uint8_t enc_int_ways; uint8_t enc_int_gran; diff --git a/include/hw/cxl/cxl_cdat.h b/include/hw/cxl/cxl_cdat.h index e9eda00..7f67638 100644 --- a/include/hw/cxl/cxl_cdat.h +++ b/include/hw/cxl/cxl_cdat.h @@ -11,6 +11,7 @@ #define CXL_CDAT_H #include "hw/cxl/cxl_pci.h" +#include "hw/pci/pcie_doe.h" /* * Reference: diff --git a/include/hw/cxl/cxl_component.h b/include/hw/cxl/cxl_component.h index 34075cf..5dca21e 100644 --- a/include/hw/cxl/cxl_component.h +++ b/include/hw/cxl/cxl_component.h @@ -18,6 +18,7 @@ #include "qemu/compiler.h" #include "qemu/range.h" #include "qemu/typedefs.h" +#include "hw/cxl/cxl_cdat.h" #include "hw/register.h" #include "qapi/error.h" diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h index 449b0ed..250adf1 100644 --- a/include/hw/cxl/cxl_device.h +++ b/include/hw/cxl/cxl_device.h @@ -10,6 +10,8 @@ #ifndef CXL_DEVICE_H #define CXL_DEVICE_H +#include "hw/cxl/cxl_component.h" +#include "hw/pci/pci_device.h" #include "hw/register.h" /* diff --git a/include/hw/cxl/cxl_pci.h b/include/hw/cxl/cxl_pci.h index 3cb79ec..01e15ed 100644 --- a/include/hw/cxl/cxl_pci.h +++ b/include/hw/cxl/cxl_pci.h @@ -11,9 +11,6 @@ #define CXL_PCI_H #include "qemu/compiler.h" -#include "hw/pci/pci.h" -#include "hw/pci/pcie.h" -#include "hw/cxl/cxl_cdat.h" #define CXL_VENDOR_ID 0x1e98 diff --git a/include/hw/display/macfb.h b/include/hw/display/macfb.h index 55a50d3..27cebef 100644 --- a/include/hw/display/macfb.h +++ b/include/hw/display/macfb.h @@ -15,9 +15,10 @@ #include "exec/memory.h" #include "hw/irq.h" +#include "hw/nubus/nubus.h" +#include "hw/sysbus.h" #include "ui/console.h" #include "qemu/timer.h" -#include "qom/object.h" typedef enum { MACFB_DISPLAY_APPLE_21_COLOR = 0, diff --git a/include/hw/dma/sifive_pdma.h b/include/hw/dma/sifive_pdma.h index e319bbd..8c6cfa7 100644 --- a/include/hw/dma/sifive_pdma.h +++ b/include/hw/dma/sifive_pdma.h @@ -23,6 +23,8 @@ #ifndef SIFIVE_PDMA_H #define SIFIVE_PDMA_H +#include "hw/sysbus.h" + struct sifive_pdma_chan { uint32_t control; uint32_t next_config; diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h index 23ee8e3..222781e 100644 --- a/include/hw/i386/ich9.h +++ b/include/hw/i386/ich9.h @@ -5,12 +5,8 @@ #include "hw/sysbus.h" #include "hw/i386/pc.h" #include "hw/isa/apm.h" -#include "hw/pci/pci.h" -#include "hw/pci/pcie_host.h" -#include "hw/pci/pci_bridge.h" #include "hw/acpi/acpi.h" #include "hw/acpi/ich9.h" -#include "hw/pci/pci_bus.h" #include "qom/object.h" void ich9_lpc_set_irq(void *opaque, int irq_num, int level); diff --git a/include/hw/i386/ioapic_internal.h b/include/hw/i386/ioapic_internal.h index 9880443..e8ff338 100644 --- a/include/hw/i386/ioapic_internal.h +++ b/include/hw/i386/ioapic_internal.h @@ -23,6 +23,7 @@ #define QEMU_IOAPIC_INTERNAL_H #include "exec/memory.h" +#include "hw/i386/ioapic.h" #include "hw/sysbus.h" #include "qemu/notify.h" #include "qom/object.h" diff --git a/include/hw/i386/sgx-epc.h b/include/hw/i386/sgx-epc.h index 581fac3..3e00efd 100644 --- a/include/hw/i386/sgx-epc.h +++ b/include/hw/i386/sgx-epc.h @@ -12,6 +12,7 @@ #ifndef QEMU_SGX_EPC_H #define QEMU_SGX_EPC_H +#include "hw/qdev-core.h" #include "hw/i386/hostmem-epc.h" #define TYPE_SGX_EPC "sgx-epc" diff --git a/include/hw/i386/x86-iommu.h b/include/hw/i386/x86-iommu.h index 7637edb..8d8d53b 100644 --- a/include/hw/i386/x86-iommu.h +++ b/include/hw/i386/x86-iommu.h @@ -21,7 +21,6 @@ #define HW_I386_X86_IOMMU_H #include "hw/sysbus.h" -#include "hw/pci/pci.h" #include "hw/pci/msi.h" #include "qom/object.h" diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h index d8384e1..2a6284a 100644 --- a/include/hw/ide/pci.h +++ b/include/hw/ide/pci.h @@ -2,7 +2,7 @@ #define HW_IDE_PCI_H #include "hw/ide/internal.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "qom/object.h" #define BM_STATUS_DMAING 0x01 diff --git a/include/hw/intc/goldfish_pic.h b/include/hw/intc/goldfish_pic.h index e9d552f..3e79580 100644 --- a/include/hw/intc/goldfish_pic.h +++ b/include/hw/intc/goldfish_pic.h @@ -10,6 +10,8 @@ #ifndef HW_INTC_GOLDFISH_PIC_H #define HW_INTC_GOLDFISH_PIC_H +#include "hw/sysbus.h" + #define TYPE_GOLDFISH_PIC "goldfish_pic" OBJECT_DECLARE_SIMPLE_TYPE(GoldfishPICState, GOLDFISH_PIC) diff --git a/include/hw/intc/loongarch_pch_msi.h b/include/hw/intc/loongarch_pch_msi.h index 832e69f..b8586fb 100644 --- a/include/hw/intc/loongarch_pch_msi.h +++ b/include/hw/intc/loongarch_pch_msi.h @@ -5,6 +5,8 @@ * Copyright (C) 2021 Loongson Technology Corporation Limited */ +#include "hw/sysbus.h" + #define TYPE_LOONGARCH_PCH_MSI "loongarch_pch_msi" OBJECT_DECLARE_SIMPLE_TYPE(LoongArchPCHMSI, LOONGARCH_PCH_MSI) diff --git a/include/hw/intc/loongarch_pch_pic.h b/include/hw/intc/loongarch_pch_pic.h index 258e3b3..d5437e8 100644 --- a/include/hw/intc/loongarch_pch_pic.h +++ b/include/hw/intc/loongarch_pch_pic.h @@ -5,6 +5,8 @@ * Copyright (c) 2021 Loongson Technology Corporation Limited */ +#include "hw/sysbus.h" + #define TYPE_LOONGARCH_PCH_PIC "loongarch_pch_pic" #define PCH_PIC_NAME(name) TYPE_LOONGARCH_PCH_PIC#name OBJECT_DECLARE_SIMPLE_TYPE(LoongArchPCHPIC, LOONGARCH_PCH_PIC) diff --git a/include/hw/intc/nios2_vic.h b/include/hw/intc/nios2_vic.h index ac507b9..5c975a2 100644 --- a/include/hw/intc/nios2_vic.h +++ b/include/hw/intc/nios2_vic.h @@ -35,6 +35,8 @@ #ifndef HW_INTC_NIOS2_VIC_H #define HW_INTC_NIOS2_VIC_H +#include "hw/sysbus.h" + #define TYPE_NIOS2_VIC "nios2-vic" OBJECT_DECLARE_SIMPLE_TYPE(Nios2VIC, NIOS2_VIC) diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h index eaa0788..e273cd3 100644 --- a/include/hw/isa/vt82c686.h +++ b/include/hw/isa/vt82c686.h @@ -1,7 +1,6 @@ #ifndef HW_VT82C686_H #define HW_VT82C686_H -#include "hw/pci/pci.h" #define TYPE_VT82C686B_ISA "vt82c686b-isa" #define TYPE_VT82C686B_USB_UHCI "vt82c686b-usb-uhci" diff --git a/include/hw/misc/macio/macio.h b/include/hw/misc/macio/macio.h index 95d30a1..86df2c2 100644 --- a/include/hw/misc/macio/macio.h +++ b/include/hw/misc/macio/macio.h @@ -27,7 +27,7 @@ #define MACIO_H #include "hw/char/escc.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/ide/internal.h" #include "hw/intc/heathrow_pic.h" #include "hw/misc/macio/cuda.h" diff --git a/include/hw/misc/mchp_pfsoc_dmc.h b/include/hw/misc/mchp_pfsoc_dmc.h index 2baa141..3bc1581 100644 --- a/include/hw/misc/mchp_pfsoc_dmc.h +++ b/include/hw/misc/mchp_pfsoc_dmc.h @@ -23,6 +23,8 @@ #ifndef MCHP_PFSOC_DMC_H #define MCHP_PFSOC_DMC_H +#include "hw/sysbus.h" + /* DDR SGMII PHY module */ #define MCHP_PFSOC_DDR_SGMII_PHY_REG_SIZE 0x1000 diff --git a/include/hw/misc/mchp_pfsoc_ioscb.h b/include/hw/misc/mchp_pfsoc_ioscb.h index a110486..3fd3e74 100644 --- a/include/hw/misc/mchp_pfsoc_ioscb.h +++ b/include/hw/misc/mchp_pfsoc_ioscb.h @@ -23,6 +23,8 @@ #ifndef MCHP_PFSOC_IOSCB_H #define MCHP_PFSOC_IOSCB_H +#include "hw/sysbus.h" + typedef struct MchpPfSoCIoscbState { SysBusDevice parent; MemoryRegion container; diff --git a/include/hw/misc/mchp_pfsoc_sysreg.h b/include/hw/misc/mchp_pfsoc_sysreg.h index 3cebe40..c2232bd 100644 --- a/include/hw/misc/mchp_pfsoc_sysreg.h +++ b/include/hw/misc/mchp_pfsoc_sysreg.h @@ -23,6 +23,8 @@ #ifndef MCHP_PFSOC_SYSREG_H #define MCHP_PFSOC_SYSREG_H +#include "hw/sysbus.h" + #define MCHP_PFSOC_SYSREG_REG_SIZE 0x2000 typedef struct MchpPfSoCSysregState { diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h index e520566..fab9416 100644 --- a/include/hw/misc/pvpanic.h +++ b/include/hw/misc/pvpanic.h @@ -15,6 +15,7 @@ #ifndef HW_MISC_PVPANIC_H #define HW_MISC_PVPANIC_H +#include "exec/memory.h" #include "qom/object.h" #define TYPE_PVPANIC_ISA_DEVICE "pvpanic" diff --git a/include/hw/misc/sifive_e_prci.h b/include/hw/misc/sifive_e_prci.h index 262ca16..6aa949e 100644 --- a/include/hw/misc/sifive_e_prci.h +++ b/include/hw/misc/sifive_e_prci.h @@ -18,7 +18,8 @@ #ifndef HW_SIFIVE_E_PRCI_H #define HW_SIFIVE_E_PRCI_H -#include "qom/object.h" + +#include "hw/sysbus.h" enum { SIFIVE_E_PRCI_HFROSCCFG = 0x0, diff --git a/include/hw/misc/sifive_u_otp.h b/include/hw/misc/sifive_u_otp.h index 5d0d7df..170d214 100644 --- a/include/hw/misc/sifive_u_otp.h +++ b/include/hw/misc/sifive_u_otp.h @@ -18,7 +18,8 @@ #ifndef HW_SIFIVE_U_OTP_H #define HW_SIFIVE_U_OTP_H -#include "qom/object.h" + +#include "hw/sysbus.h" #define SIFIVE_U_OTP_PA 0x00 #define SIFIVE_U_OTP_PAIO 0x04 diff --git a/include/hw/misc/sifive_u_prci.h b/include/hw/misc/sifive_u_prci.h index d9ebf40..4d2491a 100644 --- a/include/hw/misc/sifive_u_prci.h +++ b/include/hw/misc/sifive_u_prci.h @@ -18,7 +18,8 @@ #ifndef HW_SIFIVE_U_PRCI_H #define HW_SIFIVE_U_PRCI_H -#include "qom/object.h" + +#include "hw/sysbus.h" #define SIFIVE_U_PRCI_HFXOSCCFG 0x00 #define SIFIVE_U_PRCI_COREPLLCFG0 0x04 diff --git a/include/hw/misc/virt_ctrl.h b/include/hw/misc/virt_ctrl.h index 25a237e..81346cf 100644 --- a/include/hw/misc/virt_ctrl.h +++ b/include/hw/misc/virt_ctrl.h @@ -7,6 +7,8 @@ #ifndef VIRT_CTRL_H #define VIRT_CTRL_H +#include "hw/sysbus.h" + #define TYPE_VIRT_CTRL "virt-ctrl" OBJECT_DECLARE_SIMPLE_TYPE(VirtCtrlState, VIRT_CTRL) diff --git a/include/hw/misc/xlnx-versal-pmc-iou-slcr.h b/include/hw/misc/xlnx-versal-pmc-iou-slcr.h index 2170420..f7d24c9 100644 --- a/include/hw/misc/xlnx-versal-pmc-iou-slcr.h +++ b/include/hw/misc/xlnx-versal-pmc-iou-slcr.h @@ -54,6 +54,7 @@ #ifndef XLNX_VERSAL_PMC_IOU_SLCR_H #define XLNX_VERSAL_PMC_IOU_SLCR_H +#include "hw/sysbus.h" #include "hw/register.h" #define TYPE_XILINX_VERSAL_PMC_IOU_SLCR "xlnx.versal-pmc-iou-slcr" diff --git a/include/hw/net/lasi_82596.h b/include/hw/net/lasi_82596.h index 7b62b04..3ef2f47 100644 --- a/include/hw/net/lasi_82596.h +++ b/include/hw/net/lasi_82596.h @@ -10,7 +10,7 @@ #include "net/net.h" #include "hw/net/i82596.h" -#include "qom/object.h" +#include "hw/sysbus.h" #define TYPE_LASI_82596 "lasi_82596" typedef struct SysBusI82596State SysBusI82596State; diff --git a/include/hw/net/xlnx-zynqmp-can.h b/include/hw/net/xlnx-zynqmp-can.h index eb15587..fd2aa77 100644 --- a/include/hw/net/xlnx-zynqmp-can.h +++ b/include/hw/net/xlnx-zynqmp-can.h @@ -30,6 +30,7 @@ #ifndef XLNX_ZYNQMP_CAN_H #define XLNX_ZYNQMP_CAN_H +#include "hw/sysbus.h" #include "hw/register.h" #include "net/can_emu.h" #include "net/can_host.h" diff --git a/include/hw/pci-host/designware.h b/include/hw/pci-host/designware.h index 6d9b51a..908f3d9 100644 --- a/include/hw/pci-host/designware.h +++ b/include/hw/pci-host/designware.h @@ -22,9 +22,6 @@ #define DESIGNWARE_H #include "hw/sysbus.h" -#include "hw/pci/pci.h" -#include "hw/pci/pci_bus.h" -#include "hw/pci/pcie_host.h" #include "hw/pci/pci_bridge.h" #include "qom/object.h" diff --git a/include/hw/pci-host/gpex.h b/include/hw/pci-host/gpex.h index fcf8b63..b0240bd 100644 --- a/include/hw/pci-host/gpex.h +++ b/include/hw/pci-host/gpex.h @@ -22,7 +22,7 @@ #include "exec/hwaddr.h" #include "hw/sysbus.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/pci/pcie_host.h" #include "qom/object.h" diff --git a/include/hw/pci-host/i440fx.h b/include/hw/pci-host/i440fx.h index d02bf1e..bf57216 100644 --- a/include/hw/pci-host/i440fx.h +++ b/include/hw/pci-host/i440fx.h @@ -11,7 +11,7 @@ #ifndef HW_PCI_I440FX_H #define HW_PCI_I440FX_H -#include "hw/pci/pci_bus.h" +#include "hw/pci/pci_device.h" #include "hw/pci-host/pam.h" #include "qom/object.h" diff --git a/include/hw/pci-host/ls7a.h b/include/hw/pci-host/ls7a.h index 8061c4b..ff4b979 100644 --- a/include/hw/pci-host/ls7a.h +++ b/include/hw/pci-host/ls7a.h @@ -8,8 +8,6 @@ #ifndef HW_LS7A_H #define HW_LS7A_H -#include "hw/pci/pci.h" -#include "hw/pci/pcie_host.h" #include "hw/pci-host/pam.h" #include "qemu/units.h" #include "qemu/range.h" diff --git a/include/hw/pci-host/pnv_phb3.h b/include/hw/pci-host/pnv_phb3.h index 4854f6d..f791ebd 100644 --- a/include/hw/pci-host/pnv_phb3.h +++ b/include/hw/pci-host/pnv_phb3.h @@ -10,8 +10,6 @@ #ifndef PCI_HOST_PNV_PHB3_H #define PCI_HOST_PNV_PHB3_H -#include "hw/pci/pcie_host.h" -#include "hw/pci/pcie_port.h" #include "hw/ppc/xics.h" #include "qom/object.h" #include "hw/pci-host/pnv_phb.h" diff --git a/include/hw/pci-host/pnv_phb4.h b/include/hw/pci-host/pnv_phb4.h index 50d4faa..d9cea3f 100644 --- a/include/hw/pci-host/pnv_phb4.h +++ b/include/hw/pci-host/pnv_phb4.h @@ -10,8 +10,7 @@ #ifndef PCI_HOST_PNV_PHB4_H #define PCI_HOST_PNV_PHB4_H -#include "hw/pci/pcie_host.h" -#include "hw/pci/pcie_port.h" +#include "hw/pci/pci_bus.h" #include "hw/ppc/xive.h" #include "qom/object.h" diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h index ab98969..e89329c 100644 --- a/include/hw/pci-host/q35.h +++ b/include/hw/pci-host/q35.h @@ -22,7 +22,7 @@ #ifndef HW_Q35_H #define HW_Q35_H -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/pci/pcie_host.h" #include "hw/pci-host/pam.h" #include "qemu/units.h" diff --git a/include/hw/pci-host/sabre.h b/include/hw/pci-host/sabre.h index 0119024..d12de84 100644 --- a/include/hw/pci-host/sabre.h +++ b/include/hw/pci-host/sabre.h @@ -1,7 +1,7 @@ #ifndef HW_PCI_HOST_SABRE_H #define HW_PCI_HOST_SABRE_H -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/pci/pci_host.h" #include "hw/sparc/sun4u_iommu.h" #include "qom/object.h" diff --git a/include/hw/pci-host/xilinx-pcie.h b/include/hw/pci-host/xilinx-pcie.h index 89be88d..e1b3c1c 100644 --- a/include/hw/pci-host/xilinx-pcie.h +++ b/include/hw/pci-host/xilinx-pcie.h @@ -21,7 +21,6 @@ #define HW_XILINX_PCIE_H #include "hw/sysbus.h" -#include "hw/pci/pci.h" #include "hw/pci/pci_bridge.h" #include "hw/pci/pcie_host.h" #include "qom/object.h" diff --git a/include/hw/pci/msi.h b/include/hw/pci/msi.h index 58aa576..ee8ee46 100644 --- a/include/hw/pci/msi.h +++ b/include/hw/pci/msi.h @@ -21,7 +21,7 @@ #ifndef QEMU_MSI_H #define QEMU_MSI_H -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" struct MSIMessage { uint64_t address; diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 954f260..7048a37 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -166,7 +166,6 @@ enum { #define QEMU_PCI_VGA_IO_HI_SIZE 0x20 #include "hw/pci/pci_regs.h" -#include "hw/pci/pcie.h" /* PCI HEADER_TYPE */ #define PCI_HEADER_TYPE_MULTI_FUNCTION 0x80 @@ -210,23 +209,6 @@ enum { QEMU_PCIE_CAP_CXL = (1 << QEMU_PCIE_CXL_BITNR), }; -#define TYPE_PCI_DEVICE "pci-device" -typedef struct PCIDeviceClass PCIDeviceClass; -DECLARE_OBJ_CHECKERS(PCIDevice, PCIDeviceClass, - PCI_DEVICE, TYPE_PCI_DEVICE) - -/* - * Implemented by devices that can be plugged on CXL buses. In the spec, this is - * actually a "CXL Component, but we name it device to match the PCI naming. - */ -#define INTERFACE_CXL_DEVICE "cxl-device" - -/* Implemented by devices that can be plugged on PCI Express buses */ -#define INTERFACE_PCIE_DEVICE "pci-express-device" - -/* Implemented by devices that can be plugged on Conventional PCI buses */ -#define INTERFACE_CONVENTIONAL_PCI_DEVICE "conventional-pci-device" - typedef struct PCIINTxRoute { enum { PCI_INTX_ENABLED, @@ -236,24 +218,6 @@ typedef struct PCIINTxRoute { int irq; } PCIINTxRoute; -struct PCIDeviceClass { - DeviceClass parent_class; - - void (*realize)(PCIDevice *dev, Error **errp); - PCIUnregisterFunc *exit; - PCIConfigReadFunc *config_read; - PCIConfigWriteFunc *config_write; - - uint16_t vendor_id; - uint16_t device_id; - uint8_t revision; - uint16_t class_id; - uint16_t subsystem_vendor_id; /* only for header type = 0 */ - uint16_t subsystem_id; /* only for header type = 0 */ - - const char *romfile; /* rom bar */ -}; - typedef void (*PCIINTxRoutingNotifier)(PCIDevice *dev); typedef int (*MSIVectorUseNotifier)(PCIDevice *dev, unsigned int vector, MSIMessage msg); @@ -262,126 +226,6 @@ typedef void (*MSIVectorPollNotifier)(PCIDevice *dev, unsigned int vector_start, unsigned int vector_end); -enum PCIReqIDType { - PCI_REQ_ID_INVALID = 0, - PCI_REQ_ID_BDF, - PCI_REQ_ID_SECONDARY_BUS, - PCI_REQ_ID_MAX, -}; -typedef enum PCIReqIDType PCIReqIDType; - -struct PCIReqIDCache { - PCIDevice *dev; - PCIReqIDType type; -}; -typedef struct PCIReqIDCache PCIReqIDCache; - -struct PCIDevice { - DeviceState qdev; - bool partially_hotplugged; - bool has_power; - - /* PCI config space */ - uint8_t *config; - - /* Used to enable config checks on load. Note that writable bits are - * never checked even if set in cmask. */ - uint8_t *cmask; - - /* Used to implement R/W bytes */ - uint8_t *wmask; - - /* Used to implement RW1C(Write 1 to Clear) bytes */ - uint8_t *w1cmask; - - /* Used to allocate config space for capabilities. */ - uint8_t *used; - - /* the following fields are read only */ - int32_t devfn; - /* Cached device to fetch requester ID from, to avoid the PCI - * tree walking every time we invoke PCI request (e.g., - * MSI). For conventional PCI root complex, this field is - * meaningless. */ - PCIReqIDCache requester_id_cache; - char name[64]; - PCIIORegion io_regions[PCI_NUM_REGIONS]; - AddressSpace bus_master_as; - MemoryRegion bus_master_container_region; - MemoryRegion bus_master_enable_region; - - /* do not access the following fields */ - PCIConfigReadFunc *config_read; - PCIConfigWriteFunc *config_write; - - /* Legacy PCI VGA regions */ - MemoryRegion *vga_regions[QEMU_PCI_VGA_NUM_REGIONS]; - bool has_vga; - - /* Current IRQ levels. Used internally by the generic PCI code. */ - uint8_t irq_state; - - /* Capability bits */ - uint32_t cap_present; - - /* Offset of MSI-X capability in config space */ - uint8_t msix_cap; - - /* MSI-X entries */ - int msix_entries_nr; - - /* Space to store MSIX table & pending bit array */ - uint8_t *msix_table; - uint8_t *msix_pba; - - /* May be used by INTx or MSI during interrupt notification */ - void *irq_opaque; - - MSITriggerFunc *msi_trigger; - MSIPrepareMessageFunc *msi_prepare_message; - MSIxPrepareMessageFunc *msix_prepare_message; - - /* MemoryRegion container for msix exclusive BAR setup */ - MemoryRegion msix_exclusive_bar; - /* Memory Regions for MSIX table and pending bit entries. */ - MemoryRegion msix_table_mmio; - MemoryRegion msix_pba_mmio; - /* Reference-count for entries actually in use by driver. */ - unsigned *msix_entry_used; - /* MSIX function mask set or MSIX disabled */ - bool msix_function_masked; - /* Version id needed for VMState */ - int32_t version_id; - - /* Offset of MSI capability in config space */ - uint8_t msi_cap; - - /* PCI Express */ - PCIExpressDevice exp; - - /* SHPC */ - SHPCDevice *shpc; - - /* Location of option rom */ - char *romfile; - uint32_t romsize; - bool has_rom; - MemoryRegion rom; - uint32_t rom_bar; - - /* INTx routing notifier */ - PCIINTxRoutingNotifier intx_routing_notifier; - - /* MSI-X notifiers */ - MSIVectorUseNotifier msix_vector_use_notifier; - MSIVectorReleaseNotifier msix_vector_release_notifier; - MSIVectorPollNotifier msix_vector_poll_notifier; - - /* ID of standby device in net_failover pair */ - char *failover_pair_id; - uint32_t acpi_index; -}; - void pci_register_bar(PCIDevice *pci_dev, int region_num, uint8_t attr, MemoryRegion *memory); void pci_register_vga(PCIDevice *pci_dev, MemoryRegion *mem, @@ -742,11 +586,6 @@ void lsi53c8xx_handle_legacy_cmdline(DeviceState *lsi_dev); qemu_irq pci_allocate_irq(PCIDevice *pci_dev); void pci_set_irq(PCIDevice *pci_dev, int level); -static inline int pci_intx(PCIDevice *pci_dev) -{ - return pci_get_byte(pci_dev->config + PCI_INTERRUPT_PIN) - 1; -} - static inline void pci_irq_assert(PCIDevice *pci_dev) { pci_set_irq(pci_dev, 1); @@ -767,186 +606,6 @@ static inline void pci_irq_pulse(PCIDevice *pci_dev) pci_irq_deassert(pci_dev); } -static inline int pci_is_cxl(const PCIDevice *d) -{ - return d->cap_present & QEMU_PCIE_CAP_CXL; -} - -static inline int pci_is_express(const PCIDevice *d) -{ - return d->cap_present & QEMU_PCI_CAP_EXPRESS; -} - -static inline int pci_is_express_downstream_port(const PCIDevice *d) -{ - uint8_t type; - - if (!pci_is_express(d) || !d->exp.exp_cap) { - return 0; - } - - type = pcie_cap_get_type(d); - - return type == PCI_EXP_TYPE_DOWNSTREAM || type == PCI_EXP_TYPE_ROOT_PORT; -} - -static inline int pci_is_vf(const PCIDevice *d) -{ - return d->exp.sriov_vf.pf != NULL; -} - -static inline uint32_t pci_config_size(const PCIDevice *d) -{ - return pci_is_express(d) ? PCIE_CONFIG_SPACE_SIZE : PCI_CONFIG_SPACE_SIZE; -} - -static inline uint16_t pci_get_bdf(PCIDevice *dev) -{ - return PCI_BUILD_BDF(pci_bus_num(pci_get_bus(dev)), dev->devfn); -} - -uint16_t pci_requester_id(PCIDevice *dev); - -/* DMA access functions */ -static inline AddressSpace *pci_get_address_space(PCIDevice *dev) -{ - return &dev->bus_master_as; -} - -/** - * pci_dma_rw: Read from or write to an address space from PCI device. - * - * Return a MemTxResult indicating whether the operation succeeded - * or failed (eg unassigned memory, device rejected the transaction, - * IOMMU fault). - * - * @dev: #PCIDevice doing the memory access - * @addr: address within the #PCIDevice address space - * @buf: buffer with the data transferred - * @len: the number of bytes to read or write - * @dir: indicates the transfer direction - */ -static inline MemTxResult pci_dma_rw(PCIDevice *dev, dma_addr_t addr, - void *buf, dma_addr_t len, - DMADirection dir, MemTxAttrs attrs) -{ - return dma_memory_rw(pci_get_address_space(dev), addr, buf, len, - dir, attrs); -} - -/** - * pci_dma_read: Read from an address space from PCI device. - * - * Return a MemTxResult indicating whether the operation succeeded - * or failed (eg unassigned memory, device rejected the transaction, - * IOMMU fault). Called within RCU critical section. - * - * @dev: #PCIDevice doing the memory access - * @addr: address within the #PCIDevice address space - * @buf: buffer with the data transferred - * @len: length of the data transferred - */ -static inline MemTxResult pci_dma_read(PCIDevice *dev, dma_addr_t addr, - void *buf, dma_addr_t len) -{ - return pci_dma_rw(dev, addr, buf, len, - DMA_DIRECTION_TO_DEVICE, MEMTXATTRS_UNSPECIFIED); -} - -/** - * pci_dma_write: Write to address space from PCI device. - * - * Return a MemTxResult indicating whether the operation succeeded - * or failed (eg unassigned memory, device rejected the transaction, - * IOMMU fault). - * - * @dev: #PCIDevice doing the memory access - * @addr: address within the #PCIDevice address space - * @buf: buffer with the data transferred - * @len: the number of bytes to write - */ -static inline MemTxResult pci_dma_write(PCIDevice *dev, dma_addr_t addr, - const void *buf, dma_addr_t len) -{ - return pci_dma_rw(dev, addr, (void *) buf, len, - DMA_DIRECTION_FROM_DEVICE, MEMTXATTRS_UNSPECIFIED); -} - -#define PCI_DMA_DEFINE_LDST(_l, _s, _bits) \ - static inline MemTxResult ld##_l##_pci_dma(PCIDevice *dev, \ - dma_addr_t addr, \ - uint##_bits##_t *val, \ - MemTxAttrs attrs) \ - { \ - return ld##_l##_dma(pci_get_address_space(dev), addr, val, attrs); \ - } \ - static inline MemTxResult st##_s##_pci_dma(PCIDevice *dev, \ - dma_addr_t addr, \ - uint##_bits##_t val, \ - MemTxAttrs attrs) \ - { \ - return st##_s##_dma(pci_get_address_space(dev), addr, val, attrs); \ - } - -PCI_DMA_DEFINE_LDST(ub, b, 8); -PCI_DMA_DEFINE_LDST(uw_le, w_le, 16) -PCI_DMA_DEFINE_LDST(l_le, l_le, 32); -PCI_DMA_DEFINE_LDST(q_le, q_le, 64); -PCI_DMA_DEFINE_LDST(uw_be, w_be, 16) -PCI_DMA_DEFINE_LDST(l_be, l_be, 32); -PCI_DMA_DEFINE_LDST(q_be, q_be, 64); - -#undef PCI_DMA_DEFINE_LDST - -/** - * pci_dma_map: Map device PCI address space range into host virtual address - * @dev: #PCIDevice to be accessed - * @addr: address within that device's address space - * @plen: pointer to length of buffer; updated on return to indicate - * if only a subset of the requested range has been mapped - * @dir: indicates the transfer direction - * - * Return: A host pointer, or %NULL if the resources needed to - * perform the mapping are exhausted (in that case *@plen - * is set to zero). - */ -static inline void *pci_dma_map(PCIDevice *dev, dma_addr_t addr, - dma_addr_t *plen, DMADirection dir) -{ - return dma_memory_map(pci_get_address_space(dev), addr, plen, dir, - MEMTXATTRS_UNSPECIFIED); -} - -static inline void pci_dma_unmap(PCIDevice *dev, void *buffer, dma_addr_t len, - DMADirection dir, dma_addr_t access_len) -{ - dma_memory_unmap(pci_get_address_space(dev), buffer, len, dir, access_len); -} - -static inline void pci_dma_sglist_init(QEMUSGList *qsg, PCIDevice *dev, - int alloc_hint) -{ - qemu_sglist_init(qsg, DEVICE(dev), alloc_hint, pci_get_address_space(dev)); -} - -extern const VMStateDescription vmstate_pci_device; - -#define VMSTATE_PCI_DEVICE(_field, _state) { \ - .name = (stringify(_field)), \ - .size = sizeof(PCIDevice), \ - .vmsd = &vmstate_pci_device, \ - .flags = VMS_STRUCT, \ - .offset = vmstate_offset_value(_state, _field, PCIDevice), \ -} - -#define VMSTATE_PCI_DEVICE_POINTER(_field, _state) { \ - .name = (stringify(_field)), \ - .size = sizeof(PCIDevice), \ - .vmsd = &vmstate_pci_device, \ - .flags = VMS_STRUCT|VMS_POINTER, \ - .offset = vmstate_offset_pointer(_state, _field, PCIDevice), \ -} - MSIMessage pci_get_msi_message(PCIDevice *dev, int vector); void pci_set_power(PCIDevice *pci_dev, bool state); diff --git a/include/hw/pci/pci_bridge.h b/include/hw/pci/pci_bridge.h index ca6caf4..63a7521 100644 --- a/include/hw/pci/pci_bridge.h +++ b/include/hw/pci/pci_bridge.h @@ -26,7 +26,7 @@ #ifndef QEMU_PCI_BRIDGE_H #define QEMU_PCI_BRIDGE_H -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/pci/pci_bus.h" #include "hw/cxl/cxl.h" #include "qom/object.h" @@ -97,7 +97,6 @@ struct PXBDev { } cxl; }; -typedef struct PXBDev PXBDev; #define TYPE_PXB_CXL_DEVICE "pxb-cxl" DECLARE_INSTANCE_CHECKER(PXBDev, PXB_CXL_DEV, TYPE_PXB_CXL_DEVICE) diff --git a/include/hw/pci/pci_device.h b/include/hw/pci/pci_device.h new file mode 100644 index 0000000..d3dd0f6 --- /dev/null +++ b/include/hw/pci/pci_device.h @@ -0,0 +1,350 @@ +#ifndef QEMU_PCI_DEVICE_H +#define QEMU_PCI_DEVICE_H + +#include "hw/pci/pci.h" +#include "hw/pci/pcie.h" + +#define TYPE_PCI_DEVICE "pci-device" +typedef struct PCIDeviceClass PCIDeviceClass; +DECLARE_OBJ_CHECKERS(PCIDevice, PCIDeviceClass, + PCI_DEVICE, TYPE_PCI_DEVICE) + +/* + * Implemented by devices that can be plugged on CXL buses. In the spec, this is + * actually a "CXL Component, but we name it device to match the PCI naming. + */ +#define INTERFACE_CXL_DEVICE "cxl-device" + +/* Implemented by devices that can be plugged on PCI Express buses */ +#define INTERFACE_PCIE_DEVICE "pci-express-device" + +/* Implemented by devices that can be plugged on Conventional PCI buses */ +#define INTERFACE_CONVENTIONAL_PCI_DEVICE "conventional-pci-device" + +struct PCIDeviceClass { + DeviceClass parent_class; + + void (*realize)(PCIDevice *dev, Error **errp); + PCIUnregisterFunc *exit; + PCIConfigReadFunc *config_read; + PCIConfigWriteFunc *config_write; + + uint16_t vendor_id; + uint16_t device_id; + uint8_t revision; + uint16_t class_id; + uint16_t subsystem_vendor_id; /* only for header type = 0 */ + uint16_t subsystem_id; /* only for header type = 0 */ + + const char *romfile; /* rom bar */ +}; + +enum PCIReqIDType { + PCI_REQ_ID_INVALID = 0, + PCI_REQ_ID_BDF, + PCI_REQ_ID_SECONDARY_BUS, + PCI_REQ_ID_MAX, +}; +typedef enum PCIReqIDType PCIReqIDType; + +struct PCIReqIDCache { + PCIDevice *dev; + PCIReqIDType type; +}; +typedef struct PCIReqIDCache PCIReqIDCache; + +struct PCIDevice { + DeviceState qdev; + bool partially_hotplugged; + bool has_power; + + /* PCI config space */ + uint8_t *config; + + /* + * Used to enable config checks on load. Note that writable bits are + * never checked even if set in cmask. + */ + uint8_t *cmask; + + /* Used to implement R/W bytes */ + uint8_t *wmask; + + /* Used to implement RW1C(Write 1 to Clear) bytes */ + uint8_t *w1cmask; + + /* Used to allocate config space for capabilities. */ + uint8_t *used; + + /* the following fields are read only */ + int32_t devfn; + /* + * Cached device to fetch requester ID from, to avoid the PCI tree + * walking every time we invoke PCI request (e.g., MSI). For + * conventional PCI root complex, this field is meaningless. + */ + PCIReqIDCache requester_id_cache; + char name[64]; + PCIIORegion io_regions[PCI_NUM_REGIONS]; + AddressSpace bus_master_as; + MemoryRegion bus_master_container_region; + MemoryRegion bus_master_enable_region; + + /* do not access the following fields */ + PCIConfigReadFunc *config_read; + PCIConfigWriteFunc *config_write; + + /* Legacy PCI VGA regions */ + MemoryRegion *vga_regions[QEMU_PCI_VGA_NUM_REGIONS]; + bool has_vga; + + /* Current IRQ levels. Used internally by the generic PCI code. */ + uint8_t irq_state; + + /* Capability bits */ + uint32_t cap_present; + + /* Offset of MSI-X capability in config space */ + uint8_t msix_cap; + + /* MSI-X entries */ + int msix_entries_nr; + + /* Space to store MSIX table & pending bit array */ + uint8_t *msix_table; + uint8_t *msix_pba; + + /* May be used by INTx or MSI during interrupt notification */ + void *irq_opaque; + + MSITriggerFunc *msi_trigger; + MSIPrepareMessageFunc *msi_prepare_message; + MSIxPrepareMessageFunc *msix_prepare_message; + + /* MemoryRegion container for msix exclusive BAR setup */ + MemoryRegion msix_exclusive_bar; + /* Memory Regions for MSIX table and pending bit entries. */ + MemoryRegion msix_table_mmio; + MemoryRegion msix_pba_mmio; + /* Reference-count for entries actually in use by driver. */ + unsigned *msix_entry_used; + /* MSIX function mask set or MSIX disabled */ + bool msix_function_masked; + /* Version id needed for VMState */ + int32_t version_id; + + /* Offset of MSI capability in config space */ + uint8_t msi_cap; + + /* PCI Express */ + PCIExpressDevice exp; + + /* SHPC */ + SHPCDevice *shpc; + + /* Location of option rom */ + char *romfile; + uint32_t romsize; + bool has_rom; + MemoryRegion rom; + uint32_t rom_bar; + + /* INTx routing notifier */ + PCIINTxRoutingNotifier intx_routing_notifier; + + /* MSI-X notifiers */ + MSIVectorUseNotifier msix_vector_use_notifier; + MSIVectorReleaseNotifier msix_vector_release_notifier; + MSIVectorPollNotifier msix_vector_poll_notifier; + + /* ID of standby device in net_failover pair */ + char *failover_pair_id; + uint32_t acpi_index; +}; + +static inline int pci_intx(PCIDevice *pci_dev) +{ + return pci_get_byte(pci_dev->config + PCI_INTERRUPT_PIN) - 1; +} + +static inline int pci_is_cxl(const PCIDevice *d) +{ + return d->cap_present & QEMU_PCIE_CAP_CXL; +} + +static inline int pci_is_express(const PCIDevice *d) +{ + return d->cap_present & QEMU_PCI_CAP_EXPRESS; +} + +static inline int pci_is_express_downstream_port(const PCIDevice *d) +{ + uint8_t type; + + if (!pci_is_express(d) || !d->exp.exp_cap) { + return 0; + } + + type = pcie_cap_get_type(d); + + return type == PCI_EXP_TYPE_DOWNSTREAM || type == PCI_EXP_TYPE_ROOT_PORT; +} + +static inline int pci_is_vf(const PCIDevice *d) +{ + return d->exp.sriov_vf.pf != NULL; +} + +static inline uint32_t pci_config_size(const PCIDevice *d) +{ + return pci_is_express(d) ? PCIE_CONFIG_SPACE_SIZE : PCI_CONFIG_SPACE_SIZE; +} + +static inline uint16_t pci_get_bdf(PCIDevice *dev) +{ + return PCI_BUILD_BDF(pci_bus_num(pci_get_bus(dev)), dev->devfn); +} + +uint16_t pci_requester_id(PCIDevice *dev); + +/* DMA access functions */ +static inline AddressSpace *pci_get_address_space(PCIDevice *dev) +{ + return &dev->bus_master_as; +} + +/** + * pci_dma_rw: Read from or write to an address space from PCI device. + * + * Return a MemTxResult indicating whether the operation succeeded + * or failed (eg unassigned memory, device rejected the transaction, + * IOMMU fault). + * + * @dev: #PCIDevice doing the memory access + * @addr: address within the #PCIDevice address space + * @buf: buffer with the data transferred + * @len: the number of bytes to read or write + * @dir: indicates the transfer direction + */ +static inline MemTxResult pci_dma_rw(PCIDevice *dev, dma_addr_t addr, + void *buf, dma_addr_t len, + DMADirection dir, MemTxAttrs attrs) +{ + return dma_memory_rw(pci_get_address_space(dev), addr, buf, len, + dir, attrs); +} + +/** + * pci_dma_read: Read from an address space from PCI device. + * + * Return a MemTxResult indicating whether the operation succeeded + * or failed (eg unassigned memory, device rejected the transaction, + * IOMMU fault). Called within RCU critical section. + * + * @dev: #PCIDevice doing the memory access + * @addr: address within the #PCIDevice address space + * @buf: buffer with the data transferred + * @len: length of the data transferred + */ +static inline MemTxResult pci_dma_read(PCIDevice *dev, dma_addr_t addr, + void *buf, dma_addr_t len) +{ + return pci_dma_rw(dev, addr, buf, len, + DMA_DIRECTION_TO_DEVICE, MEMTXATTRS_UNSPECIFIED); +} + +/** + * pci_dma_write: Write to address space from PCI device. + * + * Return a MemTxResult indicating whether the operation succeeded + * or failed (eg unassigned memory, device rejected the transaction, + * IOMMU fault). + * + * @dev: #PCIDevice doing the memory access + * @addr: address within the #PCIDevice address space + * @buf: buffer with the data transferred + * @len: the number of bytes to write + */ +static inline MemTxResult pci_dma_write(PCIDevice *dev, dma_addr_t addr, + const void *buf, dma_addr_t len) +{ + return pci_dma_rw(dev, addr, (void *) buf, len, + DMA_DIRECTION_FROM_DEVICE, MEMTXATTRS_UNSPECIFIED); +} + +#define PCI_DMA_DEFINE_LDST(_l, _s, _bits) \ + static inline MemTxResult ld##_l##_pci_dma(PCIDevice *dev, \ + dma_addr_t addr, \ + uint##_bits##_t *val, \ + MemTxAttrs attrs) \ + { \ + return ld##_l##_dma(pci_get_address_space(dev), addr, val, attrs); \ + } \ + static inline MemTxResult st##_s##_pci_dma(PCIDevice *dev, \ + dma_addr_t addr, \ + uint##_bits##_t val, \ + MemTxAttrs attrs) \ + { \ + return st##_s##_dma(pci_get_address_space(dev), addr, val, attrs); \ + } + +PCI_DMA_DEFINE_LDST(ub, b, 8); +PCI_DMA_DEFINE_LDST(uw_le, w_le, 16) +PCI_DMA_DEFINE_LDST(l_le, l_le, 32); +PCI_DMA_DEFINE_LDST(q_le, q_le, 64); +PCI_DMA_DEFINE_LDST(uw_be, w_be, 16) +PCI_DMA_DEFINE_LDST(l_be, l_be, 32); +PCI_DMA_DEFINE_LDST(q_be, q_be, 64); + +#undef PCI_DMA_DEFINE_LDST + +/** + * pci_dma_map: Map device PCI address space range into host virtual address + * @dev: #PCIDevice to be accessed + * @addr: address within that device's address space + * @plen: pointer to length of buffer; updated on return to indicate + * if only a subset of the requested range has been mapped + * @dir: indicates the transfer direction + * + * Return: A host pointer, or %NULL if the resources needed to + * perform the mapping are exhausted (in that case *@plen + * is set to zero). + */ +static inline void *pci_dma_map(PCIDevice *dev, dma_addr_t addr, + dma_addr_t *plen, DMADirection dir) +{ + return dma_memory_map(pci_get_address_space(dev), addr, plen, dir, + MEMTXATTRS_UNSPECIFIED); +} + +static inline void pci_dma_unmap(PCIDevice *dev, void *buffer, dma_addr_t len, + DMADirection dir, dma_addr_t access_len) +{ + dma_memory_unmap(pci_get_address_space(dev), buffer, len, dir, access_len); +} + +static inline void pci_dma_sglist_init(QEMUSGList *qsg, PCIDevice *dev, + int alloc_hint) +{ + qemu_sglist_init(qsg, DEVICE(dev), alloc_hint, pci_get_address_space(dev)); +} + +extern const VMStateDescription vmstate_pci_device; + +#define VMSTATE_PCI_DEVICE(_field, _state) { \ + .name = (stringify(_field)), \ + .size = sizeof(PCIDevice), \ + .vmsd = &vmstate_pci_device, \ + .flags = VMS_STRUCT, \ + .offset = vmstate_offset_value(_state, _field, PCIDevice), \ +} + +#define VMSTATE_PCI_DEVICE_POINTER(_field, _state) { \ + .name = (stringify(_field)), \ + .size = sizeof(PCIDevice), \ + .vmsd = &vmstate_pci_device, \ + .flags = VMS_STRUCT | VMS_POINTER, \ + .offset = vmstate_offset_pointer(_state, _field, PCIDevice), \ +} + +#endif diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h index 698d3de..798a262 100644 --- a/include/hw/pci/pcie.h +++ b/include/hw/pci/pcie.h @@ -26,7 +26,6 @@ #include "hw/pci/pcie_aer.h" #include "hw/pci/pcie_sriov.h" #include "hw/hotplug.h" -#include "hw/pci/pcie_doe.h" typedef enum { /* for attention and power indicator */ diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h index d9b5d07..fd484af 100644 --- a/include/hw/pci/pcie_port.h +++ b/include/hw/pci/pcie_port.h @@ -23,6 +23,7 @@ #include "hw/pci/pci_bridge.h" #include "hw/pci/pci_bus.h" +#include "hw/pci/pci_device.h" #include "qom/object.h" #define TYPE_PCIE_PORT "pcie-port" diff --git a/include/hw/pci/pcie_sriov.h b/include/hw/pci/pcie_sriov.h index 80f5c84..96cc743 100644 --- a/include/hw/pci/pcie_sriov.h +++ b/include/hw/pci/pcie_sriov.h @@ -13,6 +13,8 @@ #ifndef QEMU_PCIE_SRIOV_H #define QEMU_PCIE_SRIOV_H +#include "hw/pci/pci.h" + struct PCIESriovPF { uint16_t num_vfs; /* Number of virtual functions created */ uint8_t vf_bar_type[PCI_NUM_REGIONS]; /* Store type for each VF bar */ diff --git a/include/hw/pci/shpc.h b/include/hw/pci/shpc.h index d5683b7..89c7a3b 100644 --- a/include/hw/pci/shpc.h +++ b/include/hw/pci/shpc.h @@ -3,7 +3,7 @@ #include "exec/memory.h" #include "hw/hotplug.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "migration/vmstate.h" struct SHPCDevice { diff --git a/include/hw/ppc/pnv_psi.h b/include/hw/ppc/pnv_psi.h index 8253469..2a6f715 100644 --- a/include/hw/ppc/pnv_psi.h +++ b/include/hw/ppc/pnv_psi.h @@ -23,7 +23,7 @@ #include "hw/sysbus.h" #include "hw/ppc/xics.h" #include "hw/ppc/xive.h" -#include "qom/object.h" +#include "hw/qdev-core.h" #define TYPE_PNV_PSI "pnv-psi" OBJECT_DECLARE_TYPE(PnvPsi, PnvPsiClass, diff --git a/include/hw/remote/iohub.h b/include/hw/remote/iohub.h index 0bf98e0..6a8444f 100644 --- a/include/hw/remote/iohub.h +++ b/include/hw/remote/iohub.h @@ -11,7 +11,7 @@ #ifndef REMOTE_IOHUB_H #define REMOTE_IOHUB_H -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "qemu/event_notifier.h" #include "qemu/thread-posix.h" #include "hw/remote/mpqemu-link.h" diff --git a/include/hw/remote/proxy.h b/include/hw/remote/proxy.h index 741def7..0cfd966 100644 --- a/include/hw/remote/proxy.h +++ b/include/hw/remote/proxy.h @@ -9,7 +9,7 @@ #ifndef PROXY_H #define PROXY_H -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "io/channel.h" #include "hw/remote/proxy-memory-listener.h" #include "qemu/event_notifier.h" diff --git a/include/hw/riscv/boot_opensbi.h b/include/hw/riscv/boot_opensbi.h index c19cad4..1b74966 100644 --- a/include/hw/riscv/boot_opensbi.h +++ b/include/hw/riscv/boot_opensbi.h @@ -8,6 +8,8 @@ #ifndef RISCV_BOOT_OPENSBI_H #define RISCV_BOOT_OPENSBI_H +#include "exec/cpu-defs.h" + /** Expected value of info magic ('OSBI' ascii string in hex) */ #define FW_DYNAMIC_INFO_MAGIC_VALUE 0x4942534f diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h index e65ffeb..daef086 100644 --- a/include/hw/riscv/microchip_pfsoc.h +++ b/include/hw/riscv/microchip_pfsoc.h @@ -22,13 +22,16 @@ #ifndef HW_MICROCHIP_PFSOC_H #define HW_MICROCHIP_PFSOC_H +#include "hw/boards.h" #include "hw/char/mchp_pfsoc_mmuart.h" +#include "hw/cpu/cluster.h" #include "hw/dma/sifive_pdma.h" #include "hw/misc/mchp_pfsoc_dmc.h" #include "hw/misc/mchp_pfsoc_ioscb.h" #include "hw/misc/mchp_pfsoc_sysreg.h" #include "hw/net/cadence_gem.h" #include "hw/sd/cadence_sdhci.h" +#include "hw/riscv/riscv_hart.h" typedef struct MicrochipPFSoCState { /*< private >*/ diff --git a/include/hw/riscv/numa.h b/include/hw/riscv/numa.h index fcce942..1a9cce3 100644 --- a/include/hw/riscv/numa.h +++ b/include/hw/riscv/numa.h @@ -19,6 +19,7 @@ #ifndef RISCV_NUMA_H #define RISCV_NUMA_H +#include "hw/boards.h" #include "hw/sysbus.h" #include "sysemu/numa.h" diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h index e680d61..a67328f 100644 --- a/include/hw/riscv/sifive_u.h +++ b/include/hw/riscv/sifive_u.h @@ -19,6 +19,8 @@ #ifndef HW_SIFIVE_U_H #define HW_SIFIVE_U_H +#include "hw/boards.h" +#include "hw/cpu/cluster.h" #include "hw/dma/sifive_pdma.h" #include "hw/net/cadence_gem.h" #include "hw/riscv/riscv_hart.h" diff --git a/include/hw/riscv/spike.h b/include/hw/riscv/spike.h index 73d6923..73bf2a9 100644 --- a/include/hw/riscv/spike.h +++ b/include/hw/riscv/spike.h @@ -19,9 +19,9 @@ #ifndef HW_RISCV_SPIKE_H #define HW_RISCV_SPIKE_H +#include "hw/boards.h" #include "hw/riscv/riscv_hart.h" #include "hw/sysbus.h" -#include "qom/object.h" #define SPIKE_CPUS_MAX 8 #define SPIKE_SOCKETS_MAX 8 diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index 3407c9e..b3d2613 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -19,10 +19,10 @@ #ifndef HW_RISCV_VIRT_H #define HW_RISCV_VIRT_H +#include "hw/boards.h" #include "hw/riscv/riscv_hart.h" #include "hw/sysbus.h" #include "hw/block/flash.h" -#include "qom/object.h" #define VIRT_CPUS_MAX_BITS 9 #define VIRT_CPUS_MAX (1 << VIRT_CPUS_MAX_BITS) diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h index a989fca..6cd2822 100644 --- a/include/hw/sd/sdhci.h +++ b/include/hw/sd/sdhci.h @@ -25,7 +25,7 @@ #ifndef SDHCI_H #define SDHCI_H -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/sysbus.h" #include "hw/sd/sd.h" #include "qom/object.h" diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h index 2693778..0bf48e9 100644 --- a/include/hw/southbridge/piix.h +++ b/include/hw/southbridge/piix.h @@ -12,8 +12,7 @@ #ifndef HW_SOUTHBRIDGE_PIIX_H #define HW_SOUTHBRIDGE_PIIX_H -#include "hw/pci/pci.h" -#include "qom/object.h" +#include "hw/pci/pci_device.h" /* PIRQRC[A:D]: PIRQx Route Control Registers */ #define PIIX_PIRQCA 0x60 diff --git a/include/hw/ssi/sifive_spi.h b/include/hw/ssi/sifive_spi.h index 47d0d6a..d0c40cd 100644 --- a/include/hw/ssi/sifive_spi.h +++ b/include/hw/ssi/sifive_spi.h @@ -22,6 +22,9 @@ #ifndef HW_SIFIVE_SPI_H #define HW_SIFIVE_SPI_H +#include "qemu/fifo8.h" +#include "hw/sysbus.h" + #define SIFIVE_SPI_REG_NUM (0x78 / 4) #define TYPE_SIFIVE_SPI "sifive.spi" diff --git a/include/hw/timer/sse-timer.h b/include/hw/timer/sse-timer.h index b4ee8e7..265ad32 100644 --- a/include/hw/timer/sse-timer.h +++ b/include/hw/timer/sse-timer.h @@ -25,6 +25,7 @@ #define SSE_TIMER_H #include "hw/sysbus.h" +#include "qemu/timer.h" #include "qom/object.h" #include "hw/timer/sse-counter.h" diff --git a/include/hw/usb/hcd-dwc3.h b/include/hw/usb/hcd-dwc3.h index 7c804d5..f752a27 100644 --- a/include/hw/usb/hcd-dwc3.h +++ b/include/hw/usb/hcd-dwc3.h @@ -26,6 +26,7 @@ #ifndef HCD_DWC3_H #define HCD_DWC3_H +#include "hw/register.h" #include "hw/usb/hcd-xhci.h" #include "hw/usb/hcd-xhci-sysbus.h" diff --git a/include/hw/usb/hcd-musb.h b/include/hw/usb/hcd-musb.h index f30a26f..4d4b1ec 100644 --- a/include/hw/usb/hcd-musb.h +++ b/include/hw/usb/hcd-musb.h @@ -13,6 +13,8 @@ #ifndef HW_USB_HCD_MUSB_H #define HW_USB_HCD_MUSB_H +#include "exec/hwaddr.h" + enum musb_irq_source_e { musb_irq_suspend = 0, musb_irq_resume, diff --git a/include/hw/usb/xlnx-usb-subsystem.h b/include/hw/usb/xlnx-usb-subsystem.h index 5b730ab..40f9e97 100644 --- a/include/hw/usb/xlnx-usb-subsystem.h +++ b/include/hw/usb/xlnx-usb-subsystem.h @@ -25,6 +25,8 @@ #ifndef XLNX_USB_SUBSYSTEM_H #define XLNX_USB_SUBSYSTEM_H +#include "hw/register.h" +#include "hw/sysbus.h" #include "hw/usb/xlnx-versal-usb2-ctrl-regs.h" #include "hw/usb/hcd-dwc3.h" diff --git a/include/hw/usb/xlnx-versal-usb2-ctrl-regs.h b/include/hw/usb/xlnx-versal-usb2-ctrl-regs.h index 633bf30..6a50200 100644 --- a/include/hw/usb/xlnx-versal-usb2-ctrl-regs.h +++ b/include/hw/usb/xlnx-versal-usb2-ctrl-regs.h @@ -26,6 +26,9 @@ #ifndef XLNX_VERSAL_USB2_CTRL_REGS_H #define XLNX_VERSAL_USB2_CTRL_REGS_H +#include "hw/register.h" +#include "hw/sysbus.h" + #define TYPE_XILINX_VERSAL_USB2_CTRL_REGS "xlnx.versal-usb2-ctrl-regs" #define XILINX_VERSAL_USB2_CTRL_REGS(obj) \ diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h index eab46d7..c5ab490 100644 --- a/include/hw/virtio/vhost-backend.h +++ b/include/hw/virtio/vhost-backend.h @@ -128,6 +128,8 @@ typedef int (*vhost_get_device_id_op)(struct vhost_dev *dev, uint32_t *dev_id); typedef bool (*vhost_force_iommu_op)(struct vhost_dev *dev); +typedef int (*vhost_set_config_call_op)(struct vhost_dev *dev, + int fd); typedef struct VhostOps { VhostBackendType backend_type; vhost_backend_init vhost_backend_init; @@ -174,6 +176,7 @@ typedef struct VhostOps { vhost_vq_get_addr_op vhost_vq_get_addr; vhost_get_device_id_op vhost_get_device_id; vhost_force_iommu_op vhost_force_iommu; + vhost_set_config_call_op vhost_set_config_call; } VhostOps; int vhost_backend_update_device_iotlb(struct vhost_dev *dev, diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h index 45b969a..7997f09 100644 --- a/include/hw/virtio/vhost-vdpa.h +++ b/include/hw/virtio/vhost-vdpa.h @@ -51,6 +51,8 @@ typedef struct vhost_vdpa { VhostVDPAHostNotifier notifier[VIRTIO_QUEUE_MAX]; } VhostVDPA; +int vhost_vdpa_get_iova_range(int fd, struct vhost_vdpa_iova_range *iova_range); + int vhost_vdpa_dma_map(struct vhost_vdpa *v, uint32_t asid, hwaddr iova, hwaddr size, void *vaddr, bool readonly); int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, uint32_t asid, hwaddr iova, diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h index 1cafa0d..a52f273 100644 --- a/include/hw/virtio/vhost.h +++ b/include/hw/virtio/vhost.h @@ -33,6 +33,7 @@ struct vhost_virtqueue { unsigned used_size; EventNotifier masked_notifier; EventNotifier error_notifier; + EventNotifier masked_config_notifier; struct vhost_dev *dev; }; @@ -41,6 +42,7 @@ typedef unsigned long vhost_log_chunk_t; #define VHOST_LOG_BITS (8 * sizeof(vhost_log_chunk_t)) #define VHOST_LOG_CHUNK (VHOST_LOG_PAGE * VHOST_LOG_BITS) #define VHOST_INVALID_FEATURE_BIT (0xff) +#define VHOST_QUEUE_NUM_CONFIG_INR 0 struct vhost_log { unsigned long long size; @@ -187,6 +189,8 @@ int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev); * Disable direct notifications to vhost device. */ void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev); +bool vhost_config_pending(struct vhost_dev *hdev); +void vhost_config_mask(struct vhost_dev *hdev, VirtIODevice *vdev, bool mask); /** * vhost_dev_is_started() - report status of vhost device diff --git a/include/hw/virtio/virtio-mmio.h b/include/hw/virtio/virtio-mmio.h index 090f773..aa49262 100644 --- a/include/hw/virtio/virtio-mmio.h +++ b/include/hw/virtio/virtio-mmio.h @@ -22,8 +22,8 @@ #ifndef HW_VIRTIO_MMIO_H #define HW_VIRTIO_MMIO_H +#include "hw/sysbus.h" #include "hw/virtio/virtio-bus.h" -#include "qom/object.h" /* QOM macros */ /* virtio-mmio-bus */ diff --git a/include/hw/virtio/virtio-pci.h b/include/hw/virtio/virtio-pci.h index 24fba16..ab2051b 100644 --- a/include/hw/virtio/virtio-pci.h +++ b/include/hw/virtio/virtio-pci.h @@ -261,5 +261,7 @@ void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t); * @fixed_queues. */ unsigned virtio_pci_optimal_num_queues(unsigned fixed_queues); - +void virtio_pci_set_guest_notifier_fd_handler(VirtIODevice *vdev, VirtQueue *vq, + int n, bool assign, + bool with_irqfd); #endif diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h index a36aad9..37b75e1 100644 --- a/include/hw/virtio/virtio-scsi.h +++ b/include/hw/virtio/virtio-scsi.h @@ -20,7 +20,6 @@ #define VIRTIO_SCSI_SENSE_SIZE 0 #include "standard-headers/linux/virtio_scsi.h" #include "hw/virtio/virtio.h" -#include "hw/pci/pci.h" #include "hw/scsi/scsi.h" #include "chardev/char-fe.h" #include "sysemu/iothread.h" diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 24561e9..77c6c55 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -22,7 +22,6 @@ #include "standard-headers/linux/virtio_config.h" #include "standard-headers/linux/virtio_ring.h" #include "qom/object.h" -#include "hw/virtio/vhost.h" /* * A guest should never accept this. It implies negotiation is broken @@ -79,6 +78,9 @@ typedef struct VirtQueueElement #define VIRTIO_NO_VECTOR 0xffff +/* special index value used internally for config irqs */ +#define VIRTIO_CONFIG_IRQ_IDX -1 + #define TYPE_VIRTIO_DEVICE "virtio-device" OBJECT_DECLARE_TYPE(VirtIODevice, VirtioDeviceClass, VIRTIO_DEVICE) @@ -152,6 +154,7 @@ struct VirtIODevice AddressSpace *dma_as; QLIST_HEAD(, VirtQueue) *vector_queues; QTAILQ_ENTRY(VirtIODevice) next; + EventNotifier config_notifier; }; struct VirtioDeviceClass { @@ -374,6 +377,9 @@ void virtio_queue_aio_attach_host_notifier_no_poll(VirtQueue *vq, AioContext *ct void virtio_queue_aio_detach_host_notifier(VirtQueue *vq, AioContext *ctx); VirtQueue *virtio_vector_first_queue(VirtIODevice *vdev, uint16_t vector); VirtQueue *virtio_vector_next_queue(VirtQueue *vq); +EventNotifier *virtio_config_get_guest_notifier(VirtIODevice *vdev); +void virtio_config_set_guest_notifier_fd_handler(VirtIODevice *vdev, + bool assign, bool with_irqfd); static inline void virtio_add_feature(uint64_t *features, unsigned int fbit) { diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h index 77ce17d..9a13a75 100644 --- a/include/hw/xen/xen_common.h +++ b/include/hw/xen/xen_common.h @@ -15,7 +15,7 @@ #include "hw/xen/interface/io/xenbus.h" #include "hw/xen/xen.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/xen/trace.h" extern xc_interface *xen_xc; diff --git a/include/net/vhost-user.h b/include/net/vhost-user.h index 5bcd8a6..35bf619 100644 --- a/include/net/vhost-user.h +++ b/include/net/vhost-user.h @@ -14,5 +14,6 @@ struct vhost_net; struct vhost_net *vhost_user_get_vhost_net(NetClientState *nc); uint64_t vhost_user_get_acked_features(NetClientState *nc); +void vhost_user_save_acked_features(NetClientState *nc); #endif /* VHOST_USER_H */ diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h index 40b9a40..c37aba3 100644 --- a/include/net/vhost_net.h +++ b/include/net/vhost_net.h @@ -39,6 +39,8 @@ int vhost_net_set_config(struct vhost_net *net, const uint8_t *data, bool vhost_net_virtqueue_pending(VHostNetState *net, int n); void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, int idx, bool mask); +bool vhost_net_config_pending(VHostNetState *net); +void vhost_net_config_mask(VHostNetState *net, VirtIODevice *dev, bool mask); int vhost_net_notify_migration_done(VHostNetState *net, char* mac_addr); VHostNetState *get_vhost_net(NetClientState *nc); @@ -52,4 +54,6 @@ void vhost_net_virtqueue_reset(VirtIODevice *vdev, NetClientState *nc, int vq_index); int vhost_net_virtqueue_restart(VirtIODevice *vdev, NetClientState *nc, int vq_index); + +void vhost_net_save_acked_features(NetClientState *nc); #endif diff --git a/include/qemu/plugin-memory.h b/include/qemu/plugin-memory.h index 8ad13c1..6fd5390 100644 --- a/include/qemu/plugin-memory.h +++ b/include/qemu/plugin-memory.h @@ -9,6 +9,9 @@ #ifndef PLUGIN_MEMORY_H #define PLUGIN_MEMORY_H +#include "exec/cpu-defs.h" +#include "exec/hwaddr.h" + struct qemu_plugin_hwaddr { bool is_io; bool is_store; diff --git a/include/sysemu/dirtyrate.h b/include/sysemu/dirtyrate.h index 4d3b9a4..20813f3 100644 --- a/include/sysemu/dirtyrate.h +++ b/include/sysemu/dirtyrate.h @@ -13,6 +13,8 @@ #ifndef QEMU_DIRTYRATE_H #define QEMU_DIRTYRATE_H +#include "qapi/qapi-types-migration.h" + typedef struct VcpuStat { int nvcpu; /* number of vcpu */ DirtyRateVcpu *rates; /* array of dirty rate for each vcpu */ diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h index 4ffed0b..7008d43 100644 --- a/include/sysemu/dump.h +++ b/include/sysemu/dump.h @@ -15,6 +15,7 @@ #define DUMP_H #include "qapi/qapi-types-dump.h" +#include "qemu/thread.h" #define MAKEDUMPFILE_SIGNATURE "makedumpfile" #define MAX_SIZE_MDF_HEADER (4096) /* max size of makedumpfile_header */ diff --git a/include/user/syscall-trace.h b/include/user/syscall-trace.h index b4e53d3..c5a220d 100644 --- a/include/user/syscall-trace.h +++ b/include/user/syscall-trace.h @@ -10,6 +10,7 @@ #ifndef SYSCALL_TRACE_H #define SYSCALL_TRACE_H +#include "exec/user/abitypes.h" #include "trace/trace-root.h" /* diff --git a/net/vhost-user.c b/net/vhost-user.c index 3a6b90d..5993e4a 100644 --- a/net/vhost-user.c +++ b/net/vhost-user.c @@ -45,10 +45,23 @@ uint64_t vhost_user_get_acked_features(NetClientState *nc) return s->acked_features; } -static void vhost_user_stop(int queues, NetClientState *ncs[]) +void vhost_user_save_acked_features(NetClientState *nc) { NetVhostUserState *s; + + s = DO_UPCAST(NetVhostUserState, nc, nc); + if (s->vhost_net) { + uint64_t features = vhost_net_get_acked_features(s->vhost_net); + if (features) { + s->acked_features = features; + } + } +} + +static void vhost_user_stop(int queues, NetClientState *ncs[]) +{ int i; + NetVhostUserState *s; for (i = 0; i < queues; i++) { assert(ncs[i]->info->type == NET_CLIENT_DRIVER_VHOST_USER); @@ -56,11 +69,7 @@ static void vhost_user_stop(int queues, NetClientState *ncs[]) s = DO_UPCAST(NetVhostUserState, nc, ncs[i]); if (s->vhost_net) { - /* save acked features */ - uint64_t features = vhost_net_get_acked_features(s->vhost_net); - if (features) { - s->acked_features = features; - } + vhost_user_save_acked_features(ncs[i]); vhost_net_cleanup(s->vhost_net); } } @@ -251,11 +260,7 @@ static void chr_closed_bh(void *opaque) s = DO_UPCAST(NetVhostUserState, nc, ncs[0]); for (i = queues -1; i >= 0; i--) { - s = DO_UPCAST(NetVhostUserState, nc, ncs[i]); - - if (s->vhost_net) { - s->acked_features = vhost_net_get_acked_features(s->vhost_net); - } + vhost_user_save_acked_features(ncs[i]); } qmp_set_link(name, false, &err); diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c index d36664f..1a13a34 100644 --- a/net/vhost-vdpa.c +++ b/net/vhost-vdpa.c @@ -74,7 +74,6 @@ const int vdpa_feature_bits[] = { VIRTIO_F_RING_RESET, VIRTIO_NET_F_RSS, VIRTIO_NET_F_HASH_REPORT, - VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_STATUS, VHOST_INVALID_FEATURE_BIT }; @@ -616,9 +615,18 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq, out.iov_len = iov_to_buf(elem->out_sg, elem->out_num, 0, s->cvq_cmd_out_buffer, vhost_vdpa_net_cvq_cmd_len()); - dev_written = vhost_vdpa_net_cvq_add(s, out.iov_len, sizeof(status)); - if (unlikely(dev_written < 0)) { - goto out; + if (*(uint8_t *)s->cvq_cmd_out_buffer == VIRTIO_NET_CTRL_ANNOUNCE) { + /* + * Guest announce capability is emulated by qemu, so don't forward to + * the device. + */ + dev_written = sizeof(status); + *s->status = VIRTIO_NET_OK; + } else { + dev_written = vhost_vdpa_net_cvq_add(s, out.iov_len, sizeof(status)); + if (unlikely(dev_written < 0)) { + goto out; + } } if (unlikely(dev_written < sizeof(status))) { @@ -702,14 +710,6 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer, return nc; } -static int vhost_vdpa_get_iova_range(int fd, - struct vhost_vdpa_iova_range *iova_range) -{ - int ret = ioctl(fd, VHOST_VDPA_GET_IOVA_RANGE, iova_range); - - return ret < 0 ? -errno : 0; -} - static int vhost_vdpa_get_features(int fd, uint64_t *features, Error **errp) { int ret = ioctl(fd, VHOST_GET_FEATURES, features); @@ -805,7 +805,13 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name, return queue_pairs; } - vhost_vdpa_get_iova_range(vdpa_device_fd, &iova_range); + r = vhost_vdpa_get_iova_range(vdpa_device_fd, &iova_range); + if (unlikely(r < 0)) { + error_setg(errp, "vhost-vdpa: get iova range failed: %s", + strerror(-r)); + goto err; + } + if (opts->x_svq) { if (!vhost_vdpa_net_valid_svq_features(features, errp)) { goto err_svq; diff --git a/qemu-options.hx b/qemu-options.hx index f3d5e13..fa0084c 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -343,6 +343,9 @@ SRST :: -smp 2 + + Note: The cluster topology will only be generated in ACPI and exposed + to guest if it's explicitly specified in -smp. ERST DEF("numa", HAS_ARG, QEMU_OPTION_numa, diff --git a/tests/data/acpi/virt/APIC.topology b/tests/data/acpi/virt/APIC.topology Binary files differnew file mode 100644 index 0000000..3a6ac52 --- /dev/null +++ b/tests/data/acpi/virt/APIC.topology diff --git a/tests/data/acpi/virt/DSDT.topology b/tests/data/acpi/virt/DSDT.topology Binary files differnew file mode 100644 index 0000000..501314c --- /dev/null +++ b/tests/data/acpi/virt/DSDT.topology diff --git a/tests/data/acpi/virt/PPTT b/tests/data/acpi/virt/PPTT Binary files differindex f56ea63..7a1258e 100644 --- a/tests/data/acpi/virt/PPTT +++ b/tests/data/acpi/virt/PPTT diff --git a/tests/data/acpi/virt/PPTT.acpihmatvirt b/tests/data/acpi/virt/PPTT.acpihmatvirt Binary files differindex 710dba5..4eef303 100644 --- a/tests/data/acpi/virt/PPTT.acpihmatvirt +++ b/tests/data/acpi/virt/PPTT.acpihmatvirt diff --git a/tests/data/acpi/virt/PPTT.topology b/tests/data/acpi/virt/PPTT.topology Binary files differnew file mode 100644 index 0000000..3fbcae5 --- /dev/null +++ b/tests/data/acpi/virt/PPTT.topology diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c index 395d441..e954a9c 100644 --- a/tests/qtest/bios-tables-test.c +++ b/tests/qtest/bios-tables-test.c @@ -1720,6 +1720,24 @@ static void test_acpi_virt_tcg(void) free_test_data(&data); } +static void test_acpi_virt_tcg_topology(void) +{ + test_data data = { + .machine = "virt", + .variant = ".topology", + .tcg_only = true, + .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", + .uefi_fl2 = "pc-bios/edk2-arm-vars.fd", + .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2", + .ram_start = 0x40000000ULL, + .scan_len = 128ULL * 1024 * 1024, + }; + + test_acpi_one("-cpu cortex-a57 " + "-smp sockets=1,clusters=2,cores=2,threads=2", &data); + free_test_data(&data); +} + static void test_acpi_q35_viot(void) { test_data data = { @@ -2057,6 +2075,7 @@ int main(int argc, char *argv[]) qtest_add_func("acpi/virt", test_acpi_virt_tcg); qtest_add_func("acpi/virt/acpihmatvirt", test_acpi_virt_tcg_acpi_hmat); + qtest_add_func("acpi/virt/topology", test_acpi_virt_tcg_topology); qtest_add_func("acpi/virt/numamem", test_acpi_virt_tcg_numamem); qtest_add_func("acpi/virt/memhp", test_acpi_virt_tcg_memhp); qtest_add_func("acpi/virt/pxb", test_acpi_virt_tcg_pxb); diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c index afc1d20..7326f68 100644 --- a/tests/qtest/fuzz/generic_fuzz.c +++ b/tests/qtest/fuzz/generic_fuzz.c @@ -24,6 +24,7 @@ #include "exec/ramblock.h" #include "hw/qdev-core.h" #include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/boards.h" #include "generic_fuzz_configs.h" #include "hw/mem/sparse-mem.h" @@ -17,7 +17,7 @@ #include "qemu/osdep.h" -#include "hw/pci/pci.h" +#include "hw/pci/pci_device.h" #include "hw/pci/pci_bus.h" #include "qapi/error.h" #include "ui/console.h" |