aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/cxl/guest.c
diff options
context:
space:
mode:
authorFrederic Barrat <fbarrat@linux.vnet.ibm.com>2016-03-04 12:26:40 +0100
committerMichael Ellerman <mpe@ellerman.id.au>2016-03-09 23:40:00 +1100
commitd601ea918b878582e60b773f2f943d8d292b2abf (patch)
treed2bba34d1bc92b685d21c668c3abbde2c292a464 /drivers/misc/cxl/guest.c
parentcxl: Parse device tree and create cxl device(s) at boot (diff)
downloadlinux-dev-d601ea918b878582e60b773f2f943d8d292b2abf.tar.xz
linux-dev-d601ea918b878582e60b773f2f943d8d292b2abf.zip
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>
Diffstat (limited to 'drivers/misc/cxl/guest.c')
-rw-r--r--drivers/misc/cxl/guest.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/misc/cxl/guest.c b/drivers/misc/cxl/guest.c
index 816113d9d19b..2b07ebd2b429 100644
--- a/drivers/misc/cxl/guest.c
+++ b/drivers/misc/cxl/guest.c
@@ -418,6 +418,24 @@ static int guest_afu_cr_read64(struct cxl_afu *afu, int cr_idx, u64 offset,
return _guest_afu_cr_readXX(8, afu, cr_idx, offset, out);
}
+static int guest_afu_cr_write32(struct cxl_afu *afu, int cr, u64 off, u32 in)
+{
+ /* config record is not writable from guest */
+ return -EPERM;
+}
+
+static int guest_afu_cr_write16(struct cxl_afu *afu, int cr, u64 off, u16 in)
+{
+ /* config record is not writable from guest */
+ return -EPERM;
+}
+
+static int guest_afu_cr_write8(struct cxl_afu *afu, int cr, u64 off, u8 in)
+{
+ /* config record is not writable from guest */
+ return -EPERM;
+}
+
static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr)
{
struct cxl_process_element_hcall *elem;
@@ -807,6 +825,9 @@ int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_n
afu->enabled = true;
+ if ((rc = cxl_pci_vphb_add(afu)))
+ dev_info(&afu->dev, "Can't register vPHB\n");
+
return 0;
err_put2:
@@ -832,6 +853,7 @@ void cxl_guest_remove_afu(struct cxl_afu *afu)
if (!afu)
return;
+ cxl_pci_vphb_remove(afu);
cxl_sysfs_afu_remove(afu);
spin_lock(&afu->adapter->afu_list_lock);
@@ -987,4 +1009,8 @@ const struct cxl_backend_ops cxl_guest_ops = {
.afu_cr_read16 = guest_afu_cr_read16,
.afu_cr_read32 = guest_afu_cr_read32,
.afu_cr_read64 = guest_afu_cr_read64,
+ .afu_cr_write8 = guest_afu_cr_write8,
+ .afu_cr_write16 = guest_afu_cr_write16,
+ .afu_cr_write32 = guest_afu_cr_write32,
+ .read_adapter_vpd = cxl_guest_read_adapter_vpd,
};