LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] hwmon: (ibmpowernv) Remove bogus __init annotations
From: Geert Uytterhoeven @ 2018-10-28 17:16 UTC (permalink / raw)
  To: Cédric Le Goater, Jean Delvare, Guenter Roeck,
	Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
  Cc: linux-hwmon, Geert Uytterhoeven, linuxppc-dev, linux-kernel

If gcc decides not to inline make_sensor_label():

    WARNING: vmlinux.o(.text+0x4df549c): Section mismatch in reference from the function .create_device_attrs() to the function .init.text:.make_sensor_label()
    The function .create_device_attrs() references
    the function __init .make_sensor_label().
    This is often because .create_device_attrs lacks a __init
    annotation or the annotation of .make_sensor_label is wrong.

As .probe() can be called after freeing of __init memory, all __init
annotiations in the driver are bogus, and should be removed.

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
Compile-tested only.
---
 drivers/hwmon/ibmpowernv.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/hwmon/ibmpowernv.c b/drivers/hwmon/ibmpowernv.c
index 0ccca87f527191dc..293dd1c6c7b36ef2 100644
--- a/drivers/hwmon/ibmpowernv.c
+++ b/drivers/hwmon/ibmpowernv.c
@@ -181,7 +181,7 @@ static ssize_t show_label(struct device *dev, struct device_attribute *devattr,
 	return sprintf(buf, "%s\n", sdata->label);
 }
 
-static int __init get_logical_cpu(int hwcpu)
+static int get_logical_cpu(int hwcpu)
 {
 	int cpu;
 
@@ -192,9 +192,8 @@ static int __init get_logical_cpu(int hwcpu)
 	return -ENOENT;
 }
 
-static void __init make_sensor_label(struct device_node *np,
-				     struct sensor_data *sdata,
-				     const char *label)
+static void make_sensor_label(struct device_node *np,
+			      struct sensor_data *sdata, const char *label)
 {
 	u32 id;
 	size_t n;
-- 
2.17.1


^ permalink raw reply related

* NXP P50XX/e5500: SMP doesn't work anymore with the latest Git kernel
From: Christian Zigotzky @ 2018-10-28 16:35 UTC (permalink / raw)
  To: linuxppc-dev

Hello,

SMP doesn't work anymore with the latest Git kernel (28/10/18 11:12AM 
GMT) on my P5020 board and on virtual e5500 QEMU machines.

Board with P5020 dual core CPU:

[    0.000000] -----------------------------------------------------
[    0.000000] phys_mem_size     = 0x200000000
[    0.000000] dcache_bsize      = 0x40
[    0.000000] icache_bsize      = 0x40
[    0.000000] cpu_features      = 0x00000003008003b4
[    0.000000]   possible        = 0x00000003009003b4
[    0.000000]   always          = 0x00000003008003b4
[    0.000000] cpu_user_features = 0xcc008000 0x08000000
[    0.000000] mmu_features      = 0x000a0010
[    0.000000] firmware_features = 0x0000000000000000
[    0.000000] -----------------------------------------------------
[    0.000000] CoreNet Generic board

     ...

[    0.002161] smp: Bringing up secondary CPUs ...
[    0.002339] No cpu-release-addr for cpu 1
[    0.002347] smp: failed starting cpu 1 (rc -2)
[    0.002401] smp: Brought up 1 node, 1 CPU

Virtual e5500 quad core QEMU machine:

[    0.026394] smp: Bringing up secondary CPUs ...
[    0.027831] No cpu-release-addr for cpu 1
[    0.027989] smp: failed starting cpu 1 (rc -2)
[    0.030143] No cpu-release-addr for cpu 2
[    0.030304] smp: failed starting cpu 2 (rc -2)
[    0.032400] No cpu-release-addr for cpu 3
[    0.032533] smp: failed starting cpu 3 (rc -2)
[    0.033117] smp: Brought up 1 node, 1 CPU

QEMU command: ./qemu-system-ppc64 -M ppce500 -cpu e5500 -m 2048 -kernel 
/home/christian/Downloads/vmlinux-4.20-alpha4-AmigaOne_X1000_X5000/X5000_and_QEMU_e5500/uImage-4.20 
-drive 
format=raw,file=/home/christian/Downloads/MATE_PowerPC_Remix_2017_0.9.img,index=0,if=virtio 
-nic user,model=e1000 -append "rw root=/dev/vda" -device virtio-vga 
-device virtio-mouse-pci -device virtio-keyboard-pci -usb -soundhw 
es1370 -smp 4

.config:

...
CONFIG_SMP=y
CONFIG_NR_CPUS=4
...

Please test the latest Git kernel on your NXP P50XX boards.

Thanks,
Christian

^ permalink raw reply

* [PATCH] ppc4xx: ocm: fix errnous "failed to create file" errors
From: Christian Lamparter @ 2018-10-28 16:17 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Paul Mackerras, Markus Elfring

Previously, the kernel would complain:

| debugfs ppc4xx ocm: failed to create file

But the "info" file was still created and working. This
is because debugfs_create_file() returns a pointer to a
struct *dentry on success or -ENODEV when debugfs isn't
available. This patch fixes both the debugfs_create_dir()
and debugfs_create_file() check, so this will work as
expected.

Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
---
 arch/powerpc/platforms/4xx/ocm.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/platforms/4xx/ocm.c b/arch/powerpc/platforms/4xx/ocm.c
index 69d9f60d9fe5..e616c8636303 100644
--- a/arch/powerpc/platforms/4xx/ocm.c
+++ b/arch/powerpc/platforms/4xx/ocm.c
@@ -293,13 +293,14 @@ static int ocm_debugfs_init(void)
 {
 	struct dentry *junk;
 
-	junk = debugfs_create_dir("ppc4xx_ocm", 0);
-	if (!junk) {
+	junk = debugfs_create_dir("ppc4xx_ocm", NULL);
+	if (IS_ERR_OR_NULL(junk)) {
 		printk(KERN_ALERT "debugfs ppc4xx ocm: failed to create dir\n");
 		return -1;
 	}
 
-	if (debugfs_create_file("info", 0644, junk, NULL, &ocm_debugfs_fops)) {
+	if (IS_ERR_OR_NULL(debugfs_create_file("info", 0644, junk, NULL,
+					       &ocm_debugfs_fops))) {
 		printk(KERN_ALERT "debugfs ppc4xx ocm: failed to create file\n");
 		return -1;
 	}
-- 
2.19.1


^ permalink raw reply related

* Re: [PATCH 2/4] mm: speed up mremap by 500x on large regions (v2)
From: Joel Fernandes @ 2018-10-27 19:39 UTC (permalink / raw)
  To: Balbir Singh
  Cc: linux-mips, Rich Felker, linux-ia64, linux-sh, Peter Zijlstra,
	Catalin Marinas, Dave Hansen, Will Deacon, mhocko, linux-mm,
	lokeshgidra, sparclinux, linux-riscv, elfring, Jonas Bonn, kvmarm,
	dancol, Yoshinori Sato, linux-xtensa, linux-hexagon, Helge Deller,
	maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), hughd,
	James E.J. Bottomley, kasan-dev, anton.ivanov, Ingo Molnar,
	Geert Uytterhoeven, Andrey Ryabinin, linux-snps-arc, kernel-team,
	Sam Creasey, Fenghua Yu, linux-s390, Jeff Dike, linux-um,
	Stefan Kristiansson, Julia Lawall, linux-m68k, Borislav Petkov,
	Andy Lutomirski, nios2-dev, Kirill A. Shutemov, Stafford Horne,
	Guan Xuetao, Chris Zankel, Tony Luck, Richard Weinberger,
	linux-parisc, pantin, Max Filippov, linux-kernel, minchan,
	Thomas Gleixner, linux-alpha, Ley Foon Tan, akpm, linuxppc-dev,
	David S. Miller
In-Reply-To: <20181027102102.GO8537@350D>

Hi Balbir,

On Sat, Oct 27, 2018 at 09:21:02PM +1100, Balbir Singh wrote:
> On Wed, Oct 24, 2018 at 07:13:50PM -0700, Joel Fernandes wrote:
> > On Wed, Oct 24, 2018 at 10:57:33PM +1100, Balbir Singh wrote:
> > [...]
> > > > > +		pmd_t pmd;
> > > > > +
> > > > > +		new_ptl = pmd_lockptr(mm, new_pmd);
> > > 
> > > 
> > > Looks like this is largely inspired by move_huge_pmd(), I guess a lot of
> > > the code applies, why not just reuse as much as possible? The same comments
> > > w.r.t mmap_sem helping protect against lock order issues applies as well.
> > 
> > I thought about this and when I looked into it, it seemed there are subtle
> > differences that make such sharing not worth it (or not possible).
> >
> 
> Could you elaborate on them?

The move_huge_page function is defined only for CONFIG_TRANSPARENT_HUGEPAGE
so we cannot reuse it to begin with, since we have it disabled on our
systems. I am not sure if it is a good idea to split that out and refactor it
for reuse especially since our case is quite simple compared to huge pages.

There are also a couple of subtle differences between the move_normal_pmd and
the move_huge_pmd. Atleast 2 of them are:

1. We don't concern ourself with the PMD dirty bit, since the pages being
moved are normal pages and at the soft-dirty bit accounting is at the PTE
level, since we are not moving PTEs, we don't need to do that.

2. The locking is simpler as Kirill pointed, pmd_lock cannot fail however
__pmd_trans_huge_lock can.

I feel it is not super useful to refactor move_huge_pmd to support our case
especially since move_normal_pmd is quite small, so IMHO the benefit of code
reuse isn't there very much.

Do let me know your thoughts and thanks for your interest in this.

thanks,

 - Joel


^ permalink raw reply

* Re: [PATCH 2/4] mm: speed up mremap by 500x on large regions (v2)
From: Balbir Singh @ 2018-10-27 10:21 UTC (permalink / raw)
  To: Joel Fernandes
  Cc: linux-mips, Rich Felker, linux-ia64, linux-sh, Peter Zijlstra,
	Catalin Marinas, Dave Hansen, Will Deacon, mhocko, linux-mm,
	lokeshgidra, sparclinux, linux-riscv, elfring, Jonas Bonn, kvmarm,
	dancol, Yoshinori Sato, linux-xtensa, linux-hexagon, Helge Deller,
	maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), hughd,
	James E.J. Bottomley, kasan-dev, anton.ivanov, Ingo Molnar,
	Geert Uytterhoeven, Andrey Ryabinin, linux-snps-arc, kernel-team,
	Sam Creasey, Fenghua Yu, linux-s390, Jeff Dike, linux-um,
	Stefan Kristiansson, Julia Lawall, linux-m68k, Borislav Petkov,
	Andy Lutomirski, nios2-dev, Kirill A. Shutemov, Stafford Horne,
	Guan Xuetao, Chris Zankel, Tony Luck, Richard Weinberger,
	linux-parisc, pantin, Max Filippov, linux-kernel, minchan,
	Thomas Gleixner, linux-alpha, Ley Foon Tan, akpm, linuxppc-dev,
	David S. Miller
In-Reply-To: <20181025021350.GB13560@joelaf.mtv.corp.google.com>

On Wed, Oct 24, 2018 at 07:13:50PM -0700, Joel Fernandes wrote:
> On Wed, Oct 24, 2018 at 10:57:33PM +1100, Balbir Singh wrote:
> [...]
> > > > +		pmd_t pmd;
> > > > +
> > > > +		new_ptl = pmd_lockptr(mm, new_pmd);
> > 
> > 
> > Looks like this is largely inspired by move_huge_pmd(), I guess a lot of
> > the code applies, why not just reuse as much as possible? The same comments
> > w.r.t mmap_sem helping protect against lock order issues applies as well.
> 
> I thought about this and when I looked into it, it seemed there are subtle
> differences that make such sharing not worth it (or not possible).
>

Could you elaborate on them?

Thanks,
Balbir Singh. 

^ permalink raw reply

* Re: [PATCH 2/4] mm: speed up mremap by 500x on large regions (v2)
From: Joel Fernandes @ 2018-10-26 21:11 UTC (permalink / raw)
  To: Kirill A. Shutemov
  Cc: linux-mips, Rich Felker, linux-ia64, linux-sh, Peter Zijlstra,
	Catalin Marinas, Dave Hansen, Will Deacon, mhocko, linux-mm,
	lokeshgidra, sparclinux, linux-riscv, elfring, Jonas Bonn, kvmarm,
	dancol, Yoshinori Sato, linux-xtensa, linux-hexagon, Helge Deller,
	maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), hughd,
	James E.J. Bottomley, kasan-dev, anton.ivanov, Ingo Molnar,
	Geert Uytterhoeven, Andrey Ryabinin, linux-snps-arc, kernel-team,
	Sam Creasey, Fenghua Yu, linux-s390, Jeff Dike, linux-um,
	Stefan Kristiansson, Julia Lawall, linux-m68k, Borislav Petkov,
	Andy Lutomirski, nios2-dev, Stafford Horne, Guan Xuetao,
	Chris Zankel, Tony Luck, Richard Weinberger, linux-parisc, pantin,
	Max Filippov, linux-kernel, minchan, Thomas Gleixner, linux-alpha,
	Ley Foon Tan, akpm, linuxppc-dev, David S. Miller
In-Reply-To: <20181025101900.phqnqpoju5t2gar5@kshutemo-mobl1>

On Thu, Oct 25, 2018 at 01:19:00PM +0300, Kirill A. Shutemov wrote:
> On Wed, Oct 24, 2018 at 07:09:07PM -0700, Joel Fernandes wrote:
> > On Wed, Oct 24, 2018 at 03:57:24PM +0300, Kirill A. Shutemov wrote:
> > > On Wed, Oct 24, 2018 at 10:57:33PM +1100, Balbir Singh wrote:
> > > > On Wed, Oct 24, 2018 at 01:12:56PM +0300, Kirill A. Shutemov wrote:
> > > > > On Fri, Oct 12, 2018 at 06:31:58PM -0700, Joel Fernandes (Google) wrote:
> > > > > > diff --git a/mm/mremap.c b/mm/mremap.c
> > > > > > index 9e68a02a52b1..2fd163cff406 100644
> > > > > > --- a/mm/mremap.c
> > > > > > +++ b/mm/mremap.c
> > > > > > @@ -191,6 +191,54 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
> > > > > >  		drop_rmap_locks(vma);
> > > > > >  }
> > > > > >  
> > > > > > +static bool move_normal_pmd(struct vm_area_struct *vma, unsigned long old_addr,
> > > > > > +		  unsigned long new_addr, unsigned long old_end,
> > > > > > +		  pmd_t *old_pmd, pmd_t *new_pmd, bool *need_flush)
> > > > > > +{
> > > > > > +	spinlock_t *old_ptl, *new_ptl;
> > > > > > +	struct mm_struct *mm = vma->vm_mm;
> > > > > > +
> > > > > > +	if ((old_addr & ~PMD_MASK) || (new_addr & ~PMD_MASK)
> > > > > > +	    || old_end - old_addr < PMD_SIZE)
> > > > > > +		return false;
> > > > > > +
> > > > > > +	/*
> > > > > > +	 * The destination pmd shouldn't be established, free_pgtables()
> > > > > > +	 * should have release it.
> > > > > > +	 */
> > > > > > +	if (WARN_ON(!pmd_none(*new_pmd)))
> > > > > > +		return false;
> > > > > > +
> > > > > > +	/*
> > > > > > +	 * We don't have to worry about the ordering of src and dst
> > > > > > +	 * ptlocks because exclusive mmap_sem prevents deadlock.
> > > > > > +	 */
> > > > > > +	old_ptl = pmd_lock(vma->vm_mm, old_pmd);
> > > > > > +	if (old_ptl) {
> > > > > 
> > > > > How can it ever be false?
> > 
> > Kirill,
> > It cannot, you are right. I'll remove the test.
> > 
> > By the way, there are new changes upstream by Linus which flush the TLB
> > before releasing the ptlock instead of after. I'm guessing that patch came
> > about because of reviews of this patch and someone spotted an issue in the
> > existing code :)
> > 
> > Anyway the patch in concern is:
> > eb66ae030829 ("mremap: properly flush TLB before releasing the page")
> > 
> > I need to rebase on top of that with appropriate modifications, but I worry
> > that this patch will slow down performance since we have to flush at every
> > PMD/PTE move before releasing the ptlock. Where as with my patch, the
> > intention is to flush only at once in the end of move_page_tables. When I
> > tried to flush TLB on every PMD move, it was quite slow on my arm64 device [2].
> > 
> > Further observation [1] is, it seems like the move_huge_pmds and move_ptes code
> > is a bit sub optimal in the sense, we are acquiring and releasing the same
> > ptlock for a bunch of PMDs if the said PMDs are on the same page-table page
> > right? Instead we can do better by acquiring and release the ptlock less
> > often.
> > 
> > I think this observation [1] and the frequent TLB flush issue [2] can be solved
> > by acquiring the ptlock once for a bunch of PMDs, move them all, then flush
> > the tlb and then release the ptlock, and then proceed to doing the same thing
> > for the PMDs in the next page-table page. What do you think?
> 
> Yeah, that's viable optimization.
> 
> The tricky part is that one PMD page table can have PMD entires of
> different types: THP, page table that you can move as whole and the one
> that you cannot (for any reason).
> 
> If we cannot move the PMD entry as a whole and must go to PTE page table
> we would need to drop PMD ptl and take PTE ptl (it might be the same lock
> in some configuations).

> Also we don't want to take PMD lock unless it's required.
> 
> I expect it to be not very trivial to get everything right. But take a
> shot :)

Yes, that is exactly the issue I hit when I attempted it. :) The locks need
to be release if we do something different on the next loop iteration. It
complicates the code and not sure if it is worth it in the long run.  On x86
atleast, I don't see any perf issues with the TLB-flush per-PMD move, so the
patch is Ok there. On arm64, it negates the performance benefit even though
its not any worse than what we are doing currently at the PTE level.

My thinking is to take it slow and get the patch in in its current state,
since it improves x86. Then as a next step, look into why the arm64 tlb
flushes are that expensive and look into optimizing that. On arm64 I am
testing on a 4.9 kernel so I'm wondering there are any optimizations since
4.9 that can help speed it up there. After that, if all else fails about
speeding up arm64, then I look into developing the cleanest possible solution
where we can keep the lock held for longer and flush lesser.

thanks,

 - Joel


^ permalink raw reply

* Re: [PATCH] Documentation: fix spelling mistake, EACCESS -> EACCES
From: Miguel Ojeda @ 2018-10-26 18:54 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: kernel-janitors, Jonathan Corbet, Dave Airlie, linuxppc-dev,
	Linux Doc Mailing List, maarten.lankhorst, linux-kernel,
	maxime.ripard, jk, colin.king, sean
In-Reply-To: <CANiq72m-2FU7ioqj9sqsfWk4nSp2FO9S_8kYcbnGReXNAXYM2w@mail.gmail.com>

On Fri, Oct 26, 2018 at 8:53 PM Miguel Ojeda
<miguel.ojeda.sandonis@gmail.com> wrote:
>
> On Fri, Oct 26, 2018 at 8:40 PM Matthew Wilcox <willy@infradead.org> wrote:
> >
> > On Fri, Oct 26, 2018 at 08:20:12PM +0200, Miguel Ojeda wrote:
> > > On Fri, Oct 26, 2018 at 7:27 PM Colin King <colin.king@canonical.com> wrote:
> > > >
> > > > From: Colin Ian King <colin.king@canonical.com>
> > > >
> > > > Trivial fix to a spelling mistake of the error access name EACCESS,
> > > > rename to EACCES
> > >
> > > ? It is not a typo, it is the name of the error (POSIX). Same thing
> > > for the rest of the patches.
> >
> > Are you sure?  From open(2):
> >
> >        EACCES The  requested access to the file is not allowed, or search per‐
> >               mission is denied for one of the directories in the path  prefix
> >               of  pathname,  or the file did not exist yet and write access to
> >               the parent directory is not  allowed.   (See  also  path_resolu‐
> >               tion(7).)
> >
> > include/uapi/asm-generic/errno-base.h:#define   EACCES          13      /* Permission denied */
>
> I thought you were doing the reverse change. Never mind! :-)
>
> (Btw, the POSIX reference is
> http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html#tag_13_09,
> in case you want to include it or are curious)

Sorry Matthew, thought I was answering to Colin. I should go to rest.

Cheers,
Miguel

^ permalink raw reply

* Re: [PATCH] Documentation: fix spelling mistake, EACCESS -> EACCES
From: Miguel Ojeda @ 2018-10-26 18:53 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: kernel-janitors, Jonathan Corbet, Dave Airlie, linuxppc-dev,
	Linux Doc Mailing List, maarten.lankhorst, linux-kernel,
	maxime.ripard, jk, colin.king, sean
In-Reply-To: <20181026184009.GV25444@bombadil.infradead.org>

On Fri, Oct 26, 2018 at 8:40 PM Matthew Wilcox <willy@infradead.org> wrote:
>
> On Fri, Oct 26, 2018 at 08:20:12PM +0200, Miguel Ojeda wrote:
> > On Fri, Oct 26, 2018 at 7:27 PM Colin King <colin.king@canonical.com> wrote:
> > >
> > > From: Colin Ian King <colin.king@canonical.com>
> > >
> > > Trivial fix to a spelling mistake of the error access name EACCESS,
> > > rename to EACCES
> >
> > ? It is not a typo, it is the name of the error (POSIX). Same thing
> > for the rest of the patches.
>
> Are you sure?  From open(2):
>
>        EACCES The  requested access to the file is not allowed, or search per‐
>               mission is denied for one of the directories in the path  prefix
>               of  pathname,  or the file did not exist yet and write access to
>               the parent directory is not  allowed.   (See  also  path_resolu‐
>               tion(7).)
>
> include/uapi/asm-generic/errno-base.h:#define   EACCES          13      /* Permission denied */

I thought you were doing the reverse change. Never mind! :-)

(Btw, the POSIX reference is
http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html#tag_13_09,
in case you want to include it or are curious)

Cheers,
Miguel

^ permalink raw reply

* Re: [PATCH] Documentation: fix spelling mistake, EACCESS -> EACCES
From: Miguel Ojeda @ 2018-10-26 18:20 UTC (permalink / raw)
  To: colin.king
  Cc: kernel-janitors, Jonathan Corbet, Dave Airlie, linuxppc-dev,
	Linux Doc Mailing List, maarten.lankhorst, linux-kernel,
	maxime.ripard, jk, sean
In-Reply-To: <20181026172549.3628-1-colin.king@canonical.com>

On Fri, Oct 26, 2018 at 7:27 PM Colin King <colin.king@canonical.com> wrote:
>
> From: Colin Ian King <colin.king@canonical.com>
>
> Trivial fix to a spelling mistake of the error access name EACCESS,
> rename to EACCES

? It is not a typo, it is the name of the error (POSIX). Same thing
for the rest of the patches.

Cheers,
Miguel

^ permalink raw reply

* Re: ethernet "bus" number in DTS ?
From: Florian Fainelli @ 2018-10-26 22:57 UTC (permalink / raw)
  To: Michal Suchánek
  Cc: andrew@lunn.ch, linuxppc-dev@lists.ozlabs.org, robh,
	netdev@vger.kernel.org
In-Reply-To: <20181024082239.5ee41017@naga.suse.cz>

On 10/23/18 11:22 PM, Michal Suchánek wrote:
> On Tue, 23 Oct 2018 11:20:36 -0700
> Florian Fainelli <f.fainelli@gmail.com> wrote:
> 
>> On 10/23/18 11:02 AM, Joakim Tjernlund wrote:
>>> On Tue, 2018-10-23 at 10:03 -0700, Florian Fainelli wrote:  
> 
>>>
>>> I also noted that using status = "disabled" didn't work either to
>>> create a fix name scheme. Even worse, all the eth I/F after gets
>>> renumbered. It seems to me there is value in having stability in
>>> eth I/F naming at boot. Then userspace(udev) can rename if need be. 
>>>
>>> Sure would like to known more about why this feature is not wanted ?
>>>
>>> I found
>>>   https://patchwork.kernel.org/patch/4122441/
>>> You quote policy as reason but surely it must be better to
>>> have something stable, connected to the hardware name, than
>>> semirandom naming?  
>>
>> If the Device Tree nodes are ordered by ascending base register
>> address, my understanding is that you get the same order as far as
>> platform_device creation goes, this may not be true in the future if
>> Rob decides to randomize that, but AFAICT this is still true. This
>> may not work well with status = disabled properties being inserted
>> here and there, but we have used that here and it has worked for as
>> far as I can remember doing it.
> 
> So this is unstable in several respects. First is changing the
> enabled/disabled status in the deivecetrees provided by the kernel.
> 
> Second is if you have hardware hotplug mechanism either by firmware or
> by loading device overlays.
> 
> Third is the case when the devicetree is not built as part of the
> kernel but is instead provided by firmware that initializes the
> low-level hardware details. Then the ordering by address is not
> guaranteed nor is that the same address will be used to access the same
> interface every time. There might be multiple ways to configure the
> hardware depending on firmware configuration and/or version.
> 
>  
>> Second, you might want to name network devices ethX, but what if I
>> want to name them ethernetX or fooX or barX? Should we be accepting a
>> mechanism in the kernel that would allow someone to name the
>> interfaces the way they want straight from a name being provided in
>> Device Tree?
> 
> Clearly if there is text Ethernet1 printed above the Ethernet port we
> should provide a mechanism to name the port Ethernet1 by default.

Yes, but then have a specific property that is flexible enough to
retrieve things like "vital product information". For DSA switches, we
have an optional "label" property which names the network device
directly like it would be found on the product's case. Ideally this
should be much more flexible such that it can point to the appropriate
node/firmware service/whatever to get that name, which is what some
people have been working on lately, see [1].

[1]: https://lkml.org/lkml/2018/8/14/1039

The point is don't re-purpose the aliases which is something that exists
within Device Tree to basically provide a shorter path to a specific set
of nodes for the boot program to mangle and muck with instead of having
to resolve a full path to a node. At least that is how I conceive it.

Now what complicates the matter is that some OSes like Linux tend to use
it to also generate seemingly stable index for peripherals that are
numbered by index such as SPI, I2C, etc buses, which is why we are
having this conversation here, see below for more.

> 
>>
>> Aliases are fine for providing relative stability within the Device
>> Tree itself and boot programs that might need to modify the Device
>> Tree (e.g: inserting MAC addresses) such that you don't have to
>> encode logic to search for nodes by compatible strings etc. but
>> outside of that use case, it seems to me that you can resolve every
>> naming decision in user-space.
> 
> However, this is pushing platform-specific knowledge to userspace. The
> way the Ethernet interface is attached and hence the device properties
> usable for identifying the device uniquely are platform-specific.

There is always going to be some amount of platform specific knowledge
to user-space, what matters is the level of abstraction that is
presented to you.

> 
> On the other hand, aliases are universal when provided. If they are
> good enough to assign a MAC address they are good enough to provide a
> stable default name.

We are not talking about the same aliases then. The special Device Tree
node named "aliases" is a way to create shorted Device Tree node paths,
it is not by any means an equivalent for what I would rather call a
"label", or "port name" or silk screen annotation on a PCB for instance.

> 
> I think this is indeed forcing the userspace to reinvent several wheels
> for no good reason.

udev or systemd will come up with some stable names for your network
device right off the bat. If you are deeply embedded maybe you don't
want those, but then use something like the full path in /sys to get
some stable names based on the SoC's topology.

> 
> What is the problem with adding the aliases?

aliases is IMHO the wrong tool for the job because it is too limiting,
you want it to be used to have Ethernet controller instance N to be
named "ethN", what if someone tomorrows says, no this is not good, I
want the aliases to automatically name my network devices
"ethernet-controllerN" or "blahblahN"? You see where I am getting with that?

And yes, I do realize that Linux has traditionally named Ethernet
adapters ethN, but also allows people to name interfaces just the way
they want even from within the drivers themselves.

Now imagine your platform uses ACPI, and there are no aliases there to
point a node with a shorter name, how we would go about naming your
Ethernet controller unless there is a specific VPD/label/sticker
property that can be somehow be retried?
-- 
Florian

^ permalink raw reply

* Re: [GIT PULL] Please pull powerpc/linux.git powerpc-4.20-1 tag
From: Linus Torvalds @ 2018-10-26 21:38 UTC (permalink / raw)
  To: mpe
  Cc: ego, clombard, daniel.vetter, fbarrat, mahesh, yamada.masahiro,
	mwb, oohall, leitao, aravinda, rashmica.g, breno.leitao, robh,
	mikey, aneesh.kumar, b.zolnierkie, yuehaibing, fthain, geert,
	joel, sjitindarsingh, nfont, naveen.n.rao, dan.carpenter,
	Arnd Bergmann, amodra, mhairgrove, Nick Piggin, pvorel, anton,
	dan.j.williams, zhongjiang, hbathini, dja, msuchanek, geoff,
	Linux Kernel Mailing List, sbobroff, andrew.donnellan, vaibhav,
	ldufour, linuxppc-dev
In-Reply-To: <87ftwssg7m.fsf@concordia.ellerman.id.au>

On Fri, Oct 26, 2018 at 11:42 AM Michael Ellerman <mpe@ellerman.id.au> wrote:
>
> Please pull powerpc updates for 4.20:

Pulled,

                       Linus

^ permalink raw reply

* Re: [PATCH 3/7] dmaengine: fsl-qdma: Add qDMA controller driver for Layerscape SoCs
From: Li Yang @ 2018-10-26 20:47 UTC (permalink / raw)
  To: peng.ma
  Cc: Mark Rutland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Wen He, linuxppc-dev, lkml, Jiaheng Fan, Vinod, Rob Herring,
	dmaengine, Dan Williams, Shawn Guo,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20181026095240.33668-3-peng.ma@nxp.com>

On Fri, Oct 26, 2018 at 4:57 AM Peng Ma <peng.ma@nxp.com> wrote:
>
> NXP Queue DMA controller(qDMA) on Layerscape SoCs supports channel
> virtuallization by allowing DMA jobs to be enqueued into different
> command queues.
>
> Note that this module depends on NXP DPAA.

It is not clear if you are saying that the driver can only work on
SoCs with a DPAA hardware block, or the driver is actually depending
on the DPAA drivers also.  If it is the later case, you also should
express that in the Kconfig you added below.

>
> Signed-off-by: Wen He <wen.he_1@nxp.com>
> Signed-off-by: Jiaheng Fan <jiaheng.fan@nxp.com>
> Signed-off-by: Peng Ma <peng.ma@nxp.com>
> ---
> change in v10:
>         - no
>
>  drivers/dma/Kconfig    |   13 +
>  drivers/dma/Makefile   |    1 +
>  drivers/dma/fsl-qdma.c | 1257 ++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 1271 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/dma/fsl-qdma.c
>
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index dacf3f4..50e19d7 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -218,6 +218,19 @@ config FSL_EDMA
>           multiplexing capability for DMA request sources(slot).
>           This module can be found on Freescale Vybrid and LS-1 SoCs.
>
> +config FSL_QDMA
> +       tristate "NXP Layerscape qDMA engine support"
> +       depends on ARM || ARM64
> +       select DMA_ENGINE
> +       select DMA_VIRTUAL_CHANNELS
> +       select DMA_ENGINE_RAID
> +       select ASYNC_TX_ENABLE_CHANNEL_SWITCH
> +       help
> +         Support the NXP Layerscape qDMA engine with command queue and legacy mode.
> +         Channel virtualization is supported through enqueuing of DMA jobs to,
> +         or dequeuing DMA jobs from, different work queues.
> +         This module can be found on NXP Layerscape SoCs.
> +
>  config FSL_RAID
>          tristate "Freescale RAID engine Support"
>          depends on FSL_SOC && !ASYNC_TX_ENABLE_CHANNEL_SWITCH
> diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
> index c91702d..2d1b586 100644
> --- a/drivers/dma/Makefile
> +++ b/drivers/dma/Makefile
> @@ -32,6 +32,7 @@ obj-$(CONFIG_DW_DMAC_CORE) += dw/
>  obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
>  obj-$(CONFIG_FSL_DMA) += fsldma.o
>  obj-$(CONFIG_FSL_EDMA) += fsl-edma.o
> +obj-$(CONFIG_FSL_QDMA) += fsl-qdma.o
>  obj-$(CONFIG_FSL_RAID) += fsl_raid.o
>  obj-$(CONFIG_HSU_DMA) += hsu/
>  obj-$(CONFIG_IMG_MDC_DMA) += img-mdc-dma.o
> diff --git a/drivers/dma/fsl-qdma.c b/drivers/dma/fsl-qdma.c
> new file mode 100644
> index 0000000..404869e
> --- /dev/null
> +++ b/drivers/dma/fsl-qdma.c
> @@ -0,0 +1,1257 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright 2018 NXP

I'm not sure if this is really the case.  The driver at least has been
sent out in 2015.  We should keep these copyright claims, even the
legacy Freescale copyright claims.

> +
> +/*
> + * Driver for NXP Layerscape Queue Direct Memory Access Controller
> + *
> + * Author:
> + *  Wen He <wen.he_1@nxp.com>
> + *  Jiaheng Fan <jiaheng.fan@nxp.com>
> + *
> + */
> +
> +#include <linux/module.h>
> +#include <linux/delay.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_platform.h>
> +#include <linux/of_dma.h>
> +#include <linux/dma-mapping.h>
> +
> +#include "virt-dma.h"
> +#include "fsldma.h"
> +
> +/* Register related definition */
> +#define FSL_QDMA_DMR                   0x0
> +#define FSL_QDMA_DSR                   0x4
> +#define FSL_QDMA_DEIER                 0xe00
> +#define FSL_QDMA_DEDR                  0xe04
> +#define FSL_QDMA_DECFDW0R              0xe10
> +#define FSL_QDMA_DECFDW1R              0xe14
> +#define FSL_QDMA_DECFDW2R              0xe18
> +#define FSL_QDMA_DECFDW3R              0xe1c
> +#define FSL_QDMA_DECFQIDR              0xe30
> +#define FSL_QDMA_DECBR                 0xe34
> +
> +#define FSL_QDMA_BCQMR(x)              (0xc0 + 0x100 * (x))
> +#define FSL_QDMA_BCQSR(x)              (0xc4 + 0x100 * (x))
> +#define FSL_QDMA_BCQEDPA_SADDR(x)      (0xc8 + 0x100 * (x))
> +#define FSL_QDMA_BCQDPA_SADDR(x)       (0xcc + 0x100 * (x))
> +#define FSL_QDMA_BCQEEPA_SADDR(x)      (0xd0 + 0x100 * (x))
> +#define FSL_QDMA_BCQEPA_SADDR(x)       (0xd4 + 0x100 * (x))
> +#define FSL_QDMA_BCQIER(x)             (0xe0 + 0x100 * (x))
> +#define FSL_QDMA_BCQIDR(x)             (0xe4 + 0x100 * (x))
> +
> +#define FSL_QDMA_SQDPAR                        0x80c
> +#define FSL_QDMA_SQEPAR                        0x814
> +#define FSL_QDMA_BSQMR                 0x800
> +#define FSL_QDMA_BSQSR                 0x804
> +#define FSL_QDMA_BSQICR                        0x828
> +#define FSL_QDMA_CQMR                  0xa00
> +#define FSL_QDMA_CQDSCR1               0xa08
> +#define FSL_QDMA_CQDSCR2                0xa0c
> +#define FSL_QDMA_CQIER                 0xa10
> +#define FSL_QDMA_CQEDR                 0xa14
> +#define FSL_QDMA_SQCCMR                        0xa20
> +
> +/* Registers for bit and genmask */
> +#define FSL_QDMA_CQIDR_SQT             BIT(15)
> +#define QDMA_CCDF_FOTMAT               BIT(29)
> +#define QDMA_CCDF_SER                  BIT(30)
> +#define QDMA_SG_FIN                    BIT(30)
> +#define QDMA_SG_LEN_MASK               GENMASK(29, 0)
> +#define QDMA_CCDF_MASK                 GENMASK(28, 20)
> +
> +#define FSL_QDMA_DEDR_CLEAR            GENMASK(31, 0)
> +#define FSL_QDMA_BCQIDR_CLEAR          GENMASK(31, 0)
> +#define FSL_QDMA_DEIER_CLEAR           GENMASK(31, 0)
> +
> +#define FSL_QDMA_BCQIER_CQTIE          BIT(15)
> +#define FSL_QDMA_BCQIER_CQPEIE         BIT(23)
> +#define FSL_QDMA_BSQICR_ICEN           BIT(31)
> +
> +#define FSL_QDMA_BSQICR_ICST(x)                ((x) << 16)
> +#define FSL_QDMA_CQIER_MEIE            BIT(31)
> +#define FSL_QDMA_CQIER_TEIE            BIT(0)
> +#define FSL_QDMA_SQCCMR_ENTER_WM       BIT(21)
> +
> +#define FSL_QDMA_BCQMR_EN              BIT(31)
> +#define FSL_QDMA_BCQMR_EI              BIT(30)
> +#define FSL_QDMA_BCQMR_CD_THLD(x)      ((x) << 20)
> +#define FSL_QDMA_BCQMR_CQ_SIZE(x)      ((x) << 16)
> +
> +#define FSL_QDMA_BCQSR_QF              BIT(16)
> +#define FSL_QDMA_BCQSR_XOFF            BIT(0)
> +
> +#define FSL_QDMA_BSQMR_EN              BIT(31)
> +#define FSL_QDMA_BSQMR_DI              BIT(30)
> +#define FSL_QDMA_BSQMR_CQ_SIZE(x)      ((x) << 16)
> +
> +#define FSL_QDMA_BSQSR_QE              BIT(17)
> +
> +#define FSL_QDMA_DMR_DQD               BIT(30)
> +#define FSL_QDMA_DSR_DB                BIT(31)
> +
> +/* Size related definition */
> +#define FSL_QDMA_QUEUE_MAX             8
> +#define FSL_QDMA_COMMAND_BUFFER_SIZE   64
> +#define FSL_QDMA_DESCRIPTOR_BUFFER_SIZE 32
> +#define FSL_QDMA_CIRCULAR_DESC_SIZE_MIN        64
> +#define FSL_QDMA_CIRCULAR_DESC_SIZE_MAX        16384
> +#define FSL_QDMA_QUEUE_NUM_MAX         8
> +
> +/* Field definition for CMD */
> +#define FSL_QDMA_CMD_RWTTYPE           0x4
> +#define FSL_QDMA_CMD_LWC                0x2
> +#define FSL_QDMA_CMD_RWTTYPE_OFFSET    28
> +#define FSL_QDMA_CMD_NS_OFFSET         27
> +#define FSL_QDMA_CMD_DQOS_OFFSET       24
> +#define FSL_QDMA_CMD_WTHROTL_OFFSET    20
> +#define FSL_QDMA_CMD_DSEN_OFFSET       19
> +#define FSL_QDMA_CMD_LWC_OFFSET                16
> +
> +/* Field definition for Descriptor offset */
> +#define QDMA_CCDF_STATUS               20
> +#define QDMA_CCDF_OFFSET               20
> +
> +/* Field definition for safe loop count*/
> +#define FSL_QDMA_HALT_COUNT            1500
> +#define FSL_QDMA_MAX_SIZE              16385
> +#define        FSL_QDMA_COMP_TIMEOUT           1000
> +#define FSL_COMMAND_QUEUE_OVERFLLOW    10
> +
> +#define FSL_QDMA_BLOCK_BASE_OFFSET(fsl_qdma_engine, x)                 \
> +       (((fsl_qdma_engine)->block_offset) * (x))
> +
> +/**
> + * struct fsl_qdma_format - This is the struct holding describing compound
> + *                         descriptor format with qDMA.
> + * @status:                Command status and enqueue status notification.
> + * @cfg:                   Frame offset and frame format.
> + * @addr_lo:               Holding the compound descriptor of the lower
> + *                         32-bits address in memory 40-bit address.
> + * @addr_hi:               Same as above member, but point high 8-bits in
> + *                         memory 40-bit address.
> + * @__reserved1:           Reserved field.
> + * @cfg8b_w1:              Compound descriptor command queue origin produced
> + *                         by qDMA and dynamic debug field.
> + * @data                   Pointer to the memory 40-bit address, describes DMA
> + *                         source information and DMA destination information.
> + */
> +struct fsl_qdma_format {
> +       __le32 status;
> +       __le32 cfg;
> +       union {
> +               struct {
> +                       __le32 addr_lo;
> +                       u8 addr_hi;
> +                       u8 __reserved1[2];
> +                       u8 cfg8b_w1;
> +               } __packed;
> +               __le64 data;
> +       };
> +} __packed;
> +
> +/* qDMA status notification pre information */
> +struct fsl_pre_status {
> +       u64 addr;
> +       u8 queue;
> +};
> +
> +static DEFINE_PER_CPU(struct fsl_pre_status, pre);
> +
> +struct fsl_qdma_chan {
> +       struct virt_dma_chan            vchan;
> +       struct virt_dma_desc            vdesc;
> +       enum dma_status                 status;
> +       struct fsl_qdma_engine          *qdma;
> +       struct fsl_qdma_queue           *queue;
> +};
> +
> +struct fsl_qdma_queue {
> +       struct fsl_qdma_format  *virt_head;
> +       struct fsl_qdma_format  *virt_tail;
> +       struct list_head        comp_used;
> +       struct list_head        comp_free;
> +       struct dma_pool         *comp_pool;
> +       struct dma_pool         *desc_pool;
> +       spinlock_t              queue_lock;
> +       dma_addr_t              bus_addr;
> +       u32                     n_cq;
> +       u32                     id;
> +       struct fsl_qdma_format  *cq;
> +       void __iomem            *block_base;
> +};
> +
> +struct fsl_qdma_comp {
> +       dma_addr_t              bus_addr;
> +       dma_addr_t              desc_bus_addr;
> +       struct fsl_qdma_format  *virt_addr;
> +       struct fsl_qdma_format  *desc_virt_addr;
> +       struct fsl_qdma_chan    *qchan;
> +       struct virt_dma_desc    vdesc;
> +       struct list_head        list;
> +};
> +
> +struct fsl_qdma_engine {
> +       struct dma_device       dma_dev;
> +       void __iomem            *ctrl_base;
> +       void __iomem            *status_base;
> +       void __iomem            *block_base;
> +       u32                     n_chans;
> +       u32                     n_queues;
> +       struct mutex            fsl_qdma_mutex;
> +       int                     error_irq;
> +       int                     *queue_irq;
> +       u32                     feature;
> +       struct fsl_qdma_queue   *queue;
> +       struct fsl_qdma_queue   **status;
> +       struct fsl_qdma_chan    *chans;
> +       int                     block_number;
> +       int                     block_offset;
> +       int                     irq_base;
> +       int                     desc_allocated;
> +
> +};
> +
> +static inline u64
> +qdma_ccdf_addr_get64(const struct fsl_qdma_format *ccdf)
> +{
> +       return le64_to_cpu(ccdf->data) & (U64_MAX >> 24);
> +}
> +
> +static inline void
> +qdma_desc_addr_set64(struct fsl_qdma_format *ccdf, u64 addr)
> +{
> +       ccdf->addr_hi = upper_32_bits(addr);
> +       ccdf->addr_lo = cpu_to_le32(lower_32_bits(addr));
> +}
> +
> +static inline u8
> +qdma_ccdf_get_queue(const struct fsl_qdma_format *ccdf)
> +{
> +       return ccdf->cfg8b_w1 & U8_MAX;
> +}
> +
> +static inline int
> +qdma_ccdf_get_offset(const struct fsl_qdma_format *ccdf)
> +{
> +       return (le32_to_cpu(ccdf->cfg) & QDMA_CCDF_MASK) >> QDMA_CCDF_OFFSET;
> +}
> +
> +static inline void
> +qdma_ccdf_set_format(struct fsl_qdma_format *ccdf, int offset)
> +{
> +       ccdf->cfg = cpu_to_le32(QDMA_CCDF_FOTMAT | offset);
> +}
> +
> +static inline int
> +qdma_ccdf_get_status(const struct fsl_qdma_format *ccdf)
> +{
> +       return (le32_to_cpu(ccdf->status) & QDMA_CCDF_MASK) >> QDMA_CCDF_STATUS;
> +}
> +
> +static inline void
> +qdma_ccdf_set_ser(struct fsl_qdma_format *ccdf, int status)
> +{
> +       ccdf->status = cpu_to_le32(QDMA_CCDF_SER | status);
> +}
> +
> +static inline void qdma_csgf_set_len(struct fsl_qdma_format *csgf, int len)
> +{
> +       csgf->cfg = cpu_to_le32(len & QDMA_SG_LEN_MASK);
> +}
> +
> +static inline void qdma_csgf_set_f(struct fsl_qdma_format *csgf, int len)
> +{
> +       csgf->cfg = cpu_to_le32(QDMA_SG_FIN | (len & QDMA_SG_LEN_MASK));
> +}
> +
> +static u32 qdma_readl(struct fsl_qdma_engine *qdma, void __iomem *addr)
> +{
> +       return FSL_DMA_IN(qdma, addr, 32);
> +}
> +
> +static void qdma_writel(struct fsl_qdma_engine *qdma, u32 val,
> +                       void __iomem *addr)
> +{
> +       FSL_DMA_OUT(qdma, addr, val, 32);
> +}
> +
> +static struct fsl_qdma_chan *to_fsl_qdma_chan(struct dma_chan *chan)
> +{
> +       return container_of(chan, struct fsl_qdma_chan, vchan.chan);
> +}
> +
> +static struct fsl_qdma_comp *to_fsl_qdma_comp(struct virt_dma_desc *vd)
> +{
> +       return container_of(vd, struct fsl_qdma_comp, vdesc);
> +}
> +
> +static void fsl_qdma_free_chan_resources(struct dma_chan *chan)
> +{
> +       struct fsl_qdma_chan *fsl_chan = to_fsl_qdma_chan(chan);
> +       struct fsl_qdma_queue *fsl_queue = fsl_chan->queue;
> +       struct fsl_qdma_engine *fsl_qdma = fsl_chan->qdma;
> +       struct fsl_qdma_comp *comp_temp, *_comp_temp;
> +       unsigned long flags;
> +       LIST_HEAD(head);
> +
> +       spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
> +       vchan_get_all_descriptors(&fsl_chan->vchan, &head);
> +       spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
> +
> +       vchan_dma_desc_free_list(&fsl_chan->vchan, &head);
> +
> +       if (!fsl_queue->comp_pool && !fsl_queue->comp_pool)
> +               return;
> +
> +       list_for_each_entry_safe(comp_temp, _comp_temp,
> +                                &fsl_queue->comp_used, list) {
> +               dma_pool_free(fsl_queue->comp_pool,
> +                             comp_temp->virt_addr,
> +                             comp_temp->bus_addr);
> +               dma_pool_free(fsl_queue->desc_pool,
> +                             comp_temp->desc_virt_addr,
> +                             comp_temp->desc_bus_addr);
> +               list_del(&comp_temp->list);
> +               kfree(comp_temp);
> +       }
> +
> +       list_for_each_entry_safe(comp_temp, _comp_temp,
> +                                &fsl_queue->comp_free, list) {
> +               dma_pool_free(fsl_queue->comp_pool,
> +                             comp_temp->virt_addr,
> +                             comp_temp->bus_addr);
> +               dma_pool_free(fsl_queue->desc_pool,
> +                             comp_temp->desc_virt_addr,
> +                             comp_temp->desc_bus_addr);
> +               list_del(&comp_temp->list);
> +               kfree(comp_temp);
> +       }
> +
> +       dma_pool_destroy(fsl_queue->comp_pool);
> +       dma_pool_destroy(fsl_queue->desc_pool);
> +
> +       fsl_qdma->desc_allocated--;
> +       fsl_queue->comp_pool = NULL;
> +       fsl_queue->desc_pool = NULL;
> +}
> +
> +static void fsl_qdma_comp_fill_memcpy(struct fsl_qdma_comp *fsl_comp,
> +                                     dma_addr_t dst, dma_addr_t src, u32 len)
> +{
> +       struct fsl_qdma_format *sdf, *ddf;
> +       struct fsl_qdma_format *ccdf, *csgf_desc, *csgf_src, *csgf_dest;
> +
> +       ccdf = fsl_comp->virt_addr;
> +       csgf_desc = fsl_comp->virt_addr + 1;
> +       csgf_src = fsl_comp->virt_addr + 2;
> +       csgf_dest = fsl_comp->virt_addr + 3;
> +       sdf = fsl_comp->desc_virt_addr;
> +       ddf = fsl_comp->desc_virt_addr + 1;
> +
> +       memset(fsl_comp->virt_addr, 0, FSL_QDMA_COMMAND_BUFFER_SIZE);
> +       memset(fsl_comp->desc_virt_addr, 0, FSL_QDMA_DESCRIPTOR_BUFFER_SIZE);
> +       /* Head Command Descriptor(Frame Descriptor) */
> +       qdma_desc_addr_set64(ccdf, fsl_comp->bus_addr + 16);
> +       qdma_ccdf_set_format(ccdf, qdma_ccdf_get_offset(ccdf));
> +       qdma_ccdf_set_ser(ccdf, qdma_ccdf_get_status(ccdf));
> +       /* Status notification is enqueued to status queue. */
> +       /* Compound Command Descriptor(Frame List Table) */
> +       qdma_desc_addr_set64(csgf_desc, fsl_comp->desc_bus_addr);
> +       /* It must be 32 as Compound S/G Descriptor */
> +       qdma_csgf_set_len(csgf_desc, 32);
> +       qdma_desc_addr_set64(csgf_src, src);
> +       qdma_csgf_set_len(csgf_src, len);
> +       qdma_desc_addr_set64(csgf_dest, dst);
> +       qdma_csgf_set_len(csgf_dest, len);
> +       /* This entry is the last entry. */
> +       qdma_csgf_set_f(csgf_dest, len);
> +       /* Descriptor Buffer */
> +       sdf->data =
> +               cpu_to_le64(FSL_QDMA_CMD_RWTTYPE <<
> +                           FSL_QDMA_CMD_RWTTYPE_OFFSET);
> +       ddf->data =
> +               cpu_to_le64(FSL_QDMA_CMD_RWTTYPE <<
> +                           FSL_QDMA_CMD_RWTTYPE_OFFSET);
> +       ddf->data |=
> +               cpu_to_le64(FSL_QDMA_CMD_LWC << FSL_QDMA_CMD_LWC_OFFSET);
> +}
> +
> +/*
> + * Pre-request full command descriptor for enqueue.
> + */
> +static int fsl_qdma_pre_request_enqueue_desc(struct fsl_qdma_queue *queue)
> +{
> +       int i;
> +       struct fsl_qdma_comp *comp_temp, *_comp_temp;
> +
> +       for (i = 0; i < queue->n_cq + FSL_COMMAND_QUEUE_OVERFLLOW; i++) {
> +               comp_temp = kzalloc(sizeof(*comp_temp), GFP_KERNEL);
> +               if (!comp_temp)
> +                       goto err_alloc;
> +               comp_temp->virt_addr =
> +                       dma_pool_alloc(queue->comp_pool, GFP_KERNEL,
> +                                      &comp_temp->bus_addr);
> +               if (!comp_temp->virt_addr)
> +                       goto err_dma_alloc;
> +
> +               comp_temp->desc_virt_addr =
> +                       dma_pool_alloc(queue->desc_pool, GFP_KERNEL,
> +                                      &comp_temp->desc_bus_addr);
> +               if (!comp_temp->desc_virt_addr)
> +                       goto err_desc_dma_alloc;
> +
> +               list_add_tail(&comp_temp->list, &queue->comp_free);
> +       }
> +
> +       return 0;
> +
> +err_desc_dma_alloc:
> +       dma_pool_free(queue->comp_pool, comp_temp->virt_addr,
> +                     comp_temp->bus_addr);
> +
> +err_dma_alloc:
> +       kfree(comp_temp);
> +
> +err_alloc:
> +       list_for_each_entry_safe(comp_temp, _comp_temp,
> +                                &queue->comp_free, list) {
> +               if (comp_temp->virt_addr)
> +                       dma_pool_free(queue->comp_pool,
> +                                     comp_temp->virt_addr,
> +                                     comp_temp->bus_addr);
> +               if (comp_temp->desc_virt_addr)
> +                       dma_pool_free(queue->desc_pool,
> +                                     comp_temp->desc_virt_addr,
> +                                     comp_temp->desc_bus_addr);
> +
> +               list_del(&comp_temp->list);
> +               kfree(comp_temp);
> +       }
> +
> +       return -ENOMEM;
> +}
> +
> +/*
> + * Request a command descriptor for enqueue.
> + */
> +static struct fsl_qdma_comp
> +*fsl_qdma_request_enqueue_desc(struct fsl_qdma_chan *fsl_chan)
> +{
> +       unsigned long flags;
> +       struct fsl_qdma_comp *comp_temp;
> +       int timeout = FSL_QDMA_COMP_TIMEOUT;
> +       struct fsl_qdma_queue *queue = fsl_chan->queue;
> +
> +       while (timeout--) {
> +               spin_lock_irqsave(&queue->queue_lock, flags);
> +               if (!list_empty(&queue->comp_free)) {
> +                       comp_temp = list_first_entry(&queue->comp_free,
> +                                                    struct fsl_qdma_comp,
> +                                                    list);
> +                       list_del(&comp_temp->list);
> +
> +                       spin_unlock_irqrestore(&queue->queue_lock, flags);
> +                       comp_temp->qchan = fsl_chan;
> +                       return comp_temp;
> +               }
> +               spin_unlock_irqrestore(&queue->queue_lock, flags);
> +               udelay(1);
> +       }
> +
> +       return NULL;
> +}
> +
> +static struct fsl_qdma_queue
> +*fsl_qdma_alloc_queue_resources(struct platform_device *pdev,
> +                               struct fsl_qdma_engine *fsl_qdma)
> +{
> +       int ret, len, i, j;
> +       int queue_num, block_number;
> +       unsigned int queue_size[FSL_QDMA_QUEUE_MAX];
> +       struct fsl_qdma_queue *queue_head, *queue_temp;
> +
> +       queue_num = fsl_qdma->n_queues;
> +       block_number = fsl_qdma->block_number;
> +
> +       if (queue_num > FSL_QDMA_QUEUE_MAX)
> +               queue_num = FSL_QDMA_QUEUE_MAX;
> +       len = sizeof(*queue_head) * queue_num * block_number;
> +       queue_head = devm_kzalloc(&pdev->dev, len, GFP_KERNEL);
> +       if (!queue_head)
> +               return NULL;
> +
> +       ret = device_property_read_u32_array(&pdev->dev, "queue-sizes",
> +                                            queue_size, queue_num);
> +       if (ret) {
> +               dev_err(&pdev->dev, "Can't get queue-sizes.\n");
> +               return NULL;
> +       }
> +       for (j = 0; j < block_number; j++) {
> +               for (i = 0; i < queue_num; i++) {
> +                       if (queue_size[i] > FSL_QDMA_CIRCULAR_DESC_SIZE_MAX ||
> +                           queue_size[i] < FSL_QDMA_CIRCULAR_DESC_SIZE_MIN) {
> +                               dev_err(&pdev->dev,
> +                                       "Get wrong queue-sizes.\n");
> +                               return NULL;
> +                       }
> +                       queue_temp = queue_head + i + (j * queue_num);
> +
> +                       queue_temp->cq =
> +                       dma_alloc_coherent(&pdev->dev,
> +                                          sizeof(struct fsl_qdma_format) *
> +                                          queue_size[i],
> +                                          &queue_temp->bus_addr,
> +                                          GFP_KERNEL);
> +                       if (!queue_temp->cq)
> +                               return NULL;
> +                       queue_temp->block_base = fsl_qdma->block_base +
> +                               FSL_QDMA_BLOCK_BASE_OFFSET(fsl_qdma, j);
> +                       queue_temp->n_cq = queue_size[i];
> +                       queue_temp->id = i;
> +                       queue_temp->virt_head = queue_temp->cq;
> +                       queue_temp->virt_tail = queue_temp->cq;
> +                       /*
> +                        * List for queue command buffer
> +                        */
> +                       INIT_LIST_HEAD(&queue_temp->comp_used);
> +                       spin_lock_init(&queue_temp->queue_lock);
> +               }
> +       }
> +       return queue_head;
> +}
> +
> +static struct fsl_qdma_queue
> +*fsl_qdma_prep_status_queue(struct platform_device *pdev)
> +{
> +       int ret;
> +       unsigned int status_size;
> +       struct fsl_qdma_queue *status_head;
> +       struct device_node *np = pdev->dev.of_node;
> +
> +       ret = of_property_read_u32(np, "status-sizes", &status_size);
> +       if (ret) {
> +               dev_err(&pdev->dev, "Can't get status-sizes.\n");
> +               return NULL;
> +       }
> +       if (status_size > FSL_QDMA_CIRCULAR_DESC_SIZE_MAX ||
> +           status_size < FSL_QDMA_CIRCULAR_DESC_SIZE_MIN) {
> +               dev_err(&pdev->dev, "Get wrong status_size.\n");
> +               return NULL;
> +       }
> +       status_head = devm_kzalloc(&pdev->dev,
> +                                  sizeof(*status_head), GFP_KERNEL);
> +       if (!status_head)
> +               return NULL;
> +
> +       /*
> +        * Buffer for queue command
> +        */
> +       status_head->cq = dma_alloc_coherent(&pdev->dev,
> +                                            sizeof(struct fsl_qdma_format) *
> +                                            status_size,
> +                                            &status_head->bus_addr,
> +                                            GFP_KERNEL);
> +       if (!status_head->cq) {
> +               devm_kfree(&pdev->dev, status_head);
> +               return NULL;
> +       }
> +       status_head->n_cq = status_size;
> +       status_head->virt_head = status_head->cq;
> +       status_head->virt_tail = status_head->cq;
> +       status_head->comp_pool = NULL;
> +
> +       return status_head;
> +}
> +
> +static int fsl_qdma_halt(struct fsl_qdma_engine *fsl_qdma)
> +{
> +       u32 reg;
> +       int i, j, count = FSL_QDMA_HALT_COUNT;
> +       void __iomem *block, *ctrl = fsl_qdma->ctrl_base;
> +
> +       /* Disable the command queue and wait for idle state. */
> +       reg = qdma_readl(fsl_qdma, ctrl + FSL_QDMA_DMR);
> +       reg |= FSL_QDMA_DMR_DQD;
> +       qdma_writel(fsl_qdma, reg, ctrl + FSL_QDMA_DMR);
> +       for (j = 0; j < fsl_qdma->block_number; j++) {
> +               block = fsl_qdma->block_base +
> +                       FSL_QDMA_BLOCK_BASE_OFFSET(fsl_qdma, j);
> +               for (i = 0; i < FSL_QDMA_QUEUE_NUM_MAX; i++)
> +                       qdma_writel(fsl_qdma, 0, block + FSL_QDMA_BCQMR(i));
> +       }
> +       while (1) {
> +               reg = qdma_readl(fsl_qdma, ctrl + FSL_QDMA_DSR);
> +               if (!(reg & FSL_QDMA_DSR_DB))
> +                       break;
> +               if (count-- < 0)
> +                       return -EBUSY;
> +               udelay(100);
> +       }
> +
> +       for (j = 0; j < fsl_qdma->block_number; j++) {
> +               block = fsl_qdma->block_base +
> +                       FSL_QDMA_BLOCK_BASE_OFFSET(fsl_qdma, j);
> +
> +               /* Disable status queue. */
> +               qdma_writel(fsl_qdma, 0, block + FSL_QDMA_BSQMR);
> +
> +               /*
> +                * clear the command queue interrupt detect register for
> +                * all queues.
> +                */
> +               qdma_writel(fsl_qdma, FSL_QDMA_BCQIDR_CLEAR,
> +                           block + FSL_QDMA_BCQIDR(0));
> +       }
> +
> +       return 0;
> +}
> +
> +static int
> +fsl_qdma_queue_transfer_complete(struct fsl_qdma_engine *fsl_qdma,
> +                                void *block,
> +                                int id)
> +{
> +       bool duplicate;
> +       u32 reg, i, count;
> +       struct fsl_qdma_queue *temp_queue;
> +       struct fsl_qdma_format *status_addr;
> +       struct fsl_qdma_comp *fsl_comp = NULL;
> +       struct fsl_qdma_queue *fsl_queue = fsl_qdma->queue;
> +       struct fsl_qdma_queue *fsl_status = fsl_qdma->status[id];
> +
> +       count = FSL_QDMA_MAX_SIZE;
> +
> +       while (count--) {
> +               duplicate = 0;
> +               reg = qdma_readl(fsl_qdma, block + FSL_QDMA_BSQSR);
> +               if (reg & FSL_QDMA_BSQSR_QE)
> +                       return 0;
> +
> +               status_addr = fsl_status->virt_head;
> +
> +               if (qdma_ccdf_get_queue(status_addr) ==
> +                  __this_cpu_read(pre.queue) &&
> +                       qdma_ccdf_addr_get64(status_addr) ==
> +                       __this_cpu_read(pre.addr))
> +                       duplicate = 1;
> +               i = qdma_ccdf_get_queue(status_addr) +
> +                       id * fsl_qdma->n_queues;
> +               __this_cpu_write(pre.addr, qdma_ccdf_addr_get64(status_addr));
> +               __this_cpu_write(pre.queue, qdma_ccdf_get_queue(status_addr));
> +               temp_queue = fsl_queue + i;
> +
> +               spin_lock(&temp_queue->queue_lock);
> +               if (list_empty(&temp_queue->comp_used)) {
> +                       if (!duplicate) {
> +                               spin_unlock(&temp_queue->queue_lock);
> +                               return -EAGAIN;
> +                       }
> +               } else {
> +                       fsl_comp = list_first_entry(&temp_queue->comp_used,
> +                                                   struct fsl_qdma_comp, list);
> +                       if (fsl_comp->bus_addr + 16 !=
> +                               __this_cpu_read(pre.addr)) {
> +                               if (!duplicate) {
> +                                       spin_unlock(&temp_queue->queue_lock);
> +                                       return -EAGAIN;
> +                               }
> +                       }
> +               }
> +
> +               if (duplicate) {
> +                       reg = qdma_readl(fsl_qdma, block + FSL_QDMA_BSQMR);
> +                       reg |= FSL_QDMA_BSQMR_DI;
> +                       qdma_desc_addr_set64(status_addr, 0x0);
> +                       fsl_status->virt_head++;
> +                       if (fsl_status->virt_head == fsl_status->cq
> +                                                  + fsl_status->n_cq)
> +                               fsl_status->virt_head = fsl_status->cq;
> +                       qdma_writel(fsl_qdma, reg, block + FSL_QDMA_BSQMR);
> +                       spin_unlock(&temp_queue->queue_lock);
> +                       continue;
> +               }
> +               list_del(&fsl_comp->list);
> +
> +               reg = qdma_readl(fsl_qdma, block + FSL_QDMA_BSQMR);
> +               reg |= FSL_QDMA_BSQMR_DI;
> +               qdma_desc_addr_set64(status_addr, 0x0);
> +               fsl_status->virt_head++;
> +               if (fsl_status->virt_head == fsl_status->cq + fsl_status->n_cq)
> +                       fsl_status->virt_head = fsl_status->cq;
> +               qdma_writel(fsl_qdma, reg, block + FSL_QDMA_BSQMR);
> +               spin_unlock(&temp_queue->queue_lock);
> +
> +               spin_lock(&fsl_comp->qchan->vchan.lock);
> +               vchan_cookie_complete(&fsl_comp->vdesc);
> +               fsl_comp->qchan->status = DMA_COMPLETE;
> +               spin_unlock(&fsl_comp->qchan->vchan.lock);
> +       }
> +
> +       return 0;
> +}
> +
> +static irqreturn_t fsl_qdma_error_handler(int irq, void *dev_id)
> +{
> +       unsigned int intr;
> +       struct fsl_qdma_engine *fsl_qdma = dev_id;
> +       void __iomem *status = fsl_qdma->status_base;
> +
> +       intr = qdma_readl(fsl_qdma, status + FSL_QDMA_DEDR);
> +
> +       if (intr) {
> +               dev_err(fsl_qdma->dma_dev.dev, "DMA transaction error!\n");
> +               return IRQ_NONE;
> +       }
> +
> +       qdma_writel(fsl_qdma, FSL_QDMA_DEDR_CLEAR, status + FSL_QDMA_DEDR);
> +       return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t fsl_qdma_queue_handler(int irq, void *dev_id)
> +{
> +       int id;
> +       unsigned int intr, reg;
> +       struct fsl_qdma_engine *fsl_qdma = dev_id;
> +       void __iomem *block, *ctrl = fsl_qdma->ctrl_base;
> +
> +       id = irq - fsl_qdma->irq_base;
> +       if (id < 0 && id > fsl_qdma->block_number) {
> +               dev_err(fsl_qdma->dma_dev.dev,
> +                       "irq %d is wrong irq_base is %d\n",
> +                       irq, fsl_qdma->irq_base);
> +       }
> +
> +       block = fsl_qdma->block_base +
> +               FSL_QDMA_BLOCK_BASE_OFFSET(fsl_qdma, id);
> +
> +       intr = qdma_readl(fsl_qdma, block + FSL_QDMA_BCQIDR(0));
> +
> +       if ((intr & FSL_QDMA_CQIDR_SQT) != 0)
> +               intr = fsl_qdma_queue_transfer_complete(fsl_qdma, block, id);
> +
> +       if (intr != 0) {
> +               reg = qdma_readl(fsl_qdma, ctrl + FSL_QDMA_DMR);
> +               reg |= FSL_QDMA_DMR_DQD;
> +               qdma_writel(fsl_qdma, reg, ctrl + FSL_QDMA_DMR);
> +               qdma_writel(fsl_qdma, 0, block + FSL_QDMA_BCQIER(0));
> +               dev_err(fsl_qdma->dma_dev.dev, "QDMA: status err!\n");
> +       }
> +
> +       /* Clear all detected events and interrupts. */
> +       qdma_writel(fsl_qdma, FSL_QDMA_BCQIDR_CLEAR,
> +                   block + FSL_QDMA_BCQIDR(0));
> +
> +       return IRQ_HANDLED;
> +}
> +
> +static int
> +fsl_qdma_irq_init(struct platform_device *pdev,
> +                 struct fsl_qdma_engine *fsl_qdma)
> +{
> +       int i;
> +       int cpu;
> +       int ret;
> +       char irq_name[20];
> +
> +       fsl_qdma->error_irq =
> +               platform_get_irq_byname(pdev, "qdma-error");
> +       if (fsl_qdma->error_irq < 0) {
> +               dev_err(&pdev->dev, "Can't get qdma controller irq.\n");
> +               return fsl_qdma->error_irq;
> +       }
> +
> +       ret = devm_request_irq(&pdev->dev, fsl_qdma->error_irq,
> +                              fsl_qdma_error_handler, 0,
> +                              "qDMA error", fsl_qdma);
> +       if (ret) {
> +               dev_err(&pdev->dev, "Can't register qDMA controller IRQ.\n");
> +               return  ret;
> +       }
> +
> +       for (i = 0; i < fsl_qdma->block_number; i++) {
> +               sprintf(irq_name, "qdma-queue%d", i);
> +               fsl_qdma->queue_irq[i] =
> +                               platform_get_irq_byname(pdev, irq_name);
> +
> +               if (fsl_qdma->queue_irq[i] < 0) {
> +                       dev_err(&pdev->dev,
> +                               "Can't get qdma queue %d irq.\n", i);
> +                       return fsl_qdma->queue_irq[i];
> +               }
> +
> +               ret = devm_request_irq(&pdev->dev,
> +                                      fsl_qdma->queue_irq[i],
> +                                      fsl_qdma_queue_handler,
> +                                      0,
> +                                      "qDMA queue",
> +                                      fsl_qdma);
> +               if (ret) {
> +                       dev_err(&pdev->dev,
> +                               "Can't register qDMA queue IRQ.\n");
> +                       return  ret;
> +               }
> +
> +               cpu = i % num_online_cpus();
> +               ret = irq_set_affinity_hint(fsl_qdma->queue_irq[i],
> +                                           get_cpu_mask(cpu));
> +               if (ret) {
> +                       dev_err(&pdev->dev,
> +                               "Can't set cpu %d affinity to IRQ %d.\n",
> +                               cpu,
> +                               fsl_qdma->queue_irq[i]);
> +                       return  ret;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +static void fsl_qdma_irq_exit(struct platform_device *pdev,
> +                             struct fsl_qdma_engine *fsl_qdma)
> +{
> +       int i;
> +
> +       devm_free_irq(&pdev->dev, fsl_qdma->error_irq, fsl_qdma);
> +       for (i = 0; i < fsl_qdma->block_number; i++)
> +               devm_free_irq(&pdev->dev, fsl_qdma->queue_irq[i], fsl_qdma);
> +}
> +
> +static int fsl_qdma_reg_init(struct fsl_qdma_engine *fsl_qdma)
> +{
> +       u32 reg;
> +       int i, j, ret;
> +       struct fsl_qdma_queue *temp;
> +       void __iomem *status = fsl_qdma->status_base;
> +       void __iomem *block, *ctrl = fsl_qdma->ctrl_base;
> +       struct fsl_qdma_queue *fsl_queue = fsl_qdma->queue;
> +
> +       /* Try to halt the qDMA engine first. */
> +       ret = fsl_qdma_halt(fsl_qdma);
> +       if (ret) {
> +               dev_err(fsl_qdma->dma_dev.dev, "DMA halt failed!");
> +               return ret;
> +       }
> +
> +       for (i = 0; i < fsl_qdma->block_number; i++) {
> +               /*
> +                * Clear the command queue interrupt detect register for
> +                * all queues.
> +                */
> +
> +               block = fsl_qdma->block_base +
> +                       FSL_QDMA_BLOCK_BASE_OFFSET(fsl_qdma, i);
> +               qdma_writel(fsl_qdma, FSL_QDMA_BCQIDR_CLEAR,
> +                           block + FSL_QDMA_BCQIDR(0));
> +       }
> +
> +       for (j = 0; j < fsl_qdma->block_number; j++) {
> +               block = fsl_qdma->block_base +
> +                       FSL_QDMA_BLOCK_BASE_OFFSET(fsl_qdma, j);
> +               for (i = 0; i < fsl_qdma->n_queues; i++) {
> +                       temp = fsl_queue + i + (j * fsl_qdma->n_queues);
> +                       /*
> +                        * Initialize Command Queue registers to
> +                        * point to the first
> +                        * command descriptor in memory.
> +                        * Dequeue Pointer Address Registers
> +                        * Enqueue Pointer Address Registers
> +                        */
> +
> +                       qdma_writel(fsl_qdma, temp->bus_addr,
> +                                   block + FSL_QDMA_BCQDPA_SADDR(i));
> +                       qdma_writel(fsl_qdma, temp->bus_addr,
> +                                   block + FSL_QDMA_BCQEPA_SADDR(i));
> +
> +                       /* Initialize the queue mode. */
> +                       reg = FSL_QDMA_BCQMR_EN;
> +                       reg |= FSL_QDMA_BCQMR_CD_THLD(ilog2(temp->n_cq) - 4);
> +                       reg |= FSL_QDMA_BCQMR_CQ_SIZE(ilog2(temp->n_cq) - 6);
> +                       qdma_writel(fsl_qdma, reg, block + FSL_QDMA_BCQMR(i));
> +               }
> +
> +               /*
> +                * Workaround for erratum: ERR010812.
> +                * We must enable XOFF to avoid the enqueue rejection occurs.
> +                * Setting SQCCMR ENTER_WM to 0x20.
> +                */
> +
> +               qdma_writel(fsl_qdma, FSL_QDMA_SQCCMR_ENTER_WM,
> +                           block + FSL_QDMA_SQCCMR);
> +
> +               /*
> +                * Initialize status queue registers to point to the first
> +                * command descriptor in memory.
> +                * Dequeue Pointer Address Registers
> +                * Enqueue Pointer Address Registers
> +                */
> +
> +               qdma_writel(fsl_qdma, fsl_qdma->status[j]->bus_addr,
> +                           block + FSL_QDMA_SQEPAR);
> +               qdma_writel(fsl_qdma, fsl_qdma->status[j]->bus_addr,
> +                           block + FSL_QDMA_SQDPAR);
> +               /* Initialize status queue interrupt. */
> +               qdma_writel(fsl_qdma, FSL_QDMA_BCQIER_CQTIE,
> +                           block + FSL_QDMA_BCQIER(0));
> +               qdma_writel(fsl_qdma, FSL_QDMA_BSQICR_ICEN |
> +                                  FSL_QDMA_BSQICR_ICST(5) | 0x8000,
> +                                  block + FSL_QDMA_BSQICR);
> +               qdma_writel(fsl_qdma, FSL_QDMA_CQIER_MEIE |
> +                                  FSL_QDMA_CQIER_TEIE,
> +                                  block + FSL_QDMA_CQIER);
> +
> +               /* Initialize the status queue mode. */
> +               reg = FSL_QDMA_BSQMR_EN;
> +               reg |= FSL_QDMA_BSQMR_CQ_SIZE(ilog2
> +                       (fsl_qdma->status[j]->n_cq) - 6);
> +
> +               qdma_writel(fsl_qdma, reg, block + FSL_QDMA_BSQMR);
> +               reg = qdma_readl(fsl_qdma, block + FSL_QDMA_BSQMR);
> +       }
> +
> +       /* Initialize controller interrupt register. */
> +       qdma_writel(fsl_qdma, FSL_QDMA_DEDR_CLEAR, status + FSL_QDMA_DEDR);
> +       qdma_writel(fsl_qdma, FSL_QDMA_DEIER_CLEAR, status + FSL_QDMA_DEIER);
> +
> +       reg = qdma_readl(fsl_qdma, ctrl + FSL_QDMA_DMR);
> +       reg &= ~FSL_QDMA_DMR_DQD;
> +       qdma_writel(fsl_qdma, reg, ctrl + FSL_QDMA_DMR);
> +
> +       return 0;
> +}
> +
> +static struct dma_async_tx_descriptor *
> +fsl_qdma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst,
> +                    dma_addr_t src, size_t len, unsigned long flags)
> +{
> +       struct fsl_qdma_comp *fsl_comp;
> +       struct fsl_qdma_chan *fsl_chan = to_fsl_qdma_chan(chan);
> +
> +       fsl_comp = fsl_qdma_request_enqueue_desc(fsl_chan);
> +
> +       if (!fsl_comp)
> +               return NULL;
> +
> +       fsl_qdma_comp_fill_memcpy(fsl_comp, dst, src, len);
> +
> +       return vchan_tx_prep(&fsl_chan->vchan, &fsl_comp->vdesc, flags);
> +}
> +
> +static void fsl_qdma_enqueue_desc(struct fsl_qdma_chan *fsl_chan)
> +{
> +       u32 reg;
> +       struct virt_dma_desc *vdesc;
> +       struct fsl_qdma_comp *fsl_comp;
> +       struct fsl_qdma_queue *fsl_queue = fsl_chan->queue;
> +       void __iomem *block = fsl_queue->block_base;
> +
> +       reg = qdma_readl(fsl_chan->qdma, block + FSL_QDMA_BCQSR(fsl_queue->id));
> +       if (reg & (FSL_QDMA_BCQSR_QF | FSL_QDMA_BCQSR_XOFF))
> +               return;
> +       vdesc = vchan_next_desc(&fsl_chan->vchan);
> +       if (!vdesc)
> +               return;
> +       list_del(&vdesc->node);
> +       fsl_comp = to_fsl_qdma_comp(vdesc);
> +
> +       memcpy(fsl_queue->virt_head++,
> +              fsl_comp->virt_addr, sizeof(struct fsl_qdma_format));
> +       if (fsl_queue->virt_head == fsl_queue->cq + fsl_queue->n_cq)
> +               fsl_queue->virt_head = fsl_queue->cq;
> +
> +       list_add_tail(&fsl_comp->list, &fsl_queue->comp_used);
> +       barrier();
> +       reg = qdma_readl(fsl_chan->qdma, block + FSL_QDMA_BCQMR(fsl_queue->id));
> +       reg |= FSL_QDMA_BCQMR_EI;
> +       qdma_writel(fsl_chan->qdma, reg, block + FSL_QDMA_BCQMR(fsl_queue->id));
> +       fsl_chan->status = DMA_IN_PROGRESS;
> +}
> +
> +static void fsl_qdma_free_desc(struct virt_dma_desc *vdesc)
> +{
> +       unsigned long flags;
> +       struct fsl_qdma_comp *fsl_comp;
> +       struct fsl_qdma_queue *fsl_queue;
> +
> +       fsl_comp = to_fsl_qdma_comp(vdesc);
> +       fsl_queue = fsl_comp->qchan->queue;
> +
> +       spin_lock_irqsave(&fsl_queue->queue_lock, flags);
> +       list_add_tail(&fsl_comp->list, &fsl_queue->comp_free);
> +       spin_unlock_irqrestore(&fsl_queue->queue_lock, flags);
> +}
> +
> +static void fsl_qdma_issue_pending(struct dma_chan *chan)
> +{
> +       unsigned long flags;
> +       struct fsl_qdma_chan *fsl_chan = to_fsl_qdma_chan(chan);
> +       struct fsl_qdma_queue *fsl_queue = fsl_chan->queue;
> +
> +       spin_lock_irqsave(&fsl_queue->queue_lock, flags);
> +       spin_lock(&fsl_chan->vchan.lock);
> +       if (vchan_issue_pending(&fsl_chan->vchan))
> +               fsl_qdma_enqueue_desc(fsl_chan);
> +       spin_unlock(&fsl_chan->vchan.lock);
> +       spin_unlock_irqrestore(&fsl_queue->queue_lock, flags);
> +}
> +
> +static void fsl_qdma_synchronize(struct dma_chan *chan)
> +{
> +       struct fsl_qdma_chan *fsl_chan = to_fsl_qdma_chan(chan);
> +
> +       vchan_synchronize(&fsl_chan->vchan);
> +}
> +
> +static int fsl_qdma_terminate_all(struct dma_chan *chan)
> +{
> +       LIST_HEAD(head);
> +       unsigned long flags;
> +       struct fsl_qdma_chan *fsl_chan = to_fsl_qdma_chan(chan);
> +
> +       spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
> +       vchan_get_all_descriptors(&fsl_chan->vchan, &head);
> +       spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
> +       vchan_dma_desc_free_list(&fsl_chan->vchan, &head);
> +       return 0;
> +}
> +
> +static int fsl_qdma_alloc_chan_resources(struct dma_chan *chan)
> +{
> +       int ret;
> +       struct fsl_qdma_chan *fsl_chan = to_fsl_qdma_chan(chan);
> +       struct fsl_qdma_engine *fsl_qdma = fsl_chan->qdma;
> +       struct fsl_qdma_queue *fsl_queue = fsl_chan->queue;
> +
> +       if (fsl_queue->comp_pool && fsl_queue->desc_pool)
> +               return fsl_qdma->desc_allocated;
> +
> +       INIT_LIST_HEAD(&fsl_queue->comp_free);
> +
> +       /*
> +        * The dma pool for queue command buffer
> +        */
> +       fsl_queue->comp_pool =
> +       dma_pool_create("comp_pool",
> +                       chan->device->dev,
> +                       FSL_QDMA_COMMAND_BUFFER_SIZE,
> +                       64, 0);
> +       if (!fsl_queue->comp_pool)
> +               return -ENOMEM;
> +
> +       /*
> +        * The dma pool for Descriptor(SD/DD) buffer
> +        */
> +       fsl_queue->desc_pool =
> +       dma_pool_create("desc_pool",
> +                       chan->device->dev,
> +                       FSL_QDMA_DESCRIPTOR_BUFFER_SIZE,
> +                       32, 0);
> +       if (!fsl_queue->desc_pool)
> +               goto err_desc_pool;
> +
> +       ret = fsl_qdma_pre_request_enqueue_desc(fsl_queue);
> +       if (ret) {
> +               dev_err(chan->device->dev,
> +                       "failed to alloc dma buffer for S/G descriptor\n");
> +               goto err_mem;
> +       }
> +
> +       fsl_qdma->desc_allocated++;
> +       return fsl_qdma->desc_allocated;
> +
> +err_mem:
> +       dma_pool_destroy(fsl_queue->desc_pool);
> +err_desc_pool:
> +       dma_pool_destroy(fsl_queue->comp_pool);
> +       return -ENOMEM;
> +}
> +
> +static int fsl_qdma_probe(struct platform_device *pdev)
> +{
> +       int ret, i;
> +       int blk_num, blk_off;
> +       u32 len, chans, queues;
> +       struct resource *res;
> +       struct fsl_qdma_chan *fsl_chan;
> +       struct fsl_qdma_engine *fsl_qdma;
> +       struct device_node *np = pdev->dev.of_node;
> +
> +       ret = of_property_read_u32(np, "dma-channels", &chans);
> +       if (ret) {
> +               dev_err(&pdev->dev, "Can't get dma-channels.\n");
> +               return ret;
> +       }
> +
> +       ret = of_property_read_u32(np, "block-offset", &blk_off);
> +       if (ret) {
> +               dev_err(&pdev->dev, "Can't get block-offset.\n");
> +               return ret;
> +       }
> +
> +       ret = of_property_read_u32(np, "block-number", &blk_num);
> +       if (ret) {
> +               dev_err(&pdev->dev, "Can't get block-number.\n");
> +               return ret;
> +       }
> +
> +       blk_num = min_t(int, blk_num, num_online_cpus());
> +
> +       len = sizeof(*fsl_qdma);
> +       fsl_qdma = devm_kzalloc(&pdev->dev, len, GFP_KERNEL);
> +       if (!fsl_qdma)
> +               return -ENOMEM;
> +
> +       len = sizeof(*fsl_chan) * chans;
> +       fsl_qdma->chans = devm_kzalloc(&pdev->dev, len, GFP_KERNEL);
> +       if (!fsl_qdma->chans)
> +               return -ENOMEM;
> +
> +       len = sizeof(struct fsl_qdma_queue *) * blk_num;
> +       fsl_qdma->status = devm_kzalloc(&pdev->dev, len, GFP_KERNEL);
> +       if (!fsl_qdma->status)
> +               return -ENOMEM;
> +
> +       len = sizeof(int) * blk_num;
> +       fsl_qdma->queue_irq = devm_kzalloc(&pdev->dev, len, GFP_KERNEL);
> +       if (!fsl_qdma->queue_irq)
> +               return -ENOMEM;
> +
> +       ret = of_property_read_u32(np, "fsl,dma-queues", &queues);
> +       if (ret) {
> +               dev_err(&pdev->dev, "Can't get queues.\n");
> +               return ret;
> +       }
> +
> +       fsl_qdma->desc_allocated = 0;
> +       fsl_qdma->n_chans = chans;
> +       fsl_qdma->n_queues = queues;
> +       fsl_qdma->block_number = blk_num;
> +       fsl_qdma->block_offset = blk_off;
> +
> +       mutex_init(&fsl_qdma->fsl_qdma_mutex);
> +
> +       for (i = 0; i < fsl_qdma->block_number; i++) {
> +               fsl_qdma->status[i] = fsl_qdma_prep_status_queue(pdev);
> +               if (!fsl_qdma->status[i])
> +                       return -ENOMEM;
> +       }
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       fsl_qdma->ctrl_base = devm_ioremap_resource(&pdev->dev, res);
> +       if (IS_ERR(fsl_qdma->ctrl_base))
> +               return PTR_ERR(fsl_qdma->ctrl_base);
> +
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> +       fsl_qdma->status_base = devm_ioremap_resource(&pdev->dev, res);
> +       if (IS_ERR(fsl_qdma->status_base))
> +               return PTR_ERR(fsl_qdma->status_base);
> +
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
> +       fsl_qdma->block_base = devm_ioremap_resource(&pdev->dev, res);
> +       if (IS_ERR(fsl_qdma->block_base))
> +               return PTR_ERR(fsl_qdma->block_base);
> +       fsl_qdma->queue = fsl_qdma_alloc_queue_resources(pdev, fsl_qdma);
> +       if (!fsl_qdma->queue)
> +               return -ENOMEM;
> +
> +       ret = fsl_qdma_irq_init(pdev, fsl_qdma);
> +       if (ret)
> +               return ret;
> +
> +       fsl_qdma->irq_base = platform_get_irq_byname(pdev, "qdma-queue0");
> +       fsl_qdma->feature = of_property_read_bool(np, "big-endian");
> +       INIT_LIST_HEAD(&fsl_qdma->dma_dev.channels);
> +
> +       for (i = 0; i < fsl_qdma->n_chans; i++) {
> +               struct fsl_qdma_chan *fsl_chan = &fsl_qdma->chans[i];
> +
> +               fsl_chan->qdma = fsl_qdma;
> +               fsl_chan->queue = fsl_qdma->queue + i % (fsl_qdma->n_queues *
> +                                                       fsl_qdma->block_number);
> +               fsl_chan->vchan.desc_free = fsl_qdma_free_desc;
> +               vchan_init(&fsl_chan->vchan, &fsl_qdma->dma_dev);
> +       }
> +
> +       dma_cap_set(DMA_MEMCPY, fsl_qdma->dma_dev.cap_mask);
> +
> +       fsl_qdma->dma_dev.dev = &pdev->dev;
> +       fsl_qdma->dma_dev.device_free_chan_resources =
> +               fsl_qdma_free_chan_resources;
> +       fsl_qdma->dma_dev.device_alloc_chan_resources =
> +               fsl_qdma_alloc_chan_resources;
> +       fsl_qdma->dma_dev.device_tx_status = dma_cookie_status;
> +       fsl_qdma->dma_dev.device_prep_dma_memcpy = fsl_qdma_prep_memcpy;
> +       fsl_qdma->dma_dev.device_issue_pending = fsl_qdma_issue_pending;
> +       fsl_qdma->dma_dev.device_synchronize = fsl_qdma_synchronize;
> +       fsl_qdma->dma_dev.device_terminate_all = fsl_qdma_terminate_all;
> +
> +       dma_set_mask(&pdev->dev, DMA_BIT_MASK(40));
> +
> +       platform_set_drvdata(pdev, fsl_qdma);
> +
> +       ret = dma_async_device_register(&fsl_qdma->dma_dev);
> +       if (ret) {
> +               dev_err(&pdev->dev,
> +                       "Can't register NXP Layerscape qDMA engine.\n");
> +               return ret;
> +       }
> +
> +       ret = fsl_qdma_reg_init(fsl_qdma);
> +       if (ret) {
> +               dev_err(&pdev->dev, "Can't Initialize the qDMA engine.\n");
> +               return ret;
> +       }
> +
> +       return 0;
> +}
> +
> +static void fsl_qdma_cleanup_vchan(struct dma_device *dmadev)
> +{
> +       struct fsl_qdma_chan *chan, *_chan;
> +
> +       list_for_each_entry_safe(chan, _chan,
> +                                &dmadev->channels, vchan.chan.device_node) {
> +               list_del(&chan->vchan.chan.device_node);
> +               tasklet_kill(&chan->vchan.task);
> +       }
> +}
> +
> +static int fsl_qdma_remove(struct platform_device *pdev)
> +{
> +       int i;
> +       struct fsl_qdma_queue *status;
> +       struct device_node *np = pdev->dev.of_node;
> +       struct fsl_qdma_engine *fsl_qdma = platform_get_drvdata(pdev);
> +
> +       fsl_qdma_irq_exit(pdev, fsl_qdma);
> +       fsl_qdma_cleanup_vchan(&fsl_qdma->dma_dev);
> +       of_dma_controller_free(np);
> +       dma_async_device_unregister(&fsl_qdma->dma_dev);
> +
> +       for (i = 0; i < fsl_qdma->block_number; i++) {
> +               status = fsl_qdma->status[i];
> +               dma_free_coherent(&pdev->dev, sizeof(struct fsl_qdma_format) *
> +                               status->n_cq, status->cq, status->bus_addr);
> +       }
> +       return 0;
> +}
> +
> +static const struct of_device_id fsl_qdma_dt_ids[] = {
> +       { .compatible = "fsl,ls1021a-qdma", },
> +       { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, fsl_qdma_dt_ids);
> +
> +static struct platform_driver fsl_qdma_driver = {
> +       .driver         = {
> +               .name   = "fsl-qdma",
> +               .of_match_table = fsl_qdma_dt_ids,
> +       },
> +       .probe          = fsl_qdma_probe,
> +       .remove         = fsl_qdma_remove,
> +};
> +
> +module_platform_driver(fsl_qdma_driver);
> +
> +MODULE_ALIAS("platform:fsl-qdma");
> +MODULE_DESCRIPTION("NXP Layerscape qDMA engine driver");
> --
> 1.7.1
>

^ permalink raw reply

* Re: [PATCH 3/6] PCI: layerscape: Add the EP mode support
From: Li Yang @ 2018-10-26 20:28 UTC (permalink / raw)
  To: xiaowei.bao
  Cc: Mark Rutland, Rob Herring, lorenzo.pieralisi, Arnd Bergmann,
	Roy Zang, Greg Kroah-Hartman, Kate Stewart, niklas.cassel,
	linux-pci, lkml, kishon, Minghuan Lian,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	cyrille.pitchen,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	Philippe Ombredanne, Bjorn Helgaas, linuxppc-dev, Shawn Guo,
	shawn.lin, Mingkai Hu
In-Reply-To: <HE1PR04MB14972C9176E68EEDBD3AD64BF5F00@HE1PR04MB1497.eurprd04.prod.outlook.com>

On Fri, Oct 26, 2018 at 2:43 AM Xiaowei Bao <xiaowei.bao@nxp.com> wrote:
>
>
>
> -----Original Message-----
> From: arndbergmann@gmail.com <arndbergmann@gmail.com> On Behalf Of Arnd Bergmann
> Sent: 2018年10月26日 15:01
> To: Xiaowei Bao <xiaowei.bao@nxp.com>
> Cc: Rob Herring <robh@kernel.org>; bhelgaas@google.com; mark.rutland@arm.com; shawnguo@kernel.org; Leo Li <leoyang.li@nxp.com>; kishon@ti.com; lorenzo.pieralisi@arm.com; gregkh@linuxfoundation.org; M.h. Lian <minghuan.lian@nxp.com>; Mingkai Hu <mingkai.hu@nxp.com>; Roy Zang <roy.zang@nxp.com>; kstewart@linuxfoundation.org; cyrille.pitchen@free-electrons.com; pombredanne@nexb.com; shawn.lin@rock-chips.com; niklas.cassel@axis.com; linux-pci@vger.kernel.org; devicetree@vger.kernel.org; linux-kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org; linuxppc-dev@lists.ozlabs.org
> Subject: Re: [PATCH 3/6] PCI: layerscape: Add the EP mode support
>
> On 10/26/18, Xiaowei Bao <xiaowei.bao@nxp.com> wrote:
> > From: Rob Herring <robh@kernel.org>
> >> On Thu, Oct 25, 2018 at 07:08:58PM +0800, Xiaowei Bao wrote:
> >>>          "fsl,ls2080a-pcie", "fsl,ls2085a-pcie", "snps,dw-pcie"
> >>>          "fsl,ls2088a-pcie"
> >>>          "fsl,ls1088a-pcie"
> >>>          "fsl,ls1046a-pcie"
> >>>          "fsl,ls1012a-pcie
> >>> +  EP mode:
> >>> +        "fsl,ls-pcie-ep"
> >>
> > > You need SoC specific compatibles for the same reasons as the RC.
> >
> > [Xiaowei Bao] I want to contains all layerscape platform use one
> > compatible if the PCIe controller work in EP mode.
>
> Do you mean only one of the SoCs that support RC mode has EP mode?
> I think you still need a SoC specific compatible as Rob explained, in case there will be a second one in the future.
>
> If you want to ensure that you don't have to update the device driver for each new chip that comes in when the EP mode is compatible, the way this is handled is to list multiple values in the compatible property, listing the first SoC that introduced the specific version of that IP block as the most generic type, e.g.
>
>   copatible = "fsl,ls2088a-pcie-ep", "fsl,ls1012a-pcie-ep", "snps,dw-pcie-ep";
>
> For consistency, it probably is best to match each RC mode value with the corresponding EP mode string for each device that can support both (if there is more than one).
>
>       Arnd
> [Xiaowei Bao] My mean is that the ls-pcie-ep compatibles will contain all layerscape SOCs of NXP, e.g: ls1046a-pcie-ep, fsl,ls2088a-pcie-ep, ls2088a-pcie-ep and so on, other layerscape SOCs have not test except the ls1046a, I think it is compatible if the new chip or other SOCs use the DW core, OK, I will discuss this issue internally, and reply to you later.

You can define a generic compatible string for the EP mode of all
these platforms.  But like Rob and Arnd mentioned, it is good to also
define the SoC specific compatible strings just in case that we need
special treatment for certain SoCs in the future.

Regards,
Leo

^ permalink raw reply

* Re: [PATCH] Documentation: fix spelling mistake, EACCESS -> EACCES
From: Matthew Wilcox @ 2018-10-26 18:40 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: kernel-janitors, Jonathan Corbet, Dave Airlie, linuxppc-dev,
	Linux Doc Mailing List, maarten.lankhorst, linux-kernel,
	maxime.ripard, jk, colin.king, sean
In-Reply-To: <CANiq72nFZS=3KGaQpGjRbprh8HTBiTcSpxScE2uacDmg-xqDGA@mail.gmail.com>

On Fri, Oct 26, 2018 at 08:20:12PM +0200, Miguel Ojeda wrote:
> On Fri, Oct 26, 2018 at 7:27 PM Colin King <colin.king@canonical.com> wrote:
> >
> > From: Colin Ian King <colin.king@canonical.com>
> >
> > Trivial fix to a spelling mistake of the error access name EACCESS,
> > rename to EACCES
> 
> ? It is not a typo, it is the name of the error (POSIX). Same thing
> for the rest of the patches.

Are you sure?  From open(2):

       EACCES The  requested access to the file is not allowed, or search per‐
              mission is denied for one of the directories in the path  prefix
              of  pathname,  or the file did not exist yet and write access to
              the parent directory is not  allowed.   (See  also  path_resolu‐
              tion(7).)

include/uapi/asm-generic/errno-base.h:#define   EACCES          13      /* Permission denied */


^ permalink raw reply

* Re: [PATCH v2 0/2] arm64: Cut rebuild time when changing CONFIG_BLK_DEV_INITRD
From: Florian Fainelli @ 2018-10-26 19:05 UTC (permalink / raw)
  To: Mike Rapoport
  Cc: Linux-MIPS, linux-ia64, SH-Linux, Catalin Marinas, Will Deacon,
	devicetree, sparclinux, linux-riscv,
	open list:GENERIC INCLUDE/ASM HEADER FILES, Rob Herring,
	linux-c6x-dev, linux-hexagon, arcml,
	moderated list:H8/300 ARCHITECTURE, linux-xtensa, Arnd Bergmann,
	linux-s390, Marc Zyngier, linux-um, linux-m68k, Openrisc,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	linux-parisc, Ard Biesheuvel, Greg Kroah-Hartman,
	linux-kernel@vger.kernel.org, linux-alpha, Olof Johansson,
	nios2-dev, linuxppc-dev
In-Reply-To: <20181026110708.GA3814@rapoport-lnx>

On 10/26/18 4:07 AM, Mike Rapoport wrote:
> On Thu, Oct 25, 2018 at 04:07:13PM -0700, Florian Fainelli wrote:
>> On 10/25/18 2:13 PM, Rob Herring wrote:
>>> On Thu, Oct 25, 2018 at 12:30 PM Mike Rapoport <rppt@linux.ibm.com> wrote:
>>>>
>>>> On Thu, Oct 25, 2018 at 08:15:15AM -0500, Rob Herring wrote:
>>>>> +Ard
>>>>>
>>>>> On Thu, Oct 25, 2018 at 4:38 AM Mike Rapoport <rppt@linux.ibm.com> wrote:
>>>>>>
>>>>>> On Wed, Oct 24, 2018 at 02:55:17PM -0500, Rob Herring wrote:
>>>>>>> On Wed, Oct 24, 2018 at 2:33 PM Florian Fainelli <f.fainelli@gmail.com> wrote:
>>>>>>>>
>>>>>>>> Hi all,
>>>>>>>>
>>>>>>>> While investigating why ARM64 required a ton of objects to be rebuilt
>>>>>>>> when toggling CONFIG_DEV_BLK_INITRD, it became clear that this was
>>>>>>>> because we define __early_init_dt_declare_initrd() differently and we do
>>>>>>>> that in arch/arm64/include/asm/memory.h which gets included by a fair
>>>>>>>> amount of other header files, and translation units as well.
>>>>>>>
>>>>>> I think arm64 does not have to redefine __early_init_dt_declare_initrd().
>>>>>> Something like this might be just all we need (completely untested,
>>>>>> probably it won't even compile):
> 
> [ ... ]
>  
>> FWIW, I am extracting the ARM implementation that parses the initrd
>> early command line parameter and the "setup" code doing the page
>> boundary alignment and memblock checking into a helper into lib/ that
>> other architectures can re-use. So far, this removes the need for
>> unicore32, arc and arm to duplicate essentially the same logic.
> 
> Presuming you are going to need asm-generic/initrd.h for that as well,
> using override for __early_init_dt_declare_initrd in arm64 version of
> initrd.h might be the simplest option.

What I am contemplating doing is promote
phys_initrd_start/phys_initrd_size to be global variables (similar to
initrd_start, initrd_end) and have a generic helper function for parsing
the initrd= command line parameter and finally removing
__early_init_dt_declare_initrd() because we could have
early_init_dt_check_for_initrd() just populate
phys_initrd_start/phys_initrd_size directly as well as
initrd_start/initrd_end using __va() to preserve compatibility with
architectures that rely on this. Then I would convert ARM64 to check for
phys_initrd_start which is really what it is is trying to do in
arch/arm64/mm/init.c::arm64_memblock_init().

Does that sound like a reasonable approach?
-- 
Florian

^ permalink raw reply

* [GIT PULL] Please pull powerpc/linux.git powerpc-4.20-1 tag
From: Michael Ellerman @ 2018-10-26 18:41 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: ego, clombard, daniel.vetter, fbarrat, mahesh, yamada.masahiro,
	mwb, oohall, leitao, aravinda, rashmica.g, breno.leitao, robh,
	mikey, aneesh.kumar, b.zolnierkie, yuehaibing, fthain, geert,
	joel, sjitindarsingh, nfont, naveen.n.rao, dan.carpenter, arnd,
	amodra, mhairgrove, npiggin, pvorel, anton, dan.j.williams,
	zhongjiang, hbathini, dja, msuchanek, geoff, linux-kernel,
	sbobroff, andrew.donnellan, vaibhav, ldufour, linuxppc-dev

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi Linus,

Please pull powerpc updates for 4.20:

The following changes since commit 11da3a7f84f19c26da6f86af878298694ede0804:

  Linux 4.19-rc3 (2018-09-09 17:26:43 -0700)

are available in the git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git tags/powerpc-4.20-1

for you to fetch changes up to 58cfbac25b1fd2b76f94566aed28a3662b0ff8c6:

  Revert "selftests/powerpc: Fix out-of-tree build errors" (2018-10-26 21:58:58 +1100)

- ------------------------------------------------------------------
powerpc updates for 4.20

Notable changes:

 - A large series to rewrite our SLB miss handling, replacing a lot of fairly
   complicated asm with much fewer lines of C.

 - Following on from that, we now maintain a cache of SLB entries for each
   process and preload them on context switch. Leading to a 27% speedup for our
   context switch benchmark on Power9.

 - Improvements to our handling of SLB multi-hit errors. We now print more debug
   information when they occur, and try to continue running by flushing the SLB
   and reloading, rather than treating them as fatal.

 - Enable THP migration on 64-bit Book3S machines (eg. Power7/8/9).

 - Add support for physical memory up to 2PB in the linear mapping on 64-bit
   Book3S. We only support up to 512TB as regular system memory, otherwise the
   percpu allocator runs out of vmalloc space.

 - Add stack protector support for 32 and 64-bit, with a per-task canary.

 - Add support for PTRACE_SYSEMU and PTRACE_SYSEMU_SINGLESTEP.

 - Support recognising "big cores" on Power9, where two SMT4 cores are presented
   to us as a single SMT8 core.

 - A large series to cleanup some of our ioremap handling and PTE flags.

 - Add a driver for the PAPR SCM (storage class memory) interface, allowing
   guests to operate on SCM devices (acked by Dan).

 - Changes to our ftrace code to handle very large kernels, where we need to use
   a trampoline to get to ftrace_caller().

Many other smaller enhancements and cleanups.

Thanks to:
  Alan Modra, Alistair Popple, Aneesh Kumar K.V, Anton Blanchard, Aravinda
  Prasad, Bartlomiej Zolnierkiewicz, Benjamin Herrenschmidt, Breno Leitao,
  Cédric Le Goater, Christophe Leroy, Christophe Lombard, Dan Carpenter, Daniel
  Axtens, Finn Thain, Gautham R. Shenoy, Gustavo Romero, Haren Myneni, Hari
  Bathini, Jia Hongtao, Joel Stanley, John Allen, Laurent Dufour, Madhavan
  Srinivasan, Mahesh Salgaonkar, Mark Hairgrove, Masahiro Yamada, Michael
  Bringmann, Michael Neuling, Michal Suchanek, Murilo Opsfelder Araujo, Nathan
  Fontenot, Naveen N. Rao, Nicholas Piggin, Nick Desaulniers, Oliver O'Halloran,
  Paul Mackerras, Petr Vorel, Rashmica Gupta, Reza Arbab, Rob Herring, Sam
  Bobroff, Samuel Mendoza-Jonas, Scott Wood, Stan Johnson, Stephen Rothwell,
  Stewart Smith, Suraj Jitindar Singh, Tyrel Datwyler, Vaibhav Jain, Vasant
  Hegde, YueHaibing, zhong jiang,

- ------------------------------------------------------------------
Alan Modra (1):
      powerpc/vdso: Correct call frame information

Aneesh Kumar K.V (10):
      powerpc/mm/book3s: Update pmd_present to look at _PAGE_PRESENT bit
      powerpc/mm/hugetlb/book3s: add _PAGE_PRESENT to hugepd pointer.
      powerpc/mm/book3s: Check for pmd_large instead of pmd_trans_huge
      arch/powerpc/mm/hash: validate the pte entries before handling the hash fault
      powerpc/mm/thp: update pmd_trans_huge to check for pmd_present
      powerpc/mm:book3s: Enable THP migration support
      powerpc/mm/hash: Rename get_ea_context to get_user_context
      powerpc/mm: Increase the max addressable memory to 2PB
      powerpc/mm: Make pte_pgprot return all pte bits
      powerpc/mm: Fix WARN_ON with THP NUMA migration

Anton Blanchard (4):
      powerpc/64: Remove static branch hints from memset()
      powerpc: Fix duplicate const clang warning in user access code
      powerpc/time: Use clockevents_register_device(), fixing an issue with large decrementer
      powerpc/time: Add set_state_oneshot_stopped decrementer callback

Aravinda Prasad (1):
      powerpc/pseries: Export raw per-CPU VPA data via debugfs

Bartlomiej Zolnierkiewicz (1):
      powerpc: remove redundant 'default n' from Kconfig-s

Benjamin Herrenschmidt (13):
      powerpc/prom_init: Make of_workarounds static
      powerpc/prom_init: Make "fake_elf" const
      powerpc/prom_init: Make "default_colors" const
      powerpc/prom_init: Replace __initdata with __prombss when applicable
      powerpc/prom_init: Remove support for OPAL v2
      powerpc/prom_init: Move prom_radix_disable to __prombss
      powerpc/prom_init: Move ibm_arch_vec to __prombss
      powerpc/prom_init: Move const structures to __initconst
      powerpc/prom_init: Move a few remaining statics to appropriate sections
      powerpc/prom_init: Move __prombss to it's own section and store it in .bss
      powerpc: Check prom_init for disallowed sections
      powerpc/prom_init: Generate "phandle" instead of "linux, phandle"
      macintosh/windfarm_smu_sat: Fix debug output

Breno Leitao (11):
      powerpc/selftests: Wait all threads to join
      powerpc/tm: Fix HTM documentation
      powerpc/xive: Use xive_cpu->chip_id instead of looking it up again
      powerpc/iommu: Avoid derefence before pointer check
      selftests/powerpc: Do not fail with reschedule
      powerpc: Redefine TIF_32BITS thread flag
      powerpc/ptrace: Add support for PTRACE_SYSEMU
      selftests/powerpc: New PTRACE_SYSEMU test
      powerpc/powernv: Mark function as __noreturn
      powerpc/tm: Remove msr_tm_active()
      powerpc/tm: Print 64-bits MSR

Christophe Leroy (50):
      powerpc/traps: merge unrecoverable_exception() and nonrecoverable_exception()
      powerpc/32: add stack protector support
      powerpc/64: add stack protector support
      powerpc/mm: Don't report hugepage tables as memory leaks when using kmemleak
      powerpc: Wire up memtest
      powerpc/64: properly initialise the stackprotector canary on SMP.
      powerpc/process: Fix sparse address space warnings
      powerpc/process: Add missing include of stacktrace.h
      powerpc/process: Fix interleaved output in show_user_instructions()
      powerpc/process: Constify the number of insns printed by show instructions functions.
      powerpc/32: Add ioremap_wt() and ioremap_coherent()
      drivers/video/fbdev: use ioremap_wc/wt() instead of __ioremap()
      drivers/block/z2ram: use ioremap_wt() instead of __ioremap(_PAGE_WRITETHRU)
      soc/fsl/qbman: use ioremap_cache() instead of ioremap_prot(0)
      powerpc: don't use ioremap_prot() nor __ioremap() unless really needed.
      powerpc/mm: properly set PAGE_KERNEL flags in ioremap()
      powerpc: handover page flags with a pgprot_t parameter
      powerpc/mm: don't use _PAGE_EXEC in book3s/32
      powerpc/mm: move some nohash pte helpers in nohash/[32:64]/pgtable.h
      powerpc/mm: add pte helpers to query and change pte flags
      powerpc/mm: don't use _PAGE_EXEC for calling hash_preload()
      powerpc/mm: use pte helpers in generic code
      powerpc/mm: Split dump_pagelinuxtables flag_array table
      powerpc/mm: drop unused page flags
      powerpc/mm: move __P and __S tables in the common pgtable.h
      powerpc/book3s/32: do not include pte-common.h
      powerpc/mm: Move pte_user() into nohash/pgtable.h
      powerpc/mm: Distribute platform specific PAGE and PMD flags and definitions
      powerpc/nohash/64: do not include pte-common.h
      powerpc/mm: Allow platforms to redefine some helpers
      powerpc/mm: Define platform default caches related flags
      powerpc/mm: Get rid of pte-common.h
      powerpc/8xx: change name of a few page flags to avoid confusion
      powerpc/book3s64: Avoid multiple endian conversion in pte helpers
      powerpc/book3e: redefine pte_mkprivileged() and pte_mkuser()
      powerpc/traps: fix machine check handlers to use pr_cont()
      powerpc/traps: remove redundant in_interrupt panic in die()
      powerpc/io: remove old GCC version implementation
      powerpc/book3s64: fix dump_linuxpagetables "present" flag
      powerpc/mm: Add missing tracepoint for tlbie
      powerpc/mm: Trace tlbia instruction
      powerpc/mm: fix missing prototypes in slice.c
      powerpc/mm: fix always true/false warning in slice.c
      powerpc/sysdev/ipic: check primary_ipic NULL pointer before using it
      powerpc/kgdb: add kgdb_arch_set/remove_breakpoint()
      powerpc/time: isolate scaled cputime accounting in dedicated functions.
      powerpc/time: Only set CONFIG_ARCH_HAS_SCALED_CPUTIME on PPC64
      powerpc/time: no steal_time when CONFIG_PPC_SPLPAR is not selected
      powerpc/traps: restore recoverability of machine_check interrupts
      powerpc/msi: Fix compile error on mpc83xx

Christophe Lombard (1):
      ocxl: Fix access to the AFU Descriptor Data

Dan Carpenter (1):
      powerpc: Fix signedness bug in update_flash_db()

Daniel Axtens (1):
      powerpc/nohash: fix undefined behaviour when testing page size support

Finn Thain (7):
      macintosh: Use common code to access RTC
      macintosh/adb: Rework printk output again
      macintosh/via-macii: Synchronous bus reset
      macintosh/via-macii: Remove BUG_ON assertions
      macintosh/via-macii: Simplify locking
      macintosh/via-macii, macintosh/adb-iop: Modernize printk calls
      macintosh/via-macii, macintosh/adb-iop: Clean up whitespace

Gautham R. Shenoy (4):
      powerpc: Detect the presence of big-cores via "ibm, thread-groups"
      powerpc: Use cpu_smallcore_sibling_mask at SMT level on bigcores
      powerpc/cacheinfo: Report the correct shared_cpu_map on big-cores
      powerpc/rtas: Fix a potential race between CPU-Offline & Migration

Hari Bathini (1):
      powerpc/fadump: re-register firmware-assisted dump if already registered

Joel Stanley (11):
      powerpc/powernv: Don't select the cpufreq governors
      powerpc/configs: Update skiroot defconfig
      powerpc/boot: Ensure _zimage_start is a weak symbol
      powerpc/perf: Quiet IMC PMU registration message
      powerpc: Disable -Wbuiltin-requires-header when setjmp is used
      powerpc/boot: Expose Kconfig symbols to wrapper
      powerpc/boot: Fix opal console in boot wrapper
      powerpc/boot: Disable vector instructions
      powerpc/boot: Build boot wrapper with optimisations
      powerpc/Makefile: Fix PPC_BOOK3S_64 ASFLAGS
      powerpc: Use SWITCH_FRAME_SIZE for prom and rtas entry

Laurent Dufour (3):
      powerpc/pseries/mm: Introducing FW_FEATURE_BLOCK_REMOVE
      powerpc/pseries/mm: factorize PTE slot computation
      powerpc/pseries/mm: call H_BLOCK_REMOVE

Mahesh Salgaonkar (5):
      powerpc/pseries: Define MCE error event section.
      powerpc/pseries: Flush SLB contents on SLB MCE errors.
      powerpc/pseries: Display machine check error details.
      powerpc/pseries: Dump the SLB contents on SLB MCE errors.
      powernv/pseries: consolidate code for mce early handling.

Mark Hairgrove (3):
      powerpc/powernv/npu: Reduce eieio usage when issuing ATSD invalidates
      powerpc/powernv/npu: Use size-based ATSD invalidates
      powerpc/powernv/npu: Remove atsd_threshold debugfs setting

Masahiro Yamada (1):
      powerpc: remove leftover code of old GCC version checks

Michael Bringmann (1):
      powerpc/pseries/mobility: Extend start/stop topology update scope

Michael Ellerman (23):
      Revert "convert SLB miss handlers to C" and subsequent commits
      powerpc/perf: Add missing break in power7_marked_instr_event()
      Merge branch 'fixes' into next
      powerpc/xmon: Show the stack protector canary in xmon
      powerpc: Fix stackprotector detection for non-glibc toolchains
      powerpc: Split user/kernel definitions of struct pt_regs
      powerpc/ptrace: Don't use sizeof(struct pt_regs) in ptrace code
      powerpc: Move core kernel logic into arch/powerpc/Kbuild
      powerpc: Add -Werror at arch/powerpc level
      powerpc/uapi: Fix sigcontext definition to use user_pt_regs
      powerpc/aout: Fix struct user definition to use user_pt_regs
      powerpc/time: Fix clockevent_decrementer initalisation for PR KVM
      selftests/powerpc: Fix out-of-tree build errors
      powerpc/mm/radix: Fix off-by-one in split mapping logic
      powerpc/mm/radix: Fix overuse of small pages in splitting logic
      powerpc/mm/radix: Fix small page at boundary when splitting
      powerpc/mm/radix: Remove the retry in the split mapping logic
      powerpc/mm/radix: Simplify split mapping logic
      powerpc/mm/radix: Display if mappings are exec or not
      powerpc/mm: Fix page table dump to work on Radix
      selftests/powerpc: Add a test of wild bctr
      powerpc: Fix stack protector crashes on CPU hotplug
      Revert "selftests/powerpc: Fix out-of-tree build errors"

Michael Neuling (2):
      powerpc/tm: Fix HFSCR bit for no suspend case
      powerpc/tm: Reformat comments

Michal Suchanek (1):
      powerpc/64s: consolidate MCE counter increment.

Nathan Fontenot (4):
      powerpc/pseries/memory-hotplug: Only update DT once per memory DLPAR request
      powerpc/pseries: Remove prrn_work workqueue
      powerpc/pseries: Remove unneeded uses of dlpar work queue
      powerpc/pseries: Disable CPU hotplug across migrations

Naveen N. Rao (7):
      powerpc/pseries: Fix DTL buffer registration
      powerpc/pseries: Fix how we iterate over the DTL entries
      powerpc: Add support for function error injection
      powerpc64/module elfv1: Set opd addresses after module relocation
      selftests/powerpc: Move UCONTEXT_NIA() into utils.h
      selftests/powerpc: Add test to verify rfi flush across a system call
      powerpc/ftrace: Handle large kernel configs

Nicholas Piggin (26):
      powerpc/64s/hash: Fix stab_rr off by one initialization
      powerpc/64s/hash: avoid the POWER5 < DD2.1 slb invalidate workaround on POWER8/9
      powerpc/64s/hash: move POWER5 < DD2.1 slbie workaround where it is needed
      powerpc/64s/hash: remove the vmalloc segment from the bolted SLB
      powerpc/64s/hash: Use POWER6 SLBIA IH=1 variant in switch_slb
      powerpc/64s/hash: Use POWER9 SLBIA IH=3 variant in switch_slb
      powerpc/64s/hash: convert SLB miss handlers to C
      powerpc/64s/hash: remove user SLB data from the paca
      powerpc/64s/hash: SLB allocation status bitmaps
      powerpc/64s: xmon do not dump hash fields when using radix mode
      powerpc/64s/hash: provide arch_setup_exec hooks for hash slice setup
      powerpc/64s/hash: Add a SLB preload cache
      powerpc: remove old GCC version checks
      powerpc: consolidate -mno-sched-epilog into FTRACE flags
      powerpc: avoid -mno-sched-epilog on GCC 4.9 and newer
      powerpc/64s/hash: Do not use PPC_INVALIDATE_ERAT on CPUs before POWER9
      powerpc/64s/radix: Explicitly flush ERAT with local LPID invalidation
      powerpc/64: Interrupts save PPR on stack rather than thread_struct
      powerpc/64s/hash: Convert SLB miss handlers to C
      powerpc/64s/hash: Add SLB allocation status bitmaps
      powerpc/64s/hash: Provide arch_setup_exec() hooks for hash slice setup
      powerpc/64s/hash: Add a SLB preload cache
      powerpc/64s/hash: Simplify slb_flush_and_rebolt()
      powerpc/64s/hash: Add some SLB debugging tests
      powerpc/64s/radix: Fix radix__flush_tlb_collapsed_pmd double flushing pmd
      powerpc/64/module: REL32 relocation range check

Oliver O'Halloran (3):
      powerpc/rtasd: Improve unknown error logging
      powerpc/pseries: PAPR persistent memory support
      powerpc/pseries: Add driver for PAPR SCM regions

Petr Vorel (1):
      powerpc/config: Enable CONFIG_PRINTK_TIME

Rashmica Gupta (1):
      powerpc/memtrace: Remove memory in chunks

Rob Herring (4):
      powerpc/cell: Use irq_of_parse_and_map() helper
      powerpc/pseries: Use of_irq_get helper() in request_event_sources_irqs()
      macintosh: Convert to using %pOFn instead of device_node.name
      powerpc: Convert to using %pOFn instead of device_node.name

Sam Bobroff (14):
      powerpc/eeh: Fix possible null deref in eeh_dump_dev_log()
      powerpc/eeh: Fix null deref for devices removed during EEH
      powerpc/eeh: Fix use of EEH_PE_KEEP on wrong field
      powerpc/eeh: Cleanup EEH_POSTPONED_PROBE
      powerpc/eeh: Cleanup unused field in eeh_dev
      powerpc/eeh: Cleanup eeh_add_virt_device()
      powerpc/eeh: Cleanup list_head field names
      powerpc/eeh: Cleanup field names in eeh_rmv_data
      powerpc/eeh: Cleanup logic in eeh_rmv_from_parent_pe()
      powerpc/eeh: Cleanup eeh_enabled()
      powerpc/eeh: Cleanup unnecessary eeh_pe_state_mark_with_cfg()
      powerpc/eeh: Cleanup eeh_pe_state_mark()
      powerpc/eeh: Cleanup eeh_ops.wait_state()
      powerpc/eeh: Cleanup control flow in eeh_handle_normal_event()

Suraj Jitindar Singh (2):
      powerpc/prom: Remove VLA in prom_check_platform_support()
      powerpc/pseries: Remove VLA from lparcfg_write()

Vaibhav Jain (1):
      powerpc/powernv: Make possible for user to force a full ipl cec reboot

YueHaibing (2):
      powerpc: Remove duplicated include from pci_32.c
      powerpc/pseries/memory-hotplug: Fix return value type of find_aa_index

zhong jiang (1):
      powerpc/xive: Move a dereference below a NULL test


 Documentation/admin-guide/kernel-parameters.txt    |   2 +-
 arch/m68k/mac/misc.c                               |  75 +-
 arch/powerpc/Kbuild                                |  16 +
 arch/powerpc/Kconfig                               |  19 +-
 arch/powerpc/Kconfig.debug                         |   6 -
 arch/powerpc/Makefile                              |  91 +--
 arch/powerpc/boot/.gitignore                       |   1 +
 arch/powerpc/boot/Makefile                         |  11 +-
 arch/powerpc/boot/crt0.S                           |   4 +-
 arch/powerpc/boot/opal.c                           |   8 -
 arch/powerpc/boot/serial.c                         |   1 +
 arch/powerpc/configs/g5_defconfig                  |   1 +
 arch/powerpc/configs/maple_defconfig               |   1 +
 arch/powerpc/configs/powernv_defconfig             |   4 +
 arch/powerpc/configs/ppc64_defconfig               |   4 +
 arch/powerpc/configs/ps3_defconfig                 |   1 +
 arch/powerpc/configs/pseries_defconfig             |   1 +
 arch/powerpc/configs/skiroot_defconfig             | 154 ++--
 arch/powerpc/include/asm/accounting.h              |   4 +
 arch/powerpc/include/asm/asm-prototypes.h          |   3 +-
 arch/powerpc/include/asm/book3s/32/pgtable.h       | 152 +++-
 arch/powerpc/include/asm/book3s/64/hash-4k.h       |   2 +-
 arch/powerpc/include/asm/book3s/64/hash.h          |   8 +-
 arch/powerpc/include/asm/book3s/64/hugetlb.h       |   3 +
 arch/powerpc/include/asm/book3s/64/mmu-hash.h      |  95 ++-
 arch/powerpc/include/asm/book3s/64/mmu.h           |   4 +-
 arch/powerpc/include/asm/book3s/64/pgtable-64k.h   |   3 +
 arch/powerpc/include/asm/book3s/64/pgtable.h       | 181 +++--
 arch/powerpc/include/asm/cputhreads.h              |   2 +
 arch/powerpc/include/asm/cputime.h                 |   1 -
 arch/powerpc/include/asm/drmem.h                   |   5 +
 arch/powerpc/include/asm/eeh.h                     |  24 +-
 arch/powerpc/include/asm/error-injection.h         |  13 +
 arch/powerpc/include/asm/exception-64s.h           |  17 +-
 arch/powerpc/include/asm/firmware.h                |   5 +-
 arch/powerpc/include/asm/fixmap.h                  |   2 +-
 arch/powerpc/include/asm/hvcall.h                  |  11 +-
 arch/powerpc/include/asm/io.h                      |  33 +-
 arch/powerpc/include/asm/kgdb.h                    |   5 +-
 arch/powerpc/include/asm/machdep.h                 |   3 +-
 arch/powerpc/include/asm/mce.h                     |   3 +
 arch/powerpc/include/asm/mmu.h                     |  15 +
 arch/powerpc/include/asm/mmu_context.h             |   2 +-
 arch/powerpc/include/asm/mpic.h                    |   7 +
 arch/powerpc/include/asm/nohash/32/pgtable.h       |  69 +-
 arch/powerpc/include/asm/nohash/32/pte-40x.h       |  43 ++
 arch/powerpc/include/asm/nohash/32/pte-44x.h       |  30 +
 arch/powerpc/include/asm/nohash/32/pte-8xx.h       |  87 ++-
 arch/powerpc/include/asm/nohash/32/pte-fsl-booke.h |  33 +
 arch/powerpc/include/asm/nohash/64/pgtable.h       |  41 +-
 arch/powerpc/include/asm/nohash/pgtable.h          | 100 ++-
 arch/powerpc/include/asm/nohash/pte-book3e.h       |  41 ++
 arch/powerpc/include/asm/opal-api.h                |   1 +
 arch/powerpc/include/asm/paca.h                    |  18 +-
 arch/powerpc/include/asm/pgtable.h                 |  29 +
 arch/powerpc/include/asm/ppc-pci.h                 |   1 +
 arch/powerpc/include/asm/processor.h               |   7 +-
 arch/powerpc/include/asm/pte-common.h              | 219 ------
 arch/powerpc/include/asm/ptrace.h                  |  36 +
 arch/powerpc/include/asm/reg.h                     |   7 +-
 arch/powerpc/include/asm/rtas.h                    |  15 +
 arch/powerpc/include/asm/slice.h                   |   1 +
 arch/powerpc/include/asm/smp.h                     |  11 +
 arch/powerpc/include/asm/sparsemem.h               |  11 -
 arch/powerpc/include/asm/stackprotector.h          |  38 +
 arch/powerpc/include/asm/thread_info.h             |  17 +-
 arch/powerpc/include/asm/trace.h                   |  15 +
 arch/powerpc/include/asm/uaccess.h                 |   6 +-
 arch/powerpc/include/asm/user.h                    |   2 +-
 arch/powerpc/include/uapi/asm/ptrace.h             |  11 +-
 arch/powerpc/include/uapi/asm/sigcontext.h         |   6 +-
 arch/powerpc/kernel/Makefile                       |  13 +-
 arch/powerpc/kernel/asm-offsets.c                  |  19 +-
 arch/powerpc/kernel/btext.c                        |   2 +-
 arch/powerpc/kernel/cacheinfo.c                    |  37 +-
 arch/powerpc/kernel/crash_dump.c                   |   2 +-
 arch/powerpc/kernel/eeh.c                          |  42 +-
 arch/powerpc/kernel/eeh_dev.c                      |   2 -
 arch/powerpc/kernel/eeh_driver.c                   | 237 +++----
 arch/powerpc/kernel/eeh_pe.c                       | 160 +++--
 arch/powerpc/kernel/entry_32.S                     |   4 +-
 arch/powerpc/kernel/entry_64.S                     |  33 +-
 arch/powerpc/kernel/exceptions-64s.S               | 244 ++-----
 arch/powerpc/kernel/fadump.c                       |   4 +-
 arch/powerpc/kernel/head_8xx.S                     |   6 +-
 arch/powerpc/kernel/io-workarounds.c               |   4 +-
 arch/powerpc/kernel/iommu.c                        |   2 +-
 arch/powerpc/kernel/isa-bridge.c                   |   6 +-
 arch/powerpc/kernel/kgdb.c                         |  43 +-
 arch/powerpc/kernel/mce.c                          |   9 +-
 arch/powerpc/kernel/mce_power.c                    |   9 +-
 arch/powerpc/kernel/module.c                       |   8 +
 arch/powerpc/kernel/module_64.c                    |  14 +-
 arch/powerpc/kernel/pci_32.c                       |   1 -
 arch/powerpc/kernel/pci_64.c                       |   2 +-
 arch/powerpc/kernel/process.c                      |  90 ++-
 arch/powerpc/kernel/prom_init.c                    | 223 ++----
 arch/powerpc/kernel/prom_init_check.sh             |  16 +
 arch/powerpc/kernel/ptrace.c                       |  68 +-
 arch/powerpc/kernel/rtas.c                         |  13 +-
 arch/powerpc/kernel/rtasd.c                        |  25 +-
 arch/powerpc/kernel/setup-common.c                 |   3 +
 arch/powerpc/kernel/setup_64.c                     |  18 +-
 arch/powerpc/kernel/smp.c                          | 245 ++++++-
 arch/powerpc/kernel/swsusp_asm64.S                 |   2 +-
 arch/powerpc/kernel/time.c                         | 104 +--
 arch/powerpc/kernel/tm.S                           |  75 +-
 arch/powerpc/kernel/trace/Makefile                 |   4 +-
 arch/powerpc/kernel/trace/ftrace.c                 | 261 ++++++-
 arch/powerpc/kernel/trace/ftrace_64.S              |  12 +
 arch/powerpc/kernel/traps.c                        | 123 ++--
 arch/powerpc/kernel/vdso32/datapage.S              |   1 +
 arch/powerpc/kernel/vdso32/gettimeofday.S          |   1 +
 arch/powerpc/kernel/vdso64/datapage.S              |   1 +
 arch/powerpc/kernel/vdso64/gettimeofday.S          |   1 +
 arch/powerpc/kernel/vmlinux.lds.S                  |  16 +-
 arch/powerpc/kvm/Makefile                          |   2 -
 arch/powerpc/lib/Makefile                          |   4 +-
 arch/powerpc/lib/code-patching.c                   |   3 +-
 arch/powerpc/lib/error-inject.c                    |  16 +
 arch/powerpc/lib/mem_64.S                          |   4 +-
 arch/powerpc/mm/8xx_mmu.c                          |   5 +-
 arch/powerpc/mm/Makefile                           |  13 +-
 arch/powerpc/mm/dma-noncoherent.c                  |   2 +-
 arch/powerpc/mm/dump_linuxpagetables-8xx.c         |  82 +++
 arch/powerpc/mm/dump_linuxpagetables-book3s64.c    | 120 ++++
 arch/powerpc/mm/dump_linuxpagetables-generic.c     |  82 +++
 arch/powerpc/mm/dump_linuxpagetables.c             | 167 +----
 arch/powerpc/mm/dump_linuxpagetables.h             |  19 +
 arch/powerpc/mm/hash_native_64.c                   |   4 +-
 arch/powerpc/mm/hash_utils_64.c                    |  13 +-
 arch/powerpc/mm/hugepage-hash64.c                  |   6 +
 arch/powerpc/mm/hugetlbpage-hash64.c               |   4 +
 arch/powerpc/mm/hugetlbpage.c                      |  13 +-
 arch/powerpc/mm/mem.c                              |  13 +-
 arch/powerpc/mm/mmu_context_book3s64.c             |   9 +
 arch/powerpc/mm/mmu_decl.h                         |   6 +-
 arch/powerpc/mm/numa.c                             |   6 +
 arch/powerpc/mm/pgtable-book3e.c                   |   9 +-
 arch/powerpc/mm/pgtable-book3s64.c                 |  11 +-
 arch/powerpc/mm/pgtable-hash64.c                   |   7 +-
 arch/powerpc/mm/pgtable-radix.c                    |  65 +-
 arch/powerpc/mm/pgtable.c                          |  32 +-
 arch/powerpc/mm/pgtable_32.c                       |  70 +-
 arch/powerpc/mm/pgtable_64.c                       |  57 +-
 arch/powerpc/mm/ppc_mmu_32.c                       |   2 +-
 arch/powerpc/mm/slb.c                              | 784 +++++++++++++++------
 arch/powerpc/mm/slb_low.S                          | 335 ---------
 arch/powerpc/mm/slice.c                            |  38 +-
 arch/powerpc/mm/tlb-radix.c                        |   2 +-
 arch/powerpc/mm/tlb_nohash.c                       |   3 +
 arch/powerpc/oprofile/Makefile                     |   1 -
 arch/powerpc/perf/Makefile                         |   1 -
 arch/powerpc/perf/imc-pmu.c                        |   2 +-
 arch/powerpc/perf/power7-pmu.c                     |   1 +
 arch/powerpc/platforms/40x/Kconfig                 |   9 -
 arch/powerpc/platforms/44x/Kconfig                 |  22 -
 arch/powerpc/platforms/44x/fsp2.c                  |   8 +-
 arch/powerpc/platforms/4xx/ocm.c                   |   7 +-
 arch/powerpc/platforms/82xx/Kconfig                |   1 -
 arch/powerpc/platforms/85xx/smp.c                  |   4 +-
 arch/powerpc/platforms/8xx/machine_check.c         |   4 +-
 arch/powerpc/platforms/Kconfig                     |  21 -
 arch/powerpc/platforms/Kconfig.cputype             |   5 +-
 arch/powerpc/platforms/Makefile                    |   2 -
 arch/powerpc/platforms/cell/Kconfig                |   3 -
 arch/powerpc/platforms/cell/spu_manage.c           |  25 +-
 arch/powerpc/platforms/embedded6xx/wii.c           |   2 +-
 arch/powerpc/platforms/maple/Kconfig               |   1 -
 arch/powerpc/platforms/pasemi/Kconfig              |   1 -
 arch/powerpc/platforms/pasemi/dma_lib.c            |   2 +-
 arch/powerpc/platforms/powermac/Makefile           |   3 +-
 arch/powerpc/platforms/powermac/time.c             | 126 +---
 arch/powerpc/platforms/powernv/Kconfig             |   6 -
 arch/powerpc/platforms/powernv/eeh-powernv.c       |  62 +-
 arch/powerpc/platforms/powernv/memtrace.c          |  21 +-
 arch/powerpc/platforms/powernv/npu-dma.c           | 198 +++---
 arch/powerpc/platforms/powernv/opal-powercap.c     |   3 +-
 .../powerpc/platforms/powernv/opal-sensor-groups.c |   4 +-
 arch/powerpc/platforms/powernv/opal-sysparam.c     |   2 +-
 arch/powerpc/platforms/powernv/opal.c              |   2 +-
 arch/powerpc/platforms/powernv/setup.c             |  47 +-
 arch/powerpc/platforms/ps3/Kconfig                 |   2 -
 arch/powerpc/platforms/ps3/os-area.c               |   2 +-
 arch/powerpc/platforms/ps3/spu.c                   |   3 +-
 arch/powerpc/platforms/pseries/Kconfig             |   9 +-
 arch/powerpc/platforms/pseries/Makefile            |   3 +-
 arch/powerpc/platforms/pseries/dlpar.c             |  41 +-
 arch/powerpc/platforms/pseries/dtl.c               |   4 +-
 arch/powerpc/platforms/pseries/eeh_pseries.c       |  66 +-
 arch/powerpc/platforms/pseries/event_sources.c     |  40 +-
 arch/powerpc/platforms/pseries/firmware.c          |   2 +
 arch/powerpc/platforms/pseries/hotplug-cpu.c       |  28 +-
 arch/powerpc/platforms/pseries/hotplug-memory.c    | 116 ++-
 arch/powerpc/platforms/pseries/ibmebus.c           |   2 +-
 arch/powerpc/platforms/pseries/lpar.c              | 295 +++++++-
 arch/powerpc/platforms/pseries/lparcfg.c           |   5 +-
 arch/powerpc/platforms/pseries/mobility.c          |  23 +-
 arch/powerpc/platforms/pseries/msi.c               |   3 +-
 arch/powerpc/platforms/pseries/papr_scm.c          | 345 +++++++++
 arch/powerpc/platforms/pseries/pci.c               |   1 +
 arch/powerpc/platforms/pseries/pmem.c              | 164 +++++
 arch/powerpc/platforms/pseries/pseries.h           |  11 +-
 arch/powerpc/platforms/pseries/ras.c               | 308 +++++++-
 arch/powerpc/platforms/pseries/setup.c             |  14 +
 arch/powerpc/platforms/pseries/vio.c               |  27 +-
 arch/powerpc/sysdev/Kconfig                        |   5 -
 arch/powerpc/sysdev/Makefile                       |   3 -
 arch/powerpc/sysdev/fsl_85xx_cache_sram.c          |   8 +-
 arch/powerpc/sysdev/ipic.c                         |   2 +-
 arch/powerpc/sysdev/xics/Makefile                  |   1 -
 arch/powerpc/sysdev/xive/Kconfig                   |   3 -
 arch/powerpc/sysdev/xive/Makefile                  |   1 -
 arch/powerpc/sysdev/xive/common.c                  |   7 +-
 arch/powerpc/sysdev/xive/native.c                  |  11 +-
 arch/powerpc/xmon/Makefile                         |   5 +-
 arch/powerpc/xmon/xmon.c                           |  56 +-
 drivers/block/z2ram.c                              |   3 +-
 drivers/macintosh/adb-iop.c                        |  50 +-
 drivers/macintosh/adb.c                            |   8 +-
 drivers/macintosh/adbhid.c                         |  53 +-
 drivers/macintosh/macio_asic.c                     |   8 +-
 drivers/macintosh/macio_sysfs.c                    |   8 +-
 drivers/macintosh/via-cuda.c                       |  35 +
 drivers/macintosh/via-macii.c                      | 352 +++++----
 drivers/macintosh/via-pmu.c                        |  33 +
 drivers/macintosh/windfarm_smu_controls.c          |   4 +-
 drivers/macintosh/windfarm_smu_sat.c               |  25 +-
 drivers/misc/ocxl/config.c                         |   4 +-
 drivers/pci/hotplug/pnv_php.c                      |   2 +-
 drivers/pcmcia/electra_cf.c                        |   2 +-
 drivers/soc/fsl/qbman/qman_ccsr.c                  |   2 +-
 drivers/video/fbdev/chipsfb.c                      |   3 +-
 drivers/video/fbdev/controlfb.c                    |   5 +-
 drivers/video/fbdev/platinumfb.c                   |   5 +-
 drivers/video/fbdev/valkyriefb.c                   |  12 +-
 include/linux/cuda.h                               |   4 +
 include/linux/pmu.h                                |   4 +
 tools/testing/selftests/powerpc/Makefile           |   3 +-
 tools/testing/selftests/powerpc/include/reg.h      |   1 +
 tools/testing/selftests/powerpc/include/utils.h    |  18 +
 tools/testing/selftests/powerpc/mm/.gitignore      |   3 +-
 tools/testing/selftests/powerpc/mm/Makefile        |   4 +-
 tools/testing/selftests/powerpc/mm/wild_bctr.c     | 155 ++++
 .../powerpc/primitives/load_unaligned_zeropad.c    |   8 -
 tools/testing/selftests/powerpc/ptrace/Makefile    |   2 +-
 .../selftests/powerpc/ptrace/ptrace-syscall.c      | 228 ++++++
 tools/testing/selftests/powerpc/security/Makefile  |   9 +
 .../testing/selftests/powerpc/security/rfi_flush.c | 132 ++++
 tools/testing/selftests/powerpc/tm/tm-tmspr.c      |  27 +-
 .../testing/selftests/powerpc/tm/tm-unavailable.c  |   9 +-
 tools/testing/selftests/powerpc/tm/tm.h            |   9 +
 tools/testing/selftests/powerpc/utils.c            | 152 ++++
 253 files changed, 6305 insertions(+), 3400 deletions(-)
 create mode 100644 arch/powerpc/Kbuild
 create mode 100644 arch/powerpc/include/asm/error-injection.h
 delete mode 100644 arch/powerpc/include/asm/pte-common.h
 create mode 100644 arch/powerpc/include/asm/stackprotector.h
 create mode 100644 arch/powerpc/lib/error-inject.c
 create mode 100644 arch/powerpc/mm/dump_linuxpagetables-8xx.c
 create mode 100644 arch/powerpc/mm/dump_linuxpagetables-book3s64.c
 create mode 100644 arch/powerpc/mm/dump_linuxpagetables-generic.c
 create mode 100644 arch/powerpc/mm/dump_linuxpagetables.h
 delete mode 100644 arch/powerpc/mm/slb_low.S
 create mode 100644 arch/powerpc/platforms/pseries/papr_scm.c
 create mode 100644 arch/powerpc/platforms/pseries/pmem.c
 create mode 100644 tools/testing/selftests/powerpc/mm/wild_bctr.c
 create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-syscall.c
 create mode 100644 tools/testing/selftests/powerpc/security/Makefile
 create mode 100644 tools/testing/selftests/powerpc/security/rfi_flush.c
-----BEGIN PGP SIGNATURE-----

iQIcBAEBAgAGBQJb017dAAoJEFHr6jzI4aWAnlQP/3upt08ScW29U3UWx6e+c5za
l1tj/tCzsNz6QfPBgHdPk0GGE7ZdBKAaqtXzx0OaboGg5D1467MnUU1zkh1jx53Q
/BmuWDCiWLOv7VGb7YIsYZg7XztfkwTRilZnw4J2Y6UQanYC5ebOMtu0ze6fiYey
ETmnWHCDb4yluX/RFRHthcqAjNFD1r6w4JPIVYMde19l2POlrDTnKyb/K5uAwUm/
Wr622G4BJZz5nfXPWR5VZMDto4/n+ZOLwRtF9wirqWuP18KB2uRfCxawzzKyR6oS
Bwd15zT5jz/sWeqbIvAkf7ROTZfHr55XgdZ4VDexjGuVkbnp8ri9niI3xEc0ojT1
bRtMds89BFoiSqraY8HdPBpdEP879JvQz0+T+PArHRkMXcXFvW16WaB4awtPNnl5
ga+QnQ6z8IPzYomWgNLTv+eMXbSK8A7gChcIaEtDRDOswVTIDp8yew3mtE3rwOkC
Fvnbf7PYav5lYjGfaPaV5+EaE2wlu+FQHpXmI+H/G4mLxtkUe6XR19Q7Q/XkRzY+
uP/TAziGVBjygGm4PM7bxh+f8HTXRKtfLB6Ota7ud0nLrGj7CjroMUm6dgrcS4Xz
FAaz/qmvnO0aVWOkxUvG3wwYhpzo2DyQLS99oi+t5VIOWupCBFySLc8UZSuWzK1G
3lbQqXAcSuYohCP0dgZH
=upUr
-----END PGP SIGNATURE-----

^ permalink raw reply

* [PATCH] Documentation: fix spelling mistake, EACCESS -> EACCES
From: Colin King @ 2018-10-26 17:25 UTC (permalink / raw)
  To: Jeremy Kerr, Jonathan Corbet, David Airlie, Maarten Lankhorst,
	Maxime Ripard, Sean Paul, linuxppc-dev, linux-doc
  Cc: kernel-janitors, linux-kernel

From: Colin Ian King <colin.king@canonical.com>

Trivial fix to a spelling mistake of the error access name EACCESS,
rename to EACCES

Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
 Documentation/filesystems/spufs.txt | 2 +-
 Documentation/gpu/drm-uapi.rst      | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/Documentation/filesystems/spufs.txt b/Documentation/filesystems/spufs.txt
index 1343d118a9b2..eb9e3aa63026 100644
--- a/Documentation/filesystems/spufs.txt
+++ b/Documentation/filesystems/spufs.txt
@@ -452,7 +452,7 @@ RETURN VALUE
 
 
 ERRORS
-       EACCESS
+       EACCES
               The  current  user does not have write access on the spufs mount
               point.
 
diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst
index a2214cc1f821..f2f079e91b4c 100644
--- a/Documentation/gpu/drm-uapi.rst
+++ b/Documentation/gpu/drm-uapi.rst
@@ -190,11 +190,11 @@ ENOSPC:
 
         Simply running out of kernel/system memory is signalled through ENOMEM.
 
-EPERM/EACCESS:
+EPERM/EACCES:
         Returned for an operation that is valid, but needs more privileges.
         E.g. root-only or much more common, DRM master-only operations return
         this when when called by unpriviledged clients. There's no clear
-        difference between EACCESS and EPERM.
+        difference between EACCES and EPERM.
 
 ENODEV:
         Feature (like PRIME, modesetting, GEM) is not supported by the driver.
-- 
2.19.1


^ permalink raw reply related

* Re: [PATCH 5/5] powerpc/64s: Document that PPC supports nosmap
From: LEROY Christophe @ 2018-10-26 16:35 UTC (permalink / raw)
  To: Russell Currey; +Cc: mikey, linuxppc-dev, npiggin
In-Reply-To: <20181026063513.30806-6-ruscur@russell.cc>

Why not call our new functionnality SMAP instead of calling it GUAP ?

Christophe

Russell Currey <ruscur@russell.cc> a écrit :

> Signed-off-by: Russell Currey <ruscur@russell.cc>
> ---
>  Documentation/admin-guide/kernel-parameters.txt | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/Documentation/admin-guide/kernel-parameters.txt  
> b/Documentation/admin-guide/kernel-parameters.txt
> index a5ad67d5cb16..8f78e75965f0 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -2764,7 +2764,7 @@
>  			noexec=on: enable non-executable mappings (default)
>  			noexec=off: disable non-executable mappings
>
> -	nosmap		[X86]
> +	nosmap		[X86,PPC]
>  			Disable SMAP (Supervisor Mode Access Prevention)
>  			even if it is supported by processor.
>
> --
> 2.19.1



^ permalink raw reply

* Re: [PATCH 3/5] powerpc/lib: checksum GUAP support
From: LEROY Christophe @ 2018-10-26 16:33 UTC (permalink / raw)
  To: Russell Currey; +Cc: mikey, linuxppc-dev, npiggin
In-Reply-To: <20181026063513.30806-4-ruscur@russell.cc>

Same comment as for futex

Christophe

Russell Currey <ruscur@russell.cc> a écrit :

> Wrap the checksumming code in GUAP locks and unlocks.
>
> Signed-off-by: Russell Currey <ruscur@russell.cc>
> ---
>  arch/powerpc/lib/checksum_wrappers.c | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/arch/powerpc/lib/checksum_wrappers.c  
> b/arch/powerpc/lib/checksum_wrappers.c
> index a0cb63fb76a1..c67db0a6e18b 100644
> --- a/arch/powerpc/lib/checksum_wrappers.c
> +++ b/arch/powerpc/lib/checksum_wrappers.c
> @@ -28,6 +28,7 @@ __wsum csum_and_copy_from_user(const void __user  
> *src, void *dst,
>  {
>  	unsigned int csum;
>
> +	unlock_user_access();
>  	might_sleep();
>
>  	*err_ptr = 0;
> @@ -60,6 +61,7 @@ __wsum csum_and_copy_from_user(const void __user  
> *src, void *dst,
>  	}
>
>  out:
> +	lock_user_access();
>  	return (__force __wsum)csum;
>  }
>  EXPORT_SYMBOL(csum_and_copy_from_user);
> @@ -69,6 +71,7 @@ __wsum csum_and_copy_to_user(const void *src, void  
> __user *dst, int len,
>  {
>  	unsigned int csum;
>
> +	unlock_user_access();
>  	might_sleep();
>
>  	*err_ptr = 0;
> @@ -97,6 +100,7 @@ __wsum csum_and_copy_to_user(const void *src,  
> void __user *dst, int len,
>  	}
>
>  out:
> +	lock_user_access();
>  	return (__force __wsum)csum;
>  }
>  EXPORT_SYMBOL(csum_and_copy_to_user);
> --
> 2.19.1



^ permalink raw reply

* Re: [PATCH 2/5] powerpc/futex: GUAP support for futex ops
From: LEROY Christophe @ 2018-10-26 16:32 UTC (permalink / raw)
  To: Russell Currey; +Cc: mikey, linuxppc-dev, npiggin
In-Reply-To: <20181026063513.30806-3-ruscur@russell.cc>

Russell Currey <ruscur@russell.cc> a écrit :

> Wrap the futex operations in GUAP locks and unlocks.

Does it means futex doesn't work anymore once only patch 1 is applied  
? If so, then you should split patch 1 in two parts and reorder  
patches so that guap can only be activated once all necessary changes  
are done. Otherwise the serie won't be bisectable

Christophe

>
> Signed-off-by: Russell Currey <ruscur@russell.cc>
> ---
>  arch/powerpc/include/asm/futex.h | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/arch/powerpc/include/asm/futex.h  
> b/arch/powerpc/include/asm/futex.h
> index 94542776a62d..3aed640ee9ef 100644
> --- a/arch/powerpc/include/asm/futex.h
> +++ b/arch/powerpc/include/asm/futex.h
> @@ -35,6 +35,7 @@ static inline int arch_futex_atomic_op_inuser(int  
> op, int oparg, int *oval,
>  {
>  	int oldval = 0, ret;
>
> +	unlock_user_access();
>  	pagefault_disable();
>
>  	switch (op) {
> @@ -62,6 +63,7 @@ static inline int arch_futex_atomic_op_inuser(int  
> op, int oparg, int *oval,
>  	if (!ret)
>  		*oval = oldval;
>
> +	lock_user_access();
>  	return ret;
>  }
>
> @@ -75,6 +77,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
>  	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
>  		return -EFAULT;
>
> +	unlock_user_access();
>          __asm__ __volatile__ (
>          PPC_ATOMIC_ENTRY_BARRIER
>  "1:     lwarx   %1,0,%3         # futex_atomic_cmpxchg_inatomic\n\
> @@ -95,6 +98,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
>          : "cc", "memory");
>
>  	*uval = prev;
> +	lock_user_access();
>          return ret;
>  }
>
> --
> 2.19.1



^ permalink raw reply

* Re: [PATCH 0/5] Guarded Userspace Access Prevention on Radix
From: LEROY Christophe @ 2018-10-26 16:29 UTC (permalink / raw)
  To: Russell Currey; +Cc: mikey, linuxppc-dev, npiggin
In-Reply-To: <20181026063513.30806-1-ruscur@russell.cc>

Russell Currey <ruscur@russell.cc> a écrit :

> Guarded Userspace Access Prevention is a security mechanism that prevents
> the kernel from being able to read and write userspace addresses outside of
> the allowed paths, most commonly copy_{to/from}_user().
>
> At present, the only CPU that supports this is POWER9, and only while using
> the Radix MMU.  Privileged reads and writes cannot access user data when
> key 0 of the AMR is set.  This is described in the "Radix Tree Translation
> Storage Protection" section of the POWER ISA as of version 3.0.

It is not right that only power9 can support that.

The 8xx has mmu access protection registers which can serve the same  
purpose. Today on the 8xx kernel space is group 0 and user space is  
group 1. Group 0 is set to "page defined access permission" in MD_AP  
and MI_AP registers, and group 1 is set to "all accesses done with  
supervisor rights". By setting group 1 to "user and supervisor  
interpretation swapped" we can forbid kernel access to user space  
while still allowing user access to it. Then by simply changing group  
1 mode at dedicated places we can lock/unlock kernel access to user  
space.

Could you implement something as generic as possible having that in  
mind for a future patch ?

Christophe

>
> GUAP code sets key 0 of the AMR (thus disabling accesses of user data)
> early during boot, and only ever "unlocks" access prior to certain
> operations, like copy_{to/from}_user(), futex ops, etc.  Setting this does
> not prevent unprivileged access, so userspace can operate fine while access
> is locked.
>
> There is a performance impact, although I don't consider it heavy.  Running
> a worst-case benchmark of a 1GB copy 1 byte at a time (and thus constant
> read(1) write(1) syscalls), I found enabling GUAP to be 3.5% slower than
> when disabled.  In most cases, the difference is negligible.  The main
> performance impact is the mtspr instruction, which is quite slow.
>
> There are a few caveats with this series that could be improved upon in
> future.  Right now there is no saving and restoring of the AMR value -
> there is no userspace exploitation of the AMR on Radix in POWER9, but if
> this were to change in future, saving and restoring the value would be
> necessary.
>
> No attempt to optimise cases of repeated calls - for example, if some
> code was repeatedly calling copy_to_user() for small sizes very frequently,
> it would be slower than the equivalent of wrapping that code in an unlock
> and lock and only having to modify the AMR once.
>
> There are some interesting cases that I've attempted to handle, such as if
> the AMR is unlocked (i.e. because a copy_{to_from}_user is in progress)...
>
>     - and an exception is taken, the kernel would then be running with the
>     AMR unlocked and freely able to access userspace again.  I am working
>     around this by storing a flag in the PACA to indicate if the AMR is
>     unlocked (to save a costly SPR read), and if so, locking the AMR in
>     the exception entry path and unlocking it on the way out.
>
>     - and gets context switched out, goes into a path that locks the AMR,
>     then context switches back, access will be disabled and will fault.
>     As a result, I context switch the AMR between tasks as if it was used
>     by userspace like hash (which already implements this).
>
> Another consideration is use of the isync instruction.  Without an isync
> following the mtspr instruction, there is no guarantee that the change
> takes effect.  The issue is that isync is very slow, and so I tried to
> avoid them wherever necessary.  In this series, the only place an isync
> gets used is after *unlocking* the AMR, because if an access takes place
> and access is still prevented, the kernel will fault.
>
> On the flipside, a slight delay in unlocking caused by skipping an isync
> potentially allows a small window of vulnerability.  It is my opinion
> that this window is practically impossible to exploit, but if someone
> thinks otherwise, please do share.
>
> This series is my first attempt at POWER assembly so all feedback is very
> welcome.
>
> The official theme song of this series can be found here:
>     https://www.youtube.com/watch?v=QjTrnKAcYjE
>
> Russell Currey (5):
>   powerpc/64s: Guarded Userspace Access Prevention
>   powerpc/futex: GUAP support for futex ops
>   powerpc/lib: checksum GUAP support
>   powerpc/64s: Disable GUAP with nosmap option
>   powerpc/64s: Document that PPC supports nosmap
>
>  .../admin-guide/kernel-parameters.txt         |  2 +-
>  arch/powerpc/include/asm/exception-64e.h      |  3 +
>  arch/powerpc/include/asm/exception-64s.h      | 19 ++++++-
>  arch/powerpc/include/asm/futex.h              |  6 ++
>  arch/powerpc/include/asm/mmu.h                |  7 +++
>  arch/powerpc/include/asm/paca.h               |  3 +
>  arch/powerpc/include/asm/reg.h                |  1 +
>  arch/powerpc/include/asm/uaccess.h            | 57 ++++++++++++++++---
>  arch/powerpc/kernel/asm-offsets.c             |  1 +
>  arch/powerpc/kernel/dt_cpu_ftrs.c             |  4 ++
>  arch/powerpc/kernel/entry_64.S                | 17 +++++-
>  arch/powerpc/lib/checksum_wrappers.c          |  6 +-
>  arch/powerpc/mm/fault.c                       |  9 +++
>  arch/powerpc/mm/init_64.c                     | 15 +++++
>  arch/powerpc/mm/pgtable-radix.c               |  2 +
>  arch/powerpc/mm/pkeys.c                       |  7 ++-
>  arch/powerpc/platforms/Kconfig.cputype        | 15 +++++
>  17 files changed, 158 insertions(+), 16 deletions(-)
>
> --
> 2.19.1



^ permalink raw reply

* Re: ethernet "bus" number in DTS ?
From: Joakim Tjernlund @ 2018-10-26 13:00 UTC (permalink / raw)
  To: f.fainelli@gmail.com, msuchanek@suse.de
  Cc: netdev@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
	andrew@lunn.ch
In-Reply-To: <20181024082239.5ee41017@naga.suse.cz>

On Wed, 2018-10-24 at 08:22 +0200, Michal Suchánek wrote:
> CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
> 
> 
> On Tue, 23 Oct 2018 11:20:36 -0700
> Florian Fainelli <f.fainelli@gmail.com> wrote:
> 
> > On 10/23/18 11:02 AM, Joakim Tjernlund wrote:
> > > On Tue, 2018-10-23 at 10:03 -0700, Florian Fainelli wrote:
> > > I also noted that using status = "disabled" didn't work either to
> > > create a fix name scheme. Even worse, all the eth I/F after gets
> > > renumbered. It seems to me there is value in having stability in
> > > eth I/F naming at boot. Then userspace(udev) can rename if need be.
> > > 
> > > Sure would like to known more about why this feature is not wanted ?
> > > 
> > > I found
> > >   https://patchwork.kernel.org/patch/4122441/
> > > You quote policy as reason but surely it must be better to
> > > have something stable, connected to the hardware name, than
> > > semirandom naming?
> > 
> > If the Device Tree nodes are ordered by ascending base register
> > address, my understanding is that you get the same order as far as
> > platform_device creation goes, this may not be true in the future if
> > Rob decides to randomize that, but AFAICT this is still true. This
> > may not work well with status = disabled properties being inserted
> > here and there, but we have used that here and it has worked for as
> > far as I can remember doing it.
> 
> So this is unstable in several respects. First is changing the
> enabled/disabled status in the deivecetrees provided by the kernel.
> 
> Second is if you have hardware hotplug mechanism either by firmware or
> by loading device overlays.
> 
> Third is the case when the devicetree is not built as part of the
> kernel but is instead provided by firmware that initializes the
> low-level hardware details. Then the ordering by address is not
> guaranteed nor is that the same address will be used to access the same
> interface every time. There might be multiple ways to configure the
> hardware depending on firmware configuration and/or version.
> 
> 
> > Second, you might want to name network devices ethX, but what if I
> > want to name them ethernetX or fooX or barX? Should we be accepting a
> > mechanism in the kernel that would allow someone to name the
> > interfaces the way they want straight from a name being provided in
> > Device Tree?

Just to be clear, I am saying that we don't need to control the full
name of the Ethernet device, just the numerical id so one can tie eth0
to a fixed physical device.

> 
> Clearly if there is text Ethernet1 printed above the Ethernet port we
> should provide a mechanism to name the port Ethernet1 by default.
> 
> > Aliases are fine for providing relative stability within the Device
> > Tree itself and boot programs that might need to modify the Device
> > Tree (e.g: inserting MAC addresses) such that you don't have to
> > encode logic to search for nodes by compatible strings etc. but
> > outside of that use case, it seems to me that you can resolve every
> > naming decision in user-space.
> 
> However, this is pushing platform-specific knowledge to userspace. The
> way the Ethernet interface is attached and hence the device properties
> usable for identifying the device uniquely are platform-specific.
> 
> On the other hand, aliases are universal when provided. If they are
> good enough to assign a MAC address they are good enough to provide a
> stable default name.
> 
> I think this is indeed forcing the userspace to reinvent several wheels
> for no good reason.
> 
> What is the problem with adding the aliases?

Well put above, thanks.

   Jocke

^ permalink raw reply

* Re: ethernet "bus" number in DTS ?
From: Michal Suchánek @ 2018-10-24  6:22 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: andrew@lunn.ch, linuxppc-dev@lists.ozlabs.org,
	netdev@vger.kernel.org
In-Reply-To: <8225ba9e-ce8f-b0e0-8f3d-73783693eea4@gmail.com>

On Tue, 23 Oct 2018 11:20:36 -0700
Florian Fainelli <f.fainelli@gmail.com> wrote:

> On 10/23/18 11:02 AM, Joakim Tjernlund wrote:
> > On Tue, 2018-10-23 at 10:03 -0700, Florian Fainelli wrote:  

> > 
> > I also noted that using status = "disabled" didn't work either to
> > create a fix name scheme. Even worse, all the eth I/F after gets
> > renumbered. It seems to me there is value in having stability in
> > eth I/F naming at boot. Then userspace(udev) can rename if need be. 
> > 
> > Sure would like to known more about why this feature is not wanted ?
> > 
> > I found
> >   https://patchwork.kernel.org/patch/4122441/
> > You quote policy as reason but surely it must be better to
> > have something stable, connected to the hardware name, than
> > semirandom naming?  
> 
> If the Device Tree nodes are ordered by ascending base register
> address, my understanding is that you get the same order as far as
> platform_device creation goes, this may not be true in the future if
> Rob decides to randomize that, but AFAICT this is still true. This
> may not work well with status = disabled properties being inserted
> here and there, but we have used that here and it has worked for as
> far as I can remember doing it.

So this is unstable in several respects. First is changing the
enabled/disabled status in the deivecetrees provided by the kernel.

Second is if you have hardware hotplug mechanism either by firmware or
by loading device overlays.

Third is the case when the devicetree is not built as part of the
kernel but is instead provided by firmware that initializes the
low-level hardware details. Then the ordering by address is not
guaranteed nor is that the same address will be used to access the same
interface every time. There might be multiple ways to configure the
hardware depending on firmware configuration and/or version.

 
> Second, you might want to name network devices ethX, but what if I
> want to name them ethernetX or fooX or barX? Should we be accepting a
> mechanism in the kernel that would allow someone to name the
> interfaces the way they want straight from a name being provided in
> Device Tree?

Clearly if there is text Ethernet1 printed above the Ethernet port we
should provide a mechanism to name the port Ethernet1 by default.

> 
> Aliases are fine for providing relative stability within the Device
> Tree itself and boot programs that might need to modify the Device
> Tree (e.g: inserting MAC addresses) such that you don't have to
> encode logic to search for nodes by compatible strings etc. but
> outside of that use case, it seems to me that you can resolve every
> naming decision in user-space.

However, this is pushing platform-specific knowledge to userspace. The
way the Ethernet interface is attached and hence the device properties
usable for identifying the device uniquely are platform-specific. 

On the other hand, aliases are universal when provided. If they are
good enough to assign a MAC address they are good enough to provide a
stable default name.

I think this is indeed forcing the userspace to reinvent several wheels
for no good reason.

What is the problem with adding the aliases?

Thanks

Michal

^ permalink raw reply

* Re: [PATCH v2] idle/x86: remove the call to boot_init_stack_canary() from cpu_startup_entry()
From: kbuild test robot @ 2018-10-26 12:10 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: Juergen Gross, Peter Zijlstra, x86, linux-kernel, Ingo Molnar,
	Borislav Petkov, kbuild-all, H. Peter Anvin, xen-devel,
	Boris Ostrovsky, linuxppc-dev, Thomas Gleixner
In-Reply-To: <285fcf8852b5924cb01de00be1152ea617527c52.1539944940.git.christophe.leroy@c-s.fr>

[-- Attachment #1: Type: text/plain, Size: 1468 bytes --]

Hi Christophe,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on xen-tip/linux-next]
[also build test ERROR on v4.19 next-20181019]
[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/Christophe-Leroy/idle-x86-remove-the-call-to-boot_init_stack_canary-from-cpu_startup_entry/20181020-061217
base:   https://git.kernel.org/pub/scm/linux/kernel/git/xen/tip.git linux-next
config: x86_64-rhel (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   arch/x86/xen/smp_pv.c: In function 'cpu_bringup_and_idle':
>> arch/x86/xen/smp_pv.c:91:2: error: implicit declaration of function 'boot_init_stack_canary'; did you mean 'snprint_stack_trace'? [-Werror=implicit-function-declaration]
     boot_init_stack_canary();
     ^~~~~~~~~~~~~~~~~~~~~~
     snprint_stack_trace
   cc1: some warnings being treated as errors

vim +91 arch/x86/xen/smp_pv.c

    87	
    88	asmlinkage __visible void cpu_bringup_and_idle(void)
    89	{
    90		cpu_bringup();
  > 91		boot_init_stack_canary();
    92		cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
    93	}
    94	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 41215 bytes --]

^ permalink raw reply

* Re: [PATCH v2 0/2] arm64: Cut rebuild time when changing CONFIG_BLK_DEV_INITRD
From: Mike Rapoport @ 2018-10-26 11:07 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Linux-MIPS, linux-ia64, SH-Linux, Catalin Marinas, Will Deacon,
	devicetree, sparclinux, linux-riscv,
	open list:GENERIC INCLUDE/ASM HEADER FILES, Rob Herring,
	linux-c6x-dev, linux-hexagon, arcml,
	moderated list:H8/300 ARCHITECTURE, linux-xtensa, Arnd Bergmann,
	linux-s390, Marc Zyngier, linux-um, linux-m68k, Openrisc,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	linux-parisc, Ard Biesheuvel, Greg Kroah-Hartman,
	linux-kernel@vger.kernel.org, linux-alpha, Olof Johansson,
	nios2-dev, linuxppc-dev
In-Reply-To: <1bb3bd63-a88e-b668-ea36-f0f985c0e2b1@gmail.com>

On Thu, Oct 25, 2018 at 04:07:13PM -0700, Florian Fainelli wrote:
> On 10/25/18 2:13 PM, Rob Herring wrote:
> > On Thu, Oct 25, 2018 at 12:30 PM Mike Rapoport <rppt@linux.ibm.com> wrote:
> >>
> >> On Thu, Oct 25, 2018 at 08:15:15AM -0500, Rob Herring wrote:
> >>> +Ard
> >>>
> >>> On Thu, Oct 25, 2018 at 4:38 AM Mike Rapoport <rppt@linux.ibm.com> wrote:
> >>>>
> >>>> On Wed, Oct 24, 2018 at 02:55:17PM -0500, Rob Herring wrote:
> >>>>> On Wed, Oct 24, 2018 at 2:33 PM Florian Fainelli <f.fainelli@gmail.com> wrote:
> >>>>>>
> >>>>>> Hi all,
> >>>>>>
> >>>>>> While investigating why ARM64 required a ton of objects to be rebuilt
> >>>>>> when toggling CONFIG_DEV_BLK_INITRD, it became clear that this was
> >>>>>> because we define __early_init_dt_declare_initrd() differently and we do
> >>>>>> that in arch/arm64/include/asm/memory.h which gets included by a fair
> >>>>>> amount of other header files, and translation units as well.
> >>>>>
> >>>> I think arm64 does not have to redefine __early_init_dt_declare_initrd().
> >>>> Something like this might be just all we need (completely untested,
> >>>> probably it won't even compile):

[ ... ]
 
> FWIW, I am extracting the ARM implementation that parses the initrd
> early command line parameter and the "setup" code doing the page
> boundary alignment and memblock checking into a helper into lib/ that
> other architectures can re-use. So far, this removes the need for
> unicore32, arc and arm to duplicate essentially the same logic.

Presuming you are going to need asm-generic/initrd.h for that as well,
using override for __early_init_dt_declare_initrd in arm64 version of
initrd.h might be the simplest option.

> -- 
> Florian
> 

-- 
Sincerely yours,
Mike.


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox