[PATCH 7/9] bthread: move asan fiber API into header

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Using the ASAN fibre API is essential, so the cooperative scheduling we
implement on top isn't flagged by AddressSanitizer.

To prepare using that code elsewhere later, move it to a common header.

Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx>
---
 arch/Kconfig                       |  3 ++
 arch/arm/include/asm/setjmp.h      |  2 +
 arch/kvx/include/asm/setjmp.h      |  2 +
 arch/mips/include/asm/setjmp.h     |  2 +
 arch/openrisc/include/asm/setjmp.h |  2 +
 arch/powerpc/include/asm/setjmp.h  |  2 +
 arch/riscv/include/asm/setjmp.h    |  2 +
 arch/sandbox/Kconfig               |  1 +
 arch/sandbox/include/asm/setjmp.h  | 42 ++++++++++++++++++++
 arch/x86/include/asm/setjmp.h      |  2 +
 common/bthread.c                   | 64 ++++++++----------------------
 include/asm-generic/setjmp.h       | 27 +++++++++++++
 12 files changed, 104 insertions(+), 47 deletions(-)
 create mode 100644 include/asm-generic/setjmp.h

diff --git a/arch/Kconfig b/arch/Kconfig
index ad47dbf78d6c..671e6a0e979d 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -18,3 +18,6 @@ config ARCH_HAS_CTRLC
 #
 config ARCH_DMA_DEFAULT_COHERENT
 	bool
+
+config ARCH_HAS_ASAN_FIBER_API
+	bool
diff --git a/arch/arm/include/asm/setjmp.h b/arch/arm/include/asm/setjmp.h
index 0cee5bfdda60..d28235e56c36 100644
--- a/arch/arm/include/asm/setjmp.h
+++ b/arch/arm/include/asm/setjmp.h
@@ -28,4 +28,6 @@ void longjmp(jmp_buf jmp, int ret) __attribute__((noreturn));
 
 int initjmp(jmp_buf jmp, void __attribute__((noreturn)) (*func)(void), void *stack_top);
 
+#include <asm-generic/setjmp.h>
+
 #endif /* _SETJMP_H_ */
diff --git a/arch/kvx/include/asm/setjmp.h b/arch/kvx/include/asm/setjmp.h
index 3c23576e6e82..7a09b182f251 100644
--- a/arch/kvx/include/asm/setjmp.h
+++ b/arch/kvx/include/asm/setjmp.h
@@ -12,4 +12,6 @@ int initjmp(jmp_buf jmp, void __attribute__((noreturn)) (*func)(void), void *sta
 int setjmp(jmp_buf jmp) __attribute__((returns_twice));
 void longjmp(jmp_buf jmp, int ret) __attribute__((noreturn));
 
+#include <asm-generic/setjmp.h>
+
 #endif /* _ASM_KVX_SETJMP_H_ */
diff --git a/arch/mips/include/asm/setjmp.h b/arch/mips/include/asm/setjmp.h
index 39e01e27dfc0..af25678573e7 100644
--- a/arch/mips/include/asm/setjmp.h
+++ b/arch/mips/include/asm/setjmp.h
@@ -29,4 +29,6 @@ int setjmp(jmp_buf jmp) __attribute__((returns_twice));
 void longjmp(jmp_buf jmp, int ret) __attribute__((noreturn));
 int initjmp(jmp_buf jmp, void __attribute__((noreturn)) (*func)(void), void *stack_top);
 
+#include <asm-generic/setjmp.h>
+
 #endif /* _MIPS_BITS_SETJMP_H */
diff --git a/arch/openrisc/include/asm/setjmp.h b/arch/openrisc/include/asm/setjmp.h
index ee73306d189d..d652e8a3cbcc 100644
--- a/arch/openrisc/include/asm/setjmp.h
+++ b/arch/openrisc/include/asm/setjmp.h
@@ -14,4 +14,6 @@ int setjmp(jmp_buf jmp) __attribute__((returns_twice));
 void longjmp(jmp_buf jmp, int ret) __attribute__((noreturn));
 int initjmp(jmp_buf jmp, void __attribute__((noreturn)) (*func)(void), void *stack_top);
 
+#include <asm-generic/setjmp.h>
+
 #endif /* _OR1K_BITS_SETJMP_H */
diff --git a/arch/powerpc/include/asm/setjmp.h b/arch/powerpc/include/asm/setjmp.h
index 91bfcdb7f442..1ece16bb7ea7 100644
--- a/arch/powerpc/include/asm/setjmp.h
+++ b/arch/powerpc/include/asm/setjmp.h
@@ -18,4 +18,6 @@ void longjmp(jmp_buf jmp, int ret) __attribute__((noreturn));
 
 int initjmp(jmp_buf jmp, void __attribute__((noreturn)) (*func)(void), void *stack_top);
 
+#include <asm-generic/setjmp.h>
+
 #endif /* _SETJMP_H_ */
diff --git a/arch/riscv/include/asm/setjmp.h b/arch/riscv/include/asm/setjmp.h
index 468fc4b10aaf..6604ba402bd9 100644
--- a/arch/riscv/include/asm/setjmp.h
+++ b/arch/riscv/include/asm/setjmp.h
@@ -24,4 +24,6 @@ void longjmp(jmp_buf jmp, int ret) __attribute__((noreturn));
 
 int initjmp(jmp_buf jmp, void __attribute__((noreturn)) (*func)(void), void *stack_top);
 
+#include <asm-generic/setjmp.h>
+
 #endif /* _SETJMP_H_ */
diff --git a/arch/sandbox/Kconfig b/arch/sandbox/Kconfig
index d4379c4d68db..932bfd15d212 100644
--- a/arch/sandbox/Kconfig
+++ b/arch/sandbox/Kconfig
@@ -43,6 +43,7 @@ config 64BIT
 	default CC_IS_64BIT
 	select ARCH_DMA_ADDR_T_64BIT
 	select PHYS_ADDR_T_64BIT
+	select ARCH_HAS_ASAN_FIBER_API if ASAN
 
 config 32BIT
 	def_bool !64BIT
diff --git a/arch/sandbox/include/asm/setjmp.h b/arch/sandbox/include/asm/setjmp.h
index dcc3b4e86712..65a6d5aafa87 100644
--- a/arch/sandbox/include/asm/setjmp.h
+++ b/arch/sandbox/include/asm/setjmp.h
@@ -1,4 +1,9 @@
 /* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * This file is included both in arch/sandbox/os along with
+ * system headers and outside with barebox headers, so we avoid
+ * including any other headers here.
+ */
 
 #ifndef __SETJMP_H_
 #define __SETJMP_H_
@@ -14,4 +19,41 @@ void longjmp(jmp_buf jmp, int ret) __attribute__((noreturn));
 
 int initjmp(jmp_buf jmp, void __attribute__((noreturn)) (*func)(void), void *stack_top);
 
+#define start_switch_fiber start_switch_fiber
+#define finish_switch_fiber finish_switch_fiber
+
+void __sanitizer_start_switch_fiber(void **fake_stack_save,
+                                    const void *bottom, size_t size)
+    __attribute__((visibility("default")));
+
+void __sanitizer_finish_switch_fiber(void *fake_stack_save,
+                                     const void **bottom_old, size_t *size_old)
+    __attribute__((visibility("default")));
+
+static inline void finish_switch_fiber(void *fake_stack_save,
+                                       void **initial_bottom,
+                                       unsigned *initial_stack_size)
+{
+#ifdef CONFIG_ARCH_HAS_ASAN_FIBER_API
+    const void *bottom_old;
+    size_t size_old;
+
+    __sanitizer_finish_switch_fiber(fake_stack_save,
+                                    &bottom_old, &size_old);
+
+    if (initial_bottom && !*initial_bottom) {
+        *initial_bottom = (void *)bottom_old;
+        *initial_stack_size = size_old;
+    }
+#endif
+}
+
+static inline void start_switch_fiber(void **fake_stack_save,
+                                      const void *bottom, unsigned size)
+{
+#ifdef CONFIG_ARCH_HAS_ASAN_FIBER_API
+    __sanitizer_start_switch_fiber(fake_stack_save, bottom, size);
+#endif
+}
+
 #endif
diff --git a/arch/x86/include/asm/setjmp.h b/arch/x86/include/asm/setjmp.h
index 5af5e624895c..e0f5771b06ba 100644
--- a/arch/x86/include/asm/setjmp.h
+++ b/arch/x86/include/asm/setjmp.h
@@ -41,4 +41,6 @@ void longjmp(jmp_buf jmp, int ret) __attribute__((noreturn)) __sjlj_attr;
 
 int initjmp(jmp_buf jmp, void __attribute__((noreturn)) (*func)(void), void *stack_top) __sjlj_attr;
 
+#include <asm-generic/setjmp.h>
+
 #endif
diff --git a/common/bthread.c b/common/bthread.c
index d40c0b0f9e3a..943f4c22b346 100644
--- a/common/bthread.c
+++ b/common/bthread.c
@@ -15,10 +15,6 @@
 #include <asm/setjmp.h>
 #include <linux/overflow.h>
 
-#if defined CONFIG_ASAN && !defined CONFIG_32BIT
-#define HAVE_FIBER_SANITIZER
-#endif
-
 static struct bthread {
 	void (*threadfn)(void *);
 	void *data;
@@ -27,7 +23,7 @@ static struct bthread {
 	void *stack;
 	u32 stack_size;
 	struct list_head list;
-#ifdef HAVE_FIBER_SANITIZER
+#ifdef CONFIG_ARCH_HAS_ASAN_FIBER_API
 	void *fake_stack_save;
 #endif
 	u8 awake :1;
@@ -45,12 +41,22 @@ struct bthread *current = &main_thread;
 /*
  * When using ASAN, it needs to be told when we switch stacks.
  */
-static void start_switch_fiber(struct bthread *, bool terminate_old);
-static void finish_switch_fiber(struct bthread *);
+static void bthread_finish_switch_fiber(struct bthread *bthread)
+{
+	finish_switch_fiber(bthread->fake_stack_save,
+			    &main_thread.stack, &main_thread.stack_size);
+}
+
+static void bthread_start_switch_fiber(struct bthread *to, bool terminate_old)
+{
+	start_switch_fiber(terminate_old ? &to->fake_stack_save : NULL,
+			   to->stack, to->stack_size);
+}
 
 static void __noreturn bthread_trampoline(void)
 {
-	finish_switch_fiber(current);
+	bthread_finish_switch_fiber(current);
+
 	bthread_reschedule();
 
 	current->threadfn(current->data);
@@ -59,7 +65,7 @@ static void __noreturn bthread_trampoline(void)
 	current->has_stopped = true;
 
 	current = &main_thread;
-	start_switch_fiber(current, true);
+	bthread_start_switch_fiber(current, true);
 	longjmp(current->jmp_buf, 1);
 }
 
@@ -198,7 +204,7 @@ void bthread_schedule(struct bthread *to)
 	struct bthread *from = current;
 	int ret;
 
-	start_switch_fiber(to, false);
+	bthread_start_switch_fiber(to, false);
 
 	ret = setjmp(from->jmp_buf);
 	if (ret == 0) {
@@ -206,41 +212,5 @@ void bthread_schedule(struct bthread *to)
 		longjmp(to->jmp_buf, 1);
 	}
 
-	finish_switch_fiber(from);
+	bthread_finish_switch_fiber(from);
 }
-
-#ifdef HAVE_FIBER_SANITIZER
-
-void __sanitizer_start_switch_fiber(void **fake_stack_save, const void *bottom, size_t size);
-void __sanitizer_finish_switch_fiber(void *fake_stack_save, const void **bottom_old, size_t *size_old);
-
-static void finish_switch_fiber(struct bthread *bthread)
-{
-	const void *bottom_old;
-	size_t size_old;
-
-	__sanitizer_finish_switch_fiber(bthread->fake_stack_save, &bottom_old, &size_old);
-
-	if (!main_thread.stack) {
-		main_thread.stack = (void *)bottom_old;
-		main_thread.stack_size = size_old;
-	}
-}
-
-static void start_switch_fiber(struct bthread *to, bool terminate_old)
-{
-	__sanitizer_start_switch_fiber(terminate_old ? &to->fake_stack_save : NULL,
-				       to->stack, to->stack_size);
-}
-
-#else
-
-static void finish_switch_fiber(struct bthread *bthread)
-{
-}
-
-static void start_switch_fiber(struct bthread *to, bool terminate_old)
-{
-}
-
-#endif
diff --git a/include/asm-generic/setjmp.h b/include/asm-generic/setjmp.h
new file mode 100644
index 000000000000..fb3e85ad5139
--- /dev/null
+++ b/include/asm-generic/setjmp.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * ASAN bookkeeping based on Qemu coroutine-ucontext.c
+ */
+
+#ifndef __ASM_GENERIC_SETJMP_H_
+#define __ASM_GENERIC_SETJMP_H_
+
+#ifndef finish_switch_fiber
+#define finish_switch_fiber finish_switch_fiber
+static inline void finish_switch_fiber(void *fake_stack_save,
+                                       void **initial_bottom,
+                                       unsigned *initial_stack_size)
+{
+}
+#endif
+
+#ifndef start_switch_fiber
+#define start_switch_fiber start_switch_fiber
+static inline void start_switch_fiber(void **fake_stack_save,
+                                      const void *bottom, unsigned size)
+{
+}
+
+#endif
+
+#endif
-- 
2.39.5





[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux