kaiser: stack map PAGE_SIZE at THREAD_SIZE-PAGE_SIZE
authorHugh Dickins <hughd@google.com>
Mon, 4 Sep 2017 01:57:03 +0000 (18:57 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 5 Jan 2018 14:46:32 +0000 (15:46 +0100)
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
init/main.c
kernel/fork.c

index 9db5433..4a4d6d9 100644 (file)
@@ -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 */
index 2c009f7..99f0265 100644 (file)
 #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)
index 0b9688d..70e10cb 100644 (file)
@@ -212,12 +212,9 @@ static unsigned long *alloc_thread_stack_node(struct task_struct *tsk, int node)
 #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_struct(struct task_struct *orig, int node)
         */
        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