RISC-V return from exception handler with compressed instructions
Asked Answered
M

1

6

I see the standard way of exiting RISC-V exception handler is update mepc to mepc+4 before mret.

But won't this cause problem if the next instruction is only 2-bytes long in compressed instruction mode?

In compressed instruction mode there are mixed of 4-bytes and 2-bytes instructions. If you not update mepc and just mret then you keep getting same exception. But always adding 4 to trapped mepc seem like a bug for mixed compressed instruction.

Am I missing something?

Mischiefmaker answered 3/6, 2020 at 2:16 Comment(1)
@Dave2e, You closed this question as "needs details" without hinting what detail was missing. The question is perfectly clear to me, and, I so answered it before it was closed. Given a reasonable answer, the closing makes no sense.Haber
H
8

I see the standard way of exiting risc-v exception handler is update mepc to mepc+4 before mret.

These are not serious exception handlers; they are illustrative only — to show catching of exceptions at all, and returning back to the interrupted code without having done the actual exception processing needed for the given situation.  Thus, the easiest thing to do to prevent an infinite loop is to simply skip past the offending instruction.

One of the few places where we advance the pc in order to return to the code that cause the exception is in handling an ecall.  As far as I know there is no compressed (16-bit) ecall instruction.

Many resumable exceptions need to rerun the instruction that caused the exception — loads & stores that cause page faults (available in both 32-bit and 16-bit form), for example, need to re-execute once the page tables have been fixed (the page read in from disc and mapped into the user's address space).

Many other exceptions are not generally resumable.

However, emulation of an instruction requires knowing its size, as is the case with ecall.  if you choose to emulate, for example, misaligned memory accesses, you will indeed have to make a decision as to the size of the instruction, as emulating it means resuming past it.  Also note that RISC V supports 16-bit, 32-bit, 48-bit, 64-bit and longer instructions, so an exception handler that is going to emulate instructions will need to be able to decode their length (only the instructions chosen for emulation, though).

The other thing to add is that the sample exception handlers you may be looking at are designed to work without the compressed instruction set, and since RVC is optional that is a reasonable design choice (though ideally, of course, would be clearly stated).

Haber answered 3/6, 2020 at 5:30 Comment(4)
Most page faults aren't hard (page needed from disk), at least in most systems. Much more common are soft page faults from lazy allocation and/or CoW by the kernel. But sure, hard page faults work for an example.Sakmar
Thanks Erik for clearly lay out all the exceptions and how to handle them. So for my custom trap handler the solution is to decode the instruction size and adjust mepc accordingly before mret to resume To get instruction size I just look at the lower two bits of the instruction. xxxxaa != xxxx11 is 16 bits instruction.Mischiefmaker
Yes, that test should tell you whether to increment by 2 or 4. For external interrupts, don't adjust the pc, as we just want to resume the interrupted thread unmodified; Only adjust the pc if you are either emulating/simulating an excepting instruction, as is the case with ecall, or if you simply want to skip the excepting instruction.Haber
Great answer Erik. What about of software interrupts ? If I trigger one by writing to some MMIO register, shouldn't this be not resumable?Iden

© 2022 - 2024 — McMap. All rights reserved.