Re: [PATCH v12 1/3] mm, powerpc, x86: define VM_PKEY_BITx bits if CONFIG_ARCH_HAS_PKEYS is enabled

2018-02-22 Thread kbuild test robot
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

2018-02-22 Thread Michael Ellerman
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

2018-02-22 Thread Michael Ellerman
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

2018-02-22 Thread Michael Ellerman
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. Bringmann 

Applied to powerpc fixes, thanks.

https://git.kernel.org/powerpc/c/c7a3275e0f9e461bb8942132aa6914

cheers


Re: [PATCH 00/38] cxlflash: OpenCXL transport support

2018-02-22 Thread Andrew Donnellan

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

2018-02-22 Thread Michael Ellerman
Bjorn Helgaas  writes:

> 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

2018-02-22 Thread Michael Ellerman
Bjorn Helgaas  writes:
> 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

2018-02-22 Thread Stewart Smith
Michael Ellerman  writes:
> 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

2018-02-22 Thread Michael Ellerman
Marcus Folkesson  writes:
> - 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

2018-02-22 Thread Bjorn Helgaas
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

2018-02-22 Thread Bjorn Helgaas
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

2018-02-22 Thread Uma Krishnan
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.

2018-02-22 Thread Michael Ellerman
Vaibhav Jain  writes:
> 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

2018-02-22 Thread Michael Ellerman
Yves-Alexis Perez  writes:
> 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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Uma Krishnan
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

2018-02-22 Thread Michael Ellerman
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"

cheers


Re: [PATCH v3] watchdog: add SPDX identifiers for watchdog subsystem

2018-02-22 Thread Johannes Thumshirn
Marcus Folkesson  writes:
[...]
>  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

2018-02-22 Thread Shawn Guo
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.

2018-02-22 Thread Bryant G. Ly
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

2018-02-22 Thread Kees Cook
On Thu, Feb 22, 2018 at 5:07 AM, Michal Hocko  wrote:
> 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()

2018-02-22 Thread Herbert Xu
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

2018-02-22 Thread Christophe Leroy
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

2018-02-22 Thread Christophe Leroy
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 Leroy 
Reviewed-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

2018-02-22 Thread Christophe Leroy
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:  00029032   CR: 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

2018-02-22 Thread Christophe Leroy
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

2018-02-22 Thread Christophe Leroy
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

2018-02-22 Thread Christophe Leroy
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 Leroy 
Reviewed-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

2018-02-22 Thread Nicholas Piggin
On Thu, 22 Feb 2018 23:35:45 +1100
Michael Ellerman  wrote:

> 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

2018-02-22 Thread Christophe LEROY



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

2018-02-22 Thread Nathan Fontenot
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 Rao 

Reviewed-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

2018-02-22 Thread Nathan Fontenot
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 Rao 

Reviewed-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

2018-02-22 Thread Herbert Xu
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 Xu 
Home 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

2018-02-22 Thread Michael Ellerman
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

2018-02-22 Thread Michael Ellerman
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

2018-02-22 Thread Mark Brown
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 Chen 
Date: 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

2018-02-22 Thread Mark Brown
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 Chen 
Date: 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

2018-02-22 Thread Mark Brown
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 Chen 
Date: 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

2018-02-22 Thread Mark Brown
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 Chen 
Date: 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

2018-02-22 Thread Mark Brown
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 Chen 
Date: 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

2018-02-22 Thread Mark Brown
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 Chen 
Date: 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

2018-02-22 Thread Mark Brown
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 Chen 
Date: 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

2018-02-22 Thread Mark Brown
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 Chen 
Date: 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

2018-02-22 Thread Mark Brown
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 Chen 
Date: 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

2018-02-22 Thread Mark Brown
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 Chen 
Date: 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

2018-02-22 Thread Mark Brown
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 Chen 
Date: 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

2018-02-22 Thread Mark Brown
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 Chen 
Date: 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

2018-02-22 Thread Mark Brown
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 Chen 
Date: 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

2018-02-22 Thread Mark Brown
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 Chen 
Date: 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

2018-02-22 Thread Jonathan Neuschäfer
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

2018-02-22 Thread Michal Hocko
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

2018-02-22 Thread Linus Walleij
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!

Yours,
Linus Walleij


[PATCH v4.4 backport 2/3] powerpc/64s: Simple RFI macro conversions

2018-02-22 Thread Michael Ellerman
From: Nicholas Piggin 

commit 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

2018-02-22 Thread Michael Ellerman
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 
---
 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

2018-02-22 Thread Michael Ellerman
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.

2018-02-22 Thread Vaibhav Jain

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 Jain 
Linux Technology Center, IBM India Pvt. Ltd.



Re: [PATCH 16/18] crypto: talitos - do hw_context DMA mapping outside the requests

2018-02-22 Thread Horia Geantă
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

2018-02-22 Thread Jonathan Neuschäfer
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

2018-02-22 Thread Michael Holzheu
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

2018-02-22 Thread 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 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

2018-02-22 Thread Jonathan Neuschäfer
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

2018-02-22 Thread Frederic Barrat



Le 22/02/2018 à 05:17, Alastair D'Silva a écrit :

From: Alastair D'Silva 

Signed-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

2018-02-22 Thread Frederic Barrat



Le 22/02/2018 à 05:17, Alastair D'Silva a écrit :

From: Alastair D'Silva 

Some 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

2018-02-22 Thread Jonathan Neuschäfer
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



  1   2   >