lib: Handle traps when doing unpriv load/store in get_insn()

We can get a page/access trap when doing unpriv load/store in
get_insn() function because on a SMP system Linux swapper running
on HART A can unmap pages from page table used by HART B.

To tackle this we extend get_insn() implementation so that if
we get trap in get_insn() then we redirect it to S-mode as fetch
page/access fault.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
This commit is contained in:
Anup Patel
2019-08-12 11:50:22 +05:30
parent 2e0f3ac758
commit a88e424f6c
4 changed files with 65 additions and 46 deletions

View File

@@ -117,10 +117,15 @@ int sbi_illegal_insn_handler(u32 hartid, ulong mcause,
struct sbi_scratch *scratch)
{
ulong insn = csr_read(mbadaddr);
struct unpriv_trap uptrap;
if (unlikely((insn & 3) != 3)) {
if (insn == 0)
insn = get_insn(regs->mepc, NULL);
if (insn == 0) {
insn = get_insn(regs->mepc, scratch, &uptrap);
if (uptrap.cause)
return sbi_trap_redirect(regs, scratch,
regs->mepc, uptrap.cause, uptrap.tval);
}
if ((insn & 3) != 3)
return truly_illegal_insn(insn, hartid, mcause, regs,
scratch);