| From foo@baz Wed Jan 3 20:37:21 CET 2018 |
| From: Hugh Dickins <hughd@google.com> |
| Date: Sun, 3 Sep 2017 18:57:03 -0700 |
| Subject: kaiser: stack map PAGE_SIZE at THREAD_SIZE-PAGE_SIZE |
| |
| From: Hugh Dickins <hughd@google.com> |
| |
| |
| Kaiser only needs to map one page of the stack; and |
| kernel/fork.c did not build on powerpc (no __PAGE_KERNEL). |
| It's all cleaner if linux/kaiser.h provides kaiser_map_thread_stack() |
| and kaiser_unmap_thread_stack() wrappers around asm/kaiser.h's |
| kaiser_add_mapping() and kaiser_remove_mapping(). And use |
| linux/kaiser.h in init/main.c to avoid the #ifdefs there. |
| |
| Signed-off-by: Hugh Dickins <hughd@google.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| include/linux/kaiser.h | 40 +++++++++++++++++++++++++++++++++------- |
| init/main.c | 6 +----- |
| kernel/fork.c | 7 ++----- |
| 3 files changed, 36 insertions(+), 17 deletions(-) |
| |
| --- a/include/linux/kaiser.h |
| +++ b/include/linux/kaiser.h |
| @@ -1,26 +1,52 @@ |
| -#ifndef _INCLUDE_KAISER_H |
| -#define _INCLUDE_KAISER_H |
| +#ifndef _LINUX_KAISER_H |
| +#define _LINUX_KAISER_H |
| |
| #ifdef CONFIG_KAISER |
| #include <asm/kaiser.h> |
| + |
| +static inline int kaiser_map_thread_stack(void *stack) |
| +{ |
| + /* |
| + * Map that page of kernel stack on which we enter from user context. |
| + */ |
| + return kaiser_add_mapping((unsigned long)stack + |
| + THREAD_SIZE - PAGE_SIZE, PAGE_SIZE, __PAGE_KERNEL); |
| +} |
| + |
| +static inline void kaiser_unmap_thread_stack(void *stack) |
| +{ |
| + /* |
| + * Note: may be called even when kaiser_map_thread_stack() failed. |
| + */ |
| + kaiser_remove_mapping((unsigned long)stack + |
| + THREAD_SIZE - PAGE_SIZE, PAGE_SIZE); |
| +} |
| #else |
| |
| /* |
| * These stubs are used whenever CONFIG_KAISER is off, which |
| - * includes architectures that support KAISER, but have it |
| - * disabled. |
| + * includes architectures that support KAISER, but have it disabled. |
| */ |
| |
| static inline void kaiser_init(void) |
| { |
| } |
| -static inline void kaiser_remove_mapping(unsigned long start, unsigned long size) |
| +static inline int kaiser_add_mapping(unsigned long addr, |
| + unsigned long size, unsigned long flags) |
| +{ |
| + return 0; |
| +} |
| +static inline void kaiser_remove_mapping(unsigned long start, |
| + unsigned long size) |
| { |
| } |
| -static inline int kaiser_add_mapping(unsigned long addr, unsigned long size, unsigned long flags) |
| +static inline int kaiser_map_thread_stack(void *stack) |
| { |
| return 0; |
| } |
| +static inline void kaiser_unmap_thread_stack(void *stack) |
| +{ |
| +} |
| |
| #endif /* !CONFIG_KAISER */ |
| -#endif /* _INCLUDE_KAISER_H */ |
| +#endif /* _LINUX_KAISER_H */ |
| --- a/init/main.c |
| +++ b/init/main.c |
| @@ -80,15 +80,13 @@ |
| #include <linux/integrity.h> |
| #include <linux/proc_ns.h> |
| #include <linux/io.h> |
| +#include <linux/kaiser.h> |
| |
| #include <asm/io.h> |
| #include <asm/bugs.h> |
| #include <asm/setup.h> |
| #include <asm/sections.h> |
| #include <asm/cacheflush.h> |
| -#ifdef CONFIG_KAISER |
| -#include <asm/kaiser.h> |
| -#endif |
| |
| static int kernel_init(void *); |
| |
| @@ -476,9 +474,7 @@ static void __init mm_init(void) |
| pgtable_init(); |
| vmalloc_init(); |
| ioremap_huge_init(); |
| -#ifdef CONFIG_KAISER |
| kaiser_init(); |
| -#endif |
| } |
| |
| asmlinkage __visible void __init start_kernel(void) |
| --- a/kernel/fork.c |
| +++ b/kernel/fork.c |
| @@ -212,12 +212,9 @@ static unsigned long *alloc_thread_stack |
| #endif |
| } |
| |
| -extern void kaiser_remove_mapping(unsigned long start_addr, unsigned long size); |
| static inline void free_thread_stack(struct task_struct *tsk) |
| { |
| -#ifdef CONFIG_KAISER |
| - kaiser_remove_mapping((unsigned long)tsk->stack, THREAD_SIZE); |
| -#endif |
| + kaiser_unmap_thread_stack(tsk->stack); |
| #ifdef CONFIG_VMAP_STACK |
| if (task_stack_vm_area(tsk)) { |
| unsigned long flags; |
| @@ -501,7 +498,7 @@ static struct task_struct *dup_task_stru |
| */ |
| tsk->stack = stack; |
| |
| - err= kaiser_add_mapping((unsigned long)tsk->stack, THREAD_SIZE, __PAGE_KERNEL); |
| + err= kaiser_map_thread_stack(tsk->stack); |
| if (err) |
| goto free_stack; |
| #ifdef CONFIG_VMAP_STACK |