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: 28dc86a072 ("s390x/pci: use a PCI Group structure")
Fixes: 9670ee7527 ("s390x/pci: use a PCI Function structure")
Fixes: 1e7552ff5c ("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>
This commit is contained in:
Cornelia Huck 2020-11-18 11:42:02 +01:00
parent e67ad058e4
commit a4e2fff1b1
4 changed files with 29 additions and 17 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -144,10 +144,10 @@ typedef struct ClpReqQueryPciGrp {
ClpReqHdr hdr;
uint32_t fmt;
uint64_t reserved1;
#define CLP_REQ_QPCIG_MASK_PFGID 0xff
uint32_t g;
uint32_t reserved2;
uint64_t reserved3;
uint8_t reserved2[3];
uint8_t g;
uint32_t reserved3;
uint64_t reserved4;
} QEMU_PACKED ClpReqQueryPciGrp;
/* Query PCI function group response */