Re: [PATCH v2 7/9] sparc64: numa: check the node id consistently for sparc64

2019-08-30 Thread David Miller
From: Yunsheng Lin 
Date: Sat, 31 Aug 2019 13:58:21 +0800

> According to Section 6.2.14 from ACPI spec 6.3 [1], the setting
> of proximity domain is optional, as below:

What in the world does the ACPI spec have to do with sparc64 NUMA
node ID checking?


Re: [PATCH v7 4/6] powerpc/64: make buildable without CONFIG_COMPAT

2019-08-30 Thread Christophe Leroy




Le 30/08/2019 à 23:03, Michal Suchanek a écrit :

There are numerous references to 32bit functions in generic and 64bit
code so ifdef them out.

Signed-off-by: Michal Suchanek 


Reviewed-by: Christophe Leroy 


---
v2:
- fix 32bit ifdef condition in signal.c
- simplify the compat ifdef condition in vdso.c - 64bit is redundant
- simplify the compat ifdef condition in callchain.c - 64bit is redundant
v3:
- use IS_ENABLED and maybe_unused where possible
- do not ifdef declarations
- clean up Makefile
v4:
- further makefile cleanup
- simplify is_32bit_task conditions
- avoid ifdef in condition by using return
v5:
- avoid unreachable code on 32bit
- make is_current_64bit constant on !COMPAT
- add stub perf_callchain_user_32 to avoid some ifdefs
v6:
- consolidate current_is_64bit
v7:
- remove leftover perf_callchain_user_32 stub from previous series version
---
  arch/powerpc/include/asm/thread_info.h |  4 ++--
  arch/powerpc/kernel/Makefile   |  7 +++---
  arch/powerpc/kernel/entry_64.S |  2 ++
  arch/powerpc/kernel/signal.c   |  3 +--
  arch/powerpc/kernel/syscall_64.c   |  6 ++---
  arch/powerpc/kernel/vdso.c |  5 ++---
  arch/powerpc/perf/callchain.c  | 31 +-
  7 files changed, 27 insertions(+), 31 deletions(-)

diff --git a/arch/powerpc/include/asm/thread_info.h 
b/arch/powerpc/include/asm/thread_info.h
index 8e1d0195ac36..c128d8a48ea3 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -144,10 +144,10 @@ static inline bool test_thread_local_flags(unsigned int 
flags)
return (ti->local_flags & flags) != 0;
  }
  
-#ifdef CONFIG_PPC64

+#ifdef CONFIG_COMPAT
  #define is_32bit_task()   (test_thread_flag(TIF_32BIT))
  #else
-#define is_32bit_task()(1)
+#define is_32bit_task()(IS_ENABLED(CONFIG_PPC32))
  #endif
  
  #if defined(CONFIG_PPC64)

diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 1d646a94d96c..9d8772e863b9 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -44,16 +44,15 @@ CFLAGS_btext.o += -DDISABLE_BRANCH_PROFILING
  endif
  
  obj-y:= cputable.o ptrace.o syscalls.o \

-  irq.o align.o signal_32.o pmc.o vdso.o \
+  irq.o align.o signal_$(BITS).o pmc.o vdso.o \
   process.o systbl.o idle.o \
   signal.o sysfs.o cacheinfo.o time.o \
   prom.o traps.o setup-common.o \
   udbg.o misc.o io.o misc_$(BITS).o \
   of_platform.o prom_parse.o
-obj-$(CONFIG_PPC64)+= setup_64.o sys_ppc32.o \
-  signal_64.o ptrace32.o \
-  paca.o nvram_64.o firmware.o \
+obj-$(CONFIG_PPC64)+= setup_64.o paca.o nvram_64.o firmware.o \
   syscall_64.o
+obj-$(CONFIG_COMPAT)   += sys_ppc32.o ptrace32.o signal_32.o
  obj-$(CONFIG_VDSO32)  += vdso32/
  obj-$(CONFIG_PPC_WATCHDOG)+= watchdog.o
  obj-$(CONFIG_HAVE_HW_BREAKPOINT)  += hw_breakpoint.o
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 2ec825a85f5b..a2dbf216f607 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -51,8 +51,10 @@
  SYS_CALL_TABLE:
.tc sys_call_table[TC],sys_call_table
  
+#ifdef CONFIG_COMPAT

  COMPAT_SYS_CALL_TABLE:
.tc compat_sys_call_table[TC],compat_sys_call_table
+#endif
  
  /* This value is used to mark exception frames on the stack. */

  exception_marker:
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index 60436432399f..61678cb0e6a1 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -247,7 +247,6 @@ static void do_signal(struct task_struct *tsk)
sigset_t *oldset = sigmask_to_save();
struct ksignal ksig = { .sig = 0 };
int ret;
-   int is32 = is_32bit_task();
  
  	BUG_ON(tsk != current);
  
@@ -277,7 +276,7 @@ static void do_signal(struct task_struct *tsk)
  
  	rseq_signal_deliver(&ksig, tsk->thread.regs);
  
-	if (is32) {

+   if (is_32bit_task()) {
if (ksig.ka.sa.sa_flags & SA_SIGINFO)
ret = handle_rt_signal32(&ksig, oldset, tsk);
else
diff --git a/arch/powerpc/kernel/syscall_64.c b/arch/powerpc/kernel/syscall_64.c
index 98ed970796d5..0d5cbbe54cf1 100644
--- a/arch/powerpc/kernel/syscall_64.c
+++ b/arch/powerpc/kernel/syscall_64.c
@@ -38,7 +38,6 @@ typedef long (*syscall_fn)(long, long, long, long, long, 
long);
  
  long system_call_exception(long r3, long r4, long r5, long r6, long r7, long r8, unsigned long r0, struct pt_regs *regs)

  {
-   unsigned long ti_flags;
syscall_fn f;
  
  	BUG_ON(!(regs->msr & MSR_PR));

@@ -83,8 +82,7 @@ long

Re: [PATCH v7 0/6] Disable compat cruft on ppc64le v7

2019-08-30 Thread Christophe Leroy




Le 30/08/2019 à 23:03, Michal Suchanek a écrit :

Less code means less bugs so add a knob to skip the compat stuff.


I guess on PPC64 you have Gigabytes of memory and thousands of bogomips, 
hence you focus on bugs.


My main focus usually is kernel size and performance, which makes this 
series interesting as well.


Anyway, I was wondering, would it make sense (in a following series, not 
in this one) to make it buildable as a module, just like some of binfmt ?


Christophe



This is tested on ppc64le top of

https://patchwork.ozlabs.org/cover/1153556/

Changes in v2: saner CONFIG_COMPAT ifdefs
Changes in v3:
  - change llseek to 32bit instead of builing it unconditionally in fs
  - clanup the makefile conditionals
  - remove some ifdefs or convert to IS_DEFINED where possible
Changes in v4:
  - cleanup is_32bit_task and current_is_64bit
  - more makefile cleanup
Changes in v5:
  - more current_is_64bit cleanup
  - split off callchain.c 32bit and 64bit parts
Changes in v6:
  - cleanup makefile after split
  - consolidate read_user_stack_32
  - fix some checkpatch warnings
Changes in v7:
  - add back __ARCH_WANT_SYS_LLSEEK to fix build with llseek
  - remove leftover hunk
  - add review tags

Michal Suchanek (6):
   powerpc: Add back __ARCH_WANT_SYS_LLSEEK macro
   powerpc: move common register copy functions from signal_32.c to
 signal.c
   powerpc/perf: consolidate read_user_stack_32
   powerpc/64: make buildable without CONFIG_COMPAT
   powerpc/64: Make COMPAT user-selectable disabled on littleendian by
 default.
   powerpc/perf: split callchain.c by bitness

  arch/powerpc/Kconfig   |   5 +-
  arch/powerpc/include/asm/thread_info.h |   4 +-
  arch/powerpc/include/asm/unistd.h  |   1 +
  arch/powerpc/kernel/Makefile   |   7 +-
  arch/powerpc/kernel/entry_64.S |   2 +
  arch/powerpc/kernel/signal.c   | 144 +-
  arch/powerpc/kernel/signal_32.c| 140 -
  arch/powerpc/kernel/syscall_64.c   |   6 +-
  arch/powerpc/kernel/vdso.c |   5 +-
  arch/powerpc/perf/Makefile |   5 +-
  arch/powerpc/perf/callchain.c  | 377 +
  arch/powerpc/perf/callchain.h  |  11 +
  arch/powerpc/perf/callchain_32.c   | 204 +
  arch/powerpc/perf/callchain_64.c   | 185 
  fs/read_write.c|   3 +-
  15 files changed, 566 insertions(+), 533 deletions(-)
  create mode 100644 arch/powerpc/perf/callchain.h
  create mode 100644 arch/powerpc/perf/callchain_32.c
  create mode 100644 arch/powerpc/perf/callchain_64.c



Re: Oops (request_key_auth_describe) while running cve-2016-7042 from LTP

2019-08-30 Thread Sachin Sant



> On 30-Aug-2019, at 8:43 PM, David Howells  wrote:
> 
> Can you try this patch instead of Hillf’s?

Works for me. Test ran fine without any problem.

Tested-by: Sachin Sant 

Thanks
-Sachin



lockdep warning while booting POWER9 PowerNV

2019-08-30 Thread Qian Cai
https://raw.githubusercontent.com/cailca/linux-mm/master/powerpc.config

Once in a while, booting an IBM POWER9 PowerNV system (8335-GTH) would generate
a warning in lockdep_register_key() at,

if (WARN_ON_ONCE(static_obj(key)))

because

key = 0xc19ad118
&_stext = 0xc000
&_end = 0xc49d

i.e., it will cause static_obj() returns 1.


[   23.738200][   T13] ahci 0004:03:00.0: enabling device (0541 -> 0543)
[   23.748692][T5] tg3.c:v3.137 (May 11, 2014)
[   23.748731][T5] tg3 0005:01:00.0: enabling device (0140 -> 0142)
[   23.751478][   T13] ahci 0004:03:00.0: AHCI 0001. 32 slots 4 ports 6 Gbps
0xf impl SATA mode
[   23.751517][   T13] ahci 0004:03:00.0: flags: 64bit ncq sntf led only pmp fbs
pio slum part sxs 
[   23.791077][   T13] scsi host0: ahci
[   23.802752][   T13] [ cut here ]
[   23.802786][   T13] WARNING: CPU: 0 PID: 13 at kernel/locking/lockdep.c:1120
lockdep_register_key+0x68/0x200
[   23.802814][   T13] Modules linked in: mdio tg3(+) ahci(+) libahci libphy
firmware_class libata dm_mirror dm_region_hash dm_log dm_mod
[   23.802884][   T13] CPU: 0 PID: 13 Comm: kworker/0:1 Not tainted 5.3.0-rc6-
next-20190830 #4
[   23.802930][   T13] Workqueue: events work_for_cpu_fn
[   23.802962][   T13] NIP:  c019eed8 LR: c0129400 CTR:
c08a46dc
[   23.802988][   T13] REGS: c0002db2f130 TRAP: 0700   Not tainted  (5.3.0-
rc6-next-20190830)
[   23.803032][   T13] MSR:  9282b033
  CR: 48800a89  XER: 2004
[   23.803096][   T13] CFAR: c019eeac IRQMASK: 0 
[   23.803096][   T13] GPR00: c0129400 c0002db2f3c0 c2bb9400
c49d 
[   23.803096][   T13] GPR04:  c2d84718 
0a01ff10 
[   23.803096][   T13] GPR08: c0b8a16b c0a515cc c0b8a16a
0044 
[   23.803096][   T13] GPR12: 88800a89 c49d c0080eea3290
0001 
[   23.803096][   T13] GPR16: c01bca584500 c7244954 c01bca584508
0020 
[   23.803096][   T13] GPR20: c1aea180 0001 c0080eee7560
c01bca584500 
[   23.803096][   T13] GPR24: c01bca584448 0002000a c1aea148
c0b8a161 
[   23.803096][   T13] GPR28: c1aea020 c1aea118 c1aea000
c0002db2f440 
[   23.803407][   T13] NIP [c019eed8] lockdep_register_key+0x68/0x200
[   23.803432][   T13] LR [c0129400] wq_init_lockdep+0x40/0xc0
[   23.803461][   T13] Call Trace:
[   23.803491][   T13] [c0002db2f3c0] [c0b8a16a]
trunc_msg+0x385f9/0x4c30f (unreliable)
[   23.803531][   T13] [c0002db2f440] [c0129400]
wq_init_lockdep+0x40/0xc0
[   23.803577][   T13] [c0002db2f4c0] [c0128d90]
alloc_workqueue+0x1e0/0x620
[   23.803623][   T13] [c0002db2f5c0] [c06ca048]
scsi_host_alloc+0x3d8/0x490
[   23.803701][   T13] [c0002db2f660] [c0080ee73198]
ata_scsi_add_hosts+0xd0/0x220 [libata]
[   23.803771][   T13] [c0002db2f6f0] [c0080ee6d440]
ata_host_register+0x178/0x400 [libata]
[   23.803840][   T13] [c0002db2f7d0] [c0080ee6d8f4]
ata_host_activate+0x17c/0x210 [libata]
[   23.803883][   T13] [c0002db2f880] [c0080edf4c3c]
ahci_host_activate+0x84/0x250 [libahci]
[   23.803944][   T13] [c0002db2f940] [c0080f050c7c]
ahci_init_one+0xc74/0xdc0 [ahci]
[   23.803992][   T13] [c0002db2faa0] [c062b188]
local_pci_probe+0x78/0x100
[   23.804048][   T13] [c0002db2fb30] [c012c0b0]
work_for_cpu_fn+0x40/0x70
[   23.804087][   T13] [c0002db2fb60] [c0130328]
process_one_work+0x388/0x750
[   23.804135][   T13] [c0002db2fc60] [c012fe30]
process_scheduled_works+0x50/0x90
[   23.804180][   T13] [c0002db2fca0] [c0130c50]
worker_thread+0x3d0/0x570
[   23.804216][   T13] [c0002db2fda0] [c0139a08] kthread+0x1b8/0x1e0
[   23.804253][   T13] [c0002db2fe20] [c000b660]
ret_from_kernel_thread+0x5c/0x7c
[   23.804298][   T13] Instruction dump:
[   23.804326][   T13] fbc10070 4194002c 7fa3eb78 481864a5 6000 70630001
41810018 7fa3eb78 
[   23.804373][   T13] 48075121 6000 70630001 40810020 <0fe0> ebc10070
eba10068 38210080 
[   23.804419][   T13] ---[ end trace 9ceca43eedad2a2b ]---
[   23.810924][T5] tg3 0005:01:00.0 eth0: Tigon3 [partno(BCM95719) rev
5719001] (PCI Express) MAC address 08:94:ef:80:81:c0
[   23.810967][T5] tg3 0005:01:00.0 eth0: attached PHY is 5719C
(10/100/1000Base-T Ethernet) (WireSpeed[1], EEE[1])
[   23.811027][T5] tg3 0005:01:00.0 eth0: RXcsums[1] LinkChgREG[0] MIirq[0]
ASF[1] TSOcap[1]
[   23.811074][T5] tg3 0005:01:00.0 eth0: dma_rwctrl[] dma_mask[64-
bit]
[   23.811284][   T13] scsi host1: ahci


[PATCH v7 6/6] powerpc/perf: split callchain.c by bitness

2019-08-30 Thread Michal Suchanek
Building callchain.c with !COMPAT proved quite ugly with all the
defines. Splitting out the 32bit and 64bit parts looks better.

No code change intended.

Signed-off-by: Michal Suchanek 
Reviewed-by: Christophe Leroy 
---
v6:
 - move current_is_64bit consolidetaion to earlier patch
 - move defines to the top of callchain_32.c
 - Makefile cleanup
---
 arch/powerpc/perf/Makefile   |   5 +-
 arch/powerpc/perf/callchain.c| 365 +--
 arch/powerpc/perf/callchain.h|  11 +
 arch/powerpc/perf/callchain_32.c | 204 +
 arch/powerpc/perf/callchain_64.c | 185 
 5 files changed, 405 insertions(+), 365 deletions(-)
 create mode 100644 arch/powerpc/perf/callchain.h
 create mode 100644 arch/powerpc/perf/callchain_32.c
 create mode 100644 arch/powerpc/perf/callchain_64.c

diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
index c155dcbb8691..53d614e98537 100644
--- a/arch/powerpc/perf/Makefile
+++ b/arch/powerpc/perf/Makefile
@@ -1,6 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0
 
-obj-$(CONFIG_PERF_EVENTS)  += callchain.o perf_regs.o
+obj-$(CONFIG_PERF_EVENTS)  += callchain.o callchain_$(BITS).o perf_regs.o
+ifdef CONFIG_COMPAT
+obj-$(CONFIG_PERF_EVENTS)  += callchain_32.o
+endif
 
 obj-$(CONFIG_PPC_PERF_CTRS)+= core-book3s.o bhrb.o
 obj64-$(CONFIG_PPC_PERF_CTRS)  += ppc970-pmu.o power5-pmu.o \
diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
index 9b8dc822f531..8f30f1b47c78 100644
--- a/arch/powerpc/perf/callchain.c
+++ b/arch/powerpc/perf/callchain.c
@@ -15,11 +15,9 @@
 #include 
 #include 
 #include 
-#ifdef CONFIG_COMPAT
-#include "../kernel/ppc32.h"
-#endif
 #include 
 
+#include "callchain.h"
 
 /*
  * Is sp valid as the address of the next kernel stack frame after prev_sp?
@@ -102,367 +100,6 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx 
*entry, struct pt_regs *re
}
 }
 
-#ifdef CONFIG_PPC64
-/*
- * On 64-bit we don't want to invoke hash_page on user addresses from
- * interrupt context, so if the access faults, we read the page tables
- * to find which page (if any) is mapped and access it directly.
- */
-static int read_user_stack_slow(void __user *ptr, void *buf, int nb)
-{
-   int ret = -EFAULT;
-   pgd_t *pgdir;
-   pte_t *ptep, pte;
-   unsigned shift;
-   unsigned long addr = (unsigned long) ptr;
-   unsigned long offset;
-   unsigned long pfn, flags;
-   void *kaddr;
-
-   pgdir = current->mm->pgd;
-   if (!pgdir)
-   return -EFAULT;
-
-   local_irq_save(flags);
-   ptep = find_current_mm_pte(pgdir, addr, NULL, &shift);
-   if (!ptep)
-   goto err_out;
-   if (!shift)
-   shift = PAGE_SHIFT;
-
-   /* align address to page boundary */
-   offset = addr & ((1UL << shift) - 1);
-
-   pte = READ_ONCE(*ptep);
-   if (!pte_present(pte) || !pte_user(pte))
-   goto err_out;
-   pfn = pte_pfn(pte);
-   if (!page_is_ram(pfn))
-   goto err_out;
-
-   /* no highmem to worry about here */
-   kaddr = pfn_to_kaddr(pfn);
-   memcpy(buf, kaddr + offset, nb);
-   ret = 0;
-err_out:
-   local_irq_restore(flags);
-   return ret;
-}
-
-static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret)
-{
-   if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned long) ||
-   ((unsigned long)ptr & 7))
-   return -EFAULT;
-
-   pagefault_disable();
-   if (!__get_user_inatomic(*ret, ptr)) {
-   pagefault_enable();
-   return 0;
-   }
-   pagefault_enable();
-
-   return read_user_stack_slow(ptr, ret, 8);
-}
-
-static inline int valid_user_sp(unsigned long sp, int is_64)
-{
-   if (!sp || (sp & 7) || sp > (is_64 ? TASK_SIZE : 0x1UL) - 32)
-   return 0;
-   return 1;
-}
-
-/*
- * 64-bit user processes use the same stack frame for RT and non-RT signals.
- */
-struct signal_frame_64 {
-   chardummy[__SIGNAL_FRAMESIZE];
-   struct ucontext uc;
-   unsigned long   unused[2];
-   unsigned inttramp[6];
-   struct siginfo  *pinfo;
-   void*puc;
-   struct siginfo  info;
-   charabigap[288];
-};
-
-static int is_sigreturn_64_address(unsigned long nip, unsigned long fp)
-{
-   if (nip == fp + offsetof(struct signal_frame_64, tramp))
-   return 1;
-   if (vdso64_rt_sigtramp && current->mm->context.vdso_base &&
-   nip == current->mm->context.vdso_base + vdso64_rt_sigtramp)
-   return 1;
-   return 0;
-}
-
-/*
- * Do some sanity checking on the signal frame pointed to by sp.
- * We check the pinfo and puc pointers in the frame.
- */
-static int sane_signal_64_frame(unsigned long sp)
-{
-   struct signal_frame_64 __user *sf;
-   unsigned long pinfo, puc;
-
-   sf = (struct signal_frame_64 __user *) sp;
-   

[PATCH v7 5/6] powerpc/64: Make COMPAT user-selectable disabled on littleendian by default.

2019-08-30 Thread Michal Suchanek
On bigendian ppc64 it is common to have 32bit legacy binaries but much
less so on littleendian.

Signed-off-by: Michal Suchanek 
Reviewed-by: Christophe Leroy 
---
v3: make configurable
---
 arch/powerpc/Kconfig | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 5bab0bb6b833..b0339e892329 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -264,8 +264,9 @@ config PANIC_TIMEOUT
default 180
 
 config COMPAT
-   bool
-   default y if PPC64
+   bool "Enable support for 32bit binaries"
+   depends on PPC64
+   default y if !CPU_LITTLE_ENDIAN
select COMPAT_BINFMT_ELF
select ARCH_WANT_OLD_COMPAT_IPC
select COMPAT_OLD_SIGACTION
-- 
2.22.0



[PATCH v7 4/6] powerpc/64: make buildable without CONFIG_COMPAT

2019-08-30 Thread Michal Suchanek
There are numerous references to 32bit functions in generic and 64bit
code so ifdef them out.

Signed-off-by: Michal Suchanek 
---
v2:
- fix 32bit ifdef condition in signal.c
- simplify the compat ifdef condition in vdso.c - 64bit is redundant
- simplify the compat ifdef condition in callchain.c - 64bit is redundant
v3:
- use IS_ENABLED and maybe_unused where possible
- do not ifdef declarations
- clean up Makefile
v4:
- further makefile cleanup
- simplify is_32bit_task conditions
- avoid ifdef in condition by using return
v5:
- avoid unreachable code on 32bit
- make is_current_64bit constant on !COMPAT
- add stub perf_callchain_user_32 to avoid some ifdefs
v6:
- consolidate current_is_64bit
v7:
- remove leftover perf_callchain_user_32 stub from previous series version
---
 arch/powerpc/include/asm/thread_info.h |  4 ++--
 arch/powerpc/kernel/Makefile   |  7 +++---
 arch/powerpc/kernel/entry_64.S |  2 ++
 arch/powerpc/kernel/signal.c   |  3 +--
 arch/powerpc/kernel/syscall_64.c   |  6 ++---
 arch/powerpc/kernel/vdso.c |  5 ++---
 arch/powerpc/perf/callchain.c  | 31 +-
 7 files changed, 27 insertions(+), 31 deletions(-)

diff --git a/arch/powerpc/include/asm/thread_info.h 
b/arch/powerpc/include/asm/thread_info.h
index 8e1d0195ac36..c128d8a48ea3 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -144,10 +144,10 @@ static inline bool test_thread_local_flags(unsigned int 
flags)
return (ti->local_flags & flags) != 0;
 }
 
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_COMPAT
 #define is_32bit_task()(test_thread_flag(TIF_32BIT))
 #else
-#define is_32bit_task()(1)
+#define is_32bit_task()(IS_ENABLED(CONFIG_PPC32))
 #endif
 
 #if defined(CONFIG_PPC64)
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 1d646a94d96c..9d8772e863b9 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -44,16 +44,15 @@ CFLAGS_btext.o += -DDISABLE_BRANCH_PROFILING
 endif
 
 obj-y  := cputable.o ptrace.o syscalls.o \
-  irq.o align.o signal_32.o pmc.o vdso.o \
+  irq.o align.o signal_$(BITS).o pmc.o vdso.o \
   process.o systbl.o idle.o \
   signal.o sysfs.o cacheinfo.o time.o \
   prom.o traps.o setup-common.o \
   udbg.o misc.o io.o misc_$(BITS).o \
   of_platform.o prom_parse.o
-obj-$(CONFIG_PPC64)+= setup_64.o sys_ppc32.o \
-  signal_64.o ptrace32.o \
-  paca.o nvram_64.o firmware.o \
+obj-$(CONFIG_PPC64)+= setup_64.o paca.o nvram_64.o firmware.o \
   syscall_64.o
+obj-$(CONFIG_COMPAT)   += sys_ppc32.o ptrace32.o signal_32.o
 obj-$(CONFIG_VDSO32)   += vdso32/
 obj-$(CONFIG_PPC_WATCHDOG) += watchdog.o
 obj-$(CONFIG_HAVE_HW_BREAKPOINT)   += hw_breakpoint.o
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 2ec825a85f5b..a2dbf216f607 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -51,8 +51,10 @@
 SYS_CALL_TABLE:
.tc sys_call_table[TC],sys_call_table
 
+#ifdef CONFIG_COMPAT
 COMPAT_SYS_CALL_TABLE:
.tc compat_sys_call_table[TC],compat_sys_call_table
+#endif
 
 /* This value is used to mark exception frames on the stack. */
 exception_marker:
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index 60436432399f..61678cb0e6a1 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -247,7 +247,6 @@ static void do_signal(struct task_struct *tsk)
sigset_t *oldset = sigmask_to_save();
struct ksignal ksig = { .sig = 0 };
int ret;
-   int is32 = is_32bit_task();
 
BUG_ON(tsk != current);
 
@@ -277,7 +276,7 @@ static void do_signal(struct task_struct *tsk)
 
rseq_signal_deliver(&ksig, tsk->thread.regs);
 
-   if (is32) {
+   if (is_32bit_task()) {
if (ksig.ka.sa.sa_flags & SA_SIGINFO)
ret = handle_rt_signal32(&ksig, oldset, tsk);
else
diff --git a/arch/powerpc/kernel/syscall_64.c b/arch/powerpc/kernel/syscall_64.c
index 98ed970796d5..0d5cbbe54cf1 100644
--- a/arch/powerpc/kernel/syscall_64.c
+++ b/arch/powerpc/kernel/syscall_64.c
@@ -38,7 +38,6 @@ typedef long (*syscall_fn)(long, long, long, long, long, 
long);
 
 long system_call_exception(long r3, long r4, long r5, long r6, long r7, long 
r8, unsigned long r0, struct pt_regs *regs)
 {
-   unsigned long ti_flags;
syscall_fn f;
 
BUG_ON(!(regs->msr & MSR_PR));
@@ -83,8 +82,7 @@ long system_call_exception(long r3, long r4, long r5, long 
r6, long r7, long r8,
  

[PATCH v7 3/6] powerpc/perf: consolidate read_user_stack_32

2019-08-30 Thread Michal Suchanek
There are two almost identical copies for 32bit and 64bit.

The function is used only in 32bit code which will be split out in next
patch so consolidate to one function.

Signed-off-by: Michal Suchanek 
Reviewed-by: Christophe Leroy 
---
new patch in v6
---
 arch/powerpc/perf/callchain.c | 25 +
 1 file changed, 9 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
index c84bbd4298a0..b7cdcce20280 100644
--- a/arch/powerpc/perf/callchain.c
+++ b/arch/powerpc/perf/callchain.c
@@ -165,22 +165,6 @@ static int read_user_stack_64(unsigned long __user *ptr, 
unsigned long *ret)
return read_user_stack_slow(ptr, ret, 8);
 }
 
-static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
-{
-   if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
-   ((unsigned long)ptr & 3))
-   return -EFAULT;
-
-   pagefault_disable();
-   if (!__get_user_inatomic(*ret, ptr)) {
-   pagefault_enable();
-   return 0;
-   }
-   pagefault_enable();
-
-   return read_user_stack_slow(ptr, ret, 4);
-}
-
 static inline int valid_user_sp(unsigned long sp, int is_64)
 {
if (!sp || (sp & 7) || sp > (is_64 ? TASK_SIZE : 0x1UL) - 32)
@@ -295,6 +279,12 @@ static inline int current_is_64bit(void)
 }
 
 #else  /* CONFIG_PPC64 */
+static int read_user_stack_slow(void __user *ptr, void *buf, int nb)
+{
+   return 0;
+}
+#endif /* CONFIG_PPC64 */
+
 /*
  * On 32-bit we just access the address and let hash_page create a
  * HPTE if necessary, so there is no need to fall back to reading
@@ -313,9 +303,12 @@ static int read_user_stack_32(unsigned int __user *ptr, 
unsigned int *ret)
rc = __get_user_inatomic(*ret, ptr);
pagefault_enable();
 
+   if (IS_ENABLED(CONFIG_PPC64) && rc)
+   return read_user_stack_slow(ptr, ret, 4);
return rc;
 }
 
+#ifndef CONFIG_PPC64
 static inline void perf_callchain_user_64(struct perf_callchain_entry_ctx 
*entry,
  struct pt_regs *regs)
 {
-- 
2.22.0



[PATCH v7 2/6] powerpc: move common register copy functions from signal_32.c to signal.c

2019-08-30 Thread Michal Suchanek
These functions are required for 64bit as well.

Signed-off-by: Michal Suchanek 
Reviewed-by: Christophe Leroy 
---
 arch/powerpc/kernel/signal.c| 141 
 arch/powerpc/kernel/signal_32.c | 140 ---
 2 files changed, 141 insertions(+), 140 deletions(-)

diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index e6c30cee6abf..60436432399f 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -18,12 +18,153 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 
 #include "signal.h"
 
+#ifdef CONFIG_VSX
+unsigned long copy_fpr_to_user(void __user *to,
+  struct task_struct *task)
+{
+   u64 buf[ELF_NFPREG];
+   int i;
+
+   /* save FPR copy to local buffer then write to the thread_struct */
+   for (i = 0; i < (ELF_NFPREG - 1) ; i++)
+   buf[i] = task->thread.TS_FPR(i);
+   buf[i] = task->thread.fp_state.fpscr;
+   return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
+}
+
+unsigned long copy_fpr_from_user(struct task_struct *task,
+void __user *from)
+{
+   u64 buf[ELF_NFPREG];
+   int i;
+
+   if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
+   return 1;
+   for (i = 0; i < (ELF_NFPREG - 1) ; i++)
+   task->thread.TS_FPR(i) = buf[i];
+   task->thread.fp_state.fpscr = buf[i];
+
+   return 0;
+}
+
+unsigned long copy_vsx_to_user(void __user *to,
+  struct task_struct *task)
+{
+   u64 buf[ELF_NVSRHALFREG];
+   int i;
+
+   /* save FPR copy to local buffer then write to the thread_struct */
+   for (i = 0; i < ELF_NVSRHALFREG; i++)
+   buf[i] = task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET];
+   return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
+}
+
+unsigned long copy_vsx_from_user(struct task_struct *task,
+void __user *from)
+{
+   u64 buf[ELF_NVSRHALFREG];
+   int i;
+
+   if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
+   return 1;
+   for (i = 0; i < ELF_NVSRHALFREG ; i++)
+   task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
+   return 0;
+}
+
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+unsigned long copy_ckfpr_to_user(void __user *to,
+ struct task_struct *task)
+{
+   u64 buf[ELF_NFPREG];
+   int i;
+
+   /* save FPR copy to local buffer then write to the thread_struct */
+   for (i = 0; i < (ELF_NFPREG - 1) ; i++)
+   buf[i] = task->thread.TS_CKFPR(i);
+   buf[i] = task->thread.ckfp_state.fpscr;
+   return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
+}
+
+unsigned long copy_ckfpr_from_user(struct task_struct *task,
+ void __user *from)
+{
+   u64 buf[ELF_NFPREG];
+   int i;
+
+   if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
+   return 1;
+   for (i = 0; i < (ELF_NFPREG - 1) ; i++)
+   task->thread.TS_CKFPR(i) = buf[i];
+   task->thread.ckfp_state.fpscr = buf[i];
+
+   return 0;
+}
+
+unsigned long copy_ckvsx_to_user(void __user *to,
+ struct task_struct *task)
+{
+   u64 buf[ELF_NVSRHALFREG];
+   int i;
+
+   /* save FPR copy to local buffer then write to the thread_struct */
+   for (i = 0; i < ELF_NVSRHALFREG; i++)
+   buf[i] = task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET];
+   return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
+}
+
+unsigned long copy_ckvsx_from_user(struct task_struct *task,
+ void __user *from)
+{
+   u64 buf[ELF_NVSRHALFREG];
+   int i;
+
+   if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
+   return 1;
+   for (i = 0; i < ELF_NVSRHALFREG ; i++)
+   task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
+   return 0;
+}
+#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
+#else
+inline unsigned long copy_fpr_to_user(void __user *to,
+ struct task_struct *task)
+{
+   return __copy_to_user(to, task->thread.fp_state.fpr,
+ ELF_NFPREG * sizeof(double));
+}
+
+inline unsigned long copy_fpr_from_user(struct task_struct *task,
+   void __user *from)
+{
+   return __copy_from_user(task->thread.fp_state.fpr, from,
+ ELF_NFPREG * sizeof(double));
+}
+
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+inline unsigned long copy_ckfpr_to_user(void __user *to,
+struct task_struct *task)
+{
+   return __copy_to_user(to, task->thread.ckfp_state.fpr,
+ ELF_NFPREG * sizeof(double));
+}
+

[PATCH v7 1/6] powerpc: Add back __ARCH_WANT_SYS_LLSEEK macro

2019-08-30 Thread Michal Suchanek
This partially reverts commit caf6f9c8a326 ("asm-generic: Remove
unneeded __ARCH_WANT_SYS_LLSEEK macro")

When CONFIG_COMPAT is disabled on ppc64 the kernel does not build.

There is resistance to both removing the llseek syscall from the 64bit
syscall tables and building the llseek interface unconditionally.

Link: https://lore.kernel.org/lkml/20190828151552.ga16...@infradead.org/
Link: https://lore.kernel.org/lkml/20190829214319.498c7de2@naga/

Signed-off-by: Michal Suchanek 
Reviewed-by: Arnd Bergmann 
---
 arch/powerpc/include/asm/unistd.h | 1 +
 fs/read_write.c   | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/unistd.h 
b/arch/powerpc/include/asm/unistd.h
index b0720c7c3fcf..700fcdac2e3c 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -31,6 +31,7 @@
 #define __ARCH_WANT_SYS_SOCKETCALL
 #define __ARCH_WANT_SYS_FADVISE64
 #define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT
 #define __ARCH_WANT_SYS_OLD_UNAME
diff --git a/fs/read_write.c b/fs/read_write.c
index 5bbf587f5bc1..89aa2701dbeb 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -331,7 +331,8 @@ COMPAT_SYSCALL_DEFINE3(lseek, unsigned int, fd, 
compat_off_t, offset, unsigned i
 }
 #endif
 
-#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
+#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT) || \
+   defined(__ARCH_WANT_SYS_LLSEEK)
 SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
unsigned long, offset_low, loff_t __user *, result,
unsigned int, whence)
-- 
2.22.0



[PATCH v7 0/6] Disable compat cruft on ppc64le v7

2019-08-30 Thread Michal Suchanek
Less code means less bugs so add a knob to skip the compat stuff.

This is tested on ppc64le top of

https://patchwork.ozlabs.org/cover/1153556/

Changes in v2: saner CONFIG_COMPAT ifdefs
Changes in v3:
 - change llseek to 32bit instead of builing it unconditionally in fs
 - clanup the makefile conditionals
 - remove some ifdefs or convert to IS_DEFINED where possible
Changes in v4:
 - cleanup is_32bit_task and current_is_64bit
 - more makefile cleanup
Changes in v5:
 - more current_is_64bit cleanup
 - split off callchain.c 32bit and 64bit parts
Changes in v6:
 - cleanup makefile after split
 - consolidate read_user_stack_32
 - fix some checkpatch warnings
Changes in v7:
 - add back __ARCH_WANT_SYS_LLSEEK to fix build with llseek
 - remove leftover hunk
 - add review tags

Michal Suchanek (6):
  powerpc: Add back __ARCH_WANT_SYS_LLSEEK macro
  powerpc: move common register copy functions from signal_32.c to
signal.c
  powerpc/perf: consolidate read_user_stack_32
  powerpc/64: make buildable without CONFIG_COMPAT
  powerpc/64: Make COMPAT user-selectable disabled on littleendian by
default.
  powerpc/perf: split callchain.c by bitness

 arch/powerpc/Kconfig   |   5 +-
 arch/powerpc/include/asm/thread_info.h |   4 +-
 arch/powerpc/include/asm/unistd.h  |   1 +
 arch/powerpc/kernel/Makefile   |   7 +-
 arch/powerpc/kernel/entry_64.S |   2 +
 arch/powerpc/kernel/signal.c   | 144 +-
 arch/powerpc/kernel/signal_32.c| 140 -
 arch/powerpc/kernel/syscall_64.c   |   6 +-
 arch/powerpc/kernel/vdso.c |   5 +-
 arch/powerpc/perf/Makefile |   5 +-
 arch/powerpc/perf/callchain.c  | 377 +
 arch/powerpc/perf/callchain.h  |  11 +
 arch/powerpc/perf/callchain_32.c   | 204 +
 arch/powerpc/perf/callchain_64.c   | 185 
 fs/read_write.c|   3 +-
 15 files changed, 566 insertions(+), 533 deletions(-)
 create mode 100644 arch/powerpc/perf/callchain.h
 create mode 100644 arch/powerpc/perf/callchain_32.c
 create mode 100644 arch/powerpc/perf/callchain_64.c

-- 
2.22.0



Re: [PATCH 1/2] ftrace: Fix NULL pointer dereference in t_probe_next()

2019-08-30 Thread Steven Rostedt
On Thu,  4 Jul 2019 20:04:41 +0530
"Naveen N. Rao"  wrote:


>  kernel/trace/ftrace.c | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
> index 7b037295a1f1..0791eafb693d 100644
> --- a/kernel/trace/ftrace.c
> +++ b/kernel/trace/ftrace.c
> @@ -3093,6 +3093,10 @@ t_probe_next(struct seq_file *m, loff_t *pos)
>   hnd = &iter->probe_entry->hlist;
>  
>   hash = iter->probe->ops.func_hash->filter_hash;
> +
> + if (!hash)
> + return NULL;
> +
>   size = 1 << hash->size_bits;
>  
>   retry:

OK, I added this, but I'm also adding this on top:

-- Steve

From 372e0d01da71c84dcecf7028598a33813b0d5256 Mon Sep 17 00:00:00 2001
From: "Steven Rostedt (VMware)" 
Date: Fri, 30 Aug 2019 16:30:01 -0400
Subject: [PATCH] ftrace: Check for empty hash and comment the race with
 registering probes

The race between adding a function probe and reading the probes that exist
is very subtle. It needs a comment. Also, the issue can also happen if the
probe has has the EMPTY_HASH as its func_hash.

Cc: sta...@vger.kernel.org
Fixes: 7b60f3d876156 ("ftrace: Dynamically create the probe ftrace_ops for the 
trace_array")
Signed-off-by: Steven Rostedt (VMware) 
---
 kernel/trace/ftrace.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 80beed2cf0da..6200a6fe10e3 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -3096,7 +3096,11 @@ t_probe_next(struct seq_file *m, loff_t *pos)
 
hash = iter->probe->ops.func_hash->filter_hash;
 
-   if (!hash)
+   /*
+* A probe being registered may temporarily have an empty hash
+* and it's at the end of the func_probes list.
+*/
+   if (!hash || hash == EMPTY_HASH)
return NULL;
 
size = 1 << hash->size_bits;
@@ -4324,6 +4328,10 @@ register_ftrace_function_probe(char *glob, struct 
trace_array *tr,
 
mutex_unlock(&ftrace_lock);
 
+   /*
+* Note, there's a small window here that the func_hash->filter_hash
+* may be NULL or empty. Need to be carefule when reading the loop.
+*/
mutex_lock(&probe->ops.func_hash->regex_lock);
 
orig_hash = &probe->ops.func_hash->filter_hash;
-- 
2.20.1



Re: [PATCH] Revert "asm-generic: Remove unneeded __ARCH_WANT_SYS_LLSEEK macro"

2019-08-30 Thread Arnd Bergmann
On Fri, Aug 30, 2019 at 10:13 PM Michal Suchánek  wrote:
> On Fri, 30 Aug 2019 21:54:43 +0200
> Arnd Bergmann  wrote:
> > > index 5bbf587f5bc1..2f3c4bb138c4 100644
> > > --- a/fs/read_write.c
> > > +++ b/fs/read_write.c
> > > @@ -331,7 +331,7 @@ COMPAT_SYSCALL_DEFINE3(lseek, unsigned int, fd, 
> > > compat_off_t, offset, unsigned i
> > >  }
> > >  #endif
> > >
> > > -#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
> > > +#ifdef __ARCH_WANT_SYS_LLSEEK
> > >  SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
> > > unsigned long, offset_low, loff_t __user *, result,
> > > unsigned int, whence)
> >
> > However, only reverting the patch will now break all newly added
> > 32-bit architectures that don't define __ARCH_WANT_SYS_LLSEEK:
> > at least nds32 and riscv32 come to mind, not sure if there is another.
>
> AFAICT nds32 never had the syscall. Its headers were added without
> __ARCH_WANT_SYS_LLSEEK before the define was removed.

nds32 got it from include/asm-generic/unistd.h

Arnd


Re: [PATCH v6 4/6] powerpc/64: make buildable without CONFIG_COMPAT

2019-08-30 Thread Michal Suchánek
On Fri, 30 Aug 2019 22:21:09 +0200
Christophe Leroy  wrote:

> Le 30/08/2019 à 20:57, Michal Suchanek a écrit :
> > There are numerous references to 32bit functions in generic and 64bit
> > code so ifdef them out.
> > 
> > Signed-off-by: Michal Suchanek 
> > ---
> > v2:
> > - fix 32bit ifdef condition in signal.c
> > - simplify the compat ifdef condition in vdso.c - 64bit is redundant
> > - simplify the compat ifdef condition in callchain.c - 64bit is redundant
> > v3:
> > - use IS_ENABLED and maybe_unused where possible
> > - do not ifdef declarations
> > - clean up Makefile
> > v4:
> > - further makefile cleanup
> > - simplify is_32bit_task conditions
> > - avoid ifdef in condition by using return
> > v5:
> > - avoid unreachable code on 32bit
> > - make is_current_64bit constant on !COMPAT
> > - add stub perf_callchain_user_32 to avoid some ifdefs
> > v6:
> > - consolidate current_is_64bit
> > ---
> >   arch/powerpc/include/asm/thread_info.h |  4 +--
> >   arch/powerpc/kernel/Makefile   |  7 +++--
> >   arch/powerpc/kernel/entry_64.S |  2 ++
> >   arch/powerpc/kernel/signal.c   |  3 +--
> >   arch/powerpc/kernel/syscall_64.c   |  6 ++---
> >   arch/powerpc/kernel/vdso.c |  5 ++--
> >   arch/powerpc/perf/callchain.c  | 37 +++---
> >   7 files changed, 33 insertions(+), 31 deletions(-)
> >   
> 
> [...]
> 
> > diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
> > index b7cdcce20280..788ad2c63f18 100644
> > --- a/arch/powerpc/perf/callchain.c
> > +++ b/arch/powerpc/perf/callchain.c
> > @@ -15,7 +15,7 @@
> >   #include 
> >   #include 
> >   #include 
> > -#ifdef CONFIG_PPC64
> > +#ifdef CONFIG_COMPAT
> >   #include "../kernel/ppc32.h"
> >   #endif
> >   #include 
> > @@ -268,16 +268,6 @@ static void perf_callchain_user_64(struct 
> > perf_callchain_entry_ctx *entry,
> > }
> >   }
> >   
> > -static inline int current_is_64bit(void)
> > -{
> > -   /*
> > -* We can't use test_thread_flag() here because we may be on an
> > -* interrupt stack, and the thread flags don't get copied over
> > -* from the thread_info on the main stack to the interrupt stack.
> > -*/
> > -   return !test_ti_thread_flag(task_thread_info(current), TIF_32BIT);
> > -}
> > -
> >   #else  /* CONFIG_PPC64 */
> >   static int read_user_stack_slow(void __user *ptr, void *buf, int nb)
> >   {
> > @@ -314,11 +304,6 @@ static inline void perf_callchain_user_64(struct 
> > perf_callchain_entry_ctx *entry
> >   {
> >   }
> >   
> > -static inline int current_is_64bit(void)
> > -{
> > -   return 0;
> > -}
> > -
> >   static inline int valid_user_sp(unsigned long sp, int is_64)
> >   {
> > if (!sp || (sp & 7) || sp > TASK_SIZE - 32)
> > @@ -334,6 +319,7 @@ static inline int valid_user_sp(unsigned long sp, int 
> > is_64)
> >   
> >   #endif /* CONFIG_PPC64 */
> >   
> > +#if defined(CONFIG_PPC32) || defined(CONFIG_COMPAT)
> >   /*
> >* Layout for non-RT signal frames
> >*/
> > @@ -475,6 +461,25 @@ static void perf_callchain_user_32(struct 
> > perf_callchain_entry_ctx *entry,
> > sp = next_sp;
> > }
> >   }
> > +#else /* 32bit */
> > +static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
> > +  struct pt_regs *regs)
> > +{
> > +   (void)&read_user_stack_32; /* unused if !COMPAT */  
> 
> You don't need that anymore do you ?

Yes, this part is not needed. It was removed later anyway but this
state is broken.

Thanks

Michal

> 
> Christophe
> 
> > +}
> > +#endif /* 32bit */
> > +
> > +static inline int current_is_64bit(void)
> > +{
> > +   if (!IS_ENABLED(CONFIG_COMPAT))
> > +   return IS_ENABLED(CONFIG_PPC64);
> > +   /*
> > +* We can't use test_thread_flag() here because we may be on an
> > +* interrupt stack, and the thread flags don't get copied over
> > +* from the thread_info on the main stack to the interrupt stack.
> > +*/
> > +   return !test_ti_thread_flag(task_thread_info(current), TIF_32BIT);
> > +}
> >   
> >   void
> >   perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct 
> > pt_regs *regs)
> >   



Re:

2019-08-30 Thread Arnd Bergmann
On Fri, Aug 30, 2019 at 10:30 PM Michal Suchanek  wrote:
>
> Subject: [PATCH] powerpc: Add back __ARCH_WANT_SYS_LLSEEK macro
>
> This partially reverts commit caf6f9c8a326 ("asm-generic: Remove
> unneeded __ARCH_WANT_SYS_LLSEEK macro")
>
> When CONFIG_COMPAT is disabled on ppc64 the kernel does not build.
>
> There is resistance to both removing the llseek syscall from the 64bit
> syscall tables and building the llseek interface unconditionally.
>
> Link: https://lore.kernel.org/lkml/20190828151552.ga16...@infradead.org/
> Link: https://lore.kernel.org/lkml/20190829214319.498c7de2@naga/
>
> Signed-off-by: Michal Suchanek 

Reviewed-by: Arnd Bergmann 


[no subject]

2019-08-30 Thread Michal Suchanek
Subject: [PATCH] powerpc: Add back __ARCH_WANT_SYS_LLSEEK macro

This partially reverts commit caf6f9c8a326 ("asm-generic: Remove
unneeded __ARCH_WANT_SYS_LLSEEK macro")

When CONFIG_COMPAT is disabled on ppc64 the kernel does not build.

There is resistance to both removing the llseek syscall from the 64bit
syscall tables and building the llseek interface unconditionally.

Link: https://lore.kernel.org/lkml/20190828151552.ga16...@infradead.org/
Link: https://lore.kernel.org/lkml/20190829214319.498c7de2@naga/

Signed-off-by: Michal Suchanek 
---
 arch/powerpc/include/asm/unistd.h | 1 +
 fs/read_write.c   | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/unistd.h 
b/arch/powerpc/include/asm/unistd.h
index b0720c7c3fcf..700fcdac2e3c 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -31,6 +31,7 @@
 #define __ARCH_WANT_SYS_SOCKETCALL
 #define __ARCH_WANT_SYS_FADVISE64
 #define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT
 #define __ARCH_WANT_SYS_OLD_UNAME
diff --git a/fs/read_write.c b/fs/read_write.c
index 5bbf587f5bc1..89aa2701dbeb 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -331,7 +331,8 @@ COMPAT_SYSCALL_DEFINE3(lseek, unsigned int, fd, 
compat_off_t, offset, unsigned i
 }
 #endif
 
-#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
+#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT) || \
+   defined(__ARCH_WANT_SYS_LLSEEK)
 SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
unsigned long, offset_low, loff_t __user *, result,
unsigned int, whence)
-- 
2.22.0



Re: [PATCH v6 6/6] powerpc/perf: split callchain.c by bitness

2019-08-30 Thread Christophe Leroy




Le 30/08/2019 à 20:57, Michal Suchanek a écrit :

Building callchain.c with !COMPAT proved quite ugly with all the
defines. Splitting out the 32bit and 64bit parts looks better.

No code change intended.

Signed-off-by: Michal Suchanek 


Reviewed-by: Christophe Leroy 


---
v6:
  - move current_is_64bit consolidetaion to earlier patch
  - move defines to the top of callchain_32.c
  - Makefile cleanup
---
  arch/powerpc/perf/Makefile   |   5 +-
  arch/powerpc/perf/callchain.c| 371 +--
  arch/powerpc/perf/callchain.h|  11 +
  arch/powerpc/perf/callchain_32.c | 204 +
  arch/powerpc/perf/callchain_64.c | 185 +++
  5 files changed, 405 insertions(+), 371 deletions(-)
  create mode 100644 arch/powerpc/perf/callchain.h
  create mode 100644 arch/powerpc/perf/callchain_32.c
  create mode 100644 arch/powerpc/perf/callchain_64.c

diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
index c155dcbb8691..53d614e98537 100644
--- a/arch/powerpc/perf/Makefile
+++ b/arch/powerpc/perf/Makefile
@@ -1,6 +1,9 @@
  # SPDX-License-Identifier: GPL-2.0
  
-obj-$(CONFIG_PERF_EVENTS)	+= callchain.o perf_regs.o

+obj-$(CONFIG_PERF_EVENTS)  += callchain.o callchain_$(BITS).o perf_regs.o
+ifdef CONFIG_COMPAT
+obj-$(CONFIG_PERF_EVENTS)  += callchain_32.o
+endif
  
  obj-$(CONFIG_PPC_PERF_CTRS)	+= core-book3s.o bhrb.o

  obj64-$(CONFIG_PPC_PERF_CTRS) += ppc970-pmu.o power5-pmu.o \
diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
index 788ad2c63f18..8f30f1b47c78 100644
--- a/arch/powerpc/perf/callchain.c
+++ b/arch/powerpc/perf/callchain.c
@@ -15,11 +15,9 @@
  #include 
  #include 
  #include 
-#ifdef CONFIG_COMPAT
-#include "../kernel/ppc32.h"
-#endif
  #include 
  
+#include "callchain.h"
  
  /*

   * Is sp valid as the address of the next kernel stack frame after prev_sp?
@@ -102,373 +100,6 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx 
*entry, struct pt_regs *re
}
  }
  
-#ifdef CONFIG_PPC64

-/*
- * On 64-bit we don't want to invoke hash_page on user addresses from
- * interrupt context, so if the access faults, we read the page tables
- * to find which page (if any) is mapped and access it directly.
- */
-static int read_user_stack_slow(void __user *ptr, void *buf, int nb)
-{
-   int ret = -EFAULT;
-   pgd_t *pgdir;
-   pte_t *ptep, pte;
-   unsigned shift;
-   unsigned long addr = (unsigned long) ptr;
-   unsigned long offset;
-   unsigned long pfn, flags;
-   void *kaddr;
-
-   pgdir = current->mm->pgd;
-   if (!pgdir)
-   return -EFAULT;
-
-   local_irq_save(flags);
-   ptep = find_current_mm_pte(pgdir, addr, NULL, &shift);
-   if (!ptep)
-   goto err_out;
-   if (!shift)
-   shift = PAGE_SHIFT;
-
-   /* align address to page boundary */
-   offset = addr & ((1UL << shift) - 1);
-
-   pte = READ_ONCE(*ptep);
-   if (!pte_present(pte) || !pte_user(pte))
-   goto err_out;
-   pfn = pte_pfn(pte);
-   if (!page_is_ram(pfn))
-   goto err_out;
-
-   /* no highmem to worry about here */
-   kaddr = pfn_to_kaddr(pfn);
-   memcpy(buf, kaddr + offset, nb);
-   ret = 0;
-err_out:
-   local_irq_restore(flags);
-   return ret;
-}
-
-static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret)
-{
-   if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned long) ||
-   ((unsigned long)ptr & 7))
-   return -EFAULT;
-
-   pagefault_disable();
-   if (!__get_user_inatomic(*ret, ptr)) {
-   pagefault_enable();
-   return 0;
-   }
-   pagefault_enable();
-
-   return read_user_stack_slow(ptr, ret, 8);
-}
-
-static inline int valid_user_sp(unsigned long sp, int is_64)
-{
-   if (!sp || (sp & 7) || sp > (is_64 ? TASK_SIZE : 0x1UL) - 32)
-   return 0;
-   return 1;
-}
-
-/*
- * 64-bit user processes use the same stack frame for RT and non-RT signals.
- */
-struct signal_frame_64 {
-   chardummy[__SIGNAL_FRAMESIZE];
-   struct ucontext uc;
-   unsigned long   unused[2];
-   unsigned inttramp[6];
-   struct siginfo  *pinfo;
-   void*puc;
-   struct siginfo  info;
-   charabigap[288];
-};
-
-static int is_sigreturn_64_address(unsigned long nip, unsigned long fp)
-{
-   if (nip == fp + offsetof(struct signal_frame_64, tramp))
-   return 1;
-   if (vdso64_rt_sigtramp && current->mm->context.vdso_base &&
-   nip == current->mm->context.vdso_base + vdso64_rt_sigtramp)
-   return 1;
-   return 0;
-}
-
-/*
- * Do some sanity checking on the signal frame pointed to by sp.
- * We check the pinfo and puc pointers in the frame.
- */
-static int sane_signal_64_frame(unsigned long sp)
-{
-   struct signal_frame_64 __user *sf;
-   unsigned

Re: [PATCH v6 5/6] powerpc/64: Make COMPAT user-selectable disabled on littleendian by default.

2019-08-30 Thread Christophe Leroy




Le 30/08/2019 à 20:57, Michal Suchanek a écrit :

On bigendian ppc64 it is common to have 32bit legacy binaries but much
less so on littleendian.

Signed-off-by: Michal Suchanek 


Reviewed-by: Christophe Leroy 



---
v3: make configurable
---
  arch/powerpc/Kconfig | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 5bab0bb6b833..b0339e892329 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -264,8 +264,9 @@ config PANIC_TIMEOUT
default 180
  
  config COMPAT

-   bool
-   default y if PPC64
+   bool "Enable support for 32bit binaries"
+   depends on PPC64
+   default y if !CPU_LITTLE_ENDIAN
select COMPAT_BINFMT_ELF
select ARCH_WANT_OLD_COMPAT_IPC
select COMPAT_OLD_SIGACTION



Re: [PATCH v6 2/6] powerpc: move common register copy functions from signal_32.c to signal.c

2019-08-30 Thread Christophe Leroy




Le 30/08/2019 à 20:57, Michal Suchanek a écrit :

These functions are required for 64bit as well.

Signed-off-by: Michal Suchanek 


Reviewed-by: christophe.le...@c-s.fr



---
  arch/powerpc/kernel/signal.c| 141 
  arch/powerpc/kernel/signal_32.c | 140 ---
  2 files changed, 141 insertions(+), 140 deletions(-)

diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index e6c30cee6abf..60436432399f 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -18,12 +18,153 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
  
  #include "signal.h"
  
+#ifdef CONFIG_VSX

+unsigned long copy_fpr_to_user(void __user *to,
+  struct task_struct *task)
+{
+   u64 buf[ELF_NFPREG];
+   int i;
+
+   /* save FPR copy to local buffer then write to the thread_struct */
+   for (i = 0; i < (ELF_NFPREG - 1) ; i++)
+   buf[i] = task->thread.TS_FPR(i);
+   buf[i] = task->thread.fp_state.fpscr;
+   return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
+}
+
+unsigned long copy_fpr_from_user(struct task_struct *task,
+void __user *from)
+{
+   u64 buf[ELF_NFPREG];
+   int i;
+
+   if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
+   return 1;
+   for (i = 0; i < (ELF_NFPREG - 1) ; i++)
+   task->thread.TS_FPR(i) = buf[i];
+   task->thread.fp_state.fpscr = buf[i];
+
+   return 0;
+}
+
+unsigned long copy_vsx_to_user(void __user *to,
+  struct task_struct *task)
+{
+   u64 buf[ELF_NVSRHALFREG];
+   int i;
+
+   /* save FPR copy to local buffer then write to the thread_struct */
+   for (i = 0; i < ELF_NVSRHALFREG; i++)
+   buf[i] = task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET];
+   return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
+}
+
+unsigned long copy_vsx_from_user(struct task_struct *task,
+void __user *from)
+{
+   u64 buf[ELF_NVSRHALFREG];
+   int i;
+
+   if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
+   return 1;
+   for (i = 0; i < ELF_NVSRHALFREG ; i++)
+   task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
+   return 0;
+}
+
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+unsigned long copy_ckfpr_to_user(void __user *to,
+ struct task_struct *task)
+{
+   u64 buf[ELF_NFPREG];
+   int i;
+
+   /* save FPR copy to local buffer then write to the thread_struct */
+   for (i = 0; i < (ELF_NFPREG - 1) ; i++)
+   buf[i] = task->thread.TS_CKFPR(i);
+   buf[i] = task->thread.ckfp_state.fpscr;
+   return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
+}
+
+unsigned long copy_ckfpr_from_user(struct task_struct *task,
+ void __user *from)
+{
+   u64 buf[ELF_NFPREG];
+   int i;
+
+   if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
+   return 1;
+   for (i = 0; i < (ELF_NFPREG - 1) ; i++)
+   task->thread.TS_CKFPR(i) = buf[i];
+   task->thread.ckfp_state.fpscr = buf[i];
+
+   return 0;
+}
+
+unsigned long copy_ckvsx_to_user(void __user *to,
+ struct task_struct *task)
+{
+   u64 buf[ELF_NVSRHALFREG];
+   int i;
+
+   /* save FPR copy to local buffer then write to the thread_struct */
+   for (i = 0; i < ELF_NVSRHALFREG; i++)
+   buf[i] = task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET];
+   return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
+}
+
+unsigned long copy_ckvsx_from_user(struct task_struct *task,
+ void __user *from)
+{
+   u64 buf[ELF_NVSRHALFREG];
+   int i;
+
+   if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
+   return 1;
+   for (i = 0; i < ELF_NVSRHALFREG ; i++)
+   task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
+   return 0;
+}
+#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
+#else
+inline unsigned long copy_fpr_to_user(void __user *to,
+ struct task_struct *task)
+{
+   return __copy_to_user(to, task->thread.fp_state.fpr,
+ ELF_NFPREG * sizeof(double));
+}
+
+inline unsigned long copy_fpr_from_user(struct task_struct *task,
+   void __user *from)
+{
+   return __copy_from_user(task->thread.fp_state.fpr, from,
+ ELF_NFPREG * sizeof(double));
+}
+
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+inline unsigned long copy_ckfpr_to_user(void __user *to,
+struct task_struct *task)
+{
+   return __copy_to_user(to, task->thread.ckf

Re: [PATCH v6 3/6] powerpc/perf: consolidate read_user_stack_32

2019-08-30 Thread Christophe Leroy




Le 30/08/2019 à 20:57, Michal Suchanek a écrit :

There are two almost identical copies for 32bit and 64bit.

The function is used only in 32bit code which will be split out in next
patch so consolidate to one function.

Signed-off-by: Michal Suchanek 


Reviewed-by: christophe.le...@c-s.fr


---
new patch in v6
---
  arch/powerpc/perf/callchain.c | 25 +
  1 file changed, 9 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
index c84bbd4298a0..b7cdcce20280 100644
--- a/arch/powerpc/perf/callchain.c
+++ b/arch/powerpc/perf/callchain.c
@@ -165,22 +165,6 @@ static int read_user_stack_64(unsigned long __user *ptr, 
unsigned long *ret)
return read_user_stack_slow(ptr, ret, 8);
  }
  
-static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)

-{
-   if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
-   ((unsigned long)ptr & 3))
-   return -EFAULT;
-
-   pagefault_disable();
-   if (!__get_user_inatomic(*ret, ptr)) {
-   pagefault_enable();
-   return 0;
-   }
-   pagefault_enable();
-
-   return read_user_stack_slow(ptr, ret, 4);
-}
-
  static inline int valid_user_sp(unsigned long sp, int is_64)
  {
if (!sp || (sp & 7) || sp > (is_64 ? TASK_SIZE : 0x1UL) - 32)
@@ -295,6 +279,12 @@ static inline int current_is_64bit(void)
  }
  
  #else  /* CONFIG_PPC64 */

+static int read_user_stack_slow(void __user *ptr, void *buf, int nb)
+{
+   return 0;
+}
+#endif /* CONFIG_PPC64 */
+
  /*
   * On 32-bit we just access the address and let hash_page create a
   * HPTE if necessary, so there is no need to fall back to reading
@@ -313,9 +303,12 @@ static int read_user_stack_32(unsigned int __user *ptr, 
unsigned int *ret)
rc = __get_user_inatomic(*ret, ptr);
pagefault_enable();
  
+	if (IS_ENABLED(CONFIG_PPC64) && rc)

+   return read_user_stack_slow(ptr, ret, 4);
return rc;
  }
  
+#ifndef CONFIG_PPC64

  static inline void perf_callchain_user_64(struct perf_callchain_entry_ctx 
*entry,
  struct pt_regs *regs)
  {



Re: [PATCH v6 4/6] powerpc/64: make buildable without CONFIG_COMPAT

2019-08-30 Thread Christophe Leroy




Le 30/08/2019 à 20:57, Michal Suchanek a écrit :

There are numerous references to 32bit functions in generic and 64bit
code so ifdef them out.

Signed-off-by: Michal Suchanek 
---
v2:
- fix 32bit ifdef condition in signal.c
- simplify the compat ifdef condition in vdso.c - 64bit is redundant
- simplify the compat ifdef condition in callchain.c - 64bit is redundant
v3:
- use IS_ENABLED and maybe_unused where possible
- do not ifdef declarations
- clean up Makefile
v4:
- further makefile cleanup
- simplify is_32bit_task conditions
- avoid ifdef in condition by using return
v5:
- avoid unreachable code on 32bit
- make is_current_64bit constant on !COMPAT
- add stub perf_callchain_user_32 to avoid some ifdefs
v6:
- consolidate current_is_64bit
---
  arch/powerpc/include/asm/thread_info.h |  4 +--
  arch/powerpc/kernel/Makefile   |  7 +++--
  arch/powerpc/kernel/entry_64.S |  2 ++
  arch/powerpc/kernel/signal.c   |  3 +--
  arch/powerpc/kernel/syscall_64.c   |  6 ++---
  arch/powerpc/kernel/vdso.c |  5 ++--
  arch/powerpc/perf/callchain.c  | 37 +++---
  7 files changed, 33 insertions(+), 31 deletions(-)



[...]


diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
index b7cdcce20280..788ad2c63f18 100644
--- a/arch/powerpc/perf/callchain.c
+++ b/arch/powerpc/perf/callchain.c
@@ -15,7 +15,7 @@
  #include 
  #include 
  #include 
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_COMPAT
  #include "../kernel/ppc32.h"
  #endif
  #include 
@@ -268,16 +268,6 @@ static void perf_callchain_user_64(struct 
perf_callchain_entry_ctx *entry,
}
  }
  
-static inline int current_is_64bit(void)

-{
-   /*
-* We can't use test_thread_flag() here because we may be on an
-* interrupt stack, and the thread flags don't get copied over
-* from the thread_info on the main stack to the interrupt stack.
-*/
-   return !test_ti_thread_flag(task_thread_info(current), TIF_32BIT);
-}
-
  #else  /* CONFIG_PPC64 */
  static int read_user_stack_slow(void __user *ptr, void *buf, int nb)
  {
@@ -314,11 +304,6 @@ static inline void perf_callchain_user_64(struct 
perf_callchain_entry_ctx *entry
  {
  }
  
-static inline int current_is_64bit(void)

-{
-   return 0;
-}
-
  static inline int valid_user_sp(unsigned long sp, int is_64)
  {
if (!sp || (sp & 7) || sp > TASK_SIZE - 32)
@@ -334,6 +319,7 @@ static inline int valid_user_sp(unsigned long sp, int is_64)
  
  #endif /* CONFIG_PPC64 */
  
+#if defined(CONFIG_PPC32) || defined(CONFIG_COMPAT)

  /*
   * Layout for non-RT signal frames
   */
@@ -475,6 +461,25 @@ static void perf_callchain_user_32(struct 
perf_callchain_entry_ctx *entry,
sp = next_sp;
}
  }
+#else /* 32bit */
+static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
+  struct pt_regs *regs)
+{
+   (void)&read_user_stack_32; /* unused if !COMPAT */


You don't need that anymore do you ?

Christophe


+}
+#endif /* 32bit */
+
+static inline int current_is_64bit(void)
+{
+   if (!IS_ENABLED(CONFIG_COMPAT))
+   return IS_ENABLED(CONFIG_PPC64);
+   /*
+* We can't use test_thread_flag() here because we may be on an
+* interrupt stack, and the thread flags don't get copied over
+* from the thread_info on the main stack to the interrupt stack.
+*/
+   return !test_ti_thread_flag(task_thread_info(current), TIF_32BIT);
+}
  
  void

  perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs 
*regs)



Re: [PATCH 1/2] ftrace: Fix NULL pointer dereference in t_probe_next()

2019-08-30 Thread Steven Rostedt
On Thu,  4 Jul 2019 20:04:41 +0530
"Naveen N. Rao"  wrote:

> LTP testsuite on powerpc results in the below crash:
> 
>   Unable to handle kernel paging request for data at address 0x
>   Faulting instruction address: 0xc029d800
>   Oops: Kernel access of bad area, sig: 11 [#1]
>   LE SMP NR_CPUS=2048 NUMA PowerNV
>   ...
>   CPU: 68 PID: 96584 Comm: cat Kdump: loaded Tainted: GW
>   NIP:  c029d800 LR: c029dac4 CTR: c01e6ad0
>   REGS: c0002017fae8ba10 TRAP: 0300   Tainted: GW
>   MSR:  90009033   CR: 28022422  XER: 
> 2004
>   CFAR: c029d90c DAR:  DSISR: 4000 IRQMASK: 0
>   ...
>   NIP [c029d800] t_probe_next+0x60/0x180
>   LR [c029dac4] t_mod_start+0x1a4/0x1f0
>   Call Trace:
>   [c0002017fae8bc90] [c0cdbc40] _cond_resched+0x10/0xb0 (unreliable)
>   [c0002017fae8bce0] [c02a15b0] t_start+0xf0/0x1c0
>   [c0002017fae8bd30] [c04ec2b4] seq_read+0x184/0x640
>   [c0002017fae8bdd0] [c04a57bc] sys_read+0x10c/0x300
>   [c0002017fae8be30] [c000b388] system_call+0x5c/0x70
> 
> The test (ftrace_set_ftrace_filter.sh) is part of ftrace stress tests
> and the crash happens when the test does 'cat
> $TRACING_PATH/set_ftrace_filter'.
> 
> The address points to the second line below, in t_probe_next(), where
> filter_hash is dereferenced:
>   hash = iter->probe->ops.func_hash->filter_hash;
>   size = 1 << hash->size_bits;
> 
> This happens due to a race with register_ftrace_function_probe(). A new
> ftrace_func_probe is created and added into the func_probes list in
> trace_array under ftrace_lock. However, before initializing the filter,
> we drop ftrace_lock, and re-acquire it after acquiring regex_lock. If
> another process is trying to read set_ftrace_filter, it will be able to
> acquire ftrace_lock during this window and it will end up seeing a NULL
> filter_hash.
> 
> Fix this by just checking for a NULL filter_hash in t_probe_next(). If
> the filter_hash is NULL, then this probe is just being added and we can
> simply return from here.

Hmm, this is very subtle. I'll take a deeper look at this to see if we
can keep the race from happening.

Thanks!

-- Steve

> 
> Signed-off-by: Naveen N. Rao 
> ---
>  kernel/trace/ftrace.c | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
> index 7b037295a1f1..0791eafb693d 100644
> --- a/kernel/trace/ftrace.c
> +++ b/kernel/trace/ftrace.c
> @@ -3093,6 +3093,10 @@ t_probe_next(struct seq_file *m, loff_t *pos)
>   hnd = &iter->probe_entry->hlist;
>  
>   hash = iter->probe->ops.func_hash->filter_hash;
> +
> + if (!hash)
> + return NULL;
> +
>   size = 1 << hash->size_bits;
>  
>   retry:



Re: [PATCH 0/2] ftrace: two fixes with func_probes handling

2019-08-30 Thread Steven Rostedt
On Thu, 08 Aug 2019 20:45:04 +0530
"Naveen N. Rao"  wrote:

> Naveen N. Rao wrote:
> > Two patches addressing bugs in ftrace function probe handling. The first 
> > patch addresses a NULL pointer dereference reported by LTP tests, while 
> > the second one is a trivial patch to address a missing check for return 
> > value, found by code inspection.  
> 
> Steven,
> Can you please take a look at these patches?
>

Sorry for the late reply, I've been traveling a lot lately. I'm looking
at these now. I'm trying to see how they triggered a bug.

-- Steve


Re: [PATCH] Revert "asm-generic: Remove unneeded __ARCH_WANT_SYS_LLSEEK macro"

2019-08-30 Thread Michal Suchánek
On Fri, 30 Aug 2019 21:54:43 +0200
Arnd Bergmann  wrote:

> On Fri, Aug 30, 2019 at 9:46 PM Michal Suchanek  wrote:
> >
> > This reverts commit caf6f9c8a326cffd1d4b3ff3f1cfba75d159d70b.
> >
> > Maybe it was needed after all.
> >
> > When CONFIG_COMPAT is disabled on ppc64 the kernel does not build.
> >
> > There is resistance to both removing the llseek syscall from the 64bit
> > syscall tables and building the llseek interface unconditionally.
> >
> > Link: https://lore.kernel.org/lkml/20190828151552.ga16...@infradead.org/
> > Link: https://lore.kernel.org/lkml/20190829214319.498c7de2@naga/
> >
> > Signed-off-by: Michal Suchanek   
> 
> This seems like the right idea in principle.
> 
> > index 5bbf587f5bc1..2f3c4bb138c4 100644
> > --- a/fs/read_write.c
> > +++ b/fs/read_write.c
> > @@ -331,7 +331,7 @@ COMPAT_SYSCALL_DEFINE3(lseek, unsigned int, fd, 
> > compat_off_t, offset, unsigned i
> >  }
> >  #endif
> >
> > -#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
> > +#ifdef __ARCH_WANT_SYS_LLSEEK
> >  SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
> > unsigned long, offset_low, loff_t __user *, result,
> > unsigned int, whence)  
> 
> However, only reverting the patch will now break all newly added
> 32-bit architectures that don't define __ARCH_WANT_SYS_LLSEEK:
> at least nds32 and riscv32 come to mind, not sure if there is another.

AFAICT nds32 never had the syscall. Its headers were added without
__ARCH_WANT_SYS_LLSEEK before the define was removed.

The new architecture csky should be handled.

> 
> I think the easiest way however would be to combine the two checks
> above and make it
> 
> #if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT) ||
> defined(__ARCH_WANT_SYS_LLSEEK)
> 
> and then only set __ARCH_WANT_SYS_LLSEEK for powerpc.

Yes, that limits the use of __ARCH_WANT_SYS_LLSEEK, does not require
resurrecting the old headers, and may fix some architectures like nds32
that forgot to add it.

Thanks

Michal


Re: [PATCH v2 4/4] powerpc/64: system call implement the bulk of the logic in C

2019-08-30 Thread Michal Suchánek
On Sat, 31 Aug 2019 02:48:26 +0800
kbuild test robot  wrote:

> Hi Nicholas,
> 
> I love your patch! Yet something to improve:
> 
> [auto build test ERROR on linus/master]
> [cannot apply to v5.3-rc6 next-20190830]
> [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/Nicholas-Piggin/powerpc-64-syscalls-in-C/20190828-064221
> config: powerpc64-defconfig (attached as .config)
> compiler: powerpc64-linux-gcc (GCC) 7.4.0
> reproduce:
> wget 
> https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
> ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # save the attached .config to linux build tree
> GCC_VERSION=7.4.0 make.cross ARCH=powerpc64 
> 
> If you fix the issue, kindly add following tag
> Reported-by: kbuild test robot 
> 
> All errors (new ones prefixed by >>):
> 
>powerpc64-linux-ld: warning: orphan section `.gnu.hash' from `linker 
> stubs' being placed in section `.gnu.hash'.
>arch/powerpc/kernel/syscall_64.o: In function `.system_call_exception':
> >> syscall_64.c:(.text+0x180): undefined reference to `.tabort_syscall'  

Interestingly it builds and boots for me. Is this something about
dotted vs dotless symbols depending on some config options?

I see there is _GLOBAL(ret_from_fork) just below so maybe we need
_GLOBAL(tabort_syscall) instead of .globl tabort_syscall as well.

Thanks

Michal


Re: [PATCH] Revert "asm-generic: Remove unneeded __ARCH_WANT_SYS_LLSEEK macro"

2019-08-30 Thread Arnd Bergmann
On Fri, Aug 30, 2019 at 9:46 PM Michal Suchanek  wrote:
>
> This reverts commit caf6f9c8a326cffd1d4b3ff3f1cfba75d159d70b.
>
> Maybe it was needed after all.
>
> When CONFIG_COMPAT is disabled on ppc64 the kernel does not build.
>
> There is resistance to both removing the llseek syscall from the 64bit
> syscall tables and building the llseek interface unconditionally.
>
> Link: https://lore.kernel.org/lkml/20190828151552.ga16...@infradead.org/
> Link: https://lore.kernel.org/lkml/20190829214319.498c7de2@naga/
>
> Signed-off-by: Michal Suchanek 

This seems like the right idea in principle.

> index 5bbf587f5bc1..2f3c4bb138c4 100644
> --- a/fs/read_write.c
> +++ b/fs/read_write.c
> @@ -331,7 +331,7 @@ COMPAT_SYSCALL_DEFINE3(lseek, unsigned int, fd, 
> compat_off_t, offset, unsigned i
>  }
>  #endif
>
> -#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
> +#ifdef __ARCH_WANT_SYS_LLSEEK
>  SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
> unsigned long, offset_low, loff_t __user *, result,
> unsigned int, whence)

However, only reverting the patch will now break all newly added
32-bit architectures that don't define __ARCH_WANT_SYS_LLSEEK:
at least nds32 and riscv32 come to mind, not sure if there is another.

I think the easiest way however would be to combine the two checks
above and make it

#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT) ||
defined(__ARCH_WANT_SYS_LLSEEK)

and then only set __ARCH_WANT_SYS_LLSEEK for powerpc.

 Arnd


[PATCH] Revert "asm-generic: Remove unneeded __ARCH_WANT_SYS_LLSEEK macro"

2019-08-30 Thread Michal Suchanek
This reverts commit caf6f9c8a326cffd1d4b3ff3f1cfba75d159d70b.

Maybe it was needed after all.

When CONFIG_COMPAT is disabled on ppc64 the kernel does not build.

There is resistance to both removing the llseek syscall from the 64bit
syscall tables and building the llseek interface unconditionally.

Link: https://lore.kernel.org/lkml/20190828151552.ga16...@infradead.org/
Link: https://lore.kernel.org/lkml/20190829214319.498c7de2@naga/

Signed-off-by: Michal Suchanek 
---
 arch/arm/include/asm/unistd.h|  1 +
 arch/arm64/include/asm/unistd.h  |  1 +
 arch/csky/include/asm/unistd.h   |  2 +-
 arch/m68k/include/asm/unistd.h   |  1 +
 arch/microblaze/include/asm/unistd.h |  1 +
 arch/mips/include/asm/unistd.h   |  1 +
 arch/parisc/include/asm/unistd.h |  1 +
 arch/powerpc/include/asm/unistd.h|  1 +
 arch/s390/include/asm/unistd.h   |  1 +
 arch/sh/include/asm/unistd.h |  1 +
 arch/sparc/include/asm/unistd.h  |  1 +
 arch/x86/include/asm/unistd.h|  1 +
 arch/xtensa/include/asm/unistd.h |  1 +
 fs/read_write.c  |  2 +-
 include/asm-generic/unistd.h | 12 
 15 files changed, 26 insertions(+), 2 deletions(-)
 create mode 100644 include/asm-generic/unistd.h

diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index 3676e82cf95c..e35ec8100a21 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -18,6 +18,7 @@
 #define __ARCH_WANT_SYS_GETHOSTNAME
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 2629a68b8724..2c9d8d91e347 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -7,6 +7,7 @@
 #define __ARCH_WANT_SYS_GETHOSTNAME
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
diff --git a/arch/csky/include/asm/unistd.h b/arch/csky/include/asm/unistd.h
index da7a18295615..bee8ba8309e7 100644
--- a/arch/csky/include/asm/unistd.h
+++ b/arch/csky/include/asm/unistd.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
 
-#include 
+#include 
 
 #define NR_syscalls (__NR_syscalls)
diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h
index 2e0047cf86f8..54c04eb4495a 100644
--- a/arch/m68k/include/asm/unistd.h
+++ b/arch/m68k/include/asm/unistd.h
@@ -21,6 +21,7 @@
 #define __ARCH_WANT_SYS_SOCKETCALL
 #define __ARCH_WANT_SYS_FADVISE64
 #define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT
 #define __ARCH_WANT_SYS_OLD_MMAP
diff --git a/arch/microblaze/include/asm/unistd.h 
b/arch/microblaze/include/asm/unistd.h
index d79d35ac6253..c5fcbce1f997 100644
--- a/arch/microblaze/include/asm/unistd.h
+++ b/arch/microblaze/include/asm/unistd.h
@@ -27,6 +27,7 @@
 #define __ARCH_WANT_SYS_SOCKETCALL
 #define __ARCH_WANT_SYS_FADVISE64
 #define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 /* #define __ARCH_WANT_SYS_OLD_GETRLIMIT */
 #define __ARCH_WANT_SYS_OLDUMOUNT
diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h
index 071053ece677..8e8c7cab95ca 100644
--- a/arch/mips/include/asm/unistd.h
+++ b/arch/mips/include/asm/unistd.h
@@ -38,6 +38,7 @@
 #define __ARCH_WANT_SYS_WAITPID
 #define __ARCH_WANT_SYS_SOCKETCALL
 #define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_UNAME
 #define __ARCH_WANT_SYS_OLDUMOUNT
diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h
index cd438e4150f6..29bd46381f2e 100644
--- a/arch/parisc/include/asm/unistd.h
+++ b/arch/parisc/include/asm/unistd.h
@@ -159,6 +159,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, 
type5 arg5)   \
 #define __ARCH_WANT_SYS_SOCKETCALL
 #define __ARCH_WANT_SYS_FADVISE64
 #define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
diff --git a/arch/powerpc/include/asm/unistd.h 
b/arch/powerpc/include/asm/unistd.h
index b0720c7c3fcf..700fcdac2e3c 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -31,6 +31,7 @@
 #define __ARCH_WANT_SYS_SOCKETCALL
 #define __ARCH_WANT_SYS_FADVISE64
 #define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
 #define __ARCH_WANT_SYS_OLD_GETRLIMIT
 #define __ARCH_WANT_SYS_OLD_UNAME
diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h
index 9e9f75ef046a..52e9e2fe37

Re: [PATCH v6 6/6] powerpc/perf: split callchain.c by bitness

2019-08-30 Thread Michal Suchánek
On Fri, 30 Aug 2019 20:57:57 +0200
Michal Suchanek  wrote:

> Building callchain.c with !COMPAT proved quite ugly with all the
> defines. Splitting out the 32bit and 64bit parts looks better.
> 

BTW the powerpc callchain.c does not match any of the patterns of PERF
CORE in MAINTAINERS (unlike callchain implementation on other
platforms). Is that intentional?

Thanks

Michal


[PATCH v6 6/6] powerpc/perf: split callchain.c by bitness

2019-08-30 Thread Michal Suchanek
Building callchain.c with !COMPAT proved quite ugly with all the
defines. Splitting out the 32bit and 64bit parts looks better.

No code change intended.

Signed-off-by: Michal Suchanek 
---
v6:
 - move current_is_64bit consolidetaion to earlier patch
 - move defines to the top of callchain_32.c
 - Makefile cleanup
---
 arch/powerpc/perf/Makefile   |   5 +-
 arch/powerpc/perf/callchain.c| 371 +--
 arch/powerpc/perf/callchain.h|  11 +
 arch/powerpc/perf/callchain_32.c | 204 +
 arch/powerpc/perf/callchain_64.c | 185 +++
 5 files changed, 405 insertions(+), 371 deletions(-)
 create mode 100644 arch/powerpc/perf/callchain.h
 create mode 100644 arch/powerpc/perf/callchain_32.c
 create mode 100644 arch/powerpc/perf/callchain_64.c

diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
index c155dcbb8691..53d614e98537 100644
--- a/arch/powerpc/perf/Makefile
+++ b/arch/powerpc/perf/Makefile
@@ -1,6 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0
 
-obj-$(CONFIG_PERF_EVENTS)  += callchain.o perf_regs.o
+obj-$(CONFIG_PERF_EVENTS)  += callchain.o callchain_$(BITS).o perf_regs.o
+ifdef CONFIG_COMPAT
+obj-$(CONFIG_PERF_EVENTS)  += callchain_32.o
+endif
 
 obj-$(CONFIG_PPC_PERF_CTRS)+= core-book3s.o bhrb.o
 obj64-$(CONFIG_PPC_PERF_CTRS)  += ppc970-pmu.o power5-pmu.o \
diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
index 788ad2c63f18..8f30f1b47c78 100644
--- a/arch/powerpc/perf/callchain.c
+++ b/arch/powerpc/perf/callchain.c
@@ -15,11 +15,9 @@
 #include 
 #include 
 #include 
-#ifdef CONFIG_COMPAT
-#include "../kernel/ppc32.h"
-#endif
 #include 
 
+#include "callchain.h"
 
 /*
  * Is sp valid as the address of the next kernel stack frame after prev_sp?
@@ -102,373 +100,6 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx 
*entry, struct pt_regs *re
}
 }
 
-#ifdef CONFIG_PPC64
-/*
- * On 64-bit we don't want to invoke hash_page on user addresses from
- * interrupt context, so if the access faults, we read the page tables
- * to find which page (if any) is mapped and access it directly.
- */
-static int read_user_stack_slow(void __user *ptr, void *buf, int nb)
-{
-   int ret = -EFAULT;
-   pgd_t *pgdir;
-   pte_t *ptep, pte;
-   unsigned shift;
-   unsigned long addr = (unsigned long) ptr;
-   unsigned long offset;
-   unsigned long pfn, flags;
-   void *kaddr;
-
-   pgdir = current->mm->pgd;
-   if (!pgdir)
-   return -EFAULT;
-
-   local_irq_save(flags);
-   ptep = find_current_mm_pte(pgdir, addr, NULL, &shift);
-   if (!ptep)
-   goto err_out;
-   if (!shift)
-   shift = PAGE_SHIFT;
-
-   /* align address to page boundary */
-   offset = addr & ((1UL << shift) - 1);
-
-   pte = READ_ONCE(*ptep);
-   if (!pte_present(pte) || !pte_user(pte))
-   goto err_out;
-   pfn = pte_pfn(pte);
-   if (!page_is_ram(pfn))
-   goto err_out;
-
-   /* no highmem to worry about here */
-   kaddr = pfn_to_kaddr(pfn);
-   memcpy(buf, kaddr + offset, nb);
-   ret = 0;
-err_out:
-   local_irq_restore(flags);
-   return ret;
-}
-
-static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret)
-{
-   if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned long) ||
-   ((unsigned long)ptr & 7))
-   return -EFAULT;
-
-   pagefault_disable();
-   if (!__get_user_inatomic(*ret, ptr)) {
-   pagefault_enable();
-   return 0;
-   }
-   pagefault_enable();
-
-   return read_user_stack_slow(ptr, ret, 8);
-}
-
-static inline int valid_user_sp(unsigned long sp, int is_64)
-{
-   if (!sp || (sp & 7) || sp > (is_64 ? TASK_SIZE : 0x1UL) - 32)
-   return 0;
-   return 1;
-}
-
-/*
- * 64-bit user processes use the same stack frame for RT and non-RT signals.
- */
-struct signal_frame_64 {
-   chardummy[__SIGNAL_FRAMESIZE];
-   struct ucontext uc;
-   unsigned long   unused[2];
-   unsigned inttramp[6];
-   struct siginfo  *pinfo;
-   void*puc;
-   struct siginfo  info;
-   charabigap[288];
-};
-
-static int is_sigreturn_64_address(unsigned long nip, unsigned long fp)
-{
-   if (nip == fp + offsetof(struct signal_frame_64, tramp))
-   return 1;
-   if (vdso64_rt_sigtramp && current->mm->context.vdso_base &&
-   nip == current->mm->context.vdso_base + vdso64_rt_sigtramp)
-   return 1;
-   return 0;
-}
-
-/*
- * Do some sanity checking on the signal frame pointed to by sp.
- * We check the pinfo and puc pointers in the frame.
- */
-static int sane_signal_64_frame(unsigned long sp)
-{
-   struct signal_frame_64 __user *sf;
-   unsigned long pinfo, puc;
-
-   sf = (struct signal_frame_64 __user *) sp;
-   if (read_user_stack_64((unsigned

[PATCH v6 5/6] powerpc/64: Make COMPAT user-selectable disabled on littleendian by default.

2019-08-30 Thread Michal Suchanek
On bigendian ppc64 it is common to have 32bit legacy binaries but much
less so on littleendian.

Signed-off-by: Michal Suchanek 
---
v3: make configurable
---
 arch/powerpc/Kconfig | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 5bab0bb6b833..b0339e892329 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -264,8 +264,9 @@ config PANIC_TIMEOUT
default 180
 
 config COMPAT
-   bool
-   default y if PPC64
+   bool "Enable support for 32bit binaries"
+   depends on PPC64
+   default y if !CPU_LITTLE_ENDIAN
select COMPAT_BINFMT_ELF
select ARCH_WANT_OLD_COMPAT_IPC
select COMPAT_OLD_SIGACTION
-- 
2.22.0



[PATCH v6 4/6] powerpc/64: make buildable without CONFIG_COMPAT

2019-08-30 Thread Michal Suchanek
There are numerous references to 32bit functions in generic and 64bit
code so ifdef them out.

Signed-off-by: Michal Suchanek 
---
v2:
- fix 32bit ifdef condition in signal.c
- simplify the compat ifdef condition in vdso.c - 64bit is redundant
- simplify the compat ifdef condition in callchain.c - 64bit is redundant
v3:
- use IS_ENABLED and maybe_unused where possible
- do not ifdef declarations
- clean up Makefile
v4:
- further makefile cleanup
- simplify is_32bit_task conditions
- avoid ifdef in condition by using return
v5:
- avoid unreachable code on 32bit
- make is_current_64bit constant on !COMPAT
- add stub perf_callchain_user_32 to avoid some ifdefs
v6:
- consolidate current_is_64bit
---
 arch/powerpc/include/asm/thread_info.h |  4 +--
 arch/powerpc/kernel/Makefile   |  7 +++--
 arch/powerpc/kernel/entry_64.S |  2 ++
 arch/powerpc/kernel/signal.c   |  3 +--
 arch/powerpc/kernel/syscall_64.c   |  6 ++---
 arch/powerpc/kernel/vdso.c |  5 ++--
 arch/powerpc/perf/callchain.c  | 37 +++---
 7 files changed, 33 insertions(+), 31 deletions(-)

diff --git a/arch/powerpc/include/asm/thread_info.h 
b/arch/powerpc/include/asm/thread_info.h
index 8e1d0195ac36..c128d8a48ea3 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -144,10 +144,10 @@ static inline bool test_thread_local_flags(unsigned int 
flags)
return (ti->local_flags & flags) != 0;
 }
 
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_COMPAT
 #define is_32bit_task()(test_thread_flag(TIF_32BIT))
 #else
-#define is_32bit_task()(1)
+#define is_32bit_task()(IS_ENABLED(CONFIG_PPC32))
 #endif
 
 #if defined(CONFIG_PPC64)
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 1d646a94d96c..9d8772e863b9 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -44,16 +44,15 @@ CFLAGS_btext.o += -DDISABLE_BRANCH_PROFILING
 endif
 
 obj-y  := cputable.o ptrace.o syscalls.o \
-  irq.o align.o signal_32.o pmc.o vdso.o \
+  irq.o align.o signal_$(BITS).o pmc.o vdso.o \
   process.o systbl.o idle.o \
   signal.o sysfs.o cacheinfo.o time.o \
   prom.o traps.o setup-common.o \
   udbg.o misc.o io.o misc_$(BITS).o \
   of_platform.o prom_parse.o
-obj-$(CONFIG_PPC64)+= setup_64.o sys_ppc32.o \
-  signal_64.o ptrace32.o \
-  paca.o nvram_64.o firmware.o \
+obj-$(CONFIG_PPC64)+= setup_64.o paca.o nvram_64.o firmware.o \
   syscall_64.o
+obj-$(CONFIG_COMPAT)   += sys_ppc32.o ptrace32.o signal_32.o
 obj-$(CONFIG_VDSO32)   += vdso32/
 obj-$(CONFIG_PPC_WATCHDOG) += watchdog.o
 obj-$(CONFIG_HAVE_HW_BREAKPOINT)   += hw_breakpoint.o
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 2ec825a85f5b..a2dbf216f607 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -51,8 +51,10 @@
 SYS_CALL_TABLE:
.tc sys_call_table[TC],sys_call_table
 
+#ifdef CONFIG_COMPAT
 COMPAT_SYS_CALL_TABLE:
.tc compat_sys_call_table[TC],compat_sys_call_table
+#endif
 
 /* This value is used to mark exception frames on the stack. */
 exception_marker:
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index 60436432399f..61678cb0e6a1 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -247,7 +247,6 @@ static void do_signal(struct task_struct *tsk)
sigset_t *oldset = sigmask_to_save();
struct ksignal ksig = { .sig = 0 };
int ret;
-   int is32 = is_32bit_task();
 
BUG_ON(tsk != current);
 
@@ -277,7 +276,7 @@ static void do_signal(struct task_struct *tsk)
 
rseq_signal_deliver(&ksig, tsk->thread.regs);
 
-   if (is32) {
+   if (is_32bit_task()) {
if (ksig.ka.sa.sa_flags & SA_SIGINFO)
ret = handle_rt_signal32(&ksig, oldset, tsk);
else
diff --git a/arch/powerpc/kernel/syscall_64.c b/arch/powerpc/kernel/syscall_64.c
index 98ed970796d5..0d5cbbe54cf1 100644
--- a/arch/powerpc/kernel/syscall_64.c
+++ b/arch/powerpc/kernel/syscall_64.c
@@ -38,7 +38,6 @@ typedef long (*syscall_fn)(long, long, long, long, long, 
long);
 
 long system_call_exception(long r3, long r4, long r5, long r6, long r7, long 
r8, unsigned long r0, struct pt_regs *regs)
 {
-   unsigned long ti_flags;
syscall_fn f;
 
BUG_ON(!(regs->msr & MSR_PR));
@@ -83,8 +82,7 @@ long system_call_exception(long r3, long r4, long r5, long 
r6, long r7, long r8,
 */
regs->softe = IRQS_ENABLED;
 
-   ti_flags = current_thread_info

[PATCH v6 3/6] powerpc/perf: consolidate read_user_stack_32

2019-08-30 Thread Michal Suchanek
There are two almost identical copies for 32bit and 64bit.

The function is used only in 32bit code which will be split out in next
patch so consolidate to one function.

Signed-off-by: Michal Suchanek 
---
new patch in v6
---
 arch/powerpc/perf/callchain.c | 25 +
 1 file changed, 9 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
index c84bbd4298a0..b7cdcce20280 100644
--- a/arch/powerpc/perf/callchain.c
+++ b/arch/powerpc/perf/callchain.c
@@ -165,22 +165,6 @@ static int read_user_stack_64(unsigned long __user *ptr, 
unsigned long *ret)
return read_user_stack_slow(ptr, ret, 8);
 }
 
-static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
-{
-   if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
-   ((unsigned long)ptr & 3))
-   return -EFAULT;
-
-   pagefault_disable();
-   if (!__get_user_inatomic(*ret, ptr)) {
-   pagefault_enable();
-   return 0;
-   }
-   pagefault_enable();
-
-   return read_user_stack_slow(ptr, ret, 4);
-}
-
 static inline int valid_user_sp(unsigned long sp, int is_64)
 {
if (!sp || (sp & 7) || sp > (is_64 ? TASK_SIZE : 0x1UL) - 32)
@@ -295,6 +279,12 @@ static inline int current_is_64bit(void)
 }
 
 #else  /* CONFIG_PPC64 */
+static int read_user_stack_slow(void __user *ptr, void *buf, int nb)
+{
+   return 0;
+}
+#endif /* CONFIG_PPC64 */
+
 /*
  * On 32-bit we just access the address and let hash_page create a
  * HPTE if necessary, so there is no need to fall back to reading
@@ -313,9 +303,12 @@ static int read_user_stack_32(unsigned int __user *ptr, 
unsigned int *ret)
rc = __get_user_inatomic(*ret, ptr);
pagefault_enable();
 
+   if (IS_ENABLED(CONFIG_PPC64) && rc)
+   return read_user_stack_slow(ptr, ret, 4);
return rc;
 }
 
+#ifndef CONFIG_PPC64
 static inline void perf_callchain_user_64(struct perf_callchain_entry_ctx 
*entry,
  struct pt_regs *regs)
 {
-- 
2.22.0



[PATCH v6 2/6] powerpc: move common register copy functions from signal_32.c to signal.c

2019-08-30 Thread Michal Suchanek
These functions are required for 64bit as well.

Signed-off-by: Michal Suchanek 
---
 arch/powerpc/kernel/signal.c| 141 
 arch/powerpc/kernel/signal_32.c | 140 ---
 2 files changed, 141 insertions(+), 140 deletions(-)

diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index e6c30cee6abf..60436432399f 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -18,12 +18,153 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 
 #include "signal.h"
 
+#ifdef CONFIG_VSX
+unsigned long copy_fpr_to_user(void __user *to,
+  struct task_struct *task)
+{
+   u64 buf[ELF_NFPREG];
+   int i;
+
+   /* save FPR copy to local buffer then write to the thread_struct */
+   for (i = 0; i < (ELF_NFPREG - 1) ; i++)
+   buf[i] = task->thread.TS_FPR(i);
+   buf[i] = task->thread.fp_state.fpscr;
+   return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
+}
+
+unsigned long copy_fpr_from_user(struct task_struct *task,
+void __user *from)
+{
+   u64 buf[ELF_NFPREG];
+   int i;
+
+   if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
+   return 1;
+   for (i = 0; i < (ELF_NFPREG - 1) ; i++)
+   task->thread.TS_FPR(i) = buf[i];
+   task->thread.fp_state.fpscr = buf[i];
+
+   return 0;
+}
+
+unsigned long copy_vsx_to_user(void __user *to,
+  struct task_struct *task)
+{
+   u64 buf[ELF_NVSRHALFREG];
+   int i;
+
+   /* save FPR copy to local buffer then write to the thread_struct */
+   for (i = 0; i < ELF_NVSRHALFREG; i++)
+   buf[i] = task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET];
+   return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
+}
+
+unsigned long copy_vsx_from_user(struct task_struct *task,
+void __user *from)
+{
+   u64 buf[ELF_NVSRHALFREG];
+   int i;
+
+   if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
+   return 1;
+   for (i = 0; i < ELF_NVSRHALFREG ; i++)
+   task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
+   return 0;
+}
+
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+unsigned long copy_ckfpr_to_user(void __user *to,
+ struct task_struct *task)
+{
+   u64 buf[ELF_NFPREG];
+   int i;
+
+   /* save FPR copy to local buffer then write to the thread_struct */
+   for (i = 0; i < (ELF_NFPREG - 1) ; i++)
+   buf[i] = task->thread.TS_CKFPR(i);
+   buf[i] = task->thread.ckfp_state.fpscr;
+   return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
+}
+
+unsigned long copy_ckfpr_from_user(struct task_struct *task,
+ void __user *from)
+{
+   u64 buf[ELF_NFPREG];
+   int i;
+
+   if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
+   return 1;
+   for (i = 0; i < (ELF_NFPREG - 1) ; i++)
+   task->thread.TS_CKFPR(i) = buf[i];
+   task->thread.ckfp_state.fpscr = buf[i];
+
+   return 0;
+}
+
+unsigned long copy_ckvsx_to_user(void __user *to,
+ struct task_struct *task)
+{
+   u64 buf[ELF_NVSRHALFREG];
+   int i;
+
+   /* save FPR copy to local buffer then write to the thread_struct */
+   for (i = 0; i < ELF_NVSRHALFREG; i++)
+   buf[i] = task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET];
+   return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
+}
+
+unsigned long copy_ckvsx_from_user(struct task_struct *task,
+ void __user *from)
+{
+   u64 buf[ELF_NVSRHALFREG];
+   int i;
+
+   if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
+   return 1;
+   for (i = 0; i < ELF_NVSRHALFREG ; i++)
+   task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
+   return 0;
+}
+#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
+#else
+inline unsigned long copy_fpr_to_user(void __user *to,
+ struct task_struct *task)
+{
+   return __copy_to_user(to, task->thread.fp_state.fpr,
+ ELF_NFPREG * sizeof(double));
+}
+
+inline unsigned long copy_fpr_from_user(struct task_struct *task,
+   void __user *from)
+{
+   return __copy_from_user(task->thread.fp_state.fpr, from,
+ ELF_NFPREG * sizeof(double));
+}
+
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+inline unsigned long copy_ckfpr_to_user(void __user *to,
+struct task_struct *task)
+{
+   return __copy_to_user(to, task->thread.ckfp_state.fpr,
+ ELF_NFPREG * sizeof(double));
+}
+
+inline unsigned long copy_ckfp

[PATCH v6 1/6] powerpc: make llseek 32bit-only.

2019-08-30 Thread Michal Suchanek
The llseek syscall is not built in fs/read_write.c when !64bit && !COMPAT
With the syscall marked as common in syscall.tbl build fails in this
case.

The llseek interface does not make sense on 64bit and it is explicitly
described as 32bit interface. Use on 64bit is not well-defined so just
drop it for 64bit.

Fixes: caf6f9c8a326 ("asm-generic: Remove unneeded __ARCH_WANT_SYS_LLSEEK 
macro")
Link: https://lore.kernel.org/lkml/20190828151552.ga16...@infradead.org/
Link: https://lore.kernel.org/lkml/20190829214319.498c7de2@naga/

Signed-off-by: Michal Suchanek 
---
v5: update commit message.
---
 arch/powerpc/kernel/syscalls/syscall.tbl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl 
b/arch/powerpc/kernel/syscalls/syscall.tbl
index 010b9f445586..53e427606f6c 100644
--- a/arch/powerpc/kernel/syscalls/syscall.tbl
+++ b/arch/powerpc/kernel/syscalls/syscall.tbl
@@ -188,7 +188,7 @@
 137common  afs_syscall sys_ni_syscall
 138common  setfsuidsys_setfsuid
 139common  setfsgidsys_setfsgid
-140common  _llseek sys_llseek
+14032  _llseek sys_llseek
 141common  getdentssys_getdents
compat_sys_getdents
 142common  _newselect  sys_select  
compat_sys_select
 143common  flock   sys_flock
-- 
2.22.0



[PATCH v6 0/6] Disable compat cruft on ppc64le v6

2019-08-30 Thread Michal Suchanek
Less code means less bugs so add a knob to skip the compat stuff.

This is tested on ppc64le top of

https://patchwork.ozlabs.org/cover/1153556/

Changes in v2: saner CONFIG_COMPAT ifdefs
Changes in v3:
 - change llseek to 32bit instead of builing it unconditionally in fs
 - clanup the makefile conditionals
 - remove some ifdefs or convert to IS_DEFINED where possible
Changes in v4:
 - cleanup is_32bit_task and current_is_64bit
 - more makefile cleanup
Changes in v5:
 - more current_is_64bit cleanup
 - split off callchain.c 32bit and 64bit parts
Changes in v6:
 - cleanup makefile after split
 - consolidate read_user_stack_32
 - fix some checkpatch warnings

Michal Suchanek (6):
  powerpc: make llseek 32bit-only.
  powerpc: move common register copy functions from signal_32.c to
signal.c
  powerpc/perf: consolidate read_user_stack_32
  powerpc/64: make buildable without CONFIG_COMPAT
  powerpc/64: Make COMPAT user-selectable disabled on littleendian by
default.
  powerpc/perf: split callchain.c by bitness

 arch/powerpc/Kconfig |   5 +-
 arch/powerpc/include/asm/thread_info.h   |   4 +-
 arch/powerpc/kernel/Makefile |   7 +-
 arch/powerpc/kernel/entry_64.S   |   2 +
 arch/powerpc/kernel/signal.c | 144 -
 arch/powerpc/kernel/signal_32.c  | 140 -
 arch/powerpc/kernel/syscall_64.c |   6 +-
 arch/powerpc/kernel/syscalls/syscall.tbl |   2 +-
 arch/powerpc/kernel/vdso.c   |   5 +-
 arch/powerpc/perf/Makefile   |   5 +-
 arch/powerpc/perf/callchain.c| 377 +--
 arch/powerpc/perf/callchain.h|  11 +
 arch/powerpc/perf/callchain_32.c | 204 
 arch/powerpc/perf/callchain_64.c | 185 +++
 14 files changed, 564 insertions(+), 533 deletions(-)
 create mode 100644 arch/powerpc/perf/callchain.h
 create mode 100644 arch/powerpc/perf/callchain_32.c
 create mode 100644 arch/powerpc/perf/callchain_64.c

-- 
2.22.0



Re: [PATCH v2 4/4] powerpc/64: system call implement the bulk of the logic in C

2019-08-30 Thread kbuild test robot
Hi Nicholas,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[cannot apply to v5.3-rc6 next-20190830]
[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/Nicholas-Piggin/powerpc-64-syscalls-in-C/20190828-064221
config: powerpc64-defconfig (attached as .config)
compiler: powerpc64-linux-gcc (GCC) 7.4.0
reproduce:
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=7.4.0 make.cross ARCH=powerpc64 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot 

All errors (new ones prefixed by >>):

   powerpc64-linux-ld: warning: orphan section `.gnu.hash' from `linker stubs' 
being placed in section `.gnu.hash'.
   arch/powerpc/kernel/syscall_64.o: In function `.system_call_exception':
>> syscall_64.c:(.text+0x180): undefined reference to `.tabort_syscall'

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


.config.gz
Description: application/gzip


Re: Oops (request_key_auth_describe) while running cve-2016-7042 from LTP

2019-08-30 Thread David Howells
Can you try this patch instead of Hillf's?

David
---
commit df882ad6d4e24a3763719c1798ea58e87d56c2d7
Author: Hillf Danton 
Date:   Fri Aug 30 15:54:33 2019 +0100

keys: Fix missing null pointer check in request_key_auth_describe()

If a request_key authentication token key gets revoked, there's a window in
which request_key_auth_describe() can see it with a NULL payload - but it
makes no check for this and something like the following oops may occur:

BUG: Kernel NULL pointer dereference at 0x0038
Faulting instruction address: 0xc04ddf30
Oops: Kernel access of bad area, sig: 11 [#1]
...
NIP [...] request_key_auth_describe+0x90/0xd0
LR [...] request_key_auth_describe+0x54/0xd0
Call Trace:
[...] request_key_auth_describe+0x54/0xd0 (unreliable)
[...] proc_keys_show+0x308/0x4c0
[...] seq_read+0x3d0/0x540
[...] proc_reg_read+0x90/0x110
[...] __vfs_read+0x3c/0x70
[...] vfs_read+0xb4/0x1b0
[...] ksys_read+0x7c/0x130
[...] system_call+0x5c/0x70

Fix this by checking for a NULL pointer when describing such a key.

Also make the read routine check for a NULL pointer to be on the safe side.

Fixes: 04c567d9313e ("[PATCH] Keys: Fix race between two instantiators of a 
key")
Reported-by: Sachin Sant 
Signed-off-by: David Howells 

diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index e73ec040e250..ecba39c93fd9 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -66,6 +66,9 @@ static void request_key_auth_describe(const struct key *key,
 {
struct request_key_auth *rka = dereference_key_rcu(key);
 
+   if (!rka)
+   return;
+
seq_puts(m, "key:");
seq_puts(m, key->description);
if (key_is_positive(key))
@@ -83,6 +86,9 @@ static long request_key_auth_read(const struct key *key,
size_t datalen;
long ret;
 
+   if (!rka)
+   return -EKEYREVOKED;
+
datalen = rka->callout_len;
ret = datalen;
 


Re: Oops (request_key_auth_describe) while running cve-2016-7042 from LTP

2019-08-30 Thread David Howells
Hillf Danton  wrote:

> 1, callee has no pre defined duty to help caller in general; they should not
> try to do anything, however, to help their callers in principle due to
> limited info on their hands IMO.

Ah, no.  It's entirely reasonable for an API to specify that one of its
methods will be called with one or more locks held - and that the method must
be aware of this and may make use of this.

> 3, no comment can be found in security/keys/request_key_auth.c about
> the rcu already documented.

There is API documentation in Documentation/security/keys/core.rst.  If you
look at about line 1538 onwards:

  *  ``void (*describe)(const struct key *key, struct seq_file *p);``

 This method is optional. It is called during /proc/keys reading to
 summarise a key's description and payload in text form.

 This method will be called with the RCU read lock held. rcu_dereference()
 should be used to read the payload pointer if the payload is to be
 accessed. key->datalen cannot be trusted to stay consistent with the
 contents of the payload.

 The description will not change, though the key's state may.

 It is not safe to sleep in this method; the RCU read lock is held by the
 caller.

David


Re: [PATCH v5 1/5] kasan: support backing vmalloc space with real shadow memory

2019-08-30 Thread Daniel Axtens
Hi all,

> +static int kasan_depopulate_vmalloc_pte(pte_t *ptep, unsigned long addr,
> + void *unused)
> +{
> + unsigned long page;
> +
> + page = (unsigned long)__va(pte_pfn(*ptep) << PAGE_SHIFT);
> +
> + spin_lock(&init_mm.page_table_lock);
> +
> + /*
> +  * we want to catch bugs where we end up clearing a pte that wasn't
> +  * set. This will unfortunately also fire if we are releasing a region
> +  * where we had a failure allocating the shadow region.
> +  */
> + WARN_ON_ONCE(pte_none(*ptep));
> +
> + pte_clear(&init_mm, addr, ptep);
> + free_page(page);
> + spin_unlock(&init_mm.page_table_lock);

It's just occurred to me that the free_page really needs to be guarded
by an 'if (likely(!pte_none(*pte))) {' - there won't be a page to free
if there's no pte.

I'll spin v6 on Monday.

Regards,
Daniel

> +
> + return 0;
> +}
> +
> +/*
> + * Release the backing for the vmalloc region [start, end), which
> + * lies within the free region [free_region_start, free_region_end).
> + *
> + * This can be run lazily, long after the region was freed. It runs
> + * under vmap_area_lock, so it's not safe to interact with the vmalloc/vmap
> + * infrastructure.
> + */
> +void kasan_release_vmalloc(unsigned long start, unsigned long end,
> +unsigned long free_region_start,
> +unsigned long free_region_end)
> +{
> + void *shadow_start, *shadow_end;
> + unsigned long region_start, region_end;
> +
> + /* we start with shadow entirely covered by this region */
> + region_start = ALIGN(start, PAGE_SIZE * KASAN_SHADOW_SCALE_SIZE);
> + region_end = ALIGN_DOWN(end, PAGE_SIZE * KASAN_SHADOW_SCALE_SIZE);
> +
> + /*
> +  * We don't want to extend the region we release to the entire free
> +  * region, as the free region might cover huge chunks of vmalloc space
> +  * where we never allocated anything. We just want to see if we can
> +  * extend the [start, end) range: if start or end fall part way through
> +  * a shadow page, we want to check if we can free that entire page.
> +  */
> +
> + free_region_start = ALIGN(free_region_start,
> +   PAGE_SIZE * KASAN_SHADOW_SCALE_SIZE);
> +
> + if (start != region_start &&
> + free_region_start < region_start)
> + region_start -= PAGE_SIZE * KASAN_SHADOW_SCALE_SIZE;
> +
> + free_region_end = ALIGN_DOWN(free_region_end,
> +  PAGE_SIZE * KASAN_SHADOW_SCALE_SIZE);
> +
> + if (end != region_end &&
> + free_region_end > region_end)
> + region_end += PAGE_SIZE * KASAN_SHADOW_SCALE_SIZE;
> +
> + shadow_start = kasan_mem_to_shadow((void *)region_start);
> + shadow_end = kasan_mem_to_shadow((void *)region_end);
> +
> + if (shadow_end > shadow_start)
> + apply_to_page_range(&init_mm, (unsigned long)shadow_start,
> + (unsigned long)(shadow_end - shadow_start),
> + kasan_depopulate_vmalloc_pte, NULL);
> +}
> +#endif
> diff --git a/mm/kasan/generic_report.c b/mm/kasan/generic_report.c
> index 36c645939bc9..2d97efd4954f 100644
> --- a/mm/kasan/generic_report.c
> +++ b/mm/kasan/generic_report.c
> @@ -86,6 +86,9 @@ static const char *get_shadow_bug_type(struct 
> kasan_access_info *info)
>   case KASAN_ALLOCA_RIGHT:
>   bug_type = "alloca-out-of-bounds";
>   break;
> + case KASAN_VMALLOC_INVALID:
> + bug_type = "vmalloc-out-of-bounds";
> + break;
>   }
>  
>   return bug_type;
> diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
> index 35cff6bbb716..3a083274628e 100644
> --- a/mm/kasan/kasan.h
> +++ b/mm/kasan/kasan.h
> @@ -25,6 +25,7 @@
>  #endif
>  
>  #define KASAN_GLOBAL_REDZONE0xFA  /* redzone for global variable */
> +#define KASAN_VMALLOC_INVALID   0xF9  /* unallocated space in vmapped page */
>  
>  /*
>   * Stack redzone shadow values
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index b8101030f79e..bf806566cad0 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -690,8 +690,19 @@ merge_or_add_vmap_area(struct vmap_area *va,
>   struct list_head *next;
>   struct rb_node **link;
>   struct rb_node *parent;
> + unsigned long orig_start, orig_end;
>   bool merged = false;
>  
> + /*
> +  * To manage KASAN vmalloc memory usage, we use this opportunity to
> +  * clean up the shadow memory allocated to back this allocation.
> +  * Because a vmalloc shadow page covers several pages, the start or end
> +  * of an allocation might not align with a shadow page. Use the merging
> +  * opportunities to try to extend the region we can release.
> +  */
> + orig_start = va->va_start;
> + orig_end = va->va_end;
> +
>   /*
>* Find a place in the tree where VA potentially will be
>* inserted

Re: Oops (request_key_auth_describe) while running cve-2016-7042 from LTP

2019-08-30 Thread David Howells
Hillf Danton  wrote:

> - struct request_key_auth *rka = dereference_key_rcu(key);
> + struct request_key_auth *rka;
> +
> + rcu_read_lock();
> + rka = dereference_key_rcu(key);

This shouldn't help as the caller, proc_keys_show(), is holding the RCU read
lock across the call.  The end of the function reads:

if (key->type->describe)
key->type->describe(key, m);
seq_putc(m, '\n');

rcu_read_unlock();
return 0;
}

and the documentation says "This method will be called with the RCU read lock
held".

I suspect the actual bugfix is this bit:

> + if (!rka)
> + goto out;

David


[PATCH 3/3] powerpc/mm: call H_BLOCK_REMOVE when supported

2019-08-30 Thread Laurent Dufour
Instead of calling H_BLOCK_REMOVE all the time when the feature is
exhibited, call this hcall only when the couple base page size, page size
is supported as reported by the TLB Invalidate Characteristics.

For regular pages and hugetlb, the assumption is made that the page size is
equal to the base page size. For THP the page size is assumed to be 16M.

Signed-off-by: Laurent Dufour 
---
 arch/powerpc/platforms/pseries/lpar.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/lpar.c 
b/arch/powerpc/platforms/pseries/lpar.c
index 375e19b3cf53..ef3dbf108a65 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -1143,7 +1143,11 @@ static inline void 
__pSeries_lpar_hugepage_invalidate(unsigned long *slot,
if (lock_tlbie)
spin_lock_irqsave(&pSeries_lpar_tlbie_lock, flags);
 
-   if (firmware_has_feature(FW_FEATURE_BLOCK_REMOVE))
+   /*
+* Assuming THP size is 16M, and we only support 8 bytes size buffer
+* for the momment.
+*/
+   if (mmu_psize_defs[psize].hblk[MMU_PAGE_16M] == 8)
hugepage_block_invalidate(slot, vpn, count, psize, ssize);
else
hugepage_bulk_invalidate(slot, vpn, count, psize, ssize);
@@ -1437,7 +1441,10 @@ static void pSeries_lpar_flush_hash_range(unsigned long 
number, int local)
if (lock_tlbie)
spin_lock_irqsave(&pSeries_lpar_tlbie_lock, flags);
 
-   if (firmware_has_feature(FW_FEATURE_BLOCK_REMOVE)) {
+   /*
+* Currently, we only support 8 bytes size buffer in do_block_remove().
+*/
+   if (mmu_psize_defs[batch->psize].hblk[batch->psize] == 8) {
do_block_remove(number, batch, param);
goto out;
}
-- 
2.23.0



[PATCH 2/3] powperc/mm: read TLB Block Invalidate Characteristics

2019-08-30 Thread Laurent Dufour
The PAPR document specifies the TLB Block Invalidate Characteristics which
is telling which couple base page size / page size is supported by the
H_BLOCK_REMOVE hcall.

A new set of feature is added to the mmu_psize_def structure to record per
base page size which page size is supported by H_BLOCK_REMOVE.

A new init service is added to read the characteristics. The size of the
buffer is set to twice the number of known page size, plus 10 bytes to
ensure we have enough place.

Signed-off-by: Laurent Dufour 
---
 arch/powerpc/include/asm/book3s/64/mmu.h |   3 +
 arch/powerpc/platforms/pseries/lpar.c| 107 +++
 2 files changed, 110 insertions(+)

diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h 
b/arch/powerpc/include/asm/book3s/64/mmu.h
index 23b83d3593e2..675895dfe39f 100644
--- a/arch/powerpc/include/asm/book3s/64/mmu.h
+++ b/arch/powerpc/include/asm/book3s/64/mmu.h
@@ -12,11 +12,14 @@
  *sllp  : is a bit mask with the value of SLB L || LP to be or'ed
  *directly to a slbmte "vsid" value
  *penc  : is the HPTE encoding mask for the "LP" field:
+ *hblk  : H_BLOCK_REMOVE supported block size for this page size in
+ *segment who's base page size is that page size.
  *
  */
 struct mmu_psize_def {
unsigned intshift;  /* number of bits */
int penc[MMU_PAGE_COUNT];   /* HPTE encoding */
+   int hblk[MMU_PAGE_COUNT];   /* H_BLOCK_REMOVE support */
unsigned inttlbiel; /* tlbiel supported for that page size */
unsigned long   avpnm;  /* bits to mask out in AVPN in the HPTE */
union {
diff --git a/arch/powerpc/platforms/pseries/lpar.c 
b/arch/powerpc/platforms/pseries/lpar.c
index 4f76e5f30c97..375e19b3cf53 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -1311,6 +1311,113 @@ static void do_block_remove(unsigned long number, 
struct ppc64_tlb_batch *batch,
(void)call_block_remove(pix, param, true);
 }
 
+static inline void __init set_hblk_bloc_size(int bpsize, int psize,
+unsigned int block_size)
+{
+   struct mmu_psize_def *def = &mmu_psize_defs[bpsize];
+
+   if (block_size > def->hblk[psize])
+   def->hblk[psize] = block_size;
+}
+
+static inline void __init check_lp_set_hblk(unsigned int lp,
+   unsigned int block_size)
+{
+   unsigned int bpsize, psize;
+
+
+   /* First, check the L bit, if not set, this means 4K */
+   if ((lp & 0x80) == 0) {
+   set_hblk_bloc_size(MMU_PAGE_4K, MMU_PAGE_4K, block_size);
+   return;
+   }
+
+   /* PAPR says to look at bits 2-7 (0 = MSB) */
+   lp &= 0x3f;
+   for (bpsize = 0; bpsize < MMU_PAGE_COUNT; bpsize++) {
+   struct mmu_psize_def *def =  &mmu_psize_defs[bpsize];
+
+   for (psize = 0; psize < MMU_PAGE_COUNT; psize++) {
+   if (def->penc[psize] == lp) {
+   set_hblk_bloc_size(bpsize, psize, block_size);
+   return;
+   }
+   }
+   }
+}
+
+#define SPLPAR_TLB_BIC_TOKEN   50
+#define SPLPAR_TLB_BIC_MAXLENGTH   (MMU_PAGE_COUNT*2 + 10)
+static int __init read_tlbbi_characteristics(void)
+{
+   int call_status;
+   unsigned char local_buffer[SPLPAR_TLB_BIC_MAXLENGTH];
+   int len, idx, bpsize;
+
+   if (!firmware_has_feature(FW_FEATURE_BLOCK_REMOVE)) {
+   pr_info("H_BLOCK_REMOVE is not supported");
+   return 0;
+   }
+
+   memset(local_buffer, 0, SPLPAR_TLB_BIC_MAXLENGTH);
+
+   spin_lock(&rtas_data_buf_lock);
+   memset(rtas_data_buf, 0, RTAS_DATA_BUF_SIZE);
+   call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
+   NULL,
+   SPLPAR_TLB_BIC_TOKEN,
+   __pa(rtas_data_buf),
+   RTAS_DATA_BUF_SIZE);
+   memcpy(local_buffer, rtas_data_buf, SPLPAR_TLB_BIC_MAXLENGTH);
+   local_buffer[SPLPAR_TLB_BIC_MAXLENGTH - 1] = '\0';
+   spin_unlock(&rtas_data_buf_lock);
+
+   if (call_status != 0) {
+   pr_warn("%s %s Error calling get-system-parameter (0x%x)\n",
+   __FILE__, __func__, call_status);
+   return 0;
+   }
+
+   /*
+* The first two (2) bytes of the data in the buffer are the length of
+* the returned data, not counting these first two (2) bytes.
+*/
+   len = local_buffer[0] * 256 + local_buffer[1] + 2;
+   if (len >= SPLPAR_TLB_BIC_MAXLENGTH) {
+   pr_warn("%s too large returned buffer %d", __func__, len);
+   return 0;
+   }
+
+   idx = 2;
+   while (idx < len) {
+   unsigned int block_size = local_buffer[idx++];
+   unsigned int np

[PATCH 1/3] powerpc/mm: Initialize the HPTE encoding values

2019-08-30 Thread Laurent Dufour
Before reading the HPTE encoding values we initialize all of them to -1 (an
invalid value) to later being able to detect the initialized ones.

Signed-off-by: Laurent Dufour 
---
 arch/powerpc/mm/book3s64/hash_utils.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/mm/book3s64/hash_utils.c 
b/arch/powerpc/mm/book3s64/hash_utils.c
index c3bfef08dcf8..2039bc315459 100644
--- a/arch/powerpc/mm/book3s64/hash_utils.c
+++ b/arch/powerpc/mm/book3s64/hash_utils.c
@@ -408,7 +408,7 @@ static int __init htab_dt_scan_page_sizes(unsigned long 
node,
 {
const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
const __be32 *prop;
-   int size = 0;
+   int size = 0, idx, base_idx;
 
/* We are scanning "cpu" nodes only */
if (type == NULL || strcmp(type, "cpu") != 0)
@@ -418,6 +418,11 @@ static int __init htab_dt_scan_page_sizes(unsigned long 
node,
if (!prop)
return 0;
 
+   /* Set all the penc values to invalid */
+   for (base_idx = 0; base_idx < MMU_PAGE_COUNT; base_idx++)
+   for (idx = 0; idx < MMU_PAGE_COUNT; idx++)
+   mmu_psize_defs[base_idx].penc[idx] = -1;
+
pr_info("Page sizes from device-tree:\n");
size /= 4;
cur_cpu_spec->mmu_features &= ~(MMU_FTR_16M_PAGE);
@@ -426,7 +431,6 @@ static int __init htab_dt_scan_page_sizes(unsigned long 
node,
unsigned int slbenc = be32_to_cpu(prop[1]);
unsigned int lpnum = be32_to_cpu(prop[2]);
struct mmu_psize_def *def;
-   int idx, base_idx;
 
size -= 3; prop += 3;
base_idx = get_idx_from_shift(base_shift);
-- 
2.23.0



[PATCH 0/3] powerpc/mm: Conditionally call H_BLOCK_REMOVE

2019-08-30 Thread Laurent Dufour
Since the commit ba2dd8a26baa ("powerpc/pseries/mm: call H_BLOCK_REMOVE"),
the call to H_BLOCK_REMOVE is always done if the feature is exhibited.

On some system, the hypervisor may not support all the combination of
segment base page size and page size. When this happens the hcall is
returning H_PARAM, which is triggering a BUG_ON check leading to a panic.

The PAPR document is specifying a TLB Block Invalidate Characteristics item
detailing which couple base page size, page size the hypervisor is
supporting through H_BLOCK_REMOVE. Furthermore, the characteristics are
also providing the size of the block the hcall could process.

Supporting various block size seems not needed as all systems I was able to
play with was support an 8 addresses block size, which is the maximum
through the hcall. Supporting various size may complexify the algorithm in
call_block_remove() so unless this is required, this is not done.

In the case of block size different from 8, a warning message is displayed
at boot time and that block size will be ignored checking for the
H_BLOCK_REMOVE support.

Due to the minimal amount of hardware showing a limited set of
H_BLOCK_REMOVE supported page size, I don't think there is a need to push
this series to the stable mailing list.

The first patch is initializing the penc values for each page size to an
invalid value to be able to detect those which have been initialized as 0
is a valid value.

The second patch is reading the characteristic through the hcall
ibm,get-system-parameter and record the supported block size for each page
size.

The third patch is changing the check used to detect the H_BLOCK_REMOVE
availability to take care of the base page size and page size couple.

Laurent Dufour (3):
  powerpc/mm: Initialize the HPTE encoding values
  powperc/mm: read TLB Block Invalidate Characteristics
  powerpc/mm: call H_BLOCK_REMOVE when supported

 arch/powerpc/include/asm/book3s/64/mmu.h |   3 +
 arch/powerpc/mm/book3s64/hash_utils.c|   8 +-
 arch/powerpc/platforms/pseries/lpar.c| 118 ++-
 3 files changed, 125 insertions(+), 4 deletions(-)

-- 
2.23.0



Applied "ASoC: fsl_ssi: Fix clock control issue in master mode" to the asoc tree

2019-08-30 Thread Mark Brown
The patch

   ASoC: fsl_ssi: Fix clock control issue in master mode

has been applied to the asoc tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.3

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 696d05225cebffd172008d212657be90e823eac0 Mon Sep 17 00:00:00 2001
From: Shengjiu Wang 
Date: Wed, 28 Aug 2019 13:20:17 -0400
Subject: [PATCH] ASoC: fsl_ssi: Fix clock control issue in master mode

The test case is
arecord -Dhw:0 -d 10 -f S16_LE -r 48000 -c 2 temp.wav &
aplay -Dhw:0 -d 30 -f S16_LE -r 48000 -c 2 test.wav

There will be error after end of arecord:
aplay: pcm_write:2051: write error: Input/output error

Capture and Playback work in parallel in master mode, one
substream stops, the other substream is impacted, the
reason is that clock is disabled wrongly.

The clock's reference count is not increased when second
substream starts, the hw_param() function returns in the
beginning because first substream is enabled, then in end
of first substream, the hw_free() disables the clock.

This patch is to move the clock enablement to the place
before checking of the device enablement in hw_param().

Signed-off-by: Shengjiu Wang 
Link: 
https://lore.kernel.org/r/1567012817-12625-1-git-send-email-shengjiu.w...@nxp.com
Signed-off-by: Mark Brown 
---
 sound/soc/fsl/fsl_ssi.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index fa862af25c1a..085855f9b08d 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -799,15 +799,6 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream 
*substream,
u32 wl = SSI_SxCCR_WL(sample_size);
int ret;
 
-   /*
-* SSI is properly configured if it is enabled and running in
-* the synchronous mode; Note that AC97 mode is an exception
-* that should set separate configurations for STCCR and SRCCR
-* despite running in the synchronous mode.
-*/
-   if (ssi->streams && ssi->synchronous)
-   return 0;
-
if (fsl_ssi_is_i2s_master(ssi)) {
ret = fsl_ssi_set_bclk(substream, dai, hw_params);
if (ret)
@@ -823,6 +814,15 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream 
*substream,
}
}
 
+   /*
+* SSI is properly configured if it is enabled and running in
+* the synchronous mode; Note that AC97 mode is an exception
+* that should set separate configurations for STCCR and SRCCR
+* despite running in the synchronous mode.
+*/
+   if (ssi->streams && ssi->synchronous)
+   return 0;
+
if (!fsl_ssi_is_ac97(ssi)) {
/*
 * Keep the ssi->i2s_net intact while having a local variable
-- 
2.20.1



Re: [PATCH v7 1/7] kvmppc: Driver to manage pages of secure guest

2019-08-30 Thread Bharata B Rao
On Thu, Aug 29, 2019 at 12:39:11PM -0700, Sukadev Bhattiprolu wrote:
> Bharata B Rao [bhar...@linux.ibm.com] wrote:
> > On Wed, Aug 28, 2019 at 08:02:19PM -0700, Sukadev Bhattiprolu wrote:
> Where do we serialize two threads attempting to H_SVM_PAGE_IN the same gfn
> at the same time? Or one thread issuing a H_SVM_PAGE_IN and another a
> H_SVM_PAGE_OUT for the same page?

I am not not serializing page-in/out calls on same gfn, I thought you take
care of that in UV, guess UV doesn't yet.

I can probably use rmap_lock() and serialize such calls in HV if UV can't
prevent such calls easily.

> > > > +
> > > > +   if (!trylock_page(dpage))
> > > > +   goto out_clear;
> > > > +
> > > > +   *rmap = devm_pfn | KVMPPC_RMAP_DEVM_PFN;
> > > > +   pvt = kzalloc(sizeof(*pvt), GFP_ATOMIC);
> > > > +   if (!pvt)
> > > > +   goto out_unlock;
> 
> If we fail to alloc, we don't clear the KVMPPC_RMAP_DEVM_PFN?

Right, I will move the assignment to *rmap to after kzalloc.

> 
> Also, when/where do we clear this flag on an uv-page-out?
> kvmppc_devm_drop_pages() drops the flag on a local variable but not
> in the rmap? If we don't clear the flag on page-out, would the
> subsequent H_SVM_PAGE_IN of this page fail?

It gets cleared in kvmppc_devm_page_free().

> 
> Ok. Nit. thought we can drop the "_fault" in the function name but would
> collide the other "alloc_and_copy" function used during H_SVM_PAGE_IN.
> If the two alloc_and_copy functions are symmetric, maybe they could
> have "page_in" and "page_out" in the (already long) names.

Christoph also suggested to reorganize these two calls. Will take care.

Regards,
Bharata.



Re: Oops (request_key_auth_describe) while running cve-2016-7042 from LTP

2019-08-30 Thread Sachin Sant



> On 30-Aug-2019, at 2:26 PM, Hillf Danton  wrote:
> 
> 
> On Fri, 30 Aug 2019 12:18:07 +0530 Sachin Sant wrote:
>> 
>> [ 8074.351033] BUG: Kernel NULL pointer dereference at 0x0038
>> [ 8074.351046] Faulting instruction address: 0xc04ddf30
>> [ 8074.351052] Oops: Kernel access of bad area, sig: 11 [#1]
>> [ 8074.351056] LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries
> 
> Add rcu gp.
> 
> --- a/security/keys/request_key_auth.c
> +++ b/security/keys/request_key_auth.c
> @@ -64,12 +64,19 @@ static int request_key_auth_instantiate(
> static void request_key_auth_describe(const struct key *key,
> struct seq_file *m)
> {
> - struct request_key_auth *rka = dereference_key_rcu(key);
> + struct request_key_auth *rka;
> +
> + rcu_read_lock();
> + rka = dereference_key_rcu(key);
> + if (!rka)
> + goto out;
> 

Thanks for the patch. Works for me. Test ran fine without any problems.

Tested-by: Sachin Sant 

Thanks
-Sachin



[PATCH v4 3/8] mm/memory_hotplug: Shrink zones when offlining memory

2019-08-30 Thread David Hildenbrand
We currently try to shrink a single zone when removing memory. We use the
zone of the first page of the memory we are removing. If that memmap was
never initialized (e.g., memory was never onlined), we will read garbage
and can trigger kernel BUGs (due to a stale pointer):

:/# [   23.912993] BUG: unable to handle page fault for address: 
353d
[   23.914219] #PF: supervisor write access in kernel mode
[   23.915199] #PF: error_code(0x0002) - not-present page
[   23.916160] PGD 0 P4D 0
[   23.916627] Oops: 0002 [#1] SMP PTI
[   23.917256] CPU: 1 PID: 7 Comm: kworker/u8:0 Not tainted 
5.3.0-rc5-next-20190820+ #317
[   23.918900] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.4
[   23.921194] Workqueue: kacpi_hotplug acpi_hotplug_work_fn
[   23.922249] RIP: 0010:clear_zone_contiguous+0x5/0x10
[   23.923173] Code: 48 89 c6 48 89 c3 e8 2a fe ff ff 48 85 c0 75 cf 5b 5d c3 
c6 85 fd 05 00 00 01 5b 5d c3 0f 1f 840
[   23.926876] RSP: 0018:ad2400043c98 EFLAGS: 00010246
[   23.927928] RAX:  RBX: 0002 RCX: 
[   23.929458] RDX: 0020 RSI: 0014 RDI: 2f40
[   23.930899] RBP: 00014000 R08:  R09: 0001
[   23.932362] R10:  R11:  R12: 0014
[   23.933603] R13: 0014 R14: 2f40 R15: 9e3e7aff3680
[   23.934913] FS:  () GS:9e3e7bb0() 
knlGS:
[   23.936294] CS:  0010 DS:  ES:  CR0: 80050033
[   23.937481] CR2: 353d CR3: 5861 CR4: 06e0
[   23.938687] DR0:  DR1:  DR2: 
[   23.939889] DR3:  DR6: fffe0ff0 DR7: 0400
[   23.941168] Call Trace:
[   23.941580]  __remove_pages+0x4b/0x640
[   23.942303]  ? mark_held_locks+0x49/0x70
[   23.943149]  arch_remove_memory+0x63/0x8d
[   23.943921]  try_remove_memory+0xdb/0x130
[   23.944766]  ? walk_memory_blocks+0x7f/0x9e
[   23.945616]  __remove_memory+0xa/0x11
[   23.946274]  acpi_memory_device_remove+0x70/0x100
[   23.947308]  acpi_bus_trim+0x55/0x90
[   23.947914]  acpi_device_hotplug+0x227/0x3a0
[   23.948714]  acpi_hotplug_work_fn+0x1a/0x30
[   23.949433]  process_one_work+0x221/0x550
[   23.950190]  worker_thread+0x50/0x3b0
[   23.950993]  kthread+0x105/0x140
[   23.951644]  ? process_one_work+0x550/0x550
[   23.952508]  ? kthread_park+0x80/0x80
[   23.953367]  ret_from_fork+0x3a/0x50
[   23.954025] Modules linked in:
[   23.954613] CR2: 353d
[   23.955248] ---[ end trace 93d982b1fb3e1a69 ]---

Instead, shrink the zones when offlining memory or when onlining failed.
Introduce and use remove_pfn_range_from_zone(() for that. We now properly
shrink the zones, even if we have DIMMs whereby
- Some memory blocks fall into no zone (never onlined)
- Some memory blocks fall into multiple zones (offlined+re-onlined)
- Multiple memory blocks that fall into different zones

Drop the zone parameter (with a potential dubious value) from
__remove_pages() and __remove_section().

Cc: Catalin Marinas 
Cc: Will Deacon 
Cc: Tony Luck 
Cc: Fenghua Yu 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: Michael Ellerman 
Cc: Heiko Carstens 
Cc: Vasily Gorbik 
Cc: Christian Borntraeger 
Cc: Yoshinori Sato 
Cc: Rich Felker 
Cc: Dave Hansen 
Cc: Andy Lutomirski 
Cc: Peter Zijlstra 
Cc: Thomas Gleixner 
Cc: Ingo Molnar 
Cc: Borislav Petkov 
Cc: "H. Peter Anvin" 
Cc: x...@kernel.org
Cc: Andrew Morton 
Cc: Mark Rutland 
Cc: Steve Capper 
Cc: Mike Rapoport 
Cc: Anshuman Khandual 
Cc: Yu Zhao 
Cc: Jun Yao 
Cc: Robin Murphy 
Cc: Michal Hocko 
Cc: Oscar Salvador 
Cc: "Matthew Wilcox (Oracle)" 
Cc: Christophe Leroy 
Cc: "Aneesh Kumar K.V" 
Cc: Pavel Tatashin 
Cc: Gerald Schaefer 
Cc: Halil Pasic 
Cc: Tom Lendacky 
Cc: Greg Kroah-Hartman 
Cc: Masahiro Yamada 
Cc: Dan Williams 
Cc: Wei Yang 
Cc: Qian Cai 
Cc: Jason Gunthorpe 
Cc: Logan Gunthorpe 
Cc: Ira Weiny 
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-i...@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-s...@vger.kernel.org
Cc: linux...@vger.kernel.org
Fixes: d0dc12e86b31 ("mm/memory_hotplug: optimize memory hotplug")
Signed-off-by: David Hildenbrand 
---
 arch/arm64/mm/mmu.c|  4 +---
 arch/ia64/mm/init.c|  4 +---
 arch/powerpc/mm/mem.c  |  3 +--
 arch/s390/mm/init.c|  4 +---
 arch/sh/mm/init.c  |  4 +---
 arch/x86/mm/init_32.c  |  4 +---
 arch/x86/mm/init_64.c  |  4 +---
 include/linux/memory_hotplug.h |  7 +--
 mm/memory_hotplug.c| 31 ---
 mm/memremap.c  |  3 +--
 10 files changed, 29 insertions(+), 39 deletions(-)

diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 60c929f3683b..d10247fab0fd 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -1069,7 +10

Re: Oops (request_key_auth_describe) while running cve-2016-7042 from LTP

2019-08-30 Thread Hillf Danton


On Fri, 30 Aug 2019 12:18:07 +0530 Sachin Sant wrote:
> 
> [ 8074.351033] BUG: Kernel NULL pointer dereference at 0x0038
> [ 8074.351046] Faulting instruction address: 0xc04ddf30
> [ 8074.351052] Oops: Kernel access of bad area, sig: 11 [#1]
> [ 8074.351056] LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries

Add rcu gp.

--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -64,12 +64,19 @@ static int request_key_auth_instantiate(
 static void request_key_auth_describe(const struct key *key,
  struct seq_file *m)
 {
-   struct request_key_auth *rka = dereference_key_rcu(key);
+   struct request_key_auth *rka;
+
+   rcu_read_lock();
+   rka = dereference_key_rcu(key);
+   if (!rka)
+   goto out;
 
seq_puts(m, "key:");
seq_puts(m, key->description);
if (key_is_positive(key))
seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len);
+out:
+   rcu_read_unlock();
 }
 
 /*



Re: [PATCH -next] crypto: nx - remove unused variables 'nx_driver_string' and 'nx_driver_version'

2019-08-30 Thread Herbert Xu
On Thu, Aug 22, 2019 at 10:46:49PM +0800, YueHaibing wrote:
> drivers/crypto/nx/nx.h:12:19: warning:
>  nx_driver_string defined but not used [-Wunused-const-variable=]
> drivers/crypto/nx/nx.h:13:19: warning:
>  nx_driver_version defined but not used [-Wunused-const-variable=]
> 
> They are never used, so just remove it.
> 
> Reported-by: Hulk Robot 
> Signed-off-by: YueHaibing 
> ---
>  drivers/crypto/nx/nx.h | 3 ---
>  1 file changed, 3 deletions(-)

Patch applied.  Thanks.
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [PATCH v5 3/5] powerpc/64: make buildable without CONFIG_COMPAT

2019-08-30 Thread Christophe Leroy




Le 30/08/2019 à 09:54, Michal Suchánek a écrit :

On Fri, 30 Aug 2019 06:35:13 + (UTC)
Christophe Leroy  wrote:


On 08/29/2019 10:28 PM, Michal Suchanek wrote:

There are numerous references to 32bit functions in generic and 64bit
code so ifdef them out.

Signed-off-by: Michal Suchanek 
---
v2:
- fix 32bit ifdef condition in signal.c
- simplify the compat ifdef condition in vdso.c - 64bit is redundant
- simplify the compat ifdef condition in callchain.c - 64bit is redundant
v3:
- use IS_ENABLED and maybe_unused where possible
- do not ifdef declarations
- clean up Makefile
v4:
- further makefile cleanup
- simplify is_32bit_task conditions
- avoid ifdef in condition by using return
v5:
- avoid unreachable code on 32bit
- make is_current_64bit constant on !COMPAT
- add stub perf_callchain_user_32 to avoid some ifdefs
---
   arch/powerpc/include/asm/thread_info.h |  4 ++--
   arch/powerpc/kernel/Makefile   |  7 +++
   arch/powerpc/kernel/entry_64.S |  2 ++
   arch/powerpc/kernel/signal.c   |  3 +--
   arch/powerpc/kernel/syscall_64.c   |  6 ++
   arch/powerpc/kernel/vdso.c |  5 ++---
   arch/powerpc/perf/callchain.c  | 13 +++--
   7 files changed, 23 insertions(+), 17 deletions(-)
   

[...]


diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
index c84bbd4298a0..881be5c4e9bb 100644
--- a/arch/powerpc/perf/callchain.c
+++ b/arch/powerpc/perf/callchain.c
@@ -15,7 +15,7 @@
   #include 
   #include 
   #include 
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_COMPAT
   #include "../kernel/ppc32.h"
   #endif
   #include 
@@ -291,7 +291,8 @@ static inline int current_is_64bit(void)
 * interrupt stack, and the thread flags don't get copied over
 * from the thread_info on the main stack to the interrupt stack.
 */
-   return !test_ti_thread_flag(task_thread_info(current), TIF_32BIT);
+   return !IS_ENABLED(CONFIG_COMPAT) ||
+   !test_ti_thread_flag(task_thread_info(current), TIF_32BIT);
   }
   
   #else  /* CONFIG_PPC64 */

@@ -341,6 +342,7 @@ static inline int valid_user_sp(unsigned long sp, int is_64)
   
   #endif /* CONFIG_PPC64 */
   
+#if defined(CONFIG_PPC32) || defined(CONFIG_COMPAT)

   /*
* Layout for non-RT signal frames
*/
@@ -482,6 +484,13 @@ static void perf_callchain_user_32(struct 
perf_callchain_entry_ctx *entry,
sp = next_sp;
}
   }
+#else /* 32bit */
+static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
+  struct pt_regs *regs)
+{
+   (void)&read_user_stack_32; /* unused if !COMPAT */


That looks pretty much like a hack.

See possible alternative below.


+}
+#endif /* 32bit */
   
   void

   perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs 
*regs)
   


---
  arch/powerpc/perf/callchain.c | 62 +++
  1 file changed, 27 insertions(+), 35 deletions(-)

diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
index 881be5c4e9bb..1b169b32776a 100644
--- a/arch/powerpc/perf/callchain.c
+++ b/arch/powerpc/perf/callchain.c
@@ -165,22 +165,6 @@ static int read_user_stack_64(unsigned long __user *ptr, 
unsigned long *ret)
return read_user_stack_slow(ptr, ret, 8);
  }
  
-static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)

-{
-   if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
-   ((unsigned long)ptr & 3))
-   return -EFAULT;
-
-   pagefault_disable();
-   if (!__get_user_inatomic(*ret, ptr)) {
-   pagefault_enable();
-   return 0;
-   }
-   pagefault_enable();
-
-   return read_user_stack_slow(ptr, ret, 4);
-}
-
  static inline int valid_user_sp(unsigned long sp, int is_64)
  {
if (!sp || (sp & 7) || sp > (is_64 ? TASK_SIZE : 0x1UL) - 32)
@@ -296,25 +280,10 @@ static inline int current_is_64bit(void)
  }
  
  #else  /* CONFIG_PPC64 */

-/*
- * On 32-bit we just access the address and let hash_page create a
- * HPTE if necessary, so there is no need to fall back to reading
- * the page tables.  Since this is called at interrupt level,
- * do_page_fault() won't treat a DSI as a page fault.
- */
-static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
-{
-   int rc;
-
-   if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
-   ((unsigned long)ptr & 3))
-   return -EFAULT;
  
-	pagefault_disable();

-   rc = __get_user_inatomic(*ret, ptr);
-   pagefault_enable();
-
-   return rc;
+static int read_user_stack_slow(void __user *ptr, void *buf, int nb)
+{
+   return 0;



Here it is



  }
  
  static inline void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,

@@ -344,6 +313,30 @@ static inline int valid_user_sp(unsigned long sp, int 
is_64)
  
  #if defined(CONFIG_PPC32) || defined(CONFIG_COMPAT)

  

Re: [PATCH v5 3/5] powerpc/64: make buildable without CONFIG_COMPAT

2019-08-30 Thread Michal Suchánek
On Fri, 30 Aug 2019 06:35:13 + (UTC)
Christophe Leroy  wrote:

> On 08/29/2019 10:28 PM, Michal Suchanek wrote:
> > There are numerous references to 32bit functions in generic and 64bit
> > code so ifdef them out.
> > 
> > Signed-off-by: Michal Suchanek 
> > ---
> > v2:
> > - fix 32bit ifdef condition in signal.c
> > - simplify the compat ifdef condition in vdso.c - 64bit is redundant
> > - simplify the compat ifdef condition in callchain.c - 64bit is redundant
> > v3:
> > - use IS_ENABLED and maybe_unused where possible
> > - do not ifdef declarations
> > - clean up Makefile
> > v4:
> > - further makefile cleanup
> > - simplify is_32bit_task conditions
> > - avoid ifdef in condition by using return
> > v5:
> > - avoid unreachable code on 32bit
> > - make is_current_64bit constant on !COMPAT
> > - add stub perf_callchain_user_32 to avoid some ifdefs
> > ---
> >   arch/powerpc/include/asm/thread_info.h |  4 ++--
> >   arch/powerpc/kernel/Makefile   |  7 +++
> >   arch/powerpc/kernel/entry_64.S |  2 ++
> >   arch/powerpc/kernel/signal.c   |  3 +--
> >   arch/powerpc/kernel/syscall_64.c   |  6 ++
> >   arch/powerpc/kernel/vdso.c |  5 ++---
> >   arch/powerpc/perf/callchain.c  | 13 +++--
> >   7 files changed, 23 insertions(+), 17 deletions(-)
> >   
> [...]
> 
> > diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
> > index c84bbd4298a0..881be5c4e9bb 100644
> > --- a/arch/powerpc/perf/callchain.c
> > +++ b/arch/powerpc/perf/callchain.c
> > @@ -15,7 +15,7 @@
> >   #include 
> >   #include 
> >   #include 
> > -#ifdef CONFIG_PPC64
> > +#ifdef CONFIG_COMPAT
> >   #include "../kernel/ppc32.h"
> >   #endif
> >   #include 
> > @@ -291,7 +291,8 @@ static inline int current_is_64bit(void)
> >  * interrupt stack, and the thread flags don't get copied over
> >  * from the thread_info on the main stack to the interrupt stack.
> >  */
> > -   return !test_ti_thread_flag(task_thread_info(current), TIF_32BIT);
> > +   return !IS_ENABLED(CONFIG_COMPAT) ||
> > +   !test_ti_thread_flag(task_thread_info(current), TIF_32BIT);
> >   }
> >   
> >   #else  /* CONFIG_PPC64 */
> > @@ -341,6 +342,7 @@ static inline int valid_user_sp(unsigned long sp, int 
> > is_64)
> >   
> >   #endif /* CONFIG_PPC64 */
> >   
> > +#if defined(CONFIG_PPC32) || defined(CONFIG_COMPAT)
> >   /*
> >* Layout for non-RT signal frames
> >*/
> > @@ -482,6 +484,13 @@ static void perf_callchain_user_32(struct 
> > perf_callchain_entry_ctx *entry,
> > sp = next_sp;
> > }
> >   }
> > +#else /* 32bit */
> > +static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
> > +  struct pt_regs *regs)
> > +{
> > +   (void)&read_user_stack_32; /* unused if !COMPAT */  
> 
> That looks pretty much like a hack.
> 
> See possible alternative below.
> 
> > +}
> > +#endif /* 32bit */
> >   
> >   void
> >   perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct 
> > pt_regs *regs)
> >   
> 
> ---
>  arch/powerpc/perf/callchain.c | 62 
> +++
>  1 file changed, 27 insertions(+), 35 deletions(-)
> 
> diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
> index 881be5c4e9bb..1b169b32776a 100644
> --- a/arch/powerpc/perf/callchain.c
> +++ b/arch/powerpc/perf/callchain.c
> @@ -165,22 +165,6 @@ static int read_user_stack_64(unsigned long __user *ptr, 
> unsigned long *ret)
>   return read_user_stack_slow(ptr, ret, 8);
>  }
>  
> -static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
> -{
> - if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
> - ((unsigned long)ptr & 3))
> - return -EFAULT;
> -
> - pagefault_disable();
> - if (!__get_user_inatomic(*ret, ptr)) {
> - pagefault_enable();
> - return 0;
> - }
> - pagefault_enable();
> -
> - return read_user_stack_slow(ptr, ret, 4);
> -}
> -
>  static inline int valid_user_sp(unsigned long sp, int is_64)
>  {
>   if (!sp || (sp & 7) || sp > (is_64 ? TASK_SIZE : 0x1UL) - 32)
> @@ -296,25 +280,10 @@ static inline int current_is_64bit(void)
>  }
>  
>  #else  /* CONFIG_PPC64 */
> -/*
> - * On 32-bit we just access the address and let hash_page create a
> - * HPTE if necessary, so there is no need to fall back to reading
> - * the page tables.  Since this is called at interrupt level,
> - * do_page_fault() won't treat a DSI as a page fault.
> - */
> -static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
> -{
> - int rc;
> -
> - if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
> - ((unsigned long)ptr & 3))
> - return -EFAULT;
>  
> - pagefault_disable();
> - rc = __get_user_inatomic(*ret, ptr);
> - pagefault_enable();
> -
> - return rc;
> +static int read_user_stack_slow(void __user *ptr, void *buf, int n

Re: [PATCH] powerpc/mm: tell if a bad page fault on data is read or write.

2019-08-30 Thread Christophe Leroy




Le 29/08/2019 à 14:14, Michael Ellerman a écrit :

Christophe Leroy  writes:

DSISR has a bit to tell if the fault is due to a read or a write.


Except some CPUs don't have a DSISR?

Which is why we have page_fault_is_write() that's used in
__do_page_fault().



And that's why I'm also using page_fault_is_write() in my patch.



Or is that old cruft?

I see eg. in head_40x.S we pass r5=0 for error code, and we don't set
regs->dsisr anywhere AFAICS. So it might just contain some junk.



We pass r5=0 in ISI but r5=SPRN_ESR in DSI.
And r5 is also saved into _ESR(r11)

And in asm-offset.c, we have:

STACK_PT_REGS_OFFSET(_ESR, dsisr);

So regs->dsisr has the expected content.

Christophe




cheers


diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 8432c281de92..b5047f9b5dec 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -645,6 +645,7 @@ NOKPROBE_SYMBOL(do_page_fault);
  void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
  {
const struct exception_table_entry *entry;
+   int is_write = page_fault_is_write(regs->dsisr);
  
  	/* Are we prepared to handle this fault?  */

if ((entry = search_exception_tables(regs->nip)) != NULL) {
@@ -658,9 +659,10 @@ void bad_page_fault(struct pt_regs *regs, unsigned long 
address, int sig)
case 0x300:
case 0x380:
case 0xe00:
-   pr_alert("BUG: %s at 0x%08lx\n",
+   pr_alert("BUG: %s on %s at 0x%08lx\n",
 regs->dar < PAGE_SIZE ? "Kernel NULL pointer 
dereference" :
-"Unable to handle kernel data access", regs->dar);
+"Unable to handle kernel data access",
+is_write ? "write" : "read", regs->dar);



break;
case 0x400:
case 0x480:
--
2.13.3


Re: [PATCH v5 5/5] powerpc/perf: split callchain.c by bitness

2019-08-30 Thread Christophe Leroy




Le 30/08/2019 à 09:12, Michal Suchánek a écrit :

On Fri, 30 Aug 2019 08:42:25 +0200
Michal Suchánek  wrote:


On Fri, 30 Aug 2019 06:35:11 + (UTC)
Christophe Leroy  wrote:


On 08/29/2019 10:28 PM, Michal Suchanek wrote:



  obj-$(CONFIG_PPC_PERF_CTRS)   += core-book3s.o bhrb.o
diff --git a/arch/powerpc/perf/callchain_32.c b/arch/powerpc/perf/callchain_32.c
index 0bd4484eddaa..17c43ae03084 100644
--- a/arch/powerpc/perf/callchain_32.c
+++ b/arch/powerpc/perf/callchain_32.c
@@ -15,50 +15,13 @@
  #include 
  #include 
  #include 
-#ifdef CONFIG_PPC64
-#include "../kernel/ppc32.h"
-#endif
  #include 
  
  #include "callchain.h"
  
  #ifdef CONFIG_PPC64

-static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
-{
-   if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
-   ((unsigned long)ptr & 3))
-   return -EFAULT;
-
-   pagefault_disable();
-   if (!__get_user_inatomic(*ret, ptr)) {
-   pagefault_enable();
-   return 0;
-   }
-   pagefault_enable();
-
-   return read_user_stack_slow(ptr, ret, 4);
-}
-#else /* CONFIG_PPC64 */
-/*
- * On 32-bit we just access the address and let hash_page create a
- * HPTE if necessary, so there is no need to fall back to reading
- * the page tables.  Since this is called at interrupt level,
- * do_page_fault() won't treat a DSI as a page fault.
- */
-static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
-{
-   int rc;
-
-   if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
-   ((unsigned long)ptr & 3))
-   return -EFAULT;
-
-   pagefault_disable();
-   rc = __get_user_inatomic(*ret, ptr);
-   pagefault_enable();
-
-   return rc;
-}
+#include "../kernel/ppc32.h"
+#else
  
  #define __SIGNAL_FRAMESIZE32	__SIGNAL_FRAMESIZE

  #define sigcontext32  sigcontext
@@ -95,6 +58,30 @@ struct rt_signal_frame_32 {
int abigap[56];
  };
  
+/*

+ * On 32-bit we just access the address and let hash_page create a
+ * HPTE if necessary, so there is no need to fall back to reading
+ * the page tables.  Since this is called at interrupt level,
+ * do_page_fault() won't treat a DSI as a page fault.
+ */
+static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
+{
+   int rc;
+
+   if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
+   ((unsigned long)ptr & 3))
+   return -EFAULT;
+
+   pagefault_disable();
+   rc = __get_user_inatomic(*ret, ptr);
+   pagefault_enable();
+
+   if (IS_ENABLED(CONFIG_PPC32) || !rc)
+   return rc;
+
+   return read_user_stack_slow(ptr, ret, 4);
+}
+
  static int is_sigreturn_32_address(unsigned int nip, unsigned int fp)
  {
if (nip == fp + offsetof(struct signal_frame_32, mctx.mc_pad))


I will leave consolidating this function to somebody who knows what the
desired semantic is. With a short ifdef section at the top of the file
it is a low-hanging fruit.


It looks ok if done as a separate patch.


Yes, doing it as a separate patch is good.

And if you do it before patch 3, then you don't need anymore this ugly 
hack to hide read_user_stack_32()


Christphe



Thanks

Michal



Re: [PATCH v5 5/5] powerpc/perf: split callchain.c by bitness

2019-08-30 Thread Michal Suchánek
On Fri, 30 Aug 2019 08:42:25 +0200
Michal Suchánek  wrote:

> On Fri, 30 Aug 2019 06:35:11 + (UTC)
> Christophe Leroy  wrote:
> 
> > On 08/29/2019 10:28 PM, Michal Suchanek wrote:  

> >  obj-$(CONFIG_PPC_PERF_CTRS)+= core-book3s.o bhrb.o
> > diff --git a/arch/powerpc/perf/callchain_32.c 
> > b/arch/powerpc/perf/callchain_32.c
> > index 0bd4484eddaa..17c43ae03084 100644
> > --- a/arch/powerpc/perf/callchain_32.c
> > +++ b/arch/powerpc/perf/callchain_32.c
> > @@ -15,50 +15,13 @@
> >  #include 
> >  #include 
> >  #include 
> > -#ifdef CONFIG_PPC64
> > -#include "../kernel/ppc32.h"
> > -#endif
> >  #include 
> >  
> >  #include "callchain.h"
> >  
> >  #ifdef CONFIG_PPC64
> > -static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
> > -{
> > -   if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
> > -   ((unsigned long)ptr & 3))
> > -   return -EFAULT;
> > -
> > -   pagefault_disable();
> > -   if (!__get_user_inatomic(*ret, ptr)) {
> > -   pagefault_enable();
> > -   return 0;
> > -   }
> > -   pagefault_enable();
> > -
> > -   return read_user_stack_slow(ptr, ret, 4);
> > -}
> > -#else /* CONFIG_PPC64 */
> > -/*
> > - * On 32-bit we just access the address and let hash_page create a
> > - * HPTE if necessary, so there is no need to fall back to reading
> > - * the page tables.  Since this is called at interrupt level,
> > - * do_page_fault() won't treat a DSI as a page fault.
> > - */
> > -static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
> > -{
> > -   int rc;
> > -
> > -   if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
> > -   ((unsigned long)ptr & 3))
> > -   return -EFAULT;
> > -
> > -   pagefault_disable();
> > -   rc = __get_user_inatomic(*ret, ptr);
> > -   pagefault_enable();
> > -
> > -   return rc;
> > -}
> > +#include "../kernel/ppc32.h"
> > +#else
> >  
> >  #define __SIGNAL_FRAMESIZE32   __SIGNAL_FRAMESIZE
> >  #define sigcontext32   sigcontext
> > @@ -95,6 +58,30 @@ struct rt_signal_frame_32 {
> > int abigap[56];
> >  };
> >  
> > +/*
> > + * On 32-bit we just access the address and let hash_page create a
> > + * HPTE if necessary, so there is no need to fall back to reading
> > + * the page tables.  Since this is called at interrupt level,
> > + * do_page_fault() won't treat a DSI as a page fault.
> > + */
> > +static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
> > +{
> > +   int rc;
> > +
> > +   if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
> > +   ((unsigned long)ptr & 3))
> > +   return -EFAULT;
> > +
> > +   pagefault_disable();
> > +   rc = __get_user_inatomic(*ret, ptr);
> > +   pagefault_enable();
> > +
> > +   if (IS_ENABLED(CONFIG_PPC32) || !rc)
> > +   return rc;
> > +
> > +   return read_user_stack_slow(ptr, ret, 4);
> > +}
> > +
> >  static int is_sigreturn_32_address(unsigned int nip, unsigned int fp)
> >  {
> > if (nip == fp + offsetof(struct signal_frame_32, mctx.mc_pad))  
> 
> I will leave consolidating this function to somebody who knows what the
> desired semantic is. With a short ifdef section at the top of the file
> it is a low-hanging fruit.

It looks ok if done as a separate patch.

Thanks

Michal