Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
arch: riscv32: fix IRQ handling bugs when benchmarking
The way that CONFIG_EXECUTION_BENCHMARKING=y is handled on this architecture is incorrect. The goals are: - call read_timer_start_of_isr() as close as possible to the beginning of the ISR - call read_timer_end_of_isr() after all preparations have been made to call the driver-level IRQ handler, but it hasn't been called yet The current implementation could cause kernel crashes, though. The read_timer_start_of_isr() call is made before saving MEPC or any SoC-specific context. The MEPC issue is not that big of a deal, but doing it before saving SoC context could clobber state that hasn't been saved yet and corrupt the kernel. One example is a pulpino style RISC-V SoC. Some Pulpino cores have extra registers that are used for ISA extensions used to generate code for C loops. There's no guarantee read_timer_start_of_isr() will never have a loop inside: in fact, the RISC-V User-Level ISA v2.2 explicitly recommends using a loop to get the 64-bit value of the "cycle" CSR. A Pulpino-like SoC with a cycle CSR could thus naturally have a read_timer_start_of_isr() implementation that involves loops. Saving the loop state before reading the timer would then be needed. Fix this issue by moving the call to read_timer_start_of_isr to after all context saving is done. (This is a fairer comparison to Arm Cortex-M SoCs anyway, since register stacking is performed in hardware on Cortex M and is done before the first ISR instruction executes.) The call to read_timer_end_of_isr() has an issue as well: it's called after the ISR's argument has been stored in a0 and the ISR address is in t1, but before actually calling the ISR itself. In the standard RV32I calling convention, both t1 and a0 are caller saved, so read_timer_end_of_isr() is within its rights to set them to any garbage, which we'll happily treat as a function and its argument and execute. Avoid that possibility by saving the register values to the stack in this configuration. Signed-off-by: Marti Bolivar <[email protected]>
- Loading branch information