Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging

virtio,pci,pc: features, fixes, tests

SPCR acpi table can now be disabled
vhost-vdpa can now report hashing capability to guest
PPTT acpi table now tells guest vCPUs are identical
vost-user-blk now shuts down faster
loongarch64 now supports bios-tables-test
intel_iommu now supports ATS
cxl now supports DCD Fabric Management Command Set
arm now supports acpi pci hotplug

fixes, cleanups

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

 # -----BEGIN PGP SIGNATURE-----
 #
 # iQFDBAABCgAtFiEEXQn9CHHI+FuUyooNKB8NuNKNVGkFAmh1+7APHG1zdEByZWRo
 # YXQuY29tAAoJECgfDbjSjVRpcZ8H/2udpCZ49vjPB8IwQAGdFTw2TWVdxUQFHexQ
 # pOsCGyFBNAXqD1bmb8lwWyYVJ08WELyL6xWsQ5tfVPiXpKYYHPHl4rNr/SPoyNcv
 # joY++tagudmOki2DU7nfJ+rPIIuigOTUHbv4TZciwcHle6f65s0iKXhR1sL0cj4i
 # TS6iJlApSuJInrBBUxuxSUomXk79mFTNKRiXj1k58LRw6JOUEgYvtIW8i+mOUcTg
 # h1dZphxEQr/oG+a2pM8GOVJ1AFaBPSfgEnRM4kTX9QuTIDCeMAKUBo/mwOk6PV7z
 # ZhSrDPLrea27XKGL++EJm0fFJ/AsHF1dTks2+c0rDrSK+UV87Zc=
 # =sktm
 # -----END PGP SIGNATURE-----
 # gpg: Signature made Tue 15 Jul 2025 02:56:48 EDT
 # gpg:                using RSA key 5D09FD0871C8F85B94CA8A0D281F0DB8D28D5469
 # gpg:                issuer "mst@redhat.com"
 # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" [full]
 # gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>" [full]
 # Primary key fingerprint: 0270 606B 6F3C DF3D 0B17  0970 C350 3912 AFBE 8E67
 #      Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA  8A0D 281F 0DB8 D28D 5469

* tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu: (97 commits)
  hw/cxl: mailbox-utils: 0x5605 - FMAPI Initiate DC Release
  hw/cxl: mailbox-utils: 0x5604 - FMAPI Initiate DC Add
  hw/cxl: Create helper function to create DC Event Records from extents
  hw/cxl: mailbox-utils: 0x5603 - FMAPI Get DC Region Extent Lists
  hw/cxl: mailbox-utils: 0x5602 - FMAPI Set DC Region Config
  hw/mem: cxl_type3: Add DC Region bitmap lock
  hw/cxl: Move definition for dynamic_capacity_uuid and enum for DC event types to header
  hw/cxl: mailbox-utils: 0x5601 - FMAPI Get Host Region Config
  hw/mem: cxl_type3: Add dsmas_flags to CXLDCRegion struct
  hw/cxl: mailbox-utils: 0x5600 - FMAPI Get DCD Info
  hw/cxl: fix DC extent capacity tracking
  tests: virt: Update expected ACPI tables for virt test
  hw/acpi/aml-build: Build a root node in the PPTT table
  hw/acpi/aml-build: Set identical implementation flag for PPTT processor nodes
  tests: virt: Allow changes to PPTT test table
  qtest/bios-tables-test: Generate reference blob for DSDT.acpipcihp
  qtest/bios-tables-test: Generate reference blob for DSDT.hpoffacpiindex
  tests/qtest/bios-tables-test: Add aarch64 ACPI PCI hotplug test
  tests/qtest/bios-tables-test: Prepare for addition of acpi pci hp tests
  hw/arm/virt: Let virt support pci hotplug/unplug GED event
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>

Conflicts:
  net/vhost-vdpa.c
  vhost_vdpa_set_steering_ebpf() was removed, resolve the context
  conflict.
This commit is contained in:
Stefan Hajnoczi
2025-07-16 07:00:47 -04:00
139 changed files with 2460 additions and 1034 deletions
-7
View File
@@ -22,7 +22,6 @@
#include "system/accel-ops.h"
#include "system/cpus.h"
#include "exec/cpu-common.h"
#include "exec/tswap.h"
#include "exec/replay-core.h"
#include "exec/log.h"
#include "hw/core/cpu.h"
@@ -85,9 +84,3 @@ void cpu_abort(CPUState *cpu, const char *fmt, ...)
#endif
abort();
}
#undef target_big_endian
bool target_big_endian(void)
{
return TARGET_BIG_ENDIAN;
}
+1 -1
View File
@@ -4,7 +4,7 @@
const VMStateDescription vmstate_acpi_pcihp_pci_status;
void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, PCIBus *root_bus,
void acpi_pcihp_init(Object *owner, AcpiPciHpState *s,
MemoryRegion *address_space_io, uint16_t io_base)
{
}
+21 -6
View File
@@ -160,7 +160,7 @@ void crs_replace_with_free_ranges(GPtrArray *ranges,
*/
static void crs_range_merge(GPtrArray *range)
{
GPtrArray *tmp = g_ptr_array_new_with_free_func(crs_range_free);
g_autoptr(GPtrArray) tmp = g_ptr_array_new_with_free_func(crs_range_free);
CrsRangeEntry *entry;
uint64_t range_base, range_limit;
int i;
@@ -191,7 +191,6 @@ static void crs_range_merge(GPtrArray *range)
entry = g_ptr_array_index(tmp, i);
crs_range_insert(range, entry->base, entry->limit);
}
g_ptr_array_free(tmp, true);
}
static void
@@ -2153,12 +2152,25 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
int64_t socket_id = -1, cluster_id = -1, core_id = -1;
uint32_t socket_offset = 0, cluster_offset = 0, core_offset = 0;
uint32_t pptt_start = table_data->len;
uint32_t root_offset;
int n;
AcpiTable table = { .sig = "PPTT", .rev = 2,
.oem_id = oem_id, .oem_table_id = oem_table_id };
acpi_table_begin(&table, table_data);
/*
* Build a root node for all the processor nodes. Otherwise when
* building a multi-socket system each socket tree is separated
* and will be hard for the OS like Linux to know whether the
* system is homogeneous.
*/
root_offset = table_data->len - pptt_start;
build_processor_hierarchy_node(table_data,
(1 << 0) | /* Physical package */
(1 << 4), /* Identical Implementation */
0, 0, NULL, 0);
/*
* This works with the assumption that cpus[n].props.*_id has been
* sorted from top to down levels in mc->possible_cpu_arch_ids().
@@ -2173,8 +2185,9 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
core_id = -1;
socket_offset = table_data->len - pptt_start;
build_processor_hierarchy_node(table_data,
(1 << 0), /* Physical package */
0, socket_id, NULL, 0);
(1 << 0) | /* Physical package */
(1 << 4), /* Identical Implementation */
root_offset, socket_id, NULL, 0);
}
if (mc->smp_props.clusters_supported && mc->smp_props.has_clusters) {
@@ -2184,7 +2197,8 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
core_id = -1;
cluster_offset = table_data->len - pptt_start;
build_processor_hierarchy_node(table_data,
(0 << 0), /* Not a physical package */
(0 << 0) | /* Not a physical package */
(1 << 4), /* Identical Implementation */
socket_offset, cluster_id, NULL, 0);
}
} else {
@@ -2202,7 +2216,8 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
core_id = cpus->cpus[n].props.core_id;
core_offset = table_data->len - pptt_start;
build_processor_hierarchy_node(table_data,
(0 << 0), /* Not a physical package */
(0 << 0) | /* Not a physical package */
(1 << 4), /* Identical Implementation */
cluster_offset, core_id, NULL, 0);
}
-2
View File
@@ -22,8 +22,6 @@
#include "hw/acpi/bios-linker-loader.h"
#include "hw/nvram/fw_cfg.h"
#include "qemu/bswap.h"
/*
* Linker/loader is a paravirtualized interface that passes commands to guest.
* The commands can be used to request guest to
+77
View File
@@ -12,10 +12,13 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/acpi/acpi.h"
#include "hw/acpi/pcihp.h"
#include "hw/acpi/generic_event_device.h"
#include "hw/pci/pci.h"
#include "hw/irq.h"
#include "hw/mem/pc-dimm.h"
#include "hw/mem/nvdimm.h"
#include "hw/pci/pci_device.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "qemu/error-report.h"
@@ -26,6 +29,7 @@ static const uint32_t ged_supported_events[] = {
ACPI_GED_PWR_DOWN_EVT,
ACPI_GED_NVDIMM_HOTPLUG_EVT,
ACPI_GED_CPU_HOTPLUG_EVT,
ACPI_GED_PCI_HOTPLUG_EVT,
};
/*
@@ -121,6 +125,12 @@ void build_ged_aml(Aml *table, const char *name, HotplugHandler *hotplug_dev,
aml_notify(aml_name("\\_SB.NVDR"),
aml_int(0x80)));
break;
case ACPI_GED_PCI_HOTPLUG_EVT:
aml_append(if_ctx,
aml_acquire(aml_name("\\_SB.PCI0.BLCK"), 0xFFFF));
aml_append(if_ctx, aml_call0("\\_SB.PCI0.PCNT"));
aml_append(if_ctx, aml_release(aml_name("\\_SB.PCI0.BLCK")));
break;
default:
/*
* Please make sure all the events in ged_supported_events[]
@@ -227,6 +237,14 @@ static const MemoryRegionOps ged_regs_ops = {
},
};
static void acpi_ged_device_pre_plug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
acpi_pcihp_device_pre_plug_cb(hotplug_dev, dev, errp);
}
}
static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
@@ -240,6 +258,8 @@ static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev,
}
} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
acpi_cpu_plug_cb(hotplug_dev, &s->cpuhp_state, dev, errp);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
acpi_pcihp_device_plug_cb(hotplug_dev, &s->pcihp_state, dev, errp);
} else {
error_setg(errp, "virt: device plug request for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -256,6 +276,9 @@ static void acpi_ged_unplug_request_cb(HotplugHandler *hotplug_dev,
acpi_memory_unplug_request_cb(hotplug_dev, &s->memhp_state, dev, errp);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
acpi_cpu_unplug_request_cb(hotplug_dev, &s->cpuhp_state, dev, errp);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
acpi_pcihp_device_unplug_request_cb(hotplug_dev, &s->pcihp_state,
dev, errp);
} else {
error_setg(errp, "acpi: device unplug request for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -271,6 +294,8 @@ static void acpi_ged_unplug_cb(HotplugHandler *hotplug_dev,
acpi_memory_unplug_cb(&s->memhp_state, dev, errp);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
acpi_cpu_unplug_cb(&s->cpuhp_state, dev, errp);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
acpi_pcihp_device_unplug_cb(hotplug_dev, &s->pcihp_state, dev, errp);
} else {
error_setg(errp, "acpi: device unplug for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -299,6 +324,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
sel = ACPI_GED_NVDIMM_HOTPLUG_EVT;
} else if (ev & ACPI_CPU_HOTPLUG_STATUS) {
sel = ACPI_GED_CPU_HOTPLUG_EVT;
} else if (ev & ACPI_PCI_HOTPLUG_STATUS) {
sel = ACPI_GED_PCI_HOTPLUG_EVT;
} else {
/* Unknown event. Return without generating interrupt. */
warn_report("GED: Unsupported event %d. No irq injected", ev);
@@ -318,6 +345,10 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
static const Property acpi_ged_properties[] = {
DEFINE_PROP_UINT32("ged-event", AcpiGedState, ged_event_bitmap, 0),
DEFINE_PROP_BOOL(ACPI_PM_PROP_ACPI_PCIHP_BRIDGE, AcpiGedState,
pcihp_state.use_acpi_hotplug_bridge, 0),
DEFINE_PROP_LINK("bus", AcpiGedState, pcihp_state.root,
TYPE_PCI_BUS, PCIBus *),
};
static const VMStateDescription vmstate_memhp_state = {
@@ -386,6 +417,25 @@ static const VMStateDescription vmstate_ghes_state = {
}
};
static bool pcihp_needed(void *opaque)
{
AcpiGedState *s = opaque;
return s->pcihp_state.use_acpi_hotplug_bridge;
}
static const VMStateDescription vmstate_pcihp_state = {
.name = "acpi-ged/pcihp",
.version_id = 1,
.minimum_version_id = 1,
.needed = pcihp_needed,
.fields = (const VMStateField[]) {
VMSTATE_PCI_HOTPLUG(pcihp_state,
AcpiGedState,
NULL, NULL),
VMSTATE_END_OF_LIST()
}
};
static const VMStateDescription vmstate_acpi_ged = {
.name = "acpi-ged",
.version_id = 1,
@@ -398,6 +448,7 @@ static const VMStateDescription vmstate_acpi_ged = {
&vmstate_memhp_state,
&vmstate_cpuhp_state,
&vmstate_ghes_state,
&vmstate_pcihp_state,
NULL
}
};
@@ -406,9 +457,13 @@ static void acpi_ged_realize(DeviceState *dev, Error **errp)
{
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
AcpiGedState *s = ACPI_GED(dev);
AcpiPciHpState *pcihp_state = &s->pcihp_state;
uint32_t ged_events;
int i;
if (pcihp_state->use_acpi_hotplug_bridge) {
s->ged_event_bitmap |= ACPI_GED_PCI_HOTPLUG_EVT;
}
ged_events = ctpop32(s->ged_event_bitmap);
for (i = 0; i < ARRAY_SIZE(ged_supported_events) && ged_events; i++) {
@@ -428,6 +483,13 @@ static void acpi_ged_realize(DeviceState *dev, Error **errp)
cpu_hotplug_hw_init(&s->container_cpuhp, OBJECT(dev),
&s->cpuhp_state, 0);
break;
case ACPI_GED_PCI_HOTPLUG_EVT:
memory_region_init(&s->container_pcihp, OBJECT(dev),
ACPI_PCIHP_REGION_NAME, ACPI_PCIHP_SIZE);
sysbus_init_mmio(sbd, &s->container_pcihp);
acpi_pcihp_init(OBJECT(s), &s->pcihp_state,
&s->container_pcihp, 0);
qbus_set_hotplug_handler(BUS(s->pcihp_state.root), OBJECT(dev));
}
ged_events--;
}
@@ -469,20 +531,34 @@ static void acpi_ged_initfn(Object *obj)
sysbus_init_mmio(sbd, &ged_st->regs);
}
static void ged_reset_hold(Object *obj, ResetType type)
{
AcpiGedState *s = ACPI_GED(obj);
if (s->pcihp_state.use_acpi_hotplug_bridge) {
acpi_pcihp_reset(&s->pcihp_state);
}
}
static void acpi_ged_class_init(ObjectClass *class, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(class);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(class);
AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_CLASS(class);
ResettableClass *rc = RESETTABLE_CLASS(class);
AcpiGedClass *gedc = ACPI_GED_CLASS(class);
dc->desc = "ACPI Generic Event Device";
device_class_set_props(dc, acpi_ged_properties);
dc->vmsd = &vmstate_acpi_ged;
dc->realize = acpi_ged_realize;
hc->pre_plug = acpi_ged_device_pre_plug_cb;
hc->plug = acpi_ged_device_plug_cb;
hc->unplug_request = acpi_ged_unplug_request_cb;
hc->unplug = acpi_ged_unplug_cb;
resettable_class_set_parent_phases(rc, NULL, ged_reset_hold, NULL,
&gedc->parent_phases);
adevc->ospm_status = acpi_ged_ospm_status;
adevc->send_event = acpi_ged_send_event;
@@ -494,6 +570,7 @@ static const TypeInfo acpi_ged_info = {
.instance_size = sizeof(AcpiGedState),
.instance_init = acpi_ged_initfn,
.class_init = acpi_ged_class_init,
.class_size = sizeof(AcpiGedClass),
.interfaces = (const InterfaceInfo[]) {
{ TYPE_HOTPLUG_HANDLER },
{ TYPE_ACPI_DEVICE_IF },
+6 -1
View File
@@ -322,9 +322,10 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, qemu_irq sci_irq)
}
if (pm->acpi_pci_hotplug.use_acpi_hotplug_bridge) {
object_property_set_link(OBJECT(lpc_pci), "bus",
OBJECT(pci_get_bus(lpc_pci)), &error_abort);
acpi_pcihp_init(OBJECT(lpc_pci),
&pm->acpi_pci_hotplug,
pci_get_bus(lpc_pci),
pci_address_space_io(lpc_pci),
ACPI_PCIHP_ADDR_ICH9);
@@ -428,6 +429,10 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE,
&pm->pm_io_base, OBJ_PROP_FLAG_READ);
object_property_add_link(obj, "bus", TYPE_PCI_BUS,
(Object **)&pm->acpi_pci_hotplug.root,
object_property_allow_set_link,
OBJ_PROP_LINK_STRONG);
object_property_add(obj, ACPI_PM_PROP_GPE0_BLK, "uint32",
ich9_pm_get_gpe0_blk,
NULL, NULL, pm);
+54
View File
@@ -35,3 +35,57 @@ void build_pci_bridge_aml(AcpiDevAmlIf *adev, Aml *scope)
}
}
}
Aml *build_pci_bridge_edsm(void)
{
Aml *method, *ifctx;
Aml *zero = aml_int(0);
Aml *func = aml_arg(2);
Aml *ret = aml_local(0);
Aml *aidx = aml_local(1);
Aml *params = aml_arg(4);
method = aml_method("EDSM", 5, AML_SERIALIZED);
/* get supported functions */
ifctx = aml_if(aml_equal(func, zero));
{
/* 1: have supported functions */
/* 7: support for function 7 */
const uint8_t caps = 1 | BIT(7);
build_append_pci_dsm_func0_common(ifctx, ret);
aml_append(ifctx, aml_store(aml_int(caps), aml_index(ret, zero)));
aml_append(ifctx, aml_return(ret));
}
aml_append(method, ifctx);
/* handle specific functions requests */
/*
* PCI Firmware Specification 3.1
* 4.6.7. _DSM for Naming a PCI or PCI Express Device Under
* Operating Systems
*/
ifctx = aml_if(aml_equal(func, aml_int(7)));
{
Aml *pkg = aml_package(2);
aml_append(pkg, zero);
/* optional, if not impl. should return null string */
aml_append(pkg, aml_string("%s", ""));
aml_append(ifctx, aml_store(pkg, ret));
/*
* IASL is fine when initializing Package with computational data,
* however it makes guest unhappy /it fails to process such AML/.
* So use runtime assignment to set acpi-index after initializer
* to make OSPM happy.
*/
aml_append(ifctx,
aml_store(aml_derefof(aml_index(params, aml_int(0))), aidx));
aml_append(ifctx, aml_store(aidx, aml_index(ret, zero)));
aml_append(ifctx, aml_return(ret));
}
aml_append(method, ifctx);
return method;
}
+50
View File
@@ -301,3 +301,53 @@ void build_srat_generic_affinity_structures(GArray *table_data)
object_child_foreach_recursive(object_get_root(), build_acpi_generic_port,
table_data);
}
Aml *build_pci_host_bridge_osc_method(bool enable_native_pcie_hotplug)
{
Aml *if_ctx;
Aml *if_ctx2;
Aml *else_ctx;
Aml *method;
Aml *a_cwd1 = aml_name("CDW1");
Aml *a_ctrl = aml_local(0);
method = aml_method("_OSC", 4, AML_NOTSERIALIZED);
aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1"));
if_ctx = aml_if(aml_equal(
aml_arg(0), aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766")));
aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2"));
aml_append(if_ctx, aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
aml_append(if_ctx, aml_store(aml_name("CDW3"), a_ctrl));
/*
* Always allow native PME, AER (no dependencies)
* Allow SHPC (PCI bridges can have SHPC controller)
* Disable PCIe Native Hot-plug if ACPI PCI Hot-plug is enabled.
*/
aml_append(if_ctx, aml_and(a_ctrl,
aml_int(0x1E | (enable_native_pcie_hotplug ? 0x1 : 0x0)), a_ctrl));
if_ctx2 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1))));
/* Unknown revision */
aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x08), a_cwd1));
aml_append(if_ctx, if_ctx2);
if_ctx2 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), a_ctrl)));
/* Capabilities bits were masked */
aml_append(if_ctx2, aml_or(a_cwd1, aml_int(0x10), a_cwd1));
aml_append(if_ctx, if_ctx2);
/* Update DWORD3 in the buffer */
aml_append(if_ctx, aml_store(a_ctrl, aml_name("CDW3")));
aml_append(method, if_ctx);
else_ctx = aml_else();
/* Unrecognized UUID */
aml_append(else_ctx, aml_or(a_cwd1, aml_int(4), a_cwd1));
aml_append(method, else_ctx);
aml_append(method, aml_return(aml_arg(3)));
return method;
}
+428 -11
View File
@@ -26,7 +26,8 @@
#include "qemu/osdep.h"
#include "hw/acpi/pcihp.h"
#include "hw/acpi/aml-build.h"
#include "hw/acpi/acpi_aml_interface.h"
#include "hw/pci-host/i440fx.h"
#include "hw/pci/pci.h"
#include "hw/pci/pci_bridge.h"
@@ -39,9 +40,9 @@
#include "migration/vmstate.h"
#include "qapi/error.h"
#include "qom/qom-qobject.h"
#include "qobject/qnum.h"
#include "trace.h"
#define ACPI_PCIHP_SIZE 0x0018
#define PCI_UP_BASE 0x0000
#define PCI_DOWN_BASE 0x0004
#define PCI_EJ_BASE 0x0008
@@ -97,10 +98,10 @@ static void *acpi_set_bsel(PCIBus *bus, void *opaque)
return info;
}
static void acpi_set_pci_info(bool has_bridge_hotplug)
static void acpi_set_pci_info(AcpiPciHpState *s)
{
static bool bsel_is_set;
Object *host = acpi_get_i386_pci_host();
bool has_bridge_hotplug = s->use_acpi_hotplug_bridge;
PCIBus *bus;
BSELInfo info = { .bsel_alloc = ACPI_PCIHP_BSEL_DEFAULT,
.has_bridge_hotplug = has_bridge_hotplug };
@@ -110,11 +111,8 @@ static void acpi_set_pci_info(bool has_bridge_hotplug)
}
bsel_is_set = true;
if (!host) {
return;
}
bus = PCI_HOST_BRIDGE(host)->bus;
bus = s->root;
if (bus) {
/* Scan all PCI buses. Set property to enable acpi based hotplug. */
pci_for_each_bus_depth_first(bus, acpi_set_bsel, NULL, &info);
@@ -264,7 +262,7 @@ static void acpi_pcihp_update(AcpiPciHpState *s)
void acpi_pcihp_reset(AcpiPciHpState *s)
{
acpi_set_pci_info(s->use_acpi_hotplug_bridge);
acpi_set_pci_info(s);
acpi_pcihp_update(s);
}
@@ -495,13 +493,13 @@ static const MemoryRegionOps acpi_pcihp_io_ops = {
},
};
void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, PCIBus *root_bus,
void acpi_pcihp_init(Object *owner, AcpiPciHpState *s,
MemoryRegion *io, uint16_t io_base)
{
s->io_len = ACPI_PCIHP_SIZE;
s->io_base = io_base;
s->root = root_bus;
assert(s->root);
memory_region_init_io(&s->io, owner, &acpi_pcihp_io_ops, s,
"acpi-pci-hotplug", s->io_len);
@@ -513,6 +511,425 @@ void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, PCIBus *root_bus,
OBJ_PROP_FLAG_READ);
}
void build_append_pci_dsm_func0_common(Aml *ctx, Aml *retvar)
{
Aml *UUID, *ifctx1;
uint8_t byte_list[1] = { 0 }; /* nothing supported yet */
aml_append(ctx, aml_store(aml_buffer(1, byte_list), retvar));
/*
* PCI Firmware Specification 3.1
* 4.6. _DSM Definitions for PCI
*/
UUID = aml_touuid("E5C937D0-3553-4D7A-9117-EA4D19C3434D");
ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(0), UUID)));
{
/* call is for unsupported UUID, bail out */
aml_append(ifctx1, aml_return(retvar));
}
aml_append(ctx, ifctx1);
ifctx1 = aml_if(aml_lless(aml_arg(1), aml_int(2)));
{
/* call is for unsupported REV, bail out */
aml_append(ifctx1, aml_return(retvar));
}
aml_append(ctx, ifctx1);
}
static Aml *aml_pci_pdsm(void)
{
Aml *method, *ifctx, *ifctx1;
Aml *ret = aml_local(0);
Aml *caps = aml_local(1);
Aml *acpi_index = aml_local(2);
Aml *zero = aml_int(0);
Aml *one = aml_int(1);
Aml *not_supp = aml_int(0xFFFFFFFF);
Aml *func = aml_arg(2);
Aml *params = aml_arg(4);
Aml *bnum = aml_derefof(aml_index(params, aml_int(0)));
Aml *sunum = aml_derefof(aml_index(params, aml_int(1)));
method = aml_method("PDSM", 5, AML_SERIALIZED);
/* get supported functions */
ifctx = aml_if(aml_equal(func, zero));
{
build_append_pci_dsm_func0_common(ifctx, ret);
aml_append(ifctx, aml_store(zero, caps));
aml_append(ifctx,
aml_store(aml_call2("AIDX", bnum, sunum), acpi_index));
/*
* advertise function 7 if device has acpi-index
* acpi_index values:
* 0: not present (default value)
* FFFFFFFF: not supported (old QEMU without PIDX reg)
* other: device's acpi-index
*/
ifctx1 = aml_if(aml_lnot(
aml_or(aml_equal(acpi_index, zero),
aml_equal(acpi_index, not_supp), NULL)
));
{
/* have supported functions */
aml_append(ifctx1, aml_or(caps, one, caps));
/* support for function 7 */
aml_append(ifctx1,
aml_or(caps, aml_shiftleft(one, aml_int(7)), caps));
}
aml_append(ifctx, ifctx1);
aml_append(ifctx, aml_store(caps, aml_index(ret, zero)));
aml_append(ifctx, aml_return(ret));
}
aml_append(method, ifctx);
/* handle specific functions requests */
/*
* PCI Firmware Specification 3.1
* 4.6.7. _DSM for Naming a PCI or PCI Express Device Under
* Operating Systems
*/
ifctx = aml_if(aml_equal(func, aml_int(7)));
{
Aml *pkg = aml_package(2);
aml_append(ifctx, aml_store(aml_call2("AIDX", bnum, sunum), acpi_index));
aml_append(ifctx, aml_store(pkg, ret));
/*
* Windows calls func=7 without checking if it's available,
* as workaround Microsoft has suggested to return invalid for func7
* Package, so return 2 elements package but only initialize elements
* when acpi_index is supported and leave them uninitialized, which
* leads elements to being Uninitialized ObjectType and should trip
* Windows into discarding result as an unexpected and prevent setting
* bogus 'PCI Label' on the device.
*/
ifctx1 = aml_if(aml_lnot(aml_lor(
aml_equal(acpi_index, zero), aml_equal(acpi_index, not_supp)
)));
{
aml_append(ifctx1, aml_store(acpi_index, aml_index(ret, zero)));
/*
* optional, if not impl. should return null string
*/
aml_append(ifctx1, aml_store(aml_string("%s", ""),
aml_index(ret, one)));
}
aml_append(ifctx, ifctx1);
aml_append(ifctx, aml_return(ret));
}
aml_append(method, ifctx);
return method;
}
void build_acpi_pci_hotplug(Aml *table, AmlRegionSpace rs, uint64_t pcihp_addr)
{
Aml *scope;
Aml *field;
Aml *method;
scope = aml_scope("_SB.PCI0");
aml_append(scope,
aml_operation_region("PCST", rs, aml_int(pcihp_addr), 0x08));
field = aml_field("PCST", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
aml_append(field, aml_named_field("PCIU", 32));
aml_append(field, aml_named_field("PCID", 32));
aml_append(scope, field);
aml_append(scope,
aml_operation_region("SEJ", rs,
aml_int(pcihp_addr + ACPI_PCIHP_SEJ_BASE), 0x04));
field = aml_field("SEJ", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
aml_append(field, aml_named_field("B0EJ", 32));
aml_append(scope, field);
aml_append(scope,
aml_operation_region("BNMR", rs,
aml_int(pcihp_addr + ACPI_PCIHP_BNMR_BASE), 0x08));
field = aml_field("BNMR", AML_DWORD_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS);
aml_append(field, aml_named_field("BNUM", 32));
aml_append(field, aml_named_field("PIDX", 32));
aml_append(scope, field);
aml_append(scope, aml_mutex("BLCK", 0));
method = aml_method("PCEJ", 2, AML_NOTSERIALIZED);
aml_append(method, aml_acquire(aml_name("BLCK"), 0xFFFF));
aml_append(method, aml_store(aml_arg(0), aml_name("BNUM")));
aml_append(method,
aml_store(aml_shiftleft(aml_int(1), aml_arg(1)), aml_name("B0EJ")));
aml_append(method, aml_release(aml_name("BLCK")));
aml_append(method, aml_return(aml_int(0)));
aml_append(scope, method);
method = aml_method("AIDX", 2, AML_NOTSERIALIZED);
aml_append(method, aml_acquire(aml_name("BLCK"), 0xFFFF));
aml_append(method, aml_store(aml_arg(0), aml_name("BNUM")));
aml_append(method,
aml_store(aml_shiftleft(aml_int(1), aml_arg(1)), aml_name("PIDX")));
aml_append(method, aml_store(aml_name("PIDX"), aml_local(0)));
aml_append(method, aml_release(aml_name("BLCK")));
aml_append(method, aml_return(aml_local(0)));
aml_append(scope, method);
aml_append(scope, aml_pci_pdsm());
aml_append(table, scope);
}
/* Reserve PCIHP resources */
void build_append_pcihp_resources(Aml *scope /* \\_SB.PCI0 */,
uint64_t io_addr, uint64_t io_len)
{
Aml *dev, *crs;
dev = aml_device("PHPR");
aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A06")));
aml_append(dev,
aml_name_decl("_UID", aml_string("PCI Hotplug resources")));
/* device present, functioning, decoding, not shown in UI */
aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
crs = aml_resource_template();
aml_append(crs, aml_io(AML_DECODE16, io_addr, io_addr, 1, io_len));
aml_append(dev, aml_name_decl("_CRS", crs));
aml_append(scope, dev);
}
bool build_append_notification_callback(Aml *parent_scope, const PCIBus *bus)
{
Aml *method;
PCIBus *sec;
QObject *bsel;
int nr_notifiers = 0;
GQueue *pcnt_bus_list = g_queue_new();
QLIST_FOREACH(sec, &bus->child, sibling) {
Aml *br_scope = aml_scope("S%.02X", sec->parent_dev->devfn);
if (pci_bus_is_root(sec)) {
continue;
}
nr_notifiers = nr_notifiers +
build_append_notification_callback(br_scope, sec);
/*
* add new child scope to parent
* and keep track of bus that have PCNT,
* bus list is used later to call children PCNTs from this level PCNT
*/
if (nr_notifiers) {
g_queue_push_tail(pcnt_bus_list, sec);
aml_append(parent_scope, br_scope);
}
}
/*
* Append PCNT method to notify about events on local and child buses.
* ps: hostbridge might not have hotplug (bsel) enabled but might have
* child bridges that do have bsel.
*/
method = aml_method("PCNT", 0, AML_NOTSERIALIZED);
/* If bus supports hotplug select it and notify about local events */
bsel = object_property_get_qobject(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, NULL);
if (bsel) {
uint64_t bsel_val = qnum_get_uint(qobject_to(QNum, bsel));
aml_append(method, aml_store(aml_int(bsel_val), aml_name("BNUM")));
aml_append(method, aml_call2("DVNT", aml_name("PCIU"),
aml_int(1))); /* Device Check */
aml_append(method, aml_call2("DVNT", aml_name("PCID"),
aml_int(3))); /* Eject Request */
nr_notifiers++;
}
/* Notify about child bus events in any case */
while ((sec = g_queue_pop_head(pcnt_bus_list))) {
aml_append(method, aml_name("^S%.02X.PCNT", sec->parent_dev->devfn));
}
aml_append(parent_scope, method);
qobject_unref(bsel);
g_queue_free(pcnt_bus_list);
return !!nr_notifiers;
}
static Aml *aml_pci_device_dsm(void)
{
Aml *method;
method = aml_method("_DSM", 4, AML_SERIALIZED);
{
Aml *params = aml_local(0);
Aml *pkg = aml_package(2);
aml_append(pkg, aml_int(0));
aml_append(pkg, aml_int(0));
aml_append(method, aml_store(pkg, params));
aml_append(method,
aml_store(aml_name("BSEL"), aml_index(params, aml_int(0))));
aml_append(method,
aml_store(aml_name("ASUN"), aml_index(params, aml_int(1))));
aml_append(method,
aml_return(aml_call5("PDSM", aml_arg(0), aml_arg(1),
aml_arg(2), aml_arg(3), params))
);
}
return method;
}
static Aml *aml_pci_static_endpoint_dsm(PCIDevice *pdev)
{
Aml *method;
g_assert(pdev->acpi_index != 0);
method = aml_method("_DSM", 4, AML_SERIALIZED);
{
Aml *params = aml_local(0);
Aml *pkg = aml_package(1);
aml_append(pkg, aml_int(pdev->acpi_index));
aml_append(method, aml_store(pkg, params));
aml_append(method,
aml_return(aml_call5("EDSM", aml_arg(0), aml_arg(1),
aml_arg(2), aml_arg(3), params))
);
}
return method;
}
static void build_append_pcihp_notify_entry(Aml *method, int slot)
{
Aml *if_ctx;
int32_t devfn = PCI_DEVFN(slot, 0);
if_ctx = aml_if(aml_and(aml_arg(0), aml_int(0x1U << slot), NULL));
aml_append(if_ctx, aml_notify(aml_name("S%.02X", devfn), aml_arg(1)));
aml_append(method, if_ctx);
}
static bool is_devfn_ignored_generic(const int devfn, const PCIBus *bus)
{
const PCIDevice *pdev = bus->devices[devfn];
if (PCI_FUNC(devfn)) {
if (IS_PCI_BRIDGE(pdev)) {
/*
* Ignore only hotplugged PCI bridges on !0 functions, but
* allow describing cold plugged bridges on all functions
*/
if (DEVICE(pdev)->hotplugged) {
return true;
}
}
}
return false;
}
static bool is_devfn_ignored_hotplug(const int devfn, const PCIBus *bus)
{
PCIDevice *pdev = bus->devices[devfn];
if (pdev) {
return is_devfn_ignored_generic(devfn, bus) ||
!DEVICE_GET_CLASS(pdev)->hotpluggable ||
/* Cold plugged bridges aren't themselves hot-pluggable */
(IS_PCI_BRIDGE(pdev) && !DEVICE(pdev)->hotplugged);
} else { /* non populated slots */
/*
* hotplug is supported only for non-multifunction device
* so generate device description only for function 0
*/
if (PCI_FUNC(devfn) ||
(pci_bus_is_express(bus) && PCI_SLOT(devfn) > 0)) {
return true;
}
}
return false;
}
void build_append_pcihp_slots(Aml *parent_scope, PCIBus *bus)
{
int devfn;
Aml *dev, *notify_method = NULL, *method;
QObject *bsel = object_property_get_qobject(OBJECT(bus),
ACPI_PCIHP_PROP_BSEL, NULL);
uint64_t bsel_val = qnum_get_uint(qobject_to(QNum, bsel));
qobject_unref(bsel);
aml_append(parent_scope, aml_name_decl("BSEL", aml_int(bsel_val)));
notify_method = aml_method("DVNT", 2, AML_NOTSERIALIZED);
for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
int slot = PCI_SLOT(devfn);
int adr = slot << 16 | PCI_FUNC(devfn);
if (is_devfn_ignored_hotplug(devfn, bus)) {
continue;
}
if (bus->devices[devfn]) {
dev = aml_scope("S%.02X", devfn);
} else {
dev = aml_device("S%.02X", devfn);
aml_append(dev, aml_name_decl("_ADR", aml_int(adr)));
}
/*
* Can't declare _SUN here for every device as it changes 'slot'
* enumeration order in linux kernel, so use another variable for it
*/
aml_append(dev, aml_name_decl("ASUN", aml_int(slot)));
aml_append(dev, aml_pci_device_dsm());
aml_append(dev, aml_name_decl("_SUN", aml_int(slot)));
/* add _EJ0 to make slot hotpluggable */
method = aml_method("_EJ0", 1, AML_NOTSERIALIZED);
aml_append(method,
aml_call2("PCEJ", aml_name("BSEL"), aml_name("_SUN"))
);
aml_append(dev, method);
build_append_pcihp_notify_entry(notify_method, slot);
/* device descriptor has been composed, add it into parent context */
aml_append(parent_scope, dev);
}
aml_append(parent_scope, notify_method);
}
void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus)
{
int devfn;
Aml *dev;
for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
/* ACPI spec: 1.0b: Table 6-2 _ADR Object Bus Types, PCI type */
int adr = PCI_SLOT(devfn) << 16 | PCI_FUNC(devfn);
PCIDevice *pdev = bus->devices[devfn];
if (!pdev || is_devfn_ignored_generic(devfn, bus)) {
continue;
}
/* start to compose PCI device descriptor */
dev = aml_device("S%.02X", devfn);
aml_append(dev, aml_name_decl("_ADR", aml_int(adr)));
call_dev_aml_func(DEVICE(bus->devices[devfn]), dev);
/* add _DSM if device has acpi-index set */
if (pdev->acpi_index &&
!object_property_get_bool(OBJECT(pdev), "hotpluggable",
&error_abort)) {
aml_append(dev, aml_pci_static_endpoint_dsm(pdev));
}
/* device descriptor has been composed, add it into parent context */
aml_append(parent_scope, dev);
}
}
const VMStateDescription vmstate_acpi_pcihp_pci_status = {
.name = "acpi_pcihp_pci_status",
.version_id = 1,
+4 -1
View File
@@ -567,7 +567,8 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
if (s->acpi_pci_hotplug.use_acpi_hotplug_bridge ||
s->acpi_pci_hotplug.use_acpi_root_pci_hotplug) {
acpi_pcihp_init(OBJECT(s), &s->acpi_pci_hotplug, bus, parent,
object_property_set_link(OBJECT(s), "bus", OBJECT(bus), &error_abort);
acpi_pcihp_init(OBJECT(s), &s->acpi_pci_hotplug, parent,
ACPI_PCIHP_ADDR_PIIX4);
qbus_set_hotplug_handler(BUS(pci_get_bus(PCI_DEVICE(s))), OBJECT(s));
}
@@ -611,6 +612,8 @@ static const Property piix4_pm_properties[] = {
acpi_pci_hotplug.use_acpi_hotplug_bridge, true),
DEFINE_PROP_BOOL(ACPI_PM_PROP_ACPI_PCI_ROOTHP, PIIX4PMState,
acpi_pci_hotplug.use_acpi_root_pci_hotplug, true),
DEFINE_PROP_LINK("bus", PIIX4PMState, acpi_pci_hotplug.root,
TYPE_PCI_BUS, PCIBus *),
DEFINE_PROP_BOOL("memory-hotplug-support", PIIX4PMState,
acpi_memory_hotplug.is_enabled, true),
DEFINE_PROP_BOOL("smm-compat", PIIX4PMState, smm_compat, false),
+2
View File
@@ -34,6 +34,8 @@ config ARM_VIRT
select ACPI_HW_REDUCED
select ACPI_APEI
select ACPI_VIOT
select ACPI_PCIHP
select ACPI_PCI_BRIDGE
select VIRTIO_MEM_SUPPORTED
select ACPI_CXL
select ACPI_HMAT
-1
View File
@@ -20,7 +20,6 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/bswap.h"
#include "qemu/module.h"
#include "qemu/units.h"
#include "hw/boards.h"
+2
View File
@@ -15,6 +15,7 @@
#include "hw/arm/boot.h"
#include "hw/arm/linux-boot-if.h"
#include "cpu.h"
#include "exec/tswap.h"
#include "exec/target_page.h"
#include "system/kvm.h"
#include "system/tcg.h"
@@ -29,6 +30,7 @@
#include "qemu/config-file.h"
#include "qemu/option.h"
#include "qemu/units.h"
#include "qemu/bswap.h"
/* Kernel boot protocol is specified in the kernel docs
* Documentation/arm/Booting and Documentation/arm64/booting.txt
+1 -1
View File
@@ -24,7 +24,7 @@
#include "hw/qdev-clock.h"
#include "hw/qdev-properties.h"
#include "qapi/error.h"
#include "qemu/bswap.h"
#include "exec/tswap.h"
#include "qemu/units.h"
#include "system/system.h"
#include "target/arm/cpu-qom.h"
+42 -1
View File
@@ -34,6 +34,7 @@
#include "hw/core/cpu.h"
#include "hw/acpi/acpi-defs.h"
#include "hw/acpi/acpi.h"
#include "hw/acpi/pcihp.h"
#include "hw/nvram/fw_cfg_acpi.h"
#include "hw/acpi/bios-linker-loader.h"
#include "hw/acpi/aml-build.h"
@@ -144,12 +145,21 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
int ecam_id = VIRT_ECAM_ID(vms->highmem_ecam);
bool cxl_present = false;
PCIBus *bus = vms->bus;
bool acpi_pcihp = false;
if (vms->acpi_dev) {
acpi_pcihp = object_property_get_bool(OBJECT(vms->acpi_dev),
ACPI_PM_PROP_ACPI_PCIHP_BRIDGE,
NULL);
}
struct GPEXConfig cfg = {
.mmio32 = memmap[VIRT_PCIE_MMIO],
.pio = memmap[VIRT_PCIE_PIO],
.ecam = memmap[ecam_id],
.irq = irq,
.bus = vms->bus,
.pci_native_hotplug = !acpi_pcihp,
};
if (vms->highmem_mmio) {
@@ -897,6 +907,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
const int *irqmap = vms->irqmap;
AcpiTable table = { .sig = "DSDT", .rev = 2, .oem_id = vms->oem_id,
.oem_table_id = vms->oem_table_id };
Aml *pci0_scope;
acpi_table_begin(&table, table_data);
dsdt = init_aml_allocator();
@@ -950,6 +961,33 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
aml_append(dsdt, scope);
pci0_scope = aml_scope("\\_SB.PCI0");
aml_append(pci0_scope, build_pci_bridge_edsm());
build_append_pci_bus_devices(pci0_scope, vms->bus);
if (object_property_find(OBJECT(vms->bus), ACPI_PCIHP_PROP_BSEL)) {
build_append_pcihp_slots(pci0_scope, vms->bus);
}
if (vms->acpi_dev) {
bool acpi_pcihp;
acpi_pcihp = object_property_get_bool(OBJECT(vms->acpi_dev),
ACPI_PM_PROP_ACPI_PCIHP_BRIDGE,
NULL);
if (acpi_pcihp) {
build_acpi_pci_hotplug(dsdt, AML_SYSTEM_MEMORY,
memmap[VIRT_ACPI_PCIHP].base);
build_append_pcihp_resources(pci0_scope,
memmap[VIRT_ACPI_PCIHP].base,
memmap[VIRT_ACPI_PCIHP].size);
build_append_notification_callback(pci0_scope, vms->bus);
}
}
aml_append(dsdt, pci0_scope);
/* copy AML table into ACPI tables blob */
g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len);
@@ -1023,7 +1061,10 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
}
acpi_add_table(table_offsets, tables_blob);
spcr_setup(tables_blob, tables->linker, vms);
if (ms->acpi_spcr_enabled) {
spcr_setup(tables_blob, tables->linker, vms);
}
acpi_add_table(table_offsets, tables_blob);
build_dbg2(tables_blob, tables->linker, vms);
+23 -4
View File
@@ -76,6 +76,7 @@
#include "standard-headers/linux/input.h"
#include "hw/arm/smmuv3.h"
#include "hw/acpi/acpi.h"
#include "hw/acpi/pcihp.h"
#include "target/arm/cpu-qom.h"
#include "target/arm/internals.h"
#include "target/arm/multiprocessing.h"
@@ -186,6 +187,7 @@ static const MemMapEntry base_memmap[] = {
[VIRT_NVDIMM_ACPI] = { 0x09090000, NVDIMM_ACPI_IO_LEN},
[VIRT_PVTIME] = { 0x090a0000, 0x00010000 },
[VIRT_SECURE_GPIO] = { 0x090b0000, 0x00001000 },
[VIRT_ACPI_PCIHP] = { 0x090c0000, ACPI_PCIHP_SIZE },
[VIRT_MMIO] = { 0x0a000000, 0x00000200 },
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
[VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 },
@@ -686,8 +688,10 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms)
{
DeviceState *dev;
MachineState *ms = MACHINE(vms);
SysBusDevice *sbdev;
int irq = vms->irqmap[VIRT_ACPI_GED];
uint32_t event = ACPI_GED_PWR_DOWN_EVT;
bool acpi_pcihp;
if (ms->ram_slots) {
event |= ACPI_GED_MEM_HOTPLUG_EVT;
@@ -699,11 +703,26 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms)
dev = qdev_new(TYPE_ACPI_GED);
qdev_prop_set_uint32(dev, "ged-event", event);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
object_property_set_link(OBJECT(dev), "bus", OBJECT(vms->bus), &error_abort);
sbdev = SYS_BUS_DEVICE(dev);
sysbus_realize_and_unref(sbdev, &error_fatal);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_ACPI_GED].base);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, vms->memmap[VIRT_PCDIMM_ACPI].base);
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(vms->gic, irq));
sysbus_mmio_map_name(sbdev, TYPE_ACPI_GED, vms->memmap[VIRT_ACPI_GED].base);
sysbus_mmio_map_name(sbdev, ACPI_MEMHP_REGION_NAME,
vms->memmap[VIRT_PCDIMM_ACPI].base);
acpi_pcihp = object_property_get_bool(OBJECT(dev),
ACPI_PM_PROP_ACPI_PCIHP_BRIDGE, NULL);
if (acpi_pcihp) {
int pcihp_region_index;
pcihp_region_index = sysbus_mmio_map_name(sbdev, ACPI_PCIHP_REGION_NAME,
vms->memmap[VIRT_ACPI_PCIHP].base);
assert(pcihp_region_index >= 0);
}
sysbus_connect_irq(sbdev, 0, qdev_get_gpio_in(vms->gic, irq));
return dev;
}
-1
View File
@@ -33,7 +33,6 @@
#include "qemu/osdep.h"
#include "system/block-backend.h"
#include "qapi/qapi-types-block.h"
#include "qemu/bswap.h"
#include "hw/block/block.h"
#include "trace.h"
+4 -2
View File
@@ -13,7 +13,9 @@ system_ss.add(when: 'CONFIG_SSI_M25P80', if_true: files('m25p80_sfdp.c'))
system_ss.add(when: 'CONFIG_SWIM', if_true: files('swim.c'))
system_ss.add(when: 'CONFIG_XEN_BUS', if_true: files('xen-block.c'))
specific_ss.add(when: 'CONFIG_VIRTIO_BLK', if_true: files('virtio-blk.c', 'virtio-blk-common.c'))
specific_ss.add(when: 'CONFIG_VHOST_USER_BLK', if_true: files('vhost-user-blk.c', 'virtio-blk-common.c'))
specific_ss.add(when: 'CONFIG_VIRTIO_BLK', if_true: files('virtio-blk.c'))
system_ss.add(when: 'CONFIG_VIRTIO_BLK', if_true: files('virtio-blk-common.c'))
specific_ss.add(when: 'CONFIG_VHOST_USER_BLK', if_true: files('vhost-user-blk.c'))
system_ss.add(when: 'CONFIG_VHOST_USER_BLK', if_true: files('virtio-blk-common.c'))
subdir('dataplane')
+8 -1
View File
@@ -210,6 +210,7 @@ static int vhost_user_blk_stop(VirtIODevice *vdev)
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
int ret;
bool force_stop = false;
if (!s->started_vu) {
return 0;
@@ -220,7 +221,11 @@ static int vhost_user_blk_stop(VirtIODevice *vdev)
return 0;
}
ret = vhost_dev_stop(&s->dev, vdev, true);
force_stop = s->skip_get_vring_base_on_force_shutdown &&
qemu_force_shutdown_requested();
ret = force_stop ? vhost_dev_force_stop(&s->dev, vdev, true) :
vhost_dev_stop(&s->dev, vdev, true);
if (k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false) < 0) {
error_report("vhost guest notifier cleanup failed: %d", ret);
@@ -584,6 +589,8 @@ static const Property vhost_user_blk_properties[] = {
VIRTIO_BLK_F_DISCARD, true),
DEFINE_PROP_BIT64("write-zeroes", VHostUserBlk, parent_obj.host_features,
VIRTIO_BLK_F_WRITE_ZEROES, true),
DEFINE_PROP_BOOL("skip-get-vring-base-on-force-shutdown", VHostUserBlk,
skip_get_vring_base_on_force_shutdown, false),
};
static void vhost_user_blk_class_init(ObjectClass *klass, const void *data)
-1
View File
@@ -29,7 +29,6 @@
#include "qemu/timer.h"
#include "qemu/error-report.h"
#include "system/address-spaces.h"
#include "exec/tswap.h"
#include "system/dma.h"
#include "system/runstate.h"
#include "trace.h"

Some files were not shown because too many files have changed in this diff Show More