[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-stable] [PATCH 34/54] spapr_pci: fix MSI/MSIX selection
From: |
Michael Roth |
Subject: |
[Qemu-stable] [PATCH 34/54] spapr_pci: fix MSI/MSIX selection |
Date: |
Tue, 6 Feb 2018 13:14:55 -0600 |
From: Greg Kurz <address@hidden>
In various place we don't correctly check if the device supports MSI or
MSI-X. This can cause devices to be advertised with MSI support, even
if they only support MSI-X (like virtio-pci-* devices for example):
address@hidden {
ibm,req#msi = <0x1>; <--- wrong!
.
ibm,loc-code = "qemu_virtio-net-pci:0000:00:00.0";
.
ibm,req#msi-x = <0x3>;
};
Worse, this can also cause the "ibm,change-msi" RTAS call to corrupt the
PCI status and cause migration to fail:
qemu-system-ppc64: get_pci_config_device: Bad config data: i=0x6
read: 0 device: 10 cmask: 10 wmask: 0 w1cmask:0
^^
PCI_STATUS_CAP_LIST bit which is assumed to be constant
This patch changes spapr_populate_pci_child_dt() to properly check for
MSI support using msi_present(): this ensures that PCIDevice::msi_cap
was set by msi_init() and that msi_nr_vectors_allocated() will look at
the right place in the config space.
Checking PCIDevice::msix_entries_nr is enough for MSI-X but let's add
a call to msix_present() there as well for consistency.
It also changes rtas_ibm_change_msi() to select the appropriate MSI
type in Function 1 instead of always selecting plain MSI. This new
behaviour is compliant with LoPAPR 1.1, as described in "Table 71.
ibm,change-msi Argument Call Buffer":
Function 1: If Number Outputs is equal to 3, request to set to a new
number of MSIs (including set to 0).
If the “ibm,change-msix-capable” property exists and Number
Outputs is equal to 4, request is to set to a new number of
MSI or MSI-X (platform choice) interrupts (including set to
0).
Since MSI is the the platform default (LoPAPR 6.2.3 MSI Option), let's
check for MSI support first.
And finally, it checks the input parameters are valid, as described in
LoPAPR 1.1 "R1–7.3.10.5.1–3":
For the MSI option: The platform must return a Status of -3 (Parameter
error) from ibm,change-msi, with no change in interrupt assignments if
the PCI configuration address does not support MSI and Function 3 was
requested (that is, the “ibm,req#msi” property must exist for the PCI
configuration address in order to use Function 3), or does not support
MSI-X and Function 4 is requested (that is, the “ibm,req#msi-x” property
must exist for the PCI configuration address in order to use Function 4),
or if neither MSIs nor MSI-Xs are supported and Function 1 is requested.
This ensures that the ret_intr_type variable contains a valid MSI type
for this device, and that spapr_msi_setmsg() won't corrupt the PCI status.
Signed-off-by: Greg Kurz <address@hidden>
Reviewed-by: Alexey Kardashevskiy <address@hidden>
Signed-off-by: David Gibson <address@hidden>
(cherry picked from commit 9cbe305b60cc49cfcd134765b85c28be95b1b57d)
Signed-off-by: Michael Roth <address@hidden>
---
hw/ppc/spapr_pci.c | 61 +++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 42 insertions(+), 19 deletions(-)
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 5a3122a9f9..a1929ab481 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -280,13 +280,42 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu,
sPAPRMachineState *spapr,
int *config_addr_key;
Error *err = NULL;
+ /* Fins sPAPRPHBState */
+ phb = spapr_pci_find_phb(spapr, buid);
+ if (phb) {
+ pdev = spapr_pci_find_dev(spapr, buid, config_addr);
+ }
+ if (!phb || !pdev) {
+ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+ return;
+ }
+
switch (func) {
- case RTAS_CHANGE_MSI_FN:
case RTAS_CHANGE_FN:
- ret_intr_type = RTAS_TYPE_MSI;
+ if (msi_present(pdev)) {
+ ret_intr_type = RTAS_TYPE_MSI;
+ } else if (msix_present(pdev)) {
+ ret_intr_type = RTAS_TYPE_MSIX;
+ } else {
+ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+ return;
+ }
+ break;
+ case RTAS_CHANGE_MSI_FN:
+ if (msi_present(pdev)) {
+ ret_intr_type = RTAS_TYPE_MSI;
+ } else {
+ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+ return;
+ }
break;
case RTAS_CHANGE_MSIX_FN:
- ret_intr_type = RTAS_TYPE_MSIX;
+ if (msix_present(pdev)) {
+ ret_intr_type = RTAS_TYPE_MSIX;
+ } else {
+ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+ return;
+ }
break;
default:
error_report("rtas_ibm_change_msi(%u) is not implemented", func);
@@ -294,16 +323,6 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu,
sPAPRMachineState *spapr,
return;
}
- /* Fins sPAPRPHBState */
- phb = spapr_pci_find_phb(spapr, buid);
- if (phb) {
- pdev = spapr_pci_find_dev(spapr, buid, config_addr);
- }
- if (!phb || !pdev) {
- rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
- return;
- }
-
msi = (spapr_pci_msi *) g_hash_table_lookup(phb->msi, &config_addr);
/* Releasing MSIs */
@@ -1286,13 +1305,17 @@ static void spapr_populate_pci_child_dt(PCIDevice *dev,
void *fdt, int offset,
_FDT(fdt_setprop_cell(fdt, offset, "#size-cells",
RESOURCE_CELLS_SIZE));
- max_msi = msi_nr_vectors_allocated(dev);
- if (max_msi) {
- _FDT(fdt_setprop_cell(fdt, offset, "ibm,req#msi", max_msi));
+ if (msi_present(dev)) {
+ max_msi = msi_nr_vectors_allocated(dev);
+ if (max_msi) {
+ _FDT(fdt_setprop_cell(fdt, offset, "ibm,req#msi", max_msi));
+ }
}
- max_msix = dev->msix_entries_nr;
- if (max_msix) {
- _FDT(fdt_setprop_cell(fdt, offset, "ibm,req#msi-x", max_msix));
+ if (msix_present(dev)) {
+ max_msix = dev->msix_entries_nr;
+ if (max_msix) {
+ _FDT(fdt_setprop_cell(fdt, offset, "ibm,req#msi-x", max_msix));
+ }
}
populate_resource_props(dev, &rp);
--
2.11.0
- [Qemu-stable] [PATCH 19/54] hw/pci-bridge: fix QEMU crash because of pcie-root-port, (continued)
- [Qemu-stable] [PATCH 19/54] hw/pci-bridge: fix QEMU crash because of pcie-root-port, Michael Roth, 2018/02/06
- [Qemu-stable] [PATCH 27/54] s390x: fix storage attributes migration for non-small guests, Michael Roth, 2018/02/06
- [Qemu-stable] [PATCH 22/54] i386: Add spec-ctrl CPUID bit, Michael Roth, 2018/02/06
- [Qemu-stable] [PATCH 26/54] linux-user: Fix locking order in fork_start(), Michael Roth, 2018/02/06
- [Qemu-stable] [PATCH 28/54] linux-headers: update to 4.15-rc1, Michael Roth, 2018/02/06
- [Qemu-stable] [PATCH 37/54] spapr: Add pseries-2.12 machine type, Michael Roth, 2018/02/06
- [Qemu-stable] [PATCH 35/54] linux-user/signal.c: Rename MC_* defines, Michael Roth, 2018/02/06
- [Qemu-stable] [PATCH 29/54] linux-headers: update, Michael Roth, 2018/02/06
- [Qemu-stable] [PATCH 33/54] usb-storage: Fix share-rw option parsing, Michael Roth, 2018/02/06
- [Qemu-stable] [PATCH 31/54] s390x/kvm: provide stfle.81, Michael Roth, 2018/02/06
- [Qemu-stable] [PATCH 34/54] spapr_pci: fix MSI/MSIX selection,
Michael Roth <=
- [Qemu-stable] [PATCH 32/54] osdep: Retry SETLK upon EINTR, Michael Roth, 2018/02/06
- [Qemu-stable] [PATCH 25/54] i386: Add EPYC-IBPB CPU model, Michael Roth, 2018/02/06
- [Qemu-stable] [PATCH 24/54] i386: Add new -IBRS versions of Intel CPU models, Michael Roth, 2018/02/06
- [Qemu-stable] [PATCH 30/54] s390x/kvm: Handle bpb feature, Michael Roth, 2018/02/06
- [Qemu-stable] [PATCH 41/54] target/ppc: Clean up probing of VMX, VSX and DFP availability on KVM, Michael Roth, 2018/02/06
- [Qemu-stable] [PATCH 42/54] spapr: Handle VMX/VSX presence as an spapr capability flag, Michael Roth, 2018/02/06
- [Qemu-stable] [PATCH 03/54] target/sh4: fix TCG leak during gusa sequence, Michael Roth, 2018/02/06
- [Qemu-stable] [PATCH 02/54] block/iscsi: dont leave allocmap in an invalid state on UNMAP failure, Michael Roth, 2018/02/06
- [Qemu-stable] [PATCH 44/54] hw/ppc/spapr_caps: Rework spapr_caps to use uint8 internal representation, Michael Roth, 2018/02/06
- [Qemu-stable] [PATCH 45/54] ppc: Change Power9 compat table to support at most 8 threads/core, Michael Roth, 2018/02/06