]> xenbits.xensource.com Git - xen.git/commitdiff
xen/riscv: enable GENERIC_BUG_FRAME
authorOleksii Kurochko <oleksii.kurochko@gmail.com>
Tue, 13 Aug 2024 14:38:15 +0000 (16:38 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 13 Aug 2024 14:38:15 +0000 (16:38 +0200)
Enable GENERIC_BUG_FRAME to support BUG(), WARN(), ASSERT,
and run_in_exception_handler().

"UNIMP" is used for BUG_INSTR, which, when macros from <xen/bug.h>
are used, triggers an exception with the ILLEGAL_INSTRUCTION cause.
This instruction is encoded as a 2-byte instruction when
CONFIG_RISCV_ISA_C is enabled:
  ffffffffc0046ba0:       0000                    unimp
and is encoded as a 4-byte instruction when CONFIG_RISCV_ISA_C
ins't enabled:
  ffffffffc005a460:       c0001073                unimp

Using 'ebreak' as BUG_INSTR does not guarantee proper handling of macros
from <xen/bug.h>. If a debugger inserts a breakpoint (using the 'ebreak'
instruction) at a location where Xen already uses 'ebreak', it
creates ambiguity. Xen cannot distinguish whether the 'ebreak'
instruction is inserted by the debugger or is part of Xen's own code.

Remove BUG_INSN_32 and BUG_INSN_16 macros as they encode the ebreak
instruction, which is no longer used for BUG_INSN.

Update the comment above the definition of INS_LENGTH_MASK as instead of
'ebreak' instruction 'unimp' instruction is used.

<xen/lib.h> is included for the reason that panic() and printk() are
used in common/bug.c and RISC-V fails if it is not included.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
xen/arch/riscv/Kconfig
xen/arch/riscv/include/asm/bug.h
xen/arch/riscv/traps.c
xen/common/bug.c

index b4b354a7786ed6decc78a3adbff32c7a102c7b42..f531e966575b7ef700e54978eab867d9e67b86d4 100644 (file)
@@ -1,6 +1,7 @@
 config RISCV
        def_bool y
        select FUNCTION_ALIGNMENT_16B
+       select GENERIC_BUG_FRAME
 
 config RISCV_64
        def_bool y
index f5ff96140f1a42913cfebc2aba73baa82b7cc253..e3d41f411a0bbb2fa6e968f78c31ff020ec47e52 100644 (file)
@@ -9,7 +9,7 @@
 
 #ifndef __ASSEMBLY__
 
-#define BUG_INSTR "ebreak"
+#define BUG_INSTR "unimp"
 
 /*
  * The base instruction set has a fixed length of 32-bit naturally aligned
  * There are extensions of variable length ( where each instruction can be
  * any number of 16-bit parcels in length ).
  *
- * Compressed ISA is used now where the instruction length is 16 bit  and
- * 'ebreak' instruction, in this case, can be either 16 or 32 bit (
+ * Compressed ISA is used now where the instruction length is 16 bit and
+ * 'unimp' instruction, in this case, can be either 16 or 32 bit (
  * depending on if compressed ISA is used or not )
  */
 #define INSN_LENGTH_MASK        _UL(0x3)
 #define INSN_LENGTH_32          _UL(0x3)
 
-#define BUG_INSN_32             _UL(0x00100073) /* ebreak */
-#define BUG_INSN_16             _UL(0x9002)     /* c.ebreak */
 #define COMPRESSED_INSN_MASK    _UL(0xffff)
 
 #define GET_INSN_LENGTH(insn)                               \
index 7149504ebc34418fec0a111360dc3e46f91c18be..d55a4a827b8c2138e47a32aa9302219df8a562b9 100644 (file)
@@ -5,6 +5,8 @@
  * RISC-V Trap handlers
  */
 
+#include <xen/bug.h>
+#include <xen/compiler.h>
 #include <xen/lib.h>
 #include <xen/nospec.h>
 #include <xen/sched.h>
@@ -106,7 +108,29 @@ static void do_unexpected_trap(const struct cpu_user_regs *regs)
 
 void do_trap(struct cpu_user_regs *cpu_regs)
 {
-    do_unexpected_trap(cpu_regs);
+    register_t pc = cpu_regs->sepc;
+    unsigned long cause = csr_read(CSR_SCAUSE);
+
+    switch ( cause )
+    {
+    case CAUSE_ILLEGAL_INSTRUCTION:
+        if ( do_bug_frame(cpu_regs, pc) >= 0 )
+        {
+            if ( !(is_kernel_text(pc) || is_kernel_inittext(pc)) )
+            {
+                printk("Something wrong with PC: %#lx\n", pc);
+                die();
+            }
+
+            cpu_regs->sepc += GET_INSN_LENGTH(*(uint16_t *)pc);
+
+            break;
+        }
+        fallthrough;
+    default:
+        do_unexpected_trap(cpu_regs);
+        break;
+    }
 }
 
 void vcpu_show_execution_state(struct vcpu *v)
index b7c5d8fd4d4a37a9fe8b0ceea1b0719726b37af0..75cb35fcfa58a3385cf9b50a99b1c2e8d45fec8e 100644 (file)
@@ -1,6 +1,7 @@
 #include <xen/bug.h>
 #include <xen/errno.h>
 #include <xen/kernel.h>
+#include <xen/lib.h>
 #include <xen/livepatch.h>
 #include <xen/string.h>
 #include <xen/types.h>