riscv / riscv-j-extension

Working Draft of the RISC-V J Extension Specification
https://jira.riscv.org/browse/RVG-128
Creative Commons Attribution 4.0 International
162 stars 17 forks source link

Ssnpm cannot emulate U-mode pointer masking configuration like Smnpm can #67

Open SiFiveHolland opened 6 months ago

SiFiveHolland commented 6 months ago

While implementing pointer masking in Linux, I noticed that there is no way for S-mode to emulate accesses using the U-mode pointer masking configuration, like M-mode can with mstatus.MPRV. This means that for S-mode to dereference pointers passed from U-mode, it must either

  1. manually apply the ignore transformation to each pointer in software, or
  2. configure itself to have the same pointer masking configuration as U-mode.

Option 1 requires invasive software changes, plus the overhead of the transformation. Option 2 requires a call into firmware during each context switch if PMLEN differs between userspace processes, and prevents S-mode from using longer tags for its own purposes.

What is the feasibility of defining a sstatus.MPRV bit that behaves like mstatus.MPRV and affects pointer masking?

sstatus.SUM exists, but it does not seem appropriate for that bit to affect the pointer masking configuration.

SiFiveHolland commented 6 months ago

Looks like this was brought up before, but I don't see a resolution: https://lists.riscv.org/g/tech-j-ext/topic/pointer_masking_xte_bits/74636079

martinmaas commented 6 months ago

Thanks for bringing this up, and also for talking through it in yesterday's J Extension meeting. The resolution was that these are indeed the two main options. The rationale why each of these is feasible is the following:

Applying the transformation in software

We assume the cost of applying the transformation in software is acceptable (a load and an AND when it is known or expected that a pointer comes from user mode). The mask can be pre-computed per process, which is (I think) what at least one implementation of untagged_addr is already doing:

https://github.com/torvalds/linux/blob/master/arch/x86/include/asm/uaccess_64.h

The transformation could either happen once when entering the kernel or when the address is used.

Enable pointer masking at the kernel level

I agree that fine-grained switching is not plausible in this case. However, there is (as far as I know) currently no use case in the kernel that would take advantage of PMLEN=16, and HWASAN in user mode is expected to use PMLEN=7. It is therefore plausible for psABI to define that only the top 7 bits be used for tagging (and the 8th bit from the top set to 0), and for the kernel to always have pointer masking with PMLEN=7 switched on. It is plausible that runtime systems in user mode (managed or otherwise) will use PMLEN=16 if it is available, but those are also the workloads for which it is easy to untag addresses before passing them to the kernel.

Hardware support for user mode accesses

If the use case that the kernel needs PMLEN=16 becomes common, I think it would be plausible to add some hardware feature for this – but this would probably be a future extension and would need a strong rationale. However, code would still need to be changed to use the new extension (which is probably the same implementation effort as doing the transformation in software, so it would only make sense if the performance cost is an issue).

Does this address your concern? If not, please do push back – I think it's an important point.

martinmaas commented 6 months ago

Closing the loop on the issue: I will leave the issue open for now in case there is more discussion around these topics, but currently, there are no plans to change the ISA.