aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS1
-rw-r--r--configs/devices/mips-softmmu/common.mak5
-rw-r--r--hw/acpi/Kconfig10
-rw-r--r--hw/acpi/acpi-cpu-hotplug-stub.c50
-rw-r--r--hw/acpi/acpi-mem-hotplug-stub.c35
-rw-r--r--hw/acpi/acpi-nvdimm-stub.c8
-rw-r--r--hw/acpi/acpi-pci-hotplug-stub.c47
-rw-r--r--hw/acpi/ich9.c2
-rw-r--r--hw/acpi/meson.build14
-rw-r--r--hw/acpi/pcihp.c6
-rw-r--r--hw/acpi/piix4.c4
-rw-r--r--hw/i386/acpi-build.c24
-rw-r--r--hw/i386/pc.c13
-rw-r--r--hw/i386/pc_q35.c2
-rw-r--r--hw/isa/lpc_ich9.c13
-rw-r--r--hw/net/vhost_net.c5
-rw-r--r--hw/pci-host/i440fx.c8
-rw-r--r--hw/virtio/vhost-backend.c30
-rw-r--r--hw/virtio/vhost-user.c151
-rw-r--r--hw/virtio/vhost-vdpa.c39
-rw-r--r--hw/virtio/vhost.c31
-rw-r--r--hw/virtio/virtio-balloon.c41
-rw-r--r--hw/virtio/virtio-bus.c14
-rw-r--r--hw/virtio/virtio-pci.c14
-rw-r--r--hw/virtio/virtio.c7
-rw-r--r--include/hw/acpi/acpi.h2
-rw-r--r--include/hw/acpi/generic_event_device.h2
-rw-r--r--include/hw/i386/pc.h4
-rw-r--r--include/hw/pci-host/i440fx.h1
-rw-r--r--include/hw/virtio/vhost-backend.h6
-rw-r--r--include/hw/virtio/vhost-vdpa.h1
-rw-r--r--include/hw/virtio/vhost.h6
-rw-r--r--include/hw/virtio/virtio-bus.h4
-rw-r--r--include/net/vhost_net.h1
-rw-r--r--net/tap.c1
-rw-r--r--net/vhost-user.c1
-rw-r--r--net/vhost-vdpa.c35
-rw-r--r--stubs/meson.build1
-rw-r--r--stubs/pci-host-piix.c7
-rw-r--r--tests/vhost-user-bridge.c7
40 files changed, 440 insertions, 213 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 5d923a6544..6c20634d63 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1751,6 +1751,7 @@ F: docs/specs/*pci*
ACPI/SMBIOS
M: Michael S. Tsirkin <mst@redhat.com>
M: Igor Mammedov <imammedo@redhat.com>
+R: Ani Sinha <ani@anisinha.ca>
S: Supported
F: include/hw/acpi/*
F: include/hw/firmware/smbios.h
diff --git a/configs/devices/mips-softmmu/common.mak b/configs/devices/mips-softmmu/common.mak
index ea78fe7275..752b62b1e6 100644
--- a/configs/devices/mips-softmmu/common.mak
+++ b/configs/devices/mips-softmmu/common.mak
@@ -18,10 +18,7 @@ CONFIG_PCSPK=y
CONFIG_PCKBD=y
CONFIG_FDC=y
CONFIG_ACPI=y
-CONFIG_ACPI_X86=y
-CONFIG_ACPI_MEMORY_HOTPLUG=y
-CONFIG_ACPI_NVDIMM=y
-CONFIG_ACPI_CPU_HOTPLUG=y
+CONFIG_ACPI_PIIX4=y
CONFIG_APM=y
CONFIG_I8257=y
CONFIG_PIIX4=y
diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig
index cfc4ede8d9..3b5e118c54 100644
--- a/hw/acpi/Kconfig
+++ b/hw/acpi/Kconfig
@@ -8,6 +8,8 @@ config ACPI_X86
select ACPI_CPU_HOTPLUG
select ACPI_MEMORY_HOTPLUG
select ACPI_HMAT
+ select ACPI_PIIX4
+ select ACPI_PCIHP
config ACPI_X86_ICH
bool
@@ -24,6 +26,14 @@ config ACPI_NVDIMM
bool
depends on ACPI
+config ACPI_PIIX4
+ bool
+ depends on ACPI
+
+config ACPI_PCIHP
+ bool
+ depends on ACPI
+
config ACPI_HMAT
bool
depends on ACPI
diff --git a/hw/acpi/acpi-cpu-hotplug-stub.c b/hw/acpi/acpi-cpu-hotplug-stub.c
new file mode 100644
index 0000000000..3fc4b14c26
--- /dev/null
+++ b/hw/acpi/acpi-cpu-hotplug-stub.c
@@ -0,0 +1,50 @@
+#include "qemu/osdep.h"
+#include "hw/acpi/cpu_hotplug.h"
+#include "migration/vmstate.h"
+
+
+/* Following stubs are all related to ACPI cpu hotplug */
+const VMStateDescription vmstate_cpu_hotplug;
+
+void acpi_switch_to_modern_cphp(AcpiCpuHotplug *gpe_cpu,
+ CPUHotplugState *cpuhp_state,
+ uint16_t io_port)
+{
+ return;
+}
+
+void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
+ AcpiCpuHotplug *gpe_cpu, uint16_t base)
+{
+ return;
+}
+
+void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list)
+{
+ return;
+}
+
+void acpi_cpu_plug_cb(HotplugHandler *hotplug_dev,
+ CPUHotplugState *cpu_st, DeviceState *dev, Error **errp)
+{
+ return;
+}
+
+void legacy_acpi_cpu_plug_cb(HotplugHandler *hotplug_dev,
+ AcpiCpuHotplug *g, DeviceState *dev, Error **errp)
+{
+ return;
+}
+
+void acpi_cpu_unplug_cb(CPUHotplugState *cpu_st,
+ DeviceState *dev, Error **errp)
+{
+ return;
+}
+
+void acpi_cpu_unplug_request_cb(HotplugHandler *hotplug_dev,
+ CPUHotplugState *cpu_st,
+ DeviceState *dev, Error **errp)
+{
+ return;
+}
diff --git a/hw/acpi/acpi-mem-hotplug-stub.c b/hw/acpi/acpi-mem-hotplug-stub.c
new file mode 100644
index 0000000000..73a076a265
--- /dev/null
+++ b/hw/acpi/acpi-mem-hotplug-stub.c
@@ -0,0 +1,35 @@
+#include "qemu/osdep.h"
+#include "hw/acpi/memory_hotplug.h"
+#include "migration/vmstate.h"
+
+const VMStateDescription vmstate_memory_hotplug;
+
+void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner,
+ MemHotplugState *state, hwaddr io_base)
+{
+ return;
+}
+
+void acpi_memory_ospm_status(MemHotplugState *mem_st, ACPIOSTInfoList ***list)
+{
+ return;
+}
+
+void acpi_memory_plug_cb(HotplugHandler *hotplug_dev, MemHotplugState *mem_st,
+ DeviceState *dev, Error **errp)
+{
+ return;
+}
+
+void acpi_memory_unplug_cb(MemHotplugState *mem_st,
+ DeviceState *dev, Error **errp)
+{
+ return;
+}
+
+void acpi_memory_unplug_request_cb(HotplugHandler *hotplug_dev,
+ MemHotplugState *mem_st,
+ DeviceState *dev, Error **errp)
+{
+ return;
+}
diff --git a/hw/acpi/acpi-nvdimm-stub.c b/hw/acpi/acpi-nvdimm-stub.c
new file mode 100644
index 0000000000..8baff9be6f
--- /dev/null
+++ b/hw/acpi/acpi-nvdimm-stub.c
@@ -0,0 +1,8 @@
+#include "qemu/osdep.h"
+#include "hw/mem/nvdimm.h"
+#include "hw/hotplug.h"
+
+void nvdimm_acpi_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev)
+{
+ return;
+}
diff --git a/hw/acpi/acpi-pci-hotplug-stub.c b/hw/acpi/acpi-pci-hotplug-stub.c
new file mode 100644
index 0000000000..734e4c5986
--- /dev/null
+++ b/hw/acpi/acpi-pci-hotplug-stub.c
@@ -0,0 +1,47 @@
+#include "qemu/osdep.h"
+#include "hw/acpi/pcihp.h"
+#include "migration/vmstate.h"
+
+const VMStateDescription vmstate_acpi_pcihp_pci_status;
+
+void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, PCIBus *root_bus,
+ MemoryRegion *address_space_io, bool bridges_enabled,
+ uint16_t io_base)
+{
+ return;
+}
+
+void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
+ DeviceState *dev, Error **errp)
+{
+ return;
+}
+
+void acpi_pcihp_device_pre_plug_cb(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ return;
+}
+
+void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
+ DeviceState *dev, Error **errp)
+{
+ return;
+}
+
+void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
+ AcpiPciHpState *s, DeviceState *dev,
+ Error **errp)
+{
+ return;
+}
+
+void acpi_pcihp_reset(AcpiPciHpState *s, bool acpihp_root_off)
+{
+ return;
+}
+
+bool vmstate_acpi_pcihp_use_acpi_index(void *opaque, int version_id)
+{
+ return false;
+}
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 778e27b659..1ee2ba2c50 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -451,7 +451,7 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
object_property_add_bool(obj, ACPI_PM_PROP_TCO_ENABLED,
ich9_pm_get_enable_tco,
ich9_pm_set_enable_tco);
- object_property_add_bool(obj, "acpi-pci-hotplug-with-bridge-support",
+ object_property_add_bool(obj, ACPI_PM_PROP_ACPI_PCIHP_BRIDGE,
ich9_pm_get_acpi_pci_hotplug,
ich9_pm_set_acpi_pci_hotplug);
}
diff --git a/hw/acpi/meson.build b/hw/acpi/meson.build
index 29f804d13e..7d8c0eb43e 100644
--- a/hw/acpi/meson.build
+++ b/hw/acpi/meson.build
@@ -6,16 +6,20 @@ acpi_ss.add(files(
'core.c',
'utils.c',
))
-acpi_ss.add(when: 'CONFIG_ACPI_CPU_HOTPLUG', if_true: files('cpu.c'))
-acpi_ss.add(when: 'CONFIG_ACPI_CPU_HOTPLUG', if_true: files('cpu_hotplug.c'))
+acpi_ss.add(when: 'CONFIG_ACPI_CPU_HOTPLUG', if_true: files('cpu.c', 'cpu_hotplug.c'))
+acpi_ss.add(when: 'CONFIG_ACPI_CPU_HOTPLUG', if_false: files('acpi-cpu-hotplug-stub.c'))
acpi_ss.add(when: 'CONFIG_ACPI_MEMORY_HOTPLUG', if_true: files('memory_hotplug.c'))
+acpi_ss.add(when: 'CONFIG_ACPI_MEMORY_HOTPLUG', if_false: files('acpi-mem-hotplug-stub.c'))
acpi_ss.add(when: 'CONFIG_ACPI_NVDIMM', if_true: files('nvdimm.c'))
+acpi_ss.add(when: 'CONFIG_ACPI_NVDIMM', if_false: files('acpi-nvdimm-stub.c'))
acpi_ss.add(when: 'CONFIG_ACPI_PCI', if_true: files('pci.c'))
acpi_ss.add(when: 'CONFIG_ACPI_VMGENID', if_true: files('vmgenid.c'))
acpi_ss.add(when: 'CONFIG_ACPI_HW_REDUCED', if_true: files('generic_event_device.c'))
acpi_ss.add(when: 'CONFIG_ACPI_HMAT', if_true: files('hmat.c'))
acpi_ss.add(when: 'CONFIG_ACPI_APEI', if_true: files('ghes.c'), if_false: files('ghes-stub.c'))
-acpi_ss.add(when: 'CONFIG_ACPI_X86', if_true: files('piix4.c', 'pcihp.c'))
+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_X86_ICH', if_true: files('ich9.c', 'tco.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'))
@@ -23,4 +27,6 @@ acpi_ss.add(when: 'CONFIG_TPM', if_true: files('tpm.c'))
softmmu_ss.add(when: 'CONFIG_ACPI', if_false: files('acpi-stub.c', 'aml-build-stub.c', 'ghes-stub.c'))
softmmu_ss.add_all(when: 'CONFIG_ACPI', if_true: acpi_ss)
softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('acpi-stub.c', 'aml-build-stub.c',
- 'acpi-x86-stub.c', 'ipmi-stub.c', 'ghes-stub.c'))
+ 'acpi-x86-stub.c', 'ipmi-stub.c', 'ghes-stub.c',
+ 'acpi-mem-hotplug-stub.c', 'acpi-cpu-hotplug-stub.c',
+ 'acpi-pci-hotplug-stub.c', 'acpi-nvdimm-stub.c'))
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index f4d706e47d..f610a25d2e 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -283,7 +283,7 @@ void acpi_pcihp_device_pre_plug_cb(HotplugHandler *hotplug_dev,
/* Only hotplugged devices need the hotplug capability. */
if (dev->hotplugged &&
- acpi_pcihp_get_bsel(pci_get_bus(PCI_DEVICE(dev))) < 0) {
+ acpi_pcihp_get_bsel(pci_get_bus(pdev)) < 0) {
error_setg(errp, "Unsupported bus. Bus doesn't have property '"
ACPI_PCIHP_PROP_BSEL "' set");
return;
@@ -363,8 +363,8 @@ void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
{
PCIDevice *pdev = PCI_DEVICE(dev);
- trace_acpi_pci_unplug(PCI_SLOT(PCI_DEVICE(dev)->devfn),
- acpi_pcihp_get_bsel(pci_get_bus(PCI_DEVICE(dev))));
+ trace_acpi_pci_unplug(PCI_SLOT(pdev->devfn),
+ acpi_pcihp_get_bsel(pci_get_bus(pdev)));
/*
* clean up acpi-index so it could reused by another device
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 48f7a1edbc..f0b5fac44a 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -647,9 +647,9 @@ static Property piix4_pm_properties[] = {
DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0),
DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 0),
DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_VAL, PIIX4PMState, s4_val, 2),
- DEFINE_PROP_BOOL("acpi-pci-hotplug-with-bridge-support", PIIX4PMState,
+ DEFINE_PROP_BOOL(ACPI_PM_PROP_ACPI_PCIHP_BRIDGE, PIIX4PMState,
use_acpi_hotplug_bridge, true),
- DEFINE_PROP_BOOL("acpi-root-pci-hotplug", PIIX4PMState,
+ DEFINE_PROP_BOOL(ACPI_PM_PROP_ACPI_PCI_ROOTHP, PIIX4PMState,
use_acpi_root_pci_hotplug, true),
DEFINE_PROP_BOOL("memory-hotplug-support", PIIX4PMState,
acpi_memory_hotplug.is_enabled, true),
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index a33ac8b91e..d1f5fa3b5a 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -267,10 +267,10 @@ static void acpi_get_pm_info(MachineState *machine, AcpiPmInfo *pm)
qobject_unref(o);
pm->pcihp_bridge_en =
- object_property_get_bool(obj, "acpi-pci-hotplug-with-bridge-support",
+ object_property_get_bool(obj, ACPI_PM_PROP_ACPI_PCIHP_BRIDGE,
NULL);
pm->pcihp_root_en =
- object_property_get_bool(obj, "acpi-root-pci-hotplug",
+ object_property_get_bool(obj, ACPI_PM_PROP_ACPI_PCI_ROOTHP,
NULL);
}
@@ -303,13 +303,9 @@ Object *acpi_get_i386_pci_host(void)
{
PCIHostState *host;
- host = OBJECT_CHECK(PCIHostState,
- object_resolve_path("/machine/i440fx", NULL),
- TYPE_PCI_HOST_BRIDGE);
+ host = PCI_HOST_BRIDGE(object_resolve_path("/machine/i440fx", NULL));
if (!host) {
- host = OBJECT_CHECK(PCIHostState,
- object_resolve_path("/machine/q35", NULL),
- TYPE_PCI_HOST_BRIDGE);
+ host = PCI_HOST_BRIDGE(object_resolve_path("/machine/q35", NULL));
}
return OBJECT(host);
@@ -1918,6 +1914,8 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
X86MachineState *x86ms = X86_MACHINE(machine);
const CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(machine);
PCMachineState *pcms = PC_MACHINE(machine);
+ int nb_numa_nodes = machine->numa_state->num_nodes;
+ NodeInfo *numa_info = machine->numa_state->nodes;
ram_addr_t hotplugabble_address_space_size =
object_property_get_int(OBJECT(pcms), PC_MACHINE_DEVMEM_REGION_SIZE,
NULL);
@@ -1961,9 +1959,9 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
next_base = 0;
numa_start = table_data->len;
- for (i = 1; i < pcms->numa_nodes + 1; ++i) {
+ for (i = 1; i < nb_numa_nodes + 1; ++i) {
mem_base = next_base;
- mem_len = pcms->node_mem[i - 1];
+ mem_len = numa_info[i - 1].node_mem;
next_base = mem_base + mem_len;
/* Cut out the 640K hole */
@@ -2011,7 +2009,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
}
slots = (table_data->len - numa_start) / sizeof *numamem;
- for (; slots < pcms->numa_nodes + 2; slots++) {
+ for (; slots < nb_numa_nodes + 2; slots++) {
numamem = acpi_data_push(table_data, sizeof *numamem);
build_srat_memory(numamem, 0, 0, 0, MEM_AFFINITY_NOFLAGS);
}
@@ -2027,7 +2025,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
if (hotplugabble_address_space_size) {
numamem = acpi_data_push(table_data, sizeof *numamem);
build_srat_memory(numamem, machine->device_memory->base,
- hotplugabble_address_space_size, pcms->numa_nodes - 1,
+ hotplugabble_address_space_size, nb_numa_nodes - 1,
MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED);
}
@@ -2529,7 +2527,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
}
}
#endif
- if (pcms->numa_nodes) {
+ if (machine->numa_state->num_nodes) {
acpi_add_table(table_offsets, tables_blob);
build_srat(tables_blob, tables->linker, machine);
if (machine->numa_state->have_numa_distance) {
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 1276bfeee4..7e523b913c 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -101,7 +101,7 @@ GlobalProperty pc_compat_6_0[] = {
{ "qemu64" "-" TYPE_X86_CPU, "model", "6" },
{ "qemu64" "-" TYPE_X86_CPU, "stepping", "3" },
{ TYPE_X86_CPU, "x-vendor-cpuid-only", "off" },
- { "ICH9-LPC", "acpi-pci-hotplug-with-bridge-support", "off" },
+ { "ICH9-LPC", ACPI_PM_PROP_ACPI_PCIHP_BRIDGE, "off" },
};
const size_t pc_compat_6_0_len = G_N_ELEMENTS(pc_compat_6_0);
@@ -313,7 +313,7 @@ const size_t pc_compat_2_0_len = G_N_ELEMENTS(pc_compat_2_0);
GlobalProperty pc_compat_1_7[] = {
PC_CPU_MODEL_IDS("1.7.0")
{ TYPE_USB_DEVICE, "msos-desc", "no" },
- { "PIIX4_PM", "acpi-pci-hotplug-with-bridge-support", "off" },
+ { "PIIX4_PM", ACPI_PM_PROP_ACPI_PCIHP_BRIDGE, "off" },
{ "hpet", HPET_INTCAP, "4" },
};
const size_t pc_compat_1_7_len = G_N_ELEMENTS(pc_compat_1_7);
@@ -802,18 +802,9 @@ void pc_machine_done(Notifier *notifier, void *data)
void pc_guest_info_init(PCMachineState *pcms)
{
- int i;
- MachineState *ms = MACHINE(pcms);
X86MachineState *x86ms = X86_MACHINE(pcms);
x86ms->apic_xrupt_override = true;
- pcms->numa_nodes = ms->numa_state->num_nodes;
- pcms->node_mem = g_malloc0(pcms->numa_nodes *
- sizeof *pcms->node_mem);
- for (i = 0; i < ms->numa_state->num_nodes; i++) {
- pcms->node_mem[i] = ms->numa_state->nodes[i].node_mem;
- }
-
pcms->machine_done.notify = pc_machine_done;
qemu_add_machine_init_done_notifier(&pcms->machine_done);
}
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 565fadce54..46cd542d17 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -238,7 +238,7 @@ static void pc_q35_init(MachineState *machine)
OBJECT(lpc), &error_abort);
acpi_pcihp = object_property_get_bool(OBJECT(lpc),
- "acpi-pci-hotplug-with-bridge-support",
+ ACPI_PM_PROP_ACPI_PCIHP_BRIDGE,
NULL);
if (acpi_pcihp) {
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 5f9de0239c..5f143dca17 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -31,6 +31,7 @@
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "cpu.h"
+#include "qapi/error.h"
#include "qapi/visitor.h"
#include "qemu/range.h"
#include "hw/isa/isa.h"
@@ -676,6 +677,18 @@ static void ich9_lpc_realize(PCIDevice *d, Error **errp)
DeviceState *dev = DEVICE(d);
ISABus *isa_bus;
+ if ((lpc->smi_host_features & BIT_ULL(ICH9_LPC_SMI_F_CPU_HOT_UNPLUG_BIT)) &&
+ !(lpc->smi_host_features & BIT_ULL(ICH9_LPC_SMI_F_CPU_HOTPLUG_BIT))) {
+ /*
+ * smi_features_ok_callback() throws an error on this.
+ *
+ * So bail out here instead of advertizing the invalid
+ * configuration and get obscure firmware failures from that.
+ */
+ error_setg(errp, "cpu hot-unplug requires cpu hot-plug");
+ return;
+ }
+
isa_bus = isa_bus_new(DEVICE(d), get_system_memory(), get_system_io(),
errp);
if (!isa_bus) {
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 10a7780a13..386ec2eaa2 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -165,9 +165,9 @@ struct vhost_net *vhost_net_init(VhostNetOptions *options)
goto fail;
}
net->nc = options->net_backend;
+ net->dev.nvqs = options->nvqs;
net->dev.max_queues = 1;
- net->dev.nvqs = 2;
net->dev.vqs = net->vqs;
if (backend_kernel) {
@@ -242,9 +242,6 @@ static int vhost_net_start_one(struct vhost_net *net,
struct vhost_vring_file file = { };
int r;
- net->dev.nvqs = 2;
- net->dev.vqs = net->vqs;
-
r = vhost_dev_enable_notifiers(&net->dev, dev);
if (r < 0) {
goto fail_notifiers;
diff --git a/hw/pci-host/i440fx.c b/hw/pci-host/i440fx.c
index 28c9bae899..e08716142b 100644
--- a/hw/pci-host/i440fx.c
+++ b/hw/pci-host/i440fx.c
@@ -314,14 +314,6 @@ PCIBus *i440fx_init(const char *host_type, const char *pci_type,
return b;
}
-PCIBus *find_i440fx(void)
-{
- PCIHostState *s = OBJECT_CHECK(PCIHostState,
- object_resolve_path("/machine/i440fx", NULL),
- TYPE_PCI_HOST_BRIDGE);
- return s ? s->bus : NULL;
-}
-
static void i440fx_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
index 594d770b75..b65f8f7e97 100644
--- a/hw/virtio/vhost-backend.c
+++ b/hw/virtio/vhost-backend.c
@@ -293,7 +293,7 @@ static void vhost_kernel_set_iotlb_callback(struct vhost_dev *dev,
qemu_set_fd_handler((uintptr_t)dev->opaque, NULL, NULL, NULL);
}
-static const VhostOps kernel_ops = {
+const VhostOps kernel_ops = {
.backend_type = VHOST_BACKEND_TYPE_KERNEL,
.vhost_backend_init = vhost_kernel_init,
.vhost_backend_cleanup = vhost_kernel_cleanup,
@@ -328,34 +328,6 @@ static const VhostOps kernel_ops = {
};
#endif
-int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type)
-{
- int r = 0;
-
- switch (backend_type) {
-#ifdef CONFIG_VHOST_KERNEL
- case VHOST_BACKEND_TYPE_KERNEL:
- dev->vhost_ops = &kernel_ops;
- break;
-#endif
-#ifdef CONFIG_VHOST_USER
- case VHOST_BACKEND_TYPE_USER:
- dev->vhost_ops = &user_ops;
- break;
-#endif
-#ifdef CONFIG_VHOST_VDPA
- case VHOST_BACKEND_TYPE_VDPA:
- dev->vhost_ops = &vdpa_ops;
- break;
-#endif
- default:
- error_report("Unknown vhost backend type");
- r = -1;
- }
-
- return r;
-}
-
int vhost_backend_update_device_iotlb(struct vhost_dev *dev,
uint64_t iova, uint64_t uaddr,
uint64_t len,
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 2407836fac..2c8556237f 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -429,7 +429,7 @@ static int process_message_reply(struct vhost_dev *dev,
}
if (msg_reply.hdr.request != msg->hdr.request) {
- error_report("Received unexpected msg type."
+ error_report("Received unexpected msg type. "
"Expected %d received %d",
msg->hdr.request, msg_reply.hdr.request);
return -1;
@@ -1095,23 +1095,6 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
return 0;
}
-static int vhost_user_set_vring_addr(struct vhost_dev *dev,
- struct vhost_vring_addr *addr)
-{
- VhostUserMsg msg = {
- .hdr.request = VHOST_USER_SET_VRING_ADDR,
- .hdr.flags = VHOST_USER_VERSION,
- .payload.addr = *addr,
- .hdr.size = sizeof(msg.payload.addr),
- };
-
- if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
- return -1;
- }
-
- return 0;
-}
-
static int vhost_user_set_vring_endian(struct vhost_dev *dev,
struct vhost_vring_state *ring)
{
@@ -1288,33 +1271,6 @@ static int vhost_user_set_vring_call(struct vhost_dev *dev,
return vhost_set_vring_file(dev, VHOST_USER_SET_VRING_CALL, file);
}
-static int vhost_user_set_u64(struct vhost_dev *dev, int request, uint64_t u64)
-{
- VhostUserMsg msg = {
- .hdr.request = request,
- .hdr.flags = VHOST_USER_VERSION,
- .payload.u64 = u64,
- .hdr.size = sizeof(msg.payload.u64),
- };
-
- if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
- return -1;
- }
-
- return 0;
-}
-
-static int vhost_user_set_features(struct vhost_dev *dev,
- uint64_t features)
-{
- return vhost_user_set_u64(dev, VHOST_USER_SET_FEATURES, features);
-}
-
-static int vhost_user_set_protocol_features(struct vhost_dev *dev,
- uint64_t features)
-{
- return vhost_user_set_u64(dev, VHOST_USER_SET_PROTOCOL_FEATURES, features);
-}
static int vhost_user_get_u64(struct vhost_dev *dev, int request, uint64_t *u64)
{
@@ -1360,6 +1316,107 @@ static int vhost_user_get_features(struct vhost_dev *dev, uint64_t *features)
return 0;
}
+static int enforce_reply(struct vhost_dev *dev,
+ const VhostUserMsg *msg)
+{
+ uint64_t dummy;
+
+ if (msg->hdr.flags & VHOST_USER_NEED_REPLY_MASK) {
+ return process_message_reply(dev, msg);
+ }
+
+ /*
+ * We need to wait for a reply but the backend does not
+ * support replies for the command we just sent.
+ * Send VHOST_USER_GET_FEATURES which makes all backends
+ * send a reply.
+ */
+ return vhost_user_get_features(dev, &dummy);
+}
+
+static int vhost_user_set_vring_addr(struct vhost_dev *dev,
+ struct vhost_vring_addr *addr)
+{
+ VhostUserMsg msg = {
+ .hdr.request = VHOST_USER_SET_VRING_ADDR,
+ .hdr.flags = VHOST_USER_VERSION,
+ .payload.addr = *addr,
+ .hdr.size = sizeof(msg.payload.addr),
+ };
+
+ bool reply_supported = virtio_has_feature(dev->protocol_features,
+ VHOST_USER_PROTOCOL_F_REPLY_ACK);
+
+ /*
+ * wait for a reply if logging is enabled to make sure
+ * backend is actually logging changes
+ */
+ bool wait_for_reply = addr->flags & (1 << VHOST_VRING_F_LOG);
+
+ if (reply_supported && wait_for_reply) {
+ msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK;
+ }
+
+ if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
+ return -1;
+ }
+
+ if (wait_for_reply) {
+ return enforce_reply(dev, &msg);
+ }
+
+ return 0;
+}
+
+static int vhost_user_set_u64(struct vhost_dev *dev, int request, uint64_t u64,
+ bool wait_for_reply)
+{
+ VhostUserMsg msg = {
+ .hdr.request = request,
+ .hdr.flags = VHOST_USER_VERSION,
+ .payload.u64 = u64,
+ .hdr.size = sizeof(msg.payload.u64),
+ };
+
+ if (wait_for_reply) {
+ bool reply_supported = virtio_has_feature(dev->protocol_features,
+ VHOST_USER_PROTOCOL_F_REPLY_ACK);
+ if (reply_supported) {
+ msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK;
+ }
+ }
+
+ if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
+ return -1;
+ }
+
+ if (wait_for_reply) {
+ return enforce_reply(dev, &msg);
+ }
+
+ return 0;
+}
+
+static int vhost_user_set_features(struct vhost_dev *dev,
+ uint64_t features)
+{
+ /*
+ * wait for a reply if logging is enabled to make sure
+ * backend is actually logging changes
+ */
+ bool log_enabled = features & (0x1ULL << VHOST_F_LOG_ALL);
+
+ return vhost_user_set_u64(dev, VHOST_USER_SET_FEATURES, features,
+ log_enabled);
+}
+
+static int vhost_user_set_protocol_features(struct vhost_dev *dev,
+ uint64_t features)
+{
+ return vhost_user_set_u64(dev, VHOST_USER_SET_PROTOCOL_FEATURES, features,
+ false);
+}
+
static int vhost_user_set_owner(struct vhost_dev *dev)
{
VhostUserMsg msg = {
@@ -1474,6 +1531,7 @@ static int vhost_user_slave_handle_vring_host_notifier(struct vhost_dev *dev,
g_free(name);
if (virtio_queue_set_host_notifier_mr(vdev, queue_idx, &n->mr, true)) {
+ object_unparent(OBJECT(&n->mr));
munmap(addr, page_size);
return -1;
}
@@ -2422,7 +2480,7 @@ void vhost_user_cleanup(VhostUserState *user)
if (!user->chr) {
return;
}
-
+ memory_region_transaction_begin();
for (i = 0; i < VIRTIO_QUEUE_MAX; i++) {
if (user->notifier[i].addr) {
object_unparent(OBJECT(&user->notifier[i].mr));
@@ -2430,6 +2488,7 @@ void vhost_user_cleanup(VhostUserState *user)
user->notifier[i].addr = NULL;
}
}
+ memory_region_transaction_commit();
user->chr = NULL;
}
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 4fa414feea..7633ea66d1 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -89,19 +89,13 @@ static int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, hwaddr iova,
return ret;
}
-static void vhost_vdpa_listener_begin(MemoryListener *listener)
+static void vhost_vdpa_listener_begin_batch(struct vhost_vdpa *v)
{
- struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
- struct vhost_dev *dev = v->dev;
- struct vhost_msg_v2 msg = {};
int fd = v->device_fd;
-
- if (!(dev->backend_cap & (0x1ULL << VHOST_BACKEND_F_IOTLB_BATCH))) {
- return;
- }
-
- msg.type = v->msg_type;
- msg.iotlb.type = VHOST_IOTLB_BATCH_BEGIN;
+ struct vhost_msg_v2 msg = {
+ .type = v->msg_type,
+ .iotlb.type = VHOST_IOTLB_BATCH_BEGIN,
+ };
if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) {
error_report("failed to write, fd=%d, errno=%d (%s)",
@@ -109,6 +103,16 @@ static void vhost_vdpa_listener_begin(MemoryListener *listener)
}
}
+static void vhost_vdpa_iotlb_batch_begin_once(struct vhost_vdpa *v)
+{
+ if (v->dev->backend_cap & (0x1ULL << VHOST_BACKEND_F_IOTLB_BATCH) &&
+ !v->iotlb_batch_begin_sent) {
+ vhost_vdpa_listener_begin_batch(v);
+ }
+
+ v->iotlb_batch_begin_sent = true;
+}
+
static void vhost_vdpa_listener_commit(MemoryListener *listener)
{
struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
@@ -120,6 +124,10 @@ static void vhost_vdpa_listener_commit(MemoryListener *listener)
return;
}
+ if (!v->iotlb_batch_begin_sent) {
+ return;
+ }
+
msg.type = v->msg_type;
msg.iotlb.type = VHOST_IOTLB_BATCH_END;
@@ -127,6 +135,8 @@ static void vhost_vdpa_listener_commit(MemoryListener *listener)
error_report("failed to write, fd=%d, errno=%d (%s)",
fd, errno, strerror(errno));
}
+
+ v->iotlb_batch_begin_sent = false;
}
static void vhost_vdpa_listener_region_add(MemoryListener *listener,
@@ -170,6 +180,7 @@ static void vhost_vdpa_listener_region_add(MemoryListener *listener,
llsize = int128_sub(llend, int128_make64(iova));
+ vhost_vdpa_iotlb_batch_begin_once(v);
ret = vhost_vdpa_dma_map(v, iova, int128_get64(llsize),
vaddr, section->readonly);
if (ret) {
@@ -221,6 +232,7 @@ static void vhost_vdpa_listener_region_del(MemoryListener *listener,
llsize = int128_sub(llend, int128_make64(iova));
+ vhost_vdpa_iotlb_batch_begin_once(v);
ret = vhost_vdpa_dma_unmap(v, iova, int128_get64(llsize));
if (ret) {
error_report("vhost_vdpa dma unmap error!");
@@ -234,7 +246,6 @@ static void vhost_vdpa_listener_region_del(MemoryListener *listener,
* depends on the addnop().
*/
static const MemoryListener vhost_vdpa_memory_listener = {
- .begin = vhost_vdpa_listener_begin,
.commit = vhost_vdpa_listener_commit,
.region_add = vhost_vdpa_listener_region_add,
.region_del = vhost_vdpa_listener_region_del,
@@ -432,13 +443,13 @@ static int vhost_vdpa_set_backend_cap(struct vhost_dev *dev)
int r;
if (vhost_vdpa_call(dev, VHOST_GET_BACKEND_FEATURES, &features)) {
- return 0;
+ return -EFAULT;
}
features &= f;
r = vhost_vdpa_call(dev, VHOST_SET_BACKEND_FEATURES, &features);
if (r) {
- return 0;
+ return -EFAULT;
}
dev->backend_cap = features;
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 3c0b537f89..b4b29413e6 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -174,6 +174,35 @@ static uint64_t vhost_get_log_size(struct vhost_dev *dev)
return log_size;
}
+static int vhost_set_backend_type(struct vhost_dev *dev,
+ VhostBackendType backend_type)
+{
+ int r = 0;
+
+ switch (backend_type) {
+#ifdef CONFIG_VHOST_KERNEL
+ case VHOST_BACKEND_TYPE_KERNEL:
+ dev->vhost_ops = &kernel_ops;
+ break;
+#endif
+#ifdef CONFIG_VHOST_USER
+ case VHOST_BACKEND_TYPE_USER:
+ dev->vhost_ops = &user_ops;
+ break;
+#endif
+#ifdef CONFIG_VHOST_VDPA
+ case VHOST_BACKEND_TYPE_VDPA:
+ dev->vhost_ops = &vdpa_ops;
+ break;
+#endif
+ default:
+ error_report("Unknown vhost backend type");
+ r = -1;
+ }
+
+ return r;
+}
+
static struct vhost_log *vhost_log_alloc(uint64_t size, bool share)
{
Error *err = NULL;
@@ -286,7 +315,7 @@ static int vhost_dev_has_iommu(struct vhost_dev *dev)
* does not have IOMMU, there's no need to enable this feature
* which may cause unnecessary IOTLB miss/update trnasactions.
*/
- return vdev->dma_as != &address_space_memory &&
+ return virtio_bus_device_iommu_enabled(vdev) &&
virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM);
}
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 4b5d9e5e50..5a69dce35d 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -30,6 +30,7 @@
#include "trace.h"
#include "qemu/error-report.h"
#include "migration/misc.h"
+#include "migration/migration.h"
#include "hw/virtio/virtio-bus.h"
#include "hw/virtio/virtio-access.h"
@@ -533,22 +534,18 @@ static bool get_free_page_hints(VirtIOBalloon *dev)
if (dev->free_page_hint_status == FREE_PAGE_HINT_S_REQUESTED &&
id == dev->free_page_hint_cmd_id) {
dev->free_page_hint_status = FREE_PAGE_HINT_S_START;
- } else {
+ } else if (dev->free_page_hint_status == FREE_PAGE_HINT_S_START) {
/*
* Stop the optimization only when it has started. This
* avoids a stale stop sign for the previous command.
*/
- if (dev->free_page_hint_status == FREE_PAGE_HINT_S_START) {
- dev->free_page_hint_status = FREE_PAGE_HINT_S_STOP;
- }
+ dev->free_page_hint_status = FREE_PAGE_HINT_S_STOP;
}
}
- if (elem->in_num) {
- if (dev->free_page_hint_status == FREE_PAGE_HINT_S_START) {
- qemu_guest_free_page_hint(elem->in_sg[0].iov_base,
- elem->in_sg[0].iov_len);
- }
+ if (elem->in_num && dev->free_page_hint_status == FREE_PAGE_HINT_S_START) {
+ qemu_guest_free_page_hint(elem->in_sg[0].iov_base,
+ elem->in_sg[0].iov_len);
}
out:
@@ -591,16 +588,10 @@ static void virtio_balloon_free_page_start(VirtIOBalloon *s)
{
VirtIODevice *vdev = VIRTIO_DEVICE(s);
- /* For the stop and copy phase, we don't need to start the optimization */
- if (!vdev->vm_running) {
- return;
- }
-
qemu_mutex_lock(&s->free_page_lock);
if (s->free_page_hint_cmd_id == UINT_MAX) {
- s->free_page_hint_cmd_id =
- VIRTIO_BALLOON_FREE_PAGE_HINT_CMD_ID_MIN;
+ s->free_page_hint_cmd_id = VIRTIO_BALLOON_FREE_PAGE_HINT_CMD_ID_MIN;
} else {
s->free_page_hint_cmd_id++;
}
@@ -648,8 +639,7 @@ static void virtio_balloon_free_page_done(VirtIOBalloon *s)
static int
virtio_balloon_free_page_hint_notify(NotifierWithReturn *n, void *data)
{
- VirtIOBalloon *dev = container_of(n, VirtIOBalloon,
- free_page_hint_notify);
+ VirtIOBalloon *dev = container_of(n, VirtIOBalloon, free_page_hint_notify);
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
PrecopyNotifyData *pnd = data;
@@ -662,6 +652,18 @@ virtio_balloon_free_page_hint_notify(NotifierWithReturn *n, void *data)
return 0;
}
+ /*
+ * Pages hinted via qemu_guest_free_page_hint() are cleared from the dirty
+ * bitmap and will not get migrated, especially also not when the postcopy
+ * destination starts using them and requests migration from the source; the
+ * faulting thread will stall until postcopy migration finishes and
+ * all threads are woken up. Let's not start free page hinting if postcopy
+ * is possible.
+ */
+ if (migrate_postcopy_ram()) {
+ return 0;
+ }
+
switch (pnd->reason) {
case PRECOPY_NOTIFY_BEFORE_BITMAP_SYNC:
virtio_balloon_free_page_stop(dev);
@@ -906,8 +908,7 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp)
s->dvq = virtio_add_queue(vdev, 128, virtio_balloon_handle_output);
s->svq = virtio_add_queue(vdev, 128, virtio_balloon_receive_stats);
- if (virtio_has_feature(s->host_features,
- VIRTIO_BALLOON_F_FREE_PAGE_HINT)) {
+ if (virtio_has_feature(s->host_features, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) {
s->free_page_vq = virtio_add_queue(vdev, VIRTQUEUE_MAX_SIZE,
virtio_balloon_handle_free_page_vq);
precopy_add_notifier(&s->free_page_hint_notify);
diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
index 859978d248..d23db98c56 100644
--- a/hw/virtio/virtio-bus.c
+++ b/hw/virtio/virtio-bus.c
@@ -325,6 +325,20 @@ static char *virtio_bus_get_fw_dev_path(DeviceState *dev)
return NULL;
}
+bool virtio_bus_device_iommu_enabled(VirtIODevice *vdev)
+{
+ DeviceState *qdev = DEVICE(vdev);
+ BusState *qbus = BUS(qdev_get_parent_bus(qdev));
+ VirtioBusState *bus = VIRTIO_BUS(qbus);
+ VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus);
+
+ if (!klass->iommu_enabled) {
+ return false;
+ }
+
+ return klass->iommu_enabled(qbus->parent);
+}
+
static void virtio_bus_class_init(ObjectClass *klass, void *data)
{
BusClass *bus_class = BUS_CLASS(klass);
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 433060ac02..6e16e2705c 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1121,6 +1121,19 @@ static AddressSpace *virtio_pci_get_dma_as(DeviceState *d)
return pci_get_address_space(dev);
}
+static bool virtio_pci_iommu_enabled(DeviceState *d)
+{
+ VirtIOPCIProxy *proxy = VIRTIO_PCI(d);
+ PCIDevice *dev = &proxy->pci_dev;
+ AddressSpace *dma_as = pci_device_iommu_address_space(dev);
+
+ if (dma_as == &address_space_memory) {
+ return false;
+ }
+
+ return true;
+}
+
static bool virtio_pci_queue_enabled(DeviceState *d, int n)
{
VirtIOPCIProxy *proxy = VIRTIO_PCI(d);
@@ -2202,6 +2215,7 @@ static void virtio_pci_bus_class_init(ObjectClass *klass, void *data)
k->ioeventfd_enabled = virtio_pci_ioeventfd_enabled;
k->ioeventfd_assign = virtio_pci_ioeventfd_assign;
k->get_dma_as = virtio_pci_get_dma_as;
+ k->iommu_enabled = virtio_pci_iommu_enabled;
k->queue_enabled = virtio_pci_queue_enabled;
}
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 874377f37a..3a1f6c520c 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -133,12 +133,10 @@ struct VirtQueue
QLIST_ENTRY(VirtQueue) node;
};
+/* Called within call_rcu(). */
static void virtio_free_region_cache(VRingMemoryRegionCaches *caches)
{
- if (!caches) {
- return;
- }
-
+ assert(caches != NULL);
address_space_cache_destroy(&caches->desc);
address_space_cache_destroy(&caches->avail);
address_space_cache_destroy(&caches->used);
@@ -634,6 +632,7 @@ static int virtio_queue_split_empty(VirtQueue *vq)
return empty;
}
+/* Called within rcu_read_lock(). */
static int virtio_queue_packed_empty_rcu(VirtQueue *vq)
{
struct VRingPackedDesc desc;
diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
index 9e8a76f2e2..cc0d370745 100644
--- a/include/hw/acpi/acpi.h
+++ b/include/hw/acpi/acpi.h
@@ -47,6 +47,8 @@
#define ACPI_PM_PROP_PM_IO_BASE "pm_io_base"
#define ACPI_PM_PROP_GPE0_BLK "gpe0_blk"
#define ACPI_PM_PROP_GPE0_BLK_LEN "gpe0_blk_len"
+#define ACPI_PM_PROP_ACPI_PCIHP_BRIDGE "acpi-pci-hotplug-with-bridge-support"
+#define ACPI_PM_PROP_ACPI_PCI_ROOTHP "acpi-root-pci-hotplug"
/* PM Timer ticks per second (HZ) */
#define PM_TIMER_FREQUENCY 3579545
diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h
index 6bed92e8fc..d49217c445 100644
--- a/include/hw/acpi/generic_event_device.h
+++ b/include/hw/acpi/generic_event_device.h
@@ -70,8 +70,6 @@
OBJECT_DECLARE_SIMPLE_TYPE(AcpiGedState, ACPI_GED)
#define TYPE_ACPI_GED_X86 "acpi-ged-x86"
-#define ACPI_GED_X86(obj) \
- OBJECT_CHECK(AcpiGedX86State, (obj), TYPE_ACPI_GED_X86)
#define ACPI_GED_EVT_SEL_OFFSET 0x0
#define ACPI_GED_EVT_SEL_LEN 0x4
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 97b4ab79b5..4d2e35a152 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -47,10 +47,6 @@ typedef struct PCMachineState {
bool default_bus_bypass_iommu;
uint64_t max_fw_size;
- /* NUMA information: */
- uint64_t numa_nodes;
- uint64_t *node_mem;
-
/* ACPI Memory hotplug IO base address */
hwaddr memhp_io_base;
} PCMachineState;
diff --git a/include/hw/pci-host/i440fx.h b/include/hw/pci-host/i440fx.h
index 7fcfd9485c..f068aaba8f 100644
--- a/include/hw/pci-host/i440fx.h
+++ b/include/hw/pci-host/i440fx.h
@@ -45,6 +45,5 @@ PCIBus *i440fx_init(const char *host_type, const char *pci_type,
MemoryRegion *pci_memory,
MemoryRegion *ram_memory);
-PCIBus *find_i440fx(void);
#endif
diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
index 8475c5a29d..81bf3109f8 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -173,12 +173,6 @@ typedef struct VhostOps {
vhost_force_iommu_op vhost_force_iommu;
} VhostOps;
-extern const VhostOps user_ops;
-extern const VhostOps vdpa_ops;
-
-int vhost_set_backend_type(struct vhost_dev *dev,
- VhostBackendType backend_type);
-
int vhost_backend_update_device_iotlb(struct vhost_dev *dev,
uint64_t iova, uint64_t uaddr,
uint64_t len,
diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
index 9188226d8b..a8963da2d9 100644
--- a/include/hw/virtio/vhost-vdpa.h
+++ b/include/hw/virtio/vhost-vdpa.h
@@ -22,6 +22,7 @@ typedef struct VhostVDPAHostNotifier {
typedef struct vhost_vdpa {
int device_fd;
uint32_t msg_type;
+ bool iotlb_batch_begin_sent;
MemoryListener listener;
struct vhost_dev *dev;
VhostVDPAHostNotifier notifier[VIRTIO_QUEUE_MAX];
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index 045d0fd9f2..1a9fc65089 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -71,7 +71,7 @@ struct vhost_dev {
int n_tmp_sections;
MemoryRegionSection *tmp_sections;
struct vhost_virtqueue *vqs;
- int nvqs;
+ unsigned int nvqs;
/* the first virtqueue which would be used by this vhost dev */
int vq_index;
/* if non-zero, minimum required value for max_queues */
@@ -95,6 +95,10 @@ struct vhost_dev {
const VhostDevConfigOps *config_ops;
};
+extern const VhostOps kernel_ops;
+extern const VhostOps user_ops;
+extern const VhostOps vdpa_ops;
+
struct vhost_net {
struct vhost_dev dev;
struct vhost_virtqueue vqs[2];
diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
index ef8abe49c5..7ab8c9dab0 100644
--- a/include/hw/virtio/virtio-bus.h
+++ b/include/hw/virtio/virtio-bus.h
@@ -93,6 +93,7 @@ struct VirtioBusClass {
*/
bool has_variable_vring_alignment;
AddressSpace *(*get_dma_as)(DeviceState *d);
+ bool (*iommu_enabled)(DeviceState *d);
};
struct VirtioBusState {
@@ -154,5 +155,6 @@ void virtio_bus_release_ioeventfd(VirtioBusState *bus);
int virtio_bus_set_host_notifier(VirtioBusState *bus, int n, bool assign);
/* Tell the bus that the ioeventfd handler is no longer required. */
void virtio_bus_cleanup_host_notifier(VirtioBusState *bus, int n);
-
+/* Whether the IOMMU is enabled for this device */
+bool virtio_bus_device_iommu_enabled(VirtIODevice *vdev);
#endif /* VIRTIO_BUS_H */
diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
index 172b0051d8..fba40cf695 100644
--- a/include/net/vhost_net.h
+++ b/include/net/vhost_net.h
@@ -14,6 +14,7 @@ typedef struct VhostNetOptions {
VhostBackendType backend_type;
NetClientState *net_backend;
uint32_t busyloop_timeout;
+ unsigned int nvqs;
void *opaque;
} VhostNetOptions;
diff --git a/net/tap.c b/net/tap.c
index f5686bbf77..f716be3e3f 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -749,6 +749,7 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
qemu_set_nonblock(vhostfd);
}
options.opaque = (void *)(uintptr_t)vhostfd;
+ options.nvqs = 2;
s->vhost_net = vhost_net_init(&options);
if (!s->vhost_net) {
diff --git a/net/vhost-user.c b/net/vhost-user.c
index 6adfcd623a..4a939124d2 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -85,6 +85,7 @@ static int vhost_user_start(int queues, NetClientState *ncs[],
options.net_backend = ncs[i];
options.opaque = be;
options.busyloop_timeout = 0;
+ options.nvqs = 2;
net = vhost_net_init(&options);
if (!net) {
error_report("failed to init vhost_net for queue %d", i);
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 19187dce8c..912686457c 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -29,7 +29,6 @@ typedef struct VhostVDPAState {
NetClientState nc;
struct vhost_vdpa vhost_vdpa;
VHostNetState *vhost_net;
- uint64_t acked_features;
bool started;
} VhostVDPAState;
@@ -82,16 +81,6 @@ static int vhost_vdpa_net_check_device_id(struct vhost_net *net)
return ret;
}
-static void vhost_vdpa_del(NetClientState *ncs)
-{
- VhostVDPAState *s;
- assert(ncs->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
- s = DO_UPCAST(VhostVDPAState, nc, ncs);
- if (s->vhost_net) {
- vhost_net_cleanup(s->vhost_net);
- }
-}
-
static int vhost_vdpa_add(NetClientState *ncs, void *be)
{
VhostNetOptions options;
@@ -105,27 +94,23 @@ static int vhost_vdpa_add(NetClientState *ncs, void *be)
options.net_backend = ncs;
options.opaque = be;
options.busyloop_timeout = 0;
+ options.nvqs = 2;
net = vhost_net_init(&options);
if (!net) {
error_report("failed to init vhost_net for queue");
- goto err;
- }
- if (s->vhost_net) {
- vhost_net_cleanup(s->vhost_net);
- g_free(s->vhost_net);
+ goto err_init;
}
s->vhost_net = net;
ret = vhost_vdpa_net_check_device_id(net);
if (ret) {
- goto err;
+ goto err_check;
}
return 0;
-err:
- if (net) {
- vhost_net_cleanup(net);
- }
- vhost_vdpa_del(ncs);
+err_check:
+ vhost_net_cleanup(net);
+ g_free(net);
+err_init:
return -1;
}
@@ -180,7 +165,6 @@ static int net_vhost_vdpa_init(NetClientState *peer, const char *device,
assert(name);
nc = qemu_new_net_client(&net_vhost_vdpa_info, peer, device, name);
snprintf(nc->info_str, sizeof(nc->info_str), TYPE_VHOST_VDPA);
- nc->queue_index = 0;
s = DO_UPCAST(VhostVDPAState, nc, nc);
vdpa_device_fd = qemu_open_old(vhostdev, O_RDWR);
if (vdpa_device_fd == -1) {
@@ -188,7 +172,10 @@ static int net_vhost_vdpa_init(NetClientState *peer, const char *device,
}
s->vhost_vdpa.device_fd = vdpa_device_fd;
ret = vhost_vdpa_add(nc, (void *)&s->vhost_vdpa);
- assert(s->vhost_net);
+ if (ret) {
+ qemu_close(vdpa_device_fd);
+ qemu_del_net_client(nc);
+ }
return ret;
}
diff --git a/stubs/meson.build b/stubs/meson.build
index 275ac89c16..beee31ec73 100644
--- a/stubs/meson.build
+++ b/stubs/meson.build
@@ -26,7 +26,6 @@ stub_ss.add(files('module-opts.c'))
stub_ss.add(files('monitor.c'))
stub_ss.add(files('monitor-core.c'))
stub_ss.add(files('pci-bus.c'))
-stub_ss.add(files('pci-host-piix.c'))
stub_ss.add(files('qemu-timer-notify-cb.c'))
stub_ss.add(files('qmp_memory_device.c'))
stub_ss.add(files('qmp-command-available.c'))
diff --git a/stubs/pci-host-piix.c b/stubs/pci-host-piix.c
deleted file mode 100644
index 93975adbfe..0000000000
--- a/stubs/pci-host-piix.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#include "qemu/osdep.h"
-#include "hw/pci-host/i440fx.h"
-
-PCIBus *find_i440fx(void)
-{
- return NULL;
-}
diff --git a/tests/vhost-user-bridge.c b/tests/vhost-user-bridge.c
index 24815920b2..35088dd67f 100644
--- a/tests/vhost-user-bridge.c
+++ b/tests/vhost-user-bridge.c
@@ -540,6 +540,11 @@ vubr_new(const char *path, bool client)
CallbackFunc cb;
size_t len;
+ if (strlen(path) >= sizeof(un.sun_path)) {
+ fprintf(stderr, "unix domain socket path '%s' is too long\n", path);
+ exit(1);
+ }
+
/* Get a UNIX socket. */
dev->sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (dev->sock == -1) {
@@ -826,7 +831,7 @@ main(int argc, char *argv[])
out:
fprintf(stderr, "Usage: %s ", argv[0]);
fprintf(stderr, "[-c] [-H] [-u ud_socket_path] [-l lhost:lport] [-r rhost:rport]\n");
- fprintf(stderr, "\t-u path to unix doman socket. default: %s\n",
+ fprintf(stderr, "\t-u path to unix domain socket. default: %s\n",
DEFAULT_UD_SOCKET);
fprintf(stderr, "\t-l local host and port. default: %s:%s\n",
DEFAULT_LHOST, DEFAULT_LPORT);