Re: [V6,1/9] elf: Add new powerpc specifc core note sections
On Wed, 2015-04-08 at 19:50 +0200, Ulrich Weigand wrote: > Anshuman Khandual wrote on 23.03.2015 > 11:34:30: > > > > With that in mind, do we have a way to set the top 32bits of the MSR > > > (which contain the TM bits) when ptracing 32 bit processes? I can't > > > find anything like that in this patch set. > > > > No, we dont have that yet. When ptracing in 32-bit mode the MSR value > > which can be viewed or set from the user space through PTRACE_GETREGS > > PTRACE_SETREGS call is it's lower 32 bits only. Either we can club > > the upper 32 bits of MSR as part of one of the ELF core notes we are > > adding in the patch series or we can create one more separate ELF core > > note for that purpose. Let me know your opinion on this. > > I'm not sure I understand this. I thought we had the following: > > - If the process calling ptrace is itself 64-bit (which is how GDB is > built on all current Linux distributions), then PTRACE_GETREGS etc. > will *always* operate on 64-bit register sets, even if the target > process is 32-bit. > > - If the process calling ptrace is 32-bit, then PTRACE_GETREGS will > operate on 32-bit register sets. However, there is a separate > PTRACE_GETREGS64 / PTRACE_SETREGS64 call that will also provide > the opportunity to operate on the full 64-bit register set. Both > apply independently of whether the target process is 32-bit or > 64-bit. > > Is this not correct? I think you're correct. We should be right. I'd forgotten about the GET/SETREGS64 interfaces. Mikey ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 2/6] powerpc: Add cpu name to dump stack arch description
On Tue, 2015-05-05 at 21:12 +1000, Michael Ellerman wrote: > As soon as we know the name of the cpu we're on, add it to the dump > stack arch description, which is printed in case of an oops. > > Signed-off-by: Michael Ellerman > --- > arch/powerpc/kernel/cputable.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c > index 60262fdf35ba..cf5e0c9b80cb 100644 > --- a/arch/powerpc/kernel/cputable.c > +++ b/arch/powerpc/kernel/cputable.c > @@ -15,6 +15,7 @@ > #include > #include > #include > +#include > > #include > #include > @@ -2174,6 +2175,8 @@ static struct cpu_spec * __init setup_cpu_spec(unsigned > long offset, > } > #endif /* CONFIG_PPC64 || CONFIG_BOOKE */ > > + dump_stack_add_arch_desc(t->cpu_name); > + Can we make this the PVR instead if the name? It gives us more fidelity on what the hardware revision is. Mikey > return t; > } > ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 00/19] cxl: Add AFU virtual PHB and in kernel API
This patch series adds the ability to present AFUs as PCI devices on a virtual PHB. It also adds an in kernel API (to the existing userspace API) so AFU drivers can be written as kernel drivers. Mikey ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 01/19] powerpc/copro: Fix faulting kernel segments
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 --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 02/19] powerpc/pci: Export symbols for CXL
From: Daniel Axtens 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 --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 03/19] powerpc/pci: Add release_device() hook to phb ops
Add release_device() hook to phb ops so we can clean up for specific phbs. Signed-off-by: Michael Neuling --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 04/19] powerpc: Add cxl context to device archdata
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 --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 05/19] cxl: Document external user of existing API
Now that libcxl is public, let's document it. Signed-off-by: Michael Neuling --- 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//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//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//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//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//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//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//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//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//cr/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//cr/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//cr/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
[PATCH 06/19] cxl: Add shutdown hook
Signed-off-by: Michael Neuling --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 07/19] cxl: Re-order card init to check the VSEC earlier
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: Michael Neuling --- 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 a9c90d2..1ac2ecf 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 08/19] cxl: Dump debug info on the AFU configuration record
Now that we parse the AFU Configuration record, dump some info on it when in debug mode. Signed-off-by: Michael Neuling --- 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 1ac2ecf..9066a7a 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 & 0xULL); + 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 & 0x); + show_reg("CR Device", (val >> 16) & 0x); + } #undef show_reg } -- 2.1.0 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 09/19] cxl: Add cookie parameter to afu_release_irqs()
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 --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 10/19] cxl: Rework detach context functions
Rework __detach_context() and cxl_context_detach() so we can reuse them in the kernel API. Signed-off-by: Michael Neuling --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 11/19] cxl: cxl_afu_reset() -> __cxl_afu_reset()
Rename cxl_afu_reset() to __cxl_afu_reset() to we can reuse this function name in the API. Signed-off-by: Michael Neuling --- 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 9066a7a..7130c85 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 12/19] cxl: Export some symbols
These will soon be using elsewhere in the driver. Signed-off-by: Michael Neuling --- drivers/misc/cxl/cxl.h| 5 + drivers/misc/cxl/native.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index 8180680..15e1077 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 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 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..f643bb1 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 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 assign_psn_space(struct cxl_context *ctx) { if (!ctx->afu->pp_size || ctx->master) { ctx->psn_phys = ctx->afu->psn_phys; -- 2.1.0 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 13/19] cxl: Only check pid for userspace contexts
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 --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 14/19] cxl: Split afu_register_irqs() function
Split the afu_register_irqs() function so that different parts can be useful elsewhere. Signed-off-by: Michael Neuling --- 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 15e1077..f9782a3 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 15/19] cxl: Configure PSL for kernel contexts
This updates AFU directed and dedicated modes for contexts attached to the kernel. Signed-off-by: Michael Neuling --- drivers/misc/cxl/native.c | 40 ++-- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c index f643bb1..55078f6 100644 --- a/drivers/misc/cxl/native.c +++ b/drivers/misc/cxl/native.c @@ -433,6 +433,7 @@ err: static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr) { u64 sr; + u32 pid; int r, result; assign_psn_space(ctx); @@ -447,15 +448,19 @@ static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr) 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); + + if (ctx->kernel) { + sr |= CXL_PSL_SR_An_R | (mfmsr() & MSR_SF) | CXL_PSL_SR_An_HV; + pid = 0; + } 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; + pid = current->pid; + } + ctx->elem->common.pid = cpu_to_be32(pid); ctx->elem->common.tid = 0; ctx->elem->sr = cpu_to_be64(sr); @@ -530,7 +535,7 @@ 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 sr, pid; int rc; sr = 0; @@ -539,10 +544,17 @@ static int attach_dedicated(struct cxl_context *ctx, u64 wed, u64 amr) 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); + + if (ctx->kernel) { + sr |= CXL_PSL_SR_An_R | (mfmsr() & MSR_SF) | CXL_PSL_SR_An_HV; + pid = 0; + } else { /* User space */ + 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; + pid = (u64)current->pid << 32; + } + cxl_p2n_write(afu, CXL_PSL_PID_TID_An, pid); cxl_p1n_write(afu, CXL_PSL_SR_An, sr); if ((rc = cxl_write_sstp(afu, ctx->sstp0, ctx->sstp1))) -- 2.1.0 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 16/19] cxl: Cleanup Makefile
Cleanup Makefile by fixing line wrapping. Signed-off-by: Michael Neuling --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 17/19] cxl: Move include file cxl.h -> cxl-base.h
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 --- 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 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 -#include +#include 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 #include #include -#include +#include /* * 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 #include -#include +#include #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 bb3c0c4..73e3e08 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -39,7 +39,7 @@ #include #include -#include +#include #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 #include #include -#include +#include #include "cxl.h" /* protected by rcu */ diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index f9782a3..bc88823 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include 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 #include #include -#include +#include #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 #include #include -#include +#include #include "cxl.h" #include "trace.h" diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c index 55078f6..2578ceb 100644 --- a/drivers/misc/cxl/native.c +++ b/drivers/misc/cxl/native.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 18/19] cxl: Export file ops for use by API
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 --- 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 bc88823..7c5c014 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -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 5377c8b..6a9fd72 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; @@ -212,7 +213,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; @@ -229,13 +230,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; @@ -246,7 +247,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; @@ -278,7 +279,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; @@ -359,7 +360,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, @@ -370,7 +375,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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 19/19] cxl: Add AFU virtual PHB and kernel API
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 --- drivers/misc/cxl/Makefile | 1 + drivers/misc/cxl/api.c| 326 ++ drivers/misc/cxl/cxl.h| 5 + drivers/misc/cxl/pci.c| 17 ++- drivers/misc/cxl/vphb.c | 268 + include/misc/cxl.h| 201 6 files changed, 814 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 000..09901ff --- /dev/null +++ b/drivers/misc/cxl/api.c @@ -0,0 +1,326 @@ +/* + * 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 +#include +#include +#include +#include + +#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); + } + 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); + + cxl_ctx_put(); + 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_conte
Re: [PATCH] powerpc: Make doorbell check preemption safe
On Wed, 2015-05-20 at 00:30 +0530, Shreyas B. Prabhu wrote: > Doorbell can be used to cause ipi on cpus which are sibling threads on > the same core. So icp_native_cause_ipi checks if the destination cpu > is a sibling thread of the current cpu and uses doorbell in such cases. > > But while running with CONFIG_PREEMPT=y, since this section is > preemtible, we can run into issues if after we check if the destination > cpu is a sibling cpu, the task gets migrated from a sibling cpu to a > cpu on another core. > > Fix this by using get_cpu()/ put_cpu() Thanks. Looks good and it's boots for me. Signed-off-by: Michael Neuling > Signed-off-by: Shreyas B. Prabhu > --- > arch/powerpc/sysdev/xics/icp-native.c | 14 +- > 1 file changed, 9 insertions(+), 5 deletions(-) > > diff --git a/arch/powerpc/sysdev/xics/icp-native.c > b/arch/powerpc/sysdev/xics/icp-native.c > index 2fc4cf1..62fd478 100644 > --- a/arch/powerpc/sysdev/xics/icp-native.c > +++ b/arch/powerpc/sysdev/xics/icp-native.c > @@ -147,12 +147,16 @@ static void icp_native_cause_ipi(int cpu, unsigned long > data) > { > kvmppc_set_host_ipi(cpu, 1); > #ifdef CONFIG_PPC_DOORBELL > - if (cpu_has_feature(CPU_FTR_DBELL) && > - (cpumask_test_cpu(cpu, cpu_sibling_mask(smp_processor_id() > - doorbell_cause_ipi(cpu, data); > - else > + if (cpu_has_feature(CPU_FTR_DBELL)) { > + if (cpumask_test_cpu(cpu, cpu_sibling_mask(get_cpu( { > + doorbell_cause_ipi(cpu, data); > + put_cpu(); > + return; > + } > + put_cpu(); > + } > #endif > - icp_native_set_qirr(cpu, IPI_PRIORITY); > + icp_native_set_qirr(cpu, IPI_PRIORITY); > } > > /* ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC PATCH 2/3] powerpc/kernel: Prepare for seccomp-filter in the 64-bit syscall path
On Fri, 2015-05-15 at 18:29 +1000, Michael Ellerman wrote: > In order to support seccomp-filter we need to be able to cope with > seccomp potentially setting a return value for the syscall. > > Currently this doesn't work, because we assume any failure from > do_syscall_trace_enter() should result in ENOSYS being returned to > userspace. > > The complication is that we don't know if seccomp has set a return > value, in fact the failure may not even be caused by seccomp it may have > been from ptrace. So in some cases we should return ENOSYS, and in > others we should return whatever's in regs, but we don't know which at > this level. > > The trick is to pre-fill regs->result with -ENOSYS, so that we return > that unless seccomp overwrites it with something else. > > Note that it's negative ENOSYS, so that we still go via the > syscall_error path on the way out and set CR0[SO]. > > On the other hand in syscall_set_return_value() we set the return value > as it should be presented to userspace. That is mainly for consistency > with syscall_get_error(). > > Signed-off-by: Michael Ellerman > --- > arch/powerpc/include/asm/syscall.h | 13 + > arch/powerpc/kernel/entry_64.S | 37 +++-- > 2 files changed, 44 insertions(+), 6 deletions(-) > > diff --git a/arch/powerpc/include/asm/syscall.h > b/arch/powerpc/include/asm/syscall.h > index ff21b7a2f0cc..3f61ef03a54a 100644 > --- a/arch/powerpc/include/asm/syscall.h > +++ b/arch/powerpc/include/asm/syscall.h > @@ -50,6 +50,12 @@ static inline void syscall_set_return_value(struct > task_struct *task, > struct pt_regs *regs, > int error, long val) > { > + /* > + * We are setting the return value _as presented to userspace_. > + * So we set CR0[SO] and also negate error, making it positive. > + * That means we will _not_ go through the syscall_error path on the > + * exit to userspace. > + */ > if (error) { > regs->ccr |= 0x1000L; > regs->gpr[3] = -error; > @@ -57,6 +63,13 @@ static inline void syscall_set_return_value(struct > task_struct *task, > regs->ccr &= ~0x1000L; > regs->gpr[3] = val; > } > + > + /* > + * Set regs->result to match r3. This mirrors the way a regular syscall > + * exit works. It also makes the return value juggling in > + * syscall_dotrace work. > + */ > + regs->result = regs->gpr[3]; > } > > static inline void syscall_get_arguments(struct task_struct *task, > diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S > index b55c393310f3..3c912d9047c4 100644 > --- a/arch/powerpc/kernel/entry_64.S > +++ b/arch/powerpc/kernel/entry_64.S > @@ -143,8 +143,7 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR) > CURRENT_THREAD_INFO(r11, r1) > ld r10,TI_FLAGS(r11) > andi. r11,r10,_TIF_SYSCALL_DOTRACE > - bne syscall_dotrace > -.Lsyscall_dotrace_cont: > + bne syscall_dotrace /* does not return */ > cmpldi 0,r0,NR_syscalls > bge-syscall_enosys > > @@ -235,27 +234,53 @@ syscall_error: > > /* Traced system call support */ > syscall_dotrace: > + /* Save non-volatile GPRs so seccomp/ptrace etc. can see them */ > bl save_nvgprs > > + /* > + * Seccomp may set regs->result, but we don't know at this level, so > + * preload result with ENOSYS here. That way below in the path to > + * .Lsyscall_exit we can load regs->result and get either ENOSYS, or > + * the value set by seccomp. > + */ > + li r3,-ENOSYS > + std r3,RESULT(r1) > + > /* Get pt_regs into r3 */ > mr r3, r9 > bl do_syscall_trace_enter > + > /* > - * Restore argument registers possibly just changed. > - * We use the return value of do_syscall_trace_enter > - * for the call number to look up in the table (r0). > + * We use the return value of do_syscall_trace_enter() as the syscall > + * number. If the syscall was rejected for any reason > + * do_syscall_trace_enter() returns -1 and the test below against > + * NR_syscalls will fail. >*/ > mr r0,r3 > + > + /* Restore argument registers just clobbered and/or possibly changed. */ > ld r3,GPR3(r1) > ld r4,GPR4(r1) > ld r5,GPR5(r1) > ld r6,GPR6(r1) > ld r7,GPR7(r1) > ld r8,GPR8(r1) > + > + /* Repopulate r9 and r10 for the system_call path */ > addir9,r1,STACK_FRAME_OVERHEAD > CURRENT_THREAD_INFO(r10, r1) > ld r10,TI_FLAGS(r10) > - b .Lsyscall_dotrace_cont > + > + /* Check the syscall number is valid */ > + cmpldi 0,r0,NR_syscalls > + blt+system_call > + > + /* > + * Syscall number is bad, get the result, either ENOSYS f
Re: [PATCH v2] cxl: Export AFU error buffer via sysfs
On Wed, 2015-05-20 at 16:26 +0530, Vaibhav Jain wrote: > Export the "AFU Error Buffer" via sysfs attribute (afu_err_buf). AFU > error buffer is used by the AFU to report application specific > errors. The contents of this buffer are AFU specific and are intended to > be interpreted by the application interacting with the afu. > > Testing: > - Build against pseries le/be configs. > - Run testing with a special version of memcpy afu on a 'be' > kernel. > > Change-log: > v1 -> v2 > - Simplified cxl_afu_read_err_buffer to handle unaligned reads > by performing a short read. > > Signed-off-by: Vaibhav Jain > --- > Documentation/ABI/testing/sysfs-class-cxl | 11 ++ > drivers/misc/cxl/cxl.h| 7 > drivers/misc/cxl/pci.c| 60 > +++ > drivers/misc/cxl/sysfs.c | 33 + > 4 files changed, 111 insertions(+) > > diff --git a/Documentation/ABI/testing/sysfs-class-cxl > b/Documentation/ABI/testing/sysfs-class-cxl > index d46bba8..45e9ce3 100644 > --- a/Documentation/ABI/testing/sysfs-class-cxl > +++ b/Documentation/ABI/testing/sysfs-class-cxl > @@ -6,6 +6,17 @@ Example: The real path of the attribute > /sys/class/cxl/afu0.0s/irqs_max is > > Slave contexts (eg. /sys/class/cxl/afu0.0s): > > +What: /sys/class/cxl//afu_err_buf > +Date: September 2014 > +Contact:linuxppc-dev@lists.ozlabs.org > +Description:read only > +AFU Error Buffer contents. The contents of this file are > + application specific and depends on the AFU being used. > + Applications interacting with the AFU can use this attribute > + to know about the current error condition and take appropriate > + action like logging the event etc. > + > + > What: /sys/class/cxl//irqs_max > Date: September 2014 > Contact:linuxppc-dev@lists.ozlabs.org > diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h > index a1cee47..789f077 100644 > --- a/drivers/misc/cxl/cxl.h > +++ b/drivers/misc/cxl/cxl.h > @@ -362,6 +362,10 @@ struct cxl_afu { > struct mutex spa_mutex; > spinlock_t afu_cntl_lock; > > + /* AFU error buffer fields and bin attribute for sysfs */ > + u64 eb_len, eb_offset; > + struct bin_attribute attr_eb; > + > /* >* Only the first part of the SPA is used for the process element >* linked list. The only other part that software needs to worry about > @@ -563,6 +567,9 @@ static inline void __iomem *_cxl_p2n_addr(struct cxl_afu > *afu, cxl_p2n_reg_t reg > u16 cxl_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off); > u8 cxl_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off); > > +ssize_t cxl_afu_read_err_buffer(struct cxl_afu *afu, char *buf, > + loff_t off, size_t count); > + > > struct cxl_calls { > void (*cxl_slbia)(struct mm_struct *mm); > diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c > index 1ef0164..162a8fc 100644 > --- a/drivers/misc/cxl/pci.c > +++ b/drivers/misc/cxl/pci.c > @@ -593,6 +593,22 @@ static int cxl_read_afu_descriptor(struct cxl_afu *afu) > afu->crs_len = AFUD_CR_LEN(val) * 256; > afu->crs_offset = AFUD_READ_CR_OFF(afu); > > + > + /* eb_len is in multiple of 4K */ > + afu->eb_len = AFUD_EB_LEN(AFUD_READ_EB(afu)) * 4096; > + afu->eb_offset = AFUD_READ_EB_OFF(afu); > + > + /* eb_off is 4K aligned so lower 12 bits are always zero */ > + if (EXTRACT_PPC_BITS(afu->eb_offset, 0, 11) != 0) { > + dev_warn(&afu->dev, > + "Invalid AFU error buffer offset %Lx\n", > + afu->eb_offset); > + dev_info(&afu->dev, > + "Ignoring AFU error buffer in the descriptor\n"); > + /* indicate that no afu buffer exists */ > + afu->eb_len = 0; > + } > + > return 0; > } > > @@ -672,6 +688,50 @@ static int sanitise_afu_regs(struct cxl_afu *afu) > return 0; > } > > +/* > + * afu_eb_read: > + * Called from sysfs and reads the afu error info buffer. The h/w only > supports > + * 4/8 bytes aligned access. So most of the code tries to get around this by > + * reading full 8 bytes aligned chunks, copying it to a temp buffer and > dropping > + * unneeded bytes at the beginning & the end of the requested region. > + */ > +ssize_t cxl_afu_read_err_buffer(struct cxl_afu *afu, char *buf, > + loff_t off, size_t count) > +{ > + u8 tbuff[8]; > + const void __iomem *ebuf = afu->afu_desc_mmio + afu->eb_offset; > + > + count = min((size_t)(afu->eb_len - off), count); > + > + if (unlikely(count <= 0)) { > + /* handle case where no ebuf exists or offset out of bound */ > + count = 0; > + > + } else if ((count >= 8) && IS_ALIGNED(off, 8)) { > + /* read all the interm
Re: [PATCH v2] cxl: Export AFU error buffer via sysfs
On Wed, 2015-05-20 at 22:12 +1000, Michael Neuling wrote: > On Wed, 2015-05-20 at 16:26 +0530, Vaibhav Jain wrote: > > Export the "AFU Error Buffer" via sysfs attribute (afu_err_buf). AFU > > error buffer is used by the AFU to report application specific > > errors. The contents of this buffer are AFU specific and are intended to > > be interpreted by the application interacting with the afu. > > > > Testing: > > - Build against pseries le/be configs. > > - Run testing with a special version of memcpy afu on a 'be' > > kernel. > > > > Change-log: > > v1 -> v2 > > - Simplified cxl_afu_read_err_buffer to handle unaligned reads > > by performing a short read. > > > > Signed-off-by: Vaibhav Jain > > --- > > Documentation/ABI/testing/sysfs-class-cxl | 11 ++ > > drivers/misc/cxl/cxl.h| 7 > > drivers/misc/cxl/pci.c| 60 > > +++ > > drivers/misc/cxl/sysfs.c | 33 + > > 4 files changed, 111 insertions(+) > > > > diff --git a/Documentation/ABI/testing/sysfs-class-cxl > > b/Documentation/ABI/testing/sysfs-class-cxl > > index d46bba8..45e9ce3 100644 > > --- a/Documentation/ABI/testing/sysfs-class-cxl > > +++ b/Documentation/ABI/testing/sysfs-class-cxl > > @@ -6,6 +6,17 @@ Example: The real path of the attribute > > /sys/class/cxl/afu0.0s/irqs_max is > > > > Slave contexts (eg. /sys/class/cxl/afu0.0s): > > > > +What: /sys/class/cxl//afu_err_buf > > +Date: September 2014 > > +Contact:linuxppc-dev@lists.ozlabs.org > > +Description:read only > > +AFU Error Buffer contents. The contents of this file are > > + application specific and depends on the AFU being used. > > + Applications interacting with the AFU can use this attribute > > + to know about the current error condition and take appropriate > > + action like logging the event etc. > > + > > + > > What: /sys/class/cxl//irqs_max > > Date: September 2014 > > Contact:linuxppc-dev@lists.ozlabs.org > > diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h > > index a1cee47..789f077 100644 > > --- a/drivers/misc/cxl/cxl.h > > +++ b/drivers/misc/cxl/cxl.h > > @@ -362,6 +362,10 @@ struct cxl_afu { > > struct mutex spa_mutex; > > spinlock_t afu_cntl_lock; > > > > + /* AFU error buffer fields and bin attribute for sysfs */ > > + u64 eb_len, eb_offset; > > + struct bin_attribute attr_eb; > > + > > /* > > * Only the first part of the SPA is used for the process element > > * linked list. The only other part that software needs to worry about > > @@ -563,6 +567,9 @@ static inline void __iomem *_cxl_p2n_addr(struct > > cxl_afu *afu, cxl_p2n_reg_t reg > > u16 cxl_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off); > > u8 cxl_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off); > > > > +ssize_t cxl_afu_read_err_buffer(struct cxl_afu *afu, char *buf, > > + loff_t off, size_t count); > > + > > > > struct cxl_calls { > > void (*cxl_slbia)(struct mm_struct *mm); > > diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c > > index 1ef0164..162a8fc 100644 > > --- a/drivers/misc/cxl/pci.c > > +++ b/drivers/misc/cxl/pci.c > > @@ -593,6 +593,22 @@ static int cxl_read_afu_descriptor(struct cxl_afu *afu) > > afu->crs_len = AFUD_CR_LEN(val) * 256; > > afu->crs_offset = AFUD_READ_CR_OFF(afu); > > > > + > > + /* eb_len is in multiple of 4K */ > > + afu->eb_len = AFUD_EB_LEN(AFUD_READ_EB(afu)) * 4096; > > + afu->eb_offset = AFUD_READ_EB_OFF(afu); > > + > > + /* eb_off is 4K aligned so lower 12 bits are always zero */ > > + if (EXTRACT_PPC_BITS(afu->eb_offset, 0, 11) != 0) { > > + dev_warn(&afu->dev, > > +"Invalid AFU error buffer offset %Lx\n", > > +afu->eb_offset); > > + dev_info(&afu->dev, > > +"Ignoring AFU error buffer in the descriptor\n"); > > + /* indicate that no afu buffer exists */ > > + afu->eb_len = 0; > > + } > > + > > return 0; > > } > > > > @@ -672,6 +688,50 @@ static int sanitise_afu_regs(struct cxl_afu *afu) > > return 0; &
Re: [PATCH v2] cxl: Export AFU error buffer via sysfs
On Wed, 2015-05-20 at 22:31 +1000, Michael Neuling wrote: > On Wed, 2015-05-20 at 22:12 +1000, Michael Neuling wrote: > > On Wed, 2015-05-20 at 16:26 +0530, Vaibhav Jain wrote: > > > Export the "AFU Error Buffer" via sysfs attribute (afu_err_buf). AFU > > > error buffer is used by the AFU to report application specific > > > errors. The contents of this buffer are AFU specific and are intended to > > > be interpreted by the application interacting with the afu. > > > > > > Testing: > > > - Build against pseries le/be configs. > > > - Run testing with a special version of memcpy afu on a 'be' > > > kernel. > > > > > > Change-log: > > > v1 -> v2 > > > - Simplified cxl_afu_read_err_buffer to handle unaligned reads > > > by performing a short read. > > > > > > Signed-off-by: Vaibhav Jain > > > --- > > > Documentation/ABI/testing/sysfs-class-cxl | 11 ++ > > > drivers/misc/cxl/cxl.h| 7 > > > drivers/misc/cxl/pci.c| 60 > > > +++ > > > drivers/misc/cxl/sysfs.c | 33 + > > > 4 files changed, 111 insertions(+) > > > > > > diff --git a/Documentation/ABI/testing/sysfs-class-cxl > > > b/Documentation/ABI/testing/sysfs-class-cxl > > > index d46bba8..45e9ce3 100644 > > > --- a/Documentation/ABI/testing/sysfs-class-cxl > > > +++ b/Documentation/ABI/testing/sysfs-class-cxl > > > @@ -6,6 +6,17 @@ Example: The real path of the attribute > > > /sys/class/cxl/afu0.0s/irqs_max is > > > > > > Slave contexts (eg. /sys/class/cxl/afu0.0s): > > > > > > +What: /sys/class/cxl//afu_err_buf > > > +Date: September 2014 > > > +Contact:linuxppc-dev@lists.ozlabs.org > > > +Description:read only > > > +AFU Error Buffer contents. The contents of this file are > > > + application specific and depends on the AFU being used. > > > + Applications interacting with the AFU can use this attribute > > > + to know about the current error condition and take appropriate > > > + action like logging the event etc. > > > + > > > + > > > What: /sys/class/cxl//irqs_max > > > Date: September 2014 > > > Contact:linuxppc-dev@lists.ozlabs.org > > > diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h > > > index a1cee47..789f077 100644 > > > --- a/drivers/misc/cxl/cxl.h > > > +++ b/drivers/misc/cxl/cxl.h > > > @@ -362,6 +362,10 @@ struct cxl_afu { > > > struct mutex spa_mutex; > > > spinlock_t afu_cntl_lock; > > > > > > + /* AFU error buffer fields and bin attribute for sysfs */ > > > + u64 eb_len, eb_offset; > > > + struct bin_attribute attr_eb; > > > + > > > /* > > >* Only the first part of the SPA is used for the process element > > >* linked list. The only other part that software needs to worry about > > > @@ -563,6 +567,9 @@ static inline void __iomem *_cxl_p2n_addr(struct > > > cxl_afu *afu, cxl_p2n_reg_t reg > > > u16 cxl_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off); > > > u8 cxl_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off); > > > > > > +ssize_t cxl_afu_read_err_buffer(struct cxl_afu *afu, char *buf, > > > + loff_t off, size_t count); > > > + > > > > > > struct cxl_calls { > > > void (*cxl_slbia)(struct mm_struct *mm); > > > diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c > > > index 1ef0164..162a8fc 100644 > > > --- a/drivers/misc/cxl/pci.c > > > +++ b/drivers/misc/cxl/pci.c > > > @@ -593,6 +593,22 @@ static int cxl_read_afu_descriptor(struct cxl_afu > > > *afu) > > > afu->crs_len = AFUD_CR_LEN(val) * 256; > > > afu->crs_offset = AFUD_READ_CR_OFF(afu); > > > > > > + > > > + /* eb_len is in multiple of 4K */ > > > + afu->eb_len = AFUD_EB_LEN(AFUD_READ_EB(afu)) * 4096; > > > + afu->eb_offset = AFUD_READ_EB_OFF(afu); > > > + > > > + /* eb_off is 4K aligned so lower 12 bits are always zero */ > > > + if (EXTRACT_PPC_BITS(afu->eb_offset, 0, 11) != 0) { > > > + dev_warn(&afu->dev, > > > + "Invalid AFU error buffer offset
Re: [PATCH v3] cxl: Export AFU error buffer via sysfs
+ */ > +ssize_t cxl_afu_read_err_buffer(struct cxl_afu *afu, char *buf, > + loff_t off, size_t count) > +{ > + loff_t aligned_off; > + size_t aligned_count; > + const void __iomem *ebuf = afu->afu_desc_mmio + afu->eb_offset; > + > + if (!afu->eb_len || count == 0 || off < 0) if eb_len == 0 we don't even create the sysfs file. So is this check needed? > + return 0; > + > + /* calculate aligned read window */ > + count = min((size_t)(afu->eb_len - off), count); What if count ends up being negative because off > afu->eb_len?? > + aligned_off = round_down(off, 8); > + aligned_count = round_up(off + count, 8) - aligned_off; I kinda preferred the start end variables, and length was just end - start. I though it was more readable. IMHO How about: aligned_start = round_down(off, 8); aligned_end = round_up(off + count, 8); aligned_length = aligned_end - aligned_start; > + > + /* fast path */ > + if ((aligned_off == off) && (aligned_count == count)) { > + /* no need to use the bounce buffer */ > + _memcpy_fromio(buf, ebuf + off, count); I would drop this, as the other code path should work fine. Premature optimisation. > + > + } else { > + /* use bounce buffer for copy */ > + void *tbuf = (void *)__get_free_page(GFP_TEMPORARY); > + > + if (!tbuf) > + return -ENOMEM; > + > + /* max we can copy in one read is PAGE_SIZE */ > + aligned_count = min(aligned_count, PAGE_SIZE); > + _memcpy_fromio(tbuf, ebuf + aligned_off, aligned_count); > + > + count = min(count, aligned_count); This doesn't seem right. count will equal PAGE_SIZE if it's too big but it has to be smaller by (off & 7) in this case. How about this? #define MAX_COPY_SIZE PAGE_SIZE ... void *bbuf; /* Bounds check count with err buf length */ count = min((size_t)(afu->eb_len - off), count); if ((off < 0) || (count < 0)) return 0; /* Create aligned bounce buffer to copy into */ aligned_start = round_down(off, 8); aligned_end = round_up(off + count, 8); aligned_length = aligned_end - aligned_start; if (aligned_length > MAX_COPY_SIZE) { aligned_length = MAX_COPY_SIZE; count = MAX_COPY_SIZE - (off & 0x7); } bbuf = (void *)__get_free_page(GFP_TEMPORARY); if (!bbuf) return -ENOMEM; /* Use _memcpy_fromio() so the reads are aligned */ _memcpy_fromio(bbuf, ebuf + aligned_start, aligned_length); memcpy(buf, bbuf + (off & 0x7), count); free_page(bbuf); > + memcpy(buf, tbuf + (off & 0x7), count); > + > + free_page((unsigned long)tbuf); > + } > + > + return count; ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v3] cxl: Export AFU error buffer via sysfs
On Thu, 2015-05-21 at 09:06 +0530, trigg wrote: > > > > On 21-May-2015, at 05:16, Michael Neuling wrote: > > > > + */ > > > +ssize_t cxl_afu_read_err_buffer(struct cxl_afu *afu, char *buf, > > > +loff_t off, size_t count) > > > +{ > > > +loff_t aligned_off; > > > +size_t aligned_count; > > > +const void __iomem *ebuf = afu->afu_desc_mmio + > > > afu->eb_offset; > > > + > > > +if (!afu->eb_len || count == 0 || off < 0) > > > > if eb_len == 0 we don't even create the sysfs file. So is this > > check > > needed? > This function is non static so it can be potentially called from > kernel. What? You mean outside this file? > Condition check of "if (count == 0 || off < 0 || (size_t)off > >= afu->eb_len) " > should work solving the problem below too. It makes no sense to call this outside of sysfs reading the error buffer. > > > +aligned_off = round_down(off, 8); > > > +aligned_count = round_up(off + count, 8) - aligned_off; > > > > I kinda preferred the start end variables, and length was just end - > > start. > > > > I though it was more readable. IMHO > > > > How about: > > > > aligned_start = round_down(off, 8); > > aligned_end = round_up(off + count, 8); > > aligned_length = aligned_end - aligned_start; > Agreed on aligned_start and aligned_end but would not > need aligned_end in rest of the code. Aligned_end makes it more readable. > > > > > + > > > +/* fast path */ > > > +if ((aligned_off == off) && (aligned_count == count)) { > > > +/* no need to use the bounce buffer */ > > > +_memcpy_fromio(buf, ebuf + off, count); > > > > I would drop this, as the other code path should work fine. > > Premature optimisation. > I am inclined to differ on this. Code below uses a bounce buffer > which needs more than double the amount of loads and stores. Cacheable vs non-cacheable is important here though. > If the caller wants to speed up things it can simply ask for aligned > read that won't have this overhead. This will be especially useful > In large reads. The overhead will mostly be in the non-cachable/MMIO load/stores rather than the cacheable load/stores, so there may be little performance difference anyway. The only reason this could be useful is if you have a really really large error buffer. Even then, why do you need to read it that quickly? Mikey ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 07/19] cxl: Re-order card init to check the VSEC earlier
On Thu, 2015-05-21 at 19:09 +1000, Ian Munsie wrote: > I think this is missing the From line to indicate I wrote it ;) Oops, yeah, although you could just change your name and that would also fix the problem. Mikey > Otherwise... > > Acked-by: Ian Munsie > > ;-) > ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 15/19] cxl: Configure PSL for kernel contexts
On Thu, 2015-05-21 at 19:32 +1000, Ian Munsie wrote: > Excerpts from Michael Neuling's message of 2015-05-19 21:22:32 +1000: > > +if (ctx->kernel) { > > +sr |= CXL_PSL_SR_An_R | (mfmsr() & MSR_SF) | CXL_PSL_SR_An_HV; > > +pid = 0; > > +} else { > > +sr |= CXL_PSL_SR_An_PR | CXL_PSL_SR_An_R; > > CXL_PSL_SR_An_R is common between these two cases - you could probably > move it to the initial sr = ... line instead of here. > > > +set_endian(sr); > > We should call set_endian(sr) for kernel contexts as well. > > > +if (ctx->kernel) { > > +sr |= CXL_PSL_SR_An_R | (mfmsr() & MSR_SF) | CXL_PSL_SR_An_HV; > > +pid = 0; > > +} else { /* User space */ > > +sr |= CXL_PSL_SR_An_PR | CXL_PSL_SR_An_R; > > CXL_PSL_SR_An_R is common here as well. Yeah, I meant to merge these. Will do. Mikey ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 19/19] cxl: Add AFU virtual PHB and kernel API
On Thu, 2015-05-21 at 18:58 +1000, Ian Munsie wrote: > Hi Mikey, > > > +/* wrappers around afu_* file ops which are EXPORTED */ > > This is fine, though alternatively you could export the original > functions directly from file.c (feel free to rename them to your > versions if you do change it) - I don't really mind either way :) I'll probably just keep it so all the API functions are in one spot. > > +static void cxl_pci_reset_secondary_bus(struct pci_dev *dev) > > +{ > > +/* Should we do an AFU reset here ? */ > > I'm still not sure what the best answer should be to this question... At > the moment it's working fine without an afu reset here, so we can delay > adding it until (and if) it becomes clear we need it? Yeah I think I'll leave it out > Could this be called while the afu is in use (need to be careful), or > should it only ever be called when the afu is inactive (afu reset should > be safe)? Yeah, I assume we'd need to give some EEH events to the attached driver so they could handle the AFU losing all that state/contexts. > > +/* > > + * 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. > > Ok, we'll need to be a little careful here as this differs from the > userspace api (which cannot reuse a context and relies on the file > descriptor release() to stop the context). > > Let's see... Yep. > > > +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); > > OK, this pid is put in the release call (in reclaim_ctx, which is an rcu > callback from cxl_context_free), which means if we reuse a context we > will prevent the pid from ever being reused, reducing the total number > of runnable processes by one. As discussed offline, I've moved this around. > > + kernel = false; > > + } > > + > > + cxl_ctx_get(); > > Likewise this is mirrored in the release call instead of the stop call, > so if we reuse a context we will then permanently mark cxl as being in > use, which will then permanently enable the slbia hook. Ditto. > > > + 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); > > > +/* 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); > > > +int cxl_release_context(struct cxl_context *ctx) > > +{ > > + if (ctx->status != CLOSED) > > + return -EBUSY; > > + > > + cxl_context_free(ctx); > > + > > + cxl_ctx_put(); > > + return 0; > > +} > > +EXPORT_SYMBOL_GPL(cxl_release_context); > > Otherwise it looks good :) Thanks, Mikey > > Cheers, > -Ian > ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 00/21] cxl: Add AFU virtual PHB and in kernel API
This patch series adds the ability to present AFUs as PCI devices on a virtual PHB. It also adds an in kernel API (to the existing userspace API) so AFU drivers can be written as kernel drivers. This series is dependant on Daniel DMA set mask and MSI PCI controller ops patch series. v2: - Address comments from Ian o Rename some functions now they are global o Rework context lifetime o Merge and fix SR calculation o Added ACKs from Ian o correct from Ian on one patch - Fixed powernv pci shutdown hook Mikey ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 01/21] powerpc/copro: Fix faulting kernel segments
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 --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 02/21] powerpc/pci: Export symbols for CXL
From: Daniel Axtens 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 --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 03/21] powerpc/pci: Add release_device() hook to phb ops
Add release_device() hook to phb ops so we can clean up for specific phbs. Signed-off-by: Michael Neuling --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 04/21] powerpc: Add cxl context to device archdata
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 --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 05/21] powerpc/pci: Add shutdown hook to pci_controller_ops
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 --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 06/21] cxl: Document external user of existing API
Now that libcxl is public, let's document it. Signed-off-by: Michael Neuling Acked-by: Ian Munsie --- 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//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//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//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//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//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//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//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//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//cr/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//cr/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//cr/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.or
[PATCH v2 07/21] cxl: Add shutdown hook
Signed-off-by: Michael Neuling Acked-by: Ian Munsie --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 08/21] cxl: Re-order card init to check the VSEC earlier
From: Ian Munsie 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 Signed-off-by: Michael Neuling --- 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 a9c90d2..1ac2ecf 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 09/21] cxl: Dump debug info on the AFU configuration record
Now that we parse the AFU Configuration record, dump some info on it when in debug mode. Signed-off-by: Michael Neuling Acked-by: Ian Munsie --- 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 1ac2ecf..9066a7a 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 & 0xULL); + 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 & 0x); + show_reg("CR Device", (val >> 16) & 0x); + } #undef show_reg } -- 2.1.0 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 10/21] cxl: Add cookie parameter to afu_release_irqs()
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 Acked-by: Ian Munsie --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 11/21] cxl: Rework detach context functions
Rework __detach_context() and cxl_context_detach() so we can reuse them in the kernel API. Signed-off-by: Michael Neuling Acked-by: Ian Munsie --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 12/21] cxl: cxl_afu_reset() -> __cxl_afu_reset()
Rename cxl_afu_reset() to __cxl_afu_reset() to we can reuse this function name in the API. Signed-off-by: Michael Neuling Acked-by: Ian Munsie --- 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 9066a7a..7130c85 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 13/21] cxl: Export some symbols
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 Acked-by: Ian Munsie --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 14/21] cxl: Only check pid for userspace contexts
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 Acked-by: Ian Munsie --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 15/21] cxl: Split afu_register_irqs() function
Split the afu_register_irqs() function so that different parts can be useful elsewhere. Signed-off-by: Michael Neuling Acked-by: Ian Munsie --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 16/21] cxl: Configure PSL for kernel contexts and merge code
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 Acked-by: Ian Munsie --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 17/21] cxl: Rework context lifetimes
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 Acked-by: Ian Munsie --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 18/21] cxl: Cleanup Makefile
Cleanup Makefile by fixing line wrapping. Signed-off-by: Michael Neuling Acked-by: Ian Munsie --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 19/21] cxl: Move include file cxl.h -> cxl-base.h
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 Acked-by: Ian Munsie --- 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 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 -#include +#include 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 #include #include -#include +#include /* * 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 #include -#include +#include #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 #include -#include +#include #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 #include #include -#include +#include #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 #include #include -#include +#include #include 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 #include #include -#include +#include #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 #include #include -#include +#include #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 #include #include -#include +#include #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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 20/21] cxl: Export file ops for use by API
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 Acked-by: Ian Munsie --- 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 #include #include +#include #include #include #include @@ -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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 21/21] cxl: Add AFU virtual PHB and kernel API
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 Acked-by: Ian Munsie --- drivers/misc/cxl/Makefile | 1 + drivers/misc/cxl/api.c| 325 ++ drivers/misc/cxl/cxl.h| 5 + drivers/misc/cxl/pci.c| 17 ++- drivers/misc/cxl/vphb.c | 268 ++ include/misc/cxl.h| 201 6 files changed, 813 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 000..be44b9f --- /dev/null +++ b/drivers/misc/cxl/api.c @@ -0,0 +1,325 @@ +/* + * 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 +#include +#include +#include +#include + +#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
Re: [PATCH 12/19] cxl: Export some symbols
On Thu, 2015-05-21 at 19:16 +1000, Ian Munsie wrote: > > +void assign_psn_space(struct cxl_context *ctx); > > Should we consider renaming this to cxl_assign_psn_space to namespace it > now that it's potentially callable from elsewhere in the kernel? > > > +int afu_check_and_enable(struct cxl_afu *afu); > > Likewise? Yep, I just resent with cxl_ added. Mikey > Acked-by: Ian Munsie > > -Ian > ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 00/24] cxl: Add AFU virtual PHB and in kernel API
This patch series adds the ability to present AFUs as PCI devices on a virtual PHB. It also adds an in kernel API (to the existing userspace API) so AFU drivers can be written as kernel drivers. This series is dependant on Daniel DMA set mask and MSI PCI controller ops patch series. v3: Cleans up device disable and adds a new API call. Details: - Added pci_disable_device() hook to powerpc. - Added cxl pci_disable_device() to PCI controller ops. - Added cxl_fops_get_context() API call for cxlflash team. - Fixed error path on probe(). - Removed a verbose print from cxl_remove(). v2: - Address comments from Ian o Rename some functions now they are global o Rework context lifetime o Merge and fix SR calculation o Added ACKs from Ian o correct from Ian on one patch - Fixed powernv pci shutdown hook Mikey ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 01/24] powerpc/copro: Fix faulting kernel segments
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 --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 02/24] powerpc/pci: Export symbols for CXL
From: Daniel Axtens 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 --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 03/24] powerpc/pci: Add release_device() hook to phb ops
Add release_device() hook to phb ops so we can clean up for specific phbs. Signed-off-by: Michael Neuling --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 04/24] powerpc: Add cxl context to device archdata
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 --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 05/24] powerpc/pci: Add shutdown hook to pci_controller_ops
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 --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 06/24] powerpc/pci: Add pcibios_disable_device() hook
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 --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 07/24] cxl: Document external user of existing API
Now that libcxl is public, let's document it. Signed-off-by: Michael Neuling Acked-by: Ian Munsie --- 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//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//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//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//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//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//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//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//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//cr/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//cr/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//cr/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.or
[PATCH v3 08/24] cxl: Add shutdown hook
Signed-off-by: Michael Neuling Acked-by: Ian Munsie --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 09/24] cxl: Remove unnecessarily verbose print in cxl_remove()
Signed-off-by: Michael Neuling Acked-by: Ian Munsie --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 10/24] cxl: Re-order card init to check the VSEC earlier
From: Ian Munsie 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 Signed-off-by: Michael Neuling --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 11/24] cxl: Fix error path on probe
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 Acked-by: Ian Munsie --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 12/24] cxl: Dump debug info on the AFU configuration record
Now that we parse the AFU Configuration record, dump some info on it when in debug mode. Signed-off-by: Michael Neuling Acked-by: Ian Munsie --- 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 & 0xULL); + 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 & 0x); + show_reg("CR Device", (val >> 16) & 0x); + } #undef show_reg } -- 2.1.0 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 13/24] cxl: Add cookie parameter to afu_release_irqs()
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 Acked-by: Ian Munsie --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 14/24] cxl: Rework detach context functions
Rework __detach_context() and cxl_context_detach() so we can reuse them in the kernel API. Signed-off-by: Michael Neuling Acked-by: Ian Munsie --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 15/24] cxl: cxl_afu_reset() -> __cxl_afu_reset()
Rename cxl_afu_reset() to __cxl_afu_reset() to we can reuse this function name in the API. Signed-off-by: Michael Neuling Acked-by: Ian Munsie --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 16/24] cxl: Export some symbols
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 Acked-by: Ian Munsie --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 17/24] cxl: Only check pid for userspace contexts
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 Acked-by: Ian Munsie --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 18/24] cxl: Split afu_register_irqs() function
Split the afu_register_irqs() function so that different parts can be useful elsewhere. Signed-off-by: Michael Neuling Acked-by: Ian Munsie --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 19/24] cxl: Configure PSL for kernel contexts and merge code
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 Acked-by: Ian Munsie --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 20/24] cxl: Rework context lifetimes
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 Acked-by: Ian Munsie --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 21/24] cxl: Cleanup Makefile
Cleanup Makefile by fixing line wrapping. Signed-off-by: Michael Neuling Acked-by: Ian Munsie --- 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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 22/24] cxl: Move include file cxl.h -> cxl-base.h
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 Acked-by: Ian Munsie --- 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 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 -#include +#include 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 #include #include -#include +#include /* * 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 #include -#include +#include #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 #include -#include +#include #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 #include #include -#include +#include #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 #include #include -#include +#include #include 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 #include #include -#include +#include #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 #include #include -#include +#include #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 #include #include -#include +#include #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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 23/24] cxl: Export file ops for use by API
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 Acked-by: Ian Munsie --- 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 #include #include +#include #include #include #include @@ -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 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 24/24] cxl: Add AFU virtual PHB and kernel API
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 Acked-by: Ian Munsie --- 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 000..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 +#include +#include +#include +#include + +#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_conte
Re: [PATCH] cxl: Set up and enable PSL Timebase
On Thu, 2015-05-28 at 15:12 +0200, Philippe Bergheaud wrote: > This patch configures the PSL Timebase function and enables it, > after the CAPP has been initialized by OPAL. Failures are reported > and ignored. Needs an Signed-off-by. Comments inline. > --- > drivers/misc/cxl/cxl.h |5 + > drivers/misc/cxl/pci.c | 35 +++ > 2 files changed, 40 insertions(+), 0 deletions(-) > > diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h > index a1cee47..38a7cf9 100644 > --- a/drivers/misc/cxl/cxl.h > +++ b/drivers/misc/cxl/cxl.h > @@ -82,8 +82,10 @@ static const cxl_p1_reg_t CXL_PSL_AFUSEL = {0x00B0}; > /* 0x00C0:7EFF Implementation dependent area */ > static const cxl_p1_reg_t CXL_PSL_FIR1 = {0x0100}; > static const cxl_p1_reg_t CXL_PSL_FIR2 = {0x0108}; > +static const cxl_p1_reg_t CXL_PSL_Timebase = {0x0110}; > static const cxl_p1_reg_t CXL_PSL_VERSION = {0x0118}; > static const cxl_p1_reg_t CXL_PSL_RESLCKTO = {0x0128}; > +static const cxl_p1_reg_t CXL_PSL_TB_CTLSTAT = {0x0140}; > static const cxl_p1_reg_t CXL_PSL_FIR_CNTL = {0x0148}; > static const cxl_p1_reg_t CXL_PSL_DSNDCTL = {0x0150}; > static const cxl_p1_reg_t CXL_PSL_SNWRALLOC = {0x0158}; > @@ -151,6 +153,9 @@ static const cxl_p2n_reg_t CXL_PSL_WED_An = {0x0A0}; > #define CXL_PSL_SPAP_Size_Shift 4 > #define CXL_PSL_SPAP_V0x0001ULL > > +/** CXL_PSL_Control / > +#define CXL_PSL_Control_tb 0x0001ULL > + > /** CXL_PSL_DLCNTL */ > #define CXL_PSL_DLCNTL_D (0x1ull << (63-28)) > #define CXL_PSL_DLCNTL_C (0x1ull << (63-29)) > diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c > index fc938de..afd89cc 100644 > --- a/drivers/misc/cxl/pci.c > +++ b/drivers/misc/cxl/pci.c > @@ -360,6 +360,38 @@ static int init_implementation_adapter_regs(struct cxl > *adapter, struct pci_dev > return 0; > } > > +#define TBSYNC_CNT(n) (((u64)n & 0x7) << (63-6)) > + > +static int cxl_setup_psl_timebase(struct cxl *adapter, struct pci_dev *dev) > +{ > + u64 psl_tb; > + int delta; > + unsigned int retry = 0; > + > + /* > + * Setup PSL Timebase Control and Status register > + * with the recommended Timebase Sync Count value > + */ > + cxl_p1_write(adapter, CXL_PSL_TB_CTLSTAT, TBSYNC_CNT(2)); 2? > + > + /* Enable PSL Timebase */ > + cxl_p1_write(adapter, CXL_PSL_Control, CXL_PSL_Control_tb); > + /* Wait until CORE TB and PSL TB difference <= 16usecs */ How many tries does this normally take? Should we have a sleep in here to wait for it to sync rather than just coming back around right away? > + do { > + if (retry++ > 5) { > + pr_err("PSL: Timebase sync: giving up!\n"); > + return 1; Please use negative error codes here. -EIO? > + } > + psl_tb = cxl_p1_read(adapter, CXL_PSL_Timebase); > + delta = mftb() - psl_tb; > + if (delta < 0) > + delta = -delta; > + } while (cputime_to_usecs(delta) > 16); > + > + dev_info(&dev->dev, "PSL: Timebase synced\n"); > + return 0; > +} > + > static int init_implementation_afu_regs(struct cxl_afu *afu) > { > /* read/write masks for this slice */ > @@ -995,6 +1027,9 @@ static struct cxl *cxl_init_adapter(struct pci_dev *dev) > if ((rc = pnv_phb_to_cxl(dev, OPAL_PHB_CAPI_MODE_CAPI))) > goto err3; > > + /* Don't care if this one fails: */ > + cxl_setup_psl_timebase(adapter, dev); And check it here. Thanks, Mikey > + > if ((rc = cxl_register_psl_err_irq(adapter))) > goto err3; > ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] cxl: Set up and enable PSL Timebase
On Mon, 2015-06-01 at 09:37 +0200, Philippe Bergheaud wrote: > Michael Neuling wrote: > > On Thu, 2015-05-28 at 15:12 +0200, Philippe Bergheaud wrote: > > > >>This patch configures the PSL Timebase function and enables it, > >>after the CAPP has been initialized by OPAL. Failures are reported > >>and ignored. > > > > > > Needs an Signed-off-by. > Yes. > > Comments inline. > > > > > >>--- > >> drivers/misc/cxl/cxl.h |5 + > >> drivers/misc/cxl/pci.c | 35 +++ > >> 2 files changed, 40 insertions(+), 0 deletions(-) > >> > >>diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h > >>index a1cee47..38a7cf9 100644 > >>--- a/drivers/misc/cxl/cxl.h > >>+++ b/drivers/misc/cxl/cxl.h > >>@@ -82,8 +82,10 @@ static const cxl_p1_reg_t CXL_PSL_AFUSEL = {0x00B0}; > >> /* 0x00C0:7EFF Implementation dependent area */ > >> static const cxl_p1_reg_t CXL_PSL_FIR1 = {0x0100}; > >> static const cxl_p1_reg_t CXL_PSL_FIR2 = {0x0108}; > >>+static const cxl_p1_reg_t CXL_PSL_Timebase = {0x0110}; > >> static const cxl_p1_reg_t CXL_PSL_VERSION = {0x0118}; > >> static const cxl_p1_reg_t CXL_PSL_RESLCKTO = {0x0128}; > >>+static const cxl_p1_reg_t CXL_PSL_TB_CTLSTAT = {0x0140}; > >> static const cxl_p1_reg_t CXL_PSL_FIR_CNTL = {0x0148}; > >> static const cxl_p1_reg_t CXL_PSL_DSNDCTL = {0x0150}; > >> static const cxl_p1_reg_t CXL_PSL_SNWRALLOC = {0x0158}; > >>@@ -151,6 +153,9 @@ static const cxl_p2n_reg_t CXL_PSL_WED_An = {0x0A0}; > >> #define CXL_PSL_SPAP_Size_Shift 4 > >> #define CXL_PSL_SPAP_V0x0001ULL > >> > >>+/** CXL_PSL_Control > >>/ > >>+#define CXL_PSL_Control_tb 0x0001ULL > >>+ > >> /** CXL_PSL_DLCNTL > >> */ > >> #define CXL_PSL_DLCNTL_D (0x1ull << (63-28)) > >> #define CXL_PSL_DLCNTL_C (0x1ull << (63-29)) > >>diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c > >>index fc938de..afd89cc 100644 > >>--- a/drivers/misc/cxl/pci.c > >>+++ b/drivers/misc/cxl/pci.c > >>@@ -360,6 +360,38 @@ static int init_implementation_adapter_regs(struct cxl > >>*adapter, struct pci_dev > >>return 0; > >> } > >> > >>+#define TBSYNC_CNT(n) (((u64)n & 0x7) << (63-6)) > >>+ > >>+static int cxl_setup_psl_timebase(struct cxl *adapter, struct pci_dev *dev) > >>+{ > >>+ u64 psl_tb; > >>+ int delta; > >>+ unsigned int retry = 0; > >>+ > >>+ /* > >>+* Setup PSL Timebase Control and Status register > >>+* with the recommended Timebase Sync Count value > >>+*/ > >>+ cxl_p1_write(adapter, CXL_PSL_TB_CTLSTAT, TBSYNC_CNT(2)); > > > > > > 2? > Quoting the PSL workbook description of the PSL_TB_CTLSTAT register: > > 4:6 tbsync_cnt > TimebaseSyncCount. Number of 250MHz cycles x 2048 before initiating another > Timebase Recalibration sequence. > Processor chipTimebase facilities receive a tod_sync pulse every 16us or 4000 > 250 MHz cycles so '010' is the Recommended value. > 000 = never > 001 = 2048 > 010 = 4096 (2 * 2048) > ... > 111 = 14336 (7 * 2048) > > Will make the TimebaseSyncCount unit explicit. Something like: > > #define _2048_250MHZ_CYCLES 1 > cxl_p1_write(adapter, CXL_PSL_TB_CTLSTAT, TBSYNC_CNT(2 * > _2048_250MHZ_CYCLES)); Sounds good! > > > >>+ > >>+ /* Enable PSL Timebase */ > >>+ cxl_p1_write(adapter, CXL_PSL_Control, CXL_PSL_Control_tb); > >>+ /* Wait until CORE TB and PSL TB difference <= 16usecs */ > > > > > > How many tries does this normally take? > Two. The second attempt always succeds. Ok > > Should we have a sleep in here to wait for it to sync rather than just > > coming back around right away? > Yes, will add msleep(1) at the beginning of the loop (as the first attempt > always fails). Humm, ok. Is there any documentation to say how long it's suppose to take? Mikey ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] cxl: Set up and enable PSL Timebase
On Mon, 2015-06-01 at 15:56 +0200, Philippe Bergheaud wrote: > Michael Neuling wrote: > > Please use negative error codes here. -EIO? > > And check it here. > > Mikey, > > I am reluctant to fail the entire CAPI init after a PSL timebase sync failure. > If we ignore the error, the CAPI device stays available (without timebase > sync). > If we honour the error, the CAPI device fails entirely. > > I know three reasons why PSL timebase sync can fail: > 1. h/w failure This would be a good reason to fail it. Bad hardware, we should fail. > 2. OPAL did not initialize the CAPP timebase (wrong OPAL version) This would not as we are going to have to deal with older opal for a while. Is there a way for us to tell if OPAL has this capability? I guess we could add something to the device tree of the PHB node if we know the timebase has been synced. > 3. the PCIe bus was not powered off/on between shutdown and reboot We should fix that. What's the problem? > I think that it is premature to choose to fail the entire CAPI init in all > cases. > In particular, point 3. introduces a regression, as PCIe off/on was never a > requirement for booting CAPI on P8. We should fix it. Is a PERST enough? > I have tried one workaround do far: forcing the 0 to 1 transition of the tb > bit of the PSL register TB_CTLSTAT. > In vain. > > What do you think? The OPAL one (2) is the most concerning but let's work out if we can determine if the syncing has happened in the CAPP unit or not. If we know it's synced but it fails your test, then I think we should fail the whole probe. I the other reasons (1 and 3) shouldn't be ignored. Mikey ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] cxl: Reset default context for vPHB on release
When we release the device, we should also invalidate the default context. With this cxl_get_context() will return null after removal. Signed-off-by: Michael Neuling --- drivers/misc/cxl/vphb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/misc/cxl/vphb.c b/drivers/misc/cxl/vphb.c index f733309..b1d1983a 100644 --- a/drivers/misc/cxl/vphb.c +++ b/drivers/misc/cxl/vphb.c @@ -72,6 +72,7 @@ static void cxl_pci_disable_device(struct pci_dev *dev) dev_err(&dev->dev, "Default context started\n"); return; } + dev->dev.archdata.cxl_ctx = NULL; cxl_release_context(ctx); } } -- 2.1.0 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
deb-pkg: Add support for powerpc little endian
The Debian powerpc little endian architecture is called ppc64le. This is the default architecture used by Ubuntu for powerpc. The below checks the kernel config to see if we are compiling little endian and sets the Debian arch appropriately. Signed-off-by: Michael Neuling diff --git a/scripts/package/builddeb b/scripts/package/builddeb index 35d5a58..6f4a1af 100644 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -37,7 +37,7 @@ create_package() { s390*) debarch=s390$(grep -q CONFIG_64BIT=y $KCONFIG_CONFIG && echo x || true) ;; ppc*) - debarch=powerpc ;; + debarch=$(grep -q CPU_LITTLE_ENDIAN=y $KCONFIG_CONFIG && echo ppc64el || echo powerpc) ;; parisc*) debarch=hppa ;; mips*) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2] deb-pkg: Add support for powerpc little endian
On Fri, 2014-09-05 at 09:13 +0200, Gabriel Paubert wrote: > On Fri, Sep 05, 2014 at 03:28:47PM +1000, Michael Neuling wrote: > > The Debian powerpc little endian architecture is called ppc64le. This > > Huh? ppc64le or ppc64el? ppc64el. Commit message is wrong. Fixed below. Mikey From: Michael Neuling deb-pkg: Add support for powerpc little endian The Debian powerpc little endian architecture is called ppc64el. This is the default architecture used by Ubuntu for powerpc. The below checks the kernel config to see if we are compiling little endian and sets the Debian arch appropriately. Signed-off-by: Michael Neuling diff --git a/scripts/package/builddeb b/scripts/package/builddeb index 35d5a58..6f4a1af 100644 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -37,7 +37,7 @@ create_package() { s390*) debarch=s390$(grep -q CONFIG_64BIT=y $KCONFIG_CONFIG && echo x || true) ;; ppc*) - debarch=powerpc ;; + debarch=$(grep -q CPU_LITTLE_ENDIAN=y $KCONFIG_CONFIG && echo ppc64el || echo powerpc) ;; parisc*) debarch=hppa ;; mips*) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/4] powerpc/powernv: Add OPAL check token call
On Mon, 2014-09-15 at 13:10 +1000, Michael Ellerman wrote: > On Tue, 2014-08-19 at 14:47 +1000, Michael Neuling wrote: > > Currently there is no way to generically check if an OPAL call exists or not > > from the host kernel. > > > > This adds an OPAL call opal_check_token() which tells you if the given > > token is > > present in OPAL or not. > > > > Signed-off-by: Michael Neuling > > --- > > arch/powerpc/include/asm/opal.h| 7 +++ > > arch/powerpc/platforms/powernv/opal-wrappers.S | 1 + > > 2 files changed, 8 insertions(+) > > > > diff --git a/arch/powerpc/include/asm/opal.h > > b/arch/powerpc/include/asm/opal.h > > index 86055e5..4593a93 100644 > > --- a/arch/powerpc/include/asm/opal.h > > +++ b/arch/powerpc/include/asm/opal.h > > @@ -135,6 +135,7 @@ struct opal_sg_list { > > #define OPAL_FLASH_MANAGE 77 > > #define OPAL_FLASH_UPDATE 78 > > #define OPAL_RESYNC_TIMEBASE 79 > > +#define OPAL_CHECK_TOKEN 80 > > #define OPAL_DUMP_INIT 81 > > #define OPAL_DUMP_INFO 82 > > #define OPAL_DUMP_READ 83 > > @@ -417,6 +418,11 @@ struct opal_msg { > > __be64 params[8]; > > }; > > > > +enum OpalCheckTokenStatus { > > + OPAL_TOKEN_ABSENT = 0, > > + OPAL_TOKEN_PRESENT = 1 > > +}; > > I don't see this used anywhere? > > And NoCamelCase ! We can probably just delete the enum since we are just doing this in code anyway: if (!opal_check_token(OPAL_RTC_READ)) goto out; OK? Or would you prefer the usage to read: if (opal_check_token(OPAL_RTC_READ) == OPAL_TOKEN_ABSENT) goto out; > Yes I know there's lots in that file, but I didn't merge that :) Fickle bloody maintainers. I thought I never say this but... I want our crazy Frenchman back! :-P Mikey ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 0/15] POWER8 Coherent Accelerator device driver
This add support for the Coherent Accelerator (cxl) attached to POWER8 processors. This coherent accelerator interface is designed to allow the coherent connection of FPGA based accelerators (and other devices) to a POWER systems. IBM refers to this as the Coherent Accelerator Processor Interface or CAPI. In this driver it's referred to by the name cxl to avoid confusion with the ISDN CAPI subsystem. An overview of the patches: Patches 1-2: Split some of the old Cell co-processor code out so it can be reused. Patches 3-9: Add infrastructure to arch/powerpc needed by cxl. Patches 10: Add call backs needed for invalidating cxl mm contexts. Patch11: Add cxl specific support that needs to be built in to the kernel (can't be a module). Patches 12-15: Add the majority of the device driver and API header. Patch15: Documentation. The documentation in this last patch gives an overview of the hardware architecture as well as the userspace API. The cxl driver has a user-space interface described in include/uapi/misc/cxl.h and Documentation/powerpc/cxl.txt. There are two ioctls which can be used to talk to the driver once the new /dev/cxl/afu0.0 device is opened. This device can also be read and mmaped. There's also sysfs entries used to communicate information about the cxl configuration to userspace. These are documented in Documentation/ABI/testing/sysfs-class-cxl. Many contributed to this device driver but Ian Munsie is the principal author. Driver can also be found here (based on 3.17-rc5): git://github.com/mikey/linux.git cxl https://github.com/mikey/linux/commits/cxl Please consider for inclusion. Feedback welcome! Regards, Mikey Documentation/ABI/testing/sysfs-class-cxl | 125 Documentation/ioctl/ioctl-number.txt | 1 + Documentation/powerpc/00-INDEX | 2 + Documentation/powerpc/cxl.txt | 310 MAINTAINERS| 7 + arch/powerpc/include/asm/copro.h | 18 + arch/powerpc/include/asm/mmu-hash64.h | 3 + arch/powerpc/include/asm/opal.h| 2 + arch/powerpc/include/asm/pnv-pci.h | 27 + arch/powerpc/include/asm/spu.h | 5 +- arch/powerpc/mm/Makefile | 2 + arch/powerpc/mm/copro_fault.c | 140 arch/powerpc/mm/hash_native_64.c | 6 +- arch/powerpc/mm/hash_utils_64.c| 25 +- arch/powerpc/mm/slb.c | 3 - arch/powerpc/mm/slice.c| 3 + arch/powerpc/platforms/cell/Makefile | 2 +- arch/powerpc/platforms/cell/spu_base.c | 41 +- arch/powerpc/platforms/cell/spu_fault.c| 94 --- arch/powerpc/platforms/cell/spufs/fault.c | 4 +- arch/powerpc/platforms/powernv/opal-wrappers.S | 1 + arch/powerpc/platforms/powernv/pci-ioda.c | 229 +- arch/powerpc/sysdev/msi_bitmap.c | 18 +- drivers/misc/Kconfig | 1 + drivers/misc/Makefile | 1 + drivers/misc/cxl/Kconfig | 25 + drivers/misc/cxl/Makefile | 4 + drivers/misc/cxl/base.c| 102 +++ drivers/misc/cxl/context.c | 169 + drivers/misc/cxl/cxl-pci.c | 977 + drivers/misc/cxl/cxl.h | 605 +++ drivers/misc/cxl/debugfs.c | 116 +++ drivers/misc/cxl/fault.c | 298 drivers/misc/cxl/file.c| 503 + drivers/misc/cxl/irq.c | 405 ++ drivers/misc/cxl/main.c| 238 ++ drivers/misc/cxl/native.c | 649 drivers/misc/cxl/sysfs.c | 348 + include/misc/cxl.h | 34 + include/uapi/Kbuild| 1 + include/uapi/misc/Kbuild | 2 + include/uapi/misc/cxl.h| 88 +++ 42 files changed, 5463 insertions(+), 171 deletions(-) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 01/15] powerpc/cell: Move spu_handle_mm_fault() out of cell platform
From: Ian Munsie Currently spu_handle_mm_fault() is in the cell platform. This code is generically useful for other non-cell co-processors on powerpc. This patch moves this function out of the cell platform into arch/powerpc/mm so that others may use it. Signed-off-by: Ian Munsie Signed-off-by: Michael Neuling --- arch/powerpc/include/asm/copro.h | 18 ++ arch/powerpc/include/asm/spu.h | 5 ++--- arch/powerpc/mm/Makefile | 1 + .../{platforms/cell/spu_fault.c => mm/copro_fault.c} | 14 ++ arch/powerpc/platforms/cell/Makefile | 2 +- arch/powerpc/platforms/cell/spufs/fault.c | 4 ++-- 6 files changed, 30 insertions(+), 14 deletions(-) create mode 100644 arch/powerpc/include/asm/copro.h rename arch/powerpc/{platforms/cell/spu_fault.c => mm/copro_fault.c} (89%) diff --git a/arch/powerpc/include/asm/copro.h b/arch/powerpc/include/asm/copro.h new file mode 100644 index 000..2858108 --- /dev/null +++ b/arch/powerpc/include/asm/copro.h @@ -0,0 +1,18 @@ +/* + * 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. + */ + +#ifndef _ASM_POWERPC_COPRO_H +#define _ASM_POWERPC_COPRO_H + +int copro_handle_mm_fault(struct mm_struct *mm, unsigned long ea, + unsigned long dsisr, unsigned *flt); + +int copro_data_segment(struct mm_struct *mm, u64 ea, u64 *esid, u64 *vsid); + +#endif /* _ASM_POWERPC_COPRO_H */ diff --git a/arch/powerpc/include/asm/spu.h b/arch/powerpc/include/asm/spu.h index 37b7ca3..a6e6e2b 100644 --- a/arch/powerpc/include/asm/spu.h +++ b/arch/powerpc/include/asm/spu.h @@ -27,6 +27,8 @@ #include #include #include +#include +#include #define LS_SIZE (256 * 1024) #define LS_ADDR_MASK (LS_SIZE - 1) @@ -277,9 +279,6 @@ void spu_remove_dev_attr(struct device_attribute *attr); int spu_add_dev_attr_group(struct attribute_group *attrs); void spu_remove_dev_attr_group(struct attribute_group *attrs); -int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea, - unsigned long dsisr, unsigned *flt); - /* * Notifier blocks: * diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile index d0130ff..a7f4dd7 100644 --- a/arch/powerpc/mm/Makefile +++ b/arch/powerpc/mm/Makefile @@ -34,3 +34,4 @@ obj-$(CONFIG_TRANSPARENT_HUGEPAGE) += hugepage-hash64.o obj-$(CONFIG_PPC_SUBPAGE_PROT) += subpage-prot.o obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o obj-$(CONFIG_HIGHMEM) += highmem.o +obj-$(CONFIG_SPU_BASE) += copro_fault.o diff --git a/arch/powerpc/platforms/cell/spu_fault.c b/arch/powerpc/mm/copro_fault.c similarity index 89% rename from arch/powerpc/platforms/cell/spu_fault.c rename to arch/powerpc/mm/copro_fault.c index 641e727..ba7df14 100644 --- a/arch/powerpc/platforms/cell/spu_fault.c +++ b/arch/powerpc/mm/copro_fault.c @@ -1,5 +1,5 @@ /* - * SPU mm fault handler + * CoProcessor (SPU/AFU) mm fault handler * * (C) Copyright IBM Deutschland Entwicklung GmbH 2007 * @@ -23,16 +23,14 @@ #include #include #include - -#include -#include +#include /* * This ought to be kept in sync with the powerpc specific do_page_fault * function. Currently, there are a few corner cases that we haven't had * to handle fortunately. */ -int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea, +int copro_handle_mm_fault(struct mm_struct *mm, unsigned long ea, unsigned long dsisr, unsigned *flt) { struct vm_area_struct *vma; @@ -58,12 +56,12 @@ int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea, goto out_unlock; } - is_write = dsisr & MFC_DSISR_ACCESS_PUT; + is_write = dsisr & DSISR_ISSTORE; if (is_write) { if (!(vma->vm_flags & VM_WRITE)) goto out_unlock; } else { - if (dsisr & MFC_DSISR_ACCESS_DENIED) + if (dsisr & DSISR_PROTFAULT) goto out_unlock; if (!(vma->vm_flags & (VM_READ | VM_EXEC))) goto out_unlock; @@ -91,4 +89,4 @@ out_unlock: up_read(&mm->mmap_sem); return ret; } -EXPORT_SYMBOL_GPL(spu_handle_mm_fault); +EXPORT_SYMBOL_GPL(copro_handle_mm_fault); diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile index fe053e7..2d16884 100644 --- a/arch/powerpc/platforms/cell/Makefile +++ b/arch/powerpc/platforms/cell/Makefile @@ -20,7 +20,7 @@ spu-manage-$(CONFIG_PPC_CELL_COMMON) += spu_manage.o obj-$(CONFIG_SPU_BASE) += spu_callbacks.o spu_base.o \
[PATCH 02/15] powerpc/cell: Move data segment faulting code out of cell platform
From: Ian Munsie __spu_trap_data_seg() currently contains code to determine the VSID and ESID required for a particular EA and mm struct. This code is generically useful for other co-processors. This moves the code of the cell platform so it can be used by other powerpc code. Signed-off-by: Ian Munsie Signed-off-by: Michael Neuling --- arch/powerpc/include/asm/mmu-hash64.h | 2 ++ arch/powerpc/mm/copro_fault.c | 48 ++ arch/powerpc/mm/slb.c | 3 --- arch/powerpc/platforms/cell/spu_base.c | 41 +++-- 4 files changed, 54 insertions(+), 40 deletions(-) diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h index d765144..fd19a53 100644 --- a/arch/powerpc/include/asm/mmu-hash64.h +++ b/arch/powerpc/include/asm/mmu-hash64.h @@ -180,6 +180,8 @@ static inline unsigned int mmu_psize_to_shift(unsigned int mmu_psize) * we work in all cases including 4k page size. */ #define VPN_SHIFT 12 +#define slb_vsid_shift(ssize) \ + ((ssize) == MMU_SEGSIZE_256M ? SLB_VSID_SHIFT : SLB_VSID_SHIFT_1T) /* * HPTE Large Page (LP) details diff --git a/arch/powerpc/mm/copro_fault.c b/arch/powerpc/mm/copro_fault.c index ba7df14..4105a63 100644 --- a/arch/powerpc/mm/copro_fault.c +++ b/arch/powerpc/mm/copro_fault.c @@ -90,3 +90,51 @@ out_unlock: return ret; } EXPORT_SYMBOL_GPL(copro_handle_mm_fault); + +int copro_data_segment(struct mm_struct *mm, u64 ea, u64 *esid, u64 *vsid) +{ + int psize, ssize; + + *esid = (ea & ESID_MASK) | SLB_ESID_V; + + switch (REGION_ID(ea)) { + case USER_REGION_ID: + pr_devel("copro_data_segment: 0x%llx -- USER_REGION_ID\n", ea); +#ifdef CONFIG_PPC_MM_SLICES + psize = get_slice_psize(mm, ea); +#else + psize = mm->context.user_psize; +#endif + ssize = user_segment_size(ea); + *vsid = (get_vsid(mm->context.id, ea, ssize) + << slb_vsid_shift(ssize)) | SLB_VSID_USER + | (ssize == MMU_SEGSIZE_1T ? SLB_VSID_B_1T : 0); + break; + case VMALLOC_REGION_ID: + pr_devel("copro_data_segment: 0x%llx -- VMALLOC_REGION_ID\n", ea); + if (ea < VMALLOC_END) + psize = mmu_vmalloc_psize; + else + psize = mmu_io_psize; + *vsid = (get_kernel_vsid(ea, mmu_kernel_ssize) + << SLB_VSID_SHIFT) | SLB_VSID_KERNEL + | (mmu_kernel_ssize == MMU_SEGSIZE_1T ? SLB_VSID_B_1T : 0); + break; + case KERNEL_REGION_ID: + pr_devel("copro_data_segment: 0x%llx -- KERNEL_REGION_ID\n", ea); + psize = mmu_linear_psize; + *vsid = (get_kernel_vsid(ea, mmu_kernel_ssize) + << SLB_VSID_SHIFT) | SLB_VSID_KERNEL + | (mmu_kernel_ssize == MMU_SEGSIZE_1T ? SLB_VSID_B_1T : 0); + break; + default: + /* Future: support kernel segments so that drivers can use the +* CoProcessors */ + pr_debug("invalid region access at %016llx\n", ea); + return 1; + } + *vsid |= mmu_psize_defs[psize].sllp; + + return 0; +} +EXPORT_SYMBOL_GPL(copro_data_segment); diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c index 0399a67..6e450ca 100644 --- a/arch/powerpc/mm/slb.c +++ b/arch/powerpc/mm/slb.c @@ -46,9 +46,6 @@ static inline unsigned long mk_esid_data(unsigned long ea, int ssize, return (ea & slb_esid_mask(ssize)) | SLB_ESID_V | slot; } -#define slb_vsid_shift(ssize) \ - ((ssize) == MMU_SEGSIZE_256M? SLB_VSID_SHIFT: SLB_VSID_SHIFT_1T) - static inline unsigned long mk_vsid_data(unsigned long ea, int ssize, unsigned long flags) { diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 2930d1e..fe004b1 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -167,45 +167,12 @@ static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb) static int __spu_trap_data_seg(struct spu *spu, unsigned long ea) { - struct mm_struct *mm = spu->mm; struct spu_slb slb; - int psize; - - pr_debug("%s\n", __func__); - - slb.esid = (ea & ESID_MASK) | SLB_ESID_V; + int ret; - switch(REGION_ID(ea)) { - case USER_REGION_ID: -#ifdef CONFIG_PPC_MM_SLICES - psize = get_slice_psize(mm, ea); -#else - psize = mm->context.user_psize; -#endif - slb.vsid = (get_vsid(mm->context.id, ea, MMU_SEGSIZE_256M) - << SLB_VSID_SHIFT) | SL
[PATCH 03/15] powerpc/msi: Improve IRQ bitmap allocator
From: Ian Munsie Currently msi_bitmap_alloc_hwirqs() will round up any IRQ allocation requests to the nearest power of 2. eg. ask for 5 IRQs and you'll get 8. This wastes a lot of IRQs which can be a scarce resource. For cxl we can require multiple IRQs for every contexts that is attached to the accelerator. For AFU directed accelerators, there may be 1000s of contexts attached, hence we can easily run out of IRQs, especially if we are needlessly wasting them. This changes the msi_bitmap_alloc_hwirqs() to allocate only the required number of IRQs, hence avoiding this wastage. Signed-off-by: Ian Munsie Signed-off-by: Michael Neuling --- arch/powerpc/sysdev/msi_bitmap.c | 18 +- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/sysdev/msi_bitmap.c b/arch/powerpc/sysdev/msi_bitmap.c index 2ff6302..e001559 100644 --- a/arch/powerpc/sysdev/msi_bitmap.c +++ b/arch/powerpc/sysdev/msi_bitmap.c @@ -24,28 +24,36 @@ int msi_bitmap_alloc_hwirqs(struct msi_bitmap *bmp, int num) * This is fast, but stricter than we need. We might want to add * a fallback routine which does a linear search with no alignment. */ - offset = bitmap_find_free_region(bmp->bitmap, bmp->irq_count, order); + offset = bitmap_find_next_zero_area(bmp->bitmap, bmp->irq_count, 0, + num, (1 << order) - 1); + if (offset > bmp->irq_count) + goto err; + bitmap_set(bmp->bitmap, offset, num); spin_unlock_irqrestore(&bmp->lock, flags); pr_debug("msi_bitmap: allocated 0x%x (2^%d) at offset 0x%x\n", num, order, offset); return offset; +err: + spin_unlock_irqrestore(&bmp->lock, flags); + return -ENOMEM; } +EXPORT_SYMBOL(msi_bitmap_alloc_hwirqs); void msi_bitmap_free_hwirqs(struct msi_bitmap *bmp, unsigned int offset, unsigned int num) { unsigned long flags; - int order = get_count_order(num); - pr_debug("msi_bitmap: freeing 0x%x (2^%d) at offset 0x%x\n", -num, order, offset); + pr_debug("msi_bitmap: freeing 0x%x at offset 0x%x\n", +num, offset); spin_lock_irqsave(&bmp->lock, flags); - bitmap_release_region(bmp->bitmap, offset, order); + bitmap_clear(bmp->bitmap, offset, num); spin_unlock_irqrestore(&bmp->lock, flags); } +EXPORT_SYMBOL(msi_bitmap_free_hwirqs); void msi_bitmap_reserve_hwirq(struct msi_bitmap *bmp, unsigned int hwirq) { -- 1.9.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 04/15] powerpc/mm: Export mmu_kernel_ssize and mmu_linear_psize
From: Ian Munsie Signed-off-by: Ian Munsie Signed-off-by: Michael Neuling --- arch/powerpc/mm/hash_utils_64.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index daee7f4..0f73367 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -98,6 +98,7 @@ unsigned long htab_size_bytes; unsigned long htab_hash_mask; EXPORT_SYMBOL_GPL(htab_hash_mask); int mmu_linear_psize = MMU_PAGE_4K; +EXPORT_SYMBOL_GPL(mmu_linear_psize); int mmu_virtual_psize = MMU_PAGE_4K; int mmu_vmalloc_psize = MMU_PAGE_4K; #ifdef CONFIG_SPARSEMEM_VMEMMAP @@ -105,6 +106,7 @@ int mmu_vmemmap_psize = MMU_PAGE_4K; #endif int mmu_io_psize = MMU_PAGE_4K; int mmu_kernel_ssize = MMU_SEGSIZE_256M; +EXPORT_SYMBOL_GPL(mmu_kernel_ssize); int mmu_highuser_ssize = MMU_SEGSIZE_256M; u16 mmu_slb_size = 64; EXPORT_SYMBOL_GPL(mmu_slb_size); -- 1.9.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 05/15] powerpc/powernv: Split out set MSI IRQ chip code
From: Ian Munsie Some of the MSI IRQ code in pnv_pci_ioda_msi_setup() is generically useful so split it out. This will be used by some of the cxl PCIe code later. Signed-off-by: Ian Munsie Signed-off-by: Michael Neuling --- arch/powerpc/platforms/powernv/pci-ioda.c | 43 ++- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index df241b1..194f90a 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -1306,14 +1306,36 @@ static void pnv_ioda2_msi_eoi(struct irq_data *d) icp_native_eoi(d); } + +static void set_msi_irq_chip(struct pnv_phb *phb, unsigned int virq) +{ + struct irq_data *idata; + struct irq_chip *ichip; + + /* +* Change the IRQ chip for the MSI interrupts on PHB3. +* The corresponding IRQ chip should be populated for +* the first time. +*/ + if (phb->type == PNV_PHB_IODA2) { + if (!phb->ioda.irq_chip_init) { + idata = irq_get_irq_data(virq); + ichip = irq_data_get_irq_chip(idata); + phb->ioda.irq_chip_init = 1; + phb->ioda.irq_chip = *ichip; + phb->ioda.irq_chip.irq_eoi = pnv_ioda2_msi_eoi; + } + + irq_set_chip(virq, &phb->ioda.irq_chip); + } +} + static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, unsigned int hwirq, unsigned int virq, unsigned int is_64, struct msi_msg *msg) { struct pnv_ioda_pe *pe = pnv_ioda_get_pe(dev); struct pci_dn *pdn = pci_get_pdn(dev); - struct irq_data *idata; - struct irq_chip *ichip; unsigned int xive_num = hwirq - phb->msi_base; __be32 data; int rc; @@ -1365,22 +1387,7 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, } msg->data = be32_to_cpu(data); - /* -* Change the IRQ chip for the MSI interrupts on PHB3. -* The corresponding IRQ chip should be populated for -* the first time. -*/ - if (phb->type == PNV_PHB_IODA2) { - if (!phb->ioda.irq_chip_init) { - idata = irq_get_irq_data(virq); - ichip = irq_data_get_irq_chip(idata); - phb->ioda.irq_chip_init = 1; - phb->ioda.irq_chip = *ichip; - phb->ioda.irq_chip.irq_eoi = pnv_ioda2_msi_eoi; - } - - irq_set_chip(virq, &phb->ioda.irq_chip); - } + set_msi_irq_chip(phb, virq); pr_devel("%s: %s-bit MSI on hwirq %x (xive #%d)," " address=%x_%08x data=%x PE# %d\n", -- 1.9.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 06/15] cxl: Add new header for call backs and structs
From: Ian Munsie This new header add defines for callbacks and structs needed by the rest of the kernel to hook into the cxl infrastructure. Empty functions are provided when CONFIG CXL_BASE is not enabled. Signed-off-by: Ian Munsie Signed-off-by: Michael Neuling --- include/misc/cxl.h | 34 ++ 1 file changed, 34 insertions(+) create mode 100644 include/misc/cxl.h diff --git a/include/misc/cxl.h b/include/misc/cxl.h new file mode 100644 index 000..bde46a3 --- /dev/null +++ b/include/misc/cxl.h @@ -0,0 +1,34 @@ +/* + * 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. + */ + +#ifndef _MISC_ASM_CXL_H +#define _MISC_ASM_CXL_H + +#define CXL_IRQ_RANGES 4 + +struct cxl_irq_ranges { + irq_hw_number_t offset[CXL_IRQ_RANGES]; + irq_hw_number_t range[CXL_IRQ_RANGES]; +}; + +#ifdef CONFIG_CXL_BASE + +void cxl_slbia(struct mm_struct *mm); +void cxl_ctx_get(void); +void cxl_ctx_put(void); +bool cxl_ctx_in_use(void); + +#else /* CONFIG_CXL_BASE */ + +#define cxl_slbia(...) do { } while (0) +#define cxl_ctx_in_use(...) false + +#endif /* CONFIG_CXL_BASE */ + +#endif -- 1.9.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 07/15] powerpc/powerpc: Add new PCIe functions for allocating cxl interrupts
From: Ian Munsie This adds a number of functions for allocating IRQs under powernv PCIe for cxl. Signed-off-by: Ian Munsie Signed-off-by: Michael Neuling --- arch/powerpc/include/asm/pnv-pci.h| 27 + arch/powerpc/platforms/powernv/pci-ioda.c | 186 ++ 2 files changed, 213 insertions(+) create mode 100644 arch/powerpc/include/asm/pnv-pci.h diff --git a/arch/powerpc/include/asm/pnv-pci.h b/arch/powerpc/include/asm/pnv-pci.h new file mode 100644 index 000..71717b5 --- /dev/null +++ b/arch/powerpc/include/asm/pnv-pci.h @@ -0,0 +1,27 @@ +/* + * 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. + */ + +#ifndef _ASM_PNV_PCI_H +#define _ASM_PNV_PCI_H + +#include +#include + +int pnv_phb_to_cxl(struct pci_dev *dev); +int pnv_cxl_ioda_msi_setup(struct pci_dev *dev, unsigned int hwirq, + unsigned int virq); +int pnv_cxl_alloc_hwirqs(struct pci_dev *dev, int num); +void pnv_cxl_release_hwirqs(struct pci_dev *dev, int hwirq, int num); +int pnv_cxl_alloc_hwirq_ranges(struct cxl_irq_ranges *irqs, + struct pci_dev *dev, int num); +void pnv_cxl_release_hwirq_ranges(struct cxl_irq_ranges *irqs, + struct pci_dev *dev); +int pnv_cxl_get_irq_count(struct pci_dev *dev); + +#endif diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 194f90a..80919f8 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -38,6 +38,8 @@ #include #include +#include + #include "powernv.h" #include "pci.h" @@ -503,6 +505,163 @@ static struct pnv_ioda_pe *pnv_ioda_get_pe(struct pci_dev *dev) return NULL; return &phb->ioda.pe_array[pdn->pe_number]; } + +struct device_node *pnv_pci_to_phb_node(struct pci_dev *dev) +{ + struct device_node *np; + struct property *prop = NULL; + + np = of_node_get(pci_device_to_OF_node(dev)); + + /* Scan up the tree looking for the PHB node */ + while (np) { + if ((prop = of_find_property(np, "ibm,opal-phbid", NULL))) + break; + np = of_get_next_parent(np); + } + + if (!prop) { + of_node_put(np); + return NULL; + } + + return np; +} +EXPORT_SYMBOL(pnv_pci_to_phb_node); + +#ifdef CONFIG_CXL_BASE +int pnv_phb_to_cxl(struct pci_dev *dev) +{ + struct device_node *np; + struct pnv_ioda_pe *pe; + const u64 *prop64; + u64 phb_id; + int rc; + + dev_info(&dev->dev, "switch PHB to CXL\n"); + + if (!(np = pnv_pci_to_phb_node(dev))) + return -ENODEV; + + prop64 = of_get_property(np, "ibm,opal-phbid", NULL); + + phb_id = be64_to_cpup(prop64); + dev_info(&dev->dev, "PHB-ID : 0x%016llx\n", phb_id); + + if (!(pe = pnv_ioda_get_pe(dev))) { + rc = -ENODEV; + goto out; + } + dev_info(&dev->dev, " pe : %i\n", pe->pe_number); + + if ((rc = opal_pci_set_phb_cxl_mode(phb_id, 1, pe->pe_number))) + dev_err(&dev->dev, "opal_pci_set_phb_cxl_mode failed: %i\n", rc); + +out: + of_node_put(np); + return rc; +} +EXPORT_SYMBOL(pnv_phb_to_cxl); + +int pnv_cxl_alloc_hwirqs(struct pci_dev *dev, int num) +{ + struct pci_controller *hose = pci_bus_to_host(dev->bus); + struct pnv_phb *phb = hose->private_data; + int hwirq = msi_bitmap_alloc_hwirqs(&phb->msi_bmp, num); + + if (hwirq < 0) { + dev_warn(&dev->dev, "Failed to find a free MSI\n"); + return -ENOSPC; + } + + return phb->msi_base + hwirq; +} +EXPORT_SYMBOL(pnv_cxl_alloc_hwirqs); + +void pnv_cxl_release_hwirqs(struct pci_dev *dev, int hwirq, int num) +{ + struct pci_controller *hose = pci_bus_to_host(dev->bus); + struct pnv_phb *phb = hose->private_data; + + msi_bitmap_free_hwirqs(&phb->msi_bmp, hwirq - phb->msi_base, num); +} +EXPORT_SYMBOL(pnv_cxl_release_hwirqs); + + +int pnv_cxl_alloc_hwirq_ranges(struct cxl_irq_ranges *irqs, + struct pci_dev *dev, int num) +{ + struct pci_controller *hose = pci_bus_to_host(dev->bus); + struct pnv_phb *phb = hose->private_data; + int range = 0; + int hwirq; + int try; + + memset(irqs, 0, sizeof(struct cxl_irq_ranges)); + + for (range = 1; range < CXL_IRQ_RANGES && num; range++) { + try = num; + while (tr
[PATCH 08/15] powerpc/mm: Add new hash_page_mm()
From: Ian Munsie This adds a new function hash_page_mm() based on the existing hash_page(). This version allows any struct mm to be passed in, rather than assuming current. This is useful for servicing co-processor faults which are not in the context of the current running process. We need to be careful here as the current hash_page() assumes current in a few places. Signed-off-by: Ian Munsie Signed-off-by: Michael Neuling --- arch/powerpc/include/asm/mmu-hash64.h | 1 + arch/powerpc/mm/hash_utils_64.c | 20 +--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h index fd19a53..a3b85e9 100644 --- a/arch/powerpc/include/asm/mmu-hash64.h +++ b/arch/powerpc/include/asm/mmu-hash64.h @@ -319,6 +319,7 @@ extern int __hash_page_64K(unsigned long ea, unsigned long access, unsigned int local, int ssize); struct mm_struct; unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap); +extern int hash_page_mm(struct mm_struct *mm, unsigned long ea, unsigned long access, unsigned long trap); extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap); int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, pte_t *ptep, unsigned long trap, int local, int ssize, diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 0f73367..66071af 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -991,26 +991,24 @@ static void check_paca_psize(unsigned long ea, struct mm_struct *mm, * -1 - critical hash insertion error * -2 - access not permitted by subpage protection mechanism */ -int hash_page(unsigned long ea, unsigned long access, unsigned long trap) +int hash_page_mm(struct mm_struct *mm, unsigned long ea, unsigned long access, unsigned long trap) { enum ctx_state prev_state = exception_enter(); pgd_t *pgdir; unsigned long vsid; - struct mm_struct *mm; pte_t *ptep; unsigned hugeshift; const struct cpumask *tmp; int rc, user_region = 0, local = 0; int psize, ssize; - DBG_LOW("hash_page(ea=%016lx, access=%lx, trap=%lx\n", - ea, access, trap); + DBG_LOW("%s(ea=%016lx, access=%lx, trap=%lx\n", + __func__, ea, access, trap); /* Get region & vsid */ switch (REGION_ID(ea)) { case USER_REGION_ID: user_region = 1; - mm = current->mm; if (! mm) { DBG_LOW(" user region with no mm !\n"); rc = 1; @@ -1106,7 +1104,8 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) WARN_ON(1); } #endif - check_paca_psize(ea, mm, psize, user_region); + if (current->mm == mm) + check_paca_psize(ea, mm, psize, user_region); goto bail; } @@ -1149,7 +1148,8 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) } } - check_paca_psize(ea, mm, psize, user_region); + if (current->mm == mm) + check_paca_psize(ea, mm, psize, user_region); #endif /* CONFIG_PPC_64K_PAGES */ #ifdef CONFIG_PPC_HAS_HASH_64K @@ -1184,6 +1184,12 @@ bail: exception_exit(prev_state); return rc; } +EXPORT_SYMBOL_GPL(hash_page_mm); + +int hash_page(unsigned long ea, unsigned long access, unsigned long trap) +{ + return hash_page_mm(current->mm, ea, access, trap); +} EXPORT_SYMBOL_GPL(hash_page); void hash_preload(struct mm_struct *mm, unsigned long ea, -- 1.9.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 09/15] powerpc/opal: Add PHB to cxl mode call
From: Ian Munsie This adds the OPAL call to change a PHB into cxl mode. Signed-off-by: Ian Munsie Signed-off-by: Michael Neuling --- arch/powerpc/include/asm/opal.h| 2 ++ arch/powerpc/platforms/powernv/opal-wrappers.S | 1 + 2 files changed, 3 insertions(+) diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 86055e5..84c37c4dbc 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -146,6 +146,7 @@ struct opal_sg_list { #define OPAL_GET_PARAM 89 #define OPAL_SET_PARAM 90 #define OPAL_DUMP_RESEND 91 +#define OPAL_PCI_SET_PHB_CXL_MODE 93 #define OPAL_DUMP_INFO294 #define OPAL_PCI_EEH_FREEZE_SET97 #define OPAL_HANDLE_HMI98 @@ -924,6 +925,7 @@ int64_t opal_sensor_read(uint32_t sensor_hndl, int token, __be32 *sensor_data); int64_t opal_handle_hmi(void); int64_t opal_register_dump_region(uint32_t id, uint64_t start, uint64_t end); int64_t opal_unregister_dump_region(uint32_t id); +int64_t opal_pci_set_phb_cxl_mode(uint64_t phb_id, uint64_t mode, uint64_t pe_number); /* Internal functions */ extern int early_init_dt_scan_opal(unsigned long node, const char *uname, diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index 2e6ce1b..0fb56dc 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S @@ -247,3 +247,4 @@ OPAL_CALL(opal_set_param, OPAL_SET_PARAM); OPAL_CALL(opal_handle_hmi, OPAL_HANDLE_HMI); OPAL_CALL(opal_register_dump_region, OPAL_REGISTER_DUMP_REGION); OPAL_CALL(opal_unregister_dump_region, OPAL_UNREGISTER_DUMP_REGION); +OPAL_CALL(opal_pci_set_phb_cxl_mode, OPAL_PCI_SET_PHB_CXL_MODE); -- 1.9.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 10/15] powerpc/mm: Add hooks for cxl
From: Ian Munsie This add a hook into tlbie() so that we use global invalidations when there are cxl contexts active. Normally cxl snoops broadcast tlbie. cxl can have TLB entries invalidated via MMIO, but we aren't doing that yet. So for now we are just disabling local tlbies when cxl contexts are active. In future we can make tlbie() local mode smarter so that it invalidates cxl contexts explicitly when it needs to. This also adds a hooks for when SLBs are invalidated to ensure any corresponding SLBs in cxl are also invalidated at the same time. Signed-off-by: Ian Munsie Signed-off-by: Michael Neuling --- arch/powerpc/mm/hash_native_64.c | 6 +- arch/powerpc/mm/hash_utils_64.c | 3 +++ arch/powerpc/mm/slice.c | 3 +++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index afc0a82..ae4962a 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c @@ -29,6 +29,8 @@ #include #include +#include + #ifdef DEBUG_LOW #define DBG_LOW(fmt...) udbg_printf(fmt) #else @@ -149,9 +151,11 @@ static inline void __tlbiel(unsigned long vpn, int psize, int apsize, int ssize) static inline void tlbie(unsigned long vpn, int psize, int apsize, int ssize, int local) { - unsigned int use_local = local && mmu_has_feature(MMU_FTR_TLBIEL); + unsigned int use_local; int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE); + use_local = local && mmu_has_feature(MMU_FTR_TLBIEL) && !cxl_ctx_in_use(); + if (use_local) use_local = mmu_psize_defs[psize].tlbiel; if (lock_tlbie && !use_local) diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 66071af..be40ff7 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -906,6 +907,7 @@ void demote_segment_4k(struct mm_struct *mm, unsigned long addr) #ifdef CONFIG_SPU_BASE spu_flush_all_slbs(mm); #endif + cxl_slbia(mm); if (get_paca_psize(addr) != MMU_PAGE_4K) { get_paca()->context = mm->context; slb_flush_and_rebolt(); @@ -1145,6 +1147,7 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea, unsigned long access, u #ifdef CONFIG_SPU_BASE spu_flush_all_slbs(mm); #endif + cxl_slbia(mm); } } diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c index b0c75cc..4d3a34b 100644 --- a/arch/powerpc/mm/slice.c +++ b/arch/powerpc/mm/slice.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -235,6 +236,7 @@ static void slice_convert(struct mm_struct *mm, struct slice_mask mask, int psiz #ifdef CONFIG_SPU_BASE spu_flush_all_slbs(mm); #endif + cxl_slbia(mm); } /* @@ -674,6 +676,7 @@ void slice_set_psize(struct mm_struct *mm, unsigned long address, #ifdef CONFIG_SPU_BASE spu_flush_all_slbs(mm); #endif + cxl_slbia(mm); } void slice_set_range_psize(struct mm_struct *mm, unsigned long start, -- 1.9.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 11/15] cxl: Add base builtin support
From: Ian Munsie This adds the base cxl support that needs to be build into the kernel to use cxl as a module. This is needed so that the cxl call backs from the core powerpc mm code always exist irrespective of if the cxl module is loaded or not. This is similar to how cell works with CONFIG_SPU_BASE. This adds a cxl_slbia() call (similar to spu_flush_all_slbs()) which checks for the cxl module being loaded. If the modules is not loaded we return, otherwise we call into the cxl SLB invalidation code. This also adds the cxl_ctx_in_use() function for use in the mm code to see if any cxl contexts are currently in use. This is used by the tlbie() to determine if it can do local TLB invalidations or not. This also adds get/put calls for the cxl driver module to refcount the active cxl contexts. Signed-off-by: Ian Munsie Signed-off-by: Michael Neuling --- arch/powerpc/mm/Makefile | 1 + drivers/misc/Kconfig | 1 + drivers/misc/Makefile | 1 + drivers/misc/cxl/Kconfig | 7 drivers/misc/cxl/Makefile | 1 + drivers/misc/cxl/base.c | 102 ++ 6 files changed, 113 insertions(+) create mode 100644 drivers/misc/cxl/Kconfig create mode 100644 drivers/misc/cxl/Makefile create mode 100644 drivers/misc/cxl/base.c diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile index a7f4dd7..2888133 100644 --- a/arch/powerpc/mm/Makefile +++ b/arch/powerpc/mm/Makefile @@ -35,3 +35,4 @@ obj-$(CONFIG_PPC_SUBPAGE_PROT)+= subpage-prot.o obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o obj-$(CONFIG_HIGHMEM) += highmem.o obj-$(CONFIG_SPU_BASE) += copro_fault.o +obj-$(CONFIG_CXL_BASE) += copro_fault.o diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index b841180..bbeb451 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -527,4 +527,5 @@ source "drivers/misc/vmw_vmci/Kconfig" source "drivers/misc/mic/Kconfig" source "drivers/misc/genwqe/Kconfig" source "drivers/misc/echo/Kconfig" +source "drivers/misc/cxl/Kconfig" endmenu diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 5497d02..7d5c4cd 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -55,3 +55,4 @@ obj-y += mic/ obj-$(CONFIG_GENWQE) += genwqe/ obj-$(CONFIG_ECHO) += echo/ obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o +obj-$(CONFIG_CXL_BASE) += cxl/ diff --git a/drivers/misc/cxl/Kconfig b/drivers/misc/cxl/Kconfig new file mode 100644 index 000..48533e1 --- /dev/null +++ b/drivers/misc/cxl/Kconfig @@ -0,0 +1,7 @@ +# +# IBM Coherent Accelerator (CXL) compatible devices +# + +config CXL_BASE + bool + default n diff --git a/drivers/misc/cxl/Makefile b/drivers/misc/cxl/Makefile new file mode 100644 index 000..e30ad0a --- /dev/null +++ b/drivers/misc/cxl/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_CXL_BASE) += base.o diff --git a/drivers/misc/cxl/base.c b/drivers/misc/cxl/base.c new file mode 100644 index 000..f4cbcfb --- /dev/null +++ b/drivers/misc/cxl/base.c @@ -0,0 +1,102 @@ +/* + * 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 +#include +#include +#include +#include "cxl.h" + +/* protected by rcu */ +static struct cxl_calls *cxl_calls; + +static atomic_t use_count = ATOMIC_INIT(0); + +#ifdef CONFIG_CXL_MODULE + +static inline struct cxl_calls *cxl_calls_get(void) +{ + struct cxl_calls *calls = NULL; + + rcu_read_lock(); + calls = rcu_dereference(cxl_calls); + if (calls && !try_module_get(calls->owner)) + calls = NULL; + rcu_read_unlock(); + + return calls; +} + +static inline void cxl_calls_put(struct cxl_calls *calls) +{ + BUG_ON(calls != cxl_calls); + + /* we don't need to rcu this, as we hold a reference to the module */ + module_put(cxl_calls->owner); +} + +#else /* !defined CONFIG_CXL_MODULE */ + +static inline struct cxl_calls *cxl_calls_get(void) +{ + return cxl_calls; +} + +static inline void cxl_calls_put(struct cxl_calls *calls) { } + +#endif /* CONFIG_CXL_MODULE */ + +void cxl_slbia(struct mm_struct *mm) +{ + struct cxl_calls *calls; + + calls = cxl_calls_get(); + if (!calls) + return; + + calls->cxl_slbia(mm); + cxl_calls_put(calls); +} +EXPORT_SYMBOL(cxl_slbia); + +void cxl_ctx_get(void) +{ + atomic_inc(&use_count); +} +EXPORT_SYMBOL(cxl_ctx_get); + +void cxl_ctx_put(void) +{ + atomic_dec(&use_count); +} +EXPORT_SYMBOL(cxl_ctx_put); + +bool cxl_ctx_in_use(void) +{ + return (atomic_read(&use_count) != 0); +} +E
[PATCH 13/15] cxl: Userspace header file.
From: Ian Munsie This defines structs and magic numbers required for userspace to interact with the kernel cxl driver via /dev/cxl/afu0.0. It adds this header file Kbuild so it's exported when doing make headers_installs. Signed-off-by: Ian Munsie Signed-off-by: Michael Neuling --- include/uapi/Kbuild | 1 + include/uapi/misc/Kbuild | 2 ++ include/uapi/misc/cxl.h | 88 3 files changed, 91 insertions(+) create mode 100644 include/uapi/misc/Kbuild create mode 100644 include/uapi/misc/cxl.h diff --git a/include/uapi/Kbuild b/include/uapi/Kbuild index 81d2106..245aa6e 100644 --- a/include/uapi/Kbuild +++ b/include/uapi/Kbuild @@ -12,3 +12,4 @@ header-y += video/ header-y += drm/ header-y += xen/ header-y += scsi/ +header-y += misc/ diff --git a/include/uapi/misc/Kbuild b/include/uapi/misc/Kbuild new file mode 100644 index 000..e96cae7 --- /dev/null +++ b/include/uapi/misc/Kbuild @@ -0,0 +1,2 @@ +# misc Header export list +header-y += cxl.h diff --git a/include/uapi/misc/cxl.h b/include/uapi/misc/cxl.h new file mode 100644 index 000..6a394b5 --- /dev/null +++ b/include/uapi/misc/cxl.h @@ -0,0 +1,88 @@ +/* + * 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. + */ + +#ifndef _UAPI_ASM_CXL_H +#define _UAPI_ASM_CXL_H + +#include +#include + +/* ioctls */ +struct cxl_ioctl_start_work { + __u64 wed; + __u64 amr; + __u64 reserved1; + __u32 reserved2; + __s16 num_interrupts; /* -1 = use value from afu descriptor */ + __u16 process_element; /* returned from kernel */ + __u64 reserved3; + __u64 reserved4; + __u64 reserved5; + __u64 reserved6; +}; + +#define CXL_MAGIC 0xCA +#define CXL_IOCTL_START_WORK _IOWR(CXL_MAGIC, 0x00, struct cxl_ioctl_start_work) +#define CXL_IOCTL_CHECK_ERROR _IO(CXL_MAGIC, 0x02) + +/* events from read() */ + +enum cxl_event_type { + CXL_EVENT_READ_FAIL = -1, + CXL_EVENT_RESERVED = 0, + CXL_EVENT_AFU_INTERRUPT = 1, + CXL_EVENT_DATA_STORAGE = 2, + CXL_EVENT_AFU_ERROR = 3, +}; + +struct cxl_event_header { + __u32 type; + __u16 size; + __u16 process_element; + __u64 reserved1; + __u64 reserved2; + __u64 reserved3; +}; + +struct cxl_event_afu_interrupt { + struct cxl_event_header header; + __u16 irq; /* Raised AFU interrupt number */ + __u16 reserved1; + __u32 reserved2; + __u64 reserved3; + __u64 reserved4; + __u64 reserved5; +}; + +struct cxl_event_data_storage { + struct cxl_event_header header; + __u64 addr; + __u64 reserved1; + __u64 reserved2; + __u64 reserved3; +}; + +struct cxl_event_afu_error { + struct cxl_event_header header; + __u64 err; + __u64 reserved1; + __u64 reserved2; + __u64 reserved3; +}; + +struct cxl_event { + union { + struct cxl_event_header header; + struct cxl_event_afu_interrupt irq; + struct cxl_event_data_storage fault; + struct cxl_event_afu_error afu_err; + }; +}; + +#endif -- 1.9.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev