mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-08 10:13:56 -06:00
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
31 changed files with 175 additions and 65 deletions
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
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->get_default_cpu_node_id = pc_get_default_cpu_node_id;
|
||||
mc->possible_cpu_arch_ids = pc_possible_cpu_arch_ids;
|
||||
mc->auto_enable_numa_with_memhp = true;
|
||||
mc->has_hotpluggable_cpus = true;
|
||||
mc->default_boot_order = "cad";
|
||||
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->alias = NULL;
|
||||
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,
|
||||
|
|
|
@ -318,6 +318,7 @@ static void pc_q35_2_10_machine_options(MachineClass *m)
|
|||
m->alias = NULL;
|
||||
SET_MACHINE_COMPAT(m, PC_COMPAT_2_10);
|
||||
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,
|
||||
|
|
|
@ -9,7 +9,7 @@ common-obj-$(CONFIG_PCI_TESTDEV) += pci-testdev.o
|
|||
common-obj-$(CONFIG_EDU) += edu.o
|
||||
|
||||
common-obj-y += unimp.o
|
||||
common-obj-y += vmcoreinfo.o
|
||||
common-obj-$(CONFIG_FW_CFG_DMA) += vmcoreinfo.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->realize = vmcoreinfo_realize;
|
||||
dc->hotpluggable = false;
|
||||
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
|
||||
}
|
||||
|
||||
static const TypeInfo vmcoreinfo_device_info = {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
common-obj-y += pci_bridge_dev.o pcie_pci_bridge.o
|
||||
common-obj-$(CONFIG_PCIE_PORT) += pcie_root_port.o gen_pcie_root_port.o
|
||||
common-obj-y += pci_bridge_dev.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_XIO3130) += xio3130_upstream.o xio3130_downstream.o
|
||||
common-obj-$(CONFIG_IOH3420) += ioh3420.o
|
||||
|
|
|
@ -50,6 +50,7 @@ typedef struct I440FXState {
|
|||
PCIHostState parent_obj;
|
||||
Range pci_hole;
|
||||
uint64_t pci_hole64_size;
|
||||
bool pci_hole64_fix;
|
||||
uint32_t short_root_bus;
|
||||
} I440FXState;
|
||||
|
||||
|
@ -112,6 +113,9 @@ struct PCII440FXState {
|
|||
#define I440FX_PAM_SIZE 7
|
||||
#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
|
||||
* 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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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,
|
||||
const char *name,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
PCIHostState *h = PCI_HOST_BRIDGE(obj);
|
||||
I440FXState *s = I440FX_PCI_HOST_BRIDGE(obj);
|
||||
Range w64;
|
||||
uint64_t value;
|
||||
|
||||
pci_bus_get_w64_range(h->bus, &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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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,
|
||||
const char *name, void *opaque,
|
||||
Error **errp)
|
||||
{
|
||||
PCIHostState *h = PCI_HOST_BRIDGE(obj);
|
||||
I440FXState *s = I440FX_PCI_HOST_BRIDGE(obj);
|
||||
uint64_t hole64_start = pc_pci_hole64_start();
|
||||
Range w64;
|
||||
uint64_t value;
|
||||
uint64_t value, hole64_end;
|
||||
|
||||
pci_bus_get_w64_range(h->bus, &w64);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -863,8 +890,9 @@ static const char *i440fx_pcihost_root_bus_path(PCIHostState *host_bridge,
|
|||
|
||||
static Property i440fx_props[] = {
|
||||
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_BOOL("x-pci-hole64-fix", I440FXState, pci_hole64_fix, true),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
* Q35 host
|
||||
*/
|
||||
|
||||
#define Q35_PCI_HOST_HOLE64_SIZE_DEFAULT (1ULL << 35)
|
||||
|
||||
static void q35_host_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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,
|
||||
const char *name, void *opaque,
|
||||
Error **errp)
|
||||
{
|
||||
PCIHostState *h = PCI_HOST_BRIDGE(obj);
|
||||
Q35PCIHost *s = Q35_HOST_DEVICE(obj);
|
||||
Range w64;
|
||||
uint64_t value;
|
||||
|
||||
pci_bus_get_w64_range(h->bus, &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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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,
|
||||
const char *name, void *opaque,
|
||||
Error **errp)
|
||||
{
|
||||
PCIHostState *h = PCI_HOST_BRIDGE(obj);
|
||||
Q35PCIHost *s = Q35_HOST_DEVICE(obj);
|
||||
uint64_t hole64_start = pc_pci_hole64_start();
|
||||
Range w64;
|
||||
uint64_t value;
|
||||
uint64_t value, hole64_end;
|
||||
|
||||
pci_bus_get_w64_range(h->bus, &w64);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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[] = {
|
||||
DEFINE_PROP_UINT64(PCIE_HOST_MCFG_BASE, Q35PCIHost, parent_obj.base_addr,
|
||||
MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT),
|
||||
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_SIZE(PCI_HOST_BELOW_4G_MEM_SIZE, Q35PCIHost,
|
||||
mch.below_4g_mem_size, 0),
|
||||
DEFINE_PROP_SIZE(PCI_HOST_ABOVE_4G_MEM_SIZE, Q35PCIHost,
|
||||
mch.above_4g_mem_size, 0),
|
||||
DEFINE_PROP_BOOL("x-pci-hole64-fix", Q35PCIHost, pci_hole64_fix, true),
|
||||
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);
|
||||
qdev_prop_set_int32(DEVICE(&s->mch), "addr", PCI_DEVFN(0, 0));
|
||||
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",
|
||||
q35_host_get_pci_hole_start,
|
||||
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->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),
|
||||
"bus master container", UINT64_MAX);
|
||||
|
@ -1039,7 +1040,6 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
|
|||
if (qdev_hotplug) {
|
||||
pci_init_bus_master(pci_dev);
|
||||
}
|
||||
pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
|
||||
pci_dev->irq_state = 0;
|
||||
pci_config_alloc(pci_dev);
|
||||
|
||||
|
|
|
@ -2491,6 +2491,7 @@ static void virtio_device_realize(DeviceState *dev, Error **errp)
|
|||
virtio_bus_device_plugged(vdev, &err);
|
||||
if (err != NULL) {
|
||||
error_propagate(errp, err);
|
||||
vdc->unrealize(dev, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue