@@ -5,6 +5,7 @@ config RISCV
config RISCV_64
def_bool y
select 64BIT
+ select GENERIC_BUG_FRAME
config ARCH_DEFCONFIG
string
@@ -5,6 +5,7 @@
* RISC-V Trap handlers
*/
+#include <xen/bug.h>
#include <xen/lib.h>
#include <xen/sched.h>
@@ -101,8 +102,38 @@ static void do_unexpected_trap(const struct cpu_user_regs *regs)
die();
}
+static bool is_valid_bug_insn(uint32_t insn)
+{
+ return insn == BUG_INSN_32 ||
+ (insn & COMPRESSED_INSN_MASK) == BUG_INSN_16;
+}
+
+/* Should be used only on Xen code */
+static uint32_t read_instr(unsigned long pc)
+{
+ uint16_t instr16 = *(uint16_t *)pc;
+
+ ASSERT(is_kernel_text(pc + 1) || is_kernel_inittext(pc + 1));
+
+ if ( GET_INSN_LENGTH(instr16) == 2 )
+ return instr16;
+
+ ASSERT(is_kernel_text(pc + 3) || is_kernel_inittext(pc + 3));
+
+ return *(uint32_t *)pc;
+}
+
void do_trap(struct cpu_user_regs *cpu_regs)
{
+ register_t pc = cpu_regs->sepc;
+ uint32_t instr = read_instr(pc);
+
+ if ( ( is_valid_bug_insn(instr) ) && ( do_bug_frame(cpu_regs, pc) >= 0 ) )
+ {
+ cpu_regs->sepc += GET_INSN_LENGTH(instr);
+ return;
+ }
+
do_unexpected_trap(cpu_regs);
}
@@ -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>
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com> --- xen/arch/riscv/Kconfig | 1 + xen/arch/riscv/traps.c | 31 +++++++++++++++++++++++++++++++ xen/common/bug.c | 1 + 3 files changed, 33 insertions(+)