[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v4 1/3] xen/arm: add support for run_in_exception_handler()
Hi Juergen, On 14/12/2020 07:56, Juergen Gross wrote: Add support to run a function in an exception handler for Arm. Do it the same way as on x86 via a bug_frame. Unfortunately inline assembly on Arm seems to be less capable than on x86, leading to functions called via run_in_exception_handler() having to be globally visible. Jan already commented on this, so I am not going to comment again. Signed-off-by: Juergen Gross <jgross@xxxxxxxx> --- V4: - new patch I have verified the created bugframe is correct by inspecting the created binary. Signed-off-by: Juergen Gross <jgross@xxxxxxxx> --- xen/arch/arm/traps.c | 10 +++++++++- xen/drivers/char/ns16550.c | 3 ++- xen/include/asm-arm/bug.h | 32 +++++++++++++++++++++----------- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index 22bd1bd4c6..6e677affe2 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -1236,8 +1236,16 @@ int do_bug_frame(const struct cpu_user_regs *regs, vaddr_t pc) if ( !bug ) return -ENOENT;+ if ( id == BUGFRAME_run_fn )+ { + void (*fn)(const struct cpu_user_regs *) = bug_ptr(bug); + + fn(regs); + return 0; + } + /* WARN, BUG or ASSERT: decode the filename pointer and line number. */ - filename = bug_file(bug); + filename = bug_ptr(bug); if ( !is_kernel(filename) ) return -EINVAL; fixup = strlen(filename); diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c index 9235d854fe..dd6500acc8 100644 --- a/xen/drivers/char/ns16550.c +++ b/xen/drivers/char/ns16550.c @@ -192,7 +192,8 @@ static void ns16550_interrupt( /* Safe: ns16550_poll() runs as softirq so not reentrant on a given CPU. */ static DEFINE_PER_CPU(struct serial_port *, poll_port);-static void __ns16550_poll(struct cpu_user_regs *regs)+/* run_in_exception_handler() on Arm requires globally visible symbol. */ +void __ns16550_poll(struct cpu_user_regs *regs) { struct serial_port *port = this_cpu(poll_port); struct ns16550 *uart = port->uart; diff --git a/xen/include/asm-arm/bug.h b/xen/include/asm-arm/bug.h index 36c803357c..a7da2c306f 100644 --- a/xen/include/asm-arm/bug.h +++ b/xen/include/asm-arm/bug.h @@ -15,34 +15,38 @@struct bug_frame {signed int loc_disp; /* Relative address to the bug address */ - signed int file_disp; /* Relative address to the filename */ + signed int ptr_disp; /* Relative address to the filename or function */ signed int msg_disp; /* Relative address to the predicate (for ASSERT) */ uint16_t line; /* Line number */ uint32_t pad0:16; /* Padding for 8-bytes align */ };#define bug_loc(b) ((const void *)(b) + (b)->loc_disp)-#define bug_file(b) ((const void *)(b) + (b)->file_disp); +#define bug_ptr(b) ((const void *)(b) + (b)->ptr_disp); #define bug_line(b) ((b)->line) #define bug_msg(b) ((const char *)(b) + (b)->msg_disp)-#define BUGFRAME_warn 0-#define BUGFRAME_bug 1 -#define BUGFRAME_assert 2 +#define BUGFRAME_run_fn 0 +#define BUGFRAME_warn 1 +#define BUGFRAME_bug 2 +#define BUGFRAME_assert 3 Why did you renumber it? IOW, why can't BUGFRAME_run_fn be defined as 3? -#define BUGFRAME_NR 3+#define BUGFRAME_NR 4/* Many versions of GCC doesn't support the asm %c parameter which would* be preferable to this unpleasantness. We use mergeable string * sections to avoid multiple copies of the string appearing in the * Xen image. */ -#define BUG_FRAME(type, line, file, has_msg, msg) do { \ +#define BUG_FRAME(type, line, ptr, ptr_is_file, has_msg, msg) do { \ BUILD_BUG_ON((line) >> 16); \ BUILD_BUG_ON((type) >= BUGFRAME_NR); \ asm ("1:"BUG_INSTR"\n" \ ".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \ - "2:\t.asciz " __stringify(file) "\n" \ + "2:\n" \ + ".if " #ptr_is_file "\n" \ + "\t.asciz " __stringify(ptr) "\n" \ + ".endif\n" \ "3:\n" \ ".if " #has_msg "\n" \ "\t.asciz " #msg "\n" \ @@ -52,21 +56,27 @@ struct bug_frame { "4:\n" \ ".p2align 2\n" \ ".long (1b - 4b)\n" \ + ".if " #ptr_is_file "\n" \ ".long (2b - 4b)\n" \ + ".else\n" \ + ".long (" #ptr " - 4b)\n" \ + ".endif\n" \ ".long (3b - 4b)\n" \ ".hword " __stringify(line) ", 0\n" \ ".popsection"); \ } while (0)-#define WARN() BUG_FRAME(BUGFRAME_warn, __LINE__, __FILE__, 0, "")+#define run_in_exception_handler(fn) BUG_FRAME(BUGFRAME_run_fn, 0, fn, 0, 0, "") + +#define WARN() BUG_FRAME(BUGFRAME_warn, __LINE__, __FILE__, 1, 0, "")#define BUG() do { \- BUG_FRAME(BUGFRAME_bug, __LINE__, __FILE__, 0, ""); \ + BUG_FRAME(BUGFRAME_bug, __LINE__, __FILE__, 1, 0, ""); \ unreachable(); \ } while (0)#define assert_failed(msg) do { \- BUG_FRAME(BUGFRAME_assert, __LINE__, __FILE__, 1, msg); \ + BUG_FRAME(BUGFRAME_assert, __LINE__, __FILE__, 1, 1, msg); \ unreachable(); \ } while (0) Cheers, -- Julien Grall
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |