cxl: Support the cxl kernel API from a guest
Like on bare-metal, the cxl driver creates a virtual PHB and a pci device for the AFU. The configuration space of the device is mapped to the configuration record of the AFU. Reuse the code defined in afu_cr_read8|16|32() when reading the configuration space of the AFU device. Even though the (virtual) AFU device is a pci device, the adapter is not. So a driver using the cxl kernel API cannot read the VPD of the adapter through the usual PCI interface. Therefore, we add a call to the cxl kernel API: ssize_t cxl_read_adapter_vpd(struct pci_dev *dev, void *buf, size_t count); Co-authored-by: Christophe Lombard <clombard@linux.vnet.ibm.com> Signed-off-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com> Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com> Reviewed-by: Manoj Kumar <manoj@linux.vnet.ibm.com> Acked-by: Ian Munsie <imunsie@au1.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
committed by
Michael Ellerman
parent
b40844aa55
commit
d601ea918b
@@ -1019,6 +1019,52 @@ static int native_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off, u8 *out)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int native_afu_cr_write32(struct cxl_afu *afu, int cr, u64 off, u32 in)
|
||||
{
|
||||
if (unlikely(!cxl_ops->link_ok(afu->adapter)))
|
||||
return -EIO;
|
||||
if (unlikely(off >= afu->crs_len))
|
||||
return -ERANGE;
|
||||
out_le32(afu->native->afu_desc_mmio + afu->crs_offset +
|
||||
(cr * afu->crs_len) + off, in);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int native_afu_cr_write16(struct cxl_afu *afu, int cr, u64 off, u16 in)
|
||||
{
|
||||
u64 aligned_off = off & ~0x3L;
|
||||
u32 val32, mask, shift;
|
||||
int rc;
|
||||
|
||||
rc = native_afu_cr_read32(afu, cr, aligned_off, &val32);
|
||||
if (rc)
|
||||
return rc;
|
||||
shift = (off & 0x3) * 8;
|
||||
WARN_ON(shift == 24);
|
||||
mask = 0xffff << shift;
|
||||
val32 = (val32 & ~mask) | (in << shift);
|
||||
|
||||
rc = native_afu_cr_write32(afu, cr, aligned_off, val32);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int native_afu_cr_write8(struct cxl_afu *afu, int cr, u64 off, u8 in)
|
||||
{
|
||||
u64 aligned_off = off & ~0x3L;
|
||||
u32 val32, mask, shift;
|
||||
int rc;
|
||||
|
||||
rc = native_afu_cr_read32(afu, cr, aligned_off, &val32);
|
||||
if (rc)
|
||||
return rc;
|
||||
shift = (off & 0x3) * 8;
|
||||
mask = 0xff << shift;
|
||||
val32 = (val32 & ~mask) | (in << shift);
|
||||
|
||||
rc = native_afu_cr_write32(afu, cr, aligned_off, val32);
|
||||
return rc;
|
||||
}
|
||||
|
||||
const struct cxl_backend_ops cxl_native_ops = {
|
||||
.module = THIS_MODULE,
|
||||
.adapter_reset = cxl_pci_reset,
|
||||
@@ -1044,4 +1090,8 @@ const struct cxl_backend_ops cxl_native_ops = {
|
||||
.afu_cr_read16 = native_afu_cr_read16,
|
||||
.afu_cr_read32 = native_afu_cr_read32,
|
||||
.afu_cr_read64 = native_afu_cr_read64,
|
||||
.afu_cr_write8 = native_afu_cr_write8,
|
||||
.afu_cr_write16 = native_afu_cr_write16,
|
||||
.afu_cr_write32 = native_afu_cr_write32,
|
||||
.read_adapter_vpd = cxl_pci_read_adapter_vpd,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user