diff options
author | Cornelia Huck <cohuck@redhat.com> | 2020-11-18 11:42:02 +0100 |
---|---|---|
committer | Cornelia Huck <cohuck@redhat.com> | 2020-11-18 16:59:29 +0100 |
commit | a4e2fff1b104f2b235ea2673968d0b0383f541dc (patch) | |
tree | 0e5f7d2ce5be747e1605ddaddab0cd389f02a0ba /hw | |
parent | e67ad058e45aa8b23e9b94e793b9fcf66e70ebb0 (diff) |
s390x/pci: fix endianness issues
The zPCI group and function structures are big endian. However, we do
not consistently store them as big endian locally, and are missing some
conversions.
Let's just store the structures as host endian instead and convert to
big endian when actually handling the instructions retrieving the data.
Also fix the layout of ClpReqQueryPciGrp: g is actually only 8 bit. This
also fixes accesses on little endian hosts, and makes accesses on big
endian hosts consistent.
Fixes: 28dc86a07299 ("s390x/pci: use a PCI Group structure")
Fixes: 9670ee752727 ("s390x/pci: use a PCI Function structure")
Fixes: 1e7552ff5c34 ("s390x/pci: get zPCI function info from host")
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Tested-by: Matthew Rosato <mjrosato@linux.ibm.com>
Tested-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20201118104202.1301363-1-cohuck@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/s390x/s390-pci-bus.c | 10 | ||||
-rw-r--r-- | hw/s390x/s390-pci-inst.c | 16 | ||||
-rw-r--r-- | hw/s390x/s390-pci-vfio.c | 12 |
3 files changed, 25 insertions, 13 deletions
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c index e0dc20ce4a..05f7460aec 100644 --- a/hw/s390x/s390-pci-bus.c +++ b/hw/s390x/s390-pci-bus.c @@ -777,11 +777,11 @@ static void s390_pci_init_default_group(void) group = s390_group_create(ZPCI_DEFAULT_FN_GRP); resgrp = &group->zpci_group; resgrp->fr = 1; - stq_p(&resgrp->dasm, 0); - stq_p(&resgrp->msia, ZPCI_MSI_ADDR); - stw_p(&resgrp->mui, DEFAULT_MUI); - stw_p(&resgrp->i, 128); - stw_p(&resgrp->maxstbl, 128); + resgrp->dasm = 0; + resgrp->msia = ZPCI_MSI_ADDR; + resgrp->mui = DEFAULT_MUI; + resgrp->i = 128; + resgrp->maxstbl = 128; resgrp->version = 0; } diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c index 58cd041d17..70bfd91bf7 100644 --- a/hw/s390x/s390-pci-inst.c +++ b/hw/s390x/s390-pci-inst.c @@ -281,7 +281,13 @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra) goto out; } - memcpy(resquery, &pbdev->zpci_fn, sizeof(*resquery)); + stq_p(&resquery->sdma, pbdev->zpci_fn.sdma); + stq_p(&resquery->edma, pbdev->zpci_fn.edma); + stw_p(&resquery->pchid, pbdev->zpci_fn.pchid); + resquery->flags = pbdev->zpci_fn.flags; + resquery->pfgid = pbdev->zpci_fn.pfgid; + stl_p(&resquery->fid, pbdev->zpci_fn.fid); + stl_p(&resquery->uid, pbdev->zpci_fn.uid); for (i = 0; i < PCI_BAR_COUNT; i++) { uint32_t data = pci_get_long(pbdev->pdev->config + @@ -312,7 +318,13 @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra) stw_p(&resgrp->hdr.rsp, CLP_RC_QUERYPCIFG_PFGID); goto out; } - memcpy(resgrp, &group->zpci_group, sizeof(ClpRspQueryPciGrp)); + resgrp->fr = group->zpci_group.fr; + stq_p(&resgrp->dasm, group->zpci_group.dasm); + stq_p(&resgrp->msia, group->zpci_group.msia); + stw_p(&resgrp->mui, group->zpci_group.mui); + stw_p(&resgrp->i, group->zpci_group.i); + stw_p(&resgrp->maxstbl, group->zpci_group.maxstbl); + resgrp->version = group->zpci_group.version; stw_p(&resgrp->hdr.rsp, CLP_RC_OK); break; } diff --git a/hw/s390x/s390-pci-vfio.c b/hw/s390x/s390-pci-vfio.c index d5c78063b5..9296e1bb6e 100644 --- a/hw/s390x/s390-pci-vfio.c +++ b/hw/s390x/s390-pci-vfio.c @@ -156,12 +156,12 @@ static void s390_pci_read_group(S390PCIBusDevice *pbdev, if (cap->flags & VFIO_DEVICE_INFO_ZPCI_FLAG_REFRESH) { resgrp->fr = 1; } - stq_p(&resgrp->dasm, cap->dasm); - stq_p(&resgrp->msia, cap->msi_addr); - stw_p(&resgrp->mui, cap->mui); - stw_p(&resgrp->i, cap->noi); - stw_p(&resgrp->maxstbl, cap->maxstbl); - stb_p(&resgrp->version, cap->version); + resgrp->dasm = cap->dasm; + resgrp->msia = cap->msi_addr; + resgrp->mui = cap->mui; + resgrp->i = cap->noi; + resgrp->maxstbl = cap->maxstbl; + resgrp->version = cap->version; } } |