From f29831828441318c7916ae28e6e16e4a1c4a6795 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 18 Jan 2017 22:02:53 +0200 Subject: compiler: drop ; after BUILD_BUG_ON All users include the trailing ; anyway, let's require that - it seems cleaner. Signed-off-by: Michael S. Tsirkin Reviewed-by: Eric Blake Reviewed-by: Markus Armbruster --- include/qemu/compiler.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h index 157698bfa9..75120826c1 100644 --- a/include/qemu/compiler.h +++ b/include/qemu/compiler.h @@ -86,7 +86,8 @@ #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)); + typedef char glue(qemu_build_bug_on__, __LINE__)[(x) ? -1 : 1] \ + __attribute__((unused)) #if defined __GNUC__ # if !QEMU_GNUC_PREREQ(4, 4) -- cgit v1.2.1 From df45892c1290c6c853010b83e5afebe8740cb9fa Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 25 Jan 2017 23:48:51 +0200 Subject: qxl: switch to constants within BUILD_BUG_ON We are switching BUILD_BUG_ON to verify that it's parameter is a compile-time constant, and it turns out that some gcc versions (specifically gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609) are not smart enough to figure it out for expressions involving local variables. This is harmless but means that the check is ineffective for these platforms. To fix, replace variables with macros. Reported-by: Peter Maydell Signed-off-by: Michael S. Tsirkin Reviewed-by: Eric Blake --- hw/display/qxl.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) 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) -- cgit v1.2.1 From 32f825dece6482297fc1b9b0e3bf31424529688a Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Fri, 27 Jan 2017 18:24:55 +0200 Subject: ppc: switch to constants within BUILD_BUG_ON We are switching BUILD_BUG_ON to verify that it's parameter is a compile-time constant, and it turns out that some gcc versions (specifically gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609) are not smart enough to figure it out for expressions involving local variables. This is harmless but means that the check is ineffective for these platforms. To fix, replace the variable with macros. Reported-by: Peter Maydell Signed-off-by: Michael S. Tsirkin --- hw/ppc/spapr.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) 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; } -- cgit v1.2.1 From 60abf0a5e05134187e274ce5f32524ccf0cae1a6 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 31 Jan 2017 16:29:51 +0200 Subject: QEMU_BUILD_BUG_ON: use __COUNTER__ Some headers use QEMU_BUILD_BUG_ON. This causes a problem if the C file including that header happens to have QEMU_BUILD_BUG_ON at the same line number. Fix using a widely available extension: __COUNTER__. If unavailable, provide a stub. Signed-off-by: Michael S. Tsirkin Reviewed-by: Markus Armbruster Reviewed-by: Eric Blake --- include/qemu/compiler.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h index 75120826c1..77b9ce3979 100644 --- a/include/qemu/compiler.h +++ b/include/qemu/compiler.h @@ -85,9 +85,13 @@ #define typeof_field(type, field) typeof(((type *)0)->field) #define type_check(t1,t2) ((t1*)0 - (t2*)0) +#ifdef __COUNTER__ #define QEMU_BUILD_BUG_ON(x) \ - typedef char glue(qemu_build_bug_on__, __LINE__)[(x) ? -1 : 1] \ + typedef char glue(qemu_build_bug_on__, __COUNTER__)[(x) ? -1 : 1] \ __attribute__((unused)) +#else +#define QEMU_BUILD_BUG_ON(x) +#endif #if defined __GNUC__ # if !QEMU_GNUC_PREREQ(4, 4) -- cgit v1.2.1 From f291887e8eef5d37d31484638f6e62401b4b99a2 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 19 Jan 2017 22:56:14 +0200 Subject: compiler: rework BUG_ON using a struct There are theoretical concerns that some compilers might not trigger build failures on attempts to define an array of size (x ? -1 : 1) where x is a variable and make it a variable sized array instead. Let rewrite using a struct with a negative bit field size instead as there are no dynamic bit field sizes. This is similar to what Linux does. Signed-off-by: Michael S. Tsirkin Reviewed-by: Eric Blake Reviewed-by: Markus Armbruster --- include/qemu/compiler.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h index 77b9ce3979..057639af43 100644 --- a/include/qemu/compiler.h +++ b/include/qemu/compiler.h @@ -85,10 +85,14 @@ #define typeof_field(type, field) typeof(((type *)0)->field) #define type_check(t1,t2) ((t1*)0 - (t2*)0) +#define QEMU_BUILD_BUG_ON_STRUCT(x) \ + struct { \ + int:(x) ? -1 : 1; \ + } + #ifdef __COUNTER__ -#define QEMU_BUILD_BUG_ON(x) \ - typedef char glue(qemu_build_bug_on__, __COUNTER__)[(x) ? -1 : 1] \ - __attribute__((unused)) +#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 -- cgit v1.2.1 From d757573e69f2ef58a4a7b41f6c55d65fa1e1c5c2 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 18 Jan 2017 22:05:15 +0200 Subject: compiler: expression version of QEMU_BUILD_BUG_ON QEMU_BUILD_BUG_ON uses a typedef in order to be safe to use outside functions, but sometimes it's useful to have a version that can be used within an expression. Following what Linux does, introduce QEMU_BUILD_BUG_ON_ZERO that return zero after checking condition at build time. Signed-off-by: Michael S. Tsirkin Reviewed-by: Eric Blake Reviewed-by: Markus Armbruster --- include/qemu/compiler.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h index 057639af43..e0ce9ffb28 100644 --- a/include/qemu/compiler.h +++ b/include/qemu/compiler.h @@ -97,6 +97,9 @@ #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) /* gcc versions before 4.4.x don't support gnu_printf, so use printf. */ -- cgit v1.2.1 From ed63ec0d22ccdce3b2222d9a514423b7fbba3a0d Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 18 Jan 2017 22:07:34 +0200 Subject: ARRAY_SIZE: check that argument is an array It's a familiar pattern: some code uses ARRAY_SIZE, then refactoring changes the argument from an array to a pointer to a dynamically allocated buffer. Code keeps compiling but any ARRAY_SIZE calls now return the size of the pointer divided by element size. Let's add build time checks to ARRAY_SIZE before we allow more of these in the code-base. Signed-off-by: Michael S. Tsirkin Reviewed-by: Markus Armbruster Reviewed-by: Eric Blake --- include/qemu/osdep.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) 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); -- cgit v1.2.1 From ec42813028d9ede3f9f73b8c943b00ff235ba0c1 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 19 Jan 2017 21:34:28 +0200 Subject: pci: mark ROMs read-only Looks like we didn't mark PCI ROMs as RO allowing mischief such as guests writing there. Further, e.g. vhost gets confused trying to allocate enough space to log writes there. Fix it up. Signed-off-by: Michael S. Tsirkin Reviewed-by: Marcel Apfelbaum Tested-by: Laurent Vivier --- hw/pci/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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); -- cgit v1.2.1 From 04eb6247eb1d95728b1e3e0078ba79f5b6d2ac25 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 20 Jan 2017 14:35:28 +0800 Subject: intel_iommu: fix and simplify size calculation in process_device_iotlb_desc() We don't use 1ULL which is wrong during size calculation. Fix it, and while at it, switch to use cto64() and adds a comments to make it simpler and easier to be understood. Reported-by: Paolo Bonzini Cc: Paolo Bonzini Signed-off-by: Jason Wang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Paolo Bonzini --- hw/i386/intel_iommu.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) 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; -- cgit v1.2.1 From 9d5154d753920c56b42a2b6069c0b09d74ad8c06 Mon Sep 17 00:00:00 2001 From: Marcel Apfelbaum Date: Mon, 23 Jan 2017 21:20:18 +0200 Subject: hw/pcie: Introduce a base class for PCI Express Root Ports The 'base' PCI Express Root Port includes the common code to be re-used for all Root Ports implementations. Most of the code was taken from the current implementation of Intel's IOH 3420 Root Port. Signed-off-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- default-configs/arm-softmmu.mak | 1 + default-configs/i386-softmmu.mak | 1 + default-configs/x86_64-softmmu.mak | 1 + hw/pci-bridge/Makefile.objs | 1 + hw/pci-bridge/pcie_root_port.c | 171 +++++++++++++++++++++++++++++++++++++ include/hw/pci/pcie_port.h | 19 +++++ 6 files changed, 194 insertions(+) create mode 100644 hw/pci-bridge/pcie_root_port.c 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/pci-bridge/Makefile.objs b/hw/pci-bridge/Makefile.objs index f2adfe348c..4f2039fb1a 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 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/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 + * + * 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/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 */ -- cgit v1.2.1 From fed23cb4e8b4b583a2533f05cd8975d4bf4fe3be Mon Sep 17 00:00:00 2001 From: Marcel Apfelbaum Date: Mon, 23 Jan 2017 21:20:19 +0200 Subject: hw/ioh3420: derive from PCI Express Root Port base class Preserve only Intel specific details. Signed-off-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/pci-bridge/ioh3420.c | 121 ++++++------------------------------------------ 1 file changed, 15 insertions(+), 106 deletions(-) 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, }; -- cgit v1.2.1 From f7d6f3fac8dd7b1d1ecb2662b1751e0ed3fef727 Mon Sep 17 00:00:00 2001 From: Marcel Apfelbaum Date: Mon, 23 Jan 2017 21:20:20 +0200 Subject: hw/pcie: Introduce Generic PCI Express Root Port The Generic Root Port behaves almost the same as the Intel's IOH device with id 3420, without having Intel specific attributes. The device has two purposes: (1) Can be used on both X86 and ARM machines. (2) It will allow us to tweak the behaviour (e.g add vendor-specific PCI capabilities) - something that obviously cannot be done on a known device. Signed-off-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Tested-by: Andrea Bolognani --- hw/pci-bridge/Makefile.objs | 2 +- hw/pci-bridge/gen_pcie_root_port.c | 88 ++++++++++++++++++++++++++++++++++++++ include/hw/pci/pci.h | 1 + 3 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 hw/pci-bridge/gen_pcie_root_port.c diff --git a/hw/pci-bridge/Makefile.objs b/hw/pci-bridge/Makefile.objs index 4f2039fb1a..85e8e3990f 100644 --- a/hw/pci-bridge/Makefile.objs +++ b/hw/pci-bridge/Makefile.objs @@ -1,6 +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 +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..185fd90cee --- /dev/null +++ b/hw/pci-bridge/gen_pcie_root_port.c @@ -0,0 +1,88 @@ +/* + * Generic PCI Express Root Port emulation + * + * Copyright (C) 2017 Red Hat Inc + * + * Authors: + * Marcel Apfelbaum + * + * 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); + + if (rc < 0) { + assert(rc == -ENOTSUP); + error_setg(errp, "Unable to init msix vectors"); + } 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/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 -- cgit v1.2.1 From e987c37aee1752177906847630d32477da57e705 Mon Sep 17 00:00:00 2001 From: Haozhong Zhang Date: Fri, 13 Jan 2017 19:56:51 +0800 Subject: hw/i386: check if nvdimm is enabled before plugging The missing of 'nvdimm' in the machine type option '-M' means NVDIMM is disabled. QEMU should refuse to plug any NVDIMM device in this case and report the misconfiguration. The behavior of NVDIMM on unsupported platform (HW/FW) is vendor specific. For some vendors, it's undefined and the platform may do anything. Thus, I think QEMU is free to choose the implementation. Aborting QEMU (i.e. refusing to boot) is the easiest one. Reported-by: Stefan Hajnoczi Signed-off-by: Haozhong Zhang Message-Id: 20170112110928.GF4621@stefanha-x1.localdomain Message-Id: 20170111093630.2088-1-stefanha@redhat.com Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Xiao Guangrong Reviewed-by: Eduardo Habkost Reviewed-by: Stefan Hajnoczi --- hw/i386/pc.c | 5 +++++ 1 file changed, 5 insertions(+) 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); } -- cgit v1.2.1 From 9348243687930bc54aa76d887dabb622922ea09f Mon Sep 17 00:00:00 2001 From: Cao jin Date: Tue, 17 Jan 2017 14:18:46 +0800 Subject: msix: Follow CODING_STYLE CC: Markus Armbruster CC: Marcel Apfelbaum CC: Michael S. Tsirkin Reviewed-by: Markus Armbruster Acked-by: Marcel Apfelbaum Signed-off-by: Cao jin Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/pci/msix.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hw/pci/msix.c b/hw/pci/msix.c index ee1714d2cf..c938a9b52d 100644 --- a/hw/pci/msix.c +++ b/hw/pci/msix.c @@ -447,8 +447,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 +485,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; } -- cgit v1.2.1 From 20729dbd0109b9d9065447dba354f10bcf78d0d6 Mon Sep 17 00:00:00 2001 From: Cao jin Date: Tue, 17 Jan 2017 14:18:47 +0800 Subject: hcd-xhci: check & correct param before using it usb_xhci_realize() corrects invalid values of property "intrs" automatically, but the uncorrected value is passed to msi_init(), which chokes on invalid values. Delay that until after the correction. Resources allocated by usb_xhci_init() are leaked when msi_init() fails. Fix by calling it after msi_init(). CC: Gerd Hoffmann CC: Markus Armbruster CC: Marcel Apfelbaum CC: Michael S. Tsirkin Reviewed-by: Markus Armbruster Acked-by: Marcel Apfelbaum Signed-off-by: Cao jin Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/usb/hcd-xhci.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index e0b516987f..6575d05006 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); -- cgit v1.2.1 From ee640c625e190a0c0e6b8966adc0e4720fb75200 Mon Sep 17 00:00:00 2001 From: Cao jin Date: Tue, 17 Jan 2017 14:18:48 +0800 Subject: pci: Convert msix_init() to Error and fix callers msix_init() reports errors with error_report(), which is wrong when it's used in realize(). The same issue was fixed for msi_init() in commit 1108b2f. In order to make the API change as small as possible, leave the return value check to later patch. For some devices(like e1000e, vmxnet3, nvme) who won't fail because of msix_init's failure, suppress the error report by passing NULL error object. Bonus: add comment for msix_init. CC: Jiri Pirko CC: Gerd Hoffmann CC: Dmitry Fleytman CC: Jason Wang CC: Michael S. Tsirkin CC: Hannes Reinecke CC: Paolo Bonzini CC: Alex Williamson CC: Markus Armbruster CC: Marcel Apfelbaum Signed-off-by: Cao jin Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/block/nvme.c | 2 +- hw/misc/ivshmem.c | 8 ++++---- hw/net/e1000e.c | 2 +- hw/net/rocker/rocker.c | 4 +++- hw/net/vmxnet3.c | 2 +- hw/pci-bridge/gen_pcie_root_port.c | 3 +-- hw/pci/msix.c | 36 +++++++++++++++++++++++++++++++----- hw/scsi/megasas.c | 4 +++- hw/usb/hcd-xhci.c | 4 ++-- hw/vfio/pci.c | 8 ++++++-- hw/virtio/virtio-pci.c | 4 ++-- include/hw/pci/msix.h | 5 +++-- 12 files changed, 58 insertions(+), 24 deletions(-) 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/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/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c index 185fd90cee..8ebffa8bb0 100644 --- a/hw/pci-bridge/gen_pcie_root_port.c +++ b/hw/pci-bridge/gen_pcie_root_port.c @@ -29,11 +29,10 @@ 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); + rc = msix_init_exclusive_bar(d, GEN_PCIE_ROOT_PORT_MSIX_NR_VECTOR, 0, errp); if (rc < 0) { assert(rc == -ENOTSUP); - error_setg(errp, "Unable to init msix vectors"); } else { msix_vector_use(d, 0); } diff --git a/hw/pci/msix.c b/hw/pci/msix.c index c938a9b52d..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; } 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 6575d05006..f8106789d8 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -3703,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/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/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); -- cgit v1.2.1 From c25d97c4ff37d48aeda395cb5bfb8182b786f0e1 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 20 Jan 2017 18:07:51 +0100 Subject: virtio: make virtio_should_notify static Signed-off-by: Paolo Bonzini Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Stefan Hajnoczi --- hw/virtio/virtio.c | 2 +- include/hw/virtio/virtio.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) 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/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); -- cgit v1.2.1 From d56ec1e98c0005933fe677d633484297f422691a Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 24 Jan 2017 19:03:40 +0200 Subject: vhost: skip ROM sections vhost does not support RO protections on memory at the moment - adding ROMs would mean that e.g. a buggy guest might change them in-memory - a condition from which guest reset does not recover. Not nice. We also definitely don't want to try logging writes into ROMs - in particular guests set very high addresses for ROM BARs so logging these writes would waste a lot of memory. Maybe ROMs could be supported with the iotlb variant - not sure, but there seems to be no good reason for virtio to try to do DMA from ROM. So let's just skip ROM memory. Suggested-by: Laurent Vivier Signed-off-by: Michael S. Tsirkin Reviewed-by: Laurent Vivier Tested-by: Laurent Vivier --- hw/virtio/vhost.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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) -- cgit v1.2.1 From e0b283e7c5b020c3e54629d8b82117db0af21cca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Tue, 24 Jan 2017 23:02:58 +0400 Subject: vhost-user: delete chardev on cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the chardev implicitly when cleaning up the netdev. This prevents from reusing the chardev since it would be in an incorrect state with the slave. Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1256618 Signed-off-by: Marc-André Lureau Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Eric Blake --- net/vhost-user.c | 3 +++ 1 file changed, 3 insertions(+) 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); -- cgit v1.2.1 From dc0ae767700c156894e36fab89a745a2dc4173de Mon Sep 17 00:00:00 2001 From: Marcel Apfelbaum Date: Wed, 25 Jan 2017 10:44:46 +0200 Subject: hw/pci: disable pci-bridge's shpc by default The shpc component is optional while ACPI hotplug is used for hot-plugging PCI devices into a PCI-PCI bridge. Disabling the shpc by default will make slot 0 usable at boot time and not only for hot-plug, without loosing any functionality. Older machines will have shpc enabled for compatibility reasons. Signed-off-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/pci-bridge/pci_bridge_dev.c | 2 +- include/hw/compat.h | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) 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/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 \ -- cgit v1.2.1 From 705ae59fecae341a4b1a45ce48b46de4b1bb3cf4 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Fri, 27 Jan 2017 18:17:25 +0200 Subject: arm: better stub version for MISMATCH_CHECK stub version of MISMATCH_CHECK is empty so it's easy to misuse for people not building kvm on arm. Use QEMU_BUILD_BUG_ON similar to the non-stub version to make it easier to catch bugs. Signed-off-by: Michael S. Tsirkin Reviewed-by: Peter Maydell --- target/arm/kvm-consts.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h index a2c9518592..06b6c920b1 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 -- cgit v1.2.1 From 1b28762a333bd238611103e9ed2348d7af93b0db Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Fri, 27 Jan 2017 18:20:07 +0200 Subject: arm: add trailing ; after MISMATCH_CHECK Macro calls without a trailing ; look weird in C, this works as a side effect of how QEMU_BUILD_BUG_ON is implemented. Fix this up. Signed-off-by: Michael S. Tsirkin Reviewed-by: Peter Maydell --- target/arm/kvm-consts.h | 98 ++++++++++++++++++++++++------------------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h index 06b6c920b1..aad28258a3 100644 --- a/target/arm/kvm-consts.h +++ b/target/arm/kvm-consts.h @@ -33,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)) @@ -47,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)) @@ -77,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 */ @@ -93,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 @@ -108,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: @@ -137,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 @@ -166,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 -- cgit v1.2.1