Re: [PATCH v2 5/9] powerpc/vmlinux.lds: Align __init_begin to 16M
On Sat, 3 Jun 2017 17:18:39 +1000 Balbir Singhwrote: > For CONFIG_STRICT_KERNEL_RWX align __init_begin to 16M. > We use 16M since its the larger of 2M on radix and 16M > on hash for our linear mapping. The plan is to have > .text, .rodata and everything upto __init_begin marked > as RX. Note we still have executable read only data. > We could further align read only data to another 16M > boundary, but then the linker starts using stubs and > that breaks our assembler code in head_64.S Is this still the case with powerpc next? Thanks, Nick
Re: [PATCH V3 1/2] powerpc/numa: Update CPU topology when VPHN enabled
Hi Michael, [auto build test ERROR on powerpc/next] [also build test ERROR on v4.12-rc3 next-20170602] [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/Michael-Bringmann/powerpc-numa-Update-CPU-topology-when-VPHN-enabled/20170527-052650 base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next config: powerpc-cell_defconfig (attached as .config) compiler: powerpc64-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705 reproduce: wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=powerpc All errors (new ones prefixed by >>): >> arch/powerpc/mm/numa.c:47:12: error: 'topology_update_needed' defined but >> not used [-Werror=unused-variable] static int topology_update_needed; ^~ >> arch/powerpc/mm/numa.c:46:12: error: 'topology_inited' defined but not used >> [-Werror=unused-variable] static int topology_inited; ^~~ cc1: all warnings being treated as errors vim +/topology_update_needed +47 arch/powerpc/mm/numa.c 40 #include 41 #include 42 #include 43 #include 44 45 static int numa_enabled = 1; > 46 static int topology_inited; > 47 static int topology_update_needed; 48 49 static char *cmdline __initdata; 50 --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH] powerpc/kernel: improve FP and vector registers restoration
On Sat, 3 Jun 2017 19:42:14 -0300 Breno Leitaowrote: > Hi Anton, > > On Sat, Jun 03, 2017 at 08:04:11AM +1000, Anton Blanchard wrote: > > Hi Breno, > > > > > Currently tsk->thread->load_vec and load_fp are not initialized > > > during a task creation, which set garbage to these variables > > > (non-zero value). > > > > Nice catch! It seems like we should zero load_tm too though? > > Yes, it seems we need to zero load_tm also, since it does not seem to > be zeroed anywhere else. > > But I did some tests, and load_tm is always zero after start_thread() > is being called. > > In fact, start_thread() is being called and pt_regs->load_tm is > already zero since the function start. > > I also wrote a SystemTap script[1] to investigate it better, and I've > never seen a single load_tm != 0 in a my machine. I tested on both > POWER8 bare metal and KVM guests. (load_vec and load_fp happened to > have garbage all the time) > > Any idea if this is just occasional event, or, if there is someone > zeroing it in an obscure code? Quite likely no one uses TM :) Try: #include int main(void) { __builtin_tbegin(0); execlp("/bin/true", "/bin/true", NULL); } Anton
Re: [PATCH v2 1/9] powerpc/lib/code-patching: Enhance code patching
Hi Balbir, [auto build test ERROR on powerpc/next] [also build test ERROR on v4.12-rc3 next-20170602] [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/Balbir-Singh/Enable-STRICT_KERNEL_RWX/20170603-161759 base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next config: powerpc-kilauea_defconfig (attached as .config) compiler: powerpc-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705 reproduce: wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=powerpc All errors (new ones prefixed by >>): arch/powerpc/lib/code-patching.c: In function 'kernel_map_addr': >> arch/powerpc/lib/code-patching.c:93:8: error: implicit declaration of >> function 'map_kernel_page' [-Werror=implicit-function-declaration] err = map_kernel_page( ^~~ cc1: all warnings being treated as errors vim +/map_kernel_page +93 arch/powerpc/lib/code-patching.c 87 88 if (is_vmalloc_addr(addr)) 89 pfn = vmalloc_to_pfn(addr); 90 else 91 pfn = __pa_symbol(addr) >> PAGE_SHIFT; 92 > 93 err = map_kernel_page( 94 (unsigned long)__this_cpu_read(text_poke_area)->addr, 95 (pfn << PAGE_SHIFT), _PAGE_KERNEL_RW | _PAGE_PRESENT); 96 pr_devel("Mapped addr %p with pfn %lx\n", --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH] powerpc/kernel: improve FP and vector registers restoration
Hi Anton, On Sat, Jun 03, 2017 at 08:04:11AM +1000, Anton Blanchard wrote: > Hi Breno, > > > Currently tsk->thread->load_vec and load_fp are not initialized > > during a task creation, which set garbage to these variables > > (non-zero value). > > Nice catch! It seems like we should zero load_tm too though? Yes, it seems we need to zero load_tm also, since it does not seem to be zeroed anywhere else. But I did some tests, and load_tm is always zero after start_thread() is being called. In fact, start_thread() is being called and pt_regs->load_tm is already zero since the function start. I also wrote a SystemTap script[1] to investigate it better, and I've never seen a single load_tm != 0 in a my machine. I tested on both POWER8 bare metal and KVM guests. (load_vec and load_fp happened to have garbage all the time) Any idea if this is just occasional event, or, if there is someone zeroing it in an obscure code? [1] https://github.com/leitao/htm_torture/blob/master/systemtap/load_tm_at_start_thread.stap
Re: [PATCH v3 1/2] tty: add compat_ioctl callbacks
Hi Aleksa, [auto build test ERROR on linus/master] [also build test ERROR on v4.12-rc3 next-20170602] [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/Aleksa-Sarai/tty-add-TIOCGPTPEER-ioctl/20170603-220322 config: x86_64-randconfig-x010-201722 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All errors (new ones prefixed by >>): >> cc1: error: -Werror=int-in-bool-context: no option -Wint-in-bool-context make[2]: *** [kernel/bounds.s] Error 1 make[2]: Target '__build' not remade because of errors. make[1]: *** [prepare0] Error 2 make[1]: Target 'prepare' not remade because of errors. make: *** [sub-make] Error 2 --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH v3 1/2] tty: add compat_ioctl callbacks
Hi Aleksa, [auto build test WARNING on linus/master] [also build test WARNING on v4.12-rc3 next-20170602] [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/Aleksa-Sarai/tty-add-TIOCGPTPEER-ioctl/20170603-220322 config: i386-randconfig-x018-201722 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 All warnings (new ones prefixed by >>): >> cc1: warning: -malign-functions is obsolete, use -falign-functions >> cc1: warning: -malign-jumps is obsolete, use -falign-jumps >> cc1: warning: -malign-loops is obsolete, use -falign-loops cc1: error: -Werror=int-in-bool-context: no option -Wint-in-bool-context kernel/bounds.c:1:0: error: CPU you selected does not support x86-64 instruction set /* kernel/bounds.c:1:0: error: CPU you selected does not support x86-64 instruction set kernel/bounds.c:1:0: warning: -mregparm is ignored in 64-bit mode make[2]: *** [kernel/bounds.s] Error 1 make[2]: Target '__build' not remade because of errors. make[1]: *** [prepare0] Error 2 make[1]: Target 'prepare' not remade because of errors. make: *** [sub-make] Error 2 --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
[PATCH v4 2/2] tty: add TIOCGPTPEER ioctl
When opening the slave end of a PTY, it is not possible for userspace to safely ensure that /dev/pts/$num is actually a slave (in cases where the mount namespace in which devpts was mounted is controlled by an untrusted process). In addition, there are several unresolvable race conditions if userspace were to attempt to detect attacks through stat(2) and other similar methods [in addition it is not clear how userspace could detect attacks involving FUSE]. Resolve this by providing an interface for userpace to safely open the "peer" end of a PTY file descriptor by using the dentry cached by devpts. Since it is not possible to have an open master PTY without having its slave exposed in /dev/pts this interface is safe. This interface currently does not provide a way to get the master pty (since it is not clear whether such an interface is safe or even useful). Cc: Christian BraunerCc: Valentin Rothberg Signed-off-by: Aleksa Sarai --- arch/alpha/include/uapi/asm/ioctls.h | 1 + arch/mips/include/uapi/asm/ioctls.h| 1 + arch/parisc/include/uapi/asm/ioctls.h | 1 + arch/powerpc/include/uapi/asm/ioctls.h | 1 + arch/sh/include/uapi/asm/ioctls.h | 1 + arch/sparc/include/uapi/asm/ioctls.h | 3 +- arch/xtensa/include/uapi/asm/ioctls.h | 1 + drivers/tty/pty.c | 71 -- include/uapi/asm-generic/ioctls.h | 1 + 9 files changed, 76 insertions(+), 5 deletions(-) diff --git a/arch/alpha/include/uapi/asm/ioctls.h b/arch/alpha/include/uapi/asm/ioctls.h index f30c94ae1bdb..ff67b8373bf7 100644 --- a/arch/alpha/include/uapi/asm/ioctls.h +++ b/arch/alpha/include/uapi/asm/ioctls.h @@ -100,6 +100,7 @@ #define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ +#define TIOCGPTPEER_IOR('T', 0x41, int) /* Safely open the slave */ #define TIOCSERCONFIG 0x5453 #define TIOCSERGWILD 0x5454 diff --git a/arch/mips/include/uapi/asm/ioctls.h b/arch/mips/include/uapi/asm/ioctls.h index 740219c2c894..68e19b689a00 100644 --- a/arch/mips/include/uapi/asm/ioctls.h +++ b/arch/mips/include/uapi/asm/ioctls.h @@ -91,6 +91,7 @@ #define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ +#define TIOCGPTPEER_IOR('T', 0x41, int) /* Safely open the slave */ /* I hope the range from 0x5480 on is free ... */ #define TIOCSCTTY 0x5480 /* become controlling tty */ diff --git a/arch/parisc/include/uapi/asm/ioctls.h b/arch/parisc/include/uapi/asm/ioctls.h index b6572f051b67..674c68a5bbd0 100644 --- a/arch/parisc/include/uapi/asm/ioctls.h +++ b/arch/parisc/include/uapi/asm/ioctls.h @@ -60,6 +60,7 @@ #define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ +#define TIOCGPTPEER_IOR('T', 0x41, int) /* Safely open the slave */ #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ #define FIOCLEX0x5451 diff --git a/arch/powerpc/include/uapi/asm/ioctls.h b/arch/powerpc/include/uapi/asm/ioctls.h index 49a25796a61a..bfd609a3e928 100644 --- a/arch/powerpc/include/uapi/asm/ioctls.h +++ b/arch/powerpc/include/uapi/asm/ioctls.h @@ -100,6 +100,7 @@ #define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ +#define TIOCGPTPEER_IOR('T', 0x41, int) /* Safely open the slave */ #define TIOCSERCONFIG 0x5453 #define TIOCSERGWILD 0x5454 diff --git a/arch/sh/include/uapi/asm/ioctls.h b/arch/sh/include/uapi/asm/ioctls.h index c9903e56ccf4..eec7901e9e65 100644 --- a/arch/sh/include/uapi/asm/ioctls.h +++ b/arch/sh/include/uapi/asm/ioctls.h @@ -93,6 +93,7 @@ #define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ +#define TIOCGPTPEER_IOR('T', 0x41, int) /* Safely open the slave */ #define TIOCSERCONFIG _IO('T', 83) /* 0x5453 */ #define TIOCSERGWILD _IOR('T', 84, int) /* 0x5454 */ diff --git a/arch/sparc/include/uapi/asm/ioctls.h b/arch/sparc/include/uapi/asm/ioctls.h index 06b3f6c3bb9a..6d27398632ea 100644 --- a/arch/sparc/include/uapi/asm/ioctls.h +++ b/arch/sparc/include/uapi/asm/ioctls.h @@ -27,7 +27,7 @@ #define TIOCGRS485 _IOR('T', 0x41, struct serial_rs485) #define TIOCSRS485 _IOWR('T', 0x42, struct serial_rs485) -/* Note
[PATCH v4 1/2] tty: add compat_ioctl callbacks
In order to avoid future diversions between fs/compat_ioctl.c and drivers/tty/pty.c, define .compat_ioctl callbacks for the relevant tty_operations structs. Since both pty_unix98_ioctl() and pty_bsd_ioctl() are compatible between 32-bit and 64-bit userspace no special translation is required. Signed-off-by: Aleksa Sarai--- drivers/tty/pty.c | 22 ++ fs/compat_ioctl.c | 6 -- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 65799575c666..2a6bd9ae3f8b 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -481,6 +481,16 @@ static int pty_bsd_ioctl(struct tty_struct *tty, return -ENOIOCTLCMD; } +static long pty_bsd_compat_ioctl(struct tty_struct *tty, +unsigned int cmd, unsigned long arg) +{ + /* +* PTY ioctls don't require any special translation between 32-bit and +* 64-bit userspace, they are already compatible. +*/ + return pty_bsd_ioctl(tty, cmd, arg); +} + static int legacy_count = CONFIG_LEGACY_PTY_COUNT; /* * not really modular, but the easiest way to keep compat with existing @@ -502,6 +512,7 @@ static const struct tty_operations master_pty_ops_bsd = { .chars_in_buffer = pty_chars_in_buffer, .unthrottle = pty_unthrottle, .ioctl = pty_bsd_ioctl, + .compat_ioctl = pty_bsd_compat_ioctl, .cleanup = pty_cleanup, .resize = pty_resize, .remove = pty_remove @@ -609,6 +620,16 @@ static int pty_unix98_ioctl(struct tty_struct *tty, return -ENOIOCTLCMD; } +static long pty_unix98_compat_ioctl(struct tty_struct *tty, +unsigned int cmd, unsigned long arg) +{ + /* +* PTY ioctls don't require any special translation between 32-bit and +* 64-bit userspace, they are already compatible. +*/ + return pty_unix98_ioctl(tty, cmd, arg); +} + /** * ptm_unix98_lookup - find a pty master * @driver: ptm driver @@ -681,6 +702,7 @@ static const struct tty_operations ptm_unix98_ops = { .chars_in_buffer = pty_chars_in_buffer, .unthrottle = pty_unthrottle, .ioctl = pty_unix98_ioctl, + .compat_ioctl = pty_unix98_compat_ioctl, .resize = pty_resize, .cleanup = pty_cleanup }; diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 6116d5275a3e..112b3e1e20e3 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -866,8 +866,6 @@ COMPATIBLE_IOCTL(TIOCGDEV) COMPATIBLE_IOCTL(TIOCCBRK) COMPATIBLE_IOCTL(TIOCGSID) COMPATIBLE_IOCTL(TIOCGICOUNT) -COMPATIBLE_IOCTL(TIOCGPKT) -COMPATIBLE_IOCTL(TIOCGPTLCK) COMPATIBLE_IOCTL(TIOCGEXCL) /* Little t */ COMPATIBLE_IOCTL(TIOCGETD) @@ -883,16 +881,12 @@ COMPATIBLE_IOCTL(TIOCMGET) COMPATIBLE_IOCTL(TIOCMBIC) COMPATIBLE_IOCTL(TIOCMBIS) COMPATIBLE_IOCTL(TIOCMSET) -COMPATIBLE_IOCTL(TIOCPKT) COMPATIBLE_IOCTL(TIOCNOTTY) COMPATIBLE_IOCTL(TIOCSTI) COMPATIBLE_IOCTL(TIOCOUTQ) COMPATIBLE_IOCTL(TIOCSPGRP) COMPATIBLE_IOCTL(TIOCGPGRP) -COMPATIBLE_IOCTL(TIOCGPTN) -COMPATIBLE_IOCTL(TIOCSPTLCK) COMPATIBLE_IOCTL(TIOCSERGETLSR) -COMPATIBLE_IOCTL(TIOCSIG) #ifdef TIOCSRS485 COMPATIBLE_IOCTL(TIOCSRS485) #endif -- 2.13.0
[PATCH v4 0/2] tty: add TIOCGPTPEER ioctl
Changes in v4: * Dropped an accidental change to Makefile. Aleksa Sarai (2): tty: add compat_ioctl callbacks tty: add TIOCGPTPEER ioctl arch/alpha/include/uapi/asm/ioctls.h | 1 + arch/mips/include/uapi/asm/ioctls.h| 1 + arch/parisc/include/uapi/asm/ioctls.h | 1 + arch/powerpc/include/uapi/asm/ioctls.h | 1 + arch/sh/include/uapi/asm/ioctls.h | 1 + arch/sparc/include/uapi/asm/ioctls.h | 3 +- arch/xtensa/include/uapi/asm/ioctls.h | 1 + drivers/tty/pty.c | 93 -- fs/compat_ioctl.c | 6 --- include/uapi/asm-generic/ioctls.h | 1 + 10 files changed, 98 insertions(+), 11 deletions(-) -- 2.13.0
Re: [PATCH v3 1/2] tty: add compat_ioctl callbacks
diff --git a/Makefile b/Makefile index 470bd4d9513a..fb689286d83a 100644 --- a/Makefile +++ b/Makefile @@ -401,6 +401,7 @@ KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -fno-common \ -Werror-implicit-function-declaration \ -Wno-format-security \ + -Wno-error=int-in-bool-context \ -std=gnu89 $(call cc-option,-fno-PIE) Ah sorry, I committed that by accident. I'll send a fixed version. -- Aleksa Sarai Software Engineer (Containers) SUSE Linux GmbH https://www.cyphar.com/
Re: powerpc/opal-irqchip: Use interrupt names if present
Hi Ben, On Fri, Jun 2, 2017 at 4:11 PM, Benjamin Herrenschmidtwrote: > On Fri, 2017-06-02 at 14:39 +0200, Geert Uytterhoeven wrote: >> > diff --git a/arch/powerpc/platforms/powernv/opal-irqchip.c >> > b/arch/powerpc/platforms/powernv/opal-irqchip.c >> > index 998316bf2dad..ecdcba9d1220 100644 >> > --- a/arch/powerpc/platforms/powernv/opal-irqchip.c >> > +++ b/arch/powerpc/platforms/powernv/opal-irqchip.c >> > @@ -183,8 +183,9 @@ void opal_event_shutdown(void) >> > + /* It's not an error for the names to be missing */ >> > + of_property_read_string_array(opal_node, "opal-interrupts-names", >> > + names, opal_irq_count); >> >> Just double-checking, as it's different from the standard "interrupt-names": >> is "opal-interrupts-names" the correct name? > > Yes, because the property it refers to isn't a standard "interrupts" > property... it's ... complicated :-) I'm aware it's a different property. > It could have been mind you, but the decision for that was made years > ago... it's a bunch of interrupts OPAL is interested in, which Linux > requests and sets up a handler for which just calls back into OPAL. > > In any case, firmwares with that property are out now. Thanks for the confirmation! Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
[PATCH v3 2/2] tty: add TIOCGPTPEER ioctl
When opening the slave end of a PTY, it is not possible for userspace to safely ensure that /dev/pts/$num is actually a slave (in cases where the mount namespace in which devpts was mounted is controlled by an untrusted process). In addition, there are several unresolvable race conditions if userspace were to attempt to detect attacks through stat(2) and other similar methods [in addition it is not clear how userspace could detect attacks involving FUSE]. Resolve this by providing an interface for userpace to safely open the "peer" end of a PTY file descriptor by using the dentry cached by devpts. Since it is not possible to have an open master PTY without having its slave exposed in /dev/pts this interface is safe. This interface currently does not provide a way to get the master pty (since it is not clear whether such an interface is safe or even useful). Cc: Christian BraunerCc: Valentin Rothberg Signed-off-by: Aleksa Sarai --- arch/alpha/include/uapi/asm/ioctls.h | 1 + arch/mips/include/uapi/asm/ioctls.h| 1 + arch/parisc/include/uapi/asm/ioctls.h | 1 + arch/powerpc/include/uapi/asm/ioctls.h | 1 + arch/sh/include/uapi/asm/ioctls.h | 1 + arch/sparc/include/uapi/asm/ioctls.h | 3 +- arch/xtensa/include/uapi/asm/ioctls.h | 1 + drivers/tty/pty.c | 71 -- include/uapi/asm-generic/ioctls.h | 1 + 9 files changed, 76 insertions(+), 5 deletions(-) diff --git a/arch/alpha/include/uapi/asm/ioctls.h b/arch/alpha/include/uapi/asm/ioctls.h index f30c94ae1bdb..ff67b8373bf7 100644 --- a/arch/alpha/include/uapi/asm/ioctls.h +++ b/arch/alpha/include/uapi/asm/ioctls.h @@ -100,6 +100,7 @@ #define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ +#define TIOCGPTPEER_IOR('T', 0x41, int) /* Safely open the slave */ #define TIOCSERCONFIG 0x5453 #define TIOCSERGWILD 0x5454 diff --git a/arch/mips/include/uapi/asm/ioctls.h b/arch/mips/include/uapi/asm/ioctls.h index 740219c2c894..68e19b689a00 100644 --- a/arch/mips/include/uapi/asm/ioctls.h +++ b/arch/mips/include/uapi/asm/ioctls.h @@ -91,6 +91,7 @@ #define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ +#define TIOCGPTPEER_IOR('T', 0x41, int) /* Safely open the slave */ /* I hope the range from 0x5480 on is free ... */ #define TIOCSCTTY 0x5480 /* become controlling tty */ diff --git a/arch/parisc/include/uapi/asm/ioctls.h b/arch/parisc/include/uapi/asm/ioctls.h index b6572f051b67..674c68a5bbd0 100644 --- a/arch/parisc/include/uapi/asm/ioctls.h +++ b/arch/parisc/include/uapi/asm/ioctls.h @@ -60,6 +60,7 @@ #define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ +#define TIOCGPTPEER_IOR('T', 0x41, int) /* Safely open the slave */ #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ #define FIOCLEX0x5451 diff --git a/arch/powerpc/include/uapi/asm/ioctls.h b/arch/powerpc/include/uapi/asm/ioctls.h index 49a25796a61a..bfd609a3e928 100644 --- a/arch/powerpc/include/uapi/asm/ioctls.h +++ b/arch/powerpc/include/uapi/asm/ioctls.h @@ -100,6 +100,7 @@ #define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ +#define TIOCGPTPEER_IOR('T', 0x41, int) /* Safely open the slave */ #define TIOCSERCONFIG 0x5453 #define TIOCSERGWILD 0x5454 diff --git a/arch/sh/include/uapi/asm/ioctls.h b/arch/sh/include/uapi/asm/ioctls.h index c9903e56ccf4..eec7901e9e65 100644 --- a/arch/sh/include/uapi/asm/ioctls.h +++ b/arch/sh/include/uapi/asm/ioctls.h @@ -93,6 +93,7 @@ #define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ +#define TIOCGPTPEER_IOR('T', 0x41, int) /* Safely open the slave */ #define TIOCSERCONFIG _IO('T', 83) /* 0x5453 */ #define TIOCSERGWILD _IOR('T', 84, int) /* 0x5454 */ diff --git a/arch/sparc/include/uapi/asm/ioctls.h b/arch/sparc/include/uapi/asm/ioctls.h index 06b3f6c3bb9a..6d27398632ea 100644 --- a/arch/sparc/include/uapi/asm/ioctls.h +++ b/arch/sparc/include/uapi/asm/ioctls.h @@ -27,7 +27,7 @@ #define TIOCGRS485 _IOR('T', 0x41, struct serial_rs485) #define TIOCSRS485 _IOWR('T', 0x42, struct serial_rs485) -/* Note
[PATCH v3 1/2] tty: add compat_ioctl callbacks
In order to avoid future diversions between fs/compat_ioctl.c and drivers/tty/pty.c, define .compat_ioctl callbacks for the relevant tty_operations structs. Since both pty_unix98_ioctl() and pty_bsd_ioctl() are compatible between 32-bit and 64-bit userspace no special translation is required. Signed-off-by: Aleksa Sarai--- Makefile | 1 + drivers/tty/pty.c | 22 ++ fs/compat_ioctl.c | 6 -- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 470bd4d9513a..fb689286d83a 100644 --- a/Makefile +++ b/Makefile @@ -401,6 +401,7 @@ KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -fno-common \ -Werror-implicit-function-declaration \ -Wno-format-security \ + -Wno-error=int-in-bool-context \ -std=gnu89 $(call cc-option,-fno-PIE) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 65799575c666..2a6bd9ae3f8b 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -481,6 +481,16 @@ static int pty_bsd_ioctl(struct tty_struct *tty, return -ENOIOCTLCMD; } +static long pty_bsd_compat_ioctl(struct tty_struct *tty, +unsigned int cmd, unsigned long arg) +{ + /* +* PTY ioctls don't require any special translation between 32-bit and +* 64-bit userspace, they are already compatible. +*/ + return pty_bsd_ioctl(tty, cmd, arg); +} + static int legacy_count = CONFIG_LEGACY_PTY_COUNT; /* * not really modular, but the easiest way to keep compat with existing @@ -502,6 +512,7 @@ static const struct tty_operations master_pty_ops_bsd = { .chars_in_buffer = pty_chars_in_buffer, .unthrottle = pty_unthrottle, .ioctl = pty_bsd_ioctl, + .compat_ioctl = pty_bsd_compat_ioctl, .cleanup = pty_cleanup, .resize = pty_resize, .remove = pty_remove @@ -609,6 +620,16 @@ static int pty_unix98_ioctl(struct tty_struct *tty, return -ENOIOCTLCMD; } +static long pty_unix98_compat_ioctl(struct tty_struct *tty, +unsigned int cmd, unsigned long arg) +{ + /* +* PTY ioctls don't require any special translation between 32-bit and +* 64-bit userspace, they are already compatible. +*/ + return pty_unix98_ioctl(tty, cmd, arg); +} + /** * ptm_unix98_lookup - find a pty master * @driver: ptm driver @@ -681,6 +702,7 @@ static const struct tty_operations ptm_unix98_ops = { .chars_in_buffer = pty_chars_in_buffer, .unthrottle = pty_unthrottle, .ioctl = pty_unix98_ioctl, + .compat_ioctl = pty_unix98_compat_ioctl, .resize = pty_resize, .cleanup = pty_cleanup }; diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 6116d5275a3e..112b3e1e20e3 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -866,8 +866,6 @@ COMPATIBLE_IOCTL(TIOCGDEV) COMPATIBLE_IOCTL(TIOCCBRK) COMPATIBLE_IOCTL(TIOCGSID) COMPATIBLE_IOCTL(TIOCGICOUNT) -COMPATIBLE_IOCTL(TIOCGPKT) -COMPATIBLE_IOCTL(TIOCGPTLCK) COMPATIBLE_IOCTL(TIOCGEXCL) /* Little t */ COMPATIBLE_IOCTL(TIOCGETD) @@ -883,16 +881,12 @@ COMPATIBLE_IOCTL(TIOCMGET) COMPATIBLE_IOCTL(TIOCMBIC) COMPATIBLE_IOCTL(TIOCMBIS) COMPATIBLE_IOCTL(TIOCMSET) -COMPATIBLE_IOCTL(TIOCPKT) COMPATIBLE_IOCTL(TIOCNOTTY) COMPATIBLE_IOCTL(TIOCSTI) COMPATIBLE_IOCTL(TIOCOUTQ) COMPATIBLE_IOCTL(TIOCSPGRP) COMPATIBLE_IOCTL(TIOCGPGRP) -COMPATIBLE_IOCTL(TIOCGPTN) -COMPATIBLE_IOCTL(TIOCSPTLCK) COMPATIBLE_IOCTL(TIOCSERGETLSR) -COMPATIBLE_IOCTL(TIOCSIG) #ifdef TIOCSRS485 COMPATIBLE_IOCTL(TIOCSRS485) #endif -- 2.13.0
[PATCH v3 0/2] tty: add TIOCGPTPEER ioctl
Changes in v3: * Defined a compat_ioctl callback for all pty ioctls, since they are all 32-bit and 64-bit compatible. * Made TIOCGPTPEER support 32-bit userspace. Aleksa Sarai (2): tty: add compat_ioctl callbacks tty: add TIOCGPTPEER ioctl Makefile | 1 + arch/alpha/include/uapi/asm/ioctls.h | 1 + arch/mips/include/uapi/asm/ioctls.h| 1 + arch/parisc/include/uapi/asm/ioctls.h | 1 + arch/powerpc/include/uapi/asm/ioctls.h | 1 + arch/sh/include/uapi/asm/ioctls.h | 1 + arch/sparc/include/uapi/asm/ioctls.h | 3 +- arch/xtensa/include/uapi/asm/ioctls.h | 1 + drivers/tty/pty.c | 93 -- fs/compat_ioctl.c | 6 --- include/uapi/asm-generic/ioctls.h | 1 + 11 files changed, 99 insertions(+), 11 deletions(-) -- 2.13.0
[PATCH v2 9/9] powerpc/mm/ptdump: Dump the first entry of the linear mapping as well
The check in hpte_find() should be < and not <= for PAGE_OFFSET Signed-off-by: Balbir Singh--- arch/powerpc/mm/dump_hashpagetable.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/mm/dump_hashpagetable.c b/arch/powerpc/mm/dump_hashpagetable.c index c6b900f..b1c144b 100644 --- a/arch/powerpc/mm/dump_hashpagetable.c +++ b/arch/powerpc/mm/dump_hashpagetable.c @@ -335,7 +335,7 @@ static unsigned long hpte_find(struct pg_state *st, unsigned long ea, int psize) unsigned long rpn, lp_bits; int base_psize = 0, actual_psize = 0; - if (ea <= PAGE_OFFSET) + if (ea < PAGE_OFFSET) return -1; /* Look in primary table */ -- 2.9.3
[PATCH v2 8/9] powerpc/Kconfig: Enable STRICT_KERNEL_RWX
We have the basic support in the form of patching R/O text sections, linker scripts for extending alignment of text data. We've also got mark_rodata_ro() Signed-off-by: Balbir Singh--- arch/powerpc/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 0153275..ce68c1a 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -171,6 +171,7 @@ config PPC select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK + select ARCH_HAS_STRICT_KERNEL_RWX if PPC64 && PPC_BOOK3S select HAVE_CBPF_JITif !PPC64 select HAVE_CONTEXT_TRACKINGif PPC64 select HAVE_DEBUG_KMEMLEAK -- 2.9.3
[PATCH v2 7/9] powerpc/mm/hash: Implement mark_rodata_ro() for hash
With hash we update the bolted pte to mark it read-only. We rely on the MMU_FTR_KERNEL_RO to generate the correct permissions for read-only text. The radix implementation just prints a warning in this implementation Signed-off-by: Balbir Singh--- arch/powerpc/include/asm/book3s/64/hash.h | 3 +++ arch/powerpc/include/asm/book3s/64/radix.h | 4 arch/powerpc/mm/pgtable-hash64.c | 35 ++ arch/powerpc/mm/pgtable-radix.c| 7 ++ arch/powerpc/mm/pgtable_64.c | 9 5 files changed, 58 insertions(+) diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h index 4e957b0..0ce513f 100644 --- a/arch/powerpc/include/asm/book3s/64/hash.h +++ b/arch/powerpc/include/asm/book3s/64/hash.h @@ -89,6 +89,9 @@ static inline int hash__pgd_bad(pgd_t pgd) { return (pgd_val(pgd) == 0); } +#ifdef CONFIG_STRICT_KERNEL_RWX +extern void hash__mark_rodata_ro(void); +#endif extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr, pte_t *ptep, unsigned long pte, int huge); diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h index ac16d19..368cb54 100644 --- a/arch/powerpc/include/asm/book3s/64/radix.h +++ b/arch/powerpc/include/asm/book3s/64/radix.h @@ -116,6 +116,10 @@ #define RADIX_PUD_TABLE_SIZE (sizeof(pud_t) << RADIX_PUD_INDEX_SIZE) #define RADIX_PGD_TABLE_SIZE (sizeof(pgd_t) << RADIX_PGD_INDEX_SIZE) +#ifdef CONFIG_STRICT_KERNEL_RWX +extern void radix__mark_rodata_ro(void); +#endif + static inline unsigned long __radix_pte_update(pte_t *ptep, unsigned long clr, unsigned long set) { diff --git a/arch/powerpc/mm/pgtable-hash64.c b/arch/powerpc/mm/pgtable-hash64.c index 8b85a14..dda808b 100644 --- a/arch/powerpc/mm/pgtable-hash64.c +++ b/arch/powerpc/mm/pgtable-hash64.c @@ -11,8 +11,12 @@ #include #include +#include #include +#include +#include +#include #include #include "mmu_decl.h" @@ -342,3 +346,34 @@ int hash__has_transparent_hugepage(void) return 1; } #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ + +#ifdef CONFIG_STRICT_KERNEL_RWX +void hash__mark_rodata_ro(void) +{ + unsigned long start = (unsigned long)_stext; + unsigned long end = (unsigned long)__init_begin; + unsigned long idx; + unsigned int step, shift; + unsigned long newpp = PP_RXXX; + + if (!mmu_has_feature(MMU_FTR_KERNEL_RO)) { + pr_info("R/O rodata not supported\n"); + return; + } + + shift = mmu_psize_defs[mmu_linear_psize].shift; + step = 1 << shift; + + start = ((start + step - 1) >> shift) << shift; + end = (end >> shift) << shift; + + pr_devel("marking ro start %lx, end %lx, step %x\n", + start, end, step); + + for (idx = start; idx < end; idx += step) + /* Not sure if we can do much with the return value */ + mmu_hash_ops.hpte_updateboltedpp(newpp, idx, mmu_linear_psize, + mmu_kernel_ssize); + +} +#endif diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c index c28165d..8f42309 100644 --- a/arch/powerpc/mm/pgtable-radix.c +++ b/arch/powerpc/mm/pgtable-radix.c @@ -108,6 +108,13 @@ int radix__map_kernel_page(unsigned long ea, unsigned long pa, return 0; } +#ifdef CONFIG_STRICT_KERNEL_RWX +void radix__mark_rodata_ro(void) +{ + pr_warn("Not yet implemented for radix\n"); +} +#endif + static inline void __meminit print_mapping(unsigned long start, unsigned long end, unsigned long size) diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index db93cf7..a769e4f 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -479,3 +479,12 @@ void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0, } EXPORT_SYMBOL_GPL(mmu_partition_table_set_entry); #endif /* CONFIG_PPC_BOOK3S_64 */ + +#ifdef CONFIG_STRICT_KERNEL_RWX +void mark_rodata_ro(void) +{ + if (radix_enabled()) + return radix__mark_rodata_ro(); + return hash__mark_rodata_ro(); +} +#endif -- 2.9.3
[PATCH v2 6/9] powerpc/platform/pseries/lpar: Fix updatepp and updateboltedpp
PAPR has pp0 in bit 55, currently we assumed that bit pp0 is bit 0 (all bits in IBM order). This patch fixes the pp0 bits for both these routines that use H_PROTECT Signed-off-by: Balbir Singh--- arch/powerpc/platforms/pseries/lpar.c | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 6541d0b..83db643 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -301,7 +301,7 @@ static long pSeries_lpar_hpte_updatepp(unsigned long slot, int ssize, unsigned long inv_flags) { unsigned long lpar_rc; - unsigned long flags = (newpp & 7) | H_AVPN; + unsigned long flags; unsigned long want_v; want_v = hpte_encode_avpn(vpn, psize, ssize); @@ -309,6 +309,11 @@ static long pSeries_lpar_hpte_updatepp(unsigned long slot, pr_devel("update: avpnv=%016lx, hash=%016lx, f=%lx, psize: %d ...", want_v, slot, flags, psize); + /* +* Move pp0 and set the mask, pp0 is bit 55 +* We ignore the keys for now. +*/ + flags = ((newpp & HPTE_R_PP0) >> 55) | (newpp & 7) | H_AVPN; lpar_rc = plpar_pte_protect(flags, slot, want_v); if (lpar_rc == H_NOT_FOUND) { @@ -379,7 +384,11 @@ static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp, slot = pSeries_lpar_hpte_find(vpn, psize, ssize); BUG_ON(slot == -1); - flags = newpp & 7; + /* +* Move pp0 and set the mask, pp0 is bit 55 +* We ignore the keys for now. +*/ + flags = ((newpp & HPTE_R_PP0) >> 55) | (newpp & 7); lpar_rc = plpar_pte_protect(flags, slot, 0); BUG_ON(lpar_rc != H_SUCCESS); -- 2.9.3
[PATCH v2 5/9] powerpc/vmlinux.lds: Align __init_begin to 16M
For CONFIG_STRICT_KERNEL_RWX align __init_begin to 16M. We use 16M since its the larger of 2M on radix and 16M on hash for our linear mapping. The plan is to have .text, .rodata and everything upto __init_begin marked as RX. Note we still have executable read only data. We could further align read only data to another 16M boundary, but then the linker starts using stubs and that breaks our assembler code in head_64.S We don't use multi PT_LOAD in PHDRS because we are not sure if all bootloaders support them Signed-off-by: Balbir Singh--- arch/powerpc/kernel/vmlinux.lds.S | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index ace6b65..b1a2505 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -8,6 +8,12 @@ #include #include +#ifdef CONFIG_STRICT_KERNEL_RWX +#define STRICT_ALIGN_SIZE (1 << 24) +#else +#define STRICT_ALIGN_SIZE PAGE_SIZE +#endif + ENTRY(_stext) PHDRS { @@ -123,7 +129,7 @@ SECTIONS PROVIDE32 (etext = .); /* Read-only data */ - RODATA + RO_DATA(PAGE_SIZE) EXCEPTION_TABLE(0) @@ -140,7 +146,7 @@ SECTIONS /* * Init sections discarded at runtime */ - . = ALIGN(PAGE_SIZE); + . = ALIGN(STRICT_ALIGN_SIZE); __init_begin = .; INIT_TEXT_SECTION(PAGE_SIZE) :kernel -- 2.9.3
[PATCH v2 4/9] powerpc/xmon: Add patch_instruction supporf for xmon
Move from mwrite() to patch_instruction() for xmon for breakpoint addition and removal. Signed-off-by: Balbir Singh--- arch/powerpc/xmon/xmon.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index a728e19..08e367e 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -53,6 +53,7 @@ #include #include #include +#include #ifdef CONFIG_PPC64 #include @@ -837,7 +838,8 @@ static void insert_bpts(void) store_inst(>instr[0]); if (bp->enabled & BP_CIABR) continue; - if (mwrite(bp->address, , 4) != 4) { + if (patch_instruction((unsigned int *)bp->address, + bpinstr) != 0) { printf("Couldn't write instruction at %lx, " "disabling breakpoint there\n", bp->address); bp->enabled &= ~BP_TRAP; @@ -874,7 +876,8 @@ static void remove_bpts(void) continue; if (mread(bp->address, , 4) == 4 && instr == bpinstr - && mwrite(bp->address, >instr, 4) != 4) + && patch_instruction( + (unsigned int *)bp->address, bp->instr[0]) != 0) printf("Couldn't remove breakpoint at %lx\n", bp->address); else -- 2.9.3
[PATCH v2 3/9] powerpc/kprobes/optprobes: Move over to patch_instruction
With text moving to read-only migrate optprobes to using the patch_instruction infrastructure. Without this optprobes will fail and complain. Signed-off-by: Balbir Singh--- arch/powerpc/kernel/optprobes.c | 58 ++--- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c index ec60ed0..1c7326c 100644 --- a/arch/powerpc/kernel/optprobes.c +++ b/arch/powerpc/kernel/optprobes.c @@ -158,12 +158,13 @@ void arch_remove_optimized_kprobe(struct optimized_kprobe *op) void patch_imm32_load_insns(unsigned int val, kprobe_opcode_t *addr) { /* addis r4,0,(insn)@h */ - *addr++ = PPC_INST_ADDIS | ___PPC_RT(4) | - ((val >> 16) & 0x); + patch_instruction((unsigned int *)addr, PPC_INST_ADDIS | ___PPC_RT(4) | + ((val >> 16) & 0x)); + addr++; /* ori r4,r4,(insn)@l */ - *addr = PPC_INST_ORI | ___PPC_RA(4) | ___PPC_RS(4) | - (val & 0x); + patch_instruction((unsigned int *)addr, PPC_INST_ORI | ___PPC_RA(4) | + ___PPC_RS(4) | (val & 0x)); } /* @@ -173,24 +174,28 @@ void patch_imm32_load_insns(unsigned int val, kprobe_opcode_t *addr) void patch_imm64_load_insns(unsigned long val, kprobe_opcode_t *addr) { /* lis r3,(op)@highest */ - *addr++ = PPC_INST_ADDIS | ___PPC_RT(3) | - ((val >> 48) & 0x); + patch_instruction((unsigned int *)addr, PPC_INST_ADDIS | ___PPC_RT(3) | + ((val >> 48) & 0x)); + addr++; /* ori r3,r3,(op)@higher */ - *addr++ = PPC_INST_ORI | ___PPC_RA(3) | ___PPC_RS(3) | - ((val >> 32) & 0x); + patch_instruction((unsigned int *)addr, PPC_INST_ORI | ___PPC_RA(3) | + ___PPC_RS(3) | ((val >> 32) & 0x)); + addr++; /* rldicr r3,r3,32,31 */ - *addr++ = PPC_INST_RLDICR | ___PPC_RA(3) | ___PPC_RS(3) | - __PPC_SH64(32) | __PPC_ME64(31); + patch_instruction((unsigned int *)addr, PPC_INST_RLDICR | ___PPC_RA(3) | + ___PPC_RS(3) | __PPC_SH64(32) | __PPC_ME64(31)); + addr++; /* oris r3,r3,(op)@h */ - *addr++ = PPC_INST_ORIS | ___PPC_RA(3) | ___PPC_RS(3) | - ((val >> 16) & 0x); + patch_instruction((unsigned int *)addr, PPC_INST_ORIS | ___PPC_RA(3) | + ___PPC_RS(3) | ((val >> 16) & 0x)); + addr++; /* ori r3,r3,(op)@l */ - *addr = PPC_INST_ORI | ___PPC_RA(3) | ___PPC_RS(3) | - (val & 0x); + patch_instruction((unsigned int *)addr, PPC_INST_ORI | ___PPC_RA(3) | + ___PPC_RS(3) | (val & 0x)); } int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p) @@ -198,7 +203,8 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p) kprobe_opcode_t *buff, branch_op_callback, branch_emulate_step; kprobe_opcode_t *op_callback_addr, *emulate_step_addr; long b_offset; - unsigned long nip; + unsigned long nip, size; + int rc, i; kprobe_ppc_optinsn_slots.insn_size = MAX_OPTINSN_SIZE; @@ -231,8 +237,15 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p) goto error; /* Setup template */ - memcpy(buff, optprobe_template_entry, - TMPL_END_IDX * sizeof(kprobe_opcode_t)); + /* We can optimize this via patch_instruction_window later */ + size = (TMPL_END_IDX * sizeof(kprobe_opcode_t)) / sizeof(int); + pr_devel("Copying template to %p, size %lu\n", buff, size); + for (i = 0; i < size; i++) { + rc = patch_instruction((unsigned int *)buff + i, + *((unsigned int *)(optprobe_template_entry) + i)); + if (rc < 0) + goto error; + } /* * Fixup the template with instructions to: @@ -261,8 +274,10 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p) if (!branch_op_callback || !branch_emulate_step) goto error; - buff[TMPL_CALL_HDLR_IDX] = branch_op_callback; - buff[TMPL_EMULATE_IDX] = branch_emulate_step; + patch_instruction((unsigned int *)buff + TMPL_CALL_HDLR_IDX, + branch_op_callback); + patch_instruction((unsigned int *)buff + TMPL_EMULATE_IDX, + branch_emulate_step); /* * 3. load instruction to be emulated into relevant register, and @@ -272,8 +287,9 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p) /* * 4. branch back from
[PATCH v2 2/9] powerpc/kprobes: Move kprobes over to patch_instruction
arch_arm/disarm_probe use direct assignment for copying instructions, replace them with patch_instruction Signed-off-by: Balbir Singh--- arch/powerpc/kernel/kprobes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index fc43435..b49f8f0 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -158,7 +158,7 @@ NOKPROBE_SYMBOL(arch_prepare_kprobe); void arch_arm_kprobe(struct kprobe *p) { - *p->addr = BREAKPOINT_INSTRUCTION; + patch_instruction(p->addr, BREAKPOINT_INSTRUCTION); flush_icache_range((unsigned long) p->addr, (unsigned long) p->addr + sizeof(kprobe_opcode_t)); } @@ -166,7 +166,7 @@ NOKPROBE_SYMBOL(arch_arm_kprobe); void arch_disarm_kprobe(struct kprobe *p) { - *p->addr = p->opcode; + patch_instruction(p->addr, p->opcode); flush_icache_range((unsigned long) p->addr, (unsigned long) p->addr + sizeof(kprobe_opcode_t)); } -- 2.9.3
[PATCH v2 1/9] powerpc/lib/code-patching: Enhance code patching
Today our patching happens via direct copy and patch_instruction. The patching code is well contained in the sense that copying bits are limited. While considering implementation of CONFIG_STRICT_RWX, the first requirement is to a create another mapping that will allow for patching. We create the window using text_poke_area, allocated via get_vm_area(), which might be an overkill. text_poke_area is per CPU to avoid locking Other arches do similar things, but use fixmaps. The reason for not using fixmaps is to make use of any randomization in the future. The code also relies on set_pte_at and pte_clear to do the appropriate tlb flushing. Signed-off-by: Balbir Singh--- arch/powerpc/lib/code-patching.c | 137 +-- 1 file changed, 133 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c index 500b0f6..eb26b16 100644 --- a/arch/powerpc/lib/code-patching.c +++ b/arch/powerpc/lib/code-patching.c @@ -12,23 +12,151 @@ #include #include #include +#include #include #include #include #include +#include +#include +static DEFINE_PER_CPU(struct vm_struct *, text_poke_area); +static unsigned int text_area_patch_avail; -int patch_instruction(unsigned int *addr, unsigned int instr) +static int text_area_cpu_up(unsigned int cpu) +{ + struct vm_struct *area; + + area = get_vm_area(PAGE_SIZE, VM_ALLOC); + if (!area) { + WARN_ONCE(1, "Failed to create text area for cpu %d\n", + cpu); + return -1; + } + this_cpu_write(text_poke_area, area); + return 0; +} + +static int text_area_cpu_down(unsigned int cpu) +{ + free_vm_area(this_cpu_read(text_poke_area)); + return 0; +} + +/* + * This is an early_initcall and early_initcalls happen at the right time + * for us, after slab is enabled and before we mark ro pages R/O. In the + * future if get_vm_area is randomized, this will be more flexible than + * fixmap + */ +static int __init setup_text_poke_area(void) { + struct vm_struct *area; + int cpu; + + for_each_online_cpu(cpu) { + area = get_vm_area(PAGE_SIZE, VM_ALLOC); + if (!area) { + WARN_ONCE(1, "Failed to create text area for cpu %d\n", + cpu); + /* Should we disable strict rwx? */ + continue; + } + this_cpu_write(text_poke_area, area); + } + cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, + "powerpc/text_poke:online", text_area_cpu_up, + text_area_cpu_down); + text_area_patch_avail = 1; + /* +* The barrier here ensures the write is visible to +* patch_instruction() +*/ + smp_wmb(); + pr_info("text_poke area ready...\n"); + return 0; +} + +/* + * This can be called for kernel text or a module. + */ +static int kernel_map_addr(void *addr) +{ + unsigned long pfn; int err; - __put_user_size(instr, addr, 4, err); + if (is_vmalloc_addr(addr)) + pfn = vmalloc_to_pfn(addr); + else + pfn = __pa_symbol(addr) >> PAGE_SHIFT; + + err = map_kernel_page( + (unsigned long)__this_cpu_read(text_poke_area)->addr, + (pfn << PAGE_SHIFT), _PAGE_KERNEL_RW | _PAGE_PRESENT); + pr_devel("Mapped addr %p with pfn %lx\n", + __this_cpu_read(text_poke_area)->addr, pfn); if (err) - return err; - asm ("dcbst 0, %0; sync; icbi 0,%0; sync; isync" : : "r" (addr)); + return -1; return 0; } +static inline void kernel_unmap_addr(void *addr) +{ + pte_t *pte; + unsigned long kaddr = (unsigned long)addr; + + pte = pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(kaddr), + kaddr), kaddr), kaddr); + pr_devel("clearing mm %p, pte %p, kaddr %lx\n", _mm, pte, kaddr); + pte_clear(_mm, kaddr, pte); + flush_tlb_kernel_range(kaddr, kaddr + PAGE_SIZE); +} + +int patch_instruction(unsigned int *addr, unsigned int instr) +{ + int err; + unsigned int *dest = NULL; + unsigned long flags; + unsigned long kaddr = (unsigned long)addr; + + /* +* Make sure we can see any write of text_area_patch_avail +*/ + smp_rmb(); + + /* +* During early early boot patch_instruction is called +* when text_poke_area is not ready, but we still need +* to allow patching. We just do the plain old patching +* We use text_area_patch_avail, since per cpu read +* via __this_cpu_read of text_poke_area might not +* yet be available. +* TODO: Make text_area_patch_avail per cpu? +*/ + if (!text_area_patch_avail) { +
[PATCH v2 0/9] Enable STRICT_KERNEL_RWX
Enable STRICT_KERNEL_RWX for PPC64/BOOK3S These patches enable RX mappings of kernel text. rodata is mapped RX as well as a trade-off, there are more details in the patch description As a prerequisite for R/O text, patch_instruction is moved over to using a separate mapping that allows write to kernel text. xmon/ftrace/kprobes have been moved over to work with patch_instruction There are a few bug fixes, the updatepp and updateboltedpp did not use flags as described in PAPR and the ptdump utility ignored the first PFN TODOs: 1. Radix support 2. 32 bit support For Radix support, it should be simple, we need to revisit the way linear mapping is done for text, avoid any 1G maps to make sure we use 2M and then protect at that granularity. I will send a follow-up patch to this series adding radix support There are patches for 32 bit support from Christophe Leroy at http://patchwork.ozlabs.org/patch/768257/. The patches for map_page to map_kernel_page are a pre-requisite. Another build failure was reported, because instead of using ARCH_HAS_SET_MEMORY as a gate for set_memory.h inclusion, some of the infrastructure in the core kernel uses CONFIG_STRICT_KERNEL_RWX. Balbir Singh (9): powerpc/lib/code-patching: Enhance code patching powerpc/kprobes: Move kprobes over to patch_instruction powerpc/kprobes/optprobes: Move over to patch_instruction powerpc/xmon: Add patch_instruction supporf for xmon powerpc/vmlinux.lds: Align __init_begin to 16M powerpc/platform/pseries/lpar: Fix updatepp and updateboltedpp powerpc/mm/hash: Implement mark_rodata_ro() for hash powerpc/Kconfig: Enable STRICT_KERNEL_RWX powerpc/mm/ptdump: Dump the first entry of the linear mapping as well arch/powerpc/Kconfig | 1 + arch/powerpc/include/asm/book3s/64/hash.h | 3 + arch/powerpc/include/asm/book3s/64/radix.h | 4 + arch/powerpc/kernel/kprobes.c | 4 +- arch/powerpc/kernel/optprobes.c| 58 - arch/powerpc/kernel/vmlinux.lds.S | 10 ++- arch/powerpc/lib/code-patching.c | 127 - arch/powerpc/mm/dump_hashpagetable.c | 2 +- arch/powerpc/mm/pgtable-hash64.c | 35 arch/powerpc/mm/pgtable-radix.c| 7 ++ arch/powerpc/mm/pgtable_64.c | 9 ++ arch/powerpc/platforms/pseries/lpar.c | 13 ++- arch/powerpc/xmon/xmon.c | 7 +- 13 files changed, 246 insertions(+), 34 deletions(-) -- 2.9.3