* [PATCH v3 01/24] powerpc/copro: Fix faulting kernel segments
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
@ 2015-05-27 6:06 ` Michael Neuling
2015-05-27 6:06 ` [PATCH v3 02/24] powerpc/pci: Export symbols for CXL Michael Neuling
` (22 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:06 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
This fixes calculating the key bits (KP and KS) in the SLB VSID for kernel
mappings.
I'm not CCing this to stable as there are no uses of this currently.
Signed-off-by: Michael Neuling <mikey@neuling.org>
---
arch/powerpc/mm/copro_fault.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/mm/copro_fault.c b/arch/powerpc/mm/copro_fault.c
index f031a47..7a71d7f 100644
--- a/arch/powerpc/mm/copro_fault.c
+++ b/arch/powerpc/mm/copro_fault.c
@@ -100,7 +100,7 @@ EXPORT_SYMBOL_GPL(copro_handle_mm_fault);
int copro_calculate_slb(struct mm_struct *mm, u64 ea, struct copro_slb *slb)
{
- u64 vsid;
+ u64 vsid, vsidkey;
int psize, ssize;
switch (REGION_ID(ea)) {
@@ -109,6 +109,7 @@ int copro_calculate_slb(struct mm_struct *mm, u64 ea, struct copro_slb *slb)
psize = get_slice_psize(mm, ea);
ssize = user_segment_size(ea);
vsid = get_vsid(mm->context.id, ea, ssize);
+ vsidkey = SLB_VSID_USER;
break;
case VMALLOC_REGION_ID:
pr_devel("%s: 0x%llx -- VMALLOC_REGION_ID\n", __func__, ea);
@@ -118,19 +119,21 @@ int copro_calculate_slb(struct mm_struct *mm, u64 ea, struct copro_slb *slb)
psize = mmu_io_psize;
ssize = mmu_kernel_ssize;
vsid = get_kernel_vsid(ea, mmu_kernel_ssize);
+ vsidkey = SLB_VSID_KERNEL;
break;
case KERNEL_REGION_ID:
pr_devel("%s: 0x%llx -- KERNEL_REGION_ID\n", __func__, ea);
psize = mmu_linear_psize;
ssize = mmu_kernel_ssize;
vsid = get_kernel_vsid(ea, mmu_kernel_ssize);
+ vsidkey = SLB_VSID_KERNEL;
break;
default:
pr_debug("%s: invalid region access at %016llx\n", __func__, ea);
return 1;
}
- vsid = (vsid << slb_vsid_shift(ssize)) | SLB_VSID_USER;
+ vsid = (vsid << slb_vsid_shift(ssize)) | vsidkey;
vsid |= mmu_psize_defs[psize].sllp |
((ssize == MMU_SEGSIZE_1T) ? SLB_VSID_B_1T : 0);
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 02/24] powerpc/pci: Export symbols for CXL
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
2015-05-27 6:06 ` [PATCH v3 01/24] powerpc/copro: Fix faulting kernel segments Michael Neuling
@ 2015-05-27 6:06 ` Michael Neuling
2015-05-27 6:06 ` [PATCH v3 03/24] powerpc/pci: Add release_device() hook to phb ops Michael Neuling
` (21 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:06 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
From: Daniel Axtens <dja@axtens.net>
Export pcibios_claim_one_bus, pcibios_scan_phb and pcibios_alloc_controller.
These will be used by the CXL driver.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
arch/powerpc/kernel/pci-common.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 0d05406..2040cd2 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -89,6 +89,7 @@ struct pci_controller *pcibios_alloc_controller(struct device_node *dev)
#endif
return phb;
}
+EXPORT_SYMBOL_GPL(pcibios_alloc_controller);
void pcibios_free_controller(struct pci_controller *phb)
{
@@ -1447,6 +1448,7 @@ void pcibios_claim_one_bus(struct pci_bus *bus)
list_for_each_entry(child_bus, &bus->children, node)
pcibios_claim_one_bus(child_bus);
}
+EXPORT_SYMBOL_GPL(pcibios_claim_one_bus);
/* pcibios_finish_adding_to_bus
@@ -1680,6 +1682,7 @@ void pcibios_scan_phb(struct pci_controller *hose)
pcie_bus_configure_settings(child);
}
}
+EXPORT_SYMBOL_GPL(pcibios_scan_phb);
static void fixup_hide_host_resource_fsl(struct pci_dev *dev)
{
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 03/24] powerpc/pci: Add release_device() hook to phb ops
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
2015-05-27 6:06 ` [PATCH v3 01/24] powerpc/copro: Fix faulting kernel segments Michael Neuling
2015-05-27 6:06 ` [PATCH v3 02/24] powerpc/pci: Export symbols for CXL Michael Neuling
@ 2015-05-27 6:06 ` Michael Neuling
2015-05-27 6:06 ` [PATCH v3 04/24] powerpc: Add cxl context to device archdata Michael Neuling
` (20 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:06 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
Add release_device() hook to phb ops so we can clean up for specific phbs.
Signed-off-by: Michael Neuling <mikey@neuling.org>
---
arch/powerpc/include/asm/pci-bridge.h | 2 ++
arch/powerpc/kernel/pci-hotplug.c | 5 +++++
2 files changed, 7 insertions(+)
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 6d17bb8..4cf0caa 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -27,6 +27,8 @@ struct pci_controller_ops {
* allow assignment/enabling of the device. */
bool (*enable_device_hook)(struct pci_dev *);
+ void (*release_device)(struct pci_dev *);
+
/* Called during PCI resource reassignment */
resource_size_t (*window_alignment)(struct pci_bus *, unsigned long type);
void (*reset_secondary_bus)(struct pci_dev *dev);
diff --git a/arch/powerpc/kernel/pci-hotplug.c b/arch/powerpc/kernel/pci-hotplug.c
index 7ed85a6..7f9ed0c 100644
--- a/arch/powerpc/kernel/pci-hotplug.c
+++ b/arch/powerpc/kernel/pci-hotplug.c
@@ -29,7 +29,12 @@
*/
void pcibios_release_device(struct pci_dev *dev)
{
+ struct pci_controller *phb = pci_bus_to_host(dev->bus);
+
eeh_remove_device(dev);
+
+ if (phb->controller_ops.release_device)
+ phb->controller_ops.release_device(dev);
}
/**
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 04/24] powerpc: Add cxl context to device archdata
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
` (2 preceding siblings ...)
2015-05-27 6:06 ` [PATCH v3 03/24] powerpc/pci: Add release_device() hook to phb ops Michael Neuling
@ 2015-05-27 6:06 ` Michael Neuling
2015-05-27 6:06 ` [PATCH v3 05/24] powerpc/pci: Add shutdown hook to pci_controller_ops Michael Neuling
` (19 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:06 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
Add cxl context pointer to archdata. We'll want to create one of these for cxl
PCI devices. Put them here until we can get a pci_dev specific private data.
This location was suggested by benh.
Signed-off-by: Michael Neuling <mikey@neuling.org>
---
arch/powerpc/include/asm/device.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h
index 9f1371b..e9bdda8 100644
--- a/arch/powerpc/include/asm/device.h
+++ b/arch/powerpc/include/asm/device.h
@@ -46,6 +46,9 @@ struct dev_archdata {
#ifdef CONFIG_FAIL_IOMMU
int fail_iommu;
#endif
+#ifdef CONFIG_CXL_BASE
+ struct cxl_context *cxl_ctx;
+#endif
};
struct pdev_archdata {
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 05/24] powerpc/pci: Add shutdown hook to pci_controller_ops
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
` (3 preceding siblings ...)
2015-05-27 6:06 ` [PATCH v3 04/24] powerpc: Add cxl context to device archdata Michael Neuling
@ 2015-05-27 6:06 ` Michael Neuling
2015-05-27 6:07 ` [PATCH v3 06/24] powerpc/pci: Add pcibios_disable_device() hook Michael Neuling
` (18 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:06 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
Currently pnv_pci_shutdown() calls the PHB shutdown code for all PHBs in the
system. It dereferences the private_data assuming it's a powernv PHB, which
won't be the case when we have different PHB in the systems (like when we add
vPHBs for CXL).
This moves the shutdown hook to the pci_controller_ops and fixes the call site
to use that instead.
Signed-off-by: Michael Neuling <mikey@neuling.org>
---
arch/powerpc/include/asm/pci-bridge.h | 2 ++
arch/powerpc/platforms/powernv/pci-ioda.c | 8 ++++----
arch/powerpc/platforms/powernv/pci.c | 9 +++------
arch/powerpc/platforms/powernv/pci.h | 1 -
4 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 4cf0caa..3947749 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -40,6 +40,8 @@ struct pci_controller_ops {
#endif
int (*dma_set_mask)(struct pci_dev *dev, u64 dma_mask);
+
+ void (*shutdown)(struct pci_controller *);
};
/*
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index bb3c0c4..2eaf6f7 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -2645,8 +2645,10 @@ static u32 pnv_ioda_bdfn_to_pe(struct pnv_phb *phb, struct pci_bus *bus,
return phb->ioda.pe_rmap[(bus->number << 8) | devfn];
}
-static void pnv_pci_ioda_shutdown(struct pnv_phb *phb)
+static void pnv_pci_ioda_shutdown(struct pci_controller *hose)
{
+ struct pnv_phb *phb = hose->private_data;
+
opal_pci_reset(phb->opal_id, OPAL_RESET_PCI_IODA_TABLE,
OPAL_ASSERT_RESET);
}
@@ -2796,9 +2798,6 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
phb->dma_dev_setup = pnv_pci_ioda_dma_dev_setup;
phb->dma_get_required_mask = pnv_pci_ioda_dma_get_required_mask;
- /* Setup shutdown function for kexec */
- phb->shutdown = pnv_pci_ioda_shutdown;
-
/* Setup MSI support */
pnv_pci_init_ioda_msis(phb);
@@ -2879,4 +2878,5 @@ static const struct pci_controller_ops pnv_pci_ioda_controller_ops = {
.window_alignment = pnv_pci_window_alignment,
.reset_secondary_bus = pnv_pci_reset_secondary_bus,
.dma_set_mask = pnv_pci_ioda_dma_set_mask,
+ .shutdown = pnv_pci_ioda_shutdown,
};
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index acc0ced..1614d79 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -704,12 +704,9 @@ void pnv_pci_shutdown(void)
{
struct pci_controller *hose;
- list_for_each_entry(hose, &hose_list, list_node) {
- struct pnv_phb *phb = hose->private_data;
-
- if (phb && phb->shutdown)
- phb->shutdown(phb);
- }
+ list_for_each_entry(hose, &hose_list, list_node)
+ if (hose->controller_ops.shutdown)
+ hose->controller_ops.shutdown(hose);
}
/* Fixup wrong class code in p7ioc and p8 root complex */
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
index 60bb935..7edb54f5 100644
--- a/arch/powerpc/platforms/powernv/pci.h
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -110,7 +110,6 @@ struct pnv_phb {
struct pci_dev *pdev);
void (*fixup_phb)(struct pci_controller *hose);
u32 (*bdfn_to_pe)(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn);
- void (*shutdown)(struct pnv_phb *phb);
int (*init_m64)(struct pnv_phb *phb);
void (*reserve_m64_pe)(struct pnv_phb *phb);
int (*pick_m64_pe)(struct pnv_phb *phb, struct pci_bus *bus, int all);
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 06/24] powerpc/pci: Add pcibios_disable_device() hook
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
` (4 preceding siblings ...)
2015-05-27 6:06 ` [PATCH v3 05/24] powerpc/pci: Add shutdown hook to pci_controller_ops Michael Neuling
@ 2015-05-27 6:07 ` Michael Neuling
2015-05-27 6:07 ` [PATCH v3 07/24] cxl: Document external user of existing API Michael Neuling
` (17 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:07 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
This adds a hook into the powerpc pci code for pci_disable_device() calls. The
generic code already provides a weak pcibios_disable_device() symbol, so we
just need to provide our own in powerpc and it'll get picked up.
This is passed directly to the phb controller ops, provided one exists.
Signed-off-by: Michael Neuling <mikey@neuling.org>
---
arch/powerpc/include/asm/pci-bridge.h | 2 ++
arch/powerpc/kernel/pci-common.c | 8 ++++++++
2 files changed, 10 insertions(+)
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 3947749..b76cd56 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -27,6 +27,8 @@ struct pci_controller_ops {
* allow assignment/enabling of the device. */
bool (*enable_device_hook)(struct pci_dev *);
+ void (*disable_device)(struct pci_dev *);
+
void (*release_device)(struct pci_dev *);
/* Called during PCI resource reassignment */
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 2040cd2..b9de34d 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1490,6 +1490,14 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
return pci_enable_resources(dev, mask);
}
+void pcibios_disable_device(struct pci_dev *dev)
+{
+ struct pci_controller *phb = pci_bus_to_host(dev->bus);
+
+ if (phb->controller_ops.disable_device)
+ phb->controller_ops.disable_device(dev);
+}
+
resource_size_t pcibios_io_space_offset(struct pci_controller *hose)
{
return (unsigned long) hose->io_base_virt - _IO_BASE;
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 07/24] cxl: Document external user of existing API
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
` (5 preceding siblings ...)
2015-05-27 6:07 ` [PATCH v3 06/24] powerpc/pci: Add pcibios_disable_device() hook Michael Neuling
@ 2015-05-27 6:07 ` Michael Neuling
2015-05-27 6:07 ` [PATCH v3 08/24] cxl: Add shutdown hook Michael Neuling
` (16 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:07 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
Now that libcxl is public, let's document it.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Acked-by: Ian Munsie <imunsie@au1.ibm.com>
---
Documentation/ABI/testing/sysfs-class-cxl | 22 ++++++++++++++++++++++
Documentation/powerpc/cxl.txt | 4 ++++
2 files changed, 26 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-class-cxl b/Documentation/ABI/testing/sysfs-class-cxl
index d46bba8..7cd9f2e 100644
--- a/Documentation/ABI/testing/sysfs-class-cxl
+++ b/Documentation/ABI/testing/sysfs-class-cxl
@@ -15,6 +15,7 @@ Description: read/write
that hardware can support (eg. 2037). Write values will limit
userspace applications to that many userspace interrupts. Must
be >= irqs_min.
+Users: https://github.com/ibm-capi/libcxl
What: /sys/class/cxl/<afu>/irqs_min
Date: September 2014
@@ -24,6 +25,7 @@ Description: read only
userspace must request on a CXL_START_WORK ioctl. Userspace may
omit the num_interrupts field in the START_WORK IOCTL to get
this minimum automatically.
+Users: https://github.com/ibm-capi/libcxl
What: /sys/class/cxl/<afu>/mmio_size
Date: September 2014
@@ -31,6 +33,7 @@ Contact: linuxppc-dev@lists.ozlabs.org
Description: read only
Decimal value of the size of the MMIO space that may be mmaped
by userspace.
+Users: https://github.com/ibm-capi/libcxl
What: /sys/class/cxl/<afu>/modes_supported
Date: September 2014
@@ -38,6 +41,7 @@ Contact: linuxppc-dev@lists.ozlabs.org
Description: read only
List of the modes this AFU supports. One per line.
Valid entries are: "dedicated_process" and "afu_directed"
+Users: https://github.com/ibm-capi/libcxl
What: /sys/class/cxl/<afu>/mode
Date: September 2014
@@ -46,6 +50,7 @@ Description: read/write
The current mode the AFU is using. Will be one of the modes
given in modes_supported. Writing will change the mode
provided that no user contexts are attached.
+Users: https://github.com/ibm-capi/libcxl
What: /sys/class/cxl/<afu>/prefault_mode
@@ -59,6 +64,7 @@ Description: read/write
descriptor as an effective address and
prefault what it points to.
all: all segments process calling START_WORK maps.
+Users: https://github.com/ibm-capi/libcxl
What: /sys/class/cxl/<afu>/reset
Date: September 2014
@@ -66,12 +72,14 @@ Contact: linuxppc-dev@lists.ozlabs.org
Description: write only
Writing 1 here will reset the AFU provided there are not
contexts active on the AFU.
+Users: https://github.com/ibm-capi/libcxl
What: /sys/class/cxl/<afu>/api_version
Date: September 2014
Contact: linuxppc-dev@lists.ozlabs.org
Description: read only
Decimal value of the current version of the kernel/user API.
+Users: https://github.com/ibm-capi/libcxl
What: /sys/class/cxl/<afu>/api_version_compatible
Date: September 2014
@@ -79,6 +87,7 @@ Contact: linuxppc-dev@lists.ozlabs.org
Description: read only
Decimal value of the the lowest version of the userspace API
this this kernel supports.
+Users: https://github.com/ibm-capi/libcxl
AFU configuration records (eg. /sys/class/cxl/afu0.0/cr0):
@@ -92,6 +101,7 @@ Contact: linuxppc-dev@lists.ozlabs.org
Description: read only
Hexadecimal value of the vendor ID found in this AFU
configuration record.
+Users: https://github.com/ibm-capi/libcxl
What: /sys/class/cxl/<afu>/cr<config num>/device
Date: February 2015
@@ -99,6 +109,7 @@ Contact: linuxppc-dev@lists.ozlabs.org
Description: read only
Hexadecimal value of the device ID found in this AFU
configuration record.
+Users: https://github.com/ibm-capi/libcxl
What: /sys/class/cxl/<afu>/cr<config num>/class
Date: February 2015
@@ -106,6 +117,7 @@ Contact: linuxppc-dev@lists.ozlabs.org
Description: read only
Hexadecimal value of the class code found in this AFU
configuration record.
+Users: https://github.com/ibm-capi/libcxl
What: /sys/class/cxl/<afu>/cr<config num>/config
Date: February 2015
@@ -115,6 +127,7 @@ Description: read only
record. The format is expected to match the either the standard
or extended configuration space defined by the PCIe
specification.
+Users: https://github.com/ibm-capi/libcxl
@@ -126,18 +139,21 @@ Contact: linuxppc-dev@lists.ozlabs.org
Description: read only
Decimal value of the size of the MMIO space that may be mmaped
by userspace. This includes all slave contexts space also.
+Users: https://github.com/ibm-capi/libcxl
What: /sys/class/cxl/<afu>m/pp_mmio_len
Date: September 2014
Contact: linuxppc-dev@lists.ozlabs.org
Description: read only
Decimal value of the Per Process MMIO space length.
+Users: https://github.com/ibm-capi/libcxl
What: /sys/class/cxl/<afu>m/pp_mmio_off
Date: September 2014
Contact: linuxppc-dev@lists.ozlabs.org
Description: read only
Decimal value of the Per Process MMIO space offset.
+Users: https://github.com/ibm-capi/libcxl
Card info (eg. /sys/class/cxl/card0)
@@ -147,12 +163,14 @@ Date: September 2014
Contact: linuxppc-dev@lists.ozlabs.org
Description: read only
Identifies the CAIA Version the card implements.
+Users: https://github.com/ibm-capi/libcxl
What: /sys/class/cxl/<card>/psl_revision
Date: September 2014
Contact: linuxppc-dev@lists.ozlabs.org
Description: read only
Identifies the revision level of the PSL.
+Users: https://github.com/ibm-capi/libcxl
What: /sys/class/cxl/<card>/base_image
Date: September 2014
@@ -162,6 +180,7 @@ Description: read only
that support loadable PSLs. For FPGAs this field identifies
the image contained in the on-adapter flash which is loaded
during the initial program load.
+Users: https://github.com/ibm-capi/libcxl
What: /sys/class/cxl/<card>/image_loaded
Date: September 2014
@@ -169,6 +188,7 @@ Contact: linuxppc-dev@lists.ozlabs.org
Description: read only
Will return "user" or "factory" depending on the image loaded
onto the card.
+Users: https://github.com/ibm-capi/libcxl
What: /sys/class/cxl/<card>/load_image_on_perst
Date: December 2014
@@ -183,6 +203,7 @@ Description: read/write
user or factory image to be loaded.
Default is to reload on PERST whichever image the card has
loaded.
+Users: https://github.com/ibm-capi/libcxl
What: /sys/class/cxl/<card>/reset
Date: October 2014
@@ -190,3 +211,4 @@ Contact: linuxppc-dev@lists.ozlabs.org
Description: write only
Writing 1 will issue a PERST to card which may cause the card
to reload the FPGA depending on load_image_on_perst.
+Users: https://github.com/ibm-capi/libcxl
diff --git a/Documentation/powerpc/cxl.txt b/Documentation/powerpc/cxl.txt
index 2c71ecc..2a230d01 100644
--- a/Documentation/powerpc/cxl.txt
+++ b/Documentation/powerpc/cxl.txt
@@ -133,6 +133,9 @@ User API
The following file operations are supported on both slave and
master devices.
+ A userspace library libcxl is avaliable here:
+ https://github.com/ibm-capi/libcxl
+ This provides a C interface to this kernel API.
open
----
@@ -366,6 +369,7 @@ Sysfs Class
enumeration and tuning of the accelerators. Its layout is
described in Documentation/ABI/testing/sysfs-class-cxl
+
Udev rules
==========
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 08/24] cxl: Add shutdown hook
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
` (6 preceding siblings ...)
2015-05-27 6:07 ` [PATCH v3 07/24] cxl: Document external user of existing API Michael Neuling
@ 2015-05-27 6:07 ` Michael Neuling
2015-05-27 6:07 ` [PATCH v3 09/24] cxl: Remove unnecessarily verbose print in cxl_remove() Michael Neuling
` (15 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:07 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
Signed-off-by: Michael Neuling <mikey@neuling.org>
Acked-by: Ian Munsie <imunsie@au1.ibm.com>
---
drivers/misc/cxl/pci.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index b80f867..a9c90d2 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -1135,4 +1135,5 @@ struct pci_driver cxl_pci_driver = {
.id_table = cxl_pci_tbl,
.probe = cxl_probe,
.remove = cxl_remove,
+ .shutdown = cxl_remove,
};
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 09/24] cxl: Remove unnecessarily verbose print in cxl_remove()
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
` (7 preceding siblings ...)
2015-05-27 6:07 ` [PATCH v3 08/24] cxl: Add shutdown hook Michael Neuling
@ 2015-05-27 6:07 ` Michael Neuling
2015-05-27 6:07 ` [PATCH v3 10/24] cxl: Re-order card init to check the VSEC earlier Michael Neuling
` (14 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:07 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
Signed-off-by: Michael Neuling <mikey@neuling.org>
Acked-by: Ian Munsie <imunsie@au1.ibm.com>
---
drivers/misc/cxl/pci.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index a9c90d2..8076aa3 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -1119,8 +1119,6 @@ static void cxl_remove(struct pci_dev *dev)
struct cxl *adapter = pci_get_drvdata(dev);
int afu;
- dev_warn(&dev->dev, "pci remove\n");
-
/*
* Lock to prevent someone grabbing a ref through the adapter list as
* we are removing it
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 10/24] cxl: Re-order card init to check the VSEC earlier
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
` (8 preceding siblings ...)
2015-05-27 6:07 ` [PATCH v3 09/24] cxl: Remove unnecessarily verbose print in cxl_remove() Michael Neuling
@ 2015-05-27 6:07 ` Michael Neuling
2015-05-27 6:07 ` [PATCH v3 11/24] cxl: Fix error path on probe Michael Neuling
` (13 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:07 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
From: Ian Munsie <imunsie@au1.ibm.com>
When we expose AFUs as virtual PCI devices, they may look like the physical
CAPI PCI card. ie they may have the same vendor/device IDs.
We want to avoid these AFUs binding to this driver and any init this driver may
do.
Re-order card init to check the VSEC earlier before assigning BARs or
activating CXL. Also change the dev used in early prints as the adapter struct
may not be inited at this earlier stage.
Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
Signed-off-by: Michael Neuling <mikey@neuling.org>
---
drivers/misc/cxl/pci.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index 8076aa3..3f0caa2 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -884,13 +884,13 @@ static int cxl_read_vsec(struct cxl *adapter, struct pci_dev *dev)
u16 vseclen;
if (!(vsec = find_cxl_vsec(dev))) {
- dev_err(&adapter->dev, "ABORTING: CXL VSEC not found!\n");
+ dev_err(&dev->dev, "ABORTING: CXL VSEC not found!\n");
return -ENODEV;
}
CXL_READ_VSEC_LENGTH(dev, vsec, &vseclen);
if (vseclen < CXL_VSEC_MIN_SIZE) {
- pr_err("ABORTING: CXL VSEC too short\n");
+ dev_err(&dev->dev, "ABORTING: CXL VSEC too short\n");
return -EINVAL;
}
@@ -927,24 +927,24 @@ static int cxl_vsec_looks_ok(struct cxl *adapter, struct pci_dev *dev)
return -EBUSY;
if (adapter->vsec_status & CXL_UNSUPPORTED_FEATURES) {
- dev_err(&adapter->dev, "ABORTING: CXL requires unsupported features\n");
+ dev_err(&dev->dev, "ABORTING: CXL requires unsupported features\n");
return -EINVAL;
}
if (!adapter->slices) {
/* Once we support dynamic reprogramming we can use the card if
* it supports loadable AFUs */
- dev_err(&adapter->dev, "ABORTING: Device has no AFUs\n");
+ dev_err(&dev->dev, "ABORTING: Device has no AFUs\n");
return -EINVAL;
}
if (!adapter->afu_desc_off || !adapter->afu_desc_size) {
- dev_err(&adapter->dev, "ABORTING: VSEC shows no AFU descriptors\n");
+ dev_err(&dev->dev, "ABORTING: VSEC shows no AFU descriptors\n");
return -EINVAL;
}
if (adapter->ps_size > p2_size(dev) - adapter->ps_off) {
- dev_err(&adapter->dev, "ABORTING: Problem state size larger than "
+ dev_err(&dev->dev, "ABORTING: Problem state size larger than "
"available in BAR2: 0x%llx > 0x%llx\n",
adapter->ps_size, p2_size(dev) - adapter->ps_off);
return -EINVAL;
@@ -993,6 +993,15 @@ static struct cxl *cxl_init_adapter(struct pci_dev *dev)
if (!(adapter = cxl_alloc_adapter(dev)))
return ERR_PTR(-ENOMEM);
+ if ((rc = cxl_read_vsec(adapter, dev)))
+ goto err1;
+
+ if ((rc = cxl_vsec_looks_ok(adapter, dev)))
+ goto err1;
+
+ if ((rc = setup_cxl_bars(dev)))
+ goto err1;
+
if ((rc = switch_card_to_cxl(dev)))
goto err1;
@@ -1002,12 +1011,6 @@ static struct cxl *cxl_init_adapter(struct pci_dev *dev)
if ((rc = dev_set_name(&adapter->dev, "card%i", adapter->adapter_num)))
goto err2;
- if ((rc = cxl_read_vsec(adapter, dev)))
- goto err2;
-
- if ((rc = cxl_vsec_looks_ok(adapter, dev)))
- goto err2;
-
if ((rc = cxl_update_image_control(adapter)))
goto err2;
@@ -1092,9 +1095,6 @@ static int cxl_probe(struct pci_dev *dev, const struct pci_device_id *id)
if (cxl_verbose)
dump_cxl_config_space(dev);
- if ((rc = setup_cxl_bars(dev)))
- return rc;
-
if ((rc = pci_enable_device(dev))) {
dev_err(&dev->dev, "pci_enable_device failed: %i\n", rc);
return rc;
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 11/24] cxl: Fix error path on probe
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
` (9 preceding siblings ...)
2015-05-27 6:07 ` [PATCH v3 10/24] cxl: Re-order card init to check the VSEC earlier Michael Neuling
@ 2015-05-27 6:07 ` Michael Neuling
2015-05-27 6:07 ` [PATCH v3 12/24] cxl: Dump debug info on the AFU configuration record Michael Neuling
` (12 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:07 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
When probing we call pci_enable_device() but don't call pci_disable_device() on
fail. This causes refcounting issues in the PCI subsystem if a second driver
tries to bind to the same device.
This patch adds the pci_disable_device() to the probe error path. This error
path is hit when this cxl driver tries to bind to AFUs (on the vPHB) rather
than the physical device.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Acked-by: Ian Munsie <imunsie@au1.ibm.com>
---
drivers/misc/cxl/pci.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index 3f0caa2..0d429b0 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -1103,6 +1103,7 @@ static int cxl_probe(struct pci_dev *dev, const struct pci_device_id *id)
adapter = cxl_init_adapter(dev);
if (IS_ERR(adapter)) {
dev_err(&dev->dev, "cxl_init_adapter failed: %li\n", PTR_ERR(adapter));
+ pci_disable_device(dev);
return PTR_ERR(adapter);
}
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 12/24] cxl: Dump debug info on the AFU configuration record
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
` (10 preceding siblings ...)
2015-05-27 6:07 ` [PATCH v3 11/24] cxl: Fix error path on probe Michael Neuling
@ 2015-05-27 6:07 ` Michael Neuling
2015-05-27 6:07 ` [PATCH v3 13/24] cxl: Add cookie parameter to afu_release_irqs() Michael Neuling
` (11 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:07 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
Now that we parse the AFU Configuration record, dump some info on it when in
debug mode.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Acked-by: Ian Munsie <imunsie@au1.ibm.com>
---
drivers/misc/cxl/pci.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index 0d429b0..f837d1b 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -90,6 +90,7 @@
/* This works a little different than the p1/p2 register accesses to make it
* easier to pull out individual fields */
#define AFUD_READ(afu, off) in_be64(afu->afu_desc_mmio + off)
+#define AFUD_READ_LE(afu, off) in_le64(afu->afu_desc_mmio + off)
#define EXTRACT_PPC_BIT(val, bit) (!!(val & PPC_BIT(bit)))
#define EXTRACT_PPC_BITS(val, bs, be) ((val & PPC_BITMASK(bs, be)) >> PPC_BITLSHIFT(be))
@@ -286,7 +287,8 @@ static void dump_cxl_config_space(struct pci_dev *dev)
static void dump_afu_descriptor(struct cxl_afu *afu)
{
- u64 val;
+ u64 val, afu_cr_num, afu_cr_off, afu_cr_len;
+ int i;
#define show_reg(name, what) \
dev_info(&afu->dev, "afu desc: %30s: %#llx\n", name, what)
@@ -296,6 +298,7 @@ static void dump_afu_descriptor(struct cxl_afu *afu)
show_reg("num_of_processes", AFUD_NUM_PROCS(val));
show_reg("num_of_afu_CRs", AFUD_NUM_CRS(val));
show_reg("req_prog_mode", val & 0xffffULL);
+ afu_cr_num = AFUD_NUM_CRS(val);
val = AFUD_READ(afu, 0x8);
show_reg("Reserved", val);
@@ -307,8 +310,10 @@ static void dump_afu_descriptor(struct cxl_afu *afu)
val = AFUD_READ_CR(afu);
show_reg("Reserved", (val >> (63-7)) & 0xff);
show_reg("AFU_CR_len", AFUD_CR_LEN(val));
+ afu_cr_len = AFUD_CR_LEN(val) * 256;
val = AFUD_READ_CR_OFF(afu);
+ afu_cr_off = val;
show_reg("AFU_CR_offset", val);
val = AFUD_READ_PPPSA(afu);
@@ -325,6 +330,11 @@ static void dump_afu_descriptor(struct cxl_afu *afu)
val = AFUD_READ_EB_OFF(afu);
show_reg("AFU_EB_offset", val);
+ for (i = 0; i < afu_cr_num; i++) {
+ val = AFUD_READ_LE(afu, afu_cr_off + i * afu_cr_len);
+ show_reg("CR Vendor", val & 0xffff);
+ show_reg("CR Device", (val >> 16) & 0xffff);
+ }
#undef show_reg
}
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 13/24] cxl: Add cookie parameter to afu_release_irqs()
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
` (11 preceding siblings ...)
2015-05-27 6:07 ` [PATCH v3 12/24] cxl: Dump debug info on the AFU configuration record Michael Neuling
@ 2015-05-27 6:07 ` Michael Neuling
2015-05-27 6:07 ` [PATCH v3 14/24] cxl: Rework detach context functions Michael Neuling
` (10 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:07 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
Add cookie parameter to afu_release_irqs() so that we can pass in a different
cookie than the context structure. This will be useful for other kernel
drivers that want to call this but get their own cookie back in the interrupt
handler.
Update all existing call sites.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Acked-by: Ian Munsie <imunsie@au1.ibm.com>
---
drivers/misc/cxl/context.c | 2 +-
drivers/misc/cxl/cxl.h | 2 +-
drivers/misc/cxl/file.c | 2 +-
drivers/misc/cxl/irq.c | 4 ++--
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c
index 78ce990..36bb8e4 100644
--- a/drivers/misc/cxl/context.c
+++ b/drivers/misc/cxl/context.c
@@ -186,7 +186,7 @@ static void __detach_context(struct cxl_context *ctx)
return;
WARN_ON(cxl_detach_process(ctx));
- afu_release_irqs(ctx);
+ afu_release_irqs(ctx, ctx);
flush_work(&ctx->fault_work); /* Only needed for dedicated process */
wake_up_all(&ctx->wq);
}
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index f0b6727..7c014b8 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -609,7 +609,7 @@ void cxl_release_psl_err_irq(struct cxl *adapter);
int cxl_register_serr_irq(struct cxl_afu *afu);
void cxl_release_serr_irq(struct cxl_afu *afu);
int afu_register_irqs(struct cxl_context *ctx, u32 count);
-void afu_release_irqs(struct cxl_context *ctx);
+void afu_release_irqs(struct cxl_context *ctx, void *cookie);
irqreturn_t cxl_slice_irq_err(int irq, void *data);
int cxl_debugfs_init(void);
diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c
index 2364bca..5377c8b 100644
--- a/drivers/misc/cxl/file.c
+++ b/drivers/misc/cxl/file.c
@@ -191,7 +191,7 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,
if ((rc = cxl_attach_process(ctx, false, work.work_element_descriptor,
amr))) {
- afu_release_irqs(ctx);
+ afu_release_irqs(ctx, ctx);
goto out;
}
diff --git a/drivers/misc/cxl/irq.c b/drivers/misc/cxl/irq.c
index c8929c5..c740c7b 100644
--- a/drivers/misc/cxl/irq.c
+++ b/drivers/misc/cxl/irq.c
@@ -477,7 +477,7 @@ out:
return -ENOMEM;
}
-void afu_release_irqs(struct cxl_context *ctx)
+void afu_release_irqs(struct cxl_context *ctx, void *cookie)
{
irq_hw_number_t hwirq;
unsigned int virq;
@@ -488,7 +488,7 @@ void afu_release_irqs(struct cxl_context *ctx)
for (i = 0; i < ctx->irqs.range[r]; hwirq++, i++) {
virq = irq_find_mapping(NULL, hwirq);
if (virq)
- cxl_unmap_irq(virq, ctx);
+ cxl_unmap_irq(virq, cookie);
}
}
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 14/24] cxl: Rework detach context functions
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
` (12 preceding siblings ...)
2015-05-27 6:07 ` [PATCH v3 13/24] cxl: Add cookie parameter to afu_release_irqs() Michael Neuling
@ 2015-05-27 6:07 ` Michael Neuling
2015-05-27 6:07 ` [PATCH v3 15/24] cxl: cxl_afu_reset() -> __cxl_afu_reset() Michael Neuling
` (9 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:07 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
Rework __detach_context() and cxl_context_detach() so we can reuse them in the
kernel API.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Acked-by: Ian Munsie <imunsie@au1.ibm.com>
---
drivers/misc/cxl/context.c | 20 +++++++++++++-------
drivers/misc/cxl/cxl.h | 1 +
2 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c
index 36bb8e4..7d857b7 100644
--- a/drivers/misc/cxl/context.c
+++ b/drivers/misc/cxl/context.c
@@ -174,7 +174,7 @@ int cxl_context_iomap(struct cxl_context *ctx, struct vm_area_struct *vma)
* return until all outstanding interrupts for this context have completed. The
* hardware should no longer access *ctx after this has returned.
*/
-static void __detach_context(struct cxl_context *ctx)
+int __detach_context(struct cxl_context *ctx)
{
enum cxl_context_status status;
@@ -183,12 +183,10 @@ static void __detach_context(struct cxl_context *ctx)
ctx->status = CLOSED;
mutex_unlock(&ctx->status_mutex);
if (status != STARTED)
- return;
+ return -EBUSY;
WARN_ON(cxl_detach_process(ctx));
- afu_release_irqs(ctx, ctx);
- flush_work(&ctx->fault_work); /* Only needed for dedicated process */
- wake_up_all(&ctx->wq);
+ return 0;
}
/*
@@ -199,7 +197,15 @@ static void __detach_context(struct cxl_context *ctx)
*/
void cxl_context_detach(struct cxl_context *ctx)
{
- __detach_context(ctx);
+ int rc;
+
+ rc = __detach_context(ctx);
+ if (rc)
+ return;
+
+ afu_release_irqs(ctx, ctx);
+ flush_work(&ctx->fault_work); /* Only needed for dedicated process */
+ wake_up_all(&ctx->wq);
}
/*
@@ -216,7 +222,7 @@ void cxl_context_detach_all(struct cxl_afu *afu)
* Anything done in here needs to be setup before the IDR is
* created and torn down after the IDR removed
*/
- __detach_context(ctx);
+ cxl_context_detach(ctx);
/*
* We are force detaching - remove any active PSA mappings so
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index 7c014b8..296a077 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -632,6 +632,7 @@ int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master,
struct address_space *mapping);
void cxl_context_free(struct cxl_context *ctx);
int cxl_context_iomap(struct cxl_context *ctx, struct vm_area_struct *vma);
+int __detach_context(struct cxl_context *ctx);
/* This matches the layout of the H_COLLECT_CA_INT_INFO retbuf */
struct cxl_irq_info {
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 15/24] cxl: cxl_afu_reset() -> __cxl_afu_reset()
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
` (13 preceding siblings ...)
2015-05-27 6:07 ` [PATCH v3 14/24] cxl: Rework detach context functions Michael Neuling
@ 2015-05-27 6:07 ` Michael Neuling
2015-05-27 6:07 ` [PATCH v3 16/24] cxl: Export some symbols Michael Neuling
` (8 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:07 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
Rename cxl_afu_reset() to __cxl_afu_reset() to we can reuse this function name
in the API.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Acked-by: Ian Munsie <imunsie@au1.ibm.com>
---
drivers/misc/cxl/cxl.h | 2 +-
drivers/misc/cxl/native.c | 8 ++++----
drivers/misc/cxl/pci.c | 4 ++--
drivers/misc/cxl/sysfs.c | 2 +-
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index 296a077..8180680 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -657,7 +657,7 @@ int cxl_check_error(struct cxl_afu *afu);
int cxl_afu_slbia(struct cxl_afu *afu);
int cxl_tlb_slb_invalidate(struct cxl *adapter);
int cxl_afu_disable(struct cxl_afu *afu);
-int cxl_afu_reset(struct cxl_afu *afu);
+int __cxl_afu_reset(struct cxl_afu *afu);
int cxl_psl_purge(struct cxl_afu *afu);
void cxl_stop_trace(struct cxl *cxl);
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c
index 29185fc..f85b6ae 100644
--- a/drivers/misc/cxl/native.c
+++ b/drivers/misc/cxl/native.c
@@ -73,7 +73,7 @@ int cxl_afu_disable(struct cxl_afu *afu)
}
/* This will disable as well as reset */
-int cxl_afu_reset(struct cxl_afu *afu)
+int __cxl_afu_reset(struct cxl_afu *afu)
{
pr_devel("AFU reset request\n");
@@ -495,7 +495,7 @@ static int deactivate_afu_directed(struct cxl_afu *afu)
cxl_sysfs_afu_m_remove(afu);
cxl_chardev_afu_remove(afu);
- cxl_afu_reset(afu);
+ __cxl_afu_reset(afu);
cxl_afu_disable(afu);
cxl_psl_purge(afu);
@@ -566,7 +566,7 @@ static int attach_dedicated(struct cxl_context *ctx, u64 wed, u64 amr)
/* master only context for dedicated */
assign_psn_space(ctx);
- if ((rc = cxl_afu_reset(afu)))
+ if ((rc = __cxl_afu_reset(afu)))
return rc;
cxl_p2n_write(afu, CXL_PSL_WED_An, wed);
@@ -629,7 +629,7 @@ int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u64 amr)
static inline int detach_process_native_dedicated(struct cxl_context *ctx)
{
- cxl_afu_reset(ctx->afu);
+ __cxl_afu_reset(ctx->afu);
cxl_afu_disable(ctx->afu);
cxl_psl_purge(ctx->afu);
return 0;
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index f837d1b..3879bdf 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -641,7 +641,7 @@ static int sanitise_afu_regs(struct cxl_afu *afu)
reg = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
if ((reg & CXL_AFU_Cntl_An_ES_MASK) != CXL_AFU_Cntl_An_ES_Disabled) {
dev_warn(&afu->dev, "WARNING: AFU was not disabled: %#.16llx\n", reg);
- if (cxl_afu_reset(afu))
+ if (__cxl_afu_reset(afu))
return -EIO;
if (cxl_afu_disable(afu))
return -EIO;
@@ -701,7 +701,7 @@ static int cxl_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev)
goto err2;
/* We need to reset the AFU before we can read the AFU descriptor */
- if ((rc = cxl_afu_reset(afu)))
+ if ((rc = __cxl_afu_reset(afu)))
goto err2;
if (cxl_verbose)
diff --git a/drivers/misc/cxl/sysfs.c b/drivers/misc/cxl/sysfs.c
index d0c38c7..2d6e104 100644
--- a/drivers/misc/cxl/sysfs.c
+++ b/drivers/misc/cxl/sysfs.c
@@ -185,7 +185,7 @@ static ssize_t reset_store_afu(struct device *device,
goto err;
}
- if ((rc = cxl_afu_reset(afu)))
+ if ((rc = __cxl_afu_reset(afu)))
goto err;
rc = count;
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 16/24] cxl: Export some symbols
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
` (14 preceding siblings ...)
2015-05-27 6:07 ` [PATCH v3 15/24] cxl: cxl_afu_reset() -> __cxl_afu_reset() Michael Neuling
@ 2015-05-27 6:07 ` Michael Neuling
2015-05-27 6:07 ` [PATCH v3 17/24] cxl: Only check pid for userspace contexts Michael Neuling
` (7 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:07 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
Export some symbols which will soon be used elsewhere in this driver.
Now they are global we rename them so to avoid collisions.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Acked-by: Ian Munsie <imunsie@au1.ibm.com>
---
drivers/misc/cxl/cxl.h | 5 +++++
drivers/misc/cxl/native.c | 10 +++++-----
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index 8180680..58a9b2b 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -632,6 +632,9 @@ int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master,
struct address_space *mapping);
void cxl_context_free(struct cxl_context *ctx);
int cxl_context_iomap(struct cxl_context *ctx, struct vm_area_struct *vma);
+unsigned int cxl_map_irq(struct cxl *adapter, irq_hw_number_t hwirq,
+ irq_handler_t handler, void *cookie, const char *name);
+void cxl_unmap_irq(unsigned int virq, void *cookie);
int __detach_context(struct cxl_context *ctx);
/* This matches the layout of the H_COLLECT_CA_INT_INFO retbuf */
@@ -646,6 +649,7 @@ struct cxl_irq_info {
u64 padding[3]; /* to match the expected retbuf size for plpar_hcall9 */
};
+void cxl_assign_psn_space(struct cxl_context *ctx);
int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed,
u64 amr);
int cxl_detach_process(struct cxl_context *ctx);
@@ -658,6 +662,7 @@ int cxl_afu_slbia(struct cxl_afu *afu);
int cxl_tlb_slb_invalidate(struct cxl *adapter);
int cxl_afu_disable(struct cxl_afu *afu);
int __cxl_afu_reset(struct cxl_afu *afu);
+int cxl_afu_check_and_enable(struct cxl_afu *afu);
int cxl_psl_purge(struct cxl_afu *afu);
void cxl_stop_trace(struct cxl *cxl);
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c
index f85b6ae..615ccbf 100644
--- a/drivers/misc/cxl/native.c
+++ b/drivers/misc/cxl/native.c
@@ -83,7 +83,7 @@ int __cxl_afu_reset(struct cxl_afu *afu)
false);
}
-static int afu_check_and_enable(struct cxl_afu *afu)
+int cxl_afu_check_and_enable(struct cxl_afu *afu)
{
if (afu->enabled)
return 0;
@@ -379,7 +379,7 @@ static int remove_process_element(struct cxl_context *ctx)
}
-static void assign_psn_space(struct cxl_context *ctx)
+void cxl_assign_psn_space(struct cxl_context *ctx)
{
if (!ctx->afu->pp_size || ctx->master) {
ctx->psn_phys = ctx->afu->psn_phys;
@@ -435,7 +435,7 @@ static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr)
u64 sr;
int r, result;
- assign_psn_space(ctx);
+ cxl_assign_psn_space(ctx);
ctx->elem->ctxtime = 0; /* disable */
ctx->elem->lpid = cpu_to_be32(mfspr(SPRN_LPID));
@@ -477,7 +477,7 @@ static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr)
ctx->elem->common.wed = cpu_to_be64(wed);
/* first guy needs to enable */
- if ((result = afu_check_and_enable(ctx->afu)))
+ if ((result = cxl_afu_check_and_enable(ctx->afu)))
return result;
add_process_element(ctx);
@@ -564,7 +564,7 @@ static int attach_dedicated(struct cxl_context *ctx, u64 wed, u64 amr)
cxl_p2n_write(afu, CXL_PSL_AMR_An, amr);
/* master only context for dedicated */
- assign_psn_space(ctx);
+ cxl_assign_psn_space(ctx);
if ((rc = __cxl_afu_reset(afu)))
return rc;
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 17/24] cxl: Only check pid for userspace contexts
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
` (15 preceding siblings ...)
2015-05-27 6:07 ` [PATCH v3 16/24] cxl: Export some symbols Michael Neuling
@ 2015-05-27 6:07 ` Michael Neuling
2015-05-27 6:07 ` [PATCH v3 18/24] cxl: Split afu_register_irqs() function Michael Neuling
` (6 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:07 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
We only need to check the pid attached to this context for userspace contexts.
Kernel contexts can skip this check.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Acked-by: Ian Munsie <imunsie@au1.ibm.com>
---
drivers/misc/cxl/fault.c | 34 +++++++++++++++++++---------------
1 file changed, 19 insertions(+), 15 deletions(-)
diff --git a/drivers/misc/cxl/fault.c b/drivers/misc/cxl/fault.c
index 5286b8b..25a5418 100644
--- a/drivers/misc/cxl/fault.c
+++ b/drivers/misc/cxl/fault.c
@@ -172,8 +172,8 @@ void cxl_handle_fault(struct work_struct *fault_work)
container_of(fault_work, struct cxl_context, fault_work);
u64 dsisr = ctx->dsisr;
u64 dar = ctx->dar;
- struct task_struct *task;
- struct mm_struct *mm;
+ struct task_struct *task = NULL;
+ struct mm_struct *mm = NULL;
if (cxl_p2n_read(ctx->afu, CXL_PSL_DSISR_An) != dsisr ||
cxl_p2n_read(ctx->afu, CXL_PSL_DAR_An) != dar ||
@@ -194,17 +194,19 @@ void cxl_handle_fault(struct work_struct *fault_work)
pr_devel("CXL BOTTOM HALF handling fault for afu pe: %i. "
"DSISR: %#llx DAR: %#llx\n", ctx->pe, dsisr, dar);
- if (!(task = get_pid_task(ctx->pid, PIDTYPE_PID))) {
- pr_devel("cxl_handle_fault unable to get task %i\n",
- pid_nr(ctx->pid));
- cxl_ack_ae(ctx);
- return;
- }
- if (!(mm = get_task_mm(task))) {
- pr_devel("cxl_handle_fault unable to get mm %i\n",
- pid_nr(ctx->pid));
- cxl_ack_ae(ctx);
- goto out;
+ if (!ctx->kernel) {
+ if (!(task = get_pid_task(ctx->pid, PIDTYPE_PID))) {
+ pr_devel("cxl_handle_fault unable to get task %i\n",
+ pid_nr(ctx->pid));
+ cxl_ack_ae(ctx);
+ return;
+ }
+ if (!(mm = get_task_mm(task))) {
+ pr_devel("cxl_handle_fault unable to get mm %i\n",
+ pid_nr(ctx->pid));
+ cxl_ack_ae(ctx);
+ goto out;
+ }
}
if (dsisr & CXL_PSL_DSISR_An_DS)
@@ -214,9 +216,11 @@ void cxl_handle_fault(struct work_struct *fault_work)
else
WARN(1, "cxl_handle_fault has nothing to handle\n");
- mmput(mm);
+ if (mm)
+ mmput(mm);
out:
- put_task_struct(task);
+ if (task)
+ put_task_struct(task);
}
static void cxl_prefault_one(struct cxl_context *ctx, u64 ea)
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 18/24] cxl: Split afu_register_irqs() function
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
` (16 preceding siblings ...)
2015-05-27 6:07 ` [PATCH v3 17/24] cxl: Only check pid for userspace contexts Michael Neuling
@ 2015-05-27 6:07 ` Michael Neuling
2015-05-27 6:07 ` [PATCH v3 19/24] cxl: Configure PSL for kernel contexts and merge code Michael Neuling
` (5 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:07 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
Split the afu_register_irqs() function so that different parts can
be useful elsewhere.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Acked-by: Ian Munsie <imunsie@au1.ibm.com>
---
drivers/misc/cxl/cxl.h | 1 +
drivers/misc/cxl/irq.c | 31 ++++++++++++++++++++++++-------
2 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index 58a9b2b..bbc7fd0 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -668,5 +668,6 @@ int cxl_psl_purge(struct cxl_afu *afu);
void cxl_stop_trace(struct cxl *cxl);
extern struct pci_driver cxl_pci_driver;
+int afu_allocate_irqs(struct cxl_context *ctx, u32 count);
#endif
diff --git a/drivers/misc/cxl/irq.c b/drivers/misc/cxl/irq.c
index c740c7b..212790b 100644
--- a/drivers/misc/cxl/irq.c
+++ b/drivers/misc/cxl/irq.c
@@ -416,9 +416,8 @@ void afu_irq_name_free(struct cxl_context *ctx)
}
}
-int afu_register_irqs(struct cxl_context *ctx, u32 count)
+int afu_allocate_irqs(struct cxl_context *ctx, u32 count)
{
- irq_hw_number_t hwirq;
int rc, r, i, j = 1;
struct cxl_irq_name *irq_name;
@@ -458,6 +457,18 @@ int afu_register_irqs(struct cxl_context *ctx, u32 count)
j++;
}
}
+ return 0;
+
+out:
+ afu_irq_name_free(ctx);
+ return -ENOMEM;
+}
+
+void afu_register_hwirqs(struct cxl_context *ctx)
+{
+ irq_hw_number_t hwirq;
+ struct cxl_irq_name *irq_name;
+ int r,i;
/* We've allocated all memory now, so let's do the irq allocations */
irq_name = list_first_entry(&ctx->irq_names, struct cxl_irq_name, list);
@@ -469,13 +480,19 @@ int afu_register_irqs(struct cxl_context *ctx, u32 count)
irq_name = list_next_entry(irq_name, list);
}
}
+}
- return 0;
+int afu_register_irqs(struct cxl_context *ctx, u32 count)
+{
+ int rc;
-out:
- afu_irq_name_free(ctx);
- return -ENOMEM;
-}
+ rc = afu_allocate_irqs(ctx, count);
+ if (rc)
+ return rc;
+
+ afu_register_hwirqs(ctx);
+ return 0;
+ }
void afu_release_irqs(struct cxl_context *ctx, void *cookie)
{
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 19/24] cxl: Configure PSL for kernel contexts and merge code
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
` (17 preceding siblings ...)
2015-05-27 6:07 ` [PATCH v3 18/24] cxl: Split afu_register_irqs() function Michael Neuling
@ 2015-05-27 6:07 ` Michael Neuling
2015-05-27 6:07 ` [PATCH v3 20/24] cxl: Rework context lifetimes Michael Neuling
` (4 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:07 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
This updates AFU directed and dedicated modes for contexts attached to the
kernel.
The SR (similar to the MSR in the core) calculation is getting
quite complex and is duplicated in AFU directed and dedicated
modes. This patch also merges this SR calculation for these modes.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Acked-by: Ian Munsie <imunsie@au1.ibm.com>
---
drivers/misc/cxl/native.c | 63 ++++++++++++++++++++++++++---------------------
1 file changed, 35 insertions(+), 28 deletions(-)
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c
index 615ccbf..a4b40d7 100644
--- a/drivers/misc/cxl/native.c
+++ b/drivers/misc/cxl/native.c
@@ -430,9 +430,30 @@ err:
#define set_endian(sr) ((sr) &= ~(CXL_PSL_SR_An_LE))
#endif
+static u64 calculate_sr(struct cxl_context *ctx)
+{
+ u64 sr = 0;
+
+ if (ctx->master)
+ sr |= CXL_PSL_SR_An_MP;
+ if (mfspr(SPRN_LPCR) & LPCR_TC)
+ sr |= CXL_PSL_SR_An_TC;
+ if (ctx->kernel) {
+ sr |= CXL_PSL_SR_An_R | (mfmsr() & MSR_SF);
+ sr |= CXL_PSL_SR_An_HV;
+ } else {
+ sr |= CXL_PSL_SR_An_PR | CXL_PSL_SR_An_R;
+ set_endian(sr);
+ sr &= ~(CXL_PSL_SR_An_HV);
+ if (!test_tsk_thread_flag(current, TIF_32BIT))
+ sr |= CXL_PSL_SR_An_SF;
+ }
+ return sr;
+}
+
static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr)
{
- u64 sr;
+ u32 pid;
int r, result;
cxl_assign_psn_space(ctx);
@@ -442,22 +463,13 @@ static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr)
ctx->elem->haurp = 0; /* disable */
ctx->elem->sdr = cpu_to_be64(mfspr(SPRN_SDR1));
- sr = 0;
- if (ctx->master)
- sr |= CXL_PSL_SR_An_MP;
- if (mfspr(SPRN_LPCR) & LPCR_TC)
- sr |= CXL_PSL_SR_An_TC;
- /* HV=0, PR=1, R=1 for userspace
- * For kernel contexts: this would need to change
- */
- sr |= CXL_PSL_SR_An_PR | CXL_PSL_SR_An_R;
- set_endian(sr);
- sr &= ~(CXL_PSL_SR_An_HV);
- if (!test_tsk_thread_flag(current, TIF_32BIT))
- sr |= CXL_PSL_SR_An_SF;
- ctx->elem->common.pid = cpu_to_be32(current->pid);
+ pid = current->pid;
+ if (ctx->kernel)
+ pid = 0;
ctx->elem->common.tid = 0;
- ctx->elem->sr = cpu_to_be64(sr);
+ ctx->elem->common.pid = cpu_to_be32(pid);
+
+ ctx->elem->sr = cpu_to_be64(calculate_sr(ctx));
ctx->elem->common.csrp = 0; /* disable */
ctx->elem->common.aurp0 = 0; /* disable */
@@ -530,20 +542,15 @@ static int activate_dedicated_process(struct cxl_afu *afu)
static int attach_dedicated(struct cxl_context *ctx, u64 wed, u64 amr)
{
struct cxl_afu *afu = ctx->afu;
- u64 sr;
+ u64 pid;
int rc;
- sr = 0;
- set_endian(sr);
- if (ctx->master)
- sr |= CXL_PSL_SR_An_MP;
- if (mfspr(SPRN_LPCR) & LPCR_TC)
- sr |= CXL_PSL_SR_An_TC;
- sr |= CXL_PSL_SR_An_PR | CXL_PSL_SR_An_R;
- if (!test_tsk_thread_flag(current, TIF_32BIT))
- sr |= CXL_PSL_SR_An_SF;
- cxl_p2n_write(afu, CXL_PSL_PID_TID_An, (u64)current->pid << 32);
- cxl_p1n_write(afu, CXL_PSL_SR_An, sr);
+ pid = (u64)current->pid << 32;
+ if (ctx->kernel)
+ pid = 0;
+ cxl_p2n_write(afu, CXL_PSL_PID_TID_An, pid);
+
+ cxl_p1n_write(afu, CXL_PSL_SR_An, calculate_sr(ctx));
if ((rc = cxl_write_sstp(afu, ctx->sstp0, ctx->sstp1)))
return rc;
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 20/24] cxl: Rework context lifetimes
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
` (18 preceding siblings ...)
2015-05-27 6:07 ` [PATCH v3 19/24] cxl: Configure PSL for kernel contexts and merge code Michael Neuling
@ 2015-05-27 6:07 ` Michael Neuling
2015-05-27 6:07 ` [PATCH v3 21/24] cxl: Cleanup Makefile Michael Neuling
` (3 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:07 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
This reworks contexts lifetimes a bit to enable the kernel API where we may
want to reuse contexts. Here we will want to start and stop contexts without
freeing them.
Start context does the get pid & ctx so stop context will need to do the puts.
Here we move put pid & ctx to the detach context path which will become part of
the stop context path.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Acked-by: Ian Munsie <imunsie@au1.ibm.com>
---
drivers/misc/cxl/context.c | 5 +++--
drivers/misc/cxl/file.c | 1 -
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c
index 7d857b7..2a4c80a 100644
--- a/drivers/misc/cxl/context.c
+++ b/drivers/misc/cxl/context.c
@@ -186,6 +186,9 @@ int __detach_context(struct cxl_context *ctx)
return -EBUSY;
WARN_ON(cxl_detach_process(ctx));
+ flush_work(&ctx->fault_work); /* Only needed for dedicated process */
+ put_pid(ctx->pid);
+ cxl_ctx_put();
return 0;
}
@@ -204,7 +207,6 @@ void cxl_context_detach(struct cxl_context *ctx)
return;
afu_release_irqs(ctx, ctx);
- flush_work(&ctx->fault_work); /* Only needed for dedicated process */
wake_up_all(&ctx->wq);
}
@@ -245,7 +247,6 @@ static void reclaim_ctx(struct rcu_head *rcu)
free_page((u64)ctx->sstp);
ctx->sstp = NULL;
- put_pid(ctx->pid);
kfree(ctx);
}
diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c
index 5377c8b..f7653fc 100644
--- a/drivers/misc/cxl/file.c
+++ b/drivers/misc/cxl/file.c
@@ -128,7 +128,6 @@ static int afu_release(struct inode *inode, struct file *file)
*/
cxl_context_free(ctx);
- cxl_ctx_put();
return 0;
}
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 21/24] cxl: Cleanup Makefile
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
` (19 preceding siblings ...)
2015-05-27 6:07 ` [PATCH v3 20/24] cxl: Rework context lifetimes Michael Neuling
@ 2015-05-27 6:07 ` Michael Neuling
2015-05-27 6:07 ` [PATCH v3 22/24] cxl: Move include file cxl.h -> cxl-base.h Michael Neuling
` (2 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:07 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
Cleanup Makefile by fixing line wrapping.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Acked-by: Ian Munsie <imunsie@au1.ibm.com>
---
drivers/misc/cxl/Makefile | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/cxl/Makefile b/drivers/misc/cxl/Makefile
index edb494d..f9f5514 100644
--- a/drivers/misc/cxl/Makefile
+++ b/drivers/misc/cxl/Makefile
@@ -1,4 +1,5 @@
-cxl-y += main.o file.o irq.o fault.o native.o context.o sysfs.o debugfs.o pci.o trace.o
+cxl-y += main.o file.o irq.o fault.o native.o
+cxl-y += context.o sysfs.o debugfs.o pci.o trace.o
obj-$(CONFIG_CXL) += cxl.o
obj-$(CONFIG_CXL_BASE) += base.o
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 22/24] cxl: Move include file cxl.h -> cxl-base.h
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
` (20 preceding siblings ...)
2015-05-27 6:07 ` [PATCH v3 21/24] cxl: Cleanup Makefile Michael Neuling
@ 2015-05-27 6:07 ` Michael Neuling
2015-05-27 6:07 ` [PATCH v3 23/24] cxl: Export file ops for use by API Michael Neuling
2015-05-27 6:07 ` [PATCH v3 24/24] cxl: Add AFU virtual PHB and kernel API Michael Neuling
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:07 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
This moves the current include file from cxl.h -> cxl-base.h. This current
include file is used only to pass information between the base driver that
needs to be built into the kernel and the cxl module.
This is to make way for a new include/misc/cxl.h which will
contain just the kernel API for other driver to use
Signed-off-by: Michael Neuling <mikey@neuling.org>
Acked-by: Ian Munsie <imunsie@au1.ibm.com>
---
MAINTAINERS | 2 +-
arch/powerpc/include/asm/pnv-pci.h | 2 +-
arch/powerpc/mm/copro_fault.c | 2 +-
arch/powerpc/mm/hash_native_64.c | 2 +-
arch/powerpc/platforms/powernv/pci-ioda.c | 2 +-
drivers/misc/cxl/base.c | 2 +-
drivers/misc/cxl/cxl.h | 2 +-
drivers/misc/cxl/irq.c | 2 +-
drivers/misc/cxl/main.c | 2 +-
drivers/misc/cxl/native.c | 2 +-
include/misc/{cxl.h => cxl-base.h} | 4 ++--
11 files changed, 12 insertions(+), 12 deletions(-)
rename include/misc/{cxl.h => cxl-base.h} (95%)
diff --git a/MAINTAINERS b/MAINTAINERS
index f8e0afb..10f6001 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2956,7 +2956,7 @@ M: Michael Neuling <mikey@neuling.org>
L: linuxppc-dev@lists.ozlabs.org
S: Supported
F: drivers/misc/cxl/
-F: include/misc/cxl.h
+F: include/misc/cxl*
F: include/uapi/misc/cxl.h
F: Documentation/powerpc/cxl.txt
F: Documentation/powerpc/cxl.txt
diff --git a/arch/powerpc/include/asm/pnv-pci.h b/arch/powerpc/include/asm/pnv-pci.h
index f9b4982..6f77f71 100644
--- a/arch/powerpc/include/asm/pnv-pci.h
+++ b/arch/powerpc/include/asm/pnv-pci.h
@@ -11,7 +11,7 @@
#define _ASM_PNV_PCI_H
#include <linux/pci.h>
-#include <misc/cxl.h>
+#include <misc/cxl-base.h>
int pnv_phb_to_cxl_mode(struct pci_dev *dev, uint64_t mode);
int pnv_cxl_ioda_msi_setup(struct pci_dev *dev, unsigned int hwirq,
diff --git a/arch/powerpc/mm/copro_fault.c b/arch/powerpc/mm/copro_fault.c
index 7a71d7f..6527882 100644
--- a/arch/powerpc/mm/copro_fault.c
+++ b/arch/powerpc/mm/copro_fault.c
@@ -26,7 +26,7 @@
#include <asm/reg.h>
#include <asm/copro.h>
#include <asm/spu.h>
-#include <misc/cxl.h>
+#include <misc/cxl-base.h>
/*
* This ought to be kept in sync with the powerpc specific do_page_fault
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
index 9c4880d..13befa35 100644
--- a/arch/powerpc/mm/hash_native_64.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -29,7 +29,7 @@
#include <asm/kexec.h>
#include <asm/ppc-opcode.h>
-#include <misc/cxl.h>
+#include <misc/cxl-base.h>
#ifdef DEBUG_LOW
#define DBG_LOW(fmt...) udbg_printf(fmt)
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 2eaf6f7..d21ceba 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -39,7 +39,7 @@
#include <asm/firmware.h>
#include <asm/pnv-pci.h>
-#include <misc/cxl.h>
+#include <misc/cxl-base.h>
#include "powernv.h"
#include "pci.h"
diff --git a/drivers/misc/cxl/base.c b/drivers/misc/cxl/base.c
index 0654ad8..a9f0dd3 100644
--- a/drivers/misc/cxl/base.c
+++ b/drivers/misc/cxl/base.c
@@ -10,7 +10,7 @@
#include <linux/module.h>
#include <linux/rcupdate.h>
#include <asm/errno.h>
-#include <misc/cxl.h>
+#include <misc/cxl-base.h>
#include "cxl.h"
/* protected by rcu */
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index bbc7fd0..f3b071e 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -21,7 +21,7 @@
#include <asm/cputable.h>
#include <asm/mmu.h>
#include <asm/reg.h>
-#include <misc/cxl.h>
+#include <misc/cxl-base.h>
#include <uapi/misc/cxl.h>
diff --git a/drivers/misc/cxl/irq.c b/drivers/misc/cxl/irq.c
index 212790b..680cd26 100644
--- a/drivers/misc/cxl/irq.c
+++ b/drivers/misc/cxl/irq.c
@@ -14,7 +14,7 @@
#include <linux/slab.h>
#include <linux/pid.h>
#include <asm/cputable.h>
-#include <misc/cxl.h>
+#include <misc/cxl-base.h>
#include "cxl.h"
#include "trace.h"
diff --git a/drivers/misc/cxl/main.c b/drivers/misc/cxl/main.c
index de1b19a..403780e 100644
--- a/drivers/misc/cxl/main.c
+++ b/drivers/misc/cxl/main.c
@@ -20,7 +20,7 @@
#include <linux/idr.h>
#include <linux/pci.h>
#include <asm/cputable.h>
-#include <misc/cxl.h>
+#include <misc/cxl-base.h>
#include "cxl.h"
#include "trace.h"
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c
index a4b40d7..10567f2 100644
--- a/drivers/misc/cxl/native.c
+++ b/drivers/misc/cxl/native.c
@@ -15,7 +15,7 @@
#include <linux/mm.h>
#include <linux/uaccess.h>
#include <asm/synch.h>
-#include <misc/cxl.h>
+#include <misc/cxl-base.h>
#include "cxl.h"
#include "trace.h"
diff --git a/include/misc/cxl.h b/include/misc/cxl-base.h
similarity index 95%
rename from include/misc/cxl.h
rename to include/misc/cxl-base.h
index 975cc78..5ae9625 100644
--- a/include/misc/cxl.h
+++ b/include/misc/cxl-base.h
@@ -7,8 +7,8 @@
* 2 of the License, or (at your option) any later version.
*/
-#ifndef _MISC_CXL_H
-#define _MISC_CXL_H
+#ifndef _MISC_CXL_BASE_H
+#define _MISC_CXL_BASE_H
#ifdef CONFIG_CXL_BASE
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 23/24] cxl: Export file ops for use by API
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
` (21 preceding siblings ...)
2015-05-27 6:07 ` [PATCH v3 22/24] cxl: Move include file cxl.h -> cxl-base.h Michael Neuling
@ 2015-05-27 6:07 ` Michael Neuling
2015-05-27 6:07 ` [PATCH v3 24/24] cxl: Add AFU virtual PHB and kernel API Michael Neuling
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:07 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
The cxl kernel API will allow drivers other than cxl to export a file
descriptor which has the same userspace API. These file descriptors will be
able to be used against libcxl.
This exports those file ops for use by other drivers.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Acked-by: Ian Munsie <imunsie@au1.ibm.com>
---
drivers/misc/cxl/cxl.h | 9 +++++++++
drivers/misc/cxl/file.c | 23 ++++++++++++++---------
2 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index f3b071e..af67c4b 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -18,6 +18,7 @@
#include <linux/pid.h>
#include <linux/io.h>
#include <linux/pci.h>
+#include <linux/fs.h>
#include <asm/cputable.h>
#include <asm/mmu.h>
#include <asm/reg.h>
@@ -670,4 +671,12 @@ void cxl_stop_trace(struct cxl *cxl);
extern struct pci_driver cxl_pci_driver;
int afu_allocate_irqs(struct cxl_context *ctx, u32 count);
+int afu_open(struct inode *inode, struct file *file);
+int afu_release(struct inode *inode, struct file *file);
+long afu_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+int afu_mmap(struct file *file, struct vm_area_struct *vm);
+unsigned int afu_poll(struct file *file, struct poll_table_struct *poll);
+ssize_t afu_read(struct file *file, char __user *buf, size_t count, loff_t *off);
+extern const struct file_operations afu_fops;
+
#endif
diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c
index f7653fc..72fe168 100644
--- a/drivers/misc/cxl/file.c
+++ b/drivers/misc/cxl/file.c
@@ -96,7 +96,8 @@ err_put_adapter:
put_device(&adapter->dev);
return rc;
}
-static int afu_open(struct inode *inode, struct file *file)
+
+int afu_open(struct inode *inode, struct file *file)
{
return __afu_open(inode, file, false);
}
@@ -106,7 +107,7 @@ static int afu_master_open(struct inode *inode, struct file *file)
return __afu_open(inode, file, true);
}
-static int afu_release(struct inode *inode, struct file *file)
+int afu_release(struct inode *inode, struct file *file)
{
struct cxl_context *ctx = file->private_data;
@@ -211,7 +212,7 @@ static long afu_ioctl_process_element(struct cxl_context *ctx,
return 0;
}
-static long afu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+long afu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct cxl_context *ctx = file->private_data;
@@ -228,13 +229,13 @@ static long afu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return -EINVAL;
}
-static long afu_compat_ioctl(struct file *file, unsigned int cmd,
+long afu_compat_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
return afu_ioctl(file, cmd, arg);
}
-static int afu_mmap(struct file *file, struct vm_area_struct *vm)
+int afu_mmap(struct file *file, struct vm_area_struct *vm)
{
struct cxl_context *ctx = file->private_data;
@@ -245,7 +246,7 @@ static int afu_mmap(struct file *file, struct vm_area_struct *vm)
return cxl_context_iomap(ctx, vm);
}
-static unsigned int afu_poll(struct file *file, struct poll_table_struct *poll)
+unsigned int afu_poll(struct file *file, struct poll_table_struct *poll)
{
struct cxl_context *ctx = file->private_data;
int mask = 0;
@@ -277,7 +278,7 @@ static inline int ctx_event_pending(struct cxl_context *ctx)
ctx->pending_afu_err || (ctx->status == CLOSED));
}
-static ssize_t afu_read(struct file *file, char __user *buf, size_t count,
+ssize_t afu_read(struct file *file, char __user *buf, size_t count,
loff_t *off)
{
struct cxl_context *ctx = file->private_data;
@@ -358,7 +359,11 @@ out:
return rc;
}
-static const struct file_operations afu_fops = {
+/*
+ * Note: if this is updated, we need to update api.c to patch the new ones in
+ * too
+ */
+const struct file_operations afu_fops = {
.owner = THIS_MODULE,
.open = afu_open,
.poll = afu_poll,
@@ -369,7 +374,7 @@ static const struct file_operations afu_fops = {
.mmap = afu_mmap,
};
-static const struct file_operations afu_master_fops = {
+const struct file_operations afu_master_fops = {
.owner = THIS_MODULE,
.open = afu_master_open,
.poll = afu_poll,
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v3 24/24] cxl: Add AFU virtual PHB and kernel API
2015-05-27 6:06 [PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API Michael Neuling
` (22 preceding siblings ...)
2015-05-27 6:07 ` [PATCH v3 23/24] cxl: Export file ops for use by API Michael Neuling
@ 2015-05-27 6:07 ` Michael Neuling
23 siblings, 0 replies; 25+ messages in thread
From: Michael Neuling @ 2015-05-27 6:07 UTC (permalink / raw)
To: mpe, benh
Cc: imunsie, linuxppc-dev, mikey, Daniel Axtens, Matthew R. Ochs,
Manoj N. Kumar, brking
This patch does two things.
Firstly it presents the Accelerator Function Unit (AFUs) behind the POWER
Service Layer (PSL) as PCI devices on a virtual PCI Host Bridge (vPHB). This
in in addition to the PSL being a PCI device itself.
As part of the Coherent Accelerator Interface Architecture (CAIA) AFUs can
provide an AFU configuration. This AFU configuration recored is architected to
be the same as a PCI config space.
This patch sets discovers the AFU configuration records, provides AFU config
space read/write functions to these configuration records. It then enumerates
the PCI bus. It also hooks in PCI ops where appropriate. It also destroys the
vPHB when the physical card is removed.
Secondly, it add an in kernel API for AFU to use CXL. AFUs must present a
driver that firstly binds as a PCI device. This PCI device can then be using
to do CXL specific operations (that can't sit in the PCI ops) using this API.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Acked-by: Ian Munsie <imunsie@au1.ibm.com>
---
drivers/misc/cxl/Makefile | 1 +
drivers/misc/cxl/api.c | 331 ++++++++++++++++++++++++++++++++++++++++++++++
drivers/misc/cxl/cxl.h | 5 +
drivers/misc/cxl/pci.c | 17 ++-
drivers/misc/cxl/vphb.c | 269 +++++++++++++++++++++++++++++++++++++
include/misc/cxl.h | 203 ++++++++++++++++++++++++++++
6 files changed, 822 insertions(+), 4 deletions(-)
create mode 100644 drivers/misc/cxl/api.c
create mode 100644 drivers/misc/cxl/vphb.c
create mode 100644 include/misc/cxl.h
diff --git a/drivers/misc/cxl/Makefile b/drivers/misc/cxl/Makefile
index f9f5514..14e3f82 100644
--- a/drivers/misc/cxl/Makefile
+++ b/drivers/misc/cxl/Makefile
@@ -1,5 +1,6 @@
cxl-y += main.o file.o irq.o fault.o native.o
cxl-y += context.o sysfs.o debugfs.o pci.o trace.o
+cxl-y += vphb.o api.o
obj-$(CONFIG_CXL) += cxl.o
obj-$(CONFIG_CXL_BASE) += base.o
diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c
new file mode 100644
index 0000000..0c77240
--- /dev/null
+++ b/drivers/misc/cxl/api.c
@@ -0,0 +1,331 @@
+/*
+ * Copyright 2014 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/anon_inodes.h>
+#include <linux/file.h>
+#include <misc/cxl.h>
+
+#include "cxl.h"
+
+struct cxl_context *cxl_dev_context_init(struct pci_dev *dev)
+{
+ struct cxl_afu *afu;
+ struct cxl_context *ctx;
+ int rc;
+
+ afu = cxl_pci_to_afu(dev);
+
+ ctx = cxl_context_alloc();
+ if (IS_ERR(ctx))
+ return ctx;
+
+ /* Make it a slave context. We can promote it later? */
+ rc = cxl_context_init(ctx, afu, false, NULL);
+ if (rc) {
+ kfree(ctx);
+ return ERR_PTR(-ENOMEM);
+ }
+ cxl_assign_psn_space(ctx);
+
+ return ctx;
+}
+EXPORT_SYMBOL_GPL(cxl_dev_context_init);
+
+struct cxl_context *cxl_get_context(struct pci_dev *dev)
+{
+ return dev->dev.archdata.cxl_ctx;
+}
+EXPORT_SYMBOL_GPL(cxl_get_context);
+
+struct device *cxl_get_phys_dev(struct pci_dev *dev)
+{
+ struct cxl_afu *afu;
+
+ afu = cxl_pci_to_afu(dev);
+
+ return afu->adapter->dev.parent;
+}
+EXPORT_SYMBOL_GPL(cxl_get_phys_dev);
+
+int cxl_release_context(struct cxl_context *ctx)
+{
+ if (ctx->status != CLOSED)
+ return -EBUSY;
+
+ cxl_context_free(ctx);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cxl_release_context);
+
+int cxl_allocate_afu_irqs(struct cxl_context *ctx, int num)
+{
+ if (num == 0)
+ num = ctx->afu->pp_irqs;
+ return afu_allocate_irqs(ctx, num);
+}
+EXPORT_SYMBOL_GPL(cxl_allocate_afu_irqs);
+
+void cxl_free_afu_irqs(struct cxl_context *ctx)
+{
+ cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
+}
+EXPORT_SYMBOL_GPL(cxl_free_afu_irqs);
+
+static irq_hw_number_t cxl_find_afu_irq(struct cxl_context *ctx, int num)
+{
+ __u16 range;
+ int r;
+
+ WARN_ON(num == 0);
+
+ for (r = 0; r < CXL_IRQ_RANGES; r++) {
+ range = ctx->irqs.range[r];
+ if (num < range) {
+ return ctx->irqs.offset[r] + num;
+ }
+ num -= range;
+ }
+ return 0;
+}
+
+int cxl_map_afu_irq(struct cxl_context *ctx, int num,
+ irq_handler_t handler, void *cookie, char *name)
+{
+ irq_hw_number_t hwirq;
+
+ /*
+ * Find interrupt we are to register.
+ */
+ hwirq = cxl_find_afu_irq(ctx, num);
+ if (!hwirq)
+ return -ENOENT;
+
+ return cxl_map_irq(ctx->afu->adapter, hwirq, handler, cookie, name);
+}
+EXPORT_SYMBOL_GPL(cxl_map_afu_irq);
+
+void cxl_unmap_afu_irq(struct cxl_context *ctx, int num, void *cookie)
+{
+ irq_hw_number_t hwirq;
+ unsigned int virq;
+
+ hwirq = cxl_find_afu_irq(ctx, num);
+ if (!hwirq)
+ return;
+
+ virq = irq_find_mapping(NULL, hwirq);
+ if (virq)
+ cxl_unmap_irq(virq, cookie);
+}
+EXPORT_SYMBOL_GPL(cxl_unmap_afu_irq);
+
+/*
+ * Start a context
+ * Code here similar to afu_ioctl_start_work().
+ */
+int cxl_start_context(struct cxl_context *ctx, u64 wed,
+ struct task_struct *task)
+{
+ int rc = 0;
+ bool kernel = true;
+
+ pr_devel("%s: pe: %i\n", __func__, ctx->pe);
+
+ mutex_lock(&ctx->status_mutex);
+ if (ctx->status == STARTED)
+ goto out; /* already started */
+
+ if (task) {
+ ctx->pid = get_task_pid(task, PIDTYPE_PID);
+ get_pid(ctx->pid);
+ kernel = false;
+ }
+
+ cxl_ctx_get();
+
+ if ((rc = cxl_attach_process(ctx, kernel, wed , 0))) {
+ put_pid(ctx->pid);
+ cxl_ctx_put();
+ goto out;
+ }
+
+ ctx->status = STARTED;
+ get_device(&ctx->afu->dev);
+out:
+ mutex_unlock(&ctx->status_mutex);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(cxl_start_context);
+
+int cxl_process_element(struct cxl_context *ctx)
+{
+ return ctx->pe;
+}
+EXPORT_SYMBOL_GPL(cxl_process_element);
+
+/* Stop a context. Returns 0 on success, otherwise -Errno */
+int cxl_stop_context(struct cxl_context *ctx)
+{
+ int rc;
+
+ rc = __detach_context(ctx);
+ if (!rc)
+ put_device(&ctx->afu->dev);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(cxl_stop_context);
+
+void cxl_set_master(struct cxl_context *ctx)
+{
+ ctx->master = true;
+ cxl_assign_psn_space(ctx);
+}
+EXPORT_SYMBOL_GPL(cxl_set_master);
+
+/* wrappers around afu_* file ops which are EXPORTED */
+int cxl_fd_open(struct inode *inode, struct file *file)
+{
+ return afu_open(inode, file);
+}
+EXPORT_SYMBOL_GPL(cxl_fd_open);
+int cxl_fd_release(struct inode *inode, struct file *file)
+{
+ return afu_release(inode, file);
+}
+EXPORT_SYMBOL_GPL(cxl_fd_release);
+long cxl_fd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ return afu_ioctl(file, cmd, arg);
+}
+EXPORT_SYMBOL_GPL(cxl_fd_ioctl);
+int cxl_fd_mmap(struct file *file, struct vm_area_struct *vm)
+{
+ return afu_mmap(file, vm);
+}
+EXPORT_SYMBOL_GPL(cxl_fd_mmap);
+unsigned int cxl_fd_poll(struct file *file, struct poll_table_struct *poll)
+{
+ return afu_poll(file, poll);
+}
+EXPORT_SYMBOL_GPL(cxl_fd_poll);
+ssize_t cxl_fd_read(struct file *file, char __user *buf, size_t count,
+ loff_t *off)
+{
+ return afu_read(file, buf, count, off);
+}
+EXPORT_SYMBOL_GPL(cxl_fd_read);
+
+#define PATCH_FOPS(NAME) if (!fops->NAME) fops->NAME = afu_fops.NAME
+
+/* Get a struct file and fd for a context and attach the ops */
+struct file *cxl_get_fd(struct cxl_context *ctx, struct file_operations *fops,
+ int *fd)
+{
+ struct file *file;
+ int rc, flags, fdtmp;
+
+ flags = O_RDWR | O_CLOEXEC;
+
+ /* This code is similar to anon_inode_getfd() */
+ rc = get_unused_fd_flags(flags);
+ if (rc < 0)
+ return ERR_PTR(rc);
+ fdtmp = rc;
+
+ /*
+ * Patch the file ops. Needs to be careful that this is rentrant safe.
+ */
+ if (fops) {
+ PATCH_FOPS(open);
+ PATCH_FOPS(poll);
+ PATCH_FOPS(read);
+ PATCH_FOPS(release);
+ PATCH_FOPS(unlocked_ioctl);
+ PATCH_FOPS(compat_ioctl);
+ PATCH_FOPS(mmap);
+ } else /* use default ops */
+ fops = (struct file_operations *)&afu_fops;
+
+ file = anon_inode_getfile("cxl", fops, ctx, flags);
+ if (IS_ERR(file))
+ put_unused_fd(fdtmp);
+ *fd = fdtmp;
+ return file;
+}
+EXPORT_SYMBOL_GPL(cxl_get_fd);
+
+struct cxl_context *cxl_fops_get_context(struct file *file)
+{
+ return file->private_data;
+}
+EXPORT_SYMBOL_GPL(cxl_fops_get_context);
+
+int cxl_start_work(struct cxl_context *ctx,
+ struct cxl_ioctl_start_work *work)
+{
+ int rc;
+
+ /* code taken from afu_ioctl_start_work */
+ if (!(work->flags & CXL_START_WORK_NUM_IRQS))
+ work->num_interrupts = ctx->afu->pp_irqs;
+ else if ((work->num_interrupts < ctx->afu->pp_irqs) ||
+ (work->num_interrupts > ctx->afu->irqs_max)) {
+ return -EINVAL;
+ }
+
+ rc = afu_register_irqs(ctx, work->num_interrupts);
+ if (rc)
+ return rc;
+
+ rc = cxl_start_context(ctx, work->work_element_descriptor, current);
+ if (rc < 0) {
+ afu_release_irqs(ctx, ctx);
+ return rc;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cxl_start_work);
+
+void __iomem *cxl_psa_map(struct cxl_context *ctx)
+{
+ struct cxl_afu *afu = ctx->afu;
+ int rc;
+
+ rc = cxl_afu_check_and_enable(afu);
+ if (rc)
+ return NULL;
+
+ pr_devel("%s: psn_phys%llx size:%llx\n",
+ __func__, afu->psn_phys, afu->adapter->ps_size);
+ return ioremap(ctx->psn_phys, ctx->psn_size);
+}
+EXPORT_SYMBOL_GPL(cxl_psa_map);
+
+void cxl_psa_unmap(void __iomem *addr)
+{
+ iounmap(addr);
+}
+EXPORT_SYMBOL_GPL(cxl_psa_unmap);
+
+int cxl_afu_reset(struct cxl_context *ctx)
+{
+ struct cxl_afu *afu = ctx->afu;
+ int rc;
+
+ rc = __cxl_afu_reset(afu);
+ if (rc)
+ return rc;
+
+ return cxl_afu_check_and_enable(afu);
+}
+EXPORT_SYMBOL_GPL(cxl_afu_reset);
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index af67c4b..8473de4 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -377,6 +377,9 @@ struct cxl_afu {
int spa_max_procs;
unsigned int psl_virq;
+ /* pointer to the vphb */
+ struct pci_controller *phb;
+
int pp_irqs;
int irqs_max;
int num_procs;
@@ -667,6 +670,8 @@ int cxl_afu_check_and_enable(struct cxl_afu *afu);
int cxl_psl_purge(struct cxl_afu *afu);
void cxl_stop_trace(struct cxl *cxl);
+int cxl_pci_vphb_add(struct cxl_afu *afu);
+void cxl_pci_vphb_remove(struct cxl_afu *afu);
extern struct pci_driver cxl_pci_driver;
int afu_allocate_irqs(struct cxl_context *ctx, u32 count);
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index 3879bdf..b326773 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -741,6 +741,9 @@ static int cxl_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev)
adapter->afu[afu->slice] = afu;
+ if ((rc = cxl_pci_vphb_add(afu)))
+ dev_info(&afu->dev, "Can't register vPHB\n");
+
return 0;
err_put2:
@@ -793,8 +796,10 @@ int cxl_reset(struct cxl *adapter)
dev_info(&dev->dev, "CXL reset\n");
- for (i = 0; i < adapter->slices; i++)
+ for (i = 0; i < adapter->slices; i++) {
+ cxl_pci_vphb_remove(adapter->afu[i]);
cxl_remove_afu(adapter->afu[i]);
+ }
/* pcie_warm_reset requests a fundamental pci reset which includes a
* PERST assert/deassert. PERST triggers a loading of the image
@@ -1128,14 +1133,18 @@ static int cxl_probe(struct pci_dev *dev, const struct pci_device_id *id)
static void cxl_remove(struct pci_dev *dev)
{
struct cxl *adapter = pci_get_drvdata(dev);
- int afu;
+ struct cxl_afu *afu;
+ int i;
/*
* Lock to prevent someone grabbing a ref through the adapter list as
* we are removing it
*/
- for (afu = 0; afu < adapter->slices; afu++)
- cxl_remove_afu(adapter->afu[afu]);
+ for (i = 0; i < adapter->slices; i++) {
+ afu = adapter->afu[i];
+ cxl_pci_vphb_remove(afu);
+ cxl_remove_afu(afu);
+ }
cxl_remove_adapter(adapter);
}
diff --git a/drivers/misc/cxl/vphb.c b/drivers/misc/cxl/vphb.c
new file mode 100644
index 0000000..f733309
--- /dev/null
+++ b/drivers/misc/cxl/vphb.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright 2014 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/pci.h>
+#include <misc/cxl.h>
+#include "cxl.h"
+
+static int cxl_dma_set_mask(struct pci_dev *pdev, u64 dma_mask)
+{
+ if (dma_mask < DMA_BIT_MASK(64)) {
+ pr_info("%s only 64bit DMA supported on CXL", __func__);
+ return -EIO;
+ }
+
+ *(pdev->dev.dma_mask) = dma_mask;
+ return 0;
+}
+
+static int cxl_pci_probe_mode(struct pci_bus *bus)
+{
+ return PCI_PROBE_NORMAL;
+}
+
+static int cxl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
+{
+ return -ENODEV;
+}
+
+static void cxl_teardown_msi_irqs(struct pci_dev *pdev)
+{
+ /*
+ * MSI should never be set but need still need to provide this call
+ * back.
+ */
+}
+
+static bool cxl_pci_enable_device_hook(struct pci_dev *dev)
+{
+ struct pci_controller *phb;
+ struct cxl_afu *afu;
+ struct cxl_context *ctx;
+
+ phb = pci_bus_to_host(dev->bus);
+ afu = (struct cxl_afu *)phb->private_data;
+ set_dma_ops(&dev->dev, &dma_direct_ops);
+ set_dma_offset(&dev->dev, PAGE_OFFSET);
+
+ /*
+ * Allocate a context to do cxl things too. If we eventually do real
+ * DMA ops, we'll need a default context to attach them to
+ */
+ ctx = cxl_dev_context_init(dev);
+ if (!ctx)
+ return false;
+ dev->dev.archdata.cxl_ctx = ctx;
+
+ return (cxl_afu_check_and_enable(afu) == 0);
+}
+
+static void cxl_pci_disable_device(struct pci_dev *dev)
+{
+ struct cxl_context *ctx = cxl_get_context(dev);
+
+ if (ctx) {
+ if (ctx->status == STARTED) {
+ dev_err(&dev->dev, "Default context started\n");
+ return;
+ }
+ cxl_release_context(ctx);
+ }
+}
+
+static resource_size_t cxl_pci_window_alignment(struct pci_bus *bus,
+ unsigned long type)
+{
+ return 1;
+}
+
+static void cxl_pci_reset_secondary_bus(struct pci_dev *dev)
+{
+ /* Should we do an AFU reset here ? */
+}
+
+static int cxl_pcie_cfg_record(u8 bus, u8 devfn)
+{
+ return (bus << 8) + devfn;
+}
+
+static unsigned long cxl_pcie_cfg_addr(struct pci_controller* phb,
+ u8 bus, u8 devfn, int offset)
+{
+ int record = cxl_pcie_cfg_record(bus, devfn);
+
+ return (unsigned long)phb->cfg_addr + ((unsigned long)phb->cfg_data * record) + offset;
+}
+
+
+static int cxl_pcie_config_info(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len,
+ volatile void __iomem **ioaddr,
+ u32 *mask, int *shift)
+{
+ struct pci_controller *phb;
+ struct cxl_afu *afu;
+ unsigned long addr;
+
+ phb = pci_bus_to_host(bus);
+ afu = (struct cxl_afu *)phb->private_data;
+ if (phb == NULL)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ if (cxl_pcie_cfg_record(bus->number, devfn) > afu->crs_num)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ if (offset >= (unsigned long)phb->cfg_data)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ addr = cxl_pcie_cfg_addr(phb, bus->number, devfn, offset);
+
+ *ioaddr = (void *)(addr & ~0x3ULL);
+ *shift = ((addr & 0x3) * 8);
+ switch (len) {
+ case 1:
+ *mask = 0xff;
+ break;
+ case 2:
+ *mask = 0xffff;
+ break;
+ default:
+ *mask = 0xffffffff;
+ break;
+ }
+ return 0;
+}
+
+static int cxl_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 *val)
+{
+ volatile void __iomem *ioaddr;
+ int shift, rc;
+ u32 mask;
+
+ rc = cxl_pcie_config_info(bus, devfn, offset, len, &ioaddr,
+ &mask, &shift);
+ if (rc)
+ return rc;
+
+ /* Can only read 32 bits */
+ *val = (in_le32(ioaddr) >> shift) & mask;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int cxl_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 val)
+{
+ volatile void __iomem *ioaddr;
+ u32 v, mask;
+ int shift, rc;
+
+ rc = cxl_pcie_config_info(bus, devfn, offset, len, &ioaddr,
+ &mask, &shift);
+ if (rc)
+ return rc;
+
+ /* Can only write 32 bits so do read-modify-write */
+ mask <<= shift;
+ val <<= shift;
+
+ v = (in_le32(ioaddr) & ~mask) || (val & mask);
+
+ out_le32(ioaddr, v);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops cxl_pcie_pci_ops =
+{
+ .read = cxl_pcie_read_config,
+ .write = cxl_pcie_write_config,
+};
+
+
+static struct pci_controller_ops cxl_pci_controller_ops =
+{
+ .probe_mode = cxl_pci_probe_mode,
+ .enable_device_hook = cxl_pci_enable_device_hook,
+ .disable_device = cxl_pci_disable_device,
+ .release_device = cxl_pci_disable_device,
+ .window_alignment = cxl_pci_window_alignment,
+ .reset_secondary_bus = cxl_pci_reset_secondary_bus,
+ .setup_msi_irqs = cxl_setup_msi_irqs,
+ .teardown_msi_irqs = cxl_teardown_msi_irqs,
+ .dma_set_mask = cxl_dma_set_mask,
+};
+
+int cxl_pci_vphb_add(struct cxl_afu *afu)
+{
+ struct pci_dev *phys_dev;
+ struct pci_controller *phb, *phys_phb;
+
+ phys_dev = to_pci_dev(afu->adapter->dev.parent);
+ phys_phb = pci_bus_to_host(phys_dev->bus);
+
+ /* Alloc and setup PHB data structure */
+ phb = pcibios_alloc_controller(phys_phb->dn);
+
+ if (!phb)
+ return -ENODEV;
+
+ /* Setup parent in sysfs */
+ phb->parent = &phys_dev->dev;
+
+ /* Setup the PHB using arch provided callback */
+ phb->ops = &cxl_pcie_pci_ops;
+ phb->cfg_addr = afu->afu_desc_mmio + afu->crs_offset;
+ phb->cfg_data = (void *)(u64)afu->crs_len;
+ phb->private_data = afu;
+ phb->controller_ops = cxl_pci_controller_ops;
+
+ /* Scan the bus */
+ pcibios_scan_phb(phb);
+ if (phb->bus == NULL)
+ return -ENXIO;
+
+ /* Claim resources. This might need some rework as well depending
+ * whether we are doing probe-only or not, like assigning unassigned
+ * resources etc...
+ */
+ pcibios_claim_one_bus(phb->bus);
+
+ /* Add probed PCI devices to the device model */
+ pci_bus_add_devices(phb->bus);
+
+ afu->phb = phb;
+
+ return 0;
+}
+
+
+void cxl_pci_vphb_remove(struct cxl_afu *afu)
+{
+ struct pci_controller *phb;
+
+ /* If there is no configuration record we won't have one of these */
+ if (!afu || !afu->phb)
+ return;
+
+ phb = afu->phb;
+
+ pci_remove_root_bus(phb->bus);
+}
+
+struct cxl_afu *cxl_pci_to_afu(struct pci_dev *dev)
+{
+ struct pci_controller *phb;
+
+ phb = pci_bus_to_host(dev->bus);
+
+ return (struct cxl_afu *)phb->private_data;
+}
+EXPORT_SYMBOL_GPL(cxl_pci_to_afu);
+
+unsigned int cxl_pci_to_cfg_record(struct pci_dev *dev)
+{
+ return cxl_pcie_cfg_record(dev->bus->number, dev->devfn);
+}
+EXPORT_SYMBOL_GPL(cxl_pci_to_cfg_record);
diff --git a/include/misc/cxl.h b/include/misc/cxl.h
new file mode 100644
index 0000000..7a6c1d6
--- /dev/null
+++ b/include/misc/cxl.h
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2015 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _MISC_CXL_H
+#define _MISC_CXL_H
+
+#include <linux/pci.h>
+#include <linux/poll.h>
+#include <linux/interrupt.h>
+#include <uapi/misc/cxl.h>
+
+/*
+ * This documents the in kernel API for driver to use CXL. It allows kernel
+ * drivers to bind to AFUs using an AFU configuration record exposed as a PCI
+ * configuration record.
+ *
+ * This API enables control over AFU and contexts which can't be part of the
+ * generic PCI API. This API is agnostic to the actual AFU.
+ */
+
+/* Get the AFU associated with a pci_dev */
+struct cxl_afu *cxl_pci_to_afu(struct pci_dev *dev);
+
+/* Get the AFU conf record number associated with a pci_dev */
+unsigned int cxl_pci_to_cfg_record(struct pci_dev *dev);
+
+/* Get the physical device (ie. the PCIe card) which the AFU is attached */
+struct device *cxl_get_phys_dev(struct pci_dev *dev);
+
+
+/*
+ * Context lifetime overview:
+ *
+ * An AFU context may be inited and then started and stoppped multiple times
+ * before it's released. ie.
+ * - cxl_dev_context_init()
+ * - cxl_start_context()
+ * - cxl_stop_context()
+ * - cxl_start_context()
+ * - cxl_stop_context()
+ * ...repeat...
+ * - cxl_release_context()
+ * Once released, a context can't be started again.
+ *
+ * One context is inited by the cxl driver for every pci_dev. This is to be
+ * used as a default kernel context. cxl_get_context() will get this
+ * context. This context will be released by PCI hot unplug, so doesn't need to
+ * be released explicitly by drivers.
+ *
+ * Additional kernel contexts may be inited using cxl_dev_context_init().
+ * These must be released using cxl_context_detach().
+ *
+ * Once a context has been inited, IRQs may be configured. Firstly these IRQs
+ * must be allocated (cxl_allocate_afu_irqs()), then individually mapped to
+ * specific handlers (cxl_map_afu_irq()).
+ *
+ * These IRQs can be unmapped (cxl_unmap_afu_irq()) and finally released
+ * (cxl_free_afu_irqs()).
+ *
+ * The AFU can be reset (cxl_afu_reset()). This will cause the PSL/AFU
+ * hardware to lose track of all contexts. It's upto the caller of
+ * cxl_afu_reset() to restart these contexts.
+ */
+
+/*
+ * On pci_enabled_device(), the cxl driver will init a single cxl context for
+ * use by the driver. It doesn't start this context (as that will likely
+ * generate DMA traffic for most AFUs).
+ *
+ * This gets the default context associated with this pci_dev. This context
+ * doesn't need to be released as this will be done by the PCI subsystem on hot
+ * unplug.
+ */
+struct cxl_context *cxl_get_context(struct pci_dev *dev);
+/*
+ * Allocate and initalise a context associated with a AFU PCI device. This
+ * doesn't start the context in the AFU.
+ */
+struct cxl_context *cxl_dev_context_init(struct pci_dev *dev);
+/*
+ * Release and free a context. Context should be stopped before calling.
+ */
+int cxl_release_context(struct cxl_context *ctx);
+
+/*
+ * Allocate AFU interrupts for this context. num=0 will allocate the default
+ * for this AFU as given in the AFU descriptor. This number doesn't include the
+ * interrupt 0 (CAIA defines AFU IRQ 0 for page faults). Each interrupt to be
+ * used must map a handler with cxl_map_afu_irq.
+ */
+int cxl_allocate_afu_irqs(struct cxl_context *cxl, int num);
+/* Free allocated interrupts */
+void cxl_free_afu_irqs(struct cxl_context *cxl);
+
+/*
+ * Map a handler for an AFU interrupt associated with a particular context. AFU
+ * IRQS numbers start from 1 (CAIA defines AFU IRQ 0 for page faults). cookie
+ * is private data is that will be provided to the interrupt handler.
+ */
+int cxl_map_afu_irq(struct cxl_context *cxl, int num,
+ irq_handler_t handler, void *cookie, char *name);
+/* unmap mapped IRQ handlers */
+void cxl_unmap_afu_irq(struct cxl_context *cxl, int num, void *cookie);
+
+/*
+ * Start work on the AFU. This starts an cxl context and associates it with a
+ * task. task == NULL will make it a kernel context.
+ */
+int cxl_start_context(struct cxl_context *ctx, u64 wed,
+ struct task_struct *task);
+/*
+ * Stop a context and remove it from the PSL
+ */
+int cxl_stop_context(struct cxl_context *ctx);
+
+/* Reset the AFU */
+int cxl_afu_reset(struct cxl_context *ctx);
+
+/*
+ * Set a context as a master context.
+ * This sets the default problem space area mapped as the full space, rather
+ * than just the per context area (for slaves).
+ */
+void cxl_set_master(struct cxl_context *ctx);
+
+/*
+ * Map and unmap the AFU Problem Space area. The amount and location mapped
+ * depends on if this context is a master or slave.
+ */
+void __iomem *cxl_psa_map(struct cxl_context *ctx);
+void cxl_psa_unmap(void __iomem *addr);
+
+/* Get the process element for this context */
+int cxl_process_element(struct cxl_context *ctx);
+
+
+/*
+ * These calls allow drivers to create their own file descriptors and make them
+ * identical to the cxl file descriptor user API. An example use case:
+ *
+ * struct file_operations cxl_my_fops = {};
+ * ......
+ * // Init the context
+ * ctx = cxl_dev_context_init(dev);
+ * if (IS_ERR(ctx))
+ * return PTR_ERR(ctx);
+ * // Create and attach a new file descriptor to my file ops
+ * file = cxl_get_fd(ctx, &cxl_my_fops, &fd);
+ * // Start context
+ * rc = cxl_start_work(ctx, &work.work);
+ * if (rc) {
+ * fput(file);
+ * put_unused_fd(fd);
+ * return -ENODEV;
+ * }
+ * // No error paths after installing the fd
+ * fd_install(fd, file);
+ * return fd;
+ *
+ * This inits a context, and gets a file descriptor and associates some file
+ * ops to that file descriptor. If the file ops are blank, the cxl driver will
+ * fill them in with the default ones that mimic the standard user API. Once
+ * completed, the file descriptor can be installed. Once the file descriptor is
+ * installed, it's visible to the user so no errors must occur past this point.
+ *
+ * If cxl_fd_release() file op call is installed, the context will be stopped
+ * and released when the fd is released. Hence the driver won't need to manage
+ * this itself.
+ */
+
+/*
+ * Take a context and associate it with my file ops. Returns the associated
+ * file and file descriptor. Any file ops which are blank are filled in by the
+ * cxl driver with the default ops to mimic the standard API.
+ */
+struct file *cxl_get_fd(struct cxl_context *ctx, struct file_operations *fops,
+ int *fd);
+/* Get the context associated with this file */
+struct cxl_context *cxl_fops_get_context(struct file *file);
+/*
+ * Start a context associated a struct cxl_ioctl_start_work used by the
+ * standard cxl user API.
+ */
+int cxl_start_work(struct cxl_context *ctx,
+ struct cxl_ioctl_start_work *work);
+/*
+ * Export all the existing fops so drivers can use them
+ */
+int cxl_fd_open(struct inode *inode, struct file *file);
+int cxl_fd_release(struct inode *inode, struct file *file);
+long cxl_fd_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+int cxl_fd_mmap(struct file *file, struct vm_area_struct *vm);
+unsigned int cxl_fd_poll(struct file *file, struct poll_table_struct *poll);
+ssize_t cxl_fd_read(struct file *file, char __user *buf, size_t count,
+ loff_t *off);
+
+#endif /* _MISC_CXL_H */
--
2.1.0
^ permalink raw reply related [flat|nested] 25+ messages in thread