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

virtio, pci, pc: cleanups, features

stricter rules for acpi tables: we now fail
on any difference that isn't whitelisted.

vhost-scsi migration.

some cleanups all over the place

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

# gpg: Signature made Wed 05 Jun 2019 20:55:04 BST
# gpg:                using RSA key 281F0DB8D28D5469
# 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

* remotes/mst/tags/for_upstream:
  bios-tables-test: ignore identical binaries
  tests: acpi: add simple arm/virt testcase
  tests: add expected ACPI tables for arm/virt board
  bios-tables-test: list all tables that differ
  vhost-scsi: Allow user to enable migration
  vhost-scsi: Add VMState descriptor
  vhost-scsi: The vhost backend should be stopped when the VM is not running
  bios-tables-test: add diff allowed list
  vhost: fix memory leak in vhost_user_scsi_realize
  vhost: fix incorrect print type
  vhost: remove the dead code
  docs: smbios: remove family=x from type2 entry description
  pci: Fold pci_get_bus_devfn() into its sole caller
  pci: Make is_bridge a bool
  pcie: Simplify pci_adjust_config_limit()
  acpi: pci: use build_append_foo() API to construct MCFG
  hw/acpi: Consolidate build_mcfg to pci.c

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Jun 6, 2019
2 parents 7ad5f33 + 7f36f09 commit 347a6f4
Show file tree
Hide file tree
Showing 37 changed files with 261 additions and 164 deletions.
1 change: 1 addition & 0 deletions default-configs/i386-softmmu.mak
Expand Up @@ -25,3 +25,4 @@
CONFIG_ISAPC=y
CONFIG_I440FX=y
CONFIG_Q35=y
CONFIG_ACPI_PCI=y
4 changes: 4 additions & 0 deletions hw/acpi/Kconfig
Expand Up @@ -23,6 +23,10 @@ config ACPI_NVDIMM
bool
depends on ACPI

config ACPI_PCI
bool
depends on ACPI && PCI

config ACPI_VMGENID
bool
default y
Expand Down
1 change: 1 addition & 0 deletions hw/acpi/Makefile.objs
Expand Up @@ -11,6 +11,7 @@ common-obj-$(call lnot,$(CONFIG_ACPI_X86)) += acpi-stub.o
common-obj-y += acpi_interface.o
common-obj-y += bios-linker-loader.o
common-obj-y += aml-build.o
common-obj-$(CONFIG_ACPI_PCI) += pci.o
common-obj-$(CONFIG_TPM) += tpm.o

common-obj-$(CONFIG_IPMI) += ipmi.o
Expand Down
61 changes: 61 additions & 0 deletions hw/acpi/pci.c
@@ -0,0 +1,61 @@
/*
* Support for generating PCI related ACPI tables and passing them to Guests
*
* Copyright (C) 2006 Fabrice Bellard
* Copyright (C) 2008-2010 Kevin O'Connor <kevin@koconnor.net>
* Copyright (C) 2013-2019 Red Hat Inc
* Copyright (C) 2019 Intel Corporation
*
* Author: Wei Yang <richardw.yang@linux.intel.com>
* Author: Michael S. Tsirkin <mst@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/

#include "qemu/osdep.h"
#include "hw/acpi/aml-build.h"
#include "hw/acpi/pci.h"
#include "hw/pci/pcie_host.h"

void build_mcfg(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info)
{
int mcfg_start = table_data->len;

/*
* PCI Firmware Specification, Revision 3.0
* 4.1.2 MCFG Table Description.
*/
acpi_data_push(table_data, sizeof(AcpiTableHeader));
/* Reserved */
build_append_int_noprefix(table_data, 0, 8);

/*
* Memory Mapped Enhanced Configuration Space Base Address Allocation
* Structure
*/
/* Base address, processor-relative */
build_append_int_noprefix(table_data, info->base, 8);
/* PCI segment group number */
build_append_int_noprefix(table_data, 0, 2);
/* Starting PCI Bus number */
build_append_int_noprefix(table_data, 0, 1);
/* Final PCI Bus number */
build_append_int_noprefix(table_data, PCIE_MMCFG_BUS(info->size - 1), 1);
/* Reserved */
build_append_int_noprefix(table_data, 0, 4);

build_header(linker, table_data, (void *)(table_data->data + mcfg_start),
"MCFG", table_data->len - mcfg_start, 1, NULL, NULL);
}

1 change: 1 addition & 0 deletions hw/arm/Kconfig
Expand Up @@ -19,6 +19,7 @@ config ARM_VIRT
select PLATFORM_BUS
select SMBIOS
select VIRTIO_MMIO
select ACPI_PCI

config CHEETAH
bool
Expand Down
17 changes: 0 additions & 17 deletions hw/arm/virt-acpi-build.c
Expand Up @@ -546,23 +546,6 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
"SRAT", table_data->len - srat_start, 3, NULL, NULL);
}

static void
build_mcfg(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info)
{
AcpiTableMcfg *mcfg;
int len = sizeof(*mcfg) + sizeof(mcfg->allocation[0]);

mcfg = acpi_data_push(table_data, len);
mcfg->allocation[0].address = cpu_to_le64(info->base);

/* Only a single allocation so no need to play with segments */
mcfg->allocation[0].pci_segment = cpu_to_le16(0);
mcfg->allocation[0].start_bus_number = 0;
mcfg->allocation[0].end_bus_number = PCIE_MMCFG_BUS(info->size - 1);

build_header(linker, table_data, (void *)mcfg, "MCFG", len, 1, NULL, NULL);
}

/* GTDT */
static void
build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
Expand Down
18 changes: 1 addition & 17 deletions hw/i386/acpi-build.c
Expand Up @@ -2405,22 +2405,6 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
table_data->len - srat_start, 1, NULL, NULL);
}

static void
build_mcfg_q35(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info)
{
AcpiTableMcfg *mcfg;
int len = sizeof(*mcfg) + 1 * sizeof(mcfg->allocation[0]);

mcfg = acpi_data_push(table_data, len);
mcfg->allocation[0].address = cpu_to_le64(info->base);
/* Only a single allocation so no need to play with segments */
mcfg->allocation[0].pci_segment = cpu_to_le16(0);
mcfg->allocation[0].start_bus_number = 0;
mcfg->allocation[0].end_bus_number = PCIE_MMCFG_BUS(info->size - 1);

build_header(linker, table_data, (void *)mcfg, "MCFG", len, 1, NULL, NULL);
}

/*
* VT-d spec 8.1 DMA Remapping Reporting Structure
* (version Oct. 2014 or later)
Expand Down Expand Up @@ -2690,7 +2674,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
}
if (acpi_get_mcfg(&mcfg)) {
acpi_add_table(table_offsets, tables_blob);
build_mcfg_q35(tables_blob, tables->linker, &mcfg);
build_mcfg(tables_blob, tables->linker, &mcfg);
}
if (x86_iommu_get_default()) {
IommuType IOMMUType = x86_iommu_get_type();
Expand Down
4 changes: 2 additions & 2 deletions hw/pci-bridge/dec.c
Expand Up @@ -68,7 +68,7 @@ static void dec_21154_pci_bridge_class_init(ObjectClass *klass, void *data)
k->vendor_id = PCI_VENDOR_ID_DEC;
k->device_id = PCI_DEVICE_ID_DEC_21154;
k->config_write = pci_bridge_write_config;
k->is_bridge = 1;
k->is_bridge = true;
dc->desc = "DEC 21154 PCI-PCI bridge";
dc->reset = pci_bridge_reset;
dc->vmsd = &vmstate_pci_device;
Expand Down Expand Up @@ -129,7 +129,7 @@ static void dec_21154_pci_host_class_init(ObjectClass *klass, void *data)
k->device_id = PCI_DEVICE_ID_DEC_21154;
k->revision = 0x02;
k->class_id = PCI_CLASS_BRIDGE_PCI;
k->is_bridge = 1;
k->is_bridge = true;
/*
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
Expand Down
2 changes: 1 addition & 1 deletion hw/pci-bridge/i82801b11.c
Expand Up @@ -90,7 +90,7 @@ static void i82801b11_bridge_class_init(ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);

k->is_bridge = 1;
k->is_bridge = true;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82801BA_11;
k->revision = ICH9_D2P_A2_REVISION;
Expand Down
2 changes: 1 addition & 1 deletion hw/pci-bridge/pci_bridge_dev.c
Expand Up @@ -253,7 +253,7 @@ static void pci_bridge_dev_class_init(ObjectClass *klass, void *data)
k->vendor_id = PCI_VENDOR_ID_REDHAT;
k->device_id = PCI_DEVICE_ID_REDHAT_BRIDGE;
k->class_id = PCI_CLASS_BRIDGE_PCI;
k->is_bridge = 1,
k->is_bridge = true;
dc->desc = "Standard PCI Bridge";
dc->reset = qdev_pci_bridge_dev_reset;
dc->props = pci_bridge_dev_properties;
Expand Down
2 changes: 1 addition & 1 deletion hw/pci-bridge/pcie_pci_bridge.c
Expand Up @@ -143,7 +143,7 @@ static void pcie_pci_bridge_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);

k->is_bridge = 1;
k->is_bridge = true;
k->vendor_id = PCI_VENDOR_ID_REDHAT;
k->device_id = PCI_DEVICE_ID_REDHAT_PCIE_BRIDGE;
k->realize = pcie_pci_bridge_realize;
Expand Down
2 changes: 1 addition & 1 deletion hw/pci-bridge/pcie_root_port.c
Expand Up @@ -162,7 +162,7 @@ static void rp_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

k->is_bridge = 1;
k->is_bridge = true;
k->config_write = rp_write_config;
k->realize = rp_realize;
k->exit = rp_exit;
Expand Down
2 changes: 1 addition & 1 deletion hw/pci-bridge/simba.c
Expand Up @@ -76,7 +76,7 @@ static void simba_pci_bridge_class_init(ObjectClass *klass, void *data)
k->device_id = PCI_DEVICE_ID_SUN_SIMBA;
k->revision = 0x11;
k->config_write = pci_bridge_write_config;
k->is_bridge = 1;
k->is_bridge = true;
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
dc->reset = pci_bridge_reset;
dc->vmsd = &vmstate_pci_device;
Expand Down
2 changes: 1 addition & 1 deletion hw/pci-bridge/xio3130_downstream.c
Expand Up @@ -152,7 +152,7 @@ static void xio3130_downstream_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

k->is_bridge = 1;
k->is_bridge = true;
k->config_write = xio3130_downstream_write_config;
k->realize = xio3130_downstream_realize;
k->exit = xio3130_downstream_exitfn;
Expand Down
2 changes: 1 addition & 1 deletion hw/pci-bridge/xio3130_upstream.c
Expand Up @@ -126,7 +126,7 @@ static void xio3130_upstream_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

k->is_bridge = 1;
k->is_bridge = true;
k->config_write = xio3130_upstream_write_config;
k->realize = xio3130_upstream_realize;
k->exit = xio3130_upstream_exitfn;
Expand Down
101 changes: 51 additions & 50 deletions hw/pci/pci.c
Expand Up @@ -120,6 +120,27 @@ static void pci_bus_realize(BusState *qbus, Error **errp)
vmstate_register(NULL, -1, &vmstate_pcibus, bus);
}

static void pcie_bus_realize(BusState *qbus, Error **errp)
{
PCIBus *bus = PCI_BUS(qbus);

pci_bus_realize(qbus, errp);

/*
* A PCI-E bus can support extended config space if it's the root
* bus, or if the bus/bridge above it does as well
*/
if (pci_bus_is_root(bus)) {
bus->flags |= PCI_BUS_EXTENDED_CONFIG_SPACE;
} else {
PCIBus *parent_bus = pci_get_bus(bus->parent_dev);

if (pci_bus_allows_extended_config_space(parent_bus)) {
bus->flags |= PCI_BUS_EXTENDED_CONFIG_SPACE;
}
}
}

static void pci_bus_unrealize(BusState *qbus, Error **errp)
{
PCIBus *bus = PCI_BUS(qbus);
Expand All @@ -142,11 +163,6 @@ static uint16_t pcibus_numa_node(PCIBus *bus)
return NUMA_NODE_UNASSIGNED;
}

static bool pcibus_allows_extended_config_space(PCIBus *bus)
{
return false;
}

static void pci_bus_class_init(ObjectClass *klass, void *data)
{
BusClass *k = BUS_CLASS(klass);
Expand All @@ -161,7 +177,6 @@ static void pci_bus_class_init(ObjectClass *klass, void *data)

pbc->bus_num = pcibus_num;
pbc->numa_node = pcibus_numa_node;
pbc->allows_extended_config_space = pcibus_allows_extended_config_space;
}

static const TypeInfo pci_bus_info = {
Expand All @@ -182,16 +197,11 @@ static const TypeInfo conventional_pci_interface_info = {
.parent = TYPE_INTERFACE,
};

static bool pciebus_allows_extended_config_space(PCIBus *bus)
{
return true;
}

static void pcie_bus_class_init(ObjectClass *klass, void *data)
{
PCIBusClass *pbc = PCI_BUS_CLASS(klass);
BusClass *k = BUS_CLASS(klass);

pbc->allows_extended_config_space = pciebus_allows_extended_config_space;
k->realize = pcie_bus_realize;
}

static const TypeInfo pcie_bus_info = {
Expand Down Expand Up @@ -410,11 +420,6 @@ bool pci_bus_is_express(PCIBus *bus)
return object_dynamic_cast(OBJECT(bus), TYPE_PCIE_BUS);
}

bool pci_bus_allows_extended_config_space(PCIBus *bus)
{
return PCI_BUS_GET_CLASS(bus)->allows_extended_config_space(bus);
}

void pci_root_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
const char *name,
MemoryRegion *address_space_mem,
Expand Down Expand Up @@ -718,37 +723,6 @@ static int pci_parse_devaddr(const char *addr, int *domp, int *busp,
return 0;
}

static PCIBus *pci_get_bus_devfn(int *devfnp, PCIBus *root,
const char *devaddr)
{
int dom, bus;
unsigned slot;

if (!root) {
fprintf(stderr, "No primary PCI bus\n");
return NULL;
}

assert(!root->parent_dev);

if (!devaddr) {
*devfnp = -1;
return pci_find_bus_nr(root, 0);
}

if (pci_parse_devaddr(devaddr, &dom, &bus, &slot, NULL) < 0) {
return NULL;
}

if (dom != 0) {
fprintf(stderr, "No support for non-zero PCI domains\n");
return NULL;
}

*devfnp = PCI_DEVFN(slot, 0);
return pci_find_bus_nr(root, bus);
}

static void pci_init_cmask(PCIDevice *dev)
{
pci_set_word(dev->cmask + PCI_VENDOR_ID, 0xffff);
Expand Down Expand Up @@ -1890,6 +1864,8 @@ PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus,
DeviceState *dev;
int devfn;
int i;
int dom, busnr;
unsigned slot;

if (nd->model && !strcmp(nd->model, "virtio")) {
g_free(nd->model);
Expand Down Expand Up @@ -1923,7 +1899,32 @@ PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus,
exit(1);
}

bus = pci_get_bus_devfn(&devfn, rootbus, devaddr);
if (!rootbus) {
error_report("No primary PCI bus");
exit(1);
}

assert(!rootbus->parent_dev);

if (!devaddr) {
devfn = -1;
busnr = 0;
} else {
if (pci_parse_devaddr(devaddr, &dom, &busnr, &slot, NULL) < 0) {
error_report("Invalid PCI device address %s for device %s",
devaddr, nd->model);
exit(1);
}

if (dom != 0) {
error_report("No support for non-zero PCI domains");
exit(1);
}

devfn = PCI_DEVFN(slot, 0);
}

bus = pci_find_bus_nr(rootbus, busnr);
if (!bus) {
error_report("Invalid PCI device address %s for device %s",
devaddr, nd->model);
Expand Down

0 comments on commit 347a6f4

Please sign in to comment.