Re: [PATCH v12 1/3] mm, powerpc, x86: define VM_PKEY_BITx bits if CONFIG_ARCH_HAS_PKEYS is enabled
Hi Ram, Thank you for the patch! Yet something to improve: [auto build test ERROR on linus/master] [also build test ERROR on v4.16-rc2 next-20180222] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Ram-Pai/mm-x86-powerpc-Enhancements-to-Memory-Protection-Keys/20180223-042743 config: powerpc-allmodconfig (attached as .config) compiler: powerpc64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=powerpc Note: the linux-review/Ram-Pai/mm-x86-powerpc-Enhancements-to-Memory-Protection-Keys/20180223-042743 HEAD c5692bca45543c242ffca15c811923e4c548ed19 builds fine. It only hurts bisectibility. All error/warnings (new ones prefixed by >>): In file included from include/linux/pkeys.h:9:0, from arch/powerpc/include/asm/mman.h:16, from include/uapi/linux/mman.h:5, from include/linux/mman.h:9, from arch/powerpc/kernel/asm-offsets.c:22: arch/powerpc/include/asm/pkeys.h: In function 'pkey_to_vmflag_bits': >> arch/powerpc/include/asm/pkeys.h:32:23: error: 'VM_PKEY_BIT4' undeclared >> (first use in this function); did you mean 'VM_PKEY_BIT0'? VM_PKEY_BIT3 | VM_PKEY_BIT4) ^ >> arch/powerpc/include/asm/pkeys.h:42:41: note: in expansion of macro >> 'ARCH_VM_PKEY_FLAGS' return (((u64)pkey << VM_PKEY_SHIFT) & ARCH_VM_PKEY_FLAGS); ^~ arch/powerpc/include/asm/pkeys.h:32:23: note: each undeclared identifier is reported only once for each function it appears in VM_PKEY_BIT3 | VM_PKEY_BIT4) ^ >> arch/powerpc/include/asm/pkeys.h:42:41: note: in expansion of macro >> 'ARCH_VM_PKEY_FLAGS' return (((u64)pkey << VM_PKEY_SHIFT) & ARCH_VM_PKEY_FLAGS); ^~ arch/powerpc/include/asm/pkeys.h: In function 'vmflag_to_pte_pkey_bits': arch/powerpc/include/asm/pkeys.h:54:16: error: 'VM_PKEY_BIT4' undeclared (first use in this function); did you mean 'VM_PKEY_BIT0'? ((vm_flags & VM_PKEY_BIT4) ? H_PTE_PKEY_BIT0 : 0x0UL)); ^~~~ VM_PKEY_BIT0 arch/powerpc/include/asm/pkeys.h: In function 'vma_pkey': >> arch/powerpc/include/asm/pkeys.h:32:23: error: 'VM_PKEY_BIT4' undeclared >> (first use in this function); did you mean 'VM_PKEY_BIT0'? VM_PKEY_BIT3 | VM_PKEY_BIT4) ^ arch/powerpc/include/asm/pkeys.h:61:26: note: in expansion of macro 'ARCH_VM_PKEY_FLAGS' return (vma->vm_flags & ARCH_VM_PKEY_FLAGS) >> VM_PKEY_SHIFT; ^~ make[2]: *** [arch/powerpc/kernel/asm-offsets.s] Error 1 make[2]: Target '__build' not remade because of errors. make[1]: *** [prepare0] Error 2 make[1]: Target 'prepare' not remade because of errors. make: *** [sub-make] Error 2 vim +32 arch/powerpc/include/asm/pkeys.h 4fb158f6 Ram Pai 2018-01-18 30 4fb158f6 Ram Pai 2018-01-18 31 #define ARCH_VM_PKEY_FLAGS (VM_PKEY_BIT0 | VM_PKEY_BIT1 | VM_PKEY_BIT2 | \ 4fb158f6 Ram Pai 2018-01-18 @32 VM_PKEY_BIT3 | VM_PKEY_BIT4) 4fb158f6 Ram Pai 2018-01-18 33 013a91b3 Ram Pai 2018-01-18 34 /* Override any generic PKEY permission defines */ 013a91b3 Ram Pai 2018-01-18 35 #define PKEY_DISABLE_EXECUTE 0x4 013a91b3 Ram Pai 2018-01-18 36 #define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS | \ 013a91b3 Ram Pai 2018-01-18 37 PKEY_DISABLE_WRITE | \ 013a91b3 Ram Pai 2018-01-18 38 PKEY_DISABLE_EXECUTE) 013a91b3 Ram Pai 2018-01-18 39 013a91b3 Ram Pai 2018-01-18 40 static inline u64 pkey_to_vmflag_bits(u16 pkey) 013a91b3 Ram Pai 2018-01-18 41 { 013a91b3 Ram Pai 2018-01-18 @42 return (((u64)pkey << VM_PKEY_SHIFT) & ARCH_VM_PKEY_FLAGS); 013a91b3 Ram Pai 2018-01-18 43 } 013a91b3 Ram Pai 2018-01-18 44 :: The code at line 32 was first introduced by commit :: 4fb158f65ac5556b9b4a6f63f38272853ed99b22 powerpc: track allocation status of all pkeys :: TO: Ram Pai <linux...@us.ibm.com> :: CC: Michael Ellerman <m...@ellerman.id.au> --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: powerpc/pseries: Fix duplicate firmware feature for DRC_INFO
On Wed, 2018-02-21 at 13:05:23 UTC, Michael Ellerman wrote: > We had a mid-air collision between two new firmware features, DRMEM_V2 > and DRC_INFO, and they ended up with the same value. > > No one's actually reported any problems, presumably because the new > firmware that supports both properties is not widely available, and > the two properties tend to be enabled together. > > Still if we ever had one enabled but not the other, the bugs that > could result are many and varied. So fix it. > > Fixes: 3f38000eda48 ("powerpc/firmware: Add definitions for new drc-info > firmware feature") > Signed-off-by: Michael Ellerman> Reviewed-by: Tyrel Datwyler Applied to powerpc fixes. https://git.kernel.org/powerpc/c/5539d31a04b3b9ac5f55edb766f1d2 cheers
Re: bpf, powerpc: fix jit for seccomp_data access
On Tue, 2018-02-20 at 19:49:20 UTC, Mark Lord wrote: > I am using SECCOMP to filter syscalls on a ppc32 platform, > and noticed that the JIT compiler was failing on the BPF > even though the interpreter was working fine. > > The issue was that the compiler was missing one of the instructions > used by SECCOMP, so here is a patch to enable JIT for that instruction. > > Signed-Off-By: Mark Lord> > --- old/arch/powerpc/net/bpf_jit_comp.c 2018-02-16 14:07:01.0 -0500 > +++ linux/arch/powerpc/net/bpf_jit_comp.c 2018-02-20 14:41:20.805227494 > -0500 > @@ -329,6 +329,9 @@ static int bpf_jit_build_body(struct bpf > BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4); > PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, > len)); > break; > + case BPF_LDX | BPF_W | BPF_ABS: /* A = *((u32 *)(seccomp_data > + K)); */ > + PPC_LWZ_OFFS(r_A, r_skb, K); > + break; > case BPF_LDX | BPF_W | BPF_LEN: /* X = skb->len; */ > PPC_LWZ_OFFS(r_X, r_skb, offsetof(struct sk_buff, > len)); > break; Applied to powerpc fixes, thanks. https://git.kernel.org/powerpc/c/083b20907185b076f21c265b30fe5b cheers
Re: powerpc: Revert support for ibm,drc-info devtree property
On Tue, 2018-02-13 at 20:02:53 UTC, Michael Bringmann wrote: > This reverts commit 02ef6dd8109b581343ebeb1c4c973513682535d6. > > The earlier patch tried to enable support for a new property > "ibm,drc-info" on powerpc systems. > > Unfortunately, some errors in the associated patch set break things > in some of the DLPAR operations. In particular when attempting to > hot-add a new CPU or set of CPUs, the original patch failed to > properly calculate the available resources, and aborted the operation. > In addition, the original set missed several opportunities to compress > and reuse common code. > > As the associated patch set was meant to provide an optimization of > storage and performance of a set of device-tree properties for future > systems with large amounts of resources, reverting just restores > the previous behavior for existing systems. It seems unnecessary > to enable this feature and introduce the consequent problems in the > field that it will cause at this time, so please revert it for now > until testing of the corrections are finished properly. > > Signed-off-by: Michael W. BringmannApplied to powerpc fixes, thanks. https://git.kernel.org/powerpc/c/c7a3275e0f9e461bb8942132aa6914 cheers
Re: [PATCH 00/38] cxlflash: OpenCXL transport support
On 23/02/18 09:20, Uma Krishnan wrote: This patch series adds OpenCXL support to the cxlflash driver. With this support, new devices using the OpenCXL transport will be supported by the cxlflash driver along with the existing CXL devices. An effort is made to keep this transport specific function independent of the existing core driver that communicates with the AFU. It's "OpenCAPI" for the standard, and "ocxl" for the driver - I'd rather not add "OpenCXL" to our already somewhat confusing proliferation of names :) I'll try to review as much of the ocxl-specific stuff as I can get to, though I'm a bit busy with the OpenCAPI skiboot work and reviewing the libocxl userspace library at the moment. Andrew -- Andrew Donnellan OzLabs, ADL Canberra andrew.donnel...@au1.ibm.com IBM Australia Limited
Re: [PATCH] PCI/AER: Move pci_uevent_ers() out of pci.h
Bjorn Helgaaswrites: > On Thu, Feb 08, 2018 at 09:05:45AM -0600, Bryant G. Ly wrote: >> >> On 2/8/18 6:20 AM, Michael Ellerman wrote: >> >> > There's no reason pci_uevent_ers() needs to be inline in pci.h, so >> > move it out to a C file. >> > >> > Given it's used by AER the obvious location would be somewhere in >> > drivers/pci/pcie/aer, but because it's also used by powerpc EEH code >> > unfortunately that doesn't work in the case where EEH is enabled but >> > PCIEPORTBUS is not. >> > >> > So for now put it in pci-driver.c, next to pci_uevent(), with an >> > appropriate #ifdef so it's not built if AER and EEH are both disabled. >> > >> > While we're moving it also fix up the kernel doc comment for @pdev to >> > be accurate. >> > >> > Reported-by: Linus Torvalds >> > Signed-off-by: Michael Ellerman >> > --- >> > drivers/pci/pci-driver.c | 36 >> > include/linux/pci.h | 38 +++--- >> > 2 files changed, 39 insertions(+), 35 deletions(-) >> >> Looks good, thanks for fixing it! >> >> Signed-off-by: Bryant G. Ly > > This would normally be a "Reviewed-by" unless you actually > participated in developing the patch, and in that case, your > "Signed-off-by" would normally be included in the original posting. > > What do you intend? I'll be glad to add either. I wrote the patch, so Bryant meant Reviewed-by or maybe Acked-by. cheers
Re: [PATCH] PCI/AER: Move pci_uevent_ers() out of pci.h
Bjorn Helgaaswrites: > On Thu, Feb 08, 2018 at 11:20:35PM +1100, Michael Ellerman wrote: >> There's no reason pci_uevent_ers() needs to be inline in pci.h, so >> move it out to a C file. >> >> Given it's used by AER the obvious location would be somewhere in >> drivers/pci/pcie/aer, but because it's also used by powerpc EEH code >> unfortunately that doesn't work in the case where EEH is enabled but >> PCIEPORTBUS is not. >> >> So for now put it in pci-driver.c, next to pci_uevent(), with an >> appropriate #ifdef so it's not built if AER and EEH are both disabled. >> >> While we're moving it also fix up the kernel doc comment for @pdev to >> be accurate. >> >> Reported-by: Linus Torvalds >> Signed-off-by: Michael Ellerman > > Applied to pci/aer for v4.17, thanks! Thanks. cheers
Re: [PATCH] powerpc/powernv: Turn on SCSI_AACRAID in powernv_defconfig
Michael Ellermanwrites: > Brian King writes: >> On 09/03/2017 06:19 PM, Stewart Smith wrote: >>> Michael Ellerman writes: > 2. On a bare metal machine, if you set ipr.fast_reboot=1 on the skiboot >kernel, then we should also avoid resetting the ipr adapter, so ipr >init on the kernel being kexec booted from skiboot should be extremely > fast. OK, I didn't know that was an option, so that might help. > ... > If you've got cases where ipr init is taking a long time, I'd be > interested to know what scenarios are the most annoying to see if there > is any opportunity to improve. Yeah booting bare metal is where I see it (not using ipr.fast_reboot). >>> >>> Hrm... We should probably enable that by default for petitboot then. >>> >>> It'd at least cut some time off booting straight through to OS. >> >> Agreed. I'd be interested to hear if that helps address the issue >> Michael is seeing. >> >> You can easily test this by exiting to a petitboot shell: >> >> echo 1 > /sys/module/ipr/parameters/fast_reboot >> >> Then go back to petitboot and boot the OS. > > Just following up on this (!). > > This does work, and I've now been running it in my CI for about a month > (~1000 boots) with no problems. > > You can also make it persistent by doing: > > $ nvram -p ibm,skiboot --update-config bootargs="ipr.fast_reboot=1" Okay, cool. https://github.com/open-power/op-build/pull/1900 will set it in firmware - we may as well run with this and fix any bugs we find. Any reason why it isn't the default behaviour? -- Stewart Smith OPAL Architect, IBM.
Re: [PATCH v3] watchdog: add SPDX identifiers for watchdog subsystem
Marcus Folkessonwrites: > - Add SPDX identifier > - Remove boiler plate license text > - If MODULE_LICENSE and boiler plate does not match, go for boiler plate > license > > Signed-off-by: Marcus Folkesson > diff --git a/drivers/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c > index 0240c60d14e3..af07f746b7cc 100644 > --- a/drivers/watchdog/wdrtas.c > +++ b/drivers/watchdog/wdrtas.c > @@ -1,3 +1,4 @@ > +// SPDX-License-Identifier: GPL-2.0+ > /* > * FIXME: add wdrtas_get_status and wdrtas_get_boot_status as soon as > * RTAS calls are available > @@ -10,20 +11,6 @@ > * device driver to exploit watchdog RTAS functions > * > * Authors : Utz Bacher > - * > - * 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, or (at your option) > - * any later version. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with this program; if not, write to the Free Software > - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. > */ LGTM. Acked-by: Michael Ellerman (powerpc) cheers
Re: [PATCH] PCI/AER: Move pci_uevent_ers() out of pci.h
On Thu, Feb 08, 2018 at 11:20:35PM +1100, Michael Ellerman wrote: > There's no reason pci_uevent_ers() needs to be inline in pci.h, so > move it out to a C file. > > Given it's used by AER the obvious location would be somewhere in > drivers/pci/pcie/aer, but because it's also used by powerpc EEH code > unfortunately that doesn't work in the case where EEH is enabled but > PCIEPORTBUS is not. > > So for now put it in pci-driver.c, next to pci_uevent(), with an > appropriate #ifdef so it's not built if AER and EEH are both disabled. > > While we're moving it also fix up the kernel doc comment for @pdev to > be accurate. > > Reported-by: Linus Torvalds> Signed-off-by: Michael Ellerman Applied to pci/aer for v4.17, thanks! > --- > drivers/pci/pci-driver.c | 36 > include/linux/pci.h | 38 +++--- > 2 files changed, 39 insertions(+), 35 deletions(-) > > diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c > index 3bed6beda051..f21e8b1bef80 100644 > --- a/drivers/pci/pci-driver.c > +++ b/drivers/pci/pci-driver.c > @@ -1517,6 +1517,42 @@ static int pci_uevent(struct device *dev, struct > kobj_uevent_env *env) > return 0; > } > > +#if defined(CONFIG_PCIEAER) || defined(CONFIG_EEH) > +/** > + * pci_uevent_ers - emit a uevent during recovery path of pci device > + * @pdev: pci device undergoing error recovery > + * @err_type: type of error event > + */ > +void pci_uevent_ers(struct pci_dev *pdev, enum pci_ers_result err_type) > +{ > + int idx = 0; > + char *envp[3]; > + > + switch (err_type) { > + case PCI_ERS_RESULT_NONE: > + case PCI_ERS_RESULT_CAN_RECOVER: > + envp[idx++] = "ERROR_EVENT=BEGIN_RECOVERY"; > + envp[idx++] = "DEVICE_ONLINE=0"; > + break; > + case PCI_ERS_RESULT_RECOVERED: > + envp[idx++] = "ERROR_EVENT=SUCCESSFUL_RECOVERY"; > + envp[idx++] = "DEVICE_ONLINE=1"; > + break; > + case PCI_ERS_RESULT_DISCONNECT: > + envp[idx++] = "ERROR_EVENT=FAILED_RECOVERY"; > + envp[idx++] = "DEVICE_ONLINE=0"; > + break; > + default: > + break; > + } > + > + if (idx > 0) { > + envp[idx++] = NULL; > + kobject_uevent_env(>dev.kobj, KOBJ_CHANGE, envp); > + } > +} > +#endif > + > static int pci_bus_num_vf(struct device *dev) > { > return pci_num_vf(to_pci_dev(dev)); > diff --git a/include/linux/pci.h b/include/linux/pci.h > index 024a1beda008..19c1dbcff0c6 100644 > --- a/include/linux/pci.h > +++ b/include/linux/pci.h > @@ -2280,41 +2280,9 @@ static inline bool pci_is_thunderbolt_attached(struct > pci_dev *pdev) > return false; > } > > -/** > - * pci_uevent_ers - emit a uevent during recovery path of pci device > - * @pdev: pci device to check > - * @err_type: type of error event > - * > - */ > -static inline void pci_uevent_ers(struct pci_dev *pdev, > - enum pci_ers_result err_type) > -{ > - int idx = 0; > - char *envp[3]; > - > - switch (err_type) { > - case PCI_ERS_RESULT_NONE: > - case PCI_ERS_RESULT_CAN_RECOVER: > - envp[idx++] = "ERROR_EVENT=BEGIN_RECOVERY"; > - envp[idx++] = "DEVICE_ONLINE=0"; > - break; > - case PCI_ERS_RESULT_RECOVERED: > - envp[idx++] = "ERROR_EVENT=SUCCESSFUL_RECOVERY"; > - envp[idx++] = "DEVICE_ONLINE=1"; > - break; > - case PCI_ERS_RESULT_DISCONNECT: > - envp[idx++] = "ERROR_EVENT=FAILED_RECOVERY"; > - envp[idx++] = "DEVICE_ONLINE=0"; > - break; > - default: > - break; > - } > - > - if (idx > 0) { > - envp[idx++] = NULL; > - kobject_uevent_env(>dev.kobj, KOBJ_CHANGE, envp); > - } > -} > +#if defined(CONFIG_PCIEAER) || defined(CONFIG_EEH) > +void pci_uevent_ers(struct pci_dev *pdev, enum pci_ers_result err_type); > +#endif > > /* Provide the legacy pci_dma_* API */ > #include > -- > 2.14.1 >
Re: [PATCH] PCI/AER: Move pci_uevent_ers() out of pci.h
On Thu, Feb 08, 2018 at 09:05:45AM -0600, Bryant G. Ly wrote: > > On 2/8/18 6:20 AM, Michael Ellerman wrote: > > > There's no reason pci_uevent_ers() needs to be inline in pci.h, so > > move it out to a C file. > > > > Given it's used by AER the obvious location would be somewhere in > > drivers/pci/pcie/aer, but because it's also used by powerpc EEH code > > unfortunately that doesn't work in the case where EEH is enabled but > > PCIEPORTBUS is not. > > > > So for now put it in pci-driver.c, next to pci_uevent(), with an > > appropriate #ifdef so it's not built if AER and EEH are both disabled. > > > > While we're moving it also fix up the kernel doc comment for @pdev to > > be accurate. > > > > Reported-by: Linus Torvalds> > Signed-off-by: Michael Ellerman > > --- > > drivers/pci/pci-driver.c | 36 > > include/linux/pci.h | 38 +++--- > > 2 files changed, 39 insertions(+), 35 deletions(-) > > Looks good, thanks for fixing it! > > Signed-off-by: Bryant G. Ly This would normally be a "Reviewed-by" unless you actually participated in developing the patch, and in that case, your "Signed-off-by" would normally be included in the original posting. What do you intend? I'll be glad to add either. Bjorn
[PATCH 15/38] cxlflash: Support image reload policy modification
On a PERST, the AFU image can be reloaded or left intact. Provide means to set this image reload policy. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 13 + drivers/scsi/cxlflash/ocxl_hw.h | 1 + 2 files changed, 14 insertions(+) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 2dab547..6f78e71 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -252,6 +252,18 @@ static int ocxlflash_release_context(void *ctx_cookie) } /** + * ocxlflash_perst_reloads_same_image() - sets the image reload policy + * @afu_cookie:Hardware AFU associated with the host. + * @image: Whether to load the same image on PERST. + */ +static void ocxlflash_perst_reloads_same_image(void *afu_cookie, bool image) +{ + struct ocxl_hw_afu *afu = afu_cookie; + + afu->perst_same_image = image; +} + +/** * ocxlflash_destroy_afu() - destroy the AFU structure * @afu_cookie:AFU to be freed. */ @@ -493,6 +505,7 @@ const struct cxlflash_backend_ops cxlflash_ocxl_ops = { .get_context= ocxlflash_get_context, .dev_context_init = ocxlflash_dev_context_init, .release_context= ocxlflash_release_context, + .perst_reloads_same_image = ocxlflash_perst_reloads_same_image, .create_afu = ocxlflash_create_afu, .destroy_afu= ocxlflash_destroy_afu, .get_fd = ocxlflash_get_fd, diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h index 7f234b1..6d6e323 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.h +++ b/drivers/scsi/cxlflash/ocxl_hw.h @@ -17,6 +17,7 @@ struct ocxl_hw_afu { struct ocxlflash_context *ocxl_ctx; /* Host context */ struct pci_dev *pdev; /* PCI device */ struct device *dev; /* Generic device */ + bool perst_same_image; /* Same image loaded on perst */ struct ocxl_fn_config fcfg; /* DVSEC config of the function */ struct ocxl_afu_config acfg;/* AFU configuration data */ -- 2.1.0
Re: [PATCH] PCI/AER: Add a null check before eeh_ops->notify_resume callback.
Vaibhav Jainwrites: > This patch puts a NULL check before branching to the address pointed > to by eeh_ops->notify_resume in eeh_report_resume(). The callback > is used to notify the arch EEH code that a pci device is back > online. > > For PPC64 presently, only an implementation for pseries platform is > available and not for powernv. Hence without this patch EEH recovery > on all non-virtualized hosts is causing a kernel panic when > CONFIG_PCI_IOV is set. The panic is usually is of the form: > > EEH: Notify device driver to resume > Unable to handle kernel paging request for instruction fetch > Faulting instruction address: 0x > Oops: Kernel access of bad area, sig: 11 [#1] > > LR eeh_report_resume+0x218/0x220 > Call Trace: > eeh_report_resume+0x1f0/0x220 (unreliable) > eeh_pe_dev_traverse+0x98/0x170 > eeh_handle_normal_event+0x3f4/0x650 > eeh_handle_event+0x188/0x380 > eeh_event_handler+0x208/0x210 > kthread+0x168/0x1b0 > ret_from_kernel_thread+0x5c/0xb4 > > Cc: Bryant G. Ly > Fixes: 856e1eb9bdd4("PCI/AER: Add uevents in AER and EEH error/resume") > Signed-off-by: Vaibhav Jain 10 out of 10 for the change log! But yeah this is already fixed in my fixes branch, thanks anyway. cheers
Re: [PATCH 4.9 34/77] powerpc: fix build errors in stable tree
Yves-Alexis Perezwrites: > On Fri, 2018-02-23 at 00:16 +1100, Michael Ellerman wrote: >> With the patches I just sent, for pseries and powernv, the mitigation >> should be in place. On machines with updated firmware we'll use the >> hardware-assisted L1 flush, otherwise we fallback to doing it in >> software. > > So as of 4.9.82 meltdown is *not* addressed on those arches, but it should be > ok in 4.9.83 or 4.9.84 depending on when the patches are merged? As of 4.9.82 *most* of the patches to do the mitigation have been merged. One of them was missed, due to it not applying (because it was actually a back port to 4.4 that was sent) that is: 222f20f14062 ("powerpc/64s: Simple RFI macro conversions") That patch adds calls to do the L1D cache flush when returning to user/guest, so it is important that it's missing, the mitigation is not fully effective without that patch. However, 4.9.82 *does* have a backport of: b8e90cb7bc04 ("powerpc/64: Convert the syscall exit path to use RFI_TO_USER/KERNEL") So the syscall path is protected, which means any attack which uses syscalls is likely to fail. Because the data the attack is trying to read has to be in the L1D, you can't write an attack that remains in userspace 100% of the time, you have to enter the kernel and have the kernel load the target data into the L1D for you. With the syscall flush in place you can't use a syscall for that, you have to trigger some other kernel entry/exit, eg. a page fault. TLDR is with the syscall flush in place it's much harder to write an attack. Greg has already released 4.9.83, so hopefully 4.9.84 will be fully protected. Note also that 4.9.82/83 have a bug in the SLB miss handler that can lead to hangs in userspace, fixed by the first patch I sent. cheers
[PATCH 38/38] cxlflash: Enable OpenCXL operations
This commit enables the OpenCXL operations for the OpenCXL devices. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/main.c | 9 +++-- drivers/scsi/cxlflash/main.h | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 8c55fcd..42a95b7 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -3168,7 +3168,8 @@ static struct dev_dependent_vals dev_corsa_vals = { CXLFLASH_MAX_SECTORS, static struct dev_dependent_vals dev_flash_gt_vals = { CXLFLASH_MAX_SECTORS, CXLFLASH_NOTIFY_SHUTDOWN }; static struct dev_dependent_vals dev_briard_vals = { CXLFLASH_MAX_SECTORS, - CXLFLASH_NOTIFY_SHUTDOWN }; + (CXLFLASH_NOTIFY_SHUTDOWN | + CXLFLASH_OCXL_DEV) }; /* * PCI device binding table @@ -3679,9 +3680,13 @@ static int cxlflash_probe(struct pci_dev *pdev, cfg->init_state = INIT_STATE_NONE; cfg->dev = pdev; - cfg->ops = _cxl_ops; cfg->cxl_fops = cxlflash_cxl_fops; + if (ddv->flags & CXLFLASH_OCXL_DEV) + cfg->ops = _ocxl_ops; + else + cfg->ops = _cxl_ops; + /* * Promoted LUNs move to the top of the LUN table. The rest stay on * the bottom half. The bottom half grows from the end (index = 255), diff --git a/drivers/scsi/cxlflash/main.h b/drivers/scsi/cxlflash/main.h index ba0108a..6f1be62 100644 --- a/drivers/scsi/cxlflash/main.h +++ b/drivers/scsi/cxlflash/main.h @@ -97,6 +97,7 @@ struct dev_dependent_vals { u64 flags; #define CXLFLASH_NOTIFY_SHUTDOWN 0x0001ULL #define CXLFLASH_WWPN_VPD_REQUIRED 0x0002ULL +#define CXLFLASH_OCXL_DEV 0x0004ULL }; struct asyc_intr_info { -- 2.1.0
[PATCH 37/38] cxlflash: Support AFU reset
The cxlflash core driver resets the AFU when the master contexts are created in the initialization or recovery paths. Today, the OCXL provider service to perform this operation is pending implementation. To avoid a crash due to a missing fop, log an error once and return success to continue with execution. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 17 + 1 file changed, 17 insertions(+) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index dc45ed2..8a1a9fc 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -468,6 +468,22 @@ static int ocxlflash_stop_context(void *ctx_cookie) } /** + * ocxlflash_afu_reset() - reset the AFU + * @ctx_cookie:Adapter context. + */ +static int ocxlflash_afu_reset(void *ctx_cookie) +{ + struct ocxlflash_context *ctx = ctx_cookie; + struct device *dev = ctx->hw_afu->dev; + + /* Pending implementation from OCXL transport services */ + dev_err_once(dev, "%s: afu_reset() fop not supported\n", __func__); + + /* Silently return success until it is implemented */ + return 0; +} + +/** * ocxlflash_set_master() - sets the context as master * @ctx_cookie:Adapter context to set as master. */ @@ -1393,6 +1409,7 @@ const struct cxlflash_backend_ops cxlflash_ocxl_ops = { .get_irq_objhndl= ocxlflash_get_irq_objhndl, .start_context = ocxlflash_start_context, .stop_context = ocxlflash_stop_context, + .afu_reset = ocxlflash_afu_reset, .set_master = ocxlflash_set_master, .get_context= ocxlflash_get_context, .dev_context_init = ocxlflash_dev_context_init, -- 2.1.0
[PATCH 36/38] cxlflash: Register for translation errors
While enabling a context on the link, a predefined callback can be registered with the OCXL provider services to be notified on translation errors. These errors can in turn be passed back to the user on a read operation. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 31 +-- drivers/scsi/cxlflash/ocxl_hw.h | 4 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 535b21a..dc45ed2 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -335,6 +335,25 @@ static u64 ocxlflash_get_irq_objhndl(void *ctx_cookie, int irq) } /** + * ocxlflash_xsl_fault() - callback when translation error is triggered + * @data: Private data provided at callback registration, the context. + * @addr: Address that triggered the error. + * @dsisr: Value of dsisr register. + */ +static void ocxlflash_xsl_fault(void *data, u64 addr, u64 dsisr) +{ + struct ocxlflash_context *ctx = data; + + spin_lock(>slock); + ctx->fault_addr = addr; + ctx->fault_dsisr = dsisr; + ctx->pending_fault = true; + spin_unlock(>slock); + + wake_up_all(>wq); +} + +/** * start_context() - local routine to start a context * @ctx: Adapter context to be started. * @@ -378,7 +397,8 @@ static int start_context(struct ocxlflash_context *ctx) mm = current->mm; } - rc = ocxl_link_add_pe(link_token, ctx->pe, pid, 0, 0, mm, NULL, NULL); + rc = ocxl_link_add_pe(link_token, ctx->pe, pid, 0, 0, mm, + ocxlflash_xsl_fault, ctx); if (unlikely(rc)) { dev_err(dev, "%s: ocxl_link_add_pe failed rc=%d\n", __func__, rc); @@ -512,6 +532,7 @@ static void *ocxlflash_dev_context_init(struct pci_dev *pdev, void *afu_cookie) ctx->hw_afu = afu; ctx->irq_bitmap = 0; ctx->pending_irq = false; + ctx->pending_fault = false; out: return ctx; err2: @@ -957,7 +978,7 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev) */ static inline bool ctx_event_pending(struct ocxlflash_context *ctx) { - if (ctx->pending_irq) + if (ctx->pending_irq || ctx->pending_fault) return true; return false; @@ -1062,6 +1083,12 @@ static ssize_t afu_read(struct file *file, char __user *buf, size_t count, event.irq.irq = bit + 1; if (bitmap_empty(>irq_bitmap, ctx->num_irqs)) ctx->pending_irq = false; + } else if (ctx->pending_fault) { + event.header.size += sizeof(struct cxl_event_data_storage); + event.header.type = CXL_EVENT_DATA_STORAGE; + event.fault.addr = ctx->fault_addr; + event.fault.dsisr = ctx->fault_dsisr; + ctx->pending_fault = false; } spin_unlock_irqrestore(>slock, lock_flags); diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h index c23b681..c48465a 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.h +++ b/drivers/scsi/cxlflash/ocxl_hw.h @@ -69,4 +69,8 @@ struct ocxlflash_context { int num_irqs; /* Number of interrupts */ bool pending_irq; /* Pending interrupt on the context */ ulong irq_bitmap; /* Bits indicating pending irq num */ + + u64 fault_addr; /* Address that triggered the fault */ + u64 fault_dsisr;/* Value of dsisr register at fault */ + bool pending_fault; /* Pending translation fault */ }; -- 2.1.0
[PATCH 35/38] cxlflash: Introduce OCXL context state machine
In order to protect the OCXL hardware contexts from getting clobbered, a simple state machine is added to indicate when a context is in open, close or start state. The expected states are validated throughout the code to prevent illegal operations on a context. A mutex is added to protect writes to the context state field. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 59 ++--- drivers/scsi/cxlflash/ocxl_hw.h | 8 ++ 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 1044bee..535b21a 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -163,6 +163,16 @@ static struct file *ocxlflash_getfile(struct device *dev, const char *name, static void __iomem *ocxlflash_psa_map(void *ctx_cookie) { struct ocxlflash_context *ctx = ctx_cookie; + struct device *dev = ctx->hw_afu->dev; + + mutex_lock(>state_mutex); + if (ctx->state != STARTED) { + dev_err(dev, "%s: Context not started, state=%d\n", __func__, + ctx->state); + mutex_unlock(>state_mutex); + return NULL; + } + mutex_unlock(>state_mutex); return ioremap(ctx->psn_phys, ctx->psn_size); } @@ -343,6 +353,14 @@ static int start_context(struct ocxlflash_context *ctx) int rc = 0; u32 pid; + mutex_lock(>state_mutex); + if (ctx->state != OPENED) { + dev_err(dev, "%s: Context state invalid, state=%d\n", + __func__, ctx->state); + rc = -EINVAL; + goto out; + } + if (master) { ctx->psn_size = acfg->global_mmio_size; ctx->psn_phys = afu->gmmio_phys; @@ -366,7 +384,10 @@ static int start_context(struct ocxlflash_context *ctx) __func__, rc); goto out; } + + ctx->state = STARTED; out: + mutex_unlock(>state_mutex); return rc; } @@ -396,7 +417,15 @@ static int ocxlflash_stop_context(void *ctx_cookie) struct ocxl_afu_config *acfg = >acfg; struct pci_dev *pdev = afu->pdev; struct device *dev = afu->dev; - int rc; + enum ocxlflash_ctx_state state; + int rc = 0; + + mutex_lock(>state_mutex); + state = ctx->state; + ctx->state = CLOSED; + mutex_unlock(>state_mutex); + if (state != STARTED) + goto out; rc = ocxl_config_terminate_pasid(pdev, acfg->dvsec_afu_control_pos, ctx->pe); @@ -474,7 +503,9 @@ static void *ocxlflash_dev_context_init(struct pci_dev *pdev, void *afu_cookie) spin_lock_init(>slock); init_waitqueue_head(>wq); + mutex_init(>state_mutex); + ctx->state = OPENED; ctx->pe = rc; ctx->master = false; ctx->mapping = NULL; @@ -499,11 +530,23 @@ static void *ocxlflash_dev_context_init(struct pci_dev *pdev, void *afu_cookie) static int ocxlflash_release_context(void *ctx_cookie) { struct ocxlflash_context *ctx = ctx_cookie; + struct device *dev; int rc = 0; if (!ctx) goto out; + dev = ctx->hw_afu->dev; + mutex_lock(>state_mutex); + if (ctx->state >= STARTED) { + dev_err(dev, "%s: Context in use, state=%d\n", __func__, + ctx->state); + mutex_unlock(>state_mutex); + rc = -EBUSY; + goto out; + } + mutex_unlock(>state_mutex); + idr_remove(>hw_afu->idr, ctx->pe); ocxlflash_release_mapping(ctx); kfree(ctx); @@ -939,7 +982,7 @@ static unsigned int afu_poll(struct file *file, struct poll_table_struct *poll) spin_lock_irqsave(>slock, lock_flags); if (ctx_event_pending(ctx)) mask |= POLLIN | POLLRDNORM; - else + else if (ctx->state == CLOSED) mask |= POLLERR; spin_unlock_irqrestore(>slock, lock_flags); @@ -982,7 +1025,7 @@ static ssize_t afu_read(struct file *file, char __user *buf, size_t count, for (;;) { prepare_to_wait(>wq, _wait, TASK_INTERRUPTIBLE); - if (ctx_event_pending(ctx)) + if (ctx_event_pending(ctx) || (ctx->state == CLOSED)) break; if (file->f_flags & O_NONBLOCK) { @@ -1068,12 +,22 @@ static int ocxlflash_mmap_fault(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; struct ocxlflash_context *ctx = vma->vm_file->private_data; + struct device *dev = ctx->hw_afu->dev; u64 mmio_area, offset; offset = vmf->pgoff << PAGE_SHIFT; if (offset >= ctx->psn_size) return VM_FAULT_SIGBUS; + mutex_lock(>state_mutex); + if
[PATCH 34/38] cxlflash: Update synchronous interrupt status bits
The SISLite specification has been updated to define new synchronous interrupt status bits. These bits are set by the AFU when a given PASID or EA is bad and a synchronous interrupt is triggered. The SISLite header file is updated to support these new bits. Note that there are also some formatting updates to some of the existing bits to allow all of the definitions to line up uniformly. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/sislite.h | 35 +-- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/cxlflash/sislite.h b/drivers/scsi/cxlflash/sislite.h index c08b9d3..874abce 100644 --- a/drivers/scsi/cxlflash/sislite.h +++ b/drivers/scsi/cxlflash/sislite.h @@ -258,23 +258,30 @@ struct sisl_host_map { * exit since there is no way to tell which * command caused the error. */ -#define SISL_ISTATUS_PERM_ERR_CMDROOM0x0010ULL /* b59, user error */ -#define SISL_ISTATUS_PERM_ERR_RCB_READ 0x0008ULL /* b60, user error */ -#define SISL_ISTATUS_PERM_ERR_SA_WRITE 0x0004ULL /* b61, user error */ -#define SISL_ISTATUS_PERM_ERR_RRQ_WRITE 0x0002ULL /* b62, user error */ +#define SISL_ISTATUS_PERM_ERR_LISN_3_EA0x0400ULL /* b53, user error */ +#define SISL_ISTATUS_PERM_ERR_LISN_2_EA0x0200ULL /* b54, user error */ +#define SISL_ISTATUS_PERM_ERR_LISN_1_EA0x0100ULL /* b55, user error */ +#define SISL_ISTATUS_PERM_ERR_LISN_3_PASID 0x0080ULL /* b56, user error */ +#define SISL_ISTATUS_PERM_ERR_LISN_2_PASID 0x0040ULL /* b57, user error */ +#define SISL_ISTATUS_PERM_ERR_LISN_1_PASID 0x0020ULL /* b58, user error */ +#define SISL_ISTATUS_PERM_ERR_CMDROOM 0x0010ULL /* b59, user error */ +#define SISL_ISTATUS_PERM_ERR_RCB_READ 0x0008ULL /* b60, user error */ +#define SISL_ISTATUS_PERM_ERR_SA_WRITE 0x0004ULL /* b61, user error */ +#define SISL_ISTATUS_PERM_ERR_RRQ_WRITE0x0002ULL /* b62, user error */ /* Page in wait accessing RCB/IOASA/RRQ is reported in b63. * Same error in data/LXT/RHT access is reported via IOASA. */ -#define SISL_ISTATUS_TEMP_ERR_PAGEIN 0x0001ULL /* b63, can be generated -* only when AFU auto -* retry is disabled. -* If user can determine -* the command that -* caused the error, it -* can be retried. -*/ -#define SISL_ISTATUS_UNMASK (0x001FULL) /* 1 means unmasked */ -#define SISL_ISTATUS_MASK~(SISL_ISTATUS_UNMASK)/* 1 means masked */ +#define SISL_ISTATUS_TEMP_ERR_PAGEIN 0x0001ULL /* b63, can only be + * generated when AFU + * auto retry is + * disabled. If user + * can determine the + * command that caused + * the error, it can + * be retried. + */ +#define SISL_ISTATUS_UNMASK(0x07FFULL) /* 1 means unmasked */ +#define SISL_ISTATUS_MASK ~(SISL_ISTATUS_UNMASK) /* 1 means masked */ __be64 intr_clear; __be64 intr_mask; -- 2.1.0
[PATCH 33/38] cxlflash: Setup LISNs for master contexts
Similar to user contexts, master contexts also require that the per-context LISN registers be programmed for certain AFUs. The mapped trigger page is obtained from underlying transport and registered with AFU for each master context. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/main.c | 21 + 1 file changed, 21 insertions(+) diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 5d754d1..8c55fcd 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -1756,6 +1756,8 @@ static int init_global(struct cxlflash_cfg *cfg) u64 wwpn[MAX_FC_PORTS]; /* wwpn of AFU ports */ int i = 0, num_ports = 0; int rc = 0; + int j; + void *ctx; u64 reg; rc = read_vpd(cfg, [0]); @@ -1816,6 +1818,25 @@ static int init_global(struct cxlflash_cfg *cfg) msleep(100); } + if (afu_is_ocxl_lisn(afu)) { + /* Set up the LISN effective address for each master */ + for (i = 0; i < afu->num_hwqs; i++) { + hwq = get_hwq(afu, i); + ctx = hwq->ctx_cookie; + + for (j = 0; j < hwq->num_irqs; j++) { + reg = cfg->ops->get_irq_objhndl(ctx, j); + writeq_be(reg, >ctrl_map->lisn_ea[j]); + } + + reg = hwq->ctx_hndl; + writeq_be(SISL_LISN_PASID(reg, reg), + >ctrl_map->lisn_pasid[0]); + writeq_be(SISL_LISN_PASID(0UL, reg), + >ctrl_map->lisn_pasid[1]); + } + } + /* Set up master's own CTX_CAP to allow real mode, host translation */ /* tables, afu cmds and read/write GSCSI cmds. */ /* First, unlock ctx_cap write by reading mbox */ -- 2.1.0
[PATCH 32/38] cxlflash: Setup LISNs for user contexts
The SISLite specification has been updated for OpenCXL to support communicating data to generate AFU interrupts to the AFU. This includes a new capability bit that is advertised for OpenCXL AFUs and new registers to hold the object handle and translation PASID of each interrupt. For Power, the object handle is the mapped trigger page. Note that because these mappings are kernel only, the PASID of a kernel context must be used to satisfy the translation. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/common.h| 5 + drivers/scsi/cxlflash/sislite.h | 5 + drivers/scsi/cxlflash/superpipe.c | 14 ++ 3 files changed, 24 insertions(+) diff --git a/drivers/scsi/cxlflash/common.h b/drivers/scsi/cxlflash/common.h index d7fccea..b69fd32 100644 --- a/drivers/scsi/cxlflash/common.h +++ b/drivers/scsi/cxlflash/common.h @@ -273,6 +273,11 @@ static inline bool afu_has_cap(struct afu *afu, u64 cap) return afu_cap & cap; } +static inline bool afu_is_ocxl_lisn(struct afu *afu) +{ + return afu_has_cap(afu, SISL_INTVER_CAP_OCXL_LISN); +} + static inline bool afu_is_afu_debug(struct afu *afu) { return afu_has_cap(afu, SISL_INTVER_CAP_AFU_DEBUG); diff --git a/drivers/scsi/cxlflash/sislite.h b/drivers/scsi/cxlflash/sislite.h index d8940f1..c08b9d3 100644 --- a/drivers/scsi/cxlflash/sislite.h +++ b/drivers/scsi/cxlflash/sislite.h @@ -310,6 +310,10 @@ struct sisl_ctrl_map { #define SISL_CTX_CAP_WRITE_CMD 0x0002ULL /* afu_rc 0x21 */ #define SISL_CTX_CAP_READ_CMD 0x0001ULL /* afu_rc 0x21 */ __be64 mbox_r; + __be64 lisn_pasid[2]; + /* pasid _a arg must be ULL */ +#define SISL_LISN_PASID(_a, _b)(((_a) << 32) | (_b)) + __be64 lisn_ea[3]; }; /* single copy global regs */ @@ -416,6 +420,7 @@ struct sisl_global_regs { #define SISL_INTVER_CAP_RESERVED_CMD_MODE_B0x1000ULL #define SISL_INTVER_CAP_LUN_PROVISION 0x0800ULL #define SISL_INTVER_CAP_AFU_DEBUG 0x0400ULL +#define SISL_INTVER_CAP_OCXL_LISN 0x0200ULL }; #define CXLFLASH_NUM_FC_PORTS_PER_BANK 2 /* fixed # of ports per bank */ diff --git a/drivers/scsi/cxlflash/superpipe.c b/drivers/scsi/cxlflash/superpipe.c index 2fe79df..04a3bf9 100644 --- a/drivers/scsi/cxlflash/superpipe.c +++ b/drivers/scsi/cxlflash/superpipe.c @@ -269,6 +269,7 @@ static int afu_attach(struct cxlflash_cfg *cfg, struct ctx_info *ctxi) int rc = 0; struct hwq *hwq = get_hwq(afu, PRIMARY_HWQ); u64 val; + int i; /* Unlock cap and restrict user to read/write cmds in translated mode */ readq_be(_map->mbox_r); @@ -282,6 +283,19 @@ static int afu_attach(struct cxlflash_cfg *cfg, struct ctx_info *ctxi) goto out; } + if (afu_is_ocxl_lisn(afu)) { + /* Set up the LISN effective address for each interrupt */ + for (i = 0; i < ctxi->irqs; i++) { + val = cfg->ops->get_irq_objhndl(ctxi->ctx, i); + writeq_be(val, _map->lisn_ea[i]); + } + + /* Use primary HWQ PASID as identifier for all interrupts */ + val = hwq->ctx_hndl; + writeq_be(SISL_LISN_PASID(val, val), _map->lisn_pasid[0]); + writeq_be(SISL_LISN_PASID(0UL, val), _map->lisn_pasid[1]); + } + /* Set up MMIO registers pointing to the RHT */ writeq_be((u64)ctxi->rht_start, _map->rht_start); val = SISL_RHT_CNT_ID((u64)MAX_RHT_PER_CONTEXT, (u64)(hwq->ctx_hndl)); -- 2.1.0
[PATCH 31/38] cxlflash: Introduce object handle fop
OpenCXL requires that AFUs use an opaque object handle to represent an AFU interrupt. The specification does not provide a common means to communicate the object handle to the AFU - each AFU must define this within the AFU specification. To support this model, the object handle must be passed back to the core driver as it manages the AFU specification (SISLite) for cxlflash. Note that for Power systems, the object handle is the effective address of the trigger page. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/backend.h | 1 + drivers/scsi/cxlflash/cxl_hw.c | 7 +++ drivers/scsi/cxlflash/ocxl_hw.c | 18 ++ 3 files changed, 26 insertions(+) diff --git a/drivers/scsi/cxlflash/backend.h b/drivers/scsi/cxlflash/backend.h index f675bcb..bcd8a6c 100644 --- a/drivers/scsi/cxlflash/backend.h +++ b/drivers/scsi/cxlflash/backend.h @@ -23,6 +23,7 @@ struct cxlflash_backend_ops { int (*map_afu_irq)(void *ctx_cookie, int num, irq_handler_t handler, void *cookie, char *name); void (*unmap_afu_irq)(void *ctx_cookie, int num, void *cookie); + u64 (*get_irq_objhndl)(void *ctx_cookie, int irq); int (*start_context)(void *ctx_cookie); int (*stop_context)(void *ctx_cookie); int (*afu_reset)(void *ctx_cookie); diff --git a/drivers/scsi/cxlflash/cxl_hw.c b/drivers/scsi/cxlflash/cxl_hw.c index a1d6d12..b42da88 100644 --- a/drivers/scsi/cxlflash/cxl_hw.c +++ b/drivers/scsi/cxlflash/cxl_hw.c @@ -49,6 +49,12 @@ static void cxlflash_unmap_afu_irq(void *ctx_cookie, int num, void *cookie) cxl_unmap_afu_irq(ctx_cookie, num, cookie); } +static u64 cxlflash_get_irq_objhndl(void *ctx_cookie, int irq) +{ + /* Dummy fop for cxl */ + return 0; +} + static int cxlflash_start_context(void *ctx_cookie) { return cxl_start_context(ctx_cookie, 0, NULL); @@ -153,6 +159,7 @@ const struct cxlflash_backend_ops cxlflash_cxl_ops = { .process_element= cxlflash_process_element, .map_afu_irq= cxlflash_map_afu_irq, .unmap_afu_irq = cxlflash_unmap_afu_irq, + .get_irq_objhndl= cxlflash_get_irq_objhndl, .start_context = cxlflash_start_context, .stop_context = cxlflash_stop_context, .afu_reset = cxlflash_afu_reset, diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 119481c..1044bee 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -308,6 +308,23 @@ static void ocxlflash_unmap_afu_irq(void *ctx_cookie, int num, void *cookie) } /** + * ocxlflash_get_irq_objhndl() - get the object handle for an interrupt + * @ctx_cookie:Context associated with the interrupt. + * @irq: Interrupt number. + * + * Return: effective address of the mapped region + */ +static u64 ocxlflash_get_irq_objhndl(void *ctx_cookie, int irq) +{ + struct ocxlflash_context *ctx = ctx_cookie; + + if (irq < 0 || irq >= ctx->num_irqs) + return 0; + + return (__force u64)ctx->irqs[irq].vtrig; +} + +/** * start_context() - local routine to start a context * @ctx: Adapter context to be started. * @@ -1293,6 +1310,7 @@ const struct cxlflash_backend_ops cxlflash_ocxl_ops = { .process_element= ocxlflash_process_element, .map_afu_irq= ocxlflash_map_afu_irq, .unmap_afu_irq = ocxlflash_unmap_afu_irq, + .get_irq_objhndl= ocxlflash_get_irq_objhndl, .start_context = ocxlflash_start_context, .stop_context = ocxlflash_stop_context, .set_master = ocxlflash_set_master, -- 2.1.0
[PATCH 30/38] cxlflash: Support file descriptor mapping
The cxlflash core fop API requires a way to invoke the fault and release handlers of underlying transports using their native file-based APIs. This provides the core with the ability to insert selectively itself into the processing stream of these operations for cleanup. Implement these two fops to map and release when requested. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 26 ++ 1 file changed, 26 insertions(+) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index f090563..119481c 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -1259,6 +1259,30 @@ static int ocxlflash_start_work(void *ctx_cookie, u64 num_irqs) afu_unmap_irq(0, ctx, i, ctx); free_afu_irqs(ctx); goto out; +}; + +/** + * ocxlflash_fd_mmap() - mmap handler for adapter file descriptor + * @file: File installed with adapter file descriptor. + * @vma: VM area associated with mapping. + * + * Return: 0 on success, -errno on failure + */ +static int ocxlflash_fd_mmap(struct file *file, struct vm_area_struct *vma) +{ + return afu_mmap(file, vma); +} + +/** + * ocxlflash_fd_release() - release the context associated with the file + * @inode: File inode pointer. + * @file: File associated with the adapter context. + * + * Return: 0 on success, -errno on failure + */ +static int ocxlflash_fd_release(struct inode *inode, struct file *file) +{ + return afu_release(inode, file); } /* Backend ops to ocxlflash services */ @@ -1284,4 +1308,6 @@ const struct cxlflash_backend_ops cxlflash_ocxl_ops = { .get_fd = ocxlflash_get_fd, .fops_get_context = ocxlflash_fops_get_context, .start_work = ocxlflash_start_work, + .fd_mmap= ocxlflash_fd_mmap, + .fd_release = ocxlflash_fd_release, }; -- 2.1.0
[PATCH 29/38] cxlflash: Support adapter context mmap and release
The cxlflash userspace API requires that users be able to mmap and release the adapter context. Support mapping by implementing the AFU mmap fop to map the context MMIO space and install the corresponding page table entry upon page fault. Similarly, implement the AFU release fop to terminate and clean up the context when invoked. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 72 + 1 file changed, 72 insertions(+) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index e504dd2..f090563 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -1021,10 +1021,80 @@ static ssize_t afu_read(struct file *file, char __user *buf, size_t count, goto out; } +/** + * afu_release() - release and free the context + * @inode: File inode pointer. + * @file: File associated with the context. + * + * Return: 0 on success, -errno on failure + */ +static int afu_release(struct inode *inode, struct file *file) +{ + struct ocxlflash_context *ctx = file->private_data; + int i; + + /* Unmap and free the interrupts associated with the context */ + for (i = ctx->num_irqs; i >= 0; i--) + afu_unmap_irq(0, ctx, i, ctx); + free_afu_irqs(ctx); + + return ocxlflash_release_context(ctx); +} + +/** + * ocxlflash_mmap_fault() - mmap fault handler + * @vmf: VM fault associated with current fault. + * + * Return: 0 on success, -errno on failure + */ +static int ocxlflash_mmap_fault(struct vm_fault *vmf) +{ + struct vm_area_struct *vma = vmf->vma; + struct ocxlflash_context *ctx = vma->vm_file->private_data; + u64 mmio_area, offset; + + offset = vmf->pgoff << PAGE_SHIFT; + if (offset >= ctx->psn_size) + return VM_FAULT_SIGBUS; + + mmio_area = ctx->psn_phys; + mmio_area += offset; + + vm_insert_pfn(vma, vmf->address, mmio_area >> PAGE_SHIFT); + return VM_FAULT_NOPAGE; +} + +static const struct vm_operations_struct ocxlflash_vmops = { + .fault = ocxlflash_mmap_fault, +}; + +/** + * afu_mmap() - map the fault handler operations + * @file: File associated with the context. + * @vma: VM area associated with mapping. + * + * Return: 0 on success, -errno on failure + */ +static int afu_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct ocxlflash_context *ctx = file->private_data; + + if ((vma_pages(vma) + vma->vm_pgoff) > + (ctx->psn_size >> PAGE_SHIFT)) + return -EINVAL; + + vma->vm_flags |= VM_IO | VM_PFNMAP; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + vma->vm_ops = _vmops; + return 0; +} + static const struct file_operations ocxl_afu_fops = { .owner = THIS_MODULE, .poll = afu_poll, .read = afu_read, + .release= afu_release, + .mmap = afu_mmap, }; #define PATCH_FOPS(NAME) \ @@ -1071,6 +1141,8 @@ static struct file *ocxlflash_get_fd(void *ctx_cookie, if (fops) { PATCH_FOPS(poll); PATCH_FOPS(read); + PATCH_FOPS(release); + PATCH_FOPS(mmap); } else /* Use default ops */ fops = (struct file_operations *)_afu_fops; -- 2.1.0
[PATCH 28/38] cxlflash: Support adapter context reading
The cxlflash userspace API requires that users be able to read the adapter context for any pending events or interrupts from the AFU. Support reading various events by implementing the AFU read fop to copy out event data. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 94 + 1 file changed, 94 insertions(+) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 3297934..e504dd2 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -17,9 +17,12 @@ #include #include #include +#include #include +#include + #include "backend.h" #include "ocxl_hw.h" @@ -929,9 +932,99 @@ static unsigned int afu_poll(struct file *file, struct poll_table_struct *poll) return mask; } +/** + * afu_read() - perform a read on the context for any event + * @file: File associated with the adapter context. + * @buf: Buffer to receive the data. + * @count: Size of buffer (maximum bytes that can be read). + * @off: Offset. + * + * Return: size of the data read on success, -errno on failure + */ +static ssize_t afu_read(struct file *file, char __user *buf, size_t count, + loff_t *off) +{ + struct ocxlflash_context *ctx = file->private_data; + struct device *dev = ctx->hw_afu->dev; + struct cxl_event event; + ulong lock_flags; + ssize_t esize; + ssize_t rc; + int bit; + DEFINE_WAIT(event_wait); + + if (*off != 0) { + dev_err(dev, "%s: Non-zero offset not supported, off=%lld\n", + __func__, *off); + rc = -EINVAL; + goto out; + } + + spin_lock_irqsave(>slock, lock_flags); + + for (;;) { + prepare_to_wait(>wq, _wait, TASK_INTERRUPTIBLE); + + if (ctx_event_pending(ctx)) + break; + + if (file->f_flags & O_NONBLOCK) { + dev_err(dev, "%s: File cannot be blocked on I/O\n", + __func__); + rc = -EAGAIN; + goto err; + } + + if (signal_pending(current)) { + dev_err(dev, "%s: Signal pending on the process\n", + __func__); + rc = -ERESTARTSYS; + goto err; + } + + spin_unlock_irqrestore(>slock, lock_flags); + schedule(); + spin_lock_irqsave(>slock, lock_flags); + } + + finish_wait(>wq, _wait); + + memset(, 0, sizeof(event)); + event.header.process_element = ctx->pe; + event.header.size = sizeof(struct cxl_event_header); + if (ctx->pending_irq) { + esize = sizeof(struct cxl_event_afu_interrupt); + event.header.size += esize; + event.header.type = CXL_EVENT_AFU_INTERRUPT; + + bit = find_first_bit(>irq_bitmap, ctx->num_irqs); + clear_bit(bit, >irq_bitmap); + event.irq.irq = bit + 1; + if (bitmap_empty(>irq_bitmap, ctx->num_irqs)) + ctx->pending_irq = false; + } + + spin_unlock_irqrestore(>slock, lock_flags); + + if (copy_to_user(buf, , event.header.size)) { + dev_err(dev, "%s: copy_to_user failed\n", __func__); + rc = -EFAULT; + goto out; + } + + rc = event.header.size; +out: + return rc; +err: + finish_wait(>wq, _wait); + spin_unlock_irqrestore(>slock, lock_flags); + goto out; +} + static const struct file_operations ocxl_afu_fops = { .owner = THIS_MODULE, .poll = afu_poll, + .read = afu_read, }; #define PATCH_FOPS(NAME) \ @@ -977,6 +1070,7 @@ static struct file *ocxlflash_get_fd(void *ctx_cookie, /* Patch the file ops that are not defined */ if (fops) { PATCH_FOPS(poll); + PATCH_FOPS(read); } else /* Use default ops */ fops = (struct file_operations *)_afu_fops; -- 2.1.0
[PATCH 27/38] cxlflash: Support adapter context polling
The cxlflash userspace API requires that users be able to poll the adapter context for any pending events or interrupts from the AFU. Support polling on various events by implementing the AFU poll fop using a waitqueue. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 57 +++-- drivers/scsi/cxlflash/ocxl_hw.h | 2 ++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 4ca4a72..3297934 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -452,6 +453,7 @@ static void *ocxlflash_dev_context_init(struct pci_dev *pdev, void *afu_cookie) } spin_lock_init(>slock); + init_waitqueue_head(>wq); ctx->pe = rc; ctx->master = false; @@ -884,10 +886,57 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev) goto out; } +/** + * ctx_event_pending() - check for any event pending on the context + * @ctx: Context to be checked. + * + * Return: true if there is an event pending, false if none pending + */ +static inline bool ctx_event_pending(struct ocxlflash_context *ctx) +{ + if (ctx->pending_irq) + return true; + + return false; +} + +/** + * afu_poll() - poll the AFU for events on the context + * @file: File associated with the adapter context. + * @poll: Poll structure from the user. + * + * Return: poll mask + */ +static unsigned int afu_poll(struct file *file, struct poll_table_struct *poll) +{ + struct ocxlflash_context *ctx = file->private_data; + struct device *dev = ctx->hw_afu->dev; + ulong lock_flags; + int mask = 0; + + poll_wait(file, >wq, poll); + + spin_lock_irqsave(>slock, lock_flags); + if (ctx_event_pending(ctx)) + mask |= POLLIN | POLLRDNORM; + else + mask |= POLLERR; + spin_unlock_irqrestore(>slock, lock_flags); + + dev_dbg(dev, "%s: Poll wait completed for pe %i mask %i\n", + __func__, ctx->pe, mask); + + return mask; +} + static const struct file_operations ocxl_afu_fops = { .owner = THIS_MODULE, + .poll = afu_poll, }; +#define PATCH_FOPS(NAME) \ + do { if (!fops->NAME) fops->NAME = ocxl_afu_fops.NAME; } while (0) + /** * ocxlflash_get_fd() - get file descriptor for an adapter context * @ctx_cookie:Adapter context. @@ -925,8 +974,10 @@ static struct file *ocxlflash_get_fd(void *ctx_cookie, } fdtmp = rc; - /* Use default ops if there is no fops */ - if (!fops) + /* Patch the file ops that are not defined */ + if (fops) { + PATCH_FOPS(poll); + } else /* Use default ops */ fops = (struct file_operations *)_afu_fops; name = kasprintf(GFP_KERNEL, "ocxlflash:%d", ctx->pe); @@ -990,6 +1041,8 @@ static irqreturn_t ocxlflash_afu_irq(int irq, void *data) set_bit(i - 1, >irq_bitmap); ctx->pending_irq = true; spin_unlock(>slock); + + wake_up_all(>wq); out: return IRQ_HANDLED; } diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h index c7cbf67..bdf9422 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.h +++ b/drivers/scsi/cxlflash/ocxl_hw.h @@ -55,6 +55,8 @@ struct ocxlflash_context { u64 psn_size; /* Process mapping size */ spinlock_t slock; /* Protects irq/fault/event updates */ + wait_queue_head_t wq; /* Wait queue for poll and interrupts */ + struct ocxlflash_irqs *irqs;/* Pointer to array of structures */ int num_irqs; /* Number of interrupts */ bool pending_irq; /* Pending interrupt on the context */ -- 2.1.0
[PATCH 26/38] cxlflash: Support starting user contexts
User contexts request interrupts and are started using the "start work" interface. Populate the start_work() fop to allocate and map interrupts before starting the user context. As part of starting the context, update the user process identification logic to properly derive the data required by the SPA. Also, introduce a skeleton interrupt handler using a bitmap, flag, and spinlock to track interrupts. This handler will be expanded in future commits. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 99 - drivers/scsi/cxlflash/ocxl_hw.h | 3 ++ 2 files changed, 100 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 3b28c2a..4ca4a72 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -318,7 +318,9 @@ static int start_context(struct ocxlflash_context *ctx) void *link_token = afu->link_token; struct device *dev = afu->dev; bool master = ctx->master; + struct mm_struct *mm; int rc = 0; + u32 pid; if (master) { ctx->psn_size = acfg->global_mmio_size; @@ -328,9 +330,16 @@ static int start_context(struct ocxlflash_context *ctx) ctx->psn_phys = afu->ppmmio_phys + (ctx->pe * ctx->psn_size); } + /* pid and mm not set for master contexts */ + if (master) { + pid = 0; + mm = NULL; + } else { + pid = current->mm->context.id; + mm = current->mm; + } - /* pid, tid, amr and mm are zeroes/NULL for a kernel context */ - rc = ocxl_link_add_pe(link_token, ctx->pe, 0, 0, 0, NULL, NULL, NULL); + rc = ocxl_link_add_pe(link_token, ctx->pe, pid, 0, 0, mm, NULL, NULL); if (unlikely(rc)) { dev_err(dev, "%s: ocxl_link_add_pe failed rc=%d\n", __func__, rc); @@ -442,10 +451,14 @@ static void *ocxlflash_dev_context_init(struct pci_dev *pdev, void *afu_cookie) goto err2; } + spin_lock_init(>slock); + ctx->pe = rc; ctx->master = false; ctx->mapping = NULL; ctx->hw_afu = afu; + ctx->irq_bitmap = 0; + ctx->pending_irq = false; out: return ctx; err2: @@ -948,6 +961,87 @@ static void *ocxlflash_fops_get_context(struct file *file) return file->private_data; } +/** + * ocxlflash_afu_irq() - interrupt handler for user contexts + * @irq: Interrupt number. + * @data: Private data provided at interrupt registration, the context. + * + * Return: Always return IRQ_HANDLED. + */ +static irqreturn_t ocxlflash_afu_irq(int irq, void *data) +{ + struct ocxlflash_context *ctx = data; + struct device *dev = ctx->hw_afu->dev; + int i; + + dev_dbg(dev, "%s: Interrupt raised for pe %i virq %i\n", + __func__, ctx->pe, irq); + + for (i = 0; i < ctx->num_irqs; i++) { + if (ctx->irqs[i].virq == irq) + break; + } + if (unlikely(i >= ctx->num_irqs)) { + dev_err(dev, "%s: Received AFU IRQ out of range\n", __func__); + goto out; + } + + spin_lock(>slock); + set_bit(i - 1, >irq_bitmap); + ctx->pending_irq = true; + spin_unlock(>slock); +out: + return IRQ_HANDLED; +} + +/** + * ocxlflash_start_work() - start a user context + * @ctx_cookie:Context to be started. + * @num_irqs: Number of interrupts requested. + * + * Return: 0 on success, -errno on failure + */ +static int ocxlflash_start_work(void *ctx_cookie, u64 num_irqs) +{ + struct ocxlflash_context *ctx = ctx_cookie; + struct ocxl_hw_afu *afu = ctx->hw_afu; + struct device *dev = afu->dev; + char *name; + int rc = 0; + int i; + + rc = alloc_afu_irqs(ctx, num_irqs); + if (unlikely(rc < 0)) { + dev_err(dev, "%s: alloc_afu_irqs failed rc=%d\n", __func__, rc); + goto out; + } + + for (i = 0; i < num_irqs; i++) { + name = kasprintf(GFP_KERNEL, "ocxlflash-%s-pe%i-%i", +dev_name(dev), ctx->pe, i); + rc = afu_map_irq(0, ctx, i, ocxlflash_afu_irq, ctx, name); + kfree(name); + if (unlikely(rc < 0)) { + dev_err(dev, "%s: afu_map_irq failed rc=%d\n", + __func__, rc); + goto err; + } + } + + rc = start_context(ctx); + if (unlikely(rc)) { + dev_err(dev, "%s: start_context failed rc=%d\n", __func__, rc); + goto err; + } +out: + return rc; +err: + for (i = i-1; i >= 0; i--) + afu_unmap_irq(0, ctx, i, ctx); + free_afu_irqs(ctx); + goto out; +} + /* Backend ops to ocxlflash services */ const
[PATCH 25/38] cxlflash: Support AFU interrupt mapping and registration
Add support to map and unmap the irq space and manage irq registrations with the kernel for each allocated AFU interrupt. Also support mapping the physical trigger page to obtain an effective address that will be provided to the cxlflash core in a future commit. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 120 drivers/scsi/cxlflash/ocxl_hw.h | 2 + 2 files changed, 122 insertions(+) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index acba10f..3b28c2a 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -186,6 +186,124 @@ static int ocxlflash_process_element(void *ctx_cookie) } /** + * afu_map_irq() - map the interrupt of the adapter context + * @flags: Flags. + * @ctx: Adapter context. + * @num: Per-context AFU interrupt number. + * @handler: Interrupt handler to register. + * @cookie:Interrupt handler private data. + * @name: Name of the interrupt. + * + * Return: 0 on success, -errno on failure + */ +static int afu_map_irq(u64 flags, struct ocxlflash_context *ctx, int num, + irq_handler_t handler, void *cookie, char *name) +{ + struct ocxl_hw_afu *afu = ctx->hw_afu; + struct device *dev = afu->dev; + struct ocxlflash_irqs *irq; + void __iomem *vtrig; + u32 virq; + int rc = 0; + + if (num < 0 || num >= ctx->num_irqs) { + dev_err(dev, "%s: Interrupt %d not allocated\n", __func__, num); + rc = -ENOENT; + goto out; + } + + irq = >irqs[num]; + virq = irq_create_mapping(NULL, irq->hwirq); + if (unlikely(!virq)) { + dev_err(dev, "%s: irq_create_mapping failed\n", __func__); + rc = -ENOMEM; + goto out; + } + + rc = request_irq(virq, handler, 0, name, cookie); + if (unlikely(rc)) { + dev_err(dev, "%s: request_irq failed rc=%d\n", __func__, rc); + goto err1; + } + + vtrig = ioremap(irq->ptrig, PAGE_SIZE); + if (unlikely(!vtrig)) { + dev_err(dev, "%s: Trigger page mapping failed\n", __func__); + rc = -ENOMEM; + goto err2; + } + + irq->virq = virq; + irq->vtrig = vtrig; +out: + return rc; +err2: + free_irq(virq, cookie); +err1: + irq_dispose_mapping(virq); + goto out; +} + +/** + * ocxlflash_map_afu_irq() - map the interrupt of the adapter context + * @ctx_cookie:Adapter context. + * @num: Per-context AFU interrupt number. + * @handler: Interrupt handler to register. + * @cookie:Interrupt handler private data. + * @name: Name of the interrupt. + * + * Return: 0 on success, -errno on failure + */ +static int ocxlflash_map_afu_irq(void *ctx_cookie, int num, +irq_handler_t handler, void *cookie, +char *name) +{ + return afu_map_irq(0, ctx_cookie, num, handler, cookie, name); +} + +/** + * afu_unmap_irq() - unmap the interrupt + * @flags: Flags. + * @ctx: Adapter context. + * @num: Per-context AFU interrupt number. + * @cookie:Interrupt handler private data. + */ +static void afu_unmap_irq(u64 flags, struct ocxlflash_context *ctx, int num, + void *cookie) +{ + struct ocxl_hw_afu *afu = ctx->hw_afu; + struct device *dev = afu->dev; + struct ocxlflash_irqs *irq; + + if (num < 0 || num >= ctx->num_irqs) { + dev_err(dev, "%s: Interrupt %d not allocated\n", __func__, num); + return; + } + + irq = >irqs[num]; + if (irq->vtrig) + iounmap(irq->vtrig); + + if (irq_find_mapping(NULL, irq->hwirq)) { + free_irq(irq->virq, cookie); + irq_dispose_mapping(irq->virq); + } + + memset(irq, 0, sizeof(*irq)); +} + +/** + * ocxlflash_unmap_afu_irq() - unmap the interrupt + * @ctx_cookie:Adapter context. + * @num: Per-context AFU interrupt number. + * @cookie:Interrupt handler private data. + */ +static void ocxlflash_unmap_afu_irq(void *ctx_cookie, int num, void *cookie) +{ + return afu_unmap_irq(0, ctx_cookie, num, cookie); +} + +/** * start_context() - local routine to start a context * @ctx: Adapter context to be started. * @@ -836,6 +954,8 @@ const struct cxlflash_backend_ops cxlflash_ocxl_ops = { .psa_map= ocxlflash_psa_map, .psa_unmap = ocxlflash_psa_unmap, .process_element= ocxlflash_process_element, + .map_afu_irq= ocxlflash_map_afu_irq, + .unmap_afu_irq = ocxlflash_unmap_afu_irq, .start_context = ocxlflash_start_context, .stop_context = ocxlflash_stop_context, .set_master =
[PATCH 24/38] cxlflash: Support AFU interrupt management
Add support to allocate and free AFU interrupts using the OCXL provider services. The trigger page returned upon successful allocation will be mapped and exposed to the cxlflash core in a future commit. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 104 drivers/scsi/cxlflash/ocxl_hw.h | 10 2 files changed, 114 insertions(+) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 1dd679d..acba10f 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -385,6 +385,108 @@ static ssize_t ocxlflash_read_adapter_vpd(struct pci_dev *pdev, void *buf, } /** + * free_afu_irqs() - internal service to free interrupts + * @ctx: Adapter context. + */ +static void free_afu_irqs(struct ocxlflash_context *ctx) +{ + struct ocxl_hw_afu *afu = ctx->hw_afu; + struct device *dev = afu->dev; + int i; + + if (!ctx->irqs) { + dev_err(dev, "%s: Interrupts not allocated\n", __func__); + return; + } + + for (i = ctx->num_irqs; i >= 0; i--) + ocxl_link_free_irq(afu->link_token, ctx->irqs[i].hwirq); + + kfree(ctx->irqs); + ctx->irqs = NULL; +} + +/** + * alloc_afu_irqs() - internal service to allocate interrupts + * @ctx: Context associated with the request. + * @num: Number of interrupts requested. + * + * Return: 0 on success, -errno on failure + */ +static int alloc_afu_irqs(struct ocxlflash_context *ctx, int num) +{ + struct ocxl_hw_afu *afu = ctx->hw_afu; + struct device *dev = afu->dev; + struct ocxlflash_irqs *irqs; + u64 addr; + int rc = 0; + int hwirq; + int i; + + if (ctx->irqs) { + dev_err(dev, "%s: Interrupts already allocated\n", __func__); + rc = -EEXIST; + goto out; + } + + if (num > OCXL_MAX_IRQS) { + dev_err(dev, "%s: Too many interrupts num=%d\n", __func__, num); + rc = -EINVAL; + goto out; + } + + irqs = kcalloc(num, sizeof(*irqs), GFP_KERNEL); + if (unlikely(!irqs)) { + dev_err(dev, "%s: Context irqs allocation failed\n", __func__); + rc = -ENOMEM; + goto out; + } + + for (i = 0; i < num; i++) { + rc = ocxl_link_irq_alloc(afu->link_token, , ); + if (unlikely(rc)) { + dev_err(dev, "%s: ocxl_link_irq_alloc failed rc=%d\n", + __func__, rc); + goto err; + } + + irqs[i].hwirq = hwirq; + irqs[i].ptrig = addr; + } + + ctx->irqs = irqs; + ctx->num_irqs = num; +out: + return rc; +err: + for (i = i-1; i >= 0; i--) + ocxl_link_free_irq(afu->link_token, irqs[i].hwirq); + kfree(irqs); + goto out; +} + +/** + * ocxlflash_allocate_afu_irqs() - allocates the requested number of interrupts + * @ctx_cookie:Context associated with the request. + * @num: Number of interrupts requested. + * + * Return: 0 on success, -errno on failure + */ +static int ocxlflash_allocate_afu_irqs(void *ctx_cookie, int num) +{ + return alloc_afu_irqs(ctx_cookie, num); +} + +/** + * ocxlflash_free_afu_irqs() - frees the interrupts of an adapter context + * @ctx_cookie:Adapter context. + */ +static void ocxlflash_free_afu_irqs(void *ctx_cookie) +{ + free_afu_irqs(ctx_cookie); +} + +/** * ocxlflash_unconfig_afu() - unconfigure the AFU * @afu: AFU associated with the host. */ @@ -742,6 +844,8 @@ const struct cxlflash_backend_ops cxlflash_ocxl_ops = { .release_context= ocxlflash_release_context, .perst_reloads_same_image = ocxlflash_perst_reloads_same_image, .read_adapter_vpd = ocxlflash_read_adapter_vpd, + .allocate_afu_irqs = ocxlflash_allocate_afu_irqs, + .free_afu_irqs = ocxlflash_free_afu_irqs, .create_afu = ocxlflash_create_afu, .destroy_afu= ocxlflash_destroy_afu, .get_fd = ocxlflash_get_fd, diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h index 77c2550..c889368 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.h +++ b/drivers/scsi/cxlflash/ocxl_hw.h @@ -12,6 +12,13 @@ * 2 of the License, or (at your option) any later version. */ +#define OCXL_MAX_IRQS 4 /* Max interrupts per process */ + +struct ocxlflash_irqs { + int hwirq; + u64 ptrig; +}; + /* OpenCXL hardware AFU associated with the host */ struct ocxl_hw_afu { struct ocxlflash_context *ocxl_ctx; /* Host context */ @@ -44,4 +51,7 @@ struct ocxlflash_context { phys_addr_t psn_phys; /* Process mapping */ u64 psn_size; /* Process mapping size */ + +
[PATCH 23/38] cxlflash: Support process element lifecycle
As part of the context lifecycle, the associated process element within the Shared Process Area (SPA) of the link must be updated. Each process is defined by various parameters (pid, tid, PASID mm) that are stored in the SPA upon starting a context and invalidated when a context is stopped. Use the OCXL provider services to configure the SPA with the appropriate data that is unique to the process when starting a context. Initially only kernel contexts are supported and therefore these process values are not applicable. Note that the OCXL service used has an optional callback for translation fault error notification. While not used here, it will be expanded in a future commit. Also add a service to stop a context by terminating the corresponding PASID and remove the process element from the SPA. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 52 +++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 74447f8..1dd679d 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -189,7 +189,7 @@ static int ocxlflash_process_element(void *ctx_cookie) * start_context() - local routine to start a context * @ctx: Adapter context to be started. * - * Assign the context specific MMIO space. + * Assign the context specific MMIO space, add and enable the PE. * * Return: 0 on success, -errno on failure */ @@ -197,7 +197,10 @@ static int start_context(struct ocxlflash_context *ctx) { struct ocxl_hw_afu *afu = ctx->hw_afu; struct ocxl_afu_config *acfg = >acfg; + void *link_token = afu->link_token; + struct device *dev = afu->dev; bool master = ctx->master; + int rc = 0; if (master) { ctx->psn_size = acfg->global_mmio_size; @@ -207,7 +210,16 @@ static int start_context(struct ocxlflash_context *ctx) ctx->psn_phys = afu->ppmmio_phys + (ctx->pe * ctx->psn_size); } - return 0; + + /* pid, tid, amr and mm are zeroes/NULL for a kernel context */ + rc = ocxl_link_add_pe(link_token, ctx->pe, 0, 0, 0, NULL, NULL, NULL); + if (unlikely(rc)) { + dev_err(dev, "%s: ocxl_link_add_pe failed rc=%d\n", + __func__, rc); + goto out; + } +out: + return rc; } /** @@ -224,6 +236,41 @@ static int ocxlflash_start_context(void *ctx_cookie) } /** + * ocxlflash_stop_context() - stop a context + * @ctx_cookie:Adapter context to be stopped. + * + * Return: 0 on success, -errno on failure + */ +static int ocxlflash_stop_context(void *ctx_cookie) +{ + struct ocxlflash_context *ctx = ctx_cookie; + struct ocxl_hw_afu *afu = ctx->hw_afu; + struct ocxl_afu_config *acfg = >acfg; + struct pci_dev *pdev = afu->pdev; + struct device *dev = afu->dev; + int rc; + + rc = ocxl_config_terminate_pasid(pdev, acfg->dvsec_afu_control_pos, +ctx->pe); + if (unlikely(rc)) { + dev_err(dev, "%s: ocxl_config_terminate_pasid failed rc=%d\n", + __func__, rc); + /* If EBUSY, PE could be referenced in future by the AFU */ + if (rc == -EBUSY) + goto out; + } + + rc = ocxl_link_remove_pe(afu->link_token, ctx->pe); + if (unlikely(rc)) { + dev_err(dev, "%s: ocxl_link_remove_pe failed rc=%d\n", + __func__, rc); + goto out; + } +out: + return rc; +} + +/** * ocxlflash_set_master() - sets the context as master * @ctx_cookie:Adapter context to set as master. */ @@ -688,6 +735,7 @@ const struct cxlflash_backend_ops cxlflash_ocxl_ops = { .psa_unmap = ocxlflash_psa_unmap, .process_element= ocxlflash_process_element, .start_context = ocxlflash_start_context, + .stop_context = ocxlflash_stop_context, .set_master = ocxlflash_set_master, .get_context= ocxlflash_get_context, .dev_context_init = ocxlflash_dev_context_init, -- 2.1.0
[PATCH 22/38] cxlflash: Setup OpenCXL transaction layer
The first function of the link needs to configure the transaction layer between the host and device. This is accomplished by a call to the OCXL provider services. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 3a1ad61..74447f8 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -419,8 +419,18 @@ static int ocxlflash_config_fn(struct pci_dev *pdev, struct ocxl_hw_afu *afu) __func__, rc); goto out; } + + rc = ocxl_config_set_TL(pdev, fcfg->dvsec_tl_pos); + if (unlikely(rc)) { + dev_err(dev, "%s: ocxl_config_set_TL failed rc=%d\n", + __func__, rc); + goto err; + } out: return rc; +err: + ocxl_link_release(pdev, afu->link_token); + goto out; } /** -- 2.1.0
[PATCH 21/38] cxlflash: Setup function OpenCXL link
After reading and modifying the function configuration, setup the OpenCXL link using the OCXL provider services. The link is released when the adapter is unconfigured. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 25 ++--- drivers/scsi/cxlflash/ocxl_hw.h | 1 + 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 8dcb7aa..3a1ad61 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -412,11 +412,28 @@ static int ocxlflash_config_fn(struct pci_dev *pdev, struct ocxl_hw_afu *afu) ocxl_config_set_actag(pdev, fcfg->dvsec_function_pos, base, enabled); dev_dbg(dev, "%s: Function acTag range base=%u enabled=%u\n", __func__, base, enabled); + + rc = ocxl_link_setup(pdev, 0, >link_token); + if (unlikely(rc)) { + dev_err(dev, "%s: ocxl_link_setup failed rc=%d\n", + __func__, rc); + goto out; + } out: return rc; } /** + * ocxlflash_unconfig_fn() - unconfigure the host function + * @pdev: PCI device associated with the host. + * @afu: AFU associated with the host. + */ +static void ocxlflash_unconfig_fn(struct pci_dev *pdev, struct ocxl_hw_afu *afu) +{ + ocxl_link_release(pdev, afu->link_token); +} + +/** * ocxlflash_map_mmio() - map the AFU MMIO space * @afu: AFU associated with the host. * @@ -552,7 +569,7 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev) if (unlikely(rc)) { dev_err(dev, "%s: AFU configuration failed rc=%d\n", __func__, rc); - goto err1; + goto err2; } ctx = ocxlflash_dev_context_init(pdev, afu); @@ -560,15 +577,17 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev) rc = PTR_ERR(ctx); dev_err(dev, "%s: ocxlflash_dev_context_init failed rc=%d\n", __func__, rc); - goto err2; + goto err3; } idr_init(>idr); afu->ocxl_ctx = ctx; out: return afu; -err2: +err3: ocxlflash_unconfig_afu(afu); +err2: + ocxlflash_unconfig_fn(pdev, afu); err1: kfree(afu); afu = NULL; diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h index 6912dd1..77c2550 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.h +++ b/drivers/scsi/cxlflash/ocxl_hw.h @@ -31,6 +31,7 @@ struct ocxl_hw_afu { phys_addr_t gmmio_phys; /* Global AFU MMIO space */ void __iomem *gmmio_virt; /* Global MMIO map */ + void *link_token; /* Link token for the SPA */ struct idr idr; /* IDR to manage contexts */ int max_pasid; /* Maximum number of contexts */ }; -- 2.1.0
[PATCH 20/38] cxlflash: Support reading adapter VPD data
Use the PCI VPD services to support reading the VPD data of the underlying adapter. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 7279f67..8dcb7aa 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -324,6 +324,20 @@ static void ocxlflash_perst_reloads_same_image(void *afu_cookie, bool image) } /** + * ocxlflash_read_adapter_vpd() - reads the adapter VPD + * @pdev: PCI device associated with the host. + * @buf: Buffer to get the VPD data. + * @count: Size of buffer (maximum bytes that can be read). + * + * Return: size of VPD on success, -errno on failure + */ +static ssize_t ocxlflash_read_adapter_vpd(struct pci_dev *pdev, void *buf, + size_t count) +{ + return pci_read_vpd(pdev, 0, count, buf); +} + +/** * ocxlflash_unconfig_afu() - unconfigure the AFU * @afu: AFU associated with the host. */ @@ -650,6 +664,7 @@ const struct cxlflash_backend_ops cxlflash_ocxl_ops = { .dev_context_init = ocxlflash_dev_context_init, .release_context= ocxlflash_release_context, .perst_reloads_same_image = ocxlflash_perst_reloads_same_image, + .read_adapter_vpd = ocxlflash_read_adapter_vpd, .create_afu = ocxlflash_create_afu, .destroy_afu= ocxlflash_destroy_afu, .get_fd = ocxlflash_get_fd, -- 2.1.0
[PATCH 19/38] cxlflash: Support AFU state toggling
The AFU should be enabled following a successful configuration and disabled near the end of the cleanup path. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 548438f..7279f67 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -342,12 +342,18 @@ static void ocxlflash_unconfig_afu(struct ocxl_hw_afu *afu) static void ocxlflash_destroy_afu(void *afu_cookie) { struct ocxl_hw_afu *afu = afu_cookie; + int pos; if (!afu) return; ocxlflash_release_context(afu->ocxl_ctx); idr_destroy(>idr); + + /* Disable the AFU */ + pos = afu->acfg.dvsec_afu_control_pos; + ocxl_config_set_afu_state(afu->pdev, pos, 0); + ocxlflash_unconfig_afu(afu); kfree(afu); } @@ -492,6 +498,9 @@ static int ocxlflash_config_afu(struct pci_dev *pdev, struct ocxl_hw_afu *afu) __func__, rc); goto out; } + + /* Enable the AFU */ + ocxl_config_set_afu_state(pdev, acfg->dvsec_afu_control_pos, 1); out: return rc; } -- 2.1.0
[PATCH 18/38] cxlflash: Support process specific mappings
Once the context is started, the assigned MMIO space can be mapped and unmapped. Provide means to map and unmap the context MMIO space. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 24 1 file changed, 24 insertions(+) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 7d92df0..548438f 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -151,6 +151,28 @@ static struct file *ocxlflash_getfile(struct device *dev, const char *name, } /** + * ocxlflash_psa_map() - map the process specific MMIO space + * @ctx_cookie:Adapter context for which the mapping needs to be done. + * + * Return: MMIO pointer of the mapped region + */ +static void __iomem *ocxlflash_psa_map(void *ctx_cookie) +{ + struct ocxlflash_context *ctx = ctx_cookie; + + return ioremap(ctx->psn_phys, ctx->psn_size); +} + +/** + * ocxlflash_psa_unmap() - unmap the process specific MMIO space + * @addr: MMIO pointer to unmap. + */ +static void ocxlflash_psa_unmap(void __iomem *addr) +{ + iounmap(addr); +} + +/** * ocxlflash_process_element() - get process element of the adapter context * @ctx_cookie:Adapter context associated with the process element. * @@ -610,6 +632,8 @@ static void *ocxlflash_fops_get_context(struct file *file) /* Backend ops to ocxlflash services */ const struct cxlflash_backend_ops cxlflash_ocxl_ops = { .module = THIS_MODULE, + .psa_map= ocxlflash_psa_map, + .psa_unmap = ocxlflash_psa_unmap, .process_element= ocxlflash_process_element, .start_context = ocxlflash_start_context, .set_master = ocxlflash_set_master, -- 2.1.0
[PATCH 17/38] cxlflash: Support starting an adapter context
Once the adapter context is created, it needs to be started by assigning the MMIO space for the context and by enabling the process element in the link. This commit adds the skeleton for starting the context and assigns the context specific MMIO space. Master contexts have access to the global MMIO space while the rest have access to the context specific space. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 39 +++ drivers/scsi/cxlflash/ocxl_hw.h | 3 +++ 2 files changed, 42 insertions(+) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 824d789..7d92df0 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -164,6 +164,44 @@ static int ocxlflash_process_element(void *ctx_cookie) } /** + * start_context() - local routine to start a context + * @ctx: Adapter context to be started. + * + * Assign the context specific MMIO space. + * + * Return: 0 on success, -errno on failure + */ +static int start_context(struct ocxlflash_context *ctx) +{ + struct ocxl_hw_afu *afu = ctx->hw_afu; + struct ocxl_afu_config *acfg = >acfg; + bool master = ctx->master; + + if (master) { + ctx->psn_size = acfg->global_mmio_size; + ctx->psn_phys = afu->gmmio_phys; + } else { + ctx->psn_size = acfg->pp_mmio_stride; + ctx->psn_phys = afu->ppmmio_phys + (ctx->pe * ctx->psn_size); + } + + return 0; +} + +/** + * ocxlflash_start_context() - start a kernel context + * @ctx_cookie:Adapter context to be started. + * + * Return: 0 on success, -errno on failure + */ +static int ocxlflash_start_context(void *ctx_cookie) +{ + struct ocxlflash_context *ctx = ctx_cookie; + + return start_context(ctx); +} + +/** * ocxlflash_set_master() - sets the context as master * @ctx_cookie:Adapter context to set as master. */ @@ -573,6 +611,7 @@ static void *ocxlflash_fops_get_context(struct file *file) const struct cxlflash_backend_ops cxlflash_ocxl_ops = { .module = THIS_MODULE, .process_element= ocxlflash_process_element, + .start_context = ocxlflash_start_context, .set_master = ocxlflash_set_master, .get_context= ocxlflash_get_context, .dev_context_init = ocxlflash_dev_context_init, diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h index fbe9741..6912dd1 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.h +++ b/drivers/scsi/cxlflash/ocxl_hw.h @@ -40,4 +40,7 @@ struct ocxlflash_context { struct address_space *mapping; /* Mapping for pseudo filesystem */ bool master;/* Whether this is a master context */ int pe; /* Process element */ + + phys_addr_t psn_phys; /* Process mapping */ + u64 psn_size; /* Process mapping size */ }; -- 2.1.0
[PATCH 16/38] cxlflash: MMIO map the AFU
When the AFU is configured, the global and per process MMIO regions are presented by the configuration space. Save these regions and map the global MMIO region that is used to access all of the control and provisioning data in the AFU. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 74 - drivers/scsi/cxlflash/ocxl_hw.h | 4 +++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 6f78e71..824d789 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -264,6 +264,18 @@ static void ocxlflash_perst_reloads_same_image(void *afu_cookie, bool image) } /** + * ocxlflash_unconfig_afu() - unconfigure the AFU + * @afu: AFU associated with the host. + */ +static void ocxlflash_unconfig_afu(struct ocxl_hw_afu *afu) +{ + if (afu->gmmio_virt) { + iounmap(afu->gmmio_virt); + afu->gmmio_virt = NULL; + } +} + +/** * ocxlflash_destroy_afu() - destroy the AFU structure * @afu_cookie:AFU to be freed. */ @@ -276,6 +288,7 @@ static void ocxlflash_destroy_afu(void *afu_cookie) ocxlflash_release_context(afu->ocxl_ctx); idr_destroy(>idr); + ocxlflash_unconfig_afu(afu); kfree(afu); } @@ -324,6 +337,56 @@ static int ocxlflash_config_fn(struct pci_dev *pdev, struct ocxl_hw_afu *afu) } /** + * ocxlflash_map_mmio() - map the AFU MMIO space + * @afu: AFU associated with the host. + * + * Return: 0 on success, -errno on failure + */ +static int ocxlflash_map_mmio(struct ocxl_hw_afu *afu) +{ + struct ocxl_afu_config *acfg = >acfg; + struct pci_dev *pdev = afu->pdev; + struct device *dev = afu->dev; + phys_addr_t gmmio, ppmmio; + int rc = 0; + + rc = pci_request_region(pdev, acfg->global_mmio_bar, "ocxlflash"); + if (unlikely(rc)) { + dev_err(dev, "%s: pci_request_region for global failed rc=%d\n", + __func__, rc); + goto out; + } + gmmio = pci_resource_start(pdev, acfg->global_mmio_bar); + gmmio += acfg->global_mmio_offset; + + rc = pci_request_region(pdev, acfg->pp_mmio_bar, "ocxlflash"); + if (unlikely(rc)) { + dev_err(dev, "%s: pci_request_region for pp bar failed rc=%d\n", + __func__, rc); + goto err1; + } + ppmmio = pci_resource_start(pdev, acfg->pp_mmio_bar); + ppmmio += acfg->pp_mmio_offset; + + afu->gmmio_virt = ioremap(gmmio, acfg->global_mmio_size); + if (unlikely(!afu->gmmio_virt)) { + dev_err(dev, "%s: MMIO mapping failed\n", __func__); + rc = -ENOMEM; + goto err2; + } + + afu->gmmio_phys = gmmio; + afu->ppmmio_phys = ppmmio; +out: + return rc; +err2: + pci_release_region(pdev, acfg->pp_mmio_bar); +err1: + pci_release_region(pdev, acfg->global_mmio_bar); + goto out; +} + +/** * ocxlflash_config_afu() - configure the host AFU * @pdev: PCI device associated with the host. * @afu: AFU associated with the host. @@ -362,6 +425,13 @@ static int ocxlflash_config_afu(struct pci_dev *pdev, struct ocxl_hw_afu *afu) afu->max_pasid = 1 << acfg->pasid_supported_log; ocxl_config_set_afu_pasid(pdev, pos, 0, acfg->pasid_supported_log); + + rc = ocxlflash_map_mmio(afu); + if (unlikely(rc)) { + dev_err(dev, "%s: ocxlflash_map_mmio failed rc=%d\n", + __func__, rc); + goto out; + } out: return rc; } @@ -407,13 +477,15 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev) rc = PTR_ERR(ctx); dev_err(dev, "%s: ocxlflash_dev_context_init failed rc=%d\n", __func__, rc); - goto err1; + goto err2; } idr_init(>idr); afu->ocxl_ctx = ctx; out: return afu; +err2: + ocxlflash_unconfig_afu(afu); err1: kfree(afu); afu = NULL; diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h index 6d6e323..fbe9741 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.h +++ b/drivers/scsi/cxlflash/ocxl_hw.h @@ -27,6 +27,10 @@ struct ocxl_hw_afu { int afu_actag_base; /* AFU acTag base */ int afu_actag_enabled; /* AFU acTag number enabled */ + phys_addr_t ppmmio_phys;/* Per process MMIO space */ + phys_addr_t gmmio_phys; /* Global AFU MMIO space */ + void __iomem *gmmio_virt; /* Global MMIO map */ + struct idr idr; /* IDR to manage contexts */ int max_pasid; /* Maximum number of contexts */ }; -- 2.1.0
[PATCH 14/38] cxlflash: Support adapter context discovery
Provide means to obtain the process element of an adapter context as well as locate an adapter context by file. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 26 ++ 1 file changed, 26 insertions(+) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index ee3702d..2dab547 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -151,6 +151,19 @@ static struct file *ocxlflash_getfile(struct device *dev, const char *name, } /** + * ocxlflash_process_element() - get process element of the adapter context + * @ctx_cookie:Adapter context associated with the process element. + * + * Return: process element of the adapter context + */ +static int ocxlflash_process_element(void *ctx_cookie) +{ + struct ocxlflash_context *ctx = ctx_cookie; + + return ctx->pe; +} + +/** * ocxlflash_set_master() - sets the context as master * @ctx_cookie:Adapter context to set as master. */ @@ -461,9 +474,21 @@ static struct file *ocxlflash_get_fd(void *ctx_cookie, goto out; } +/** + * ocxlflash_fops_get_context() - get the context associated with the file + * @file: File associated with the adapter context. + * + * Return: pointer to the context + */ +static void *ocxlflash_fops_get_context(struct file *file) +{ + return file->private_data; +} + /* Backend ops to ocxlflash services */ const struct cxlflash_backend_ops cxlflash_ocxl_ops = { .module = THIS_MODULE, + .process_element= ocxlflash_process_element, .set_master = ocxlflash_set_master, .get_context= ocxlflash_get_context, .dev_context_init = ocxlflash_dev_context_init, @@ -471,4 +496,5 @@ const struct cxlflash_backend_ops cxlflash_ocxl_ops = { .create_afu = ocxlflash_create_afu, .destroy_afu= ocxlflash_destroy_afu, .get_fd = ocxlflash_get_fd, + .fops_get_context = ocxlflash_fops_get_context, }; -- 2.1.0
[PATCH 13/38] cxlflash: Support adapter file descriptors for OpenCXL
Allocate a file descriptor for an adapter context when requested. In order to allocate inodes for the file descriptors, a pseudo filesystem is created and used. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 200 drivers/scsi/cxlflash/ocxl_hw.h | 1 + 2 files changed, 201 insertions(+) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 30db79d..ee3702d 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -12,13 +12,144 @@ * 2 of the License, or (at your option) any later version. */ +#include #include +#include +#include #include #include "backend.h" #include "ocxl_hw.h" +/* + * Pseudo-filesystem to allocate inodes. + */ + +#define OCXLFLASH_FS_MAGIC 0x1697698f + +static int ocxlflash_fs_cnt; +static struct vfsmount *ocxlflash_vfs_mount; + +static const struct dentry_operations ocxlflash_fs_dops = { + .d_dname= simple_dname, +}; + +/* + * ocxlflash_fs_mount() - mount the pseudo-filesystem + * @fs_type: File system type. + * @flags: Flags for the filesystem. + * @dev_name: Device name associated with the filesystem. + * @data: Data pointer. + * + * Return: pointer to the directory entry structure + */ +static struct dentry *ocxlflash_fs_mount(struct file_system_type *fs_type, +int flags, const char *dev_name, +void *data) +{ + return mount_pseudo(fs_type, "ocxlflash:", NULL, _fs_dops, + OCXLFLASH_FS_MAGIC); +} + +static struct file_system_type ocxlflash_fs_type = { + .name = "ocxlflash", + .owner = THIS_MODULE, + .mount = ocxlflash_fs_mount, + .kill_sb= kill_anon_super, +}; + +/* + * ocxlflash_release_mapping() - release the memory mapping + * @ctx: Context whose mapping is to be released. + */ +static void ocxlflash_release_mapping(struct ocxlflash_context *ctx) +{ + if (ctx->mapping) + simple_release_fs(_vfs_mount, _fs_cnt); + ctx->mapping = NULL; +} + +/* + * ocxlflash_getfile() - allocate pseudo filesystem, inode, and the file + * @dev: Generic device of the host. + * @name: Name of the pseudo filesystem. + * @fops: File operations. + * @priv: Private data. + * @flags: Flags for the file. + * + * Return: pointer to the file on success, ERR_PTR on failure + */ +static struct file *ocxlflash_getfile(struct device *dev, const char *name, + const struct file_operations *fops, + void *priv, int flags) +{ + struct qstr this; + struct path path; + struct file *file; + struct inode *inode = NULL; + int rc; + + if (fops->owner && !try_module_get(fops->owner)) { + dev_err(dev, "%s: Owner does not exist\n", __func__); + rc = -ENOENT; + goto err1; + } + + rc = simple_pin_fs(_fs_type, _vfs_mount, + _fs_cnt); + if (unlikely(rc < 0)) { + dev_err(dev, "%s: Cannot mount ocxlflash pseudofs rc=%d\n", + __func__, rc); + goto err2; + } + + inode = alloc_anon_inode(ocxlflash_vfs_mount->mnt_sb); + if (IS_ERR(inode)) { + rc = PTR_ERR(inode); + dev_err(dev, "%s: alloc_anon_inode failed rc=%d\n", + __func__, rc); + goto err3; + } + + this.name = name; + this.len = strlen(name); + this.hash = 0; + path.dentry = d_alloc_pseudo(ocxlflash_vfs_mount->mnt_sb, ); + if (!path.dentry) { + dev_err(dev, "%s: d_alloc_pseudo failed\n", __func__); + rc = -ENOMEM; + goto err4; + } + + path.mnt = mntget(ocxlflash_vfs_mount); + d_instantiate(path.dentry, inode); + + file = alloc_file(, OPEN_FMODE(flags), fops); + if (IS_ERR(file)) { + rc = PTR_ERR(file); + dev_err(dev, "%s: alloc_file failed rc=%d\n", + __func__, rc); + goto err5; + } + + file->f_flags = flags & (O_ACCMODE | O_NONBLOCK); + file->private_data = priv; +out: + return file; +err5: + path_put(); +err4: + iput(inode); +err3: + simple_release_fs(_vfs_mount, _fs_cnt); +err2: + module_put(fops->owner); +err1: + file = ERR_PTR(rc); + goto out; +} + /** * ocxlflash_set_master() - sets the context as master * @ctx_cookie:Adapter context to set as master. @@ -75,6 +206,7 @@ static void *ocxlflash_dev_context_init(struct pci_dev *pdev, void *afu_cookie) ctx->pe = rc; ctx->master = false; + ctx->mapping = NULL; ctx->hw_afu = afu; out: return ctx; @@ -100,6
[PATCH 12/38] cxlflash: Use IDR to manage adapter contexts
A range of PASIDs are used as identifiers for the adapter contexts. These contexts may be destroyed and created randomly. Use an IDR to keep track of contexts that are in use and assign a unique identifier to new ones. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 20 ++-- drivers/scsi/cxlflash/ocxl_hw.h | 2 ++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index c5f5c81..30db79d 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -12,6 +12,8 @@ * 2 of the License, or (at your option) any later version. */ +#include + #include #include "backend.h" @@ -60,14 +62,25 @@ static void *ocxlflash_dev_context_init(struct pci_dev *pdev, void *afu_cookie) if (unlikely(!ctx)) { dev_err(dev, "%s: Context allocation failed\n", __func__); rc = -ENOMEM; - goto err; + goto err1; + } + + idr_preload(GFP_KERNEL); + rc = idr_alloc(>idr, ctx, 0, afu->max_pasid, GFP_NOWAIT); + idr_preload_end(); + if (unlikely(rc < 0)) { + dev_err(dev, "%s: idr_alloc failed rc=%d\n", __func__, rc); + goto err2; } + ctx->pe = rc; ctx->master = false; ctx->hw_afu = afu; out: return ctx; -err: +err2: + kfree(ctx); +err1: ctx = ERR_PTR(rc); goto out; } @@ -86,6 +99,7 @@ static int ocxlflash_release_context(void *ctx_cookie) if (!ctx) goto out; + idr_remove(>hw_afu->idr, ctx->pe); kfree(ctx); out: return rc; @@ -103,6 +117,7 @@ static void ocxlflash_destroy_afu(void *afu_cookie) return; ocxlflash_release_context(afu->ocxl_ctx); + idr_destroy(>idr); kfree(afu); } @@ -237,6 +252,7 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev) goto err1; } + idr_init(>idr); afu->ocxl_ctx = ctx; out: return afu; diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h index f78e5c9..49d5d08 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.h +++ b/drivers/scsi/cxlflash/ocxl_hw.h @@ -26,10 +26,12 @@ struct ocxl_hw_afu { int afu_actag_base; /* AFU acTag base */ int afu_actag_enabled; /* AFU acTag number enabled */ + struct idr idr; /* IDR to manage contexts */ int max_pasid; /* Maximum number of contexts */ }; struct ocxlflash_context { struct ocxl_hw_afu *hw_afu; /* HW AFU back pointer */ bool master;/* Whether this is a master context */ + int pe; /* Process element */ }; -- 2.1.0
[PATCH 11/38] cxlflash: Adapter context support for OpenCXL
Add support to create and release the adapter contexts for OpenCXL and provide means to specify certain contexts as a master. The existing cxlflash core has a design requirement that each host will have a single host context available by default. To satisfy this requirement, one host adapter context is created when the hardware AFU is initialized. This is returned by the get_context() fop. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 90 + drivers/scsi/cxlflash/ocxl_hw.h | 6 +++ 2 files changed, 96 insertions(+) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 677bc34..c5f5c81 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -18,6 +18,80 @@ #include "ocxl_hw.h" /** + * ocxlflash_set_master() - sets the context as master + * @ctx_cookie:Adapter context to set as master. + */ +static void ocxlflash_set_master(void *ctx_cookie) +{ + struct ocxlflash_context *ctx = ctx_cookie; + + ctx->master = true; +} + +/** + * ocxlflash_get_context() - obtains the context associated with the host + * @pdev: PCI device associated with the host. + * @afu_cookie:Hardware AFU associated with the host. + * + * Return: returns the pointer to host adapter context + */ +static void *ocxlflash_get_context(struct pci_dev *pdev, void *afu_cookie) +{ + struct ocxl_hw_afu *afu = afu_cookie; + + return afu->ocxl_ctx; +} + +/** + * ocxlflash_dev_context_init() - allocate and initialize an adapter context + * @pdev: PCI device associated with the host. + * @afu_cookie:Hardware AFU associated with the host. + * + * Return: returns the adapter context on success, ERR_PTR on failure + */ +static void *ocxlflash_dev_context_init(struct pci_dev *pdev, void *afu_cookie) +{ + struct ocxl_hw_afu *afu = afu_cookie; + struct device *dev = afu->dev; + struct ocxlflash_context *ctx; + int rc; + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (unlikely(!ctx)) { + dev_err(dev, "%s: Context allocation failed\n", __func__); + rc = -ENOMEM; + goto err; + } + + ctx->master = false; + ctx->hw_afu = afu; +out: + return ctx; +err: + ctx = ERR_PTR(rc); + goto out; +} + +/** + * ocxlflash_release_context() - releases an adapter context + * @ctx_cookie:Adapter context to be released. + * + * Return: 0 on success, -errno on failure + */ +static int ocxlflash_release_context(void *ctx_cookie) +{ + struct ocxlflash_context *ctx = ctx_cookie; + int rc = 0; + + if (!ctx) + goto out; + + kfree(ctx); +out: + return rc; +} + +/** * ocxlflash_destroy_afu() - destroy the AFU structure * @afu_cookie:AFU to be freed. */ @@ -28,6 +102,7 @@ static void ocxlflash_destroy_afu(void *afu_cookie) if (!afu) return; + ocxlflash_release_context(afu->ocxl_ctx); kfree(afu); } @@ -127,6 +202,7 @@ static int ocxlflash_config_afu(struct pci_dev *pdev, struct ocxl_hw_afu *afu) static void *ocxlflash_create_afu(struct pci_dev *pdev) { struct device *dev = >dev; + struct ocxlflash_context *ctx; struct ocxl_hw_afu *afu; int rc; @@ -152,6 +228,16 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev) __func__, rc); goto err1; } + + ctx = ocxlflash_dev_context_init(pdev, afu); + if (IS_ERR(ctx)) { + rc = PTR_ERR(ctx); + dev_err(dev, "%s: ocxlflash_dev_context_init failed rc=%d\n", + __func__, rc); + goto err1; + } + + afu->ocxl_ctx = ctx; out: return afu; err1: @@ -163,6 +249,10 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev) /* Backend ops to ocxlflash services */ const struct cxlflash_backend_ops cxlflash_ocxl_ops = { .module = THIS_MODULE, + .set_master = ocxlflash_set_master, + .get_context= ocxlflash_get_context, + .dev_context_init = ocxlflash_dev_context_init, + .release_context= ocxlflash_release_context, .create_afu = ocxlflash_create_afu, .destroy_afu= ocxlflash_destroy_afu, }; diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h index a807656..f78e5c9 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.h +++ b/drivers/scsi/cxlflash/ocxl_hw.h @@ -14,6 +14,7 @@ /* OpenCXL hardware AFU associated with the host */ struct ocxl_hw_afu { + struct ocxlflash_context *ocxl_ctx; /* Host context */ struct pci_dev *pdev; /* PCI device */ struct device *dev; /* Generic device */ @@ -27,3 +28,8 @@ struct ocxl_hw_afu { int max_pasid; /*
[PATCH 10/38] cxlflash: Setup AFU PASID
Per the OpenCXL specification, the maximum PASID supported by the AFU is indicated by a field within the configuration space. Similar to acTags, implementations can choose to use any sub-range of PASID within their assigned range. For cxlflash, the entire range is used. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 3 +++ drivers/scsi/cxlflash/ocxl_hw.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 3875ed4..677bc34 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -111,6 +111,9 @@ static int ocxlflash_config_afu(struct pci_dev *pdev, struct ocxl_hw_afu *afu) dev_dbg(dev, "%s: acTag base=%d enabled=%d\n", __func__, base, count); afu->afu_actag_base = base; afu->afu_actag_enabled = count; + afu->max_pasid = 1 << acfg->pasid_supported_log; + + ocxl_config_set_afu_pasid(pdev, pos, 0, acfg->pasid_supported_log); out: return rc; } diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h index a0ef04c..a807656 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.h +++ b/drivers/scsi/cxlflash/ocxl_hw.h @@ -24,4 +24,6 @@ struct ocxl_hw_afu { int fn_actag_enabled; /* Function acTag number enabled */ int afu_actag_base; /* AFU acTag base */ int afu_actag_enabled; /* AFU acTag number enabled */ + + int max_pasid; /* Maximum number of contexts */ }; -- 2.1.0
[PATCH 09/38] cxlflash: Setup AFU acTag range
The OpenCXL specification supports distributing acTags amongst different AFUs and functions on the link. As cxlflash devices are expected to only support a single AFU and function, the entire range that was assigned to the function is also assigned to the AFU. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 13 + drivers/scsi/cxlflash/ocxl_hw.h | 2 ++ 2 files changed, 15 insertions(+) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 8e48480..3875ed4 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -89,6 +89,9 @@ static int ocxlflash_config_afu(struct pci_dev *pdev, struct ocxl_hw_afu *afu) struct ocxl_afu_config *acfg = >acfg; struct ocxl_fn_config *fcfg = >fcfg; struct device *dev = >dev; + int count; + int base; + int pos; int rc = 0; /* Read AFU config at index 0 */ @@ -98,6 +101,16 @@ static int ocxlflash_config_afu(struct pci_dev *pdev, struct ocxl_hw_afu *afu) __func__, rc); goto out; } + + /* Only one AFU per function is supported, so actag_base is same */ + base = afu->fn_actag_base; + count = min_t(int, acfg->actag_supported, afu->fn_actag_enabled); + pos = acfg->dvsec_afu_control_pos; + + ocxl_config_set_afu_actag(pdev, pos, base, count); + dev_dbg(dev, "%s: acTag base=%d enabled=%d\n", __func__, base, count); + afu->afu_actag_base = base; + afu->afu_actag_enabled = count; out: return rc; } diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h index 29fd338..a0ef04c 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.h +++ b/drivers/scsi/cxlflash/ocxl_hw.h @@ -22,4 +22,6 @@ struct ocxl_hw_afu { int fn_actag_base; /* Function acTag base */ int fn_actag_enabled; /* Function acTag number enabled */ + int afu_actag_base; /* AFU acTag base */ + int afu_actag_enabled; /* AFU acTag number enabled */ }; -- 2.1.0
[PATCH 08/38] cxlflash: Read host AFU configuration
The host AFU configuration is read on the initialization path to identify the features and configuration of the AFU. This data is cached for use in later configuration steps. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 34 ++ drivers/scsi/cxlflash/ocxl_hw.h | 1 + 2 files changed, 35 insertions(+) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index add2803..8e48480 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -76,6 +76,33 @@ static int ocxlflash_config_fn(struct pci_dev *pdev, struct ocxl_hw_afu *afu) } /** + * ocxlflash_config_afu() - configure the host AFU + * @pdev: PCI device associated with the host. + * @afu: AFU associated with the host. + * + * Must be called _after_ host function configuration. + * + * Return: 0 on success, -errno on failure + */ +static int ocxlflash_config_afu(struct pci_dev *pdev, struct ocxl_hw_afu *afu) +{ + struct ocxl_afu_config *acfg = >acfg; + struct ocxl_fn_config *fcfg = >fcfg; + struct device *dev = >dev; + int rc = 0; + + /* Read AFU config at index 0 */ + rc = ocxl_config_read_afu(pdev, fcfg, acfg, 0); + if (unlikely(rc)) { + dev_err(dev, "%s: ocxl_config_read_afu failed rc=%d\n", + __func__, rc); + goto out; + } +out: + return rc; +} + +/** * ocxlflash_create_afu() - create the AFU for OpenCXL * @pdev: PCI device associated with the host. * @@ -102,6 +129,13 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev) __func__, rc); goto err1; } + + rc = ocxlflash_config_afu(pdev, afu); + if (unlikely(rc)) { + dev_err(dev, "%s: AFU configuration failed rc=%d\n", + __func__, rc); + goto err1; + } out: return afu; err1: diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h index 8c0a172..29fd338 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.h +++ b/drivers/scsi/cxlflash/ocxl_hw.h @@ -18,6 +18,7 @@ struct ocxl_hw_afu { struct device *dev; /* Generic device */ struct ocxl_fn_config fcfg; /* DVSEC config of the function */ + struct ocxl_afu_config acfg;/* AFU configuration data */ int fn_actag_base; /* Function acTag base */ int fn_actag_enabled; /* Function acTag number enabled */ -- 2.1.0
[PATCH 07/38] cxlflash: Setup function acTag range
The OpenCXL specification supports distributing acTags amongst different AFUs and functions on the link. The platform-specific acTag range for the link is obtained using the OCXL provider services and then assigned to the host function based on implementation. For cxlflash devices only a single function per host is expected and thus the entire range is assigned. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 15 +++ drivers/scsi/cxlflash/ocxl_hw.h | 3 +++ 2 files changed, 18 insertions(+) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index a349ec6..add2803 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -42,6 +42,7 @@ static int ocxlflash_config_fn(struct pci_dev *pdev, struct ocxl_hw_afu *afu) { struct ocxl_fn_config *fcfg = >fcfg; struct device *dev = >dev; + u16 base, enabled, supported; int rc = 0; /* Read DVSEC config of the function */ @@ -56,6 +57,20 @@ static int ocxlflash_config_fn(struct pci_dev *pdev, struct ocxl_hw_afu *afu) if (fcfg->max_afu_index != 0) dev_warn(dev, "%s: Unexpected AFU index value %d\n", __func__, fcfg->max_afu_index); + + rc = ocxl_config_get_actag_info(pdev, , , ); + if (unlikely(rc)) { + dev_err(dev, "%s: ocxl_config_get_actag_info failed rc=%d\n", + __func__, rc); + goto out; + } + + afu->fn_actag_base = base; + afu->fn_actag_enabled = enabled; + + ocxl_config_set_actag(pdev, fcfg->dvsec_function_pos, base, enabled); + dev_dbg(dev, "%s: Function acTag range base=%u enabled=%u\n", + __func__, base, enabled); out: return rc; } diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h index 9c1b5347..8c0a172 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.h +++ b/drivers/scsi/cxlflash/ocxl_hw.h @@ -18,4 +18,7 @@ struct ocxl_hw_afu { struct device *dev; /* Generic device */ struct ocxl_fn_config fcfg; /* DVSEC config of the function */ + + int fn_actag_base; /* Function acTag base */ + int fn_actag_enabled; /* Function acTag number enabled */ }; -- 2.1.0
[PATCH 06/38] cxlflash: Read host function configuration
Per the OpenCXL specification, the underlying host can have multiple AFUs per function with each function supporting its own configuration. The host function configuration is read on the initialization path to evaluate the number of functions present and identify the features and configuration of the functions present. This data is cached for use in later configuration steps. Note that for the OCXL hardware supported by the cxlflash driver, only one AFU per function is expected. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/ocxl_hw.c | 41 + drivers/scsi/cxlflash/ocxl_hw.h | 2 ++ 2 files changed, 43 insertions(+) diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 667cf77..a349ec6 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -32,6 +32,35 @@ static void ocxlflash_destroy_afu(void *afu_cookie) } /** + * ocxlflash_config_fn() - configure the host function + * @pdev: PCI device associated with the host. + * @afu: AFU associated with the host. + * + * Return: 0 on success, -errno on failure + */ +static int ocxlflash_config_fn(struct pci_dev *pdev, struct ocxl_hw_afu *afu) +{ + struct ocxl_fn_config *fcfg = >fcfg; + struct device *dev = >dev; + int rc = 0; + + /* Read DVSEC config of the function */ + rc = ocxl_config_read_function(pdev, fcfg); + if (unlikely(rc)) { + dev_err(dev, "%s: ocxl_config_read_function failed rc=%d\n", + __func__, rc); + goto out; + } + + /* Only one AFU per function is supported by ocxlflash */ + if (fcfg->max_afu_index != 0) + dev_warn(dev, "%s: Unexpected AFU index value %d\n", +__func__, fcfg->max_afu_index); +out: + return rc; +} + +/** * ocxlflash_create_afu() - create the AFU for OpenCXL * @pdev: PCI device associated with the host. * @@ -41,6 +70,7 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev) { struct device *dev = >dev; struct ocxl_hw_afu *afu; + int rc; afu = kzalloc(sizeof(*afu), GFP_KERNEL); if (unlikely(!afu)) { @@ -50,8 +80,19 @@ static void *ocxlflash_create_afu(struct pci_dev *pdev) afu->pdev = pdev; afu->dev = dev; + + rc = ocxlflash_config_fn(pdev, afu); + if (unlikely(rc)) { + dev_err(dev, "%s: Function configuration failed rc=%d\n", + __func__, rc); + goto err1; + } out: return afu; +err1: + kfree(afu); + afu = NULL; + goto out; } /* Backend ops to ocxlflash services */ diff --git a/drivers/scsi/cxlflash/ocxl_hw.h b/drivers/scsi/cxlflash/ocxl_hw.h index 57eb53b..9c1b5347 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.h +++ b/drivers/scsi/cxlflash/ocxl_hw.h @@ -16,4 +16,6 @@ struct ocxl_hw_afu { struct pci_dev *pdev; /* PCI device */ struct device *dev; /* Generic device */ + + struct ocxl_fn_config fcfg; /* DVSEC config of the function */ }; -- 2.1.0
[PATCH 05/38] cxlflash: Hardware AFU for OpenCXL
When an adapter is initialized, transport specific configuration and MMIO mapping details need to be saved. For CXL, this data is managed by the underlying kernel module. To maintain a separation between the cxlflash core and underlying transports, introduce a new structure to store data specific to an OpenCXL AFU. Initially only the pointers to underlying PCI and generic devices are added to this new structure - it will be expanded further in future commits. Services to create and destroy this hardware AFU are added and integrated in the probe and exit paths of the driver. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/backend.h | 1 + drivers/scsi/cxlflash/cxl_hw.c | 6 ++ drivers/scsi/cxlflash/main.c| 9 +++-- drivers/scsi/cxlflash/ocxl_hw.c | 40 drivers/scsi/cxlflash/ocxl_hw.h | 19 +++ 5 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 drivers/scsi/cxlflash/ocxl_hw.h diff --git a/drivers/scsi/cxlflash/backend.h b/drivers/scsi/cxlflash/backend.h index a60f051..f675bcb 100644 --- a/drivers/scsi/cxlflash/backend.h +++ b/drivers/scsi/cxlflash/backend.h @@ -36,6 +36,7 @@ struct cxlflash_backend_ops { int (*allocate_afu_irqs)(void *ctx_cookie, int num); void (*free_afu_irqs)(void *ctx_cookie); void * (*create_afu)(struct pci_dev *dev); + void (*destroy_afu)(void *afu_cookie); struct file * (*get_fd)(void *ctx_cookie, struct file_operations *fops, int *fd); void * (*fops_get_context)(struct file *file); diff --git a/drivers/scsi/cxlflash/cxl_hw.c b/drivers/scsi/cxlflash/cxl_hw.c index db1cada..a1d6d12 100644 --- a/drivers/scsi/cxlflash/cxl_hw.c +++ b/drivers/scsi/cxlflash/cxl_hw.c @@ -110,6 +110,11 @@ static void *cxlflash_create_afu(struct pci_dev *dev) return cxl_pci_to_afu(dev); } +static void cxlflash_destroy_afu(void *afu) +{ + /* Dummy fop for cxl */ +} + static struct file *cxlflash_get_fd(void *ctx_cookie, struct file_operations *fops, int *fd) { @@ -160,6 +165,7 @@ const struct cxlflash_backend_ops cxlflash_cxl_ops = { .allocate_afu_irqs = cxlflash_allocate_afu_irqs, .free_afu_irqs = cxlflash_free_afu_irqs, .create_afu = cxlflash_create_afu, + .destroy_afu= cxlflash_destroy_afu, .get_fd = cxlflash_get_fd, .fops_get_context = cxlflash_fops_get_context, .start_work = cxlflash_start_work, diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index b83a55a..5d754d1 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -971,6 +971,7 @@ static void cxlflash_remove(struct pci_dev *pdev) case INIT_STATE_AFU: term_afu(cfg); case INIT_STATE_PCI: + cfg->ops->destroy_afu(cfg->afu_cookie); pci_disable_device(pdev); case INIT_STATE_NONE: free_mem(cfg); @@ -3689,8 +3690,6 @@ static int cxlflash_probe(struct pci_dev *pdev, pci_set_drvdata(pdev, cfg); - cfg->afu_cookie = cfg->ops->create_afu(pdev); - rc = init_pci(cfg); if (rc) { dev_err(dev, "%s: init_pci failed rc=%d\n", __func__, rc); @@ -3698,6 +3697,12 @@ static int cxlflash_probe(struct pci_dev *pdev, } cfg->init_state = INIT_STATE_PCI; + cfg->afu_cookie = cfg->ops->create_afu(pdev); + if (unlikely(!cfg->afu_cookie)) { + dev_err(dev, "%s: create_afu failed\n", __func__); + goto out_remove; + } + rc = init_afu(cfg); if (rc && !wq_has_sleeper(>reset_waitq)) { dev_err(dev, "%s: init_afu failed rc=%d\n", __func__, rc); diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 58a3182..667cf77 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -15,8 +15,48 @@ #include #include "backend.h" +#include "ocxl_hw.h" + +/** + * ocxlflash_destroy_afu() - destroy the AFU structure + * @afu_cookie:AFU to be freed. + */ +static void ocxlflash_destroy_afu(void *afu_cookie) +{ + struct ocxl_hw_afu *afu = afu_cookie; + + if (!afu) + return; + + kfree(afu); +} + +/** + * ocxlflash_create_afu() - create the AFU for OpenCXL + * @pdev: PCI device associated with the host. + * + * Return: AFU on success, NULL on failure + */ +static void *ocxlflash_create_afu(struct pci_dev *pdev) +{ + struct device *dev = >dev; + struct ocxl_hw_afu *afu; + + afu = kzalloc(sizeof(*afu), GFP_KERNEL); + if (unlikely(!afu)) { + dev_err(dev, "%s: HW AFU allocation failed\n", __func__); + goto out; + } + + afu->pdev = pdev; + afu->dev = dev; +out: + return afu; +}
[PATCH 04/38] cxlflash: Introduce OpenCXL backend
Add initial infrastructure to support a new cxlflash transport, OpenCXL. Claim a dependency on OpenCXL (OCXL) and add a new file, ocxl_hw.c, which will host the backend routines that are specific to OpenCXL. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/Kconfig | 2 +- drivers/scsi/cxlflash/Makefile | 2 +- drivers/scsi/cxlflash/backend.h | 1 + drivers/scsi/cxlflash/ocxl_hw.c | 22 ++ 4 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 drivers/scsi/cxlflash/ocxl_hw.c diff --git a/drivers/scsi/cxlflash/Kconfig b/drivers/scsi/cxlflash/Kconfig index a011c5d..e2a3a1b 100644 --- a/drivers/scsi/cxlflash/Kconfig +++ b/drivers/scsi/cxlflash/Kconfig @@ -4,7 +4,7 @@ config CXLFLASH tristate "Support for IBM CAPI Flash" - depends on PCI && SCSI && CXL && EEH + depends on PCI && SCSI && CXL && OCXL && EEH select IRQ_POLL default m help diff --git a/drivers/scsi/cxlflash/Makefile b/drivers/scsi/cxlflash/Makefile index 7ec3f6b..5124c68 100644 --- a/drivers/scsi/cxlflash/Makefile +++ b/drivers/scsi/cxlflash/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_CXLFLASH) += cxlflash.o -cxlflash-y += main.o superpipe.o lunmgt.o vlun.o cxl_hw.o +cxlflash-y += main.o superpipe.o lunmgt.o vlun.o cxl_hw.o ocxl_hw.o diff --git a/drivers/scsi/cxlflash/backend.h b/drivers/scsi/cxlflash/backend.h index 7b72149..a60f051 100644 --- a/drivers/scsi/cxlflash/backend.h +++ b/drivers/scsi/cxlflash/backend.h @@ -13,6 +13,7 @@ */ extern const struct cxlflash_backend_ops cxlflash_cxl_ops; +extern const struct cxlflash_backend_ops cxlflash_ocxl_ops; struct cxlflash_backend_ops { struct module *module; diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c new file mode 100644 index 000..58a3182 --- /dev/null +++ b/drivers/scsi/cxlflash/ocxl_hw.c @@ -0,0 +1,22 @@ +/* + * CXL Flash Device Driver + * + * Written by: Matthew R. Ochs , IBM Corporation + * Uma Krishnan , IBM Corporation + * + * Copyright (C) 2018 IBM Corporation + * + * 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 "backend.h" + +/* Backend ops to ocxlflash services */ +const struct cxlflash_backend_ops cxlflash_ocxl_ops = { + .module = THIS_MODULE, +}; -- 2.1.0
[PATCH 03/38] cxlflash: Add argument identifier names
Checkpatch throws a warning when the argument identifier names are not included in the function definitions. To avoid these warnings, argument identifiers are added in the existing function definitions. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/backend.h | 47 ++--- drivers/scsi/cxlflash/common.h | 4 ++-- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/drivers/scsi/cxlflash/backend.h b/drivers/scsi/cxlflash/backend.h index 339e42b..7b72149 100644 --- a/drivers/scsi/cxlflash/backend.h +++ b/drivers/scsi/cxlflash/backend.h @@ -16,26 +16,29 @@ extern const struct cxlflash_backend_ops cxlflash_cxl_ops; struct cxlflash_backend_ops { struct module *module; - void __iomem * (*psa_map)(void *); - void (*psa_unmap)(void __iomem *); - int (*process_element)(void *); - int (*map_afu_irq)(void *, int, irq_handler_t, void *, char *); - void (*unmap_afu_irq)(void *, int, void *); - int (*start_context)(void *); - int (*stop_context)(void *); - int (*afu_reset)(void *); - void (*set_master)(void *); - void * (*get_context)(struct pci_dev *, void *); - void * (*dev_context_init)(struct pci_dev *, void *); - int (*release_context)(void *); - void (*perst_reloads_same_image)(void *, bool); - ssize_t (*read_adapter_vpd)(struct pci_dev *, void *, size_t); - int (*allocate_afu_irqs)(void *, int); - void (*free_afu_irqs)(void *); - void * (*create_afu)(struct pci_dev *); - struct file * (*get_fd)(void *, struct file_operations *, int *); - void * (*fops_get_context)(struct file *); - int (*start_work)(void *, u64); - int (*fd_mmap)(struct file *, struct vm_area_struct *); - int (*fd_release)(struct inode *, struct file *); + void __iomem * (*psa_map)(void *ctx_cookie); + void (*psa_unmap)(void __iomem *addr); + int (*process_element)(void *ctx_cookie); + int (*map_afu_irq)(void *ctx_cookie, int num, irq_handler_t handler, + void *cookie, char *name); + void (*unmap_afu_irq)(void *ctx_cookie, int num, void *cookie); + int (*start_context)(void *ctx_cookie); + int (*stop_context)(void *ctx_cookie); + int (*afu_reset)(void *ctx_cookie); + void (*set_master)(void *ctx_cookie); + void * (*get_context)(struct pci_dev *dev, void *afu_cookie); + void * (*dev_context_init)(struct pci_dev *dev, void *afu_cookie); + int (*release_context)(void *ctx_cookie); + void (*perst_reloads_same_image)(void *afu_cookie, bool image); + ssize_t (*read_adapter_vpd)(struct pci_dev *dev, void *buf, + size_t count); + int (*allocate_afu_irqs)(void *ctx_cookie, int num); + void (*free_afu_irqs)(void *ctx_cookie); + void * (*create_afu)(struct pci_dev *dev); + struct file * (*get_fd)(void *ctx_cookie, struct file_operations *fops, + int *fd); + void * (*fops_get_context)(struct file *file); + int (*start_work)(void *ctx_cookie, u64 irqs); + int (*fd_mmap)(struct file *file, struct vm_area_struct *vm); + int (*fd_release)(struct inode *inode, struct file *file); }; diff --git a/drivers/scsi/cxlflash/common.h b/drivers/scsi/cxlflash/common.h index 5d7ca01..d7fccea 100644 --- a/drivers/scsi/cxlflash/common.h +++ b/drivers/scsi/cxlflash/common.h @@ -232,8 +232,8 @@ struct hwq { struct afu { struct hwq hwqs[CXLFLASH_MAX_HWQS]; - int (*send_cmd)(struct afu *, struct afu_cmd *); - int (*context_reset)(struct hwq *); + int (*send_cmd)(struct afu *afu, struct afu_cmd *cmd); + int (*context_reset)(struct hwq *hwq); /* AFU HW */ struct cxlflash_afu_map __iomem *afu_map; /* entire MMIO map */ -- 2.1.0
[PATCH 02/38] cxlflash: Avoid clobbering context control register value
From: "Matthew R. Ochs"The SISLite specification originally defined the context control register with a single field of bits to represent the LISN and also stipulated that the register reset value be 0. The cxlflash driver took advantage of this when programming the LISN for the master contexts via an unconditional write - no other bits were preserved. When unmap support was added, SISLite was updated to define bit 0 of the context control register as a way for the AFU to notify the context owner that unmap operations were supported. Thus the assumptions under which the register is setup changed and the existing unconditional write is clobbering the unmap state for master contexts. This is presently not an issue due to the order in which the context control register is programmed in relation to the unmap bit being queried but should be addressed to avoid a future regression in the event this code is moved elsewhere. To remedy this issue, preserve the bits when programming the LISN field in the context control register. Since the LISN will now be programmed using a read value, assert that the initial state of the LISN field is as described in SISLite (0). Signed-off-by: Matthew R. Ochs Signed-off-by: Uma Krishnan --- drivers/scsi/cxlflash/main.c| 5 - drivers/scsi/cxlflash/sislite.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 3d3e003..b83a55a 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -1303,7 +1303,10 @@ static void afu_err_intr_init(struct afu *afu) for (i = 0; i < afu->num_hwqs; i++) { hwq = get_hwq(afu, i); - writeq_be(SISL_MSI_SYNC_ERROR, >host_map->ctx_ctrl); + reg = readq_be(>host_map->ctx_ctrl); + WARN_ON((reg & SISL_CTX_CTRL_LISN_MASK) != 0); + reg |= SISL_MSI_SYNC_ERROR; + writeq_be(reg, >host_map->ctx_ctrl); writeq_be(SISL_ISTATUS_MASK, >host_map->intr_mask); } } diff --git a/drivers/scsi/cxlflash/sislite.h b/drivers/scsi/cxlflash/sislite.h index bedf1ce..d8940f1 100644 --- a/drivers/scsi/cxlflash/sislite.h +++ b/drivers/scsi/cxlflash/sislite.h @@ -284,6 +284,7 @@ struct sisl_host_map { __be64 cmd_room; __be64 ctx_ctrl;/* least significant byte or b56:63 is LISN# */ #define SISL_CTX_CTRL_UNMAP_SECTOR 0x8000ULL /* b0 */ +#define SISL_CTX_CTRL_LISN_MASK(0xFFULL) __be64 mbox_w; /* restricted use */ __be64 sq_start;/* Submission Queue (R/W): write sequence and */ __be64 sq_end; /* inclusion semantics are the same as RRQ*/ -- 2.1.0
[PATCH 01/38] cxlflash: Preserve number of interrupts for master contexts
The number of interrupts requested for user contexts are stored in the context specific structures and utilized to manage the interrupts. For the master contexts, this number is only used once and therefore not saved. To prepare for future commits where the number of interrupts will be required in more than one place, preserve the value in the master context structure. Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/common.h | 1 + drivers/scsi/cxlflash/main.c | 11 --- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/cxlflash/common.h b/drivers/scsi/cxlflash/common.h index 102fd26..5d7ca01 100644 --- a/drivers/scsi/cxlflash/common.h +++ b/drivers/scsi/cxlflash/common.h @@ -211,6 +211,7 @@ struct hwq { struct sisl_ctrl_map __iomem *ctrl_map; /* MC control map */ ctx_hndl_t ctx_hndl;/* master's context handle */ u32 index; /* Index of this hwq */ + int num_irqs; /* Numer of interrupts requested for context */ struct list_head pending_cmds; /* Commands pending completion */ atomic_t hsq_credits; diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index d8fe7ab8..3d3e003 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -1911,7 +1911,7 @@ static enum undo_level init_intr(struct cxlflash_cfg *cfg, int rc = 0; enum undo_level level = UNDO_NOOP; bool is_primary_hwq = (hwq->index == PRIMARY_HWQ); - int num_irqs = is_primary_hwq ? 3 : 2; + int num_irqs = hwq->num_irqs; rc = cfg->ops->allocate_afu_irqs(ctx, num_irqs); if (unlikely(rc)) { @@ -1965,16 +1965,20 @@ static int init_mc(struct cxlflash_cfg *cfg, u32 index) struct device *dev = >dev->dev; struct hwq *hwq = get_hwq(cfg->afu, index); int rc = 0; + int num_irqs; enum undo_level level; hwq->afu = cfg->afu; hwq->index = index; INIT_LIST_HEAD(>pending_cmds); - if (index == PRIMARY_HWQ) + if (index == PRIMARY_HWQ) { ctx = cfg->ops->get_context(cfg->dev, cfg->afu_cookie); - else + num_irqs = 3; + } else { ctx = cfg->ops->dev_context_init(cfg->dev, cfg->afu_cookie); + num_irqs = 2; + } if (IS_ERR_OR_NULL(ctx)) { rc = -ENOMEM; goto err1; @@ -1982,6 +1986,7 @@ static int init_mc(struct cxlflash_cfg *cfg, u32 index) WARN_ON(hwq->ctx_cookie); hwq->ctx_cookie = ctx; + hwq->num_irqs = num_irqs; /* Set it up as a master with the CXL */ cfg->ops->set_master(ctx); -- 2.1.0
[PATCH 00/38] cxlflash: OpenCXL transport support
This patch series adds OpenCXL support to the cxlflash driver. With this support, new devices using the OpenCXL transport will be supported by the cxlflash driver along with the existing CXL devices. An effort is made to keep this transport specific function independent of the existing core driver that communicates with the AFU. The first three patches contain a minor fix and staging improvements. This series is intended for 4.17 and is bisectable. Matthew R. Ochs (1): cxlflash: Avoid clobbering context control register value Uma Krishnan (37): cxlflash: Preserve number of interrupts for master contexts cxlflash: Add argument identifier names cxlflash: Introduce OpenCXL backend cxlflash: Hardware AFU for OpenCXL cxlflash: Read host function configuration cxlflash: Setup function acTag range cxlflash: Read host AFU configuration cxlflash: Setup AFU acTag range cxlflash: Setup AFU PASID cxlflash: Adapter context support for OpenCXL cxlflash: Use IDR to manage adapter contexts cxlflash: Support adapter file descriptors for OpenCXL cxlflash: Support adapter context discovery cxlflash: Support image reload policy modification cxlflash: MMIO map the AFU cxlflash: Support starting an adapter context cxlflash: Support process specific mappings cxlflash: Support AFU state toggling cxlflash: Support reading adapter VPD data cxlflash: Setup function OpenCXL link cxlflash: Setup OpenCXL transaction layer cxlflash: Support process element lifecycle cxlflash: Support AFU interrupt management cxlflash: Support AFU interrupt mapping and registration cxlflash: Support starting user contexts cxlflash: Support adapter context polling cxlflash: Support adapter context reading cxlflash: Support adapter context mmap and release cxlflash: Support file descriptor mapping cxlflash: Introduce object handle fop cxlflash: Setup LISNs for user contexts cxlflash: Setup LISNs for master contexts cxlflash: Update synchronous interrupt status bits cxlflash: Introduce OCXL context state machine cxlflash: Register for translation errors cxlflash: Support AFU reset cxlflash: Enable OpenCXL operations drivers/scsi/cxlflash/Kconfig |2 +- drivers/scsi/cxlflash/Makefile|2 +- drivers/scsi/cxlflash/backend.h | 50 +- drivers/scsi/cxlflash/common.h| 10 +- drivers/scsi/cxlflash/cxl_hw.c| 13 + drivers/scsi/cxlflash/main.c | 55 +- drivers/scsi/cxlflash/main.h |1 + drivers/scsi/cxlflash/ocxl_hw.c | 1428 + drivers/scsi/cxlflash/ocxl_hw.h | 76 ++ drivers/scsi/cxlflash/sislite.h | 41 +- drivers/scsi/cxlflash/superpipe.c | 14 + 11 files changed, 1644 insertions(+), 48 deletions(-) create mode 100644 drivers/scsi/cxlflash/ocxl_hw.c create mode 100644 drivers/scsi/cxlflash/ocxl_hw.h -- 2.1.0
Re: [PATCH] powerpc/powernv: Turn on SCSI_AACRAID in powernv_defconfig
Brian Kingwrites: > On 09/03/2017 06:19 PM, Stewart Smith wrote: >> Michael Ellerman writes: 2. On a bare metal machine, if you set ipr.fast_reboot=1 on the skiboot kernel, then we should also avoid resetting the ipr adapter, so ipr init on the kernel being kexec booted from skiboot should be extremely fast. >>> >>> OK, I didn't know that was an option, so that might help. >>> ... If you've got cases where ipr init is taking a long time, I'd be interested to know what scenarios are the most annoying to see if there is any opportunity to improve. >>> >>> Yeah booting bare metal is where I see it (not using ipr.fast_reboot). >> >> Hrm... We should probably enable that by default for petitboot then. >> >> It'd at least cut some time off booting straight through to OS. > > Agreed. I'd be interested to hear if that helps address the issue > Michael is seeing. > > You can easily test this by exiting to a petitboot shell: > > echo 1 > /sys/module/ipr/parameters/fast_reboot > > Then go back to petitboot and boot the OS. Just following up on this (!). This does work, and I've now been running it in my CI for about a month (~1000 boots) with no problems. You can also make it persistent by doing: $ nvram -p ibm,skiboot --update-config bootargs="ipr.fast_reboot=1" cheers
Re: [PATCH v3] watchdog: add SPDX identifiers for watchdog subsystem
Marcus Folkessonwrites: [...] > drivers/watchdog/mena21_wdt.c | 4 +-- For mena21_wdt: Acked-by: Johannes Thumshirn -- Johannes Thumshirn Storage jthumsh...@suse.de+49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850
Re: [PATCH] fix double ;;s in code
Hi Pavel, On Sat, Feb 17, 2018 at 10:19:55PM +0100, Pavel Machek wrote: ... > diff --git a/drivers/soc/imx/gpc.c b/drivers/soc/imx/gpc.c > index 53f7275..cfb42f5 100644 > --- a/drivers/soc/imx/gpc.c > +++ b/drivers/soc/imx/gpc.c > @@ -348,7 +348,7 @@ static int imx_gpc_old_dt_init(struct device *dev, struct > regmap *regmap, > if (i == 1) { > domain->supply = devm_regulator_get(dev, "pu"); > if (IS_ERR(domain->supply)) > - return PTR_ERR(domain->supply);; > + return PTR_ERR(domain->supply); > > ret = imx_pgc_get_clocks(dev, domain); > if (ret) > Considering the controversy how the changes should be merged, I'm going to send a separate patch just for IMX GPC driver with a reported-by-you tag. Thanks for catching this. Shawn
Re: [PATCH] PCI/AER: Add a null check before eeh_ops->notify_resume callback.
On 2/22/18 5:58 AM, Vaibhav Jain wrote: > This patch puts a NULL check before branching to the address pointed > to by eeh_ops->notify_resume in eeh_report_resume(). The callback > is used to notify the arch EEH code that a pci device is back > online. > > For PPC64 presently, only an implementation for pseries platform is > available and not for powernv. Hence without this patch EEH recovery > on all non-virtualized hosts is causing a kernel panic when > CONFIG_PCI_IOV is set. The panic is usually is of the form: > > EEH: Notify device driver to resume > Unable to handle kernel paging request for instruction fetch > Faulting instruction address: 0x > Oops: Kernel access of bad area, sig: 11 [#1] > > LR eeh_report_resume+0x218/0x220 > Call Trace: > eeh_report_resume+0x1f0/0x220 (unreliable) > eeh_pe_dev_traverse+0x98/0x170 > eeh_handle_normal_event+0x3f4/0x650 > eeh_handle_event+0x188/0x380 > eeh_event_handler+0x208/0x210 > kthread+0x168/0x1b0 > ret_from_kernel_thread+0x5c/0xb4 > > Cc: Bryant G. Ly> Fixes: 856e1eb9bdd4("PCI/AER: Add uevents in AER and EEH error/resume") > Signed-off-by: Vaibhav Jain > --- > arch/powerpc/kernel/eeh_driver.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/arch/powerpc/kernel/eeh_driver.c > b/arch/powerpc/kernel/eeh_driver.c > index beea2182d754..932858a293ea 100644 > --- a/arch/powerpc/kernel/eeh_driver.c > +++ b/arch/powerpc/kernel/eeh_driver.c > @@ -384,7 +384,8 @@ static void *eeh_report_resume(void *data, void *userdata) > eeh_pcid_put(dev); > pci_uevent_ers(dev, PCI_ERS_RESULT_RECOVERED); > #ifdef CONFIG_PCI_IOV > - eeh_ops->notify_resume(eeh_dev_to_pdn(edev)); > + if (eeh_ops->notify_resume) > + eeh_ops->notify_resume(eeh_dev_to_pdn(edev)); > #endif > return NULL; > } A version of this patch already upstreamed. https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/commit/?h=fixes=521ca5a9859a870e354d1a6b84a6ff4c07bbceb0 -Bryant
Re: samples/seccomp/ broken when cross compiling s390, ppc allyesconfig
On Thu, Feb 22, 2018 at 5:07 AM, Michal Hockowrote: > On Wed 14-02-18 09:14:47, Kees Cook wrote: > [...] >> I can send it through my seccomp tree via James Morris. > > Could you please do it? Hi! Yes, sorry, this fell through the cracks. Now applied. -Kees -- Kees Cook Pixel Security
Re: [PATCH] crypto: nx-842: Delete an error message for a failed memory allocation in nx842_pseries_init()
On Wed, Feb 14, 2018 at 05:17:08PM +0100, SF Markus Elfring wrote: > From: Markus Elfring> Date: Wed, 14 Feb 2018 17:05:13 +0100 > > Omit an extra message for a memory allocation failure in this function. > > This issue was detected by using the Coccinelle software. > > Signed-off-by: Markus Elfring Patch applied. Thanks. -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
[PATCH v5 6/6] powerpc/8xx: Increase number of slices to 64
On the 8xx, the minimum slice size is the size of the area covered by a single PMD entry, ie 4M in 4K pages mode and 64M in 16K pages mode. This patch increases the number of slices from 16 to 64 on the 8xx. Signed-off-by: Christophe Leroy--- v4: New v5: No change arch/powerpc/include/asm/nohash/32/slice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/nohash/32/slice.h b/arch/powerpc/include/asm/nohash/32/slice.h index 95d532e18092..777d62e40ac0 100644 --- a/arch/powerpc/include/asm/nohash/32/slice.h +++ b/arch/powerpc/include/asm/nohash/32/slice.h @@ -4,7 +4,7 @@ #ifdef CONFIG_PPC_MM_SLICES -#define SLICE_LOW_SHIFT28 +#define SLICE_LOW_SHIFT26 /* 64 slices */ #define SLICE_LOW_TOP (0x1ull) #define SLICE_NUM_LOW (SLICE_LOW_TOP >> SLICE_LOW_SHIFT) #define GET_LOW_SLICE_INDEX(addr) ((addr) >> SLICE_LOW_SHIFT) -- 2.13.3
[PATCH v5 5/6] powerpc/mm/slice: Allow up to 64 low slices
While the implementation of the "slices" address space allows a significant amount of high slices, it limits the number of low slices to 16 due to the use of a single u64 low_slices_psize element in struct mm_context_t On the 8xx, the minimum slice size is the size of the area covered by a single PMD entry, ie 4M in 4K pages mode and 64M in 16K pages mode. This means we could have at least 64 slices. In order to override this limitation, this patch switches the handling of low_slices_psize to char array as done already for high_slices_psize. Signed-off-by: Christophe LeroyReviewed-by: Aneesh Kumar K.V --- v2: Using slice_bitmap_xxx() macros instead of bitmap_xxx() functions. v3: keep low_slices as a u64, this allows 64 slices which is enough. v4: Moved the 8xx specifics to next patch v5: No change arch/powerpc/include/asm/book3s/64/mmu.h | 3 +- arch/powerpc/include/asm/mmu-8xx.h | 7 +++- arch/powerpc/include/asm/paca.h | 2 +- arch/powerpc/kernel/paca.c | 3 +- arch/powerpc/mm/hash_utils_64.c | 13 arch/powerpc/mm/slb_low.S| 8 +++-- arch/powerpc/mm/slice.c | 57 +--- 7 files changed, 52 insertions(+), 41 deletions(-) diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h index 0abeb0e2d616..bef6e39ed63a 100644 --- a/arch/powerpc/include/asm/book3s/64/mmu.h +++ b/arch/powerpc/include/asm/book3s/64/mmu.h @@ -91,7 +91,8 @@ typedef struct { struct npu_context *npu_context; #ifdef CONFIG_PPC_MM_SLICES - u64 low_slices_psize; /* SLB page size encodings */ +/* SLB page size encodings*/ + unsigned char low_slices_psize[BITS_PER_LONG / BITS_PER_BYTE]; unsigned char high_slices_psize[SLICE_ARRAY_SIZE]; unsigned long slb_addr_limit; #else diff --git a/arch/powerpc/include/asm/mmu-8xx.h b/arch/powerpc/include/asm/mmu-8xx.h index b324ab46d838..d3d7e79140c6 100644 --- a/arch/powerpc/include/asm/mmu-8xx.h +++ b/arch/powerpc/include/asm/mmu-8xx.h @@ -186,6 +186,11 @@ #define M_APG2 0x0040 #define M_APG3 0x0060 +#ifdef CONFIG_PPC_MM_SLICES +#include +#define SLICE_ARRAY_SIZE (1 << (32 - SLICE_LOW_SHIFT - 1)) +#endif + #ifndef __ASSEMBLY__ typedef struct { unsigned int id; @@ -193,7 +198,7 @@ typedef struct { unsigned long vdso_base; #ifdef CONFIG_PPC_MM_SLICES u16 user_psize; /* page size index */ - u64 low_slices_psize; /* page size encodings */ + unsigned char low_slices_psize[SLICE_ARRAY_SIZE]; unsigned char high_slices_psize[0]; unsigned long slb_addr_limit; #endif diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index b62c31037cad..d2bf71dddbef 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h @@ -141,7 +141,7 @@ struct paca_struct { #ifdef CONFIG_PPC_BOOK3S mm_context_id_t mm_ctx_id; #ifdef CONFIG_PPC_MM_SLICES - u64 mm_ctx_low_slices_psize; + unsigned char mm_ctx_low_slices_psize[BITS_PER_LONG / BITS_PER_BYTE]; unsigned char mm_ctx_high_slices_psize[SLICE_ARRAY_SIZE]; unsigned long mm_ctx_slb_addr_limit; #else diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index 95ffedf14885..2fd563d05831 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c @@ -265,7 +265,8 @@ void copy_mm_to_paca(struct mm_struct *mm) #ifdef CONFIG_PPC_MM_SLICES VM_BUG_ON(!mm->context.slb_addr_limit); get_paca()->mm_ctx_slb_addr_limit = mm->context.slb_addr_limit; - get_paca()->mm_ctx_low_slices_psize = context->low_slices_psize; + memcpy(_paca()->mm_ctx_low_slices_psize, + >low_slices_psize, sizeof(context->low_slices_psize)); memcpy(_paca()->mm_ctx_high_slices_psize, >high_slices_psize, TASK_SLICE_ARRAY_SZ(mm)); #else /* CONFIG_PPC_MM_SLICES */ diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index cf290d415dcd..b578148d89e6 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -1110,19 +1110,18 @@ unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap) #ifdef CONFIG_PPC_MM_SLICES static unsigned int get_paca_psize(unsigned long addr) { - u64 lpsizes; - unsigned char *hpsizes; + unsigned char *psizes; unsigned long index, mask_index; if (addr < SLICE_LOW_TOP) { - lpsizes = get_paca()->mm_ctx_low_slices_psize; + psizes = get_paca()->mm_ctx_low_slices_psize; index = GET_LOW_SLICE_INDEX(addr); - return (lpsizes >> (index * 4)) & 0xF; + } else { + psizes = get_paca()->mm_ctx_high_slices_psize; + index = GET_HIGH_SLICE_INDEX(addr); } - hpsizes =
[PATCH v5 4/6] powerpc/mm/slice: Fix hugepage allocation at hint address on 8xx
On the 8xx, the page size is set in the PMD entry and applies to all pages of the page table pointed by the said PMD entry. When an app has some regular pages allocated (e.g. see below) and tries to mmap() a huge page at a hint address covered by the same PMD entry, the kernel accepts the hint allthough the 8xx cannot handle different page sizes in the same PMD entry. 1000-10001000 r-xp 00:0f 2597 /root/malloc 1001-10011000 rwxp 00:0f 2597 /root/malloc mmap(0x1008, 524288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|0x4, -1, 0) = 0x1008 This results the app remaining forever in do_page_fault()/hugetlb_fault() and when interrupting that app, we get the following warning: [162980.035629] WARNING: CPU: 0 PID: 2777 at arch/powerpc/mm/hugetlbpage.c:354 hugetlb_free_pgd_range+0xc8/0x1e4 [162980.035699] CPU: 0 PID: 2777 Comm: malloc Tainted: G W 4.14.6 #85 [162980.035744] task: c67e2c00 task.stack: c668e000 [162980.035783] NIP: c000fe18 LR: c00e1eec CTR: c00f90c0 [162980.035830] REGS: c668fc20 TRAP: 0700 Tainted: G W(4.14.6) [162980.035854] MSR: 00029032CR: 24044224 XER: 2000 [162980.036003] [162980.036003] GPR00: c00e1eec c668fcd0 c67e2c00 0010 c6869410 1008 77fb4000 [162980.036003] GPR08: 0001 0683c001 ff80 44028228 10018a34 4008 418004fc [162980.036003] GPR16: c668e000 00040100 c668e000 c06c c668fe78 c668e000 c6835ba0 c668fd48 [162980.036003] GPR24: 73ff 7400 0001 77fb4000 100f 1010 1010 [162980.036743] NIP [c000fe18] hugetlb_free_pgd_range+0xc8/0x1e4 [162980.036839] LR [c00e1eec] free_pgtables+0x12c/0x150 [162980.036861] Call Trace: [162980.036939] [c668fcd0] [c00f0774] unlink_anon_vmas+0x1c4/0x214 (unreliable) [162980.037040] [c668fd10] [c00e1eec] free_pgtables+0x12c/0x150 [162980.037118] [c668fd40] [c00eabac] exit_mmap+0xe8/0x1b4 [162980.037210] [c668fda0] [c0019710] mmput.part.9+0x20/0xd8 [162980.037301] [c668fdb0] [c001ecb0] do_exit+0x1f0/0x93c [162980.037386] [c668fe00] [c001f478] do_group_exit+0x40/0xcc [162980.037479] [c668fe10] [c002a76c] get_signal+0x47c/0x614 [162980.037570] [c668fe70] [c0007840] do_signal+0x54/0x244 [162980.037654] [c668ff30] [c0007ae8] do_notify_resume+0x34/0x88 [162980.037744] [c668ff40] [c000dae8] do_user_signal+0x74/0xc4 [162980.037781] Instruction dump: [162980.037821] 7fdff378 8137 54a3463a 80890020 7d24182e 7c841a14 712a0004 4082ff94 [162980.038014] 2f89 419e0010 712a0ff0 408200e0 <0fe0> 54a9000a 7f984840 419d0094 [162980.038216] ---[ end trace c0ceeca8e7a5800a ]--- [162980.038754] BUG: non-zero nr_ptes on freeing mm: 1 [162985.363322] BUG: non-zero nr_ptes on freeing mm: -1 In order to fix this, this patch uses the address space "slices" implemented for BOOK3S/64 and enhanced to support PPC32 by the preceding patch. This patch modifies the context.id on the 8xx to be in the range [1:16] instead of [0:15] in order to identify context.id == 0 as not initialised contexts as done on BOOK3S This patch activates CONFIG_PPC_MM_SLICES when CONFIG_HUGETLB_PAGE is selected for the 8xx Alltough we could in theory have as many slices as PMD entries, the current slices implementation limits the number of low slices to 16. This limitation is not preventing us to fix the initial issue allthough it is suboptimal. It will be cured in a subsequent patch. Fixes: 4b91428699477 ("powerpc/8xx: Implement support of hugepages") Signed-off-by: Christophe Leroy Reviewed-by: Aneesh Kumar K.V --- v2: First patch of v1 serie split in two parts v3: No changes v4: No changes v5: No changes arch/powerpc/include/asm/mmu-8xx.h | 6 ++ arch/powerpc/kernel/setup-common.c | 2 ++ arch/powerpc/mm/8xx_mmu.c | 2 +- arch/powerpc/mm/hugetlbpage.c | 2 ++ arch/powerpc/mm/mmu_context_nohash.c | 18 -- arch/powerpc/platforms/Kconfig.cputype | 1 + 6 files changed, 28 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/include/asm/mmu-8xx.h b/arch/powerpc/include/asm/mmu-8xx.h index 2f806e329648..b324ab46d838 100644 --- a/arch/powerpc/include/asm/mmu-8xx.h +++ b/arch/powerpc/include/asm/mmu-8xx.h @@ -191,6 +191,12 @@ typedef struct { unsigned int id; unsigned int active; unsigned long vdso_base; +#ifdef CONFIG_PPC_MM_SLICES + u16 user_psize; /* page size index */ + u64 low_slices_psize; /* page size encodings */ + unsigned char high_slices_psize[0]; + unsigned long slb_addr_limit; +#endif } mm_context_t; #define PHYS_IMMR_BASE (mfspr(SPRN_IMMR) & 0xfff8) diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index d73ec518ef80..a6002f9449b1 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -919,6 +919,8 @@ void __init setup_arch(char **cmdline_p) #ifdef
[PATCH v5 3/6] powerpc/mm/slice: Enhance for supporting PPC32
In preparation for the following patch which will fix an issue on the 8xx by re-using the 'slices', this patch enhances the 'slices' implementation to support 32 bits CPUs. On PPC32, the address space is limited to 4Gbytes, hence only the low slices will be used. The high slices use bitmaps. As bitmap functions are not prepared to handle bitmaps of size 0, this patch ensures that bitmap functions are called only when SLICE_NUM_HIGH is not nul. Signed-off-by: Christophe Leroy--- v2: First patch of v1 serie split in two parts ; added slice_bitmap_xxx() macros. v3: Moving slice related stuff in slice.h and slice_32/64.h slice_bitmap_xxx() are now static inline functions and platform dependent SLICE_LOW_TOP declared ull on PPC32 with correct casts allows to keep it 0x1 v4: Moved slice_32.h and slice_64.h to respective subarch dirs Moved somes #ifdefs from asm/slice.h to respective subarch slice.h SLICE_LOW_ details distributed in repective subarch slices allthough they are identical for the moment v5: Split in two parts. The moving of slice related stuffs into slice.h files is now done in the preceding patch Based on several feedback received, this version removes the slice_bitmap_xxx() wrappers and comes back to the initial approach of checking that SLICE_NUM_HIGH is not nul before using bitmap_xxx() functions. Unlike the others, this approach has the advantage of allowing the reader to immediatly know what's going on and avoid all this set of copy/empty wrappers in subarch slice.h files. It also significantly reduces the size of the patch, which is a prerequisite for backporting it to stable releases. arch/powerpc/include/asm/nohash/32/slice.h | 18 +++ arch/powerpc/include/asm/slice.h | 4 +++- arch/powerpc/mm/slice.c| 37 +++--- 3 files changed, 50 insertions(+), 9 deletions(-) create mode 100644 arch/powerpc/include/asm/nohash/32/slice.h diff --git a/arch/powerpc/include/asm/nohash/32/slice.h b/arch/powerpc/include/asm/nohash/32/slice.h new file mode 100644 index ..95d532e18092 --- /dev/null +++ b/arch/powerpc/include/asm/nohash/32/slice.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_POWERPC_NOHASH_32_SLICE_H +#define _ASM_POWERPC_NOHASH_32_SLICE_H + +#ifdef CONFIG_PPC_MM_SLICES + +#define SLICE_LOW_SHIFT28 +#define SLICE_LOW_TOP (0x1ull) +#define SLICE_NUM_LOW (SLICE_LOW_TOP >> SLICE_LOW_SHIFT) +#define GET_LOW_SLICE_INDEX(addr) ((addr) >> SLICE_LOW_SHIFT) + +#define SLICE_HIGH_SHIFT 0 +#define SLICE_NUM_HIGH 0ul +#define GET_HIGH_SLICE_INDEX(addr) (addr & 0) + +#endif /* CONFIG_PPC_MM_SLICES */ + +#endif /* _ASM_POWERPC_NOHASH_32_SLICE_H */ diff --git a/arch/powerpc/include/asm/slice.h b/arch/powerpc/include/asm/slice.h index 17c5a5d8c418..172711fadb1c 100644 --- a/arch/powerpc/include/asm/slice.h +++ b/arch/powerpc/include/asm/slice.h @@ -4,8 +4,10 @@ #ifdef CONFIG_PPC_BOOK3S_64 #include -#else +#elif defined(CONFIG_PPC64) #include +#elif defined(CONFIG_PPC_MMU_NOHASH) +#include #endif #ifdef CONFIG_PPC_MM_SLICES diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c index 98b53d48968f..0beca1ba2282 100644 --- a/arch/powerpc/mm/slice.c +++ b/arch/powerpc/mm/slice.c @@ -73,10 +73,12 @@ static void slice_range_to_mask(unsigned long start, unsigned long len, unsigned long end = start + len - 1; ret->low_slices = 0; - bitmap_zero(ret->high_slices, SLICE_NUM_HIGH); + if (SLICE_NUM_HIGH) + bitmap_zero(ret->high_slices, SLICE_NUM_HIGH); if (start < SLICE_LOW_TOP) { - unsigned long mend = min(end, (SLICE_LOW_TOP - 1)); + unsigned long mend = min(end, +(unsigned long)(SLICE_LOW_TOP - 1)); ret->low_slices = (1u << (GET_LOW_SLICE_INDEX(mend) + 1)) - (1u << GET_LOW_SLICE_INDEX(start)); @@ -113,11 +115,13 @@ static int slice_high_has_vma(struct mm_struct *mm, unsigned long slice) unsigned long start = slice << SLICE_HIGH_SHIFT; unsigned long end = start + (1ul << SLICE_HIGH_SHIFT); +#ifdef CONFIG_PPC64 /* Hack, so that each addresses is controlled by exactly one * of the high or low area bitmaps, the first high area starts * at 4GB, not 0 */ if (start == 0) start = SLICE_LOW_TOP; +#endif return !slice_area_is_free(mm, start, end - start); } @@ -128,7 +132,8 @@ static void slice_mask_for_free(struct mm_struct *mm, struct slice_mask *ret, unsigned long i; ret->low_slices = 0; - bitmap_zero(ret->high_slices, SLICE_NUM_HIGH); + if (SLICE_NUM_HIGH) + bitmap_zero(ret->high_slices, SLICE_NUM_HIGH); for (i = 0; i < SLICE_NUM_LOW; i++)
[PATCH v5 2/6] powerpc/mm/slice: create header files dedicated to slices
In preparation for the following patch which will enhance 'slices' for supporting PPC32 in order to fix an issue on hugepages on 8xx, this patch takes out of page*.h all bits related to 'slices' and put them into newly created slice.h header files. While common parts go into asm/slice.h, subarch specific parts go into respective books3s/64/slice.c and nohash/64/slice.c 'slices' Signed-off-by: Christophe Leroy--- v5: new - come from a split of patch 2 of v4 arch/powerpc/include/asm/book3s/64/slice.h | 27 ++ arch/powerpc/include/asm/nohash/64/slice.h | 12 ++ arch/powerpc/include/asm/page.h| 1 + arch/powerpc/include/asm/page_64.h | 59 -- arch/powerpc/include/asm/slice.h | 40 5 files changed, 80 insertions(+), 59 deletions(-) create mode 100644 arch/powerpc/include/asm/book3s/64/slice.h create mode 100644 arch/powerpc/include/asm/nohash/64/slice.h create mode 100644 arch/powerpc/include/asm/slice.h diff --git a/arch/powerpc/include/asm/book3s/64/slice.h b/arch/powerpc/include/asm/book3s/64/slice.h new file mode 100644 index ..db0dedab65ee --- /dev/null +++ b/arch/powerpc/include/asm/book3s/64/slice.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_POWERPC_BOOK3S_64_SLICE_H +#define _ASM_POWERPC_BOOK3S_64_SLICE_H + +#ifdef CONFIG_PPC_MM_SLICES + +#define SLICE_LOW_SHIFT28 +#define SLICE_LOW_TOP (0x1ul) +#define SLICE_NUM_LOW (SLICE_LOW_TOP >> SLICE_LOW_SHIFT) +#define GET_LOW_SLICE_INDEX(addr) ((addr) >> SLICE_LOW_SHIFT) + +#define SLICE_HIGH_SHIFT 40 +#define SLICE_NUM_HIGH (H_PGTABLE_RANGE >> SLICE_HIGH_SHIFT) +#define GET_HIGH_SLICE_INDEX(addr) ((addr) >> SLICE_HIGH_SHIFT) + +#else /* CONFIG_PPC_MM_SLICES */ + +#define get_slice_psize(mm, addr) ((mm)->context.user_psize) +#define slice_set_user_psize(mm, psize)\ +do { \ + (mm)->context.user_psize = (psize); \ + (mm)->context.sllp = SLB_VSID_USER | mmu_psize_defs[(psize)].sllp; \ +} while (0) + +#endif /* CONFIG_PPC_MM_SLICES */ + +#endif /* _ASM_POWERPC_BOOK3S_64_SLICE_H */ diff --git a/arch/powerpc/include/asm/nohash/64/slice.h b/arch/powerpc/include/asm/nohash/64/slice.h new file mode 100644 index ..ad0d6e3cc1c5 --- /dev/null +++ b/arch/powerpc/include/asm/nohash/64/slice.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_POWERPC_NOHASH_64_SLICE_H +#define _ASM_POWERPC_NOHASH_64_SLICE_H + +#ifdef CONFIG_PPC_64K_PAGES +#define get_slice_psize(mm, addr) MMU_PAGE_64K +#else /* CONFIG_PPC_64K_PAGES */ +#define get_slice_psize(mm, addr) MMU_PAGE_4K +#endif /* !CONFIG_PPC_64K_PAGES */ +#define slice_set_user_psize(mm, psize)do { BUG(); } while (0) + +#endif /* _ASM_POWERPC_NOHASH_64_SLICE_H */ diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h index 8da5d4c1cab2..d5f1c41b7dba 100644 --- a/arch/powerpc/include/asm/page.h +++ b/arch/powerpc/include/asm/page.h @@ -344,5 +344,6 @@ typedef struct page *pgtable_t; #include #endif /* __ASSEMBLY__ */ +#include #endif /* _ASM_POWERPC_PAGE_H */ diff --git a/arch/powerpc/include/asm/page_64.h b/arch/powerpc/include/asm/page_64.h index 56234c6fcd61..af04acdb873f 100644 --- a/arch/powerpc/include/asm/page_64.h +++ b/arch/powerpc/include/asm/page_64.h @@ -86,65 +86,6 @@ extern u64 ppc64_pft_size; #endif /* __ASSEMBLY__ */ -#ifdef CONFIG_PPC_MM_SLICES - -#define SLICE_LOW_SHIFT28 -#define SLICE_HIGH_SHIFT 40 - -#define SLICE_LOW_TOP (0x1ul) -#define SLICE_NUM_LOW (SLICE_LOW_TOP >> SLICE_LOW_SHIFT) -#define SLICE_NUM_HIGH (H_PGTABLE_RANGE >> SLICE_HIGH_SHIFT) - -#define GET_LOW_SLICE_INDEX(addr) ((addr) >> SLICE_LOW_SHIFT) -#define GET_HIGH_SLICE_INDEX(addr) ((addr) >> SLICE_HIGH_SHIFT) - -#ifndef __ASSEMBLY__ -struct mm_struct; - -extern unsigned long slice_get_unmapped_area(unsigned long addr, -unsigned long len, -unsigned long flags, -unsigned int psize, -int topdown); - -extern unsigned int get_slice_psize(struct mm_struct *mm, - unsigned long addr); - -extern void slice_set_user_psize(struct mm_struct *mm, unsigned int psize); -extern void slice_set_range_psize(struct mm_struct *mm, unsigned long start, - unsigned long len, unsigned int psize); - -#endif /* __ASSEMBLY__ */ -#else -#define slice_init() -#ifdef CONFIG_PPC_BOOK3S_64 -#define get_slice_psize(mm, addr) ((mm)->context.user_psize) -#define slice_set_user_psize(mm, psize)\ -do { \ -
[PATCH v5 1/6] powerpc/mm/slice: Remove intermediate bitmap copy
bitmap_or() and bitmap_andnot() can work properly with dst identical to src1 or src2. There is no need of an intermediate result bitmap that is copied back to dst in a second step. Signed-off-by: Christophe LeroyReviewed-by: Aneesh Kumar K.V Reviewed-by: Nicholas Piggin --- v2: New in v2 v3: patch moved up front of the serie to avoid ephemeral slice_bitmap_copy() function in following patch v4: No change v5: No change arch/powerpc/mm/slice.c | 12 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c index 23ec2c5e3b78..98b53d48968f 100644 --- a/arch/powerpc/mm/slice.c +++ b/arch/powerpc/mm/slice.c @@ -388,21 +388,17 @@ static unsigned long slice_find_area(struct mm_struct *mm, unsigned long len, static inline void slice_or_mask(struct slice_mask *dst, struct slice_mask *src) { - DECLARE_BITMAP(result, SLICE_NUM_HIGH); - dst->low_slices |= src->low_slices; - bitmap_or(result, dst->high_slices, src->high_slices, SLICE_NUM_HIGH); - bitmap_copy(dst->high_slices, result, SLICE_NUM_HIGH); + bitmap_or(dst->high_slices, dst->high_slices, src->high_slices, + SLICE_NUM_HIGH); } static inline void slice_andnot_mask(struct slice_mask *dst, struct slice_mask *src) { - DECLARE_BITMAP(result, SLICE_NUM_HIGH); - dst->low_slices &= ~src->low_slices; - bitmap_andnot(result, dst->high_slices, src->high_slices, SLICE_NUM_HIGH); - bitmap_copy(dst->high_slices, result, SLICE_NUM_HIGH); + bitmap_andnot(dst->high_slices, dst->high_slices, src->high_slices, + SLICE_NUM_HIGH); } #ifdef CONFIG_PPC_64K_PAGES -- 2.13.3
Re: [PATCH v4.4 backport 3/3] powerpc/64s: Improve RFI L1-D cache flush fallback
On Thu, 22 Feb 2018 23:35:45 +1100 Michael Ellermanwrote: > From: Nicholas Piggin > > commit bdcb1aefc5b3f7d0f1dc8b02673602bca2ff7a4b upstream. > > The fallback RFI flush is used when firmware does not provide a way > to flush the cache. It's a "displacement flush" that evicts useful > data by displacing it with an uninteresting buffer. > > The flush has to take care to work with implementation specific cache > replacment policies, so the recipe has been in flux. The initial > slow but conservative approach is to touch all lines of a congruence > class, with dependencies between each load. It has since been > determined that a linear pattern of loads without dependencies is > sufficient, and is significantly faster. > > Measuring the speed of a null syscall with RFI fallback flush enabled > gives the relative improvement: > > P8 - 1.83x > P9 - 1.75x > > The flush also becomes simpler and more adaptable to different cache > geometries. > > Signed-off-by: Nicholas Piggin > [mpe: Backport to 4.9] > Signed-off-by: Michael Ellerman Thanks for doing these. They all look okay to me. Thanks, Nick
Re: [PATCH v4 2/5] powerpc/mm/slice: Enhance for supporting PPC32
Le 12/02/2018 à 00:34, Nicholas Piggin a écrit : On Sun, 11 Feb 2018 21:04:42 +0530 "Aneesh Kumar K.V"wrote: On 02/11/2018 07:29 PM, Nicholas Piggin wrote: On Sat, 10 Feb 2018 13:54:27 +0100 (CET) Christophe Leroy wrote: In preparation for the following patch which will fix an issue on the 8xx by re-using the 'slices', this patch enhances the 'slices' implementation to support 32 bits CPUs. On PPC32, the address space is limited to 4Gbytes, hence only the low slices will be used. This patch moves "slices" functions prototypes from page64.h to slice.h The high slices use bitmaps. As bitmap functions are not prepared to handling bitmaps of size 0, the bitmap_xxx() calls are wrapped into slice_bitmap_xxx() functions which will void on PPC32 On this last point, I think it would be better to put these with the existing slice bitmap functions in slice.c and just have a few #ifdefs for SLICE_NUM_HIGH == 0. We went back and forth with that. IMHO, we should avoid as much #ifdef as possible across platforms. It helps to understand the platform restrictions better as we have less and less access to these platforms. The above change indicates that nohash 32 wants to use the slice code and they have different restrictions. With that we now know that book3s64 and nohash 32 are the two different configs using slice code. I don't think it's the right place to put it. It's not platform dependent so much as it just depends on whether or not you have 0 high slices as a workaround for bitmap API not accepting 0 length. Another platform that uses the slice code would just have to copy and paste either the nop or the bitmap implementation depending if it has high slices. So I don't think it's the right abstraction. And it implies a bitmap operation but it very specifically only works for struct slice_mask.high_slices bitmap, which is not clear. Better to just work with struct slice_mask. Some ifdefs inside .c code for small helper functions like this IMO isn't really a big deal -- it's not worse than having it in headers. You just want to avoid ifdef mess when looking at non-trivial logic. static inline void slice_or_mask(struct slice_mask *dst, struct slice_mask *src) { dst->low_slices |= src->low_slices; #if SLICE_NUM_HIGH > 0 bitmap_or(result, dst->high_slices, src->high_slices, SLICE_NUM_HIGH); #endif } I think that's pretty fine. If you have a singular hatred for ifdef in .c, then if() works just as well. To be honest, I tend to agree with you. Therefore, after a few words with Michael, v5 gets rid of those obscure wrappers to come back to the initial (v1) approach which was to use 'if (SLICE_NUM_HIGH)'. Behind the fact that it in my mind looks cleared in the code than using slice_bitmap_xxx() wrappers, it also has the advantage of significantly reducing the size of the patch, which is a must to be able to get it applied on stable. Christophe
Re: [RFC PATCH v0 2/2] powerpc, drmem: Rename DRMEM_LMB_RESERVED to DRMEM_LMB_ISOLATED
On 02/21/2018 04:36 AM, Bharata B Rao wrote: > Memory hotplug code uses a temporary LMB flags bit DRMEM_LMB_RESERVED > to mark the LMB which is currently undergoing hotplug or unplug. > It is easy to confuse DRMEM_LMB_RESERVED to mean the LMB is reserved > for which a separate flag bit already exists DRCONF_MEM_RESERVED. Since > both DRMEM_LMB_RESERVED and DRCONF_MEM_RESERVED operate on the same > LMB flags word, rename the former to DRMEM_LMB_ISOLATED. > > Signed-off-by: Bharata B RaoReviewed-by: Nathan Fontenot > --- > arch/powerpc/include/asm/drmem.h| 14 - > arch/powerpc/mm/drmem.c | 2 +- > arch/powerpc/platforms/pseries/hotplug-memory.c | 40 > - > 3 files changed, 28 insertions(+), 28 deletions(-) > > diff --git a/arch/powerpc/include/asm/drmem.h > b/arch/powerpc/include/asm/drmem.h > index ce242b9..b3fa3f7 100644 > --- a/arch/powerpc/include/asm/drmem.h > +++ b/arch/powerpc/include/asm/drmem.h > @@ -72,21 +72,21 @@ static inline u32 drmem_lmb_size(void) > return drmem_info->lmb_size; > } > > -#define DRMEM_LMB_RESERVED 0x8000 > +#define DRMEM_LMB_ISOLATED 0x8000 > > -static inline void drmem_mark_lmb_reserved(struct drmem_lmb *lmb) > +static inline void drmem_mark_lmb_isolated(struct drmem_lmb *lmb) > { > - lmb->flags |= DRMEM_LMB_RESERVED; > + lmb->flags |= DRMEM_LMB_ISOLATED; > } > > -static inline void drmem_remove_lmb_reservation(struct drmem_lmb *lmb) > +static inline void drmem_remove_lmb_isolation(struct drmem_lmb *lmb) > { > - lmb->flags &= ~DRMEM_LMB_RESERVED; > + lmb->flags &= ~DRMEM_LMB_ISOLATED; > } > > -static inline bool drmem_lmb_reserved(struct drmem_lmb *lmb) > +static inline bool drmem_lmb_isolated(struct drmem_lmb *lmb) > { > - return lmb->flags & DRMEM_LMB_RESERVED; > + return lmb->flags & DRMEM_LMB_ISOLATED; > } > > u64 drmem_lmb_memory_max(void); > diff --git a/arch/powerpc/mm/drmem.c b/arch/powerpc/mm/drmem.c > index 3f18036..652bf3a 100644 > --- a/arch/powerpc/mm/drmem.c > +++ b/arch/powerpc/mm/drmem.c > @@ -35,7 +35,7 @@ static u32 drmem_lmb_flags(struct drmem_lmb *lmb) >* Return the value of the lmb flags field minus the reserved >* bit used internally for hotplug processing. >*/ > - return lmb->flags & ~DRMEM_LMB_RESERVED; > + return lmb->flags & ~DRMEM_LMB_ISOLATED; > } > > static struct property *clone_property(struct property *prop, u32 prop_sz) > diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c > b/arch/powerpc/platforms/pseries/hotplug-memory.c > index c1578f5..2f5ca29 100644 > --- a/arch/powerpc/platforms/pseries/hotplug-memory.c > +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c > @@ -467,7 +467,7 @@ static int dlpar_memory_remove_by_count(u32 > lmbs_to_remove) > /* Mark this lmb so we can add it later if all of the >* requested LMBs cannot be removed. >*/ > - drmem_mark_lmb_reserved(lmb); > + drmem_mark_lmb_isolated(lmb); > > lmbs_removed++; > if (lmbs_removed == lmbs_to_remove) > @@ -478,7 +478,7 @@ static int dlpar_memory_remove_by_count(u32 > lmbs_to_remove) > pr_err("Memory hot-remove failed, adding LMB's back\n"); > > for_each_drmem_lmb(lmb) { > - if (!drmem_lmb_reserved(lmb)) > + if (!drmem_lmb_isolated(lmb)) > continue; > > rc = dlpar_add_lmb(lmb); > @@ -486,20 +486,20 @@ static int dlpar_memory_remove_by_count(u32 > lmbs_to_remove) > pr_err("Failed to add LMB back, drc index %x\n", > lmb->drc_index); > > - drmem_remove_lmb_reservation(lmb); > + drmem_remove_lmb_isolation(lmb); > } > > rc = -EINVAL; > } else { > for_each_drmem_lmb(lmb) { > - if (!drmem_lmb_reserved(lmb)) > + if (!drmem_lmb_isolated(lmb)) > continue; > > dlpar_release_drc(lmb->drc_index); > pr_info("Memory at %llx was hot-removed\n", > lmb->base_addr); > > - drmem_remove_lmb_reservation(lmb); > + drmem_remove_lmb_isolation(lmb); > } > rc = 0; > } > @@ -608,7 +608,7 @@ static int dlpar_memory_remove_by_ic(u32 lmbs_to_remove, > u32 drc_index) > if (rc) > break; > > - drmem_mark_lmb_reserved(lmb); > + drmem_mark_lmb_isolated(lmb); > } > > if (rc) { > @@ -616,7 +616,7 @@ static int dlpar_memory_remove_by_ic(u32 lmbs_to_remove, > u32 drc_index) > > >
Re: [RFC PATCH v0 1/2] powerpc, drmem: Fix unexpected flag value in ibm, dynamic-memory-v2
On 02/21/2018 04:36 AM, Bharata B Rao wrote: > Memory addtion and removal by count and indexed-count methods > temporarily mark the LMBs that are being added/removed by a special > flag value DRMEM_LMB_RESERVED. Accessing flags value directly at > a few places without proper accessor method is causing two unexpected > side-effects: > > - DRMEM_LMB_RESERVED bit is becoming part of the flags word of > drconf_cell_v2 entries in ibm,dynamic-memory-v2 DT property. > - This results in extra drconf_cell entries in ibm,dynamic-memory-v2. > For example if 1G memory is added, it leads to one entry for 3 LMBs > and 1 separate entry for the last LMB. All the 4 LMBs should be > defined by one entry here. > > Fix this by always accessing the flags by its accessor method > drmem_lmb_flags(). > > Signed-off-by: Bharata B RaoReviewed-by: Nathan Fontenot > --- > arch/powerpc/mm/drmem.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/arch/powerpc/mm/drmem.c b/arch/powerpc/mm/drmem.c > index 916844f..3f18036 100644 > --- a/arch/powerpc/mm/drmem.c > +++ b/arch/powerpc/mm/drmem.c > @@ -98,7 +98,7 @@ static void init_drconf_v2_cell(struct of_drconf_cell_v2 > *dr_cell, > dr_cell->base_addr = cpu_to_be64(lmb->base_addr); > dr_cell->drc_index = cpu_to_be32(lmb->drc_index); > dr_cell->aa_index = cpu_to_be32(lmb->aa_index); > - dr_cell->flags = cpu_to_be32(lmb->flags); > + dr_cell->flags = cpu_to_be32(drmem_lmb_flags(lmb)); > } > > static int drmem_update_dt_v2(struct device_node *memory, > @@ -121,7 +121,7 @@ static int drmem_update_dt_v2(struct device_node *memory, > } > > if (prev_lmb->aa_index != lmb->aa_index || > - prev_lmb->flags != lmb->flags) > + drmem_lmb_flags(prev_lmb) != drmem_lmb_flags(lmb)) > lmb_sets++; > > prev_lmb = lmb; > @@ -150,7 +150,7 @@ static int drmem_update_dt_v2(struct device_node *memory, > } > > if (prev_lmb->aa_index != lmb->aa_index || > - prev_lmb->flags != lmb->flags) { > + drmem_lmb_flags(prev_lmb) != drmem_lmb_flags(lmb)) { > /* end of one set, start of another */ > dr_cell->seq_lmbs = cpu_to_be32(seq_lmbs); > dr_cell++; >
Re: [PATCH 16/18] crypto: talitos - do hw_context DMA mapping outside the requests
On Thu, Feb 22, 2018 at 12:29:28PM +, Horia Geantă wrote: > > IIUC this means that there is no room for improvement. > This patch needs to be reverted, to restore previous behaviour when the > hw_context was mapped / unmapped for every request. In general we should avoid trying to do batching in drivers. Such optimisations should instead be done at a higher level. For example, for disk encryption we want to do the aggregation at the block layer rather than the crypto API because that has innate knowledge of the data layout which we can only guess. Cheers, -- Email: Herbert XuHome Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
[PATCH 2/2] powerpc/powernv: Support firmware disable of RFI flush
Some versions of firmware will have a setting that can be configured to disable the RFI flush, add support for it. Fixes: 6e032b350cd1 ("powerpc/powernv: Check device-tree for RFI flush settings") Signed-off-by: Michael Ellerman--- arch/powerpc/platforms/powernv/setup.c | 4 1 file changed, 4 insertions(+) diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index 4fb21e17504a..092715b9674b 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c @@ -80,6 +80,10 @@ static void pnv_setup_rfi_flush(void) if (np && of_property_read_bool(np, "disabled")) enable--; + np = of_get_child_by_name(fw_features, "speculation-policy-favor-security"); + if (np && of_property_read_bool(np, "disabled")) + enable = 0; + of_node_put(np); of_node_put(fw_features); } -- 2.14.1
[PATCH 1/2] powerpc/pseries: Support firmware disable of RFI flush
Some versions of firmware will have a setting that can be configured to disable the RFI flush, add support for it. Fixes: 8989d56878a7 ("powerpc/pseries: Query hypervisor for RFI flush settings") Signed-off-by: Michael Ellerman--- arch/powerpc/platforms/pseries/setup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 372d7ada1a0c..1a527625acf7 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -482,7 +482,8 @@ static void pseries_setup_rfi_flush(void) if (types == L1D_FLUSH_NONE) types = L1D_FLUSH_FALLBACK; - if (!(result.behaviour & H_CPU_BEHAV_L1D_FLUSH_PR)) + if ((!(result.behaviour & H_CPU_BEHAV_L1D_FLUSH_PR)) || + (!(result.behaviour & H_CPU_BEHAV_FAVOUR_SECURITY))) enable = false; } else { /* Default to fallback if case hcall is not available */ -- 2.14.1
Applied "ASoC: fsl_ssi: Redefine RX and TX macros" to the asoc tree
The patch ASoC: fsl_ssi: Redefine RX and TX macros has been applied to the asoc tree at https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From 1476105c3f4a6b8f0c6c1fe07295fc85cbffbd83 Mon Sep 17 00:00:00 2001 From: Nicolin ChenDate: Mon, 12 Feb 2018 14:03:09 -0800 Subject: [PATCH] ASoC: fsl_ssi: Redefine RX and TX macros The RX and TX macros were defined implicitly and there was a potential risk if someone changes their values. Since they were defined to index the array ssi->regvals[2], this patch moves these two macros to fsl_ssi.c, closer to its owner ssi->regvals. And it also puts some comments here to limit their value within [0, 1]. Signed-off-by: Nicolin Chen Tested-by: Caleb Crome Tested-by: Maciej S. Szmigiero Reviewed-by: Maciej S. Szmigiero Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 4 sound/soc/fsl/fsl_ssi.h | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 24fb672f3c65..3c8dd609e42e 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -56,6 +56,10 @@ #include "fsl_ssi.h" #include "imx-pcm.h" +/* Define RX and TX to index ssi->regvals array; Can be 0 or 1 only */ +#define RX 0 +#define TX 1 + /** * FSLSSI_I2S_FORMATS: audio formats supported by the SSI * diff --git a/sound/soc/fsl/fsl_ssi.h b/sound/soc/fsl/fsl_ssi.h index de2fdc5db726..18f8dd5209d5 100644 --- a/sound/soc/fsl/fsl_ssi.h +++ b/sound/soc/fsl/fsl_ssi.h @@ -12,9 +12,6 @@ #ifndef _MPC8610_I2S_H #define _MPC8610_I2S_H -#define RX 0 -#define TX 1 - /* -- SSI Register Map -- */ /* SSI Transmit Data Register 0 */ -- 2.16.1
Applied "ASoC: fsl_ssi: Keep ssi->i2s_net updated" to the asoc tree
The patch ASoC: fsl_ssi: Keep ssi->i2s_net updated has been applied to the asoc tree at https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From ebf08ae3bc906fc5dd33d02977efa5d4b9831517 Mon Sep 17 00:00:00 2001 From: Nicolin ChenDate: Mon, 12 Feb 2018 14:03:10 -0800 Subject: [PATCH] ASoC: fsl_ssi: Keep ssi->i2s_net updated The hw_params() overwrites i2s_net settings for special cases like mono-channel support, however, it doesn't update ssi->i2s_net as set_dai_fmt() does. This patch removes the local i2s_net variable and directly updates ssi->i2s_net in the hw_params() so that the driver can simply look up the ssi->i2s_net instead of reading the register. Signed-off-by: Nicolin Chen Tested-by: Caleb Crome Tested-by: Maciej S. Szmigiero Reviewed-by: Maciej S. Szmigiero Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 3c8dd609e42e..d4f1f0d64136 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -838,16 +838,16 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, } if (!fsl_ssi_is_ac97(ssi)) { - u8 i2s_net; /* Normal + Network mode to send 16-bit data in 32-bit frames */ if (fsl_ssi_is_i2s_cbm_cfs(ssi) && sample_size == 16) - i2s_net = SSI_SCR_I2S_MODE_NORMAL | SSI_SCR_NET; - else - i2s_net = ssi->i2s_net; + ssi->i2s_net = SSI_SCR_I2S_MODE_NORMAL | SSI_SCR_NET; + + /* Use Normal mode to send mono data at 1st slot of 2 slots */ + if (channels == 1) + ssi->i2s_net = SSI_SCR_I2S_MODE_NORMAL; regmap_update_bits(regs, REG_SSI_SCR, - SSI_SCR_I2S_NET_MASK, - channels == 1 ? 0 : i2s_net); + SSI_SCR_I2S_NET_MASK, ssi->i2s_net); } /* In synchronous mode, the SSI uses STCCR for capture */ -- 2.16.1
Applied "ASoC: fsl_ssi: Clean up set_dai_tdm_slot()" to the asoc tree
The patch ASoC: fsl_ssi: Clean up set_dai_tdm_slot() has been applied to the asoc tree at https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From 09947634829ccc5568a80ac02c3395a8b77276c1 Mon Sep 17 00:00:00 2001 From: Nicolin ChenDate: Mon, 12 Feb 2018 14:03:11 -0800 Subject: [PATCH] ASoC: fsl_ssi: Clean up set_dai_tdm_slot() This patch replaces the register read with ssi->i2s_net for simplification. It also removes masking SSIEN from scr value since it's handled later by regmap_update_bits() to set this scr value back. Signed-off-by: Nicolin Chen Tested-by: Caleb Crome Tested-by: Maciej S. Szmigiero Reviewed-by: Maciej S. Szmigiero Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index d4f1f0d64136..14046c32dc07 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -1055,9 +1055,7 @@ static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, } /* The slot number should be >= 2 if using Network mode or I2S mode */ - regmap_read(regs, REG_SSI_SCR, ); - val &= SSI_SCR_I2S_MODE_MASK | SSI_SCR_NET; - if (val && slots < 2) { + if (ssi->i2s_net && slots < 2) { dev_err(dai->dev, "slot number should be >= 2 in I2S or NET\n"); return -EINVAL; } @@ -1067,9 +1065,8 @@ static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, regmap_update_bits(regs, REG_SSI_SRCCR, SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(slots)); - /* Save SSIEN bit of the SCR register */ + /* Save the SCR register value */ regmap_read(regs, REG_SSI_SCR, ); - val &= SSI_SCR_SSIEN; /* Temporarily enable SSI to allow SxMSKs to be configurable */ regmap_update_bits(regs, REG_SSI_SCR, SSI_SCR_SSIEN, SSI_SCR_SSIEN); -- 2.16.1
Applied "ASoC: fsl_ssi: Maintain a mask of active streams" to the asoc tree
The patch ASoC: fsl_ssi: Maintain a mask of active streams has been applied to the asoc tree at https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From e0582731abe004163e78ad2dac4cd1196db0908f Mon Sep 17 00:00:00 2001 From: Nicolin ChenDate: Mon, 12 Feb 2018 14:03:12 -0800 Subject: [PATCH] ASoC: fsl_ssi: Maintain a mask of active streams Checking TE and RE bits in SCR register doesn't work for AC97 mode which enables SSIEN, TE and RE in the fsl_ssi_setup_ac97() that's called during probe(). So when running into the trigger(), it will always get the result of both TE and RE being enabled already, even if actually there is no active stream. This patch fixes this issue by adding a variable to log the active streams manually. Signed-off-by: Nicolin Chen Tested-by: Caleb Crome Tested-by: Maciej S. Szmigiero Reviewed-by: Maciej S. Szmigiero Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 15 +++ 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 14046c32dc07..b277a563ff48 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -205,6 +205,7 @@ struct fsl_ssi_soc_data { * @cpu_dai_drv: CPU DAI driver for this device * * @dai_fmt: DAI configuration this device is currently used with + * @streams: Mask of current active streams: BIT(TX) and BIT(RX) * @i2s_net: I2S and Network mode configurations of SCR register * @use_dma: DMA is used or FIQ with stream filter * @use_dual_fifo: DMA with support for dual FIFO mode @@ -249,6 +250,7 @@ struct fsl_ssi { struct snd_soc_dai_driver cpu_dai_drv; unsigned int dai_fmt; + u8 streams; u8 i2s_net; bool use_dma; bool use_dual_fifo; @@ -444,15 +446,14 @@ static void fsl_ssi_fifo_clear(struct fsl_ssi *ssi, bool is_rx) static void fsl_ssi_config(struct fsl_ssi *ssi, bool enable, struct fsl_ssi_regvals *vals) { + int dir = (>regvals[TX] == vals) ? TX : RX; struct regmap *regs = ssi->regs; struct fsl_ssi_regvals *avals; int nr_active_streams; - u32 scr; int keep_active; - regmap_read(regs, REG_SSI_SCR, ); - - nr_active_streams = !!(scr & SSI_SCR_TE) + !!(scr & SSI_SCR_RE); + nr_active_streams = !!(ssi->streams & BIT(TX)) + + !!(ssi->streams & BIT(RX)); if (nr_active_streams - 1 > 0) keep_active = 1; @@ -474,6 +475,9 @@ static void fsl_ssi_config(struct fsl_ssi *ssi, bool enable, keep_active); /* Safely disable SCR register for the stream */ regmap_update_bits(regs, REG_SSI_SCR, scr, 0); + + /* Log the disabled stream to the mask */ + ssi->streams &= ~BIT(dir); } /* @@ -549,6 +553,9 @@ static void fsl_ssi_config(struct fsl_ssi *ssi, bool enable, } /* Enable all remaining bits */ regmap_update_bits(regs, REG_SSI_SCR, vals->scr, vals->scr); + + /* Log the enabled stream to the mask */ + ssi->streams |= BIT(dir); } } -- 2.16.1
Applied "ASoC: fsl_ssi: Rename fsl_ssi_disable_val macro" to the asoc tree
The patch ASoC: fsl_ssi: Rename fsl_ssi_disable_val macro has been applied to the asoc tree at https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From 06a994540505a9ce7028d9e801c52f967654b836 Mon Sep 17 00:00:00 2001 From: Nicolin ChenDate: Mon, 12 Feb 2018 14:03:13 -0800 Subject: [PATCH] ASoC: fsl_ssi: Rename fsl_ssi_disable_val macro The define of fsl_ssi_disable_val is not so clear as it mixes two steps of calculations together. And those parameter names are also a bit long to read. Since it just tries to exclude the shared bits from the regvals of current stream while the opposite stream is active, it's better to use something like ssi_excl_shared_bits. This patch also bisects fsl_ssi_disable_val into two macros of two corresponding steps and then shortens its parameter names. It also updates callers in the fsl_ssi_config() accordingly. Signed-off-by: Nicolin Chen Tested-by: Caleb Crome Tested-by: Maciej S. Szmigiero Reviewed-by: Maciej S. Szmigiero Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 55 + 1 file changed, 23 insertions(+), 32 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index b277a563ff48..0d8c800db0b3 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -421,24 +421,24 @@ static void fsl_ssi_fifo_clear(struct fsl_ssi *ssi, bool is_rx) } /** - * Calculate the bits that have to be disabled for the current stream that is - * getting disabled. This keeps the bits enabled that are necessary for the - * second stream to work if 'stream_active' is true. + * Exclude bits that are used by the opposite stream * - * Detailed calculation: - * These are the values that need to be active after disabling. For non-active - * second stream, this is 0: - * vals_stream * !!stream_active + * When both streams are active, disabling some bits for the current stream + * might break the other stream if these bits are used by it. * - * The following computes the overall differences between the setup for the - * to-disable stream and the active stream, a simple XOR: - * vals_disable ^ (vals_stream * !!(stream_active)) + * @vals : regvals of the current stream + * @avals: regvals of the opposite stream + * @aactive: active state of the opposite stream * - * The full expression adds a mask on all values we care about + * 1) XOR vals and avals to get the differences if the other stream is active; + * Otherwise, return current vals if the other stream is not active + * 2) AND the result of 1) with the current vals */ -#define fsl_ssi_disable_val(vals_disable, vals_stream, stream_active) \ - ((vals_disable) & \ -((vals_disable) ^ ((vals_stream) * (u32)!!(stream_active +#define _ssi_xor_shared_bits(vals, avals, aactive) \ + ((vals) ^ ((avals) * (aactive))) + +#define ssi_excl_shared_bits(vals, avals, aactive) \ + ((vals) & _ssi_xor_shared_bits(vals, avals, aactive)) /** * Enable or disable SSI configuration. @@ -446,19 +446,14 @@ static void fsl_ssi_fifo_clear(struct fsl_ssi *ssi, bool is_rx) static void fsl_ssi_config(struct fsl_ssi *ssi, bool enable, struct fsl_ssi_regvals *vals) { + int adir = (>regvals[TX] == vals) ? RX : TX; int dir = (>regvals[TX] == vals) ? TX : RX; struct regmap *regs = ssi->regs; struct fsl_ssi_regvals *avals; - int nr_active_streams; - int keep_active; - - nr_active_streams = !!(ssi->streams & BIT(TX)) + - !!(ssi->streams & BIT(RX)); + bool aactive; - if (nr_active_streams - 1 > 0) - keep_active = 1; - else - keep_active = 0; + /* Check if the opposite stream is active */ + aactive = ssi->streams & BIT(adir); /* Get the opposite direction to keep its values untouched */ if (>regvals[RX] == vals) @@ -471,8 +466,7 @@ static void fsl_ssi_config(struct fsl_ssi *ssi, bool enable, * To keep the other stream
Applied "ASoC: fsl_ssi: Clean up helper functions of trigger()" to the asoc tree
The patch ASoC: fsl_ssi: Clean up helper functions of trigger() has been applied to the asoc tree at https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From 7d67bcb669bc92d5de037c7dadcebaf0c8f5ad24 Mon Sep 17 00:00:00 2001 From: Nicolin ChenDate: Mon, 12 Feb 2018 14:03:15 -0800 Subject: [PATCH] ASoC: fsl_ssi: Clean up helper functions of trigger() The trigger() calls fsl_ssi_tx_config() and fsl_ssi_rx_config(), and both of them jump to fsl_ssi_config(). And fsl_ssi_config() later calls another fsl_ssi_rxtx_config(). However, the whole routine, especially fsl_ssi_config() function, is too complicated because of the folowing reasons: 1) It has to handle the concern of the opposite stream. 2) It has to handle cases of offline configurations support. 3) It has to handle enable and disable operations while they're mostly different. Since the enable and disable routines have more differences than TX and RX rountines, this patch simplifies these helper functions with the following changes: - Changing to two helper functions of enable and disable instead of TX and RX. - Removing fsl_ssi_rxtx_config() by separately integrating it to two newly introduced enable & disable functions. Signed-off-by: Nicolin Chen Tested-by: Caleb Crome Tested-by: Maciej S. Szmigiero Reviewed-by: Maciej S. Szmigiero Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 256 +++- 1 file changed, 122 insertions(+), 134 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index d276b78684e4..9f024a9afaa5 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -382,31 +382,83 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) } /** - * Enable or disable all rx/tx config flags at once + * Set SCR, SIER, STCR and SRCR registers with cached values in regvals + * + * Notes: + * 1) For offline_config SoCs, enable all necessary bits of both streams + *when 1st stream starts, even if the opposite stream will not start + * 2) It also clears FIFO before setting regvals; SOR is safe to set online */ -static void fsl_ssi_rxtx_config(struct fsl_ssi *ssi, bool enable) +static void fsl_ssi_config_enable(struct fsl_ssi *ssi, bool tx) { - struct regmap *regs = ssi->regs; struct fsl_ssi_regvals *vals = ssi->regvals; + int dir = tx ? TX : RX; + u32 sier, srcr, stcr; - if (enable) { - regmap_update_bits(regs, REG_SSI_SIER, - vals[RX].sier | vals[TX].sier, - vals[RX].sier | vals[TX].sier); - regmap_update_bits(regs, REG_SSI_SRCR, - vals[RX].srcr | vals[TX].srcr, - vals[RX].srcr | vals[TX].srcr); - regmap_update_bits(regs, REG_SSI_STCR, - vals[RX].stcr | vals[TX].stcr, - vals[RX].stcr | vals[TX].stcr); + /* Clear dirty data in the FIFO; It also prevents channel slipping */ + regmap_update_bits(ssi->regs, REG_SSI_SOR, + SSI_SOR_xX_CLR(tx), SSI_SOR_xX_CLR(tx)); + + /* +* On offline_config SoCs, SxCR and SIER are already configured when +* the previous stream started. So skip all SxCR and SIER settings +* to prevent online reconfigurations, then jump to set SCR directly +*/ + if (ssi->soc->offline_config && ssi->streams) + goto enable_scr; + + if (ssi->soc->offline_config) { + /* +* Online reconfiguration not supported, so enable all bits for +* both streams at once to avoid necessity of reconfigurations +*/ + srcr = vals[RX].srcr | vals[TX].srcr; + stcr = vals[RX].stcr | vals[TX].stcr; + sier = vals[RX].sier | vals[TX].sier; } else { - regmap_update_bits(regs, REG_SSI_SRCR, - vals[RX].srcr | vals[TX].srcr,
Applied "ASoC: fsl_ssi: Add DAIFMT define for AC97" to the asoc tree
The patch ASoC: fsl_ssi: Add DAIFMT define for AC97 has been applied to the asoc tree at https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From b6c93f7f60a0d0b61c1fce2872b9d4f7263d6ec2 Mon Sep 17 00:00:00 2001 From: Nicolin ChenDate: Mon, 12 Feb 2018 14:03:16 -0800 Subject: [PATCH] ASoC: fsl_ssi: Add DAIFMT define for AC97 The _fsl_ssi_set_dai_fmt() bypasses an undefined format for AC97 mode. However, it's not really necessary if AC97 has its complete format defined. So this patch adds a DAIFMT macro of complete format including a clock direction and polarity. Signed-off-by: Nicolin Chen Tested-by: Caleb Crome Tested-by: Maciej S. Szmigiero Reviewed-by: Maciej S. Szmigiero Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 15 --- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 9f024a9afaa5..fc5768d243d1 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -90,6 +90,16 @@ SNDRV_PCM_FMTBIT_S24_LE) #endif +/* + * In AC97 mode, TXDIR bit is forced to 0 and TFDIR bit is forced to 1: + * - SSI inputs external bit clock and outputs frame sync clock -- CBM_CFS + * - Also have NB_NF to mark these two clocks will not be inverted + */ +#define FSLSSI_AC97_DAIFMT \ + (SND_SOC_DAIFMT_AC97 | \ +SND_SOC_DAIFMT_CBM_CFS | \ +SND_SOC_DAIFMT_NB_NF) + #define FSLSSI_SIER_DBG_RX_FLAGS \ (SSI_SIER_RFF0_EN | \ SSI_SIER_RLS_EN | \ @@ -964,8 +974,7 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev, scr &= ~SSI_SCR_SYS_CLK_EN; break; default: - if (!fsl_ssi_is_ac97(ssi)) - return -EINVAL; + return -EINVAL; } stcr |= strcr; @@ -1372,7 +1381,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) sprop = of_get_property(np, "fsl,mode", NULL); if (sprop) { if (!strcmp(sprop, "ac97-slave")) - ssi->dai_fmt = SND_SOC_DAIFMT_AC97; + ssi->dai_fmt = FSLSSI_AC97_DAIFMT; } /* Select DMA or FIQ */ -- 2.16.1
Applied "ASoC: fsl_ssi: Clean up fsl_ssi_setup_regvals()" to the asoc tree
The patch ASoC: fsl_ssi: Clean up fsl_ssi_setup_regvals() has been applied to the asoc tree at https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From 501bc1d70cf5ba8ccd9775ce987c90485034464e Mon Sep 17 00:00:00 2001 From: Nicolin ChenDate: Mon, 12 Feb 2018 14:03:17 -0800 Subject: [PATCH] ASoC: fsl_ssi: Clean up fsl_ssi_setup_regvals() This patch cleans fsl_ssi_setup_regvals() by following changes: 1) Moving DBG bits to the first lines. 2) Setting SSIE, RE/TE as default and cleaning it for AC97 Signed-off-by: Nicolin Chen Tested-by: Caleb Crome Tested-by: Maciej S. Szmigiero Reviewed-by: Maciej S. Szmigiero Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 17 ++--- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index fc5768d243d1..156f5132feba 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -580,18 +580,16 @@ static void fsl_ssi_setup_regvals(struct fsl_ssi *ssi) { struct fsl_ssi_regvals *vals = ssi->regvals; - vals[RX].sier = SSI_SIER_RFF0_EN; + vals[RX].sier = SSI_SIER_RFF0_EN | FSLSSI_SIER_DBG_RX_FLAGS; vals[RX].srcr = SSI_SRCR_RFEN0; - vals[RX].scr = 0; - vals[TX].sier = SSI_SIER_TFE0_EN; + vals[RX].scr = SSI_SCR_SSIEN | SSI_SCR_RE; + vals[TX].sier = SSI_SIER_TFE0_EN | FSLSSI_SIER_DBG_TX_FLAGS; vals[TX].stcr = SSI_STCR_TFEN0; - vals[TX].scr = 0; + vals[TX].scr = SSI_SCR_SSIEN | SSI_SCR_TE; /* AC97 has already enabled SSIEN, RE and TE, so ignore them */ - if (!fsl_ssi_is_ac97(ssi)) { - vals[RX].scr = SSI_SCR_SSIEN | SSI_SCR_RE; - vals[TX].scr = SSI_SCR_SSIEN | SSI_SCR_TE; - } + if (fsl_ssi_is_ac97(ssi)) + vals[RX].scr = vals[TX].scr = 0; if (ssi->use_dma) { vals[RX].sier |= SSI_SIER_RDMAE; @@ -600,9 +598,6 @@ static void fsl_ssi_setup_regvals(struct fsl_ssi *ssi) vals[RX].sier |= SSI_SIER_RIE; vals[TX].sier |= SSI_SIER_TIE; } - - vals[RX].sier |= FSLSSI_SIER_DBG_RX_FLAGS; - vals[TX].sier |= FSLSSI_SIER_DBG_TX_FLAGS; } static void fsl_ssi_setup_ac97(struct fsl_ssi *ssi) -- 2.16.1
Applied "ASoC: fsl_ssi: Set xFEN0 and xFEN1 together" to the asoc tree
The patch ASoC: fsl_ssi: Set xFEN0 and xFEN1 together has been applied to the asoc tree at https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From 702d7965e402a8dcd88e964fd5bba6f5f159d625 Mon Sep 17 00:00:00 2001 From: Nicolin ChenDate: Mon, 12 Feb 2018 14:03:18 -0800 Subject: [PATCH] ASoC: fsl_ssi: Set xFEN0 and xFEN1 together It'd be safer to enable both FIFOs for TX or RX at the same time. Signed-off-by: Nicolin Chen Tested-by: Caleb Crome Tested-by: Maciej S. Szmigiero Reviewed-by: Maciej S. Szmigiero Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 156f5132feba..00dfdc77b567 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -591,6 +591,11 @@ static void fsl_ssi_setup_regvals(struct fsl_ssi *ssi) if (fsl_ssi_is_ac97(ssi)) vals[RX].scr = vals[TX].scr = 0; + if (ssi->use_dual_fifo) { + vals[RX].srcr |= SSI_SRCR_RFEN1; + vals[TX].stcr |= SSI_STCR_TFEN1; + } + if (ssi->use_dma) { vals[RX].sier |= SSI_SIER_RDMAE; vals[TX].sier |= SSI_SIER_TDMAE; @@ -991,14 +996,9 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev, SSI_SFCSR_TFWM0(wm) | SSI_SFCSR_RFWM0(wm) | SSI_SFCSR_TFWM1(wm) | SSI_SFCSR_RFWM1(wm)); - if (ssi->use_dual_fifo) { - regmap_update_bits(regs, REG_SSI_SRCR, - SSI_SRCR_RFEN1, SSI_SRCR_RFEN1); - regmap_update_bits(regs, REG_SSI_STCR, - SSI_STCR_TFEN1, SSI_STCR_TFEN1); + if (ssi->use_dual_fifo) regmap_update_bits(regs, REG_SSI_SCR, SSI_SCR_TCH_EN, SSI_SCR_TCH_EN); - } if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_AC97) fsl_ssi_setup_ac97(ssi); -- 2.16.1
Applied "ASoC: fsl_ssi: Use snd_soc_init_dma_data instead" to the asoc tree
The patch ASoC: fsl_ssi: Use snd_soc_init_dma_data instead has been applied to the asoc tree at https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From 40f2563377006b14b94a4f5e9547b8e4498125af Mon Sep 17 00:00:00 2001 From: Nicolin ChenDate: Mon, 12 Feb 2018 14:03:19 -0800 Subject: [PATCH] ASoC: fsl_ssi: Use snd_soc_init_dma_data instead Since there is a helper function, use it to help readability. Signed-off-by: Nicolin Chen Tested-by: Caleb Crome Tested-by: Maciej S. Szmigiero Reviewed-by: Maciej S. Szmigiero Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 00dfdc77b567..7e15b30d4f94 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -1110,10 +1110,9 @@ static int fsl_ssi_dai_probe(struct snd_soc_dai *dai) { struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai); - if (ssi->soc->imx && ssi->use_dma) { - dai->playback_dma_data = >dma_params_tx; - dai->capture_dma_data = >dma_params_rx; - } + if (ssi->soc->imx && ssi->use_dma) + snd_soc_dai_init_dma_data(dai, >dma_params_tx, + >dma_params_rx); return 0; } -- 2.16.1
Applied "ASoC: fsl_ssi: Clean up _fsl_ssi_set_dai_fmt()" to the asoc tree
The patch ASoC: fsl_ssi: Clean up _fsl_ssi_set_dai_fmt() has been applied to the asoc tree at https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From 26b31f4f7d7905f67b6faa52ef147595341134c5 Mon Sep 17 00:00:00 2001 From: Nicolin ChenDate: Mon, 12 Feb 2018 14:03:22 -0800 Subject: [PATCH] ASoC: fsl_ssi: Clean up _fsl_ssi_set_dai_fmt() The _fsl_ssi_set_dai_fmt() is a helper function being called from fsl_ssi_set_dai_fmt() as an ASoC operation and fsl_ssi_hw_init() mainly for AC97 format initialization. This patch cleans the _fsl_ssi_set_dai_fmt() in following ways: * Removing *dev pointer in the parameters as it's included in the *ssi pointer of struct fsl_ssi. * Using regmap_update_bits() instead of regmap_read() with masking the value manually. * Moving baudclk check to the switch-case routine to skip the I2S master check. And moving SxCCR.DC settings after baudclk check. * Adding format settings for SND_SOC_DAIFMT_AC97 like others. Signed-off-by: Nicolin Chen Tested-by: Caleb Crome Tested-by: Maciej S. Szmigiero Reviewed-by: Maciej S. Szmigiero Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 74 +++-- 1 file changed, 35 insertions(+), 39 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index dfb0da3cedda..ed9102d91cf5 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -860,42 +860,31 @@ static int fsl_ssi_hw_free(struct snd_pcm_substream *substream, return 0; } -static int _fsl_ssi_set_dai_fmt(struct device *dev, - struct fsl_ssi *ssi, unsigned int fmt) +static int _fsl_ssi_set_dai_fmt(struct fsl_ssi *ssi, unsigned int fmt) { - struct regmap *regs = ssi->regs; - u32 strcr = 0, stcr, srcr, scr, mask; + u32 strcr = 0, scr = 0, stcr, srcr, mask; ssi->dai_fmt = fmt; - if (fsl_ssi_is_i2s_master(ssi) && IS_ERR(ssi->baudclk)) { - dev_err(dev, "missing baudclk for master mode\n"); - return -EINVAL; - } - - regmap_read(regs, REG_SSI_SCR, ); - scr &= ~(SSI_SCR_SYN | SSI_SCR_I2S_MODE_MASK); /* Synchronize frame sync clock for TE to avoid data slipping */ scr |= SSI_SCR_SYNC_TX_FS; - mask = SSI_STCR_TXBIT0 | SSI_STCR_TFDIR | SSI_STCR_TXDIR | - SSI_STCR_TSCKP | SSI_STCR_TFSI | SSI_STCR_TFSL | SSI_STCR_TEFS; - regmap_read(regs, REG_SSI_STCR, ); - regmap_read(regs, REG_SSI_SRCR, ); - stcr &= ~mask; - srcr &= ~mask; + /* Set to default shifting settings: LSB_ALIGNED */ + strcr |= SSI_STCR_TXBIT0; /* Use Network mode as default */ ssi->i2s_net = SSI_SCR_NET; switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: - regmap_update_bits(regs, REG_SSI_STCCR, - SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(2)); - regmap_update_bits(regs, REG_SSI_SRCCR, - SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(2)); switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFS: case SND_SOC_DAIFMT_CBS_CFS: + if (IS_ERR(ssi->baudclk)) { + dev_err(ssi->dev, + "missing baudclk for master mode\n"); + return -EINVAL; + } + /* fall through */ + case SND_SOC_DAIFMT_CBM_CFS: ssi->i2s_net |= SSI_SCR_I2S_MODE_MASTER; break; case SND_SOC_DAIFMT_CBM_CFM: @@ -905,30 +894,34 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev, return -EINVAL; } + regmap_update_bits(ssi->regs, REG_SSI_STCCR, + SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(2)); + regmap_update_bits(ssi->regs, REG_SSI_SRCCR, +
Applied "ASoC: fsl_ssi: Move DT related code to a separate probe()" to the asoc tree
The patch ASoC: fsl_ssi: Move DT related code to a separate probe() has been applied to the asoc tree at https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From 76f3845110d7d40eb60c12bc64cdfe431a985947 Mon Sep 17 00:00:00 2001 From: Nicolin ChenDate: Mon, 12 Feb 2018 14:03:24 -0800 Subject: [PATCH] ASoC: fsl_ssi: Move DT related code to a separate probe() This patch cleans up probe() function by moving all Device Tree related code into a separate function. It allows the probe() to be Device Tree independent. This will be very useful for future integration of imx-ssi driver which has similar functionalities while exists only because it supports non-DT cases. This patch also moves symmetric_channels of AC97 from the probe to the structure snd_soc_dai_driver for simplification. Additionally, since PowerPC and AC97 use the same pdev pointer to register a platform device, this patch also unifies related code. Signed-off-by: Nicolin Chen Tested-by: Caleb Crome Tested-by: Maciej S. Szmigiero Reviewed-by: Maciej S. Szmigiero Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 219 +++- 1 file changed, 124 insertions(+), 95 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index b58fabe77c6f..5bc67ad8000f 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -239,8 +239,12 @@ struct fsl_ssi_soc_data { * * @fiq_params: FIQ stream filtering parameters * - * @pdev: Pointer to pdev when using fsl-ssi as sound card (ppc only) - *TODO: Should be replaced with simple-sound-card + * @card_pdev: Platform_device pointer to register a sound card for PowerPC or + * to register a CODEC platform device for AC97 + * @card_name: Platform_device name to register a sound card for PowerPC or + * to register a CODEC platform device for AC97 + * @card_idx: The index of SSI to register a sound card for PowerPC or + *to register a CODEC platform device for AC97 * * @dbg_stats: Debugging statistics * @@ -285,7 +289,9 @@ struct fsl_ssi { struct imx_pcm_fiq_params fiq_params; - struct platform_device *pdev; + struct platform_device *card_pdev; + char card_name[32]; + u32 card_idx; struct fsl_ssi_dbg dbg_stats; @@ -1134,6 +1140,7 @@ static const struct snd_soc_component_driver fsl_ssi_component = { static struct snd_soc_dai_driver fsl_ssi_ac97_dai = { .bus_control = true, + .symmetric_channels = 1, .probe = fsl_ssi_dai_probe, .playback = { .stream_name = "AC97 Playback", @@ -1291,9 +1298,7 @@ static void make_lowercase(char *s) static int fsl_ssi_imx_probe(struct platform_device *pdev, struct fsl_ssi *ssi, void __iomem *iomem) { - struct device_node *np = pdev->dev.of_node; struct device *dev = >dev; - u32 dmas[4]; int ret; /* Backward compatible for a DT without ipg clock name assigned */ @@ -1327,14 +1332,8 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev, ssi->dma_params_tx.addr = ssi->ssi_phys + REG_SSI_STX0; ssi->dma_params_rx.addr = ssi->ssi_phys + REG_SSI_SRX0; - /* Set to dual FIFO mode according to the SDMA sciprt */ - ret = of_property_read_u32_array(np, "dmas", dmas, 4); - if (ssi->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) { - ssi->use_dual_fifo = true; - /* -* Use even numbers to avoid channel swap due to SDMA -* script design -*/ + /* Use even numbers to avoid channel swap due to SDMA script design */ + if (ssi->use_dual_fifo) { ssi->dma_params_tx.maxburst &= ~0x1; ssi->dma_params_rx.maxburst &= ~0x1; } @@ -1375,41 +1374,109 @@ static void fsl_ssi_imx_clean(struct platform_device *pdev, struct fsl_ssi *ssi) clk_disable_unprepare(ssi->clk); } -static int fsl_ssi_probe(struct platform_device
Applied "ASoC: fsl_ssi: Add bool synchronous to mark synchronous mode" to the asoc tree
The patch ASoC: fsl_ssi: Add bool synchronous to mark synchronous mode has been applied to the asoc tree at https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From badc9595bc15686be3b01e3554421647de348df0 Mon Sep 17 00:00:00 2001 From: Nicolin ChenDate: Mon, 12 Feb 2018 14:03:23 -0800 Subject: [PATCH] ASoC: fsl_ssi: Add bool synchronous to mark synchronous mode Using symmetric_rates in the cpu_dai_drv is a bit implicit, so this patch adds a bool synchronous instead. Signed-off-by: Nicolin Chen Tested-by: Caleb Crome Tested-by: Maciej S. Szmigiero Reviewed-by: Maciej S. Szmigiero Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 13 - 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index ed9102d91cf5..b58fabe77c6f 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -217,6 +217,7 @@ struct fsl_ssi_soc_data { * @dai_fmt: DAI configuration this device is currently used with * @streams: Mask of current active streams: BIT(TX) and BIT(RX) * @i2s_net: I2S and Network mode configurations of SCR register + * @synchronous: Use synchronous mode - both of TX and RX use STCK and SFCK * @use_dma: DMA is used or FIQ with stream filter * @use_dual_fifo: DMA with support for dual FIFO mode * @has_ipg_clk_name: If "ipg" is in the clock name list of device tree @@ -262,6 +263,7 @@ struct fsl_ssi { unsigned int dai_fmt; u8 streams; u8 i2s_net; + bool synchronous; bool use_dma; bool use_dual_fifo; bool has_ipg_clk_name; @@ -673,7 +675,6 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, bool tx2, tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai); struct regmap *regs = ssi->regs; - int synchronous = ssi->cpu_dai_drv.symmetric_rates, ret; u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i; unsigned long clkrate, baudrate, tmprate; unsigned int slots = params_channels(hw_params); @@ -681,6 +682,7 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, u64 sub, savesub = 10; unsigned int freq; bool baudclk_is_used; + int ret; /* Override slots and slot_width if being specifically set... */ if (ssi->slots) @@ -759,7 +761,7 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, mask = SSI_SxCCR_PM_MASK | SSI_SxCCR_DIV2 | SSI_SxCCR_PSR; /* STCCR is used for RX in synchronous mode */ - tx2 = tx || synchronous; + tx2 = tx || ssi->synchronous; regmap_update_bits(regs, REG_SSI_SxCCR(tx2), mask, stccr); if (!baudclk_is_used) { @@ -807,7 +809,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, * that should set separate configurations for STCCR and SRCCR * despite running in the synchronous mode. */ - if (enabled && ssi->cpu_dai_drv.symmetric_rates) + if (enabled && ssi->synchronous) return 0; if (fsl_ssi_is_i2s_master(ssi)) { @@ -839,7 +841,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, } /* In synchronous mode, the SSI uses STCCR for capture */ - tx2 = tx || ssi->cpu_dai_drv.symmetric_rates; + tx2 = tx || ssi->synchronous; regmap_update_bits(regs, REG_SSI_SxCCR(tx2), SSI_SxCCR_WL_MASK, wl); return 0; @@ -968,7 +970,7 @@ static int _fsl_ssi_set_dai_fmt(struct fsl_ssi *ssi, unsigned int fmt) srcr = strcr; /* Set SYN mode and clear RXDIR bit when using SYN or AC97 mode */ - if (ssi->cpu_dai_drv.symmetric_rates || fsl_ssi_is_ac97(ssi)) { + if (ssi->synchronous || fsl_ssi_is_ac97(ssi)) { srcr &= ~SSI_SRCR_RXDIR; scr |= SSI_SCR_SYN; } @@ -1456,6 +1458,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) if (!fsl_ssi_is_ac97(ssi)) {
Applied "ASoC: fsl_ssi: Use ssi->streams instead of reading register" to the asoc tree
The patch ASoC: fsl_ssi: Use ssi->streams instead of reading register has been applied to the asoc tree at https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From 9c4f509a53cbcd968677c7f15c07260dd6c2276c Mon Sep 17 00:00:00 2001 From: Nicolin ChenDate: Mon, 12 Feb 2018 14:03:25 -0800 Subject: [PATCH] ASoC: fsl_ssi: Use ssi->streams instead of reading register Since ssi->streams is being updated along with SCR register and its SSIEN bit, it's simpler to use it instead. Signed-off-by: Nicolin Chen Tested-by: Caleb Crome Tested-by: Maciej S. Szmigiero Reviewed-by: Maciej S. Szmigiero Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 5bc67ad8000f..0823b08923b5 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -803,11 +803,6 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, unsigned int sample_size = params_width(hw_params); u32 wl = SSI_SxCCR_WL(sample_size); int ret; - u32 scr; - int enabled; - - regmap_read(regs, REG_SSI_SCR, ); - enabled = scr & SSI_SCR_SSIEN; /* * SSI is properly configured if it is enabled and running in @@ -815,7 +810,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, * that should set separate configurations for STCCR and SRCCR * despite running in the synchronous mode. */ - if (enabled && ssi->synchronous) + if (ssi->streams && ssi->synchronous) return 0; if (fsl_ssi_is_i2s_master(ssi)) { -- 2.16.1
Re: [PATCH v3 2/4] gpio: Add GPIO driver for Nintendo Wii
On Thu, Feb 22, 2018 at 01:57:07PM +0100, Linus Walleij wrote: > On Fri, Feb 9, 2018 at 1:07 PM, Jonathan Neuschäfer >wrote: > > > The Nintendo Wii's chipset (called "Hollywood") has a GPIO controller > > that supports a configurable number of pins (up to 32), interrupts, and > > some special mechanisms to share the controller between the system's > > security processor (an ARM926) and the PowerPC CPU. Pin multiplexing is > > not supported. > > > > This patch adds a basic driver for this GPIO controller. Interrupt > > support will come in a later patch. > > > > This patch is based on code developed by Albert Herranz and the GameCube > > Linux Team, file arch/powerpc/platforms/embedded6xx/hlwd-gpio.c, > > available at https://github.com/DeltaResero/GC-Wii-Linux-Kernels, but > > has grown quite dissimilar. > > > > Signed-off-by: Jonathan Neuschäfer > > Cc: Albert Herranz > > Cc: Segher Boessenkool > > <--- > > > > v3: > > - Do some style cleanups, as suggest by Andy Shevchenko > > Patch applied to the GPIO tree for v4.17 with all the review tags. > > I just folded the changelog into the commit message, for new > drivers it is sometimes useful to keep these around in > git actually. > > If any further changes are needed we can just patch on top > of this. > > It's a very pretty driver, good work! Thanks! :-) Jonathan Neuschäfer signature.asc Description: PGP signature
Re: samples/seccomp/ broken when cross compiling s390, ppc allyesconfig
On Wed 14-02-18 09:14:47, Kees Cook wrote: [...] > I can send it through my seccomp tree via James Morris. Could you please do it? > > > > From 8d8457e96296538508e478f598d1c8b3406a8626 Mon Sep 17 00:00:00 2001 > > From: Michal Hocko> > Date: Wed, 14 Feb 2018 10:15:12 +0100 > > Subject: [PATCH] samples/seccomp: do not compile when cross compiled > > MIME-Version: 1.0 > > Content-Type: text/plain; charset=UTF-8 > > Content-Transfer-Encoding: 8bit > > > > samples/seccomp relies on the host setting which is not suitable for > > crosscompilation and it actually fails when crosscompiling s390 and > > powerpc all{yes,mod}config on x86_64 with > > > > samples/seccomp/bpf-helper.h:135:2: error: #error __BITS_PER_LONG value > > unusable. > > #error __BITS_PER_LONG value unusable. > > ^ > > In file included from samples/seccomp/bpf-fancy.c:13:0: > > samples/seccomp/bpf-fancy.c: In function ‘main’: > > samples/seccomp/bpf-fancy.c:38:11: error: ‘__NR_exit’ undeclared (first use > > in this function) > >SYSCALL(__NR_exit, ALLOW), > > > > and many others. I am doing these for compile testing and it's been > > quite useful to catch issues. Crosscompiling sample code on the other > > hand doesn't seem all that important so it seems like the easiest way to > > simply disable samples/seccomp when crosscompiling. > > > > Fixing this properly is not that easy as Kees explains: > > : IIRC, one of the problems is with build ordering problems: the kernel > > : headers used by the samples aren't available when cross compiling. > > > > Acked-by: Kees Cook > > Signed-off-by: Michal Hocko > > --- > > samples/seccomp/Makefile | 10 +- > > 1 file changed, 1 insertion(+), 9 deletions(-) > > > > diff --git a/samples/seccomp/Makefile b/samples/seccomp/Makefile > > index 0e349b80686e..ba942e3ead89 100644 > > --- a/samples/seccomp/Makefile > > +++ b/samples/seccomp/Makefile > > @@ -1,4 +1,5 @@ > > # SPDX-License-Identifier: GPL-2.0 > > +ifndef CROSS_COMPILE > > hostprogs-$(CONFIG_SAMPLE_SECCOMP) := bpf-fancy dropper bpf-direct > > > > HOSTCFLAGS_bpf-fancy.o += -I$(objtree)/usr/include > > @@ -16,7 +17,6 @@ HOSTCFLAGS_bpf-direct.o += -idirafter $(objtree)/include > > bpf-direct-objs := bpf-direct.o > > > > # Try to match the kernel target. > > -ifndef CROSS_COMPILE > > ifndef CONFIG_64BIT > > > > # s390 has -m31 flag to build 31 bit binaries > > @@ -35,12 +35,4 @@ HOSTLOADLIBES_bpf-fancy += $(MFLAG) > > HOSTLOADLIBES_dropper += $(MFLAG) > > endif > > always := $(hostprogs-m) > > -else > > -# MIPS system calls are defined based on the -mabi that is passed > > -# to the toolchain which may or may not be a valid option > > -# for the host toolchain. So disable tests if target architecture > > -# is MIPS but the host isn't. > > -ifndef CONFIG_MIPS > > -always := $(hostprogs-m) > > -endif > > endif > > -- > > 2.15.1 > > > > -- > > Michal Hocko > > SUSE Labs > > > > -- > Kees Cook > Pixel Security -- Michal Hocko SUSE Labs
Re: [PATCH v3 2/4] gpio: Add GPIO driver for Nintendo Wii
On Fri, Feb 9, 2018 at 1:07 PM, Jonathan Neuschäferwrote: > The Nintendo Wii's chipset (called "Hollywood") has a GPIO controller > that supports a configurable number of pins (up to 32), interrupts, and > some special mechanisms to share the controller between the system's > security processor (an ARM926) and the PowerPC CPU. Pin multiplexing is > not supported. > > This patch adds a basic driver for this GPIO controller. Interrupt > support will come in a later patch. > > This patch is based on code developed by Albert Herranz and the GameCube > Linux Team, file arch/powerpc/platforms/embedded6xx/hlwd-gpio.c, > available at https://github.com/DeltaResero/GC-Wii-Linux-Kernels, but > has grown quite dissimilar. > > Signed-off-by: Jonathan Neuschäfer > Cc: Albert Herranz > Cc: Segher Boessenkool > <--- > > v3: > - Do some style cleanups, as suggest by Andy Shevchenko Patch applied to the GPIO tree for v4.17 with all the review tags. I just folded the changelog into the commit message, for new drivers it is sometimes useful to keep these around in git actually. If any further changes are needed we can just patch on top of this. It's a very pretty driver, good work! Yours, Linus Walleij
[PATCH v4.4 backport 2/3] powerpc/64s: Simple RFI macro conversions
From: Nicholas Piggincommit 222f20f140623ef6033491d0103ee0875fe87d35 upstream. This commit does simple conversions of rfi/rfid to the new macros that include the expected destination context. By simple we mean cases where there is a single well known destination context, and it's simply a matter of substituting the instruction for the appropriate macro. Signed-off-by: Nicholas Piggin [mpe: Backport to 4.9, use RFI_TO_KERNEL in idle_book3s.S] Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 2 +- arch/powerpc/kernel/entry_64.S | 14 +- arch/powerpc/kernel/exceptions-64s.S | 22 +++--- arch/powerpc/kernel/idle_book3s.S| 7 --- arch/powerpc/kvm/book3s_hv_rmhandlers.S | 7 +++ arch/powerpc/kvm/book3s_rmhandlers.S | 7 +-- arch/powerpc/kvm/book3s_segment.S| 4 ++-- 7 files changed, 35 insertions(+), 28 deletions(-) diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index cab6d2a46c41..903e76a9f158 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -242,7 +242,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) mtspr SPRN_##h##SRR0,r12; \ mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \ mtspr SPRN_##h##SRR1,r10; \ - h##rfid;\ + h##RFI_TO_KERNEL; \ b . /* prevent speculative execution */ #define EXCEPTION_PROLOG_PSERIES_1(label, h) \ __EXCEPTION_PROLOG_PSERIES_1(label, h) diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index c33b69d10919..2dc52e6d2af4 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -39,6 +39,11 @@ #include #include #include +#ifdef CONFIG_PPC_BOOK3S +#include +#else +#include +#endif /* * System calls. @@ -396,8 +401,7 @@ tabort_syscall: mtmsrd r10, 1 mtspr SPRN_SRR0, r11 mtspr SPRN_SRR1, r12 - - rfid + RFI_TO_USER b . /* prevent speculative execution */ #endif @@ -1073,7 +1077,7 @@ _GLOBAL(enter_rtas) mtspr SPRN_SRR0,r5 mtspr SPRN_SRR1,r6 - rfid + RFI_TO_KERNEL b . /* prevent speculative execution */ rtas_return_loc: @@ -1098,7 +1102,7 @@ rtas_return_loc: mtspr SPRN_SRR0,r3 mtspr SPRN_SRR1,r4 - rfid + RFI_TO_KERNEL b . /* prevent speculative execution */ .align 3 @@ -1169,7 +1173,7 @@ _GLOBAL(enter_prom) LOAD_REG_IMMEDIATE(r12, MSR_SF | MSR_ISF | MSR_LE) andcr11,r11,r12 mtsrr1 r11 - rfid + RFI_TO_KERNEL #endif /* CONFIG_PPC_BOOK3E */ 1: /* Return from OF */ diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index d0be752ea86c..29892500e646 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -244,7 +244,7 @@ BEGIN_FTR_SECTION LOAD_HANDLER(r12, machine_check_handle_early) 1: mtspr SPRN_SRR0,r12 mtspr SPRN_SRR1,r11 - rfid + RFI_TO_KERNEL b . /* prevent speculative execution */ 2: /* Stack overflow. Stay on emergency stack and panic. @@ -280,7 +280,7 @@ machine_check_pSeries_0: mtspr SPRN_SRR0,r12 mfspr r12,SPRN_SRR1 mtspr SPRN_SRR1,r10 - rfid + RFI_TO_KERNEL b . /* prevent speculative execution */ TRAMP_KVM_SKIP(PACA_EXMC, 0x200) @@ -446,7 +446,7 @@ EXC_COMMON_BEGIN(machine_check_handle_early) li r3,MSR_ME andcr10,r10,r3 /* Turn off MSR_ME */ mtspr SPRN_SRR1,r10 - rfid + RFI_TO_KERNEL b . 2: /* @@ -464,7 +464,7 @@ EXC_COMMON_BEGIN(machine_check_handle_early) */ bl machine_check_queue_event MACHINE_CHECK_HANDLER_WINDUP - rfid + RFI_TO_USER_OR_KERNEL 9: /* Deliver the machine check to host kernel in V mode. */ MACHINE_CHECK_HANDLER_WINDUP @@ -706,7 +706,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX) mtspr SPRN_SRR0,r10 ld r10,PACAKMSR(r13) mtspr SPRN_SRR1,r10 - rfid + RFI_TO_KERNEL b . EXC_COMMON_BEGIN(unrecov_slb) @@ -893,7 +893,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) \ mtspr SPRN_SRR0,r10 ; \ ld r10,PACAKMSR(r13) ; \ mtspr SPRN_SRR1,r10 ; \ - rfid ;
[PATCH v4.4 backport 3/3] powerpc/64s: Improve RFI L1-D cache flush fallback
From: Nicholas Piggincommit bdcb1aefc5b3f7d0f1dc8b02673602bca2ff7a4b upstream. The fallback RFI flush is used when firmware does not provide a way to flush the cache. It's a "displacement flush" that evicts useful data by displacing it with an uninteresting buffer. The flush has to take care to work with implementation specific cache replacment policies, so the recipe has been in flux. The initial slow but conservative approach is to touch all lines of a congruence class, with dependencies between each load. It has since been determined that a linear pattern of loads without dependencies is sufficient, and is significantly faster. Measuring the speed of a null syscall with RFI fallback flush enabled gives the relative improvement: P8 - 1.83x P9 - 1.75x The flush also becomes simpler and more adaptable to different cache geometries. Signed-off-by: Nicholas Piggin [mpe: Backport to 4.9] Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/paca.h | 3 +- arch/powerpc/kernel/asm-offsets.c| 3 +- arch/powerpc/kernel/exceptions-64s.S | 76 +--- arch/powerpc/kernel/setup_64.c | 13 +- 4 files changed, 39 insertions(+), 56 deletions(-) diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index ea43897183fd..c75ee2d886fc 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h @@ -212,8 +212,7 @@ struct paca_struct { */ u64 exrfi[13] __aligned(0x80); void *rfi_flush_fallback_area; - u64 l1d_flush_congruence; - u64 l1d_flush_sets; + u64 l1d_flush_size; #endif }; diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 64bcbd580495..14fbbd9035ca 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -242,8 +242,7 @@ int main(void) DEFINE(PACA_IN_MCE, offsetof(struct paca_struct, in_mce)); DEFINE(PACA_RFI_FLUSH_FALLBACK_AREA, offsetof(struct paca_struct, rfi_flush_fallback_area)); DEFINE(PACA_EXRFI, offsetof(struct paca_struct, exrfi)); - DEFINE(PACA_L1D_FLUSH_CONGRUENCE, offsetof(struct paca_struct, l1d_flush_congruence)); - DEFINE(PACA_L1D_FLUSH_SETS, offsetof(struct paca_struct, l1d_flush_sets)); + DEFINE(PACA_L1D_FLUSH_SIZE, offsetof(struct paca_struct, l1d_flush_size)); #endif DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id)); DEFINE(PACAKEXECSTATE, offsetof(struct paca_struct, kexec_state)); diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 29892500e646..7614d1dd2c0b 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -1602,39 +1602,37 @@ rfi_flush_fallback: std r9,PACA_EXRFI+EX_R9(r13) std r10,PACA_EXRFI+EX_R10(r13) std r11,PACA_EXRFI+EX_R11(r13) - std r12,PACA_EXRFI+EX_R12(r13) - std r8,PACA_EXRFI+EX_R13(r13) mfctr r9 ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13) - ld r11,PACA_L1D_FLUSH_SETS(r13) - ld r12,PACA_L1D_FLUSH_CONGRUENCE(r13) - /* -* The load adresses are at staggered offsets within cachelines, -* which suits some pipelines better (on others it should not -* hurt). -*/ - addir12,r12,8 + ld r11,PACA_L1D_FLUSH_SIZE(r13) + srdir11,r11,(7 + 3) /* 128 byte lines, unrolled 8x */ mtctr r11 DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */ /* order ld/st prior to dcbt stop all streams with flushing */ sync -1: li r8,0 - .rept 8 /* 8-way set associative */ - ldx r11,r10,r8 - add r8,r8,r12 - xor r11,r11,r11 // Ensure r11 is 0 even if fallback area is not - add r8,r8,r11 // Add 0, this creates a dependency on the ldx - .endr - addir10,r10,128 /* 128 byte cache line */ + + /* +* The load adresses are at staggered offsets within cachelines, +* which suits some pipelines better (on others it should not +* hurt). +*/ +1: + ld r11,(0x80 + 8)*0(r10) + ld r11,(0x80 + 8)*1(r10) + ld r11,(0x80 + 8)*2(r10) + ld r11,(0x80 + 8)*3(r10) + ld r11,(0x80 + 8)*4(r10) + ld r11,(0x80 + 8)*5(r10) + ld r11,(0x80 + 8)*6(r10) + ld r11,(0x80 + 8)*7(r10) + addir10,r10,0x80*8 bdnz1b mtctr r9 ld r9,PACA_EXRFI+EX_R9(r13) ld r10,PACA_EXRFI+EX_R10(r13) ld r11,PACA_EXRFI+EX_R11(r13) - ld r12,PACA_EXRFI+EX_R12(r13) - ld r8,PACA_EXRFI+EX_R13(r13) GET_SCRATCH0(r13); rfid @@ -1645,39 +1643,37 @@ hrfi_flush_fallback: std r9,PACA_EXRFI+EX_R9(r13) std
[PATCH v4.9 backport 1/3] powerpc/64s: Fix conversion of slb_miss_common to use RFI_TO_USER/KERNEL
The back port of commit c7305645eb0c ("powerpc/64s: Convert slb_miss_common to use RFI_TO_USER/KERNEL") missed a hunk needed to restore cr6. Fixes: 48cc95d4e4d6 ("powerpc/64s: Convert slb_miss_common to use RFI_TO_USER/KERNEL") Signed-off-by: Michael Ellerman--- arch/powerpc/kernel/exceptions-64s.S | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 96db6c3adebe..d0be752ea86c 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -680,6 +680,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX) .machine push .machine "power4" mtcrf 0x80,r9 + mtcrf 0x02,r9 /* I/D indication is in cr6 */ mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */ .machine pop -- 2.14.1
Re: [PATCH] PCI/AER: Add a null check before eeh_ops->notify_resume callback.
There is already a patch for this issue applied to ppc-next viz commit 521ca5a9859a870e354d1a6b84a6ff ("powerpc/eeh: Add conditional check on notify_resume"). So please ignore the patch. -- Vaibhav JainLinux Technology Center, IBM India Pvt. Ltd.
Re: [PATCH 16/18] crypto: talitos - do hw_context DMA mapping outside the requests
On 2/22/2018 1:47 PM, Herbert Xu wrote: > On Tue, Feb 20, 2018 at 11:32:25AM +, Horia Geantă wrote: >> >> If final/finup is optional, how is the final hash supposed to be retrieved? > > Sometimes the computation ends with a partial hash, that's what > export is for. Also it is completely legal to abandon the hash > state entirely. > Thanks for the explanation. It's unintuitive to call .init() -> .update() and then not to call any of .final(), .finup(), .export(). Christophe, IIUC this means that there is no room for improvement. This patch needs to be reverted, to restore previous behaviour when the hw_context was mapped / unmapped for every request. Thanks, Horia
[PATCH 5/5] powerpc/mm/32: Remove the reserved memory hack
This hack, introduced in commit c5df7f775148 ("powerpc: allow ioremap within reserved memory regions") is now unnecessary. Signed-off-by: Jonathan Neuschäfer--- arch/powerpc/mm/init_32.c| 5 - arch/powerpc/mm/mmu_decl.h | 1 - arch/powerpc/mm/pgtable_32.c | 3 +-- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index 6419b33ca309..326240177fa6 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c @@ -88,11 +88,6 @@ void MMU_init(void); int __map_without_bats; int __map_without_ltlbs; -/* - * This tells the system to allow ioremapping memory marked as reserved. - */ -int __allow_ioremap_reserved; - /* max amount of low RAM to map in */ unsigned long __max_low_memory = MAX_LOW_MEM; diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index 57fbc554c785..c4c0a09a7775 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h @@ -98,7 +98,6 @@ extern void setbat(int index, unsigned long virt, phys_addr_t phys, unsigned int size, pgprot_t prot); extern int __map_without_bats; -extern int __allow_ioremap_reserved; extern unsigned int rtas_data, rtas_size; struct hash_pte; diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index d54e1a9c1c99..a89eb3b898cd 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -146,8 +146,7 @@ __ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags, /* * Don't allow anybody to remap normal RAM that we're using. */ - if (page_is_ram(__phys_to_pfn(p)) && - !(__allow_ioremap_reserved && memblock_is_region_reserved(p, size))) { + if (page_is_ram(__phys_to_pfn(p))) { printk("__ioremap(): phys addr 0x%llx is RAM lr %ps\n", (unsigned long long)p, __builtin_return_address(0)); return NULL; -- 2.16.1
Re: [RFC][PATCH bpf v2 1/2] bpf: allow 64-bit offsets for bpf function calls
Am Thu, 22 Feb 2018 13:06:40 +0100 schrieb Michael Holzheu: > Am Fri, 16 Feb 2018 21:20:09 +0530 > schrieb "Naveen N. Rao" : > > > Daniel Borkmann wrote: > > > On 02/15/2018 05:25 PM, Daniel Borkmann wrote: > > >> On 02/13/2018 05:05 AM, Sandipan Das wrote: > > >>> The imm field of a bpf_insn is a signed 32-bit integer. For > > >>> JIT-ed bpf-to-bpf function calls, it stores the offset from > > >>> __bpf_call_base to the start of the callee function. > > >>> > > >>> For some architectures, such as powerpc64, it was found that > > >>> this offset may be as large as 64 bits because of which this > > >>> cannot be accomodated in the imm field without truncation. > > >>> > > >>> To resolve this, we additionally make aux->func within each > > >>> bpf_prog associated with the functions to point to the list > > >>> of all function addresses determined by the verifier. > > >>> > > >>> We keep the value assigned to the off field of the bpf_insn > > >>> as a way to index into aux->func and also set aux->func_cnt > > >>> so that this can be used for performing basic upper bound > > >>> checks for the off field. > > >>> > > >>> Signed-off-by: Sandipan Das > > >>> --- > > >>> v2: Make aux->func point to the list of functions determined > > >>> by the verifier rather than allocating a separate callee > > >>> list for each function. > > >> > > >> Approach looks good to me; do you know whether s390x JIT would > > >> have similar requirement? I think one limitation that would still > > >> need to be addressed later with such approach would be regarding the > > >> xlated prog dump in bpftool, see 'BPF calls via JIT' in 7105e828c087 > > >> ("bpf: allow for correlation of maps and helpers in dump"). Any > > >> ideas for this (potentially if we could use off + imm for calls, > > >> we'd get to 48 bits, but that seems still not be enough as you say)? > > > > All good points. I'm not really sure how s390x works, so I can't comment > > on that, but I'm copying Michael Holzheu for his consideration. > > > > With the existing scheme, 48 bits won't be enough, so we rejected that > > approach. I can also see how this will be a problem with bpftool, but I > > haven't looked into it in detail. I wonder if we can annotate the output > > to indicate the function being referred to? > > > > > > > > One other random thought, although I'm not sure how feasible this > > > is for ppc64 JIT to realize ... but idea would be to have something > > > like the below: > > > > > > diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c > > > index 29ca920..daa7258 100644 > > > --- a/kernel/bpf/core.c > > > +++ b/kernel/bpf/core.c > > > @@ -512,6 +512,11 @@ int bpf_get_kallsym(unsigned int symnum, unsigned > > > long *value, char *type, > > > return ret; > > > } > > > > > > +void * __weak bpf_jit_image_alloc(unsigned long size) > > > +{ > > > + return module_alloc(size); > > > +} > > > + > > > struct bpf_binary_header * > > > bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr, > > >unsigned int alignment, > > > @@ -525,7 +530,7 @@ bpf_jit_binary_alloc(unsigned int proglen, u8 > > > **image_ptr, > > >* random section of illegal instructions. > > >*/ > > > size = round_up(proglen + sizeof(*hdr) + 128, PAGE_SIZE); > > > - hdr = module_alloc(size); > > > + hdr = bpf_jit_image_alloc(size); > > > if (hdr == NULL) > > > return NULL; > > > > > > And ppc64 JIT could override bpf_jit_image_alloc() in a similar way > > > like some archs would override the module_alloc() helper through a > > > custom implementation, usually via __vmalloc_node_range(), so we > > > could perhaps fit the range for BPF JITed images in a way that they > > > could use the 32bit imm in the end? There are not that many progs > > > loaded typically, so the range could be a bit narrower in such case > > > anyway. (Not sure if this would work out though, but I thought to > > > bring it up.) > > > > That'd be a good option to consider. I don't think we want to allocate > > anything from the linear memory range since users could load > > unprivileged BPF programs and consume a lot of memory that way. I doubt > > if we can map vmalloc'ed memory into the 0xc0 address range, but I'm not > > entirely sure. > > > > Michael, > > Is the above possible? The question is if we can have BPF programs be > > allocated within 4GB of __bpf_call_base (which is a kernel symbol), so > > that calls to those programs can be encoded in a 32-bit immediate field > > in a BPF instruction. As an extension, we may be able to extend it to > > 48-bits by combining with another BPF instruction field (offset). In > > either case, the vmalloc'ed address range won't work. > > > > The alternative is to pass the full 64-bit address of the BPF program in > > an auxiliary field (as proposed in this patch set) but we need to fix it > > up for 'bpftool' as
Re: [RFC][PATCH bpf v2 1/2] bpf: allow 64-bit offsets for bpf function calls
Am Fri, 16 Feb 2018 21:20:09 +0530 schrieb "Naveen N. Rao": > Daniel Borkmann wrote: > > On 02/15/2018 05:25 PM, Daniel Borkmann wrote: > >> On 02/13/2018 05:05 AM, Sandipan Das wrote: > >>> The imm field of a bpf_insn is a signed 32-bit integer. For > >>> JIT-ed bpf-to-bpf function calls, it stores the offset from > >>> __bpf_call_base to the start of the callee function. > >>> > >>> For some architectures, such as powerpc64, it was found that > >>> this offset may be as large as 64 bits because of which this > >>> cannot be accomodated in the imm field without truncation. > >>> > >>> To resolve this, we additionally make aux->func within each > >>> bpf_prog associated with the functions to point to the list > >>> of all function addresses determined by the verifier. > >>> > >>> We keep the value assigned to the off field of the bpf_insn > >>> as a way to index into aux->func and also set aux->func_cnt > >>> so that this can be used for performing basic upper bound > >>> checks for the off field. > >>> > >>> Signed-off-by: Sandipan Das > >>> --- > >>> v2: Make aux->func point to the list of functions determined > >>> by the verifier rather than allocating a separate callee > >>> list for each function. > >> > >> Approach looks good to me; do you know whether s390x JIT would > >> have similar requirement? I think one limitation that would still > >> need to be addressed later with such approach would be regarding the > >> xlated prog dump in bpftool, see 'BPF calls via JIT' in 7105e828c087 > >> ("bpf: allow for correlation of maps and helpers in dump"). Any > >> ideas for this (potentially if we could use off + imm for calls, > >> we'd get to 48 bits, but that seems still not be enough as you say)? > > All good points. I'm not really sure how s390x works, so I can't comment > on that, but I'm copying Michael Holzheu for his consideration. > > With the existing scheme, 48 bits won't be enough, so we rejected that > approach. I can also see how this will be a problem with bpftool, but I > haven't looked into it in detail. I wonder if we can annotate the output > to indicate the function being referred to? > > > > > One other random thought, although I'm not sure how feasible this > > is for ppc64 JIT to realize ... but idea would be to have something > > like the below: > > > > diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c > > index 29ca920..daa7258 100644 > > --- a/kernel/bpf/core.c > > +++ b/kernel/bpf/core.c > > @@ -512,6 +512,11 @@ int bpf_get_kallsym(unsigned int symnum, unsigned long > > *value, char *type, > > return ret; > > } > > > > +void * __weak bpf_jit_image_alloc(unsigned long size) > > +{ > > + return module_alloc(size); > > +} > > + > > struct bpf_binary_header * > > bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr, > > unsigned int alignment, > > @@ -525,7 +530,7 @@ bpf_jit_binary_alloc(unsigned int proglen, u8 > > **image_ptr, > > * random section of illegal instructions. > > */ > > size = round_up(proglen + sizeof(*hdr) + 128, PAGE_SIZE); > > - hdr = module_alloc(size); > > + hdr = bpf_jit_image_alloc(size); > > if (hdr == NULL) > > return NULL; > > > > And ppc64 JIT could override bpf_jit_image_alloc() in a similar way > > like some archs would override the module_alloc() helper through a > > custom implementation, usually via __vmalloc_node_range(), so we > > could perhaps fit the range for BPF JITed images in a way that they > > could use the 32bit imm in the end? There are not that many progs > > loaded typically, so the range could be a bit narrower in such case > > anyway. (Not sure if this would work out though, but I thought to > > bring it up.) > > That'd be a good option to consider. I don't think we want to allocate > anything from the linear memory range since users could load > unprivileged BPF programs and consume a lot of memory that way. I doubt > if we can map vmalloc'ed memory into the 0xc0 address range, but I'm not > entirely sure. > > Michael, > Is the above possible? The question is if we can have BPF programs be > allocated within 4GB of __bpf_call_base (which is a kernel symbol), so > that calls to those programs can be encoded in a 32-bit immediate field > in a BPF instruction. As an extension, we may be able to extend it to > 48-bits by combining with another BPF instruction field (offset). In > either case, the vmalloc'ed address range won't work. > > The alternative is to pass the full 64-bit address of the BPF program in > an auxiliary field (as proposed in this patch set) but we need to fix it > up for 'bpftool' as well. Hi Naveen, Our s390 kernel maintainer Martin Schwidefsky took over eBPF responsibility for s390 from me. @Martin: Can you answer Navee's question? Michael
[PATCH 3/5] powerpc/mm/32: Use page_is_ram to check for RAM
Signed-off-by: Jonathan Neuschäfer--- arch/powerpc/mm/pgtable_32.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index d35d9ad3c1cd..d54e1a9c1c99 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -145,9 +145,8 @@ __ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags, #ifndef CONFIG_CRASH_DUMP /* * Don't allow anybody to remap normal RAM that we're using. -* mem_init() sets high_memory so only do the check after that. */ - if (slab_is_available() && (p < virt_to_phys(high_memory)) && + if (page_is_ram(__phys_to_pfn(p)) && !(__allow_ioremap_reserved && memblock_is_region_reserved(p, size))) { printk("__ioremap(): phys addr 0x%llx is RAM lr %ps\n", (unsigned long long)p, __builtin_return_address(0)); -- 2.16.1
Re: [PATCH v3 2/2] ocxl: Document the OCXL_IOCTL_GET_METADATA IOCTL
Le 22/02/2018 à 05:17, Alastair D'Silva a écrit : From: Alastair D'SilvaSigned-off-by: Alastair D'Silva --- Acked-by: Frederic Barrat Documentation/accelerators/ocxl.rst | 5 + 1 file changed, 5 insertions(+) diff --git a/Documentation/accelerators/ocxl.rst b/Documentation/accelerators/ocxl.rst index 4f7af841d935..ddcc58d01cfb 100644 --- a/Documentation/accelerators/ocxl.rst +++ b/Documentation/accelerators/ocxl.rst @@ -152,6 +152,11 @@ OCXL_IOCTL_IRQ_SET_FD: Associate an event fd to an AFU interrupt so that the user process can be notified when the AFU sends an interrupt. +OCXL_IOCTL_GET_METADATA: + + Obtains configuration information from the card, such at the size of + MMIO areas, the AFU version, and the PASID for the current context. + mmap
Re: [PATCH v3 1/2] ocxl: Add get_metadata IOCTL to share OCXL information to userspace
Le 22/02/2018 à 05:17, Alastair D'Silva a écrit : From: Alastair D'SilvaSome required information is not exposed to userspace currently (eg. the PASID), pass this information back, along with other information which is currently communicated via sysfs, which saves some parsing effort in userspace. Signed-off-by: Alastair D'Silva --- Thanks! Acked-by: Frederic Barrat drivers/misc/ocxl/file.c | 27 +++ include/uapi/misc/ocxl.h | 17 + 2 files changed, 44 insertions(+) diff --git a/drivers/misc/ocxl/file.c b/drivers/misc/ocxl/file.c index d9aa407db06a..90df1be5ef3f 100644 --- a/drivers/misc/ocxl/file.c +++ b/drivers/misc/ocxl/file.c @@ -102,10 +102,32 @@ static long afu_ioctl_attach(struct ocxl_context *ctx, return rc; } +static long afu_ioctl_get_metadata(struct ocxl_context *ctx, + struct ocxl_ioctl_metadata __user *uarg) +{ + struct ocxl_ioctl_metadata arg; + + memset(, 0, sizeof(arg)); + + arg.version = 0; + + arg.afu_version_major = ctx->afu->config.version_major; + arg.afu_version_minor = ctx->afu->config.version_minor; + arg.pasid = ctx->pasid; + arg.pp_mmio_size = ctx->afu->config.pp_mmio_stride; + arg.global_mmio_size = ctx->afu->config.global_mmio_size; + + if (copy_to_user(uarg, , sizeof(arg))) + return -EFAULT; + + return 0; +} + #define CMD_STR(x) (x == OCXL_IOCTL_ATTACH ? "ATTACH" : \ x == OCXL_IOCTL_IRQ_ALLOC ? "IRQ_ALLOC" : \ x == OCXL_IOCTL_IRQ_FREE ? "IRQ_FREE" : \ x == OCXL_IOCTL_IRQ_SET_FD ? "IRQ_SET_FD" : \ + x == OCXL_IOCTL_GET_METADATA ? "GET_METADATA" : \ "UNKNOWN") static long afu_ioctl(struct file *file, unsigned int cmd, @@ -157,6 +179,11 @@ static long afu_ioctl(struct file *file, unsigned int cmd, irq_fd.eventfd); break; + case OCXL_IOCTL_GET_METADATA: + rc = afu_ioctl_get_metadata(ctx, + (struct ocxl_ioctl_metadata __user *) args); + break; + default: rc = -EINVAL; } diff --git a/include/uapi/misc/ocxl.h b/include/uapi/misc/ocxl.h index 4b0b0b756f3e..0af83d80fb3e 100644 --- a/include/uapi/misc/ocxl.h +++ b/include/uapi/misc/ocxl.h @@ -32,6 +32,22 @@ struct ocxl_ioctl_attach { __u64 reserved3; }; +struct ocxl_ioctl_metadata { + __u16 version; // struct version, always backwards compatible + + // Version 0 fields + __u8 afu_version_major; + __u8 afu_version_minor; + __u32 pasid;// PASID assigned to the current context + + __u64 pp_mmio_size; // Per PASID MMIO size + __u64 global_mmio_size; + + // End version 0 fields + + __u64 reserved[13]; // Total of 16*u64 +}; + struct ocxl_ioctl_irq_fd { __u64 irq_offset; __s32 eventfd; @@ -45,5 +61,6 @@ struct ocxl_ioctl_irq_fd { #define OCXL_IOCTL_IRQ_ALLOC _IOR(OCXL_MAGIC, 0x11, __u64) #define OCXL_IOCTL_IRQ_FREE _IOW(OCXL_MAGIC, 0x12, __u64) #define OCXL_IOCTL_IRQ_SET_FD _IOW(OCXL_MAGIC, 0x13, struct ocxl_ioctl_irq_fd) +#define OCXL_IOCTL_GET_METADATA _IOR(OCXL_MAGIC, 0x14, struct ocxl_ioctl_metadata) #endif /* _UAPI_MISC_OCXL_H */
[PATCH 2/5] powerpc: mm: Use memblock API for PPC32 page_is_ram
To support accurate checking for different blocks of memory on PPC32, use the same memblock-based approach that's already used on PPC64 also on PPC32. Signed-off-by: Jonathan Neuschäfer--- arch/powerpc/mm/mem.c | 4 1 file changed, 4 deletions(-) diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index da4e1555d61d..a42b86e2a34c 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -82,11 +82,7 @@ static inline pte_t *virt_to_kpte(unsigned long vaddr) int page_is_ram(unsigned long pfn) { -#ifndef CONFIG_PPC64 /* XXX for now */ - return pfn < max_pfn; -#else return memblock_is_memory(__pfn_to_phys(pfn)); -#endif } pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, -- 2.16.1