From: Ahmad Fatoum <a.fatoum@pengutronix.de>
To: barebox@lists.infradead.org
Cc: Ahmad Fatoum <a.fatoum@pengutronix.de>
Subject: [PATCH 7/9] bthread: move asan fiber API into header
Date: Mon, 25 Nov 2024 16:35:21 +0100 [thread overview]
Message-ID: <20241125153523.1411849-8-a.fatoum@pengutronix.de> (raw)
In-Reply-To: <20241125153523.1411849-1-a.fatoum@pengutronix.de>
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@pengutronix.de>
---
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
next prev parent reply other threads:[~2024-11-25 15:36 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-25 15:35 [PATCH 0/9] sandbox: use native setjmp/longjmp/initjmp implementation by default Ahmad Fatoum
2024-11-25 15:35 ` [PATCH 1/9] sandbox: asm: support inclusion from sandbox os support code Ahmad Fatoum
2024-11-25 15:35 ` [PATCH 2/9] test: self: setjmp: add simple initial testcase Ahmad Fatoum
2024-11-25 15:35 ` [PATCH 3/9] sandbox: source/invoke um Makefiles provided by host architecture Ahmad Fatoum
2024-11-25 15:35 ` [PATCH 4/9] sandbox: setjmp: mark C version as __weak Ahmad Fatoum
2024-11-25 15:35 ` [PATCH 5/9] sandbox: use native setjmp/longjmp/initjmp implementation by default Ahmad Fatoum
2024-11-25 15:35 ` [PATCH 6/9] sandbox: retire HAVE_ARCH_ASAN Ahmad Fatoum
2024-11-25 15:35 ` Ahmad Fatoum [this message]
2024-11-25 15:35 ` [PATCH 8/9] test: self: setjmp: make compatible with ASAN Ahmad Fatoum
2024-11-25 15:35 ` [PATCH 9/9] bthread: fix use of ASAN fiber stack switch API Ahmad Fatoum
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241125153523.1411849-8-a.fatoum@pengutronix.de \
--to=a.fatoum@pengutronix.de \
--cc=barebox@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox