Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into sta…
Browse files Browse the repository at this point in the history
…ging

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>
  • Loading branch information
pm215 committed Nov 16, 2017
2 parents afdad8b + 3831c07 commit b91f0f2
Show file tree
Hide file tree
Showing 31 changed files with 175 additions and 65 deletions.
2 changes: 2 additions & 0 deletions default-configs/arm-softmmu.mak
Expand Up @@ -130,3 +130,5 @@ CONFIG_SMBIOS=y
CONFIG_ASPEED_SOC=y
CONFIG_GPIO_KEY=y
CONFIG_MSF2=y

CONFIG_FW_CFG_DMA=y
1 change: 1 addition & 0 deletions default-configs/i386-softmmu.mak
Expand Up @@ -60,3 +60,4 @@ CONFIG_SMBIOS=y
CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM)
CONFIG_PXB=y
CONFIG_ACPI_VMGENID=y
CONFIG_FW_CFG_DMA=y
1 change: 1 addition & 0 deletions default-configs/x86_64-softmmu.mak
Expand Up @@ -60,3 +60,4 @@ CONFIG_SMBIOS=y
CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM)
CONFIG_PXB=y
CONFIG_ACPI_VMGENID=y
CONFIG_FW_CFG_DMA=y
23 changes: 23 additions & 0 deletions hw/i386/pc.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions hw/i386/pc_piix.c
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions hw/i386/pc_q35.c
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion hw/misc/Makefile.objs
Expand Up @@ -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

Expand Down
1 change: 1 addition & 0 deletions hw/misc/vmcoreinfo.c
Expand Up @@ -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 = {
Expand Down
4 changes: 2 additions & 2 deletions hw/pci-bridge/Makefile.objs
@@ -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
Expand Down
32 changes: 30 additions & 2 deletions hw/pci-host/piix.c
Expand Up @@ -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;

Expand Down Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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(),
};

Expand Down
42 changes: 39 additions & 3 deletions hw/pci-host/q35.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}

Expand All @@ -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(),
};

Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion hw/pci/pci.c
Expand Up @@ -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);
Expand All @@ -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);

Expand Down
1 change: 1 addition & 0 deletions hw/virtio/virtio.c
Expand Up @@ -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;
}

Expand Down
1 change: 1 addition & 0 deletions include/hw/boards.h
Expand Up @@ -197,6 +197,7 @@ struct MachineClass {
bool ignore_memory_transaction_failures;
int numa_mem_align_shift;
const char **valid_cpu_types;
bool auto_enable_numa_with_memhp;
void (*numa_auto_assign_ram)(MachineClass *mc, NodeInfo *nodes,
int nb_nodes, ram_addr_t size);

Expand Down
10 changes: 9 additions & 1 deletion include/hw/i386/pc.h
Expand Up @@ -238,7 +238,6 @@ void pc_guest_info_init(PCMachineState *pcms);
#define PCI_HOST_PROP_PCI_HOLE64_SIZE "pci-hole64-size"
#define PCI_HOST_BELOW_4G_MEM_SIZE "below-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,
Expand All @@ -249,6 +248,7 @@ void pc_memory_init(PCMachineState *pcms,
MemoryRegion *system_memory,
MemoryRegion *rom_memory,
MemoryRegion **ram_memory);
uint64_t pc_pci_hole64_start(void);
qemu_irq pc_allocate_cpu_irq(void);
DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus);
void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
Expand Down Expand Up @@ -375,6 +375,14 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
.driver = TYPE_X86_CPU,\
.property = "x-hv-max-vps",\
.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 \
Expand Down
1 change: 1 addition & 0 deletions include/hw/pci-host/q35.h
Expand Up @@ -68,6 +68,7 @@ typedef struct Q35PCIHost {
PCIExpressHost parent_obj;
/*< public >*/

bool pci_hole64_fix;
MCHPCIState mch;
} Q35PCIHost;

Expand Down
21 changes: 20 additions & 1 deletion numa.c
Expand Up @@ -216,6 +216,7 @@ static void parse_numa_node(MachineState *ms, NumaNodeOptions *node,
}
numa_info[nodenr].present = true;
max_numa_nodeid = MAX(max_numa_nodeid, nodenr + 1);
nb_numa_nodes++;
}

static void parse_numa_distance(NumaDistOptions *dist, Error **errp)
Expand Down Expand Up @@ -282,7 +283,6 @@ static int parse_numa(void *opaque, QemuOpts *opts, Error **errp)
if (err) {
goto end;
}
nb_numa_nodes++;
break;
case NUMA_OPTIONS_TYPE_DIST:
parse_numa_distance(&object->u.dist, &err);
Expand Down Expand Up @@ -433,6 +433,25 @@ void parse_numa_opts(MachineState *ms)
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);

/* No support for sparse NUMA node IDs yet: */
Expand Down
Binary file modified tests/acpi-test-data/pc/DSDT
Binary file not shown.
Binary file modified tests/acpi-test-data/pc/DSDT.bridge
Binary file not shown.
Binary file modified tests/acpi-test-data/pc/DSDT.cphp
Binary file not shown.
Binary file modified tests/acpi-test-data/pc/DSDT.ipmikcs
Binary file not shown.
Binary file modified tests/acpi-test-data/pc/DSDT.memhp
Binary file not shown.
Binary file modified tests/acpi-test-data/q35/DSDT
Binary file not shown.
Binary file modified tests/acpi-test-data/q35/DSDT.bridge
Binary file not shown.
Binary file modified tests/acpi-test-data/q35/DSDT.cphp
Binary file not shown.
Binary file modified tests/acpi-test-data/q35/DSDT.ipmibt
Binary file not shown.
Binary file modified tests/acpi-test-data/q35/DSDT.memhp
Binary file not shown.

0 comments on commit b91f0f2

Please sign in to comment.