Re: [RFC PATCH 0/5] powerpc: KASAN for 64-bit Book3E

2019-02-16 Thread Balbir Singh
On Fri, Feb 15, 2019 at 11:04:36AM +1100, Daniel Axtens wrote:
> Building on the work of Christophe, Aneesh and Balbir, I've ported
> KASAN to the e6500, a 64-bit Book3E processor which doesn't have a
> hashed page table. It applies on top of Christophe's series, v5.
> 
> It requires some changes to the KASAN core - please let me know if
> these are problematic and we see if an alternative approach is
> possible.
> 
> The KASAN shadow area is mapped into vmemmap space:
> 0x8000 0400   to 0x8000 0600  .
> To do this we require that vmemmap be disabled. (This is the default
> in the kernel config that QorIQ provides for the machine in their
> SDK anyway - they use flat memory.)
> 
> Only outline instrumentation is supported and only KASAN_MINIMAL works.
> Only the kernel linear mapping (0xc000...) is checked. The vmalloc and
> ioremap areas (also in 0x800...) are all mapped to a zero page. As
> with the Book3S hash series, this requires overriding the memory <->
> shadow mapping.
> 
> Also, as with both previous 64-bit series, early instrumentation is not
> supported.
> 
> KVM, kexec and xmon have not been tested.
> 
> Thanks to those who have done the heavy lifting over the past several years:
>  - Christophe's 32 bit series: 
> https://lists.ozlabs.org/pipermail/linuxppc-dev/2019-February/185379.html
>  - Aneesh's Book3S hash series: https://lwn.net/Articles/655642/
>  - Balbir's Book3S radix series: https://patchwork.ozlabs.org/patch/795211/
> 
> While useful if you have an Book3E device, this is mostly intended
> as a warm-up exercise for reviving Aneesh's series for book3s hash.
> In particular, changes to the kasan core are going to be required
> for hash and radix as well.
>

Thanks for following through with this, could you please share details on
how you've been testing this?

I know qemu supports qemu -cpu e6500, but beyond that what does the machine
look like?

Balbir Singh. 


Re: [PATCH] powerpc/64s: Fix possible corruption on big endian due to pgd/pud_present()

2019-02-16 Thread Balbir Singh
On Sat, Feb 16, 2019 at 08:22:12AM -0600, Segher Boessenkool wrote:
> Hi all,
> 
> On Sat, Feb 16, 2019 at 09:55:11PM +1100, Balbir Singh wrote:
> > On Thu, Feb 14, 2019 at 05:23:39PM +1100, Michael Ellerman wrote:
> > > In v4.20 we changed our pgd/pud_present() to check for _PAGE_PRESENT
> > > rather than just checking that the value is non-zero, e.g.:
> > > 
> > >   static inline int pgd_present(pgd_t pgd)
> > >   {
> > >  -   return !pgd_none(pgd);
> > >  +   return (pgd_raw(pgd) & cpu_to_be64(_PAGE_PRESENT));
> > >   }
> > > 
> > > Unfortunately this is broken on big endian, as the result of the
> > > bitwise && is truncated to int, which is always zero because
> 
> (Bitwise "&" of course).
> 
> > Not sure why that should happen, why is the result an int? What
> > causes the casting of pgd_t & be64 to be truncated to an int.
> 
> Yes, it's not obvious as written...  It's simply that the return type of
> pgd_present is int.  So it is truncated _after_ the bitwise and.
>

Thanks, I am surprised the compiler does not complain about the truncation
of bits. I wonder if we are missing -Wconversion

Balbir


[RFC PATCH 2/2] powerpc/mm/hash64: Map all the kernel mapping in the same 0xc range

2019-02-16 Thread Aneesh Kumar K.V
This patch maps vmap, IO and vmemap regions in the 0xc address range
instead of the current 0xd and 0xf range. This brings the mapping closer
to radix translation mode.

With hash 64K page size each of this region is 512TB whereas with 4K config
we are limitted by the max page table range of 64TB and hence there regions
are of 16TB size.

NOT-Signed-off-by: Aneesh Kumar K.V 
---
 arch/powerpc/include/asm/book3s/64/hash-4k.h  | 17 
 arch/powerpc/include/asm/book3s/64/hash-64k.h | 11 +++
 arch/powerpc/include/asm/book3s/64/hash.h | 89 ++-
 arch/powerpc/include/asm/book3s/64/mmu-hash.h | 31 ---
 arch/powerpc/include/asm/book3s/64/radix.h| 24 ++---
 arch/powerpc/include/asm/page.h   |  3 +-
 arch/powerpc/kvm/book3s_hv_rm_xics.c  |  2 +-
 arch/powerpc/mm/copro_fault.c | 14 +--
 arch/powerpc/mm/dump_hashpagetable.c  |  2 +-
 arch/powerpc/mm/dump_linuxpagetables.c|  2 +-
 arch/powerpc/mm/hash_utils_64.c   | 29 +++---
 arch/powerpc/mm/pgtable-radix.c   |  2 +-
 arch/powerpc/mm/slb.c | 22 +++--
 13 files changed, 166 insertions(+), 82 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h 
b/arch/powerpc/include/asm/book3s/64/hash-4k.h
index cf5ba5254299..6db6e5c5c176 100644
--- a/arch/powerpc/include/asm/book3s/64/hash-4k.h
+++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h
@@ -13,6 +13,23 @@
  */
 #define MAX_EA_BITS_PER_CONTEXT46
 
+/*
+ * Our page table limit us to 64TB. Hence for the kernel mapping,
+ * each MAP area is limited to 16 TB.
+ * The four map areas are:
+ * linear mapping
+ * vmap
+ * IO
+ * vmemmap
+ */
+#define EA_KERNEL_MAP_SIZE (ASM_CONST(1) << (46 - 2))
+
+/*
+ * Define the address range of the kernel non-linear virtual area
+ * 16TB
+ */
+#define H_KERN_VIRT_START  ASM_CONST(0xc0001000)
+
 #ifndef __ASSEMBLY__
 #define H_PTE_TABLE_SIZE   (sizeof(pte_t) << H_PTE_INDEX_SIZE)
 #define H_PMD_TABLE_SIZE   (sizeof(pmd_t) << H_PMD_INDEX_SIZE)
diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h 
b/arch/powerpc/include/asm/book3s/64/hash-64k.h
index f82ee8a3b561..11add16d25d3 100644
--- a/arch/powerpc/include/asm/book3s/64/hash-64k.h
+++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h
@@ -13,6 +13,17 @@
  */
 #define MAX_EA_BITS_PER_CONTEXT49
 
+/*
+ * We use one context for each MAP area.
+ */
+#define EA_KERNEL_MAP_SIZE (1UL << MAX_EA_BITS_PER_CONTEXT)
+
+/*
+ * Define the address range of the kernel non-linear virtual area
+ * 2PB
+ */
+#define H_KERN_VIRT_START  ASM_CONST(0xc008)
+
 /*
  * 64k aligned address free up few of the lower bits of RPN for us
  * We steal that here. For more deatils look at pte_pfn/pfn_pte()
diff --git a/arch/powerpc/include/asm/book3s/64/hash.h 
b/arch/powerpc/include/asm/book3s/64/hash.h
index 94f9db7a746a..18d5caab7e1d 100644
--- a/arch/powerpc/include/asm/book3s/64/hash.h
+++ b/arch/powerpc/include/asm/book3s/64/hash.h
@@ -30,6 +30,11 @@
 H_PUD_INDEX_SIZE + H_PGD_INDEX_SIZE + 
PAGE_SHIFT)
 #define H_PGTABLE_RANGE(ASM_CONST(1) << H_PGTABLE_EADDR_SIZE)
 
+/*
+ * Top 4 bits are ignored in page table walk.
+ */
+#define EA_MASK(~(0xfUL << 60))
+
 /*
  * We store the slot details in the second half of page table.
  * Increase the pud level table so that hugetlb ptes can be stored
@@ -40,41 +45,63 @@
 #else
 #define H_PUD_CACHE_INDEX  (H_PUD_INDEX_SIZE)
 #endif
+
 /*
- * Define the address range of the kernel non-linear virtual area
+ * 3 context will be used for vmap, IO and vmemmap
  */
-#define H_KERN_VIRT_START ASM_CONST(0xD000)
-#define H_KERN_VIRT_SIZE  ASM_CONST(0x4000) /* 64T */
-
+#define H_KERN_VIRT_SIZE   (EA_KERNEL_MAP_SIZE * 3)
 /*
- * The vmalloc space starts at the beginning of that region, and
- * occupies half of it on hash CPUs and a quarter of it on Book3E
- * (we keep a quarter for the virtual memmap)
+ * +--+
+ * |  |
+ * |  |
+ * |  |
+ * +--+  Kernel virtual map end 
(0xc00e)
+ * |  |
+ * |  |
+ * |  512TB/16TB of vmemmap   |
+ * |  |
+ * |  |
+ * +--+  Kernel vmemmap  start
+ * |  |
+ * |  512TB/16TB of IO map|
+ * |  |
+ * +--+  Kernel IO map start
+ * |  |
+ * |  512TB/16TB of vmap  |
+ * |  |
+ * +--+  Kernel virt start (0xc008)
+ * |  |
+ * |  |
+ * |

[RFC PATCH 1/2] powerpc/mm/hash64: Add a variable to track the end of IO mapping

2019-02-16 Thread Aneesh Kumar K.V
NOT-Signed-off-by: Aneesh Kumar K.V 
---
 arch/powerpc/include/asm/book3s/64/hash.h| 1 +
 arch/powerpc/include/asm/book3s/64/pgtable.h | 8 +---
 arch/powerpc/include/asm/book3s/64/radix.h   | 1 +
 arch/powerpc/mm/hash_utils_64.c  | 1 +
 arch/powerpc/mm/pgtable-radix.c  | 1 +
 arch/powerpc/mm/pgtable_64.c | 2 ++
 6 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/64/hash.h 
b/arch/powerpc/include/asm/book3s/64/hash.h
index 247aff9cc6ba..94f9db7a746a 100644
--- a/arch/powerpc/include/asm/book3s/64/hash.h
+++ b/arch/powerpc/include/asm/book3s/64/hash.h
@@ -56,6 +56,7 @@
 #define H_VMALLOC_END  (H_VMALLOC_START + H_VMALLOC_SIZE)
 
 #define H_KERN_IO_STARTH_VMALLOC_END
+#define H_KERN_IO_END  (H_KERN_VIRT_START + H_KER_VIRT_SIZE)
 
 /*
  * Region IDs
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h 
b/arch/powerpc/include/asm/book3s/64/pgtable.h
index 544e54b3046d..dc71e2b92003 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -277,9 +277,12 @@ extern unsigned long __vmalloc_end;
 extern unsigned long __kernel_virt_start;
 extern unsigned long __kernel_virt_size;
 extern unsigned long __kernel_io_start;
+extern unsigned long __kernel_io_end;
 #define KERN_VIRT_START __kernel_virt_start
 #define KERN_VIRT_SIZE  __kernel_virt_size
 #define KERN_IO_START  __kernel_io_start
+#define KERN_IO_END __kernel_io_end
+
 extern struct page *vmemmap;
 extern unsigned long ioremap_bot;
 extern unsigned long pci_io_base;
@@ -296,8 +299,7 @@ extern unsigned long pci_io_base;
 
 #include 
 /*
- * The second half of the kernel virtual space is used for IO mappings,
- * it's itself carved into the PIO region (ISA and PHB IO space) and
+ * IO space itself carved into the PIO region (ISA and PHB IO space) and
  * the ioremap space
  *
  *  ISA_IO_BASE = KERN_IO_START, 64K reserved area
@@ -310,7 +312,7 @@ extern unsigned long pci_io_base;
 #define  PHB_IO_BASE   (ISA_IO_END)
 #define  PHB_IO_END(KERN_IO_START + FULL_IO_SIZE)
 #define IOREMAP_BASE   (PHB_IO_END)
-#define IOREMAP_END(KERN_VIRT_START + KERN_VIRT_SIZE)
+#define IOREMAP_END(KERN_IO_END)
 
 /* Advertise special mapping type for AGP */
 #define HAVE_PAGE_AGP
diff --git a/arch/powerpc/include/asm/book3s/64/radix.h 
b/arch/powerpc/include/asm/book3s/64/radix.h
index 7d1a3d1543fc..0718c16b4e8d 100644
--- a/arch/powerpc/include/asm/book3s/64/radix.h
+++ b/arch/powerpc/include/asm/book3s/64/radix.h
@@ -111,6 +111,7 @@
 #define RADIX_VMEMMAP_BASE (RADIX_VMALLOC_END)
 
 #define RADIX_KERN_IO_START(RADIX_KERN_VIRT_START + (RADIX_KERN_VIRT_SIZE 
>> 1))
+#define RADIX_KERN_IO_END   (RADIX_KERN_VIRT_START + RADIX_KERN_VIRT_SIZE)
 
 #ifndef __ASSEMBLY__
 #define RADIX_PTE_TABLE_SIZE   (sizeof(pte_t) << RADIX_PTE_INDEX_SIZE)
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 4aa0797000f7..bbd87748f3f7 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -1010,6 +1010,7 @@ void __init hash__early_init_mmu(void)
__vmalloc_start = H_VMALLOC_START;
__vmalloc_end = H_VMALLOC_END;
__kernel_io_start = H_KERN_IO_START;
+   __kernel_io_end = H_KERN_IO_END;
vmemmap = (struct page *)H_VMEMMAP_BASE;
ioremap_bot = IOREMAP_BASE;
 
diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c
index 931156069a81..c288abfc09e1 100644
--- a/arch/powerpc/mm/pgtable-radix.c
+++ b/arch/powerpc/mm/pgtable-radix.c
@@ -582,6 +582,7 @@ void __init radix__early_init_mmu(void)
__vmalloc_start = RADIX_VMALLOC_START;
__vmalloc_end = RADIX_VMALLOC_END;
__kernel_io_start = RADIX_KERN_IO_START;
+   __kernel_io_end = RADIX_KERN_IO_END;
vmemmap = (struct page *)RADIX_VMEMMAP_BASE;
ioremap_bot = IOREMAP_BASE;
 
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index fb1375c07e8c..7cea39bdf05f 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -98,6 +98,8 @@ unsigned long __vmalloc_end;
 EXPORT_SYMBOL(__vmalloc_end);
 unsigned long __kernel_io_start;
 EXPORT_SYMBOL(__kernel_io_start);
+unsigned long __kernel_io_end;
+EXPORT_SYMBOL(__kernel_io_end);
 struct page *vmemmap;
 EXPORT_SYMBOL(vmemmap);
 unsigned long __pte_frag_nr;
-- 
2.20.1



Re: [PATCH] powerpc/ptrace: Simplify vr_get/set() to avoid GCC warning

2019-02-16 Thread Meelis Roos

Rather than relying on that we can pass an explict end_pos based on
the sizeof(vrsave). The result should be exactly the same but it's
more obviously not over-reading/writing the stack and it avoids the
compiler warning.


It works on my PowerMac G4 with Debian-ports unstable with gcc 8.

--
Meelis Roos


[PATCH] cpufreq: powernv: fix missing check of return value in init_powernv_pstates()

2019-02-16 Thread Yangtao Li
kmalloc() could fail, so insert a check of its return value. And
if it fails, returns -ENOMEM.

And remove (struct pstate_idx_revmap_data *) to fix coccinelle WARNING
by the way.

WARNING: casting value returned by memory allocation function to (struct
pstate_idx_revmap_data *) is useless.

Signed-off-by: Yangtao Li 
---
 drivers/cpufreq/powernv-cpufreq.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/cpufreq/powernv-cpufreq.c 
b/drivers/cpufreq/powernv-cpufreq.c
index 7e7ad3879c4e..d2230812fa4b 100644
--- a/drivers/cpufreq/powernv-cpufreq.c
+++ b/drivers/cpufreq/powernv-cpufreq.c
@@ -244,6 +244,7 @@ static int init_powernv_pstates(void)
u32 len_ids, len_freqs;
u32 pstate_min, pstate_max, pstate_nominal;
u32 pstate_turbo, pstate_ultra_turbo;
+   int rc = -ENODEV;
 
power_mgt = of_find_node_by_path("/ibm,opal/power-mgt");
if (!power_mgt) {
@@ -327,8 +328,11 @@ static int init_powernv_pstates(void)
powernv_freqs[i].frequency = freq * 1000; /* kHz */
powernv_freqs[i].driver_data = id & 0xFF;
 
-   revmap_data = (struct pstate_idx_revmap_data *)
- kmalloc(sizeof(*revmap_data), GFP_KERNEL);
+   revmap_data = kmalloc(sizeof(*revmap_data), GFP_KERNEL);
+   if (!revmap_data) {
+   rc = -ENOMEM;
+   goto out;
+   }
 
revmap_data->pstate_id = id & 0xFF;
revmap_data->cpufreq_table_idx = i;
@@ -357,7 +361,7 @@ static int init_powernv_pstates(void)
return 0;
 out:
of_node_put(power_mgt);
-   return -ENODEV;
+   return rc;
 }
 
 /* Returns the CPU frequency corresponding to the pstate_id. */
-- 
2.17.0



Re: [PATCH] powerpc/64s: Fix possible corruption on big endian due to pgd/pud_present()

2019-02-16 Thread Segher Boessenkool
Hi all,

On Sat, Feb 16, 2019 at 09:55:11PM +1100, Balbir Singh wrote:
> On Thu, Feb 14, 2019 at 05:23:39PM +1100, Michael Ellerman wrote:
> > In v4.20 we changed our pgd/pud_present() to check for _PAGE_PRESENT
> > rather than just checking that the value is non-zero, e.g.:
> > 
> >   static inline int pgd_present(pgd_t pgd)
> >   {
> >  -   return !pgd_none(pgd);
> >  +   return (pgd_raw(pgd) & cpu_to_be64(_PAGE_PRESENT));
> >   }
> > 
> > Unfortunately this is broken on big endian, as the result of the
> > bitwise && is truncated to int, which is always zero because

(Bitwise "&" of course).

> Not sure why that should happen, why is the result an int? What
> causes the casting of pgd_t & be64 to be truncated to an int.

Yes, it's not obvious as written...  It's simply that the return type of
pgd_present is int.  So it is truncated _after_ the bitwise and.


Segher


Re: [PATCH] powerpc/64s: Fix possible corruption on big endian due to pgd/pud_present()

2019-02-16 Thread Andreas Schwab
On Feb 14 2019, Michael Ellerman  wrote:

> The fix is simple, we need to convert the result of the bitwise && to
> an int before returning it.

Alternatively, the return type could be changed to bool, so that the
compiler does the right thing by itself.

Andreas.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."


Re: [PATCH] ASoC: fsl_esai: fix register setting issue in RIGHT_J mode

2019-02-16 Thread Fabio Estevam
Hi Shengjiu,

On Fri, Feb 15, 2019 at 9:04 AM S.j. Wang  wrote:
>
> The ESAI_xCR_xWA is xCR's bit, not the xCCR's bit, driver set it to
> wrong register, correct it.
>
> Signed-off-by: Shengjiu Wang 

Reviewed-by: Fabio Estevam 

Please add a Fixes tag and Cc stable.

Also, it seems that Mark Brown is not on Cc. Please Cc him in v2.

Thanks


Re: [PATCH] powerpc/64s: Fix possible corruption on big endian due to pgd/pud_present()

2019-02-16 Thread Balbir Singh
On Thu, Feb 14, 2019 at 05:23:39PM +1100, Michael Ellerman wrote:
> In v4.20 we changed our pgd/pud_present() to check for _PAGE_PRESENT
> rather than just checking that the value is non-zero, e.g.:
> 
>   static inline int pgd_present(pgd_t pgd)
>   {
>  -   return !pgd_none(pgd);
>  +   return (pgd_raw(pgd) & cpu_to_be64(_PAGE_PRESENT));
>   }
> 
> Unfortunately this is broken on big endian, as the result of the
> bitwise && is truncated to int, which is always zero because

Not sure why that should happen, why is the result an int? What
causes the casting of pgd_t & be64 to be truncated to an int.

> _PAGE_PRESENT is 0x8000ul. This means pgd_present() and
> pud_present() are always false at compile time, and the compiler
> elides the subsequent code.
> 
> Remarkably with that bug present we are still able to boot and run
> with few noticeable effects. However under some work loads we are able
> to trigger a warning in the ext4 code:
> 
>   WARNING: CPU: 11 PID: 29593 at fs/ext4/inode.c:3927 
> .ext4_set_page_dirty+0x70/0xb0
>   CPU: 11 PID: 29593 Comm: debugedit Not tainted 4.20.0-rc1 #1
>   ...
>   NIP .ext4_set_page_dirty+0x70/0xb0
>   LR  .set_page_dirty+0xa0/0x150
>   Call Trace:
>.set_page_dirty+0xa0/0x150
>.unmap_page_range+0xbf0/0xe10
>.unmap_vmas+0x84/0x130
>.unmap_region+0xe8/0x190
>.__do_munmap+0x2f0/0x510
>.__vm_munmap+0x80/0x110
>.__se_sys_munmap+0x14/0x30
>system_call+0x5c/0x70
> 
> The fix is simple, we need to convert the result of the bitwise && to
> an int before returning it.
> 
> Thanks to Jan Kara and Aneesh for help with debugging.
> 
> Fixes: da7ad366b497 ("powerpc/mm/book3s: Update pmd_present to look at 
> _PAGE_PRESENT bit")
> Cc: sta...@vger.kernel.org # v4.20+
> Reported-by: Erhard F. 
> Reviewed-by: Aneesh Kumar K.V 
> Signed-off-by: Michael Ellerman 
> ---
>  arch/powerpc/include/asm/book3s/64/pgtable.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h 
> b/arch/powerpc/include/asm/book3s/64/pgtable.h
> index c9bfe526ca9d..d8c8d7c9df15 100644
> --- a/arch/powerpc/include/asm/book3s/64/pgtable.h
> +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
> @@ -904,7 +904,7 @@ static inline int pud_none(pud_t pud)
>  
>  static inline int pud_present(pud_t pud)
>  {
> - return (pud_raw(pud) & cpu_to_be64(_PAGE_PRESENT));
> + return !!(pud_raw(pud) & cpu_to_be64(_PAGE_PRESENT));
>  }
>  
>  extern struct page *pud_page(pud_t pud);
> @@ -951,7 +951,7 @@ static inline int pgd_none(pgd_t pgd)
>  
>  static inline int pgd_present(pgd_t pgd)
>  {
> - return (pgd_raw(pgd) & cpu_to_be64(_PAGE_PRESENT));
> + return !!(pgd_raw(pgd) & cpu_to_be64(_PAGE_PRESENT));
>  }
>

Care to put a big FAT warning, so that we don't repeat this again
(as in authors planning on changing these bits). 

Balbir Singh.