diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-02-02 11:03:37 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-02-02 11:03:37 +0000 |
commit | e905587b752a700644235fbbf6af6d21f0632616 (patch) | |
tree | c35ad97aebd1bd0fe114e87fad3cb9a9c191a071 | |
parent | 2d6752d38d8acda6aae674a72b72be05482a58eb (diff) | |
parent | 1b28762a333bd238611103e9ed2348d7af93b0db (diff) |
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
virtio, vhost, pci: fixes, features
generic pci root port support
disable shpc by default
safer version of ARRAY_SIZE and QEMU_BUILD_BUG_ON
fixes and cleanups all over the place
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
# gpg: Signature made Wed 01 Feb 2017 01:38:34 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: (22 commits)
arm: add trailing ; after MISMATCH_CHECK
arm: better stub version for MISMATCH_CHECK
hw/pci: disable pci-bridge's shpc by default
vhost-user: delete chardev on cleanup
vhost: skip ROM sections
virtio: make virtio_should_notify static
pci: Convert msix_init() to Error and fix callers
hcd-xhci: check & correct param before using it
msix: Follow CODING_STYLE
hw/i386: check if nvdimm is enabled before plugging
hw/pcie: Introduce Generic PCI Express Root Port
hw/ioh3420: derive from PCI Express Root Port base class
hw/pcie: Introduce a base class for PCI Express Root Ports
intel_iommu: fix and simplify size calculation in process_device_iotlb_desc()
pci: mark ROMs read-only
ARRAY_SIZE: check that argument is an array
compiler: expression version of QEMU_BUILD_BUG_ON
compiler: rework BUG_ON using a struct
QEMU_BUILD_BUG_ON: use __COUNTER__
ppc: switch to constants within BUILD_BUG_ON
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34 files changed, 492 insertions, 221 deletions
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index 6de3e16a3e..6f2a180985 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -108,6 +108,7 @@ CONFIG_FSL_IMX25=y CONFIG_IMX_I2C=y +CONFIG_PCIE_PORT=y CONFIG_XIO3130=y CONFIG_IOH3420=y CONFIG_I82801B11=y diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak index 0b513602c8..9288838e32 100644 --- a/default-configs/i386-softmmu.mak +++ b/default-configs/i386-softmmu.mak @@ -51,6 +51,7 @@ CONFIG_PVPANIC=y CONFIG_MEM_HOTPLUG=y CONFIG_NVDIMM=y CONFIG_ACPI_NVDIMM=y +CONFIG_PCIE_PORT=y CONFIG_XIO3130=y CONFIG_IOH3420=y CONFIG_I82801B11=y diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak index 7f89503f95..7d2c2d4d3a 100644 --- a/default-configs/x86_64-softmmu.mak +++ b/default-configs/x86_64-softmmu.mak @@ -51,6 +51,7 @@ CONFIG_PVPANIC=y CONFIG_MEM_HOTPLUG=y CONFIG_NVDIMM=y CONFIG_ACPI_NVDIMM=y +CONFIG_PCIE_PORT=y CONFIG_XIO3130=y CONFIG_IOH3420=y CONFIG_I82801B11=y diff --git a/hw/block/nvme.c b/hw/block/nvme.c index d479fd22f5..ae91a18f17 100644 --- a/hw/block/nvme.c +++ b/hw/block/nvme.c @@ -872,7 +872,7 @@ static int nvme_init(PCIDevice *pci_dev) pci_register_bar(&n->parent_obj, 0, PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64, &n->iomem); - msix_init_exclusive_bar(&n->parent_obj, n->num_queues, 4); + msix_init_exclusive_bar(&n->parent_obj, n->num_queues, 4, NULL); id->vid = cpu_to_le16(pci_get_word(pci_conf + PCI_VENDOR_ID)); id->ssvid = cpu_to_le16(pci_get_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID)); diff --git a/hw/display/qxl.c b/hw/display/qxl.c index 62d0c80dcf..af4c0ca002 100644 --- a/hw/display/qxl.c +++ b/hw/display/qxl.c @@ -306,12 +306,11 @@ void qxl_spice_reset_cursor(PCIQXLDevice *qxl) static ram_addr_t qxl_rom_size(void) { - uint32_t required_rom_size = sizeof(QXLRom) + sizeof(QXLModes) + - sizeof(qxl_modes); - uint32_t rom_size = 8192; /* two pages */ +#define QXL_REQUIRED_SZ (sizeof(QXLRom) + sizeof(QXLModes) + sizeof(qxl_modes)) +#define QXL_ROM_SZ 8192 - QEMU_BUILD_BUG_ON(required_rom_size > rom_size); - return rom_size; + QEMU_BUILD_BUG_ON(QXL_REQUIRED_SZ > QXL_ROM_SZ); + return QXL_ROM_SZ; } static void init_qxl_rom(PCIQXLDevice *d) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index ec62239aba..3270fb9162 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -1485,8 +1485,16 @@ static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s, goto done; } + /* According to ATS spec table 2.4: + * S = 0, bits 15:12 = xxxx range size: 4K + * S = 1, bits 15:12 = xxx0 range size: 8K + * S = 1, bits 15:12 = xx01 range size: 16K + * S = 1, bits 15:12 = x011 range size: 32K + * S = 1, bits 15:12 = 0111 range size: 64K + * ... + */ if (size) { - sz = 1 << (ctz64(~(addr | (VTD_PAGE_MASK_4K - 1))) + 1); + sz = (VTD_PAGE_SIZE * 2) << cto64(addr >> VTD_PAGE_SHIFT); addr &= ~(sz - 1); } else { sz = VTD_PAGE_SIZE; diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 706e2330ac..e3fcd514dd 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1708,6 +1708,11 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev, } if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) { + if (!pcms->acpi_nvdimm_state.is_enabled) { + error_setg(&local_err, + "nvdimm is not enabled: missing 'nvdimm' in '-M'"); + goto out; + } nvdimm_plug(&pcms->acpi_nvdimm_state); } diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c index 846e903eb2..bf57e635d6 100644 --- a/hw/misc/ivshmem.c +++ b/hw/misc/ivshmem.c @@ -749,13 +749,13 @@ static void ivshmem_reset(DeviceState *d) } } -static int ivshmem_setup_interrupts(IVShmemState *s) +static int ivshmem_setup_interrupts(IVShmemState *s, Error **errp) { /* allocate QEMU callback data for receiving interrupts */ s->msi_vectors = g_malloc0(s->vectors * sizeof(MSIVector)); if (ivshmem_has_feature(s, IVSHMEM_MSI)) { - if (msix_init_exclusive_bar(PCI_DEVICE(s), s->vectors, 1)) { + if (msix_init_exclusive_bar(PCI_DEVICE(s), s->vectors, 1, errp)) { return -1; } @@ -898,8 +898,8 @@ static void ivshmem_common_realize(PCIDevice *dev, Error **errp) qemu_chr_fe_set_handlers(&s->server_chr, ivshmem_can_receive, ivshmem_read, NULL, s, NULL, true); - if (ivshmem_setup_interrupts(s) < 0) { - error_setg(errp, "failed to initialize interrupts"); + if (ivshmem_setup_interrupts(s, errp) < 0) { + error_prepend(errp, "Failed to initialize interrupts: "); return; } } diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c index 0e9a25b7ab..b0f429b8e5 100644 --- a/hw/net/e1000e.c +++ b/hw/net/e1000e.c @@ -292,7 +292,7 @@ e1000e_init_msix(E1000EState *s) E1000E_MSIX_IDX, E1000E_MSIX_TABLE, &s->msix, E1000E_MSIX_IDX, E1000E_MSIX_PBA, - 0xA0); + 0xA0, NULL); if (res < 0) { trace_e1000e_msix_init_fail(res); diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c index e9d215aa4d..6e70fddee3 100644 --- a/hw/net/rocker/rocker.c +++ b/hw/net/rocker/rocker.c @@ -1256,14 +1256,16 @@ static int rocker_msix_init(Rocker *r) { PCIDevice *dev = PCI_DEVICE(r); int err; + Error *local_err = NULL; err = msix_init(dev, ROCKER_MSIX_VEC_COUNT(r->fp_ports), &r->msix_bar, ROCKER_PCI_MSIX_BAR_IDX, ROCKER_PCI_MSIX_TABLE_OFFSET, &r->msix_bar, ROCKER_PCI_MSIX_BAR_IDX, ROCKER_PCI_MSIX_PBA_OFFSET, - 0); + 0, &local_err); if (err) { + error_report_err(local_err); return err; } diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 2cb2731e29..7dd456551c 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -2191,7 +2191,7 @@ vmxnet3_init_msix(VMXNET3State *s) VMXNET3_MSIX_BAR_IDX, VMXNET3_OFF_MSIX_TABLE, &s->msix_bar, VMXNET3_MSIX_BAR_IDX, VMXNET3_OFF_MSIX_PBA(s), - VMXNET3_MSIX_OFFSET(s)); + VMXNET3_MSIX_OFFSET(s), NULL); if (0 > res) { VMW_WRPRN("Failed to initialize MSI-X, error %d", res); diff --git a/hw/pci-bridge/Makefile.objs b/hw/pci-bridge/Makefile.objs index f2adfe348c..85e8e3990f 100644 --- a/hw/pci-bridge/Makefile.objs +++ b/hw/pci-bridge/Makefile.objs @@ -1,5 +1,6 @@ common-obj-y += pci_bridge_dev.o common-obj-y += pci_expander_bridge.o +common-obj-$(CONFIG_PCIE_PORT) += pcie_root_port.o gen_pcie_root_port.o common-obj-$(CONFIG_XIO3130) += xio3130_upstream.o xio3130_downstream.o common-obj-$(CONFIG_IOH3420) += ioh3420.o common-obj-$(CONFIG_I82801B11) += i82801b11.o diff --git a/hw/pci-bridge/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c new file mode 100644 index 0000000000..8ebffa8bb0 --- /dev/null +++ b/hw/pci-bridge/gen_pcie_root_port.c @@ -0,0 +1,87 @@ +/* + * Generic PCI Express Root Port emulation + * + * Copyright (C) 2017 Red Hat Inc + * + * Authors: + * Marcel Apfelbaum <marcel@redhat.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "hw/pci/msix.h" +#include "hw/pci/pcie_port.h" + +#define TYPE_GEN_PCIE_ROOT_PORT "pcie-root-port" + +#define GEN_PCIE_ROOT_PORT_AER_OFFSET 0x100 +#define GEN_PCIE_ROOT_PORT_MSIX_NR_VECTOR 1 + +static uint8_t gen_rp_aer_vector(const PCIDevice *d) +{ + return 0; +} + +static int gen_rp_interrupts_init(PCIDevice *d, Error **errp) +{ + int rc; + + rc = msix_init_exclusive_bar(d, GEN_PCIE_ROOT_PORT_MSIX_NR_VECTOR, 0, errp); + + if (rc < 0) { + assert(rc == -ENOTSUP); + } else { + msix_vector_use(d, 0); + } + + return rc; +} + +static void gen_rp_interrupts_uninit(PCIDevice *d) +{ + msix_uninit_exclusive_bar(d); +} + +static const VMStateDescription vmstate_rp_dev = { + .name = "pcie-root-port", + .version_id = 1, + .minimum_version_id = 1, + .post_load = pcie_cap_slot_post_load, + .fields = (VMStateField[]) { + VMSTATE_PCI_DEVICE(parent_obj.parent_obj.parent_obj, PCIESlot), + VMSTATE_STRUCT(parent_obj.parent_obj.parent_obj.exp.aer_log, + PCIESlot, 0, vmstate_pcie_aer_log, PCIEAERLog), + VMSTATE_END_OF_LIST() + } +}; + +static void gen_rp_dev_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + PCIERootPortClass *rpc = PCIE_ROOT_PORT_CLASS(klass); + + k->vendor_id = PCI_VENDOR_ID_REDHAT; + k->device_id = PCI_DEVICE_ID_REDHAT_PCIE_RP; + dc->desc = "PCI Express Root Port"; + dc->vmsd = &vmstate_rp_dev; + rpc->aer_vector = gen_rp_aer_vector; + rpc->interrupts_init = gen_rp_interrupts_init; + rpc->interrupts_uninit = gen_rp_interrupts_uninit; + rpc->aer_offset = GEN_PCIE_ROOT_PORT_AER_OFFSET; +} + +static const TypeInfo gen_rp_dev_info = { + .name = TYPE_GEN_PCIE_ROOT_PORT, + .parent = TYPE_PCIE_ROOT_PORT, + .class_init = gen_rp_dev_class_init, +}; + + static void gen_rp_register_types(void) + { + type_register_static(&gen_rp_dev_info); + } + type_init(gen_rp_register_types) diff --git a/hw/pci-bridge/ioh3420.c b/hw/pci-bridge/ioh3420.c index 0eef87a4f8..da4e5bdf04 100644 --- a/hw/pci-bridge/ioh3420.c +++ b/hw/pci-bridge/ioh3420.c @@ -61,119 +61,28 @@ static uint8_t ioh3420_aer_vector(const PCIDevice *d) return 0; } -static void ioh3420_aer_vector_update(PCIDevice *d) +static int ioh3420_interrupts_init(PCIDevice *d, Error **errp) { - pcie_aer_root_set_vector(d, ioh3420_aer_vector(d)); -} - -static void ioh3420_write_config(PCIDevice *d, - uint32_t address, uint32_t val, int len) -{ - uint32_t root_cmd = - pci_get_long(d->config + d->exp.aer_cap + PCI_ERR_ROOT_COMMAND); - - pci_bridge_write_config(d, address, val, len); - ioh3420_aer_vector_update(d); - pcie_cap_slot_write_config(d, address, val, len); - pcie_aer_write_config(d, address, val, len); - pcie_aer_root_write_config(d, address, val, len, root_cmd); -} - -static void ioh3420_reset(DeviceState *qdev) -{ - PCIDevice *d = PCI_DEVICE(qdev); - - ioh3420_aer_vector_update(d); - pcie_cap_root_reset(d); - pcie_cap_deverr_reset(d); - pcie_cap_slot_reset(d); - pcie_cap_arifwd_reset(d); - pcie_aer_root_reset(d); - pci_bridge_reset(qdev); - pci_bridge_disable_base_limit(d); -} - -static int ioh3420_initfn(PCIDevice *d) -{ - PCIEPort *p = PCIE_PORT(d); - PCIESlot *s = PCIE_SLOT(d); int rc; - Error *err = NULL; - - pci_config_set_interrupt_pin(d->config, 1); - pci_bridge_initfn(d, TYPE_PCIE_BUS); - pcie_port_init_reg(d); - - rc = pci_bridge_ssvid_init(d, IOH_EP_SSVID_OFFSET, - IOH_EP_SSVID_SVID, IOH_EP_SSVID_SSID); - if (rc < 0) { - goto err_bridge; - } + Error *local_err = NULL; rc = msi_init(d, IOH_EP_MSI_OFFSET, IOH_EP_MSI_NR_VECTOR, IOH_EP_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT, - IOH_EP_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT, &err); + IOH_EP_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT, + &local_err); if (rc < 0) { assert(rc == -ENOTSUP); - error_report_err(err); - goto err_bridge; + error_propagate(errp, local_err); } - rc = pcie_cap_init(d, IOH_EP_EXP_OFFSET, PCI_EXP_TYPE_ROOT_PORT, p->port); - if (rc < 0) { - goto err_msi; - } - - pcie_cap_arifwd_init(d); - pcie_cap_deverr_init(d); - pcie_cap_slot_init(d, s->slot); - pcie_cap_root_init(d); - - pcie_chassis_create(s->chassis); - rc = pcie_chassis_add_slot(s); - if (rc < 0) { - goto err_pcie_cap; - } - - rc = pcie_aer_init(d, PCI_ERR_VER, IOH_EP_AER_OFFSET, - PCI_ERR_SIZEOF, &err); - if (rc < 0) { - error_report_err(err); - goto err; - } - pcie_aer_root_init(d); - ioh3420_aer_vector_update(d); - - return 0; - -err: - pcie_chassis_del_slot(s); -err_pcie_cap: - pcie_cap_exit(d); -err_msi: - msi_uninit(d); -err_bridge: - pci_bridge_exitfn(d); return rc; } -static void ioh3420_exitfn(PCIDevice *d) +static void ioh3420_interrupts_uninit(PCIDevice *d) { - PCIESlot *s = PCIE_SLOT(d); - - pcie_aer_exit(d); - pcie_chassis_del_slot(s); - pcie_cap_exit(d); msi_uninit(d); - pci_bridge_exitfn(d); } -static Property ioh3420_props[] = { - DEFINE_PROP_BIT(COMPAT_PROP_PCP, PCIDevice, cap_present, - QEMU_PCIE_SLTCAP_PCP_BITNR, true), - DEFINE_PROP_END_OF_LIST() -}; - static const VMStateDescription vmstate_ioh3420 = { .name = "ioh-3240-express-root-port", .version_id = 1, @@ -191,25 +100,25 @@ static void ioh3420_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + PCIERootPortClass *rpc = PCIE_ROOT_PORT_CLASS(klass); - k->is_express = 1; - k->is_bridge = 1; - k->config_write = ioh3420_write_config; - k->init = ioh3420_initfn; - k->exit = ioh3420_exitfn; k->vendor_id = PCI_VENDOR_ID_INTEL; k->device_id = PCI_DEVICE_ID_IOH_EPORT; k->revision = PCI_DEVICE_ID_IOH_REV; - set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); dc->desc = "Intel IOH device id 3420 PCIE Root Port"; - dc->reset = ioh3420_reset; dc->vmsd = &vmstate_ioh3420; - dc->props = ioh3420_props; + rpc->aer_vector = ioh3420_aer_vector; + rpc->interrupts_init = ioh3420_interrupts_init; + rpc->interrupts_uninit = ioh3420_interrupts_uninit; + rpc->exp_offset = IOH_EP_EXP_OFFSET; + rpc->aer_offset = IOH_EP_AER_OFFSET; + rpc->ssvid_offset = IOH_EP_SSVID_OFFSET; + rpc->ssid = IOH_EP_SSVID_SSID; } static const TypeInfo ioh3420_info = { .name = "ioh3420", - .parent = TYPE_PCIE_SLOT, + .parent = TYPE_PCIE_ROOT_PORT, .class_init = ioh3420_class_init, }; diff --git a/hw/pci-bridge/pci_bridge_dev.c b/hw/pci-bridge/pci_bridge_dev.c index 5dbd933cc1..647ad80155 100644 --- a/hw/pci-bridge/pci_bridge_dev.c +++ b/hw/pci-bridge/pci_bridge_dev.c @@ -163,7 +163,7 @@ static Property pci_bridge_dev_properties[] = { DEFINE_PROP_ON_OFF_AUTO(PCI_BRIDGE_DEV_PROP_MSI, PCIBridgeDev, msi, ON_OFF_AUTO_AUTO), DEFINE_PROP_BIT(PCI_BRIDGE_DEV_PROP_SHPC, PCIBridgeDev, flags, - PCI_BRIDGE_DEV_F_SHPC_REQ, true), + PCI_BRIDGE_DEV_F_SHPC_REQ, false), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/pci-bridge/pcie_root_port.c b/hw/pci-bridge/pcie_root_port.c new file mode 100644 index 0000000000..cf3631806f --- /dev/null +++ b/hw/pci-bridge/pcie_root_port.c @@ -0,0 +1,171 @@ +/* + * Base class for PCI Express Root Ports + * + * Copyright (C) 2017 Red Hat Inc + * + * Authors: + * Marcel Apfelbaum <marcel@redhat.com> + * + * Most of the code was migrated from hw/pci-bridge/ioh3420. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "hw/pci/pcie_port.h" + +static void rp_aer_vector_update(PCIDevice *d) +{ + PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d); + + if (rpc->aer_vector) { + pcie_aer_root_set_vector(d, rpc->aer_vector(d)); + } +} + +static void rp_write_config(PCIDevice *d, uint32_t address, + uint32_t val, int len) +{ + uint32_t root_cmd = + pci_get_long(d->config + d->exp.aer_cap + PCI_ERR_ROOT_COMMAND); + + pci_bridge_write_config(d, address, val, len); + rp_aer_vector_update(d); + pcie_cap_slot_write_config(d, address, val, len); + pcie_aer_write_config(d, address, val, len); + pcie_aer_root_write_config(d, address, val, len, root_cmd); +} + +static void rp_reset(DeviceState *qdev) +{ + PCIDevice *d = PCI_DEVICE(qdev); + + rp_aer_vector_update(d); + pcie_cap_root_reset(d); + pcie_cap_deverr_reset(d); + pcie_cap_slot_reset(d); + pcie_cap_arifwd_reset(d); + pcie_aer_root_reset(d); + pci_bridge_reset(qdev); + pci_bridge_disable_base_limit(d); +} + +static void rp_realize(PCIDevice *d, Error **errp) +{ + PCIEPort *p = PCIE_PORT(d); + PCIESlot *s = PCIE_SLOT(d); + PCIDeviceClass *dc = PCI_DEVICE_GET_CLASS(d); + PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d); + int rc; + Error *local_err = NULL; + + pci_config_set_interrupt_pin(d->config, 1); + pci_bridge_initfn(d, TYPE_PCIE_BUS); + pcie_port_init_reg(d); + + rc = pci_bridge_ssvid_init(d, rpc->ssvid_offset, dc->vendor_id, rpc->ssid); + if (rc < 0) { + error_setg(errp, "Can't init SSV ID, error %d", rc); + goto err_bridge; + } + + if (rpc->interrupts_init) { + rc = rpc->interrupts_init(d, &local_err); + if (rc < 0) { + error_propagate(errp, local_err); + goto err_bridge; + } + } + + rc = pcie_cap_init(d, rpc->exp_offset, PCI_EXP_TYPE_ROOT_PORT, p->port); + if (rc < 0) { + error_setg(errp, "Can't add Root Port capability, error %d", rc); + goto err_int; + } + + pcie_cap_arifwd_init(d); + pcie_cap_deverr_init(d); + pcie_cap_slot_init(d, s->slot); + pcie_cap_root_init(d); + + pcie_chassis_create(s->chassis); + rc = pcie_chassis_add_slot(s); + if (rc < 0) { + error_setg(errp, "Can't add chassis slot, error %d", rc); + goto err_pcie_cap; + } + + rc = pcie_aer_init(d, PCI_ERR_VER, rpc->aer_offset, + PCI_ERR_SIZEOF, &local_err); + if (rc < 0) { + error_propagate(errp, local_err); + goto err; + } + pcie_aer_root_init(d); + rp_aer_vector_update(d); + + return; + +err: + pcie_chassis_del_slot(s); +err_pcie_cap: + pcie_cap_exit(d); +err_int: + if (rpc->interrupts_uninit) { + rpc->interrupts_uninit(d); + } +err_bridge: + pci_bridge_exitfn(d); +} + +static void rp_exit(PCIDevice *d) +{ + PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d); + PCIESlot *s = PCIE_SLOT(d); + + pcie_aer_exit(d); + pcie_chassis_del_slot(s); + pcie_cap_exit(d); + if (rpc->interrupts_uninit) { + rpc->interrupts_uninit(d); + } + pci_bridge_exitfn(d); +} + +static Property rp_props[] = { + DEFINE_PROP_BIT(COMPAT_PROP_PCP, PCIDevice, cap_present, + QEMU_PCIE_SLTCAP_PCP_BITNR, true), + DEFINE_PROP_END_OF_LIST() +}; + +static void rp_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + + k->is_express = 1; + k->is_bridge = 1; + k->config_write = rp_write_config; + k->realize = rp_realize; + k->exit = rp_exit; + set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); + dc->reset = rp_reset; + dc->props = rp_props; +} + +static const TypeInfo rp_info = { + .name = TYPE_PCIE_ROOT_PORT, + .parent = TYPE_PCIE_SLOT, + .class_init = rp_class_init, + .abstract = true, + .class_size = sizeof(PCIERootPortClass), +}; + +static void rp_register_types(void) +{ + type_register_static(&rp_info); +} + +type_init(rp_register_types) diff --git a/hw/pci/msix.c b/hw/pci/msix.c index ee1714d2cf..bb54e8b0ac 100644 --- a/hw/pci/msix.c +++ b/hw/pci/msix.c @@ -21,6 +21,7 @@ #include "hw/pci/pci.h" #include "hw/xen/xen.h" #include "qemu/range.h" +#include "qapi/error.h" #define MSIX_CAP_LENGTH 12 @@ -238,11 +239,31 @@ static void msix_mask_all(struct PCIDevice *dev, unsigned nentries) } } -/* Initialize the MSI-X structures */ +/* + * Make PCI device @dev MSI-X capable + * @nentries is the max number of MSI-X vectors that the device support. + * @table_bar is the MemoryRegion that MSI-X table structure resides. + * @table_bar_nr is number of base address register corresponding to @table_bar. + * @table_offset indicates the offset that the MSI-X table structure starts with + * in @table_bar. + * @pba_bar is the MemoryRegion that the Pending Bit Array structure resides. + * @pba_bar_nr is number of base address register corresponding to @pba_bar. + * @pba_offset indicates the offset that the Pending Bit Array structure + * starts with in @pba_bar. + * Non-zero @cap_pos puts capability MSI-X at that offset in PCI config space. + * @errp is for returning errors. + * + * Return 0 on success; set @errp and return -errno on error: + * -ENOTSUP means lacking msi support for a msi-capable platform. + * -EINVAL means capability overlap, happens when @cap_pos is non-zero, + * also means a programming error, except device assignment, which can check + * if a real HW is broken. + */ int msix_init(struct PCIDevice *dev, unsigned short nentries, MemoryRegion *table_bar, uint8_t table_bar_nr, unsigned table_offset, MemoryRegion *pba_bar, - uint8_t pba_bar_nr, unsigned pba_offset, uint8_t cap_pos) + uint8_t pba_bar_nr, unsigned pba_offset, uint8_t cap_pos, + Error **errp) { int cap; unsigned table_size, pba_size; @@ -250,10 +271,12 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries, /* Nothing to do if MSI is not supported by interrupt controller */ if (!msi_nonbroken) { + error_setg(errp, "MSI-X is not supported by interrupt controller"); return -ENOTSUP; } if (nentries < 1 || nentries > PCI_MSIX_FLAGS_QSIZE + 1) { + error_setg(errp, "The number of MSI-X vectors is invalid"); return -EINVAL; } @@ -266,10 +289,13 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries, table_offset + table_size > memory_region_size(table_bar) || pba_offset + pba_size > memory_region_size(pba_bar) || (table_offset | pba_offset) & PCI_MSIX_FLAGS_BIRMASK) { + error_setg(errp, "table & pba overlap, or they don't fit in BARs," + " or don't align"); return -EINVAL; } - cap = pci_add_capability(dev, PCI_CAP_ID_MSIX, cap_pos, MSIX_CAP_LENGTH); + cap = pci_add_capability2(dev, PCI_CAP_ID_MSIX, + cap_pos, MSIX_CAP_LENGTH, errp); if (cap < 0) { return cap; } @@ -306,7 +332,7 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries, } int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries, - uint8_t bar_nr) + uint8_t bar_nr, Error **errp) { int ret; char *name; @@ -338,7 +364,7 @@ int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries, ret = msix_init(dev, nentries, &dev->msix_exclusive_bar, bar_nr, 0, &dev->msix_exclusive_bar, bar_nr, bar_pba_offset, - 0); + 0, errp); if (ret) { return ret; } @@ -447,8 +473,10 @@ void msix_notify(PCIDevice *dev, unsigned vector) { MSIMessage msg; - if (vector >= dev->msix_entries_nr || !dev->msix_entry_used[vector]) + if (vector >= dev->msix_entries_nr || !dev->msix_entry_used[vector]) { return; + } + if (msix_is_masked(dev, vector)) { msix_set_pending(dev, vector); return; @@ -483,8 +511,10 @@ void msix_reset(PCIDevice *dev) /* Mark vector as used. */ int msix_vector_use(PCIDevice *dev, unsigned vector) { - if (vector >= dev->msix_entries_nr) + if (vector >= dev->msix_entries_nr) { return -EINVAL; + } + dev->msix_entry_used[vector]++; return 0; } diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 47ca3af69a..a563555e7d 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -2195,7 +2195,7 @@ static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom, snprintf(name, sizeof(name), "%s.rom", object_get_typename(OBJECT(pdev))); } pdev->has_rom = true; - memory_region_init_ram(&pdev->rom, OBJECT(pdev), name, size, &error_fatal); + memory_region_init_rom(&pdev->rom, OBJECT(pdev), name, size, &error_fatal); vmstate_register_ram(&pdev->rom, &pdev->qdev); ptr = memory_region_get_ram_ptr(&pdev->rom); load_image(path, ptr); diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index a642e663d4..45b7d99821 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2630,8 +2630,8 @@ static void spapr_phb_placement(sPAPRMachineState *spapr, uint32_t index, * 1TiB 64-bit MMIO windows for each PHB. */ const uint64_t base_buid = 0x800000020000000ULL; - const int max_phbs = - (SPAPR_PCI_LIMIT - SPAPR_PCI_BASE) / SPAPR_PCI_MEM64_WIN_SIZE - 1; +#define SPAPR_MAX_PHBS ((SPAPR_PCI_LIMIT - SPAPR_PCI_BASE) / \ + SPAPR_PCI_MEM64_WIN_SIZE - 1) int i; /* Sanity check natural alignments */ @@ -2640,12 +2640,14 @@ static void spapr_phb_placement(sPAPRMachineState *spapr, uint32_t index, QEMU_BUILD_BUG_ON((SPAPR_PCI_MEM64_WIN_SIZE % SPAPR_PCI_MEM32_WIN_SIZE) != 0); QEMU_BUILD_BUG_ON((SPAPR_PCI_MEM32_WIN_SIZE % SPAPR_PCI_IO_WIN_SIZE) != 0); /* Sanity check bounds */ - QEMU_BUILD_BUG_ON((max_phbs * SPAPR_PCI_IO_WIN_SIZE) > SPAPR_PCI_MEM32_WIN_SIZE); - QEMU_BUILD_BUG_ON((max_phbs * SPAPR_PCI_MEM32_WIN_SIZE) > SPAPR_PCI_MEM64_WIN_SIZE); - - if (index >= max_phbs) { - error_setg(errp, "\"index\" for PAPR PHB is too large (max %u)", - max_phbs - 1); + QEMU_BUILD_BUG_ON((SPAPR_MAX_PHBS * SPAPR_PCI_IO_WIN_SIZE) > + SPAPR_PCI_MEM32_WIN_SIZE); + QEMU_BUILD_BUG_ON((SPAPR_MAX_PHBS * SPAPR_PCI_MEM32_WIN_SIZE) > + SPAPR_PCI_MEM64_WIN_SIZE); + + if (index >= SPAPR_MAX_PHBS) { + error_setg(errp, "\"index\" for PAPR PHB is too large (max %llu)", + SPAPR_MAX_PHBS - 1); return; } diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c index 6aad7c9a06..1a8b04c6d7 100644 --- a/hw/scsi/megasas.c +++ b/hw/scsi/megasas.c @@ -2367,9 +2367,11 @@ static void megasas_scsi_realize(PCIDevice *dev, Error **errp) if (megasas_use_msix(s) && msix_init(dev, 15, &s->mmio_io, b->mmio_bar, 0x2000, - &s->mmio_io, b->mmio_bar, 0x3800, 0x68)) { + &s->mmio_io, b->mmio_bar, 0x3800, 0x68, NULL)) { + /* TODO: check msix_init's error, and should fail on msix=on */ s->msix = ON_OFF_AUTO_OFF; } + if (pci_is_express(dev)) { pcie_endpoint_cap_init(dev, 0xa0); } diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index e0b516987f..f8106789d8 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -3627,25 +3627,6 @@ static void usb_xhci_realize(struct PCIDevice *dev, Error **errp) dev->config[PCI_CACHE_LINE_SIZE] = 0x10; dev->config[0x60] = 0x30; /* release number */ - usb_xhci_init(xhci); - - if (xhci->msi != ON_OFF_AUTO_OFF) { - ret = msi_init(dev, 0x70, xhci->numintrs, true, false, &err); - /* Any error other than -ENOTSUP(board's MSI support is broken) - * is a programming error */ - assert(!ret || ret == -ENOTSUP); - if (ret && xhci->msi == ON_OFF_AUTO_ON) { - /* Can't satisfy user's explicit msi=on request, fail */ - error_append_hint(&err, "You have to use msi=auto (default) or " - "msi=off with this machine type.\n"); - error_propagate(errp, err); - return; - } - assert(!err || xhci->msi == ON_OFF_AUTO_AUTO); - /* With msi=auto, we fall back to MSI off silently */ - error_free(err); - } - if (xhci->numintrs > MAXINTRS) { xhci->numintrs = MAXINTRS; } @@ -3667,6 +3648,24 @@ static void usb_xhci_realize(struct PCIDevice *dev, Error **errp) xhci->max_pstreams_mask = 0; } + if (xhci->msi != ON_OFF_AUTO_OFF) { + ret = msi_init(dev, 0x70, xhci->numintrs, true, false, &err); + /* Any error other than -ENOTSUP(board's MSI support is broken) + * is a programming error */ + assert(!ret || ret == -ENOTSUP); + if (ret && xhci->msi == ON_OFF_AUTO_ON) { + /* Can't satisfy user's explicit msi=on request, fail */ + error_append_hint(&err, "You have to use msi=auto (default) or " + "msi=off with this machine type.\n"); + error_propagate(errp, err); + return; + } + assert(!err || xhci->msi == ON_OFF_AUTO_AUTO); + /* With msi=auto, we fall back to MSI off silently */ + error_free(err); + } + + usb_xhci_init(xhci); xhci->mfwrap_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, xhci_mfwrap_timer, xhci); memory_region_init(&xhci->mem, OBJECT(xhci), "xhci", LEN_REGS); @@ -3704,11 +3703,11 @@ static void usb_xhci_realize(struct PCIDevice *dev, Error **errp) } if (xhci->msix != ON_OFF_AUTO_OFF) { - /* TODO check for errors */ + /* TODO check for errors, and should fail when msix=on */ msix_init(dev, xhci->numintrs, &xhci->mem, 0, OFF_MSIX_TABLE, &xhci->mem, 0, OFF_MSIX_PBA, - 0x90); + 0x90, NULL); } } diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index 882d3a91b6..332f41d662 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -1432,6 +1432,7 @@ static void vfio_msix_early_setup(VFIOPCIDevice *vdev, Error **errp) static int vfio_msix_setup(VFIOPCIDevice *vdev, int pos, Error **errp) { int ret; + Error *err = NULL; vdev->msix->pending = g_malloc0(BITS_TO_LONGS(vdev->msix->entries) * sizeof(unsigned long)); @@ -1439,12 +1440,15 @@ static int vfio_msix_setup(VFIOPCIDevice *vdev, int pos, Error **errp) vdev->bars[vdev->msix->table_bar].region.mem, vdev->msix->table_bar, vdev->msix->table_offset, vdev->bars[vdev->msix->pba_bar].region.mem, - vdev->msix->pba_bar, vdev->msix->pba_offset, pos); + vdev->msix->pba_bar, vdev->msix->pba_offset, pos, + &err); if (ret < 0) { if (ret == -ENOTSUP) { + error_report_err(err); return 0; } - error_setg(errp, "msix_init failed"); + + error_propagate(errp, err); return ret; } diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index b124d97d7c..febe519bbd 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -612,7 +612,8 @@ static void vhost_set_memory(MemoryListener *listener, static bool vhost_section(MemoryRegionSection *section) { - return memory_region_is_ram(section->mr); + return memory_region_is_ram(section->mr) && + !memory_region_is_rom(section->mr); } static void vhost_begin(MemoryListener *listener) diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index b5af2a00f3..5ce42af9d4 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1686,9 +1686,9 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp) if (proxy->nvectors) { int err = msix_init_exclusive_bar(&proxy->pci_dev, proxy->nvectors, - proxy->msix_bar_idx); + proxy->msix_bar_idx, NULL); if (err) { - /* Notice when a system that supports MSIx can't initialize it. */ + /* Notice when a system that supports MSIx can't initialize it */ if (err != -ENOTSUP) { error_report("unable to init msix vectors to %" PRIu32, proxy->nvectors); diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index f292a53940..63657066e7 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -1383,7 +1383,7 @@ static void virtio_set_isr(VirtIODevice *vdev, int value) } } -bool virtio_should_notify(VirtIODevice *vdev, VirtQueue *vq) +static bool virtio_should_notify(VirtIODevice *vdev, VirtQueue *vq) { uint16_t old, new; bool v; diff --git a/include/hw/compat.h b/include/hw/compat.h index ee0dd1b5df..b7db43803c 100644 --- a/include/hw/compat.h +++ b/include/hw/compat.h @@ -14,6 +14,10 @@ .driver = "pflash_cfi01",\ .property = "old-multiple-chip-handling",\ .value = "on",\ + },{\ + .driver = "pci-bridge",\ + .property = "shpc",\ + .value = "on",\ }, #define HW_COMPAT_2_7 \ diff --git a/include/hw/pci/msix.h b/include/hw/pci/msix.h index 048a29dd2f..1f27658d35 100644 --- a/include/hw/pci/msix.h +++ b/include/hw/pci/msix.h @@ -9,9 +9,10 @@ MSIMessage msix_get_message(PCIDevice *dev, unsigned int vector); int msix_init(PCIDevice *dev, unsigned short nentries, MemoryRegion *table_bar, uint8_t table_bar_nr, unsigned table_offset, MemoryRegion *pba_bar, - uint8_t pba_bar_nr, unsigned pba_offset, uint8_t cap_pos); + uint8_t pba_bar_nr, unsigned pba_offset, uint8_t cap_pos, + Error **errp); int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries, - uint8_t bar_nr); + uint8_t bar_nr, Error **errp); void msix_write_config(PCIDevice *dev, uint32_t address, uint32_t val, int len); diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 772692f1b2..cbc1fdfb5b 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -96,6 +96,7 @@ #define PCI_DEVICE_ID_REDHAT_PXB 0x0009 #define PCI_DEVICE_ID_REDHAT_BRIDGE_SEAT 0x000a #define PCI_DEVICE_ID_REDHAT_PXB_PCIE 0x000b +#define PCI_DEVICE_ID_REDHAT_PCIE_RP 0x000c #define PCI_DEVICE_ID_REDHAT_QXL 0x0100 #define FMT_PCIBUS PRIx64 diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h index f7b64db00c..13332668e8 100644 --- a/include/hw/pci/pcie_port.h +++ b/include/hw/pci/pcie_port.h @@ -57,4 +57,23 @@ PCIESlot *pcie_chassis_find_slot(uint8_t chassis, uint16_t slot); int pcie_chassis_add_slot(struct PCIESlot *slot); void pcie_chassis_del_slot(PCIESlot *s); +#define TYPE_PCIE_ROOT_PORT "pcie-root-port-base" +#define PCIE_ROOT_PORT_CLASS(klass) \ + OBJECT_CLASS_CHECK(PCIERootPortClass, (klass), TYPE_PCIE_ROOT_PORT) +#define PCIE_ROOT_PORT_GET_CLASS(obj) \ + OBJECT_GET_CLASS(PCIERootPortClass, (obj), TYPE_PCIE_ROOT_PORT) + +typedef struct PCIERootPortClass { + PCIDeviceClass parent_class; + + uint8_t (*aer_vector)(const PCIDevice *dev); + int (*interrupts_init)(PCIDevice *dev, Error **errp); + void (*interrupts_uninit)(PCIDevice *dev); + + int exp_offset; + int aer_offset; + int ssvid_offset; + int ssid; +} PCIERootPortClass; + #endif /* QEMU_PCIE_PORT_H */ diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 6523bacd2f..525da24222 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -182,7 +182,6 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes, unsigned int *out_bytes, unsigned max_in_bytes, unsigned max_out_bytes); -bool virtio_should_notify(VirtIODevice *vdev, VirtQueue *vq); void virtio_notify_irqfd(VirtIODevice *vdev, VirtQueue *vq); void virtio_notify(VirtIODevice *vdev, VirtQueue *vq); diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h index 157698bfa9..e0ce9ffb28 100644 --- a/include/qemu/compiler.h +++ b/include/qemu/compiler.h @@ -85,8 +85,20 @@ #define typeof_field(type, field) typeof(((type *)0)->field) #define type_check(t1,t2) ((t1*)0 - (t2*)0) -#define QEMU_BUILD_BUG_ON(x) \ - typedef char glue(qemu_build_bug_on__,__LINE__)[(x)?-1:1] __attribute__((unused)); +#define QEMU_BUILD_BUG_ON_STRUCT(x) \ + struct { \ + int:(x) ? -1 : 1; \ + } + +#ifdef __COUNTER__ +#define QEMU_BUILD_BUG_ON(x) typedef QEMU_BUILD_BUG_ON_STRUCT(x) \ + glue(qemu_build_bug_on__, __COUNTER__) __attribute__((unused)) +#else +#define QEMU_BUILD_BUG_ON(x) +#endif + +#define QEMU_BUILD_BUG_ON_ZERO(x) (sizeof(QEMU_BUILD_BUG_ON_STRUCT(x)) - \ + sizeof(QEMU_BUILD_BUG_ON_STRUCT(x))) #if defined __GNUC__ # if !QEMU_GNUC_PREREQ(4, 4) diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index 689f253ea7..56c9e22405 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -198,8 +198,15 @@ extern int daemon(int, int); #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) #endif +/* + * &(x)[0] is always a pointer - if it's same type as x then the argument is a + * pointer, not an array. + */ +#define QEMU_IS_ARRAY(x) (!__builtin_types_compatible_p(typeof(x), \ + typeof(&(x)[0]))) #ifndef ARRAY_SIZE -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#define ARRAY_SIZE(x) ((sizeof(x) / sizeof((x)[0])) + \ + QEMU_BUILD_BUG_ON_ZERO(!QEMU_IS_ARRAY(x))) #endif int qemu_daemon(int nochdir, int noclose); diff --git a/net/vhost-user.c b/net/vhost-user.c index b0f0ab6cc8..77b8110f8c 100644 --- a/net/vhost-user.c +++ b/net/vhost-user.c @@ -151,7 +151,10 @@ static void vhost_user_cleanup(NetClientState *nc) s->vhost_net = NULL; } if (nc->queue_index == 0) { + Chardev *chr = qemu_chr_fe_get_driver(&s->chr); + qemu_chr_fe_deinit(&s->chr); + qemu_chr_delete(chr); } qemu_purge_queued_packets(nc); diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h index a2c9518592..aad28258a3 100644 --- a/target/arm/kvm-consts.h +++ b/target/arm/kvm-consts.h @@ -21,7 +21,9 @@ #define MISMATCH_CHECK(X, Y) QEMU_BUILD_BUG_ON(X != Y) #else -#define MISMATCH_CHECK(X, Y) + +#define MISMATCH_CHECK(X, Y) QEMU_BUILD_BUG_ON(0) + #endif #define CP_REG_SIZE_SHIFT 52 @@ -31,12 +33,12 @@ #define CP_REG_ARM 0x4000000000000000ULL #define CP_REG_ARCH_MASK 0xff00000000000000ULL -MISMATCH_CHECK(CP_REG_SIZE_SHIFT, KVM_REG_SIZE_SHIFT) -MISMATCH_CHECK(CP_REG_SIZE_MASK, KVM_REG_SIZE_MASK) -MISMATCH_CHECK(CP_REG_SIZE_U32, KVM_REG_SIZE_U32) -MISMATCH_CHECK(CP_REG_SIZE_U64, KVM_REG_SIZE_U64) -MISMATCH_CHECK(CP_REG_ARM, KVM_REG_ARM) -MISMATCH_CHECK(CP_REG_ARCH_MASK, KVM_REG_ARCH_MASK) +MISMATCH_CHECK(CP_REG_SIZE_SHIFT, KVM_REG_SIZE_SHIFT); +MISMATCH_CHECK(CP_REG_SIZE_MASK, KVM_REG_SIZE_MASK); +MISMATCH_CHECK(CP_REG_SIZE_U32, KVM_REG_SIZE_U32); +MISMATCH_CHECK(CP_REG_SIZE_U64, KVM_REG_SIZE_U64); +MISMATCH_CHECK(CP_REG_ARM, KVM_REG_ARM); +MISMATCH_CHECK(CP_REG_ARCH_MASK, KVM_REG_ARCH_MASK); #define QEMU_PSCI_0_1_FN_BASE 0x95c1ba5e #define QEMU_PSCI_0_1_FN(n) (QEMU_PSCI_0_1_FN_BASE + (n)) @@ -45,10 +47,10 @@ MISMATCH_CHECK(CP_REG_ARCH_MASK, KVM_REG_ARCH_MASK) #define QEMU_PSCI_0_1_FN_CPU_ON QEMU_PSCI_0_1_FN(2) #define QEMU_PSCI_0_1_FN_MIGRATE QEMU_PSCI_0_1_FN(3) -MISMATCH_CHECK(QEMU_PSCI_0_1_FN_CPU_SUSPEND, KVM_PSCI_FN_CPU_SUSPEND) -MISMATCH_CHECK(QEMU_PSCI_0_1_FN_CPU_OFF, KVM_PSCI_FN_CPU_OFF) -MISMATCH_CHECK(QEMU_PSCI_0_1_FN_CPU_ON, KVM_PSCI_FN_CPU_ON) -MISMATCH_CHECK(QEMU_PSCI_0_1_FN_MIGRATE, KVM_PSCI_FN_MIGRATE) +MISMATCH_CHECK(QEMU_PSCI_0_1_FN_CPU_SUSPEND, KVM_PSCI_FN_CPU_SUSPEND); +MISMATCH_CHECK(QEMU_PSCI_0_1_FN_CPU_OFF, KVM_PSCI_FN_CPU_OFF); +MISMATCH_CHECK(QEMU_PSCI_0_1_FN_CPU_ON, KVM_PSCI_FN_CPU_ON); +MISMATCH_CHECK(QEMU_PSCI_0_1_FN_MIGRATE, KVM_PSCI_FN_MIGRATE); #define QEMU_PSCI_0_2_FN_BASE 0x84000000 #define QEMU_PSCI_0_2_FN(n) (QEMU_PSCI_0_2_FN_BASE + (n)) @@ -75,13 +77,13 @@ MISMATCH_CHECK(QEMU_PSCI_0_1_FN_MIGRATE, KVM_PSCI_FN_MIGRATE) #define QEMU_PSCI_0_2_FN64_AFFINITY_INFO QEMU_PSCI_0_2_FN64(4) #define QEMU_PSCI_0_2_FN64_MIGRATE QEMU_PSCI_0_2_FN64(5) -MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_SUSPEND, PSCI_0_2_FN_CPU_SUSPEND) -MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_OFF, PSCI_0_2_FN_CPU_OFF) -MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_ON, PSCI_0_2_FN_CPU_ON) -MISMATCH_CHECK(QEMU_PSCI_0_2_FN_MIGRATE, PSCI_0_2_FN_MIGRATE) -MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_CPU_SUSPEND, PSCI_0_2_FN64_CPU_SUSPEND) -MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_CPU_ON, PSCI_0_2_FN64_CPU_ON) -MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_MIGRATE, PSCI_0_2_FN64_MIGRATE) +MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_SUSPEND, PSCI_0_2_FN_CPU_SUSPEND); +MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_OFF, PSCI_0_2_FN_CPU_OFF); +MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_ON, PSCI_0_2_FN_CPU_ON); +MISMATCH_CHECK(QEMU_PSCI_0_2_FN_MIGRATE, PSCI_0_2_FN_MIGRATE); +MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_CPU_SUSPEND, PSCI_0_2_FN64_CPU_SUSPEND); +MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_CPU_ON, PSCI_0_2_FN64_CPU_ON); +MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_MIGRATE, PSCI_0_2_FN64_MIGRATE); /* PSCI v0.2 return values used by TCG emulation of PSCI */ @@ -91,9 +93,9 @@ MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_MIGRATE, PSCI_0_2_FN64_MIGRATE) /* We implement version 0.2 only */ #define QEMU_PSCI_0_2_RET_VERSION_0_2 2 -MISMATCH_CHECK(QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED, PSCI_0_2_TOS_MP) +MISMATCH_CHECK(QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED, PSCI_0_2_TOS_MP); MISMATCH_CHECK(QEMU_PSCI_0_2_RET_VERSION_0_2, - (PSCI_VERSION_MAJOR(0) | PSCI_VERSION_MINOR(2))) + (PSCI_VERSION_MAJOR(0) | PSCI_VERSION_MINOR(2))); /* PSCI return values (inclusive of all PSCI versions) */ #define QEMU_PSCI_RET_SUCCESS 0 @@ -106,15 +108,15 @@ MISMATCH_CHECK(QEMU_PSCI_0_2_RET_VERSION_0_2, #define QEMU_PSCI_RET_NOT_PRESENT -7 #define QEMU_PSCI_RET_DISABLED -8 -MISMATCH_CHECK(QEMU_PSCI_RET_SUCCESS, PSCI_RET_SUCCESS) -MISMATCH_CHECK(QEMU_PSCI_RET_NOT_SUPPORTED, PSCI_RET_NOT_SUPPORTED) -MISMATCH_CHECK(QEMU_PSCI_RET_INVALID_PARAMS, PSCI_RET_INVALID_PARAMS) -MISMATCH_CHECK(QEMU_PSCI_RET_DENIED, PSCI_RET_DENIED) -MISMATCH_CHECK(QEMU_PSCI_RET_ALREADY_ON, PSCI_RET_ALREADY_ON) -MISMATCH_CHECK(QEMU_PSCI_RET_ON_PENDING, PSCI_RET_ON_PENDING) -MISMATCH_CHECK(QEMU_PSCI_RET_INTERNAL_FAILURE, PSCI_RET_INTERNAL_FAILURE) -MISMATCH_CHECK(QEMU_PSCI_RET_NOT_PRESENT, PSCI_RET_NOT_PRESENT) -MISMATCH_CHECK(QEMU_PSCI_RET_DISABLED, PSCI_RET_DISABLED) +MISMATCH_CHECK(QEMU_PSCI_RET_SUCCESS, PSCI_RET_SUCCESS); +MISMATCH_CHECK(QEMU_PSCI_RET_NOT_SUPPORTED, PSCI_RET_NOT_SUPPORTED); +MISMATCH_CHECK(QEMU_PSCI_RET_INVALID_PARAMS, PSCI_RET_INVALID_PARAMS); +MISMATCH_CHECK(QEMU_PSCI_RET_DENIED, PSCI_RET_DENIED); +MISMATCH_CHECK(QEMU_PSCI_RET_ALREADY_ON, PSCI_RET_ALREADY_ON); +MISMATCH_CHECK(QEMU_PSCI_RET_ON_PENDING, PSCI_RET_ON_PENDING); +MISMATCH_CHECK(QEMU_PSCI_RET_INTERNAL_FAILURE, PSCI_RET_INTERNAL_FAILURE); +MISMATCH_CHECK(QEMU_PSCI_RET_NOT_PRESENT, PSCI_RET_NOT_PRESENT); +MISMATCH_CHECK(QEMU_PSCI_RET_DISABLED, PSCI_RET_DISABLED); /* Note that KVM uses overlapping values for AArch32 and AArch64 * target CPU numbers. AArch32 targets: @@ -135,14 +137,14 @@ MISMATCH_CHECK(QEMU_PSCI_RET_DISABLED, PSCI_RET_DISABLED) #define QEMU_KVM_ARM_TARGET_NONE UINT_MAX #ifdef TARGET_AARCH64 -MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_AEM_V8, KVM_ARM_TARGET_AEM_V8) -MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_FOUNDATION_V8, KVM_ARM_TARGET_FOUNDATION_V8) -MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A57, KVM_ARM_TARGET_CORTEX_A57) -MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_XGENE_POTENZA, KVM_ARM_TARGET_XGENE_POTENZA) -MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A53, KVM_ARM_TARGET_CORTEX_A53) +MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_AEM_V8, KVM_ARM_TARGET_AEM_V8); +MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_FOUNDATION_V8, KVM_ARM_TARGET_FOUNDATION_V8); +MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A57, KVM_ARM_TARGET_CORTEX_A57); +MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_XGENE_POTENZA, KVM_ARM_TARGET_XGENE_POTENZA); +MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A53, KVM_ARM_TARGET_CORTEX_A53); #else -MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A15, KVM_ARM_TARGET_CORTEX_A15) -MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A7, KVM_ARM_TARGET_CORTEX_A7) +MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A15, KVM_ARM_TARGET_CORTEX_A15); +MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A7, KVM_ARM_TARGET_CORTEX_A7); #endif #define CP_REG_ARM64 0x6000000000000000ULL @@ -164,20 +166,20 @@ MISMATCH_CHECK(QEMU_KVM_ARM_TARGET_CORTEX_A7, KVM_ARM_TARGET_CORTEX_A7) #define CP_REG_ARM64_SYSREG_CP (CP_REG_ARM64_SYSREG >> CP_REG_ARM_COPROC_SHIFT) #ifdef TARGET_AARCH64 -MISMATCH_CHECK(CP_REG_ARM64, KVM_REG_ARM64) -MISMATCH_CHECK(CP_REG_ARM_COPROC_MASK, KVM_REG_ARM_COPROC_MASK) -MISMATCH_CHECK(CP_REG_ARM_COPROC_SHIFT, KVM_REG_ARM_COPROC_SHIFT) -MISMATCH_CHECK(CP_REG_ARM64_SYSREG, KVM_REG_ARM64_SYSREG) -MISMATCH_CHECK(CP_REG_ARM64_SYSREG_OP0_MASK, KVM_REG_ARM64_SYSREG_OP0_MASK) -MISMATCH_CHECK(CP_REG_ARM64_SYSREG_OP0_SHIFT, KVM_REG_ARM64_SYSREG_OP0_SHIFT) -MISMATCH_CHECK(CP_REG_ARM64_SYSREG_OP1_MASK, KVM_REG_ARM64_SYSREG_OP1_MASK) -MISMATCH_CHECK(CP_REG_ARM64_SYSREG_OP1_SHIFT, KVM_REG_ARM64_SYSREG_OP1_SHIFT) -MISMATCH_CHECK(CP_REG_ARM64_SYSREG_CRN_MASK, KVM_REG_ARM64_SYSREG_CRN_MASK) -MISMATCH_CHECK(CP_REG_ARM64_SYSREG_CRN_SHIFT, KVM_REG_ARM64_SYSREG_CRN_SHIFT) -MISMATCH_CHECK(CP_REG_ARM64_SYSREG_CRM_MASK, KVM_REG_ARM64_SYSREG_CRM_MASK) -MISMATCH_CHECK(CP_REG_ARM64_SYSREG_CRM_SHIFT, KVM_REG_ARM64_SYSREG_CRM_SHIFT) -MISMATCH_CHECK(CP_REG_ARM64_SYSREG_OP2_MASK, KVM_REG_ARM64_SYSREG_OP2_MASK) -MISMATCH_CHECK(CP_REG_ARM64_SYSREG_OP2_SHIFT, KVM_REG_ARM64_SYSREG_OP2_SHIFT) +MISMATCH_CHECK(CP_REG_ARM64, KVM_REG_ARM64); +MISMATCH_CHECK(CP_REG_ARM_COPROC_MASK, KVM_REG_ARM_COPROC_MASK); +MISMATCH_CHECK(CP_REG_ARM_COPROC_SHIFT, KVM_REG_ARM_COPROC_SHIFT); +MISMATCH_CHECK(CP_REG_ARM64_SYSREG, KVM_REG_ARM64_SYSREG); +MISMATCH_CHECK(CP_REG_ARM64_SYSREG_OP0_MASK, KVM_REG_ARM64_SYSREG_OP0_MASK); +MISMATCH_CHECK(CP_REG_ARM64_SYSREG_OP0_SHIFT, KVM_REG_ARM64_SYSREG_OP0_SHIFT); +MISMATCH_CHECK(CP_REG_ARM64_SYSREG_OP1_MASK, KVM_REG_ARM64_SYSREG_OP1_MASK); +MISMATCH_CHECK(CP_REG_ARM64_SYSREG_OP1_SHIFT, KVM_REG_ARM64_SYSREG_OP1_SHIFT); +MISMATCH_CHECK(CP_REG_ARM64_SYSREG_CRN_MASK, KVM_REG_ARM64_SYSREG_CRN_MASK); +MISMATCH_CHECK(CP_REG_ARM64_SYSREG_CRN_SHIFT, KVM_REG_ARM64_SYSREG_CRN_SHIFT); +MISMATCH_CHECK(CP_REG_ARM64_SYSREG_CRM_MASK, KVM_REG_ARM64_SYSREG_CRM_MASK); +MISMATCH_CHECK(CP_REG_ARM64_SYSREG_CRM_SHIFT, KVM_REG_ARM64_SYSREG_CRM_SHIFT); +MISMATCH_CHECK(CP_REG_ARM64_SYSREG_OP2_MASK, KVM_REG_ARM64_SYSREG_OP2_MASK); +MISMATCH_CHECK(CP_REG_ARM64_SYSREG_OP2_SHIFT, KVM_REG_ARM64_SYSREG_OP2_SHIFT); #endif #undef MISMATCH_CHECK |