0

I am working on a custom version of Rocket Chip that features some extra instructions that I would like to be properly handled by Linux. Although bare-metal programs using these instructions run fine, Linux makes the same benchmarks crash with "Illegal Instruction" messages.

Does anyone know which software element of Linux - loader, disassembler, something else - is responsible for detecting illegal instructions?

My goal is to modify that piece of software so that Linux stops complaining about my instructions. If anyone knows about an easier way to suppress this kind of error, that would be very useful too.

  • Are those instructions considered privileged by the processor? If so, the problem may not be with Linux so much as the fact that you're running in user mode and not kernel mode when you run an application in an OS. – merlin2011 Aug 13 '18 at 17:58
  • The processor generates the trap. The OS handles the trap and usually kills your app. ARM has Exception Levels (EL). User land is EL0. You have to be privileged for instructions at EL1 and above. – jww Aug 14 '18 at 00:54
  • I just figured out that I should have set bit 0x8000 of a certain CSR (`mstatus`) to enable the execution of the custom instructions. It was really the processor that was generating the illegal instruction traps. Now everything is working. Thanks to @merlin2011 and @jww for the help. – Lucas Morais Aug 15 '18 at 20:23

1 Answers1

1

The RISC-V implementation (the processor) raises an illegal instruction trap whenever it encounters an instruction it has not implemented. These illegal instruction traps will be piped through to Linux (either via trap delegation or after being handled by the machine-mode software), which then flow through the standard trap handling flow:

  • strapvec points to Handle_exception, which does a bunch of bookkeeping to avoid trashing userspace and then direct traps to the correct location.
  • For illegal instruction traps, you'll fall through to the excp_vect_table jump table, which handles all the boring traps.
  • This is indexed by scause, which in this case points to do_trap_insn_illegal.
  • do_trap_insn_illegal is just a generic Linux trap handler, it passes SIGILL to whatever caused the trap. This may raise a signal to a userspace task, a kernel task, or just panic the kernel directly.

There are a bunch of levels of indirection here that we're currently not doing anything with, but may serve to emulate unimplemented instructions in the future.

Palmer Dabbelt
  • 980
  • 5
  • 8