@@ -12,6 +12,7 @@ config ARM_64
config ARM
def_bool y
+ select GENERIC_BUG_FRAME
select HAS_ALTERNATIVE
select HAS_DEVICE_TREE
select HAS_PASSTHROUGH
@@ -48,7 +48,7 @@ void do_trap_undefined_instruction(struct cpu_user_regs *regs)
if ( instr != BUG_OPCODE )
goto die;
- if ( do_bug_frame(regs, pc) )
+ if ( do_bug_frame(regs, pc) < 0 )
goto die;
regs->pc += 4;
@@ -10,6 +10,4 @@
#define BUG_INSTR ".word " __stringify(BUG_OPCODE)
-#define BUG_FN_REG r0
-
#endif /* __ARM_ARM32_BUG_H__ */
@@ -6,6 +6,4 @@
#define BUG_INSTR "brk " __stringify(BRK_BUG_FRAME_IMM)
-#define BUG_FN_REG x0
-
#endif /* __ARM_ARM64_BUG_H__ */
@@ -11,80 +11,7 @@
# error "unknown ARM variant"
#endif
-#define BUG_DISP_WIDTH 24
-#define BUG_LINE_LO_WIDTH (31 - BUG_DISP_WIDTH)
-#define BUG_LINE_HI_WIDTH (31 - BUG_DISP_WIDTH)
-
-#define BUG_FRAME_STRUCT
-
-struct bug_frame {
- signed int loc_disp; /* Relative address to the bug address */
- signed int file_disp; /* Relative address to the filename */
- 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_line(b) ((b)->line)
-#define bug_msg(b) ((const char *)(b) + (b)->msg_disp)
-
-/* 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. BUGFRAME_run_fn needs to be handled separately.
- */
-#define BUG_FRAME(type, line, 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" \
- "3:\n" \
- ".if " #has_msg "\n" \
- "\t.asciz " #msg "\n" \
- ".endif\n" \
- ".popsection\n" \
- ".pushsection .bug_frames." __stringify(type) ", \"a\", %progbits\n"\
- "4:\n" \
- ".p2align 2\n" \
- ".long (1b - 4b)\n" \
- ".long (2b - 4b)\n" \
- ".long (3b - 4b)\n" \
- ".hword " __stringify(line) ", 0\n" \
- ".popsection"); \
-} while (0)
-
-/*
- * GCC will not allow to use "i" when PIE is enabled (Xen doesn't set the
- * flag but instead rely on the default value from the compiler). So the
- * easiest way to implement run_in_exception_handler() is to pass the to
- * be called function in a fixed register.
- */
-#define run_in_exception_handler(fn) do { \
- asm ("mov " __stringify(BUG_FN_REG) ", %0\n" \
- "1:"BUG_INSTR"\n" \
- ".pushsection .bug_frames." __stringify(BUGFRAME_run_fn) "," \
- " \"a\", %%progbits\n" \
- "2:\n" \
- ".p2align 2\n" \
- ".long (1b - 2b)\n" \
- ".long 0, 0, 0\n" \
- ".popsection" :: "r" (fn) : __stringify(BUG_FN_REG) ); \
-} while (0)
-
-#define WARN() BUG_FRAME(BUGFRAME_warn, __LINE__, __FILE__, 0, "")
-
-#define BUG() do { \
- BUG_FRAME(BUGFRAME_bug, __LINE__, __FILE__, 0, ""); \
- unreachable(); \
-} while (0)
-
-#define assert_failed(msg) do { \
- BUG_FRAME(BUGFRAME_assert, __LINE__, __FILE__, 1, msg); \
- unreachable(); \
-} while (0)
+#define BUG_ASM_CONST "c"
#endif /* __ARM_BUG_H__ */
/*
@@ -69,8 +69,6 @@ void do_cp(struct cpu_user_regs *regs, const union hsr hsr);
void do_trap_smc(struct cpu_user_regs *regs, const union hsr hsr);
void do_trap_hvc_smccc(struct cpu_user_regs *regs);
-int do_bug_frame(const struct cpu_user_regs *regs, vaddr_t pc);
-
void noreturn do_unexpected_trap(const char *msg,
const struct cpu_user_regs *regs);
void do_trap_hyp_sync(struct cpu_user_regs *regs);
@@ -1197,85 +1197,6 @@ void do_unexpected_trap(const char *msg, const struct cpu_user_regs *regs)
panic("CPU%d: Unexpected Trap: %s\n", smp_processor_id(), msg);
}
-int do_bug_frame(const struct cpu_user_regs *regs, vaddr_t pc)
-{
- const struct bug_frame *bug = NULL;
- const char *prefix = "", *filename, *predicate;
- unsigned long fixup;
- int id = -1, lineno;
- const struct virtual_region *region;
-
- region = find_text_region(pc);
- if ( region )
- {
- for ( id = 0; id < BUGFRAME_NR; id++ )
- {
- const struct bug_frame *b;
- unsigned int i;
-
- for ( i = 0, b = region->frame[id].bugs;
- i < region->frame[id].n_bugs; b++, i++ )
- {
- if ( ((vaddr_t)bug_loc(b)) == pc )
- {
- bug = b;
- goto found;
- }
- }
- }
- }
- found:
- if ( !bug )
- return -ENOENT;
-
- if ( id == BUGFRAME_run_fn )
- {
- void (*fn)(const struct cpu_user_regs *) = (void *)regs->BUG_FN_REG;
-
- fn(regs);
- return 0;
- }
-
- /* WARN, BUG or ASSERT: decode the filename pointer and line number. */
- filename = bug_file(bug);
- if ( !is_kernel(filename) )
- return -EINVAL;
- fixup = strlen(filename);
- if ( fixup > 50 )
- {
- filename += fixup - 47;
- prefix = "...";
- }
- lineno = bug_line(bug);
-
- switch ( id )
- {
- case BUGFRAME_warn:
- printk("Xen WARN at %s%s:%d\n", prefix, filename, lineno);
- show_execution_state(regs);
- return 0;
-
- case BUGFRAME_bug:
- printk("Xen BUG at %s%s:%d\n", prefix, filename, lineno);
- show_execution_state(regs);
- panic("Xen BUG at %s%s:%d\n", prefix, filename, lineno);
-
- case BUGFRAME_assert:
- /* ASSERT: decode the predicate string pointer. */
- predicate = bug_msg(bug);
- if ( !is_kernel(predicate) )
- predicate = "<unknown>";
-
- printk("Assertion '%s' failed at %s%s:%d\n",
- predicate, prefix, filename, lineno);
- show_execution_state(regs);
- panic("Assertion '%s' failed at %s%s:%d\n",
- predicate, prefix, filename, lineno);
- }
-
- return -EINVAL;
-}
-
#ifdef CONFIG_ARM_64
static void do_trap_brk(struct cpu_user_regs *regs, const union hsr hsr)
{
@@ -1292,7 +1213,7 @@ static void do_trap_brk(struct cpu_user_regs *regs, const union hsr hsr)
switch ( hsr.brk.comment )
{
case BRK_BUG_FRAME_IMM:
- if ( do_bug_frame(regs, regs->pc) )
+ if ( do_bug_frame(regs, regs->pc) < 0 )
goto die;
regs->pc += 4;
@@ -46,11 +46,7 @@ int do_bug_frame(struct cpu_user_regs *regs, unsigned long pc)
if ( id == BUGFRAME_run_fn )
{
-#ifdef BUG_FN_REG
- void (*fn)(const struct cpu_user_regs *) = (void *)regs->BUG_FN_REG;
-#else
void (*fn)(const struct cpu_user_regs *) = bug_ptr(bug);
-#endif
fn(regs);
The following changes were made: * make GENERIC_BUG_FRAME mandatory for ARM * As do_bug_frame() returns -EINVAL in case something goes wrong otherwise id of bug frame. Thereby 'if' cases where do_bug_frame() was updated to check if the returned value is less than 0 * Switch ARM's implementation of bug.h macros to generic one Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com> --- Changes in V4: * Switch ARM implementation to generic one * Remove BUG_FN_REG from arm{16,32}/bug.h as it isn't needed after switch to generic implementation * Update commit message --- Changes in V3: * As prototype and what do_bug_frame() returns was changed so patch 3 and 4 was updated to use a new version of do_bug_frame --- Changes in V2: * Rename bug_file() in ARM implementation to bug_ptr() as generic do_bug_frame() uses bug_ptr(). * Remove generic parts from bug.h * Remove declaration of 'int do_bug_frame(...)' from <asm/traps.h> as it was introduced in <xen/bug.h> --- xen/arch/arm/Kconfig | 1 + xen/arch/arm/arm32/traps.c | 2 +- xen/arch/arm/include/asm/arm32/bug.h | 2 - xen/arch/arm/include/asm/arm64/bug.h | 2 - xen/arch/arm/include/asm/bug.h | 75 +------------------------- xen/arch/arm/include/asm/traps.h | 2 - xen/arch/arm/traps.c | 81 +--------------------------- xen/common/bug.c | 4 -- 8 files changed, 4 insertions(+), 165 deletions(-)