pc, pci, virtio: fixes for rc1
A bunch of fixes all over the place. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> -----BEGIN PGP SIGNATURE----- iQEcBAABAgAGBQJaDb7BAAoJECgfDbjSjVRpQ+cH/iFeCPuzIOD1+rUw72OTe2Y/ +/eg3EvhsRBOztWPnbsgw4R0ptbnJw+t0bv1CJ413Ugch0JJy39c91h4WjtJDAvt qax3WU8UR/Z9M8s0JBw7eDZQ6mLwDufbL58uw/41dHG834A2dxH9qwc0jrKuicJA xXLxRpD6LVLAlACQgusivJ8/GeH/CireY+qQfNxWuS26zgcNqmNrj2jUV7Dir8dm /0aTmMLP8Vl8+zvKk1qXJgvjPAST+wzKFc9tFoQN7KQWvsHMOAxPG3krT2FE5VZ/ FQvSXGOQVuvEKUhqL7Xu1s8kO69uEdMomAvBFiXZNZ3xmgQTzwRUsWRuS/SEsfU= =1El4 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging pc, pci, virtio: fixes for rc1 A bunch of fixes all over the place. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Thu 16 Nov 2017 16:37:21 GMT # gpg: using RSA key 0x281F0DB8D28D5469 # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" # 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 * remotes/mst/tags/for_upstream: tests/bios-tables-test: Fix endianess problems when passing data to iasl build-sys: restrict vmcoreinfo to fw_cfg+dma capable targets vmcoreinfo: put it in the 'misc' device category NUMA: Enable adding NUMA node implicitly tests/acpi-test-data: update _CRS in DSDT hw/pcie-pci-bridge: restrict to X86 and ARM hw/pci-host: Fix x86 Host Bridges 64bit PCI hole pci: Initialize pci_dev->name before use fix: unrealize virtio device if we fail to hotplug it Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
b91f0f25c7
@ -130,3 +130,5 @@ CONFIG_SMBIOS=y
|
|||||||
CONFIG_ASPEED_SOC=y
|
CONFIG_ASPEED_SOC=y
|
||||||
CONFIG_GPIO_KEY=y
|
CONFIG_GPIO_KEY=y
|
||||||
CONFIG_MSF2=y
|
CONFIG_MSF2=y
|
||||||
|
|
||||||
|
CONFIG_FW_CFG_DMA=y
|
||||||
|
@ -60,3 +60,4 @@ CONFIG_SMBIOS=y
|
|||||||
CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM)
|
CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM)
|
||||||
CONFIG_PXB=y
|
CONFIG_PXB=y
|
||||||
CONFIG_ACPI_VMGENID=y
|
CONFIG_ACPI_VMGENID=y
|
||||||
|
CONFIG_FW_CFG_DMA=y
|
||||||
|
@ -60,3 +60,4 @@ CONFIG_SMBIOS=y
|
|||||||
CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM)
|
CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM)
|
||||||
CONFIG_PXB=y
|
CONFIG_PXB=y
|
||||||
CONFIG_ACPI_VMGENID=y
|
CONFIG_ACPI_VMGENID=y
|
||||||
|
CONFIG_FW_CFG_DMA=y
|
||||||
|
23
hw/i386/pc.c
23
hw/i386/pc.c
@ -1448,6 +1448,28 @@ void pc_memory_init(PCMachineState *pcms,
|
|||||||
pcms->ioapic_as = &address_space_memory;
|
pcms->ioapic_as = &address_space_memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The 64bit pci hole starts after "above 4G RAM" and
|
||||||
|
* potentially the space reserved for memory hotplug.
|
||||||
|
*/
|
||||||
|
uint64_t pc_pci_hole64_start(void)
|
||||||
|
{
|
||||||
|
PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
|
||||||
|
PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
|
||||||
|
uint64_t hole64_start = 0;
|
||||||
|
|
||||||
|
if (pcmc->has_reserved_memory && pcms->hotplug_memory.base) {
|
||||||
|
hole64_start = pcms->hotplug_memory.base;
|
||||||
|
if (!pcmc->broken_reserved_end) {
|
||||||
|
hole64_start += memory_region_size(&pcms->hotplug_memory.mr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hole64_start = 0x100000000ULL + pcms->above_4g_mem_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ROUND_UP(hole64_start, 1ULL << 30);
|
||||||
|
}
|
||||||
|
|
||||||
qemu_irq pc_allocate_cpu_irq(void)
|
qemu_irq pc_allocate_cpu_irq(void)
|
||||||
{
|
{
|
||||||
return qemu_allocate_irq(pic_irq_request, NULL, 0);
|
return qemu_allocate_irq(pic_irq_request, NULL, 0);
|
||||||
@ -2325,6 +2347,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
|
|||||||
mc->cpu_index_to_instance_props = pc_cpu_index_to_props;
|
mc->cpu_index_to_instance_props = pc_cpu_index_to_props;
|
||||||
mc->get_default_cpu_node_id = pc_get_default_cpu_node_id;
|
mc->get_default_cpu_node_id = pc_get_default_cpu_node_id;
|
||||||
mc->possible_cpu_arch_ids = pc_possible_cpu_arch_ids;
|
mc->possible_cpu_arch_ids = pc_possible_cpu_arch_ids;
|
||||||
|
mc->auto_enable_numa_with_memhp = true;
|
||||||
mc->has_hotpluggable_cpus = true;
|
mc->has_hotpluggable_cpus = true;
|
||||||
mc->default_boot_order = "cad";
|
mc->default_boot_order = "cad";
|
||||||
mc->hot_add_cpu = pc_hot_add_cpu;
|
mc->hot_add_cpu = pc_hot_add_cpu;
|
||||||
|
@ -446,6 +446,7 @@ static void pc_i440fx_2_10_machine_options(MachineClass *m)
|
|||||||
m->is_default = 0;
|
m->is_default = 0;
|
||||||
m->alias = NULL;
|
m->alias = NULL;
|
||||||
SET_MACHINE_COMPAT(m, PC_COMPAT_2_10);
|
SET_MACHINE_COMPAT(m, PC_COMPAT_2_10);
|
||||||
|
m->auto_enable_numa_with_memhp = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_I440FX_MACHINE(v2_10, "pc-i440fx-2.10", NULL,
|
DEFINE_I440FX_MACHINE(v2_10, "pc-i440fx-2.10", NULL,
|
||||||
|
@ -318,6 +318,7 @@ static void pc_q35_2_10_machine_options(MachineClass *m)
|
|||||||
m->alias = NULL;
|
m->alias = NULL;
|
||||||
SET_MACHINE_COMPAT(m, PC_COMPAT_2_10);
|
SET_MACHINE_COMPAT(m, PC_COMPAT_2_10);
|
||||||
m->numa_auto_assign_ram = numa_legacy_auto_assign_ram;
|
m->numa_auto_assign_ram = numa_legacy_auto_assign_ram;
|
||||||
|
m->auto_enable_numa_with_memhp = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_Q35_MACHINE(v2_10, "pc-q35-2.10", NULL,
|
DEFINE_Q35_MACHINE(v2_10, "pc-q35-2.10", NULL,
|
||||||
|
@ -9,7 +9,7 @@ common-obj-$(CONFIG_PCI_TESTDEV) += pci-testdev.o
|
|||||||
common-obj-$(CONFIG_EDU) += edu.o
|
common-obj-$(CONFIG_EDU) += edu.o
|
||||||
|
|
||||||
common-obj-y += unimp.o
|
common-obj-y += unimp.o
|
||||||
common-obj-y += vmcoreinfo.o
|
common-obj-$(CONFIG_FW_CFG_DMA) += vmcoreinfo.o
|
||||||
|
|
||||||
obj-$(CONFIG_VMPORT) += vmport.o
|
obj-$(CONFIG_VMPORT) += vmport.o
|
||||||
|
|
||||||
|
@ -79,6 +79,7 @@ static void vmcoreinfo_device_class_init(ObjectClass *klass, void *data)
|
|||||||
dc->vmsd = &vmstate_vmcoreinfo;
|
dc->vmsd = &vmstate_vmcoreinfo;
|
||||||
dc->realize = vmcoreinfo_realize;
|
dc->realize = vmcoreinfo_realize;
|
||||||
dc->hotpluggable = false;
|
dc->hotpluggable = false;
|
||||||
|
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo vmcoreinfo_device_info = {
|
static const TypeInfo vmcoreinfo_device_info = {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
common-obj-y += pci_bridge_dev.o pcie_pci_bridge.o
|
common-obj-y += pci_bridge_dev.o
|
||||||
common-obj-$(CONFIG_PCIE_PORT) += pcie_root_port.o gen_pcie_root_port.o
|
common-obj-$(CONFIG_PCIE_PORT) += pcie_root_port.o gen_pcie_root_port.o pcie_pci_bridge.o
|
||||||
common-obj-$(CONFIG_PXB) += pci_expander_bridge.o
|
common-obj-$(CONFIG_PXB) += pci_expander_bridge.o
|
||||||
common-obj-$(CONFIG_XIO3130) += xio3130_upstream.o xio3130_downstream.o
|
common-obj-$(CONFIG_XIO3130) += xio3130_upstream.o xio3130_downstream.o
|
||||||
common-obj-$(CONFIG_IOH3420) += ioh3420.o
|
common-obj-$(CONFIG_IOH3420) += ioh3420.o
|
||||||
|
@ -50,6 +50,7 @@ typedef struct I440FXState {
|
|||||||
PCIHostState parent_obj;
|
PCIHostState parent_obj;
|
||||||
Range pci_hole;
|
Range pci_hole;
|
||||||
uint64_t pci_hole64_size;
|
uint64_t pci_hole64_size;
|
||||||
|
bool pci_hole64_fix;
|
||||||
uint32_t short_root_bus;
|
uint32_t short_root_bus;
|
||||||
} I440FXState;
|
} I440FXState;
|
||||||
|
|
||||||
@ -112,6 +113,9 @@ struct PCII440FXState {
|
|||||||
#define I440FX_PAM_SIZE 7
|
#define I440FX_PAM_SIZE 7
|
||||||
#define I440FX_SMRAM 0x72
|
#define I440FX_SMRAM 0x72
|
||||||
|
|
||||||
|
/* Keep it 2G to comply with older win32 guests */
|
||||||
|
#define I440FX_PCI_HOST_HOLE64_SIZE_DEFAULT (1ULL << 31)
|
||||||
|
|
||||||
/* Older coreboot versions (4.0 and older) read a config register that doesn't
|
/* Older coreboot versions (4.0 and older) read a config register that doesn't
|
||||||
* exist in real hardware, to get the RAM size from QEMU.
|
* exist in real hardware, to get the RAM size from QEMU.
|
||||||
*/
|
*/
|
||||||
@ -238,29 +242,52 @@ static void i440fx_pcihost_get_pci_hole_end(Object *obj, Visitor *v,
|
|||||||
visit_type_uint32(v, name, &value, errp);
|
visit_type_uint32(v, name, &value, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The 64bit PCI hole start is set by the Guest firmware
|
||||||
|
* as the address of the first 64bit PCI MEM resource.
|
||||||
|
* If no PCI device has resources on the 64bit area,
|
||||||
|
* the 64bit PCI hole will start after "over 4G RAM" and the
|
||||||
|
* reserved space for memory hotplug if any.
|
||||||
|
*/
|
||||||
static void i440fx_pcihost_get_pci_hole64_start(Object *obj, Visitor *v,
|
static void i440fx_pcihost_get_pci_hole64_start(Object *obj, Visitor *v,
|
||||||
const char *name,
|
const char *name,
|
||||||
void *opaque, Error **errp)
|
void *opaque, Error **errp)
|
||||||
{
|
{
|
||||||
PCIHostState *h = PCI_HOST_BRIDGE(obj);
|
PCIHostState *h = PCI_HOST_BRIDGE(obj);
|
||||||
|
I440FXState *s = I440FX_PCI_HOST_BRIDGE(obj);
|
||||||
Range w64;
|
Range w64;
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
|
|
||||||
pci_bus_get_w64_range(h->bus, &w64);
|
pci_bus_get_w64_range(h->bus, &w64);
|
||||||
value = range_is_empty(&w64) ? 0 : range_lob(&w64);
|
value = range_is_empty(&w64) ? 0 : range_lob(&w64);
|
||||||
|
if (!value && s->pci_hole64_fix) {
|
||||||
|
value = pc_pci_hole64_start();
|
||||||
|
}
|
||||||
visit_type_uint64(v, name, &value, errp);
|
visit_type_uint64(v, name, &value, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The 64bit PCI hole end is set by the Guest firmware
|
||||||
|
* as the address of the last 64bit PCI MEM resource.
|
||||||
|
* Then it is expanded to the PCI_HOST_PROP_PCI_HOLE64_SIZE
|
||||||
|
* that can be configured by the user.
|
||||||
|
*/
|
||||||
static void i440fx_pcihost_get_pci_hole64_end(Object *obj, Visitor *v,
|
static void i440fx_pcihost_get_pci_hole64_end(Object *obj, Visitor *v,
|
||||||
const char *name, void *opaque,
|
const char *name, void *opaque,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
PCIHostState *h = PCI_HOST_BRIDGE(obj);
|
PCIHostState *h = PCI_HOST_BRIDGE(obj);
|
||||||
|
I440FXState *s = I440FX_PCI_HOST_BRIDGE(obj);
|
||||||
|
uint64_t hole64_start = pc_pci_hole64_start();
|
||||||
Range w64;
|
Range w64;
|
||||||
uint64_t value;
|
uint64_t value, hole64_end;
|
||||||
|
|
||||||
pci_bus_get_w64_range(h->bus, &w64);
|
pci_bus_get_w64_range(h->bus, &w64);
|
||||||
value = range_is_empty(&w64) ? 0 : range_upb(&w64) + 1;
|
value = range_is_empty(&w64) ? 0 : range_upb(&w64) + 1;
|
||||||
|
hole64_end = ROUND_UP(hole64_start + s->pci_hole64_size, 1ULL << 30);
|
||||||
|
if (s->pci_hole64_fix && value < hole64_end) {
|
||||||
|
value = hole64_end;
|
||||||
|
}
|
||||||
visit_type_uint64(v, name, &value, errp);
|
visit_type_uint64(v, name, &value, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -863,8 +890,9 @@ static const char *i440fx_pcihost_root_bus_path(PCIHostState *host_bridge,
|
|||||||
|
|
||||||
static Property i440fx_props[] = {
|
static Property i440fx_props[] = {
|
||||||
DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, I440FXState,
|
DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, I440FXState,
|
||||||
pci_hole64_size, DEFAULT_PCI_HOLE64_SIZE),
|
pci_hole64_size, I440FX_PCI_HOST_HOLE64_SIZE_DEFAULT),
|
||||||
DEFINE_PROP_UINT32("short_root_bus", I440FXState, short_root_bus, 0),
|
DEFINE_PROP_UINT32("short_root_bus", I440FXState, short_root_bus, 0),
|
||||||
|
DEFINE_PROP_BOOL("x-pci-hole64-fix", I440FXState, pci_hole64_fix, true),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -37,6 +37,8 @@
|
|||||||
* Q35 host
|
* Q35 host
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define Q35_PCI_HOST_HOLE64_SIZE_DEFAULT (1ULL << 35)
|
||||||
|
|
||||||
static void q35_host_realize(DeviceState *dev, Error **errp)
|
static void q35_host_realize(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
PCIHostState *pci = PCI_HOST_BRIDGE(dev);
|
PCIHostState *pci = PCI_HOST_BRIDGE(dev);
|
||||||
@ -99,29 +101,52 @@ static void q35_host_get_pci_hole_end(Object *obj, Visitor *v,
|
|||||||
visit_type_uint32(v, name, &value, errp);
|
visit_type_uint32(v, name, &value, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The 64bit PCI hole start is set by the Guest firmware
|
||||||
|
* as the address of the first 64bit PCI MEM resource.
|
||||||
|
* If no PCI device has resources on the 64bit area,
|
||||||
|
* the 64bit PCI hole will start after "over 4G RAM" and the
|
||||||
|
* reserved space for memory hotplug if any.
|
||||||
|
*/
|
||||||
static void q35_host_get_pci_hole64_start(Object *obj, Visitor *v,
|
static void q35_host_get_pci_hole64_start(Object *obj, Visitor *v,
|
||||||
const char *name, void *opaque,
|
const char *name, void *opaque,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
PCIHostState *h = PCI_HOST_BRIDGE(obj);
|
PCIHostState *h = PCI_HOST_BRIDGE(obj);
|
||||||
|
Q35PCIHost *s = Q35_HOST_DEVICE(obj);
|
||||||
Range w64;
|
Range w64;
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
|
|
||||||
pci_bus_get_w64_range(h->bus, &w64);
|
pci_bus_get_w64_range(h->bus, &w64);
|
||||||
value = range_is_empty(&w64) ? 0 : range_lob(&w64);
|
value = range_is_empty(&w64) ? 0 : range_lob(&w64);
|
||||||
|
if (!value && s->pci_hole64_fix) {
|
||||||
|
value = pc_pci_hole64_start();
|
||||||
|
}
|
||||||
visit_type_uint64(v, name, &value, errp);
|
visit_type_uint64(v, name, &value, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The 64bit PCI hole end is set by the Guest firmware
|
||||||
|
* as the address of the last 64bit PCI MEM resource.
|
||||||
|
* Then it is expanded to the PCI_HOST_PROP_PCI_HOLE64_SIZE
|
||||||
|
* that can be configured by the user.
|
||||||
|
*/
|
||||||
static void q35_host_get_pci_hole64_end(Object *obj, Visitor *v,
|
static void q35_host_get_pci_hole64_end(Object *obj, Visitor *v,
|
||||||
const char *name, void *opaque,
|
const char *name, void *opaque,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
PCIHostState *h = PCI_HOST_BRIDGE(obj);
|
PCIHostState *h = PCI_HOST_BRIDGE(obj);
|
||||||
|
Q35PCIHost *s = Q35_HOST_DEVICE(obj);
|
||||||
|
uint64_t hole64_start = pc_pci_hole64_start();
|
||||||
Range w64;
|
Range w64;
|
||||||
uint64_t value;
|
uint64_t value, hole64_end;
|
||||||
|
|
||||||
pci_bus_get_w64_range(h->bus, &w64);
|
pci_bus_get_w64_range(h->bus, &w64);
|
||||||
value = range_is_empty(&w64) ? 0 : range_upb(&w64) + 1;
|
value = range_is_empty(&w64) ? 0 : range_upb(&w64) + 1;
|
||||||
|
hole64_end = ROUND_UP(hole64_start + s->mch.pci_hole64_size, 1ULL << 30);
|
||||||
|
if (s->pci_hole64_fix && value < hole64_end) {
|
||||||
|
value = hole64_end;
|
||||||
|
}
|
||||||
visit_type_uint64(v, name, &value, errp);
|
visit_type_uint64(v, name, &value, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,16 +158,25 @@ static void q35_host_get_mmcfg_size(Object *obj, Visitor *v, const char *name,
|
|||||||
visit_type_uint64(v, name, &e->size, errp);
|
visit_type_uint64(v, name, &e->size, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: setting defaults for the mch.* fields in this table
|
||||||
|
* doesn't work, because mch is a separate QOM object that is
|
||||||
|
* zeroed by the object_initialize(&s->mch, ...) call inside
|
||||||
|
* q35_host_initfn(). The default values for those
|
||||||
|
* properties need to be initialized manually by
|
||||||
|
* q35_host_initfn() after the object_initialize() call.
|
||||||
|
*/
|
||||||
static Property q35_host_props[] = {
|
static Property q35_host_props[] = {
|
||||||
DEFINE_PROP_UINT64(PCIE_HOST_MCFG_BASE, Q35PCIHost, parent_obj.base_addr,
|
DEFINE_PROP_UINT64(PCIE_HOST_MCFG_BASE, Q35PCIHost, parent_obj.base_addr,
|
||||||
MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT),
|
MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT),
|
||||||
DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, Q35PCIHost,
|
DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, Q35PCIHost,
|
||||||
mch.pci_hole64_size, DEFAULT_PCI_HOLE64_SIZE),
|
mch.pci_hole64_size, Q35_PCI_HOST_HOLE64_SIZE_DEFAULT),
|
||||||
DEFINE_PROP_UINT32("short_root_bus", Q35PCIHost, mch.short_root_bus, 0),
|
DEFINE_PROP_UINT32("short_root_bus", Q35PCIHost, mch.short_root_bus, 0),
|
||||||
DEFINE_PROP_SIZE(PCI_HOST_BELOW_4G_MEM_SIZE, Q35PCIHost,
|
DEFINE_PROP_SIZE(PCI_HOST_BELOW_4G_MEM_SIZE, Q35PCIHost,
|
||||||
mch.below_4g_mem_size, 0),
|
mch.below_4g_mem_size, 0),
|
||||||
DEFINE_PROP_SIZE(PCI_HOST_ABOVE_4G_MEM_SIZE, Q35PCIHost,
|
DEFINE_PROP_SIZE(PCI_HOST_ABOVE_4G_MEM_SIZE, Q35PCIHost,
|
||||||
mch.above_4g_mem_size, 0),
|
mch.above_4g_mem_size, 0),
|
||||||
|
DEFINE_PROP_BOOL("x-pci-hole64-fix", Q35PCIHost, pci_hole64_fix, true),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -174,7 +208,9 @@ static void q35_host_initfn(Object *obj)
|
|||||||
object_property_add_child(OBJECT(s), "mch", OBJECT(&s->mch), NULL);
|
object_property_add_child(OBJECT(s), "mch", OBJECT(&s->mch), NULL);
|
||||||
qdev_prop_set_int32(DEVICE(&s->mch), "addr", PCI_DEVFN(0, 0));
|
qdev_prop_set_int32(DEVICE(&s->mch), "addr", PCI_DEVFN(0, 0));
|
||||||
qdev_prop_set_bit(DEVICE(&s->mch), "multifunction", false);
|
qdev_prop_set_bit(DEVICE(&s->mch), "multifunction", false);
|
||||||
|
/* mch's object_initialize resets the default value, set it again */
|
||||||
|
qdev_prop_set_uint64(DEVICE(s), PCI_HOST_PROP_PCI_HOLE64_SIZE,
|
||||||
|
Q35_PCI_HOST_HOLE64_SIZE_DEFAULT);
|
||||||
object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "uint32",
|
object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "uint32",
|
||||||
q35_host_get_pci_hole_start,
|
q35_host_get_pci_hole_start,
|
||||||
NULL, NULL, NULL, NULL);
|
NULL, NULL, NULL, NULL);
|
||||||
|
@ -1030,6 +1030,7 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
|
|||||||
|
|
||||||
pci_dev->devfn = devfn;
|
pci_dev->devfn = devfn;
|
||||||
pci_dev->requester_id_cache = pci_req_id_cache_get(pci_dev);
|
pci_dev->requester_id_cache = pci_req_id_cache_get(pci_dev);
|
||||||
|
pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
|
||||||
|
|
||||||
memory_region_init(&pci_dev->bus_master_container_region, OBJECT(pci_dev),
|
memory_region_init(&pci_dev->bus_master_container_region, OBJECT(pci_dev),
|
||||||
"bus master container", UINT64_MAX);
|
"bus master container", UINT64_MAX);
|
||||||
@ -1039,7 +1040,6 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
|
|||||||
if (qdev_hotplug) {
|
if (qdev_hotplug) {
|
||||||
pci_init_bus_master(pci_dev);
|
pci_init_bus_master(pci_dev);
|
||||||
}
|
}
|
||||||
pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
|
|
||||||
pci_dev->irq_state = 0;
|
pci_dev->irq_state = 0;
|
||||||
pci_config_alloc(pci_dev);
|
pci_config_alloc(pci_dev);
|
||||||
|
|
||||||
|
@ -2491,6 +2491,7 @@ static void virtio_device_realize(DeviceState *dev, Error **errp)
|
|||||||
virtio_bus_device_plugged(vdev, &err);
|
virtio_bus_device_plugged(vdev, &err);
|
||||||
if (err != NULL) {
|
if (err != NULL) {
|
||||||
error_propagate(errp, err);
|
error_propagate(errp, err);
|
||||||
|
vdc->unrealize(dev, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,6 +197,7 @@ struct MachineClass {
|
|||||||
bool ignore_memory_transaction_failures;
|
bool ignore_memory_transaction_failures;
|
||||||
int numa_mem_align_shift;
|
int numa_mem_align_shift;
|
||||||
const char **valid_cpu_types;
|
const char **valid_cpu_types;
|
||||||
|
bool auto_enable_numa_with_memhp;
|
||||||
void (*numa_auto_assign_ram)(MachineClass *mc, NodeInfo *nodes,
|
void (*numa_auto_assign_ram)(MachineClass *mc, NodeInfo *nodes,
|
||||||
int nb_nodes, ram_addr_t size);
|
int nb_nodes, ram_addr_t size);
|
||||||
|
|
||||||
|
@ -238,7 +238,6 @@ void pc_guest_info_init(PCMachineState *pcms);
|
|||||||
#define PCI_HOST_PROP_PCI_HOLE64_SIZE "pci-hole64-size"
|
#define PCI_HOST_PROP_PCI_HOLE64_SIZE "pci-hole64-size"
|
||||||
#define PCI_HOST_BELOW_4G_MEM_SIZE "below-4g-mem-size"
|
#define PCI_HOST_BELOW_4G_MEM_SIZE "below-4g-mem-size"
|
||||||
#define PCI_HOST_ABOVE_4G_MEM_SIZE "above-4g-mem-size"
|
#define PCI_HOST_ABOVE_4G_MEM_SIZE "above-4g-mem-size"
|
||||||
#define DEFAULT_PCI_HOLE64_SIZE (~0x0ULL)
|
|
||||||
|
|
||||||
|
|
||||||
void pc_pci_as_mapping_init(Object *owner, MemoryRegion *system_memory,
|
void pc_pci_as_mapping_init(Object *owner, MemoryRegion *system_memory,
|
||||||
@ -249,6 +248,7 @@ void pc_memory_init(PCMachineState *pcms,
|
|||||||
MemoryRegion *system_memory,
|
MemoryRegion *system_memory,
|
||||||
MemoryRegion *rom_memory,
|
MemoryRegion *rom_memory,
|
||||||
MemoryRegion **ram_memory);
|
MemoryRegion **ram_memory);
|
||||||
|
uint64_t pc_pci_hole64_start(void);
|
||||||
qemu_irq pc_allocate_cpu_irq(void);
|
qemu_irq pc_allocate_cpu_irq(void);
|
||||||
DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus);
|
DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus);
|
||||||
void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
|
void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
|
||||||
@ -375,6 +375,14 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
|
|||||||
.driver = TYPE_X86_CPU,\
|
.driver = TYPE_X86_CPU,\
|
||||||
.property = "x-hv-max-vps",\
|
.property = "x-hv-max-vps",\
|
||||||
.value = "0x40",\
|
.value = "0x40",\
|
||||||
|
},{\
|
||||||
|
.driver = "i440FX-pcihost",\
|
||||||
|
.property = "x-pci-hole64-fix",\
|
||||||
|
.value = "off",\
|
||||||
|
},{\
|
||||||
|
.driver = "q35-pcihost",\
|
||||||
|
.property = "x-pci-hole64-fix",\
|
||||||
|
.value = "off",\
|
||||||
},
|
},
|
||||||
|
|
||||||
#define PC_COMPAT_2_9 \
|
#define PC_COMPAT_2_9 \
|
||||||
|
@ -68,6 +68,7 @@ typedef struct Q35PCIHost {
|
|||||||
PCIExpressHost parent_obj;
|
PCIExpressHost parent_obj;
|
||||||
/*< public >*/
|
/*< public >*/
|
||||||
|
|
||||||
|
bool pci_hole64_fix;
|
||||||
MCHPCIState mch;
|
MCHPCIState mch;
|
||||||
} Q35PCIHost;
|
} Q35PCIHost;
|
||||||
|
|
||||||
|
21
numa.c
21
numa.c
@ -216,6 +216,7 @@ static void parse_numa_node(MachineState *ms, NumaNodeOptions *node,
|
|||||||
}
|
}
|
||||||
numa_info[nodenr].present = true;
|
numa_info[nodenr].present = true;
|
||||||
max_numa_nodeid = MAX(max_numa_nodeid, nodenr + 1);
|
max_numa_nodeid = MAX(max_numa_nodeid, nodenr + 1);
|
||||||
|
nb_numa_nodes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parse_numa_distance(NumaDistOptions *dist, Error **errp)
|
static void parse_numa_distance(NumaDistOptions *dist, Error **errp)
|
||||||
@ -282,7 +283,6 @@ static int parse_numa(void *opaque, QemuOpts *opts, Error **errp)
|
|||||||
if (err) {
|
if (err) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
nb_numa_nodes++;
|
|
||||||
break;
|
break;
|
||||||
case NUMA_OPTIONS_TYPE_DIST:
|
case NUMA_OPTIONS_TYPE_DIST:
|
||||||
parse_numa_distance(&object->u.dist, &err);
|
parse_numa_distance(&object->u.dist, &err);
|
||||||
@ -433,6 +433,25 @@ void parse_numa_opts(MachineState *ms)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If memory hotplug is enabled (slots > 0) but without '-numa'
|
||||||
|
* options explicitly on CLI, guestes will break.
|
||||||
|
*
|
||||||
|
* Windows: won't enable memory hotplug without SRAT table at all
|
||||||
|
*
|
||||||
|
* Linux: if QEMU is started with initial memory all below 4Gb
|
||||||
|
* and no SRAT table present, guest kernel will use nommu DMA ops,
|
||||||
|
* which breaks 32bit hw drivers when memory is hotplugged and
|
||||||
|
* guest tries to use it with that drivers.
|
||||||
|
*
|
||||||
|
* Enable NUMA implicitly by adding a new NUMA node automatically.
|
||||||
|
*/
|
||||||
|
if (ms->ram_slots > 0 && nb_numa_nodes == 0 &&
|
||||||
|
mc->auto_enable_numa_with_memhp) {
|
||||||
|
NumaNodeOptions node = { };
|
||||||
|
parse_numa_node(ms, &node, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
assert(max_numa_nodeid <= MAX_NODES);
|
assert(max_numa_nodeid <= MAX_NODES);
|
||||||
|
|
||||||
/* No support for sparse NUMA node IDs yet: */
|
/* No support for sparse NUMA node IDs yet: */
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -28,24 +28,9 @@ typedef struct {
|
|||||||
bool tmp_files_retain; /* do not delete the temp asl/aml */
|
bool tmp_files_retain; /* do not delete the temp asl/aml */
|
||||||
} AcpiSdtTable;
|
} AcpiSdtTable;
|
||||||
|
|
||||||
#define ACPI_READ_FIELD(field, addr) \
|
#define ACPI_READ_FIELD(field, addr) \
|
||||||
do { \
|
do { \
|
||||||
switch (sizeof(field)) { \
|
memread(addr, &field, sizeof(field)); \
|
||||||
case 1: \
|
|
||||||
field = readb(addr); \
|
|
||||||
break; \
|
|
||||||
case 2: \
|
|
||||||
field = readw(addr); \
|
|
||||||
break; \
|
|
||||||
case 4: \
|
|
||||||
field = readl(addr); \
|
|
||||||
break; \
|
|
||||||
case 8: \
|
|
||||||
field = readq(addr); \
|
|
||||||
break; \
|
|
||||||
default: \
|
|
||||||
g_assert(false); \
|
|
||||||
} \
|
|
||||||
addr += sizeof(field); \
|
addr += sizeof(field); \
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
@ -74,16 +59,14 @@ typedef struct {
|
|||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
#define ACPI_ASSERT_CMP(actual, expected) do { \
|
#define ACPI_ASSERT_CMP(actual, expected) do { \
|
||||||
uint32_t ACPI_ASSERT_CMP_le = cpu_to_le32(actual); \
|
|
||||||
char ACPI_ASSERT_CMP_str[5] = {}; \
|
char ACPI_ASSERT_CMP_str[5] = {}; \
|
||||||
memcpy(ACPI_ASSERT_CMP_str, &ACPI_ASSERT_CMP_le, 4); \
|
memcpy(ACPI_ASSERT_CMP_str, &actual, 4); \
|
||||||
g_assert_cmpstr(ACPI_ASSERT_CMP_str, ==, expected); \
|
g_assert_cmpstr(ACPI_ASSERT_CMP_str, ==, expected); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define ACPI_ASSERT_CMP64(actual, expected) do { \
|
#define ACPI_ASSERT_CMP64(actual, expected) do { \
|
||||||
uint64_t ACPI_ASSERT_CMP_le = cpu_to_le64(actual); \
|
|
||||||
char ACPI_ASSERT_CMP_str[9] = {}; \
|
char ACPI_ASSERT_CMP_str[9] = {}; \
|
||||||
memcpy(ACPI_ASSERT_CMP_str, &ACPI_ASSERT_CMP_le, 8); \
|
memcpy(ACPI_ASSERT_CMP_str, &actual, 8); \
|
||||||
g_assert_cmpstr(ACPI_ASSERT_CMP_str, ==, expected); \
|
g_assert_cmpstr(ACPI_ASSERT_CMP_str, ==, expected); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
@ -96,17 +96,20 @@ static void test_acpi_rsdp_table(test_data *data)
|
|||||||
static void test_acpi_rsdt_table(test_data *data)
|
static void test_acpi_rsdt_table(test_data *data)
|
||||||
{
|
{
|
||||||
AcpiRsdtDescriptorRev1 *rsdt_table = &data->rsdt_table;
|
AcpiRsdtDescriptorRev1 *rsdt_table = &data->rsdt_table;
|
||||||
uint32_t addr = data->rsdp_table.rsdt_physical_address;
|
uint32_t addr = le32_to_cpu(data->rsdp_table.rsdt_physical_address);
|
||||||
uint32_t *tables;
|
uint32_t *tables;
|
||||||
int tables_nr;
|
int tables_nr;
|
||||||
uint8_t checksum;
|
uint8_t checksum;
|
||||||
|
uint32_t rsdt_table_length;
|
||||||
|
|
||||||
/* read the header */
|
/* read the header */
|
||||||
ACPI_READ_TABLE_HEADER(rsdt_table, addr);
|
ACPI_READ_TABLE_HEADER(rsdt_table, addr);
|
||||||
ACPI_ASSERT_CMP(rsdt_table->signature, "RSDT");
|
ACPI_ASSERT_CMP(rsdt_table->signature, "RSDT");
|
||||||
|
|
||||||
|
rsdt_table_length = le32_to_cpu(rsdt_table->length);
|
||||||
|
|
||||||
/* compute the table entries in rsdt */
|
/* compute the table entries in rsdt */
|
||||||
tables_nr = (rsdt_table->length - sizeof(AcpiRsdtDescriptorRev1)) /
|
tables_nr = (rsdt_table_length - sizeof(AcpiRsdtDescriptorRev1)) /
|
||||||
sizeof(uint32_t);
|
sizeof(uint32_t);
|
||||||
g_assert(tables_nr > 0);
|
g_assert(tables_nr > 0);
|
||||||
|
|
||||||
@ -114,7 +117,7 @@ static void test_acpi_rsdt_table(test_data *data)
|
|||||||
tables = g_new0(uint32_t, tables_nr);
|
tables = g_new0(uint32_t, tables_nr);
|
||||||
ACPI_READ_ARRAY_PTR(tables, tables_nr, addr);
|
ACPI_READ_ARRAY_PTR(tables, tables_nr, addr);
|
||||||
|
|
||||||
checksum = acpi_calc_checksum((uint8_t *)rsdt_table, rsdt_table->length) +
|
checksum = acpi_calc_checksum((uint8_t *)rsdt_table, rsdt_table_length) +
|
||||||
acpi_calc_checksum((uint8_t *)tables,
|
acpi_calc_checksum((uint8_t *)tables,
|
||||||
tables_nr * sizeof(uint32_t));
|
tables_nr * sizeof(uint32_t));
|
||||||
g_assert(!checksum);
|
g_assert(!checksum);
|
||||||
@ -130,7 +133,7 @@ static void test_acpi_fadt_table(test_data *data)
|
|||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
|
|
||||||
/* FADT table comes first */
|
/* FADT table comes first */
|
||||||
addr = data->rsdt_tables_addr[0];
|
addr = le32_to_cpu(data->rsdt_tables_addr[0]);
|
||||||
ACPI_READ_TABLE_HEADER(fadt_table, addr);
|
ACPI_READ_TABLE_HEADER(fadt_table, addr);
|
||||||
|
|
||||||
ACPI_READ_FIELD(fadt_table->firmware_ctrl, addr);
|
ACPI_READ_FIELD(fadt_table->firmware_ctrl, addr);
|
||||||
@ -187,13 +190,14 @@ static void test_acpi_fadt_table(test_data *data)
|
|||||||
ACPI_READ_GENERIC_ADDRESS(fadt_table->xgpe1_block, addr);
|
ACPI_READ_GENERIC_ADDRESS(fadt_table->xgpe1_block, addr);
|
||||||
|
|
||||||
ACPI_ASSERT_CMP(fadt_table->signature, "FACP");
|
ACPI_ASSERT_CMP(fadt_table->signature, "FACP");
|
||||||
g_assert(!acpi_calc_checksum((uint8_t *)fadt_table, fadt_table->length));
|
g_assert(!acpi_calc_checksum((uint8_t *)fadt_table,
|
||||||
|
le32_to_cpu(fadt_table->length)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_acpi_facs_table(test_data *data)
|
static void test_acpi_facs_table(test_data *data)
|
||||||
{
|
{
|
||||||
AcpiFacsDescriptorRev1 *facs_table = &data->facs_table;
|
AcpiFacsDescriptorRev1 *facs_table = &data->facs_table;
|
||||||
uint32_t addr = data->fadt_table.firmware_ctrl;
|
uint32_t addr = le32_to_cpu(data->fadt_table.firmware_ctrl);
|
||||||
|
|
||||||
ACPI_READ_FIELD(facs_table->signature, addr);
|
ACPI_READ_FIELD(facs_table->signature, addr);
|
||||||
ACPI_READ_FIELD(facs_table->length, addr);
|
ACPI_READ_FIELD(facs_table->length, addr);
|
||||||
@ -212,7 +216,8 @@ static void test_dst_table(AcpiSdtTable *sdt_table, uint32_t addr)
|
|||||||
|
|
||||||
ACPI_READ_TABLE_HEADER(&sdt_table->header, addr);
|
ACPI_READ_TABLE_HEADER(&sdt_table->header, addr);
|
||||||
|
|
||||||
sdt_table->aml_len = sdt_table->header.length - sizeof(AcpiTableHeader);
|
sdt_table->aml_len = le32_to_cpu(sdt_table->header.length)
|
||||||
|
- sizeof(AcpiTableHeader);
|
||||||
sdt_table->aml = g_malloc0(sdt_table->aml_len);
|
sdt_table->aml = g_malloc0(sdt_table->aml_len);
|
||||||
ACPI_READ_ARRAY_PTR(sdt_table->aml, sdt_table->aml_len, addr);
|
ACPI_READ_ARRAY_PTR(sdt_table->aml, sdt_table->aml_len, addr);
|
||||||
|
|
||||||
@ -226,7 +231,7 @@ static void test_dst_table(AcpiSdtTable *sdt_table, uint32_t addr)
|
|||||||
static void test_acpi_dsdt_table(test_data *data)
|
static void test_acpi_dsdt_table(test_data *data)
|
||||||
{
|
{
|
||||||
AcpiSdtTable dsdt_table;
|
AcpiSdtTable dsdt_table;
|
||||||
uint32_t addr = data->fadt_table.dsdt;
|
uint32_t addr = le32_to_cpu(data->fadt_table.dsdt);
|
||||||
|
|
||||||
memset(&dsdt_table, 0, sizeof(dsdt_table));
|
memset(&dsdt_table, 0, sizeof(dsdt_table));
|
||||||
data->tables = g_array_new(false, true, sizeof(AcpiSdtTable));
|
data->tables = g_array_new(false, true, sizeof(AcpiSdtTable));
|
||||||
@ -245,9 +250,10 @@ static void test_acpi_tables(test_data *data)
|
|||||||
|
|
||||||
for (i = 0; i < tables_nr; i++) {
|
for (i = 0; i < tables_nr; i++) {
|
||||||
AcpiSdtTable ssdt_table;
|
AcpiSdtTable ssdt_table;
|
||||||
|
uint32_t addr;
|
||||||
|
|
||||||
memset(&ssdt_table, 0, sizeof(ssdt_table));
|
memset(&ssdt_table, 0, sizeof(ssdt_table));
|
||||||
uint32_t addr = data->rsdt_tables_addr[i + 1]; /* fadt is first */
|
addr = le32_to_cpu(data->rsdt_tables_addr[i + 1]); /* fadt is first */
|
||||||
test_dst_table(&ssdt_table, addr);
|
test_dst_table(&ssdt_table, addr);
|
||||||
g_array_append_val(data->tables, ssdt_table);
|
g_array_append_val(data->tables, ssdt_table);
|
||||||
}
|
}
|
||||||
@ -268,9 +274,8 @@ static void dump_aml_files(test_data *data, bool rebuild)
|
|||||||
g_assert(sdt->aml);
|
g_assert(sdt->aml);
|
||||||
|
|
||||||
if (rebuild) {
|
if (rebuild) {
|
||||||
uint32_t signature = cpu_to_le32(sdt->header.signature);
|
|
||||||
aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine,
|
aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine,
|
||||||
(gchar *)&signature, ext);
|
(gchar *)&sdt->header.signature, ext);
|
||||||
fd = g_open(aml_file, O_WRONLY|O_TRUNC|O_CREAT,
|
fd = g_open(aml_file, O_WRONLY|O_TRUNC|O_CREAT,
|
||||||
S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
|
S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
|
||||||
} else {
|
} else {
|
||||||
@ -381,7 +386,6 @@ static GArray *load_expected_aml(test_data *data)
|
|||||||
GArray *exp_tables = g_array_new(false, true, sizeof(AcpiSdtTable));
|
GArray *exp_tables = g_array_new(false, true, sizeof(AcpiSdtTable));
|
||||||
for (i = 0; i < data->tables->len; ++i) {
|
for (i = 0; i < data->tables->len; ++i) {
|
||||||
AcpiSdtTable exp_sdt;
|
AcpiSdtTable exp_sdt;
|
||||||
uint32_t signature;
|
|
||||||
gchar *aml_file = NULL;
|
gchar *aml_file = NULL;
|
||||||
const char *ext = data->variant ? data->variant : "";
|
const char *ext = data->variant ? data->variant : "";
|
||||||
|
|
||||||
@ -390,11 +394,9 @@ static GArray *load_expected_aml(test_data *data)
|
|||||||
memset(&exp_sdt, 0, sizeof(exp_sdt));
|
memset(&exp_sdt, 0, sizeof(exp_sdt));
|
||||||
exp_sdt.header.signature = sdt->header.signature;
|
exp_sdt.header.signature = sdt->header.signature;
|
||||||
|
|
||||||
signature = cpu_to_le32(sdt->header.signature);
|
|
||||||
|
|
||||||
try_again:
|
try_again:
|
||||||
aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine,
|
aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine,
|
||||||
(gchar *)&signature, ext);
|
(gchar *)&sdt->header.signature, ext);
|
||||||
if (getenv("V")) {
|
if (getenv("V")) {
|
||||||
fprintf(stderr, "\nLooking for expected file '%s'\n", aml_file);
|
fprintf(stderr, "\nLooking for expected file '%s'\n", aml_file);
|
||||||
}
|
}
|
||||||
@ -571,12 +573,12 @@ static void test_smbios_structs(test_data *data)
|
|||||||
{
|
{
|
||||||
DECLARE_BITMAP(struct_bitmap, SMBIOS_MAX_TYPE+1) = { 0 };
|
DECLARE_BITMAP(struct_bitmap, SMBIOS_MAX_TYPE+1) = { 0 };
|
||||||
struct smbios_21_entry_point *ep_table = &data->smbios_ep_table;
|
struct smbios_21_entry_point *ep_table = &data->smbios_ep_table;
|
||||||
uint32_t addr = ep_table->structure_table_address;
|
uint32_t addr = le32_to_cpu(ep_table->structure_table_address);
|
||||||
int i, len, max_len = 0;
|
int i, len, max_len = 0;
|
||||||
uint8_t type, prv, crt;
|
uint8_t type, prv, crt;
|
||||||
|
|
||||||
/* walk the smbios tables */
|
/* walk the smbios tables */
|
||||||
for (i = 0; i < ep_table->number_of_structures; i++) {
|
for (i = 0; i < le16_to_cpu(ep_table->number_of_structures); i++) {
|
||||||
|
|
||||||
/* grab type and formatted area length from struct header */
|
/* grab type and formatted area length from struct header */
|
||||||
type = readb(addr);
|
type = readb(addr);
|
||||||
@ -608,9 +610,9 @@ static void test_smbios_structs(test_data *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* total table length and max struct size must match entry point values */
|
/* total table length and max struct size must match entry point values */
|
||||||
g_assert_cmpuint(ep_table->structure_table_length, ==,
|
g_assert_cmpuint(le16_to_cpu(ep_table->structure_table_length), ==,
|
||||||
addr - ep_table->structure_table_address);
|
addr - le32_to_cpu(ep_table->structure_table_address));
|
||||||
g_assert_cmpuint(ep_table->max_structure_size, ==, max_len);
|
g_assert_cmpuint(le16_to_cpu(ep_table->max_structure_size), ==, max_len);
|
||||||
|
|
||||||
/* required struct types must all be present */
|
/* required struct types must all be present */
|
||||||
for (i = 0; i < data->required_struct_types_len; i++) {
|
for (i = 0; i < data->required_struct_types_len; i++) {
|
||||||
|
@ -38,7 +38,7 @@ static uint32_t acpi_find_vgia(void)
|
|||||||
uint32_t rsdp_offset;
|
uint32_t rsdp_offset;
|
||||||
uint32_t guid_offset = 0;
|
uint32_t guid_offset = 0;
|
||||||
AcpiRsdpDescriptor rsdp_table;
|
AcpiRsdpDescriptor rsdp_table;
|
||||||
uint32_t rsdt;
|
uint32_t rsdt, rsdt_table_length;
|
||||||
AcpiRsdtDescriptorRev1 rsdt_table;
|
AcpiRsdtDescriptorRev1 rsdt_table;
|
||||||
size_t tables_nr;
|
size_t tables_nr;
|
||||||
uint32_t *tables;
|
uint32_t *tables;
|
||||||
@ -56,14 +56,15 @@ static uint32_t acpi_find_vgia(void)
|
|||||||
|
|
||||||
acpi_parse_rsdp_table(rsdp_offset, &rsdp_table);
|
acpi_parse_rsdp_table(rsdp_offset, &rsdp_table);
|
||||||
|
|
||||||
rsdt = rsdp_table.rsdt_physical_address;
|
rsdt = le32_to_cpu(rsdp_table.rsdt_physical_address);
|
||||||
/* read the header */
|
/* read the header */
|
||||||
ACPI_READ_TABLE_HEADER(&rsdt_table, rsdt);
|
ACPI_READ_TABLE_HEADER(&rsdt_table, rsdt);
|
||||||
ACPI_ASSERT_CMP(rsdt_table.signature, "RSDT");
|
ACPI_ASSERT_CMP(rsdt_table.signature, "RSDT");
|
||||||
|
rsdt_table_length = le32_to_cpu(rsdt_table.length);
|
||||||
|
|
||||||
/* compute the table entries in rsdt */
|
/* compute the table entries in rsdt */
|
||||||
g_assert_cmpint(rsdt_table.length, >, sizeof(AcpiRsdtDescriptorRev1));
|
g_assert_cmpint(rsdt_table_length, >, sizeof(AcpiRsdtDescriptorRev1));
|
||||||
tables_nr = (rsdt_table.length - sizeof(AcpiRsdtDescriptorRev1)) /
|
tables_nr = (rsdt_table_length - sizeof(AcpiRsdtDescriptorRev1)) /
|
||||||
sizeof(uint32_t);
|
sizeof(uint32_t);
|
||||||
|
|
||||||
/* get the addresses of the tables pointed by rsdt */
|
/* get the addresses of the tables pointed by rsdt */
|
||||||
@ -71,23 +72,24 @@ static uint32_t acpi_find_vgia(void)
|
|||||||
ACPI_READ_ARRAY_PTR(tables, tables_nr, rsdt);
|
ACPI_READ_ARRAY_PTR(tables, tables_nr, rsdt);
|
||||||
|
|
||||||
for (i = 0; i < tables_nr; i++) {
|
for (i = 0; i < tables_nr; i++) {
|
||||||
ACPI_READ_TABLE_HEADER(&ssdt_table, tables[i]);
|
uint32_t addr = le32_to_cpu(tables[i]);
|
||||||
|
ACPI_READ_TABLE_HEADER(&ssdt_table, addr);
|
||||||
if (!strncmp((char *)ssdt_table.oem_table_id, "VMGENID", 7)) {
|
if (!strncmp((char *)ssdt_table.oem_table_id, "VMGENID", 7)) {
|
||||||
/* the first entry in the table should be VGIA
|
/* the first entry in the table should be VGIA
|
||||||
* That's all we need
|
* That's all we need
|
||||||
*/
|
*/
|
||||||
ACPI_READ_FIELD(vgid_table.name_op, tables[i]);
|
ACPI_READ_FIELD(vgid_table.name_op, addr);
|
||||||
g_assert(vgid_table.name_op == 0x08); /* name */
|
g_assert(vgid_table.name_op == 0x08); /* name */
|
||||||
ACPI_READ_ARRAY(vgid_table.vgia, tables[i]);
|
ACPI_READ_ARRAY(vgid_table.vgia, addr);
|
||||||
g_assert(memcmp(vgid_table.vgia, "VGIA", 4) == 0);
|
g_assert(memcmp(vgid_table.vgia, "VGIA", 4) == 0);
|
||||||
ACPI_READ_FIELD(vgid_table.val_op, tables[i]);
|
ACPI_READ_FIELD(vgid_table.val_op, addr);
|
||||||
g_assert(vgid_table.val_op == 0x0C); /* dword */
|
g_assert(vgid_table.val_op == 0x0C); /* dword */
|
||||||
ACPI_READ_FIELD(vgid_table.vgia_val, tables[i]);
|
ACPI_READ_FIELD(vgid_table.vgia_val, addr);
|
||||||
/* The GUID is written at a fixed offset into the fw_cfg file
|
/* The GUID is written at a fixed offset into the fw_cfg file
|
||||||
* in order to implement the "OVMF SDT Header probe suppressor"
|
* in order to implement the "OVMF SDT Header probe suppressor"
|
||||||
* see docs/specs/vmgenid.txt for more details
|
* see docs/specs/vmgenid.txt for more details
|
||||||
*/
|
*/
|
||||||
guid_offset = vgid_table.vgia_val + VMGENID_GUID_OFFSET;
|
guid_offset = le32_to_cpu(vgid_table.vgia_val) + VMGENID_GUID_OFFSET;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
3
vl.c
3
vl.c
@ -4690,8 +4690,6 @@ int main(int argc, char **argv, char **envp)
|
|||||||
default_drive(default_floppy, snapshot, IF_FLOPPY, 0, FD_OPTS);
|
default_drive(default_floppy, snapshot, IF_FLOPPY, 0, FD_OPTS);
|
||||||
default_drive(default_sdcard, snapshot, IF_SD, 0, SD_OPTS);
|
default_drive(default_sdcard, snapshot, IF_SD, 0, SD_OPTS);
|
||||||
|
|
||||||
parse_numa_opts(current_machine);
|
|
||||||
|
|
||||||
if (qemu_opts_foreach(qemu_find_opts("mon"),
|
if (qemu_opts_foreach(qemu_find_opts("mon"),
|
||||||
mon_init_func, NULL, NULL)) {
|
mon_init_func, NULL, NULL)) {
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -4741,6 +4739,7 @@ int main(int argc, char **argv, char **envp)
|
|||||||
current_machine->boot_order = boot_order;
|
current_machine->boot_order = boot_order;
|
||||||
current_machine->cpu_model = cpu_model;
|
current_machine->cpu_model = cpu_model;
|
||||||
|
|
||||||
|
parse_numa_opts(current_machine);
|
||||||
|
|
||||||
/* parse features once if machine provides default cpu_type */
|
/* parse features once if machine provides default cpu_type */
|
||||||
if (machine_class->default_cpu_type) {
|
if (machine_class->default_cpu_type) {
|
||||||
|
Loading…
Reference in New Issue
Block a user