The stack pointer is swapped with the sscratch CSR just before the
jump to cpu_exception_handler_user where the first instruction swaps
it again. The two swaps together are a no-op, but the csr swap
instructions can be expensive (e.g. on Bluespec RISC-V cores csr swap
instructions force a full pipeline stall).
Details
Details
- Reviewers
br mhorne jrtc27 - Commits
- rS357313: Trim duplicate CSR swaps from user exceptions.
- booted in qemu
Diff Detail
Diff Detail
- Repository
- rS FreeBSD src repository - subversion
- Lint
Lint Not Applicable - Unit
Tests Not Applicable
Event Timeline
sys/riscv/riscv/exception.S | ||
---|---|---|
209 ↗ | (On Diff #67394) | So we check that the sscratch register is empty as a means of determining which mode we came from? I think this would be better as a check of the SPP bit in sstatus, because it looks like you could eliminate another double sscratch swap in the supervisor case. |
sys/riscv/riscv/exception.S | ||
---|---|---|
209 ↗ | (On Diff #67394) | Yes, checking sscratch in this way is pretty typical. You can't check sstatus because you haven't yet saved any GPRs anywhere, so you can't do a 'csrr` to get the value of sstatus and check it. The scheme is that the kernel clears sscratch so that nested kernel exceptions see a 0 value. bbl does the same thing with mscratch FWIW, and I suspect it's probably what Linux does as well. There aren't really any other options when you only have the single scratch register. |