-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reset values of capability CSRs #43
Comments
Interesting information - especially the link to the CVE. Any capabililty width CSRs which are non reset must reset the tag to zero, so (e.g.) mscratchc could only have the tag bit reset. |
Even with Zcheri_legacy implemented, M-mode always starts in Capability mode (since MXL resets to the widest supported XLEN and xenvcfg CSRs only affect modes lower than x), so I don't think it's possible for cap-supporting hardware to run a cap-naive M-mode. I wouldn't personally oppose an effort to make cap-naive M-mode work, although past comments (riscv/riscv-isa-manual#820, riscv/riscv-isa-manual#817, possibly others) suggest this is considered a non-goal. |
The machine always starts in Legacy mode when Zcheri_mode is supported because the reset value of PCC in that case is M=0. As Tariq mentioned, the intention is to be compatible with RISC-V code that is not capability-aware in M-mode. @sorear: I agree that the current spec does not need to require extended CSRs to have all their bits reset to a value, but they do need to have their tag bits reset at the very least. |
Concluding this, the idea is to have reset values as follows:
This confines the resets for a lot of registers to only the tag bit. Any thoughts? @jrtc27 @arichardson @sorear |
Surely xepcc, dpcc and dddc need to be infinite too |
You are right, I think xepcc needs to be Infinite as well. Cap-unaware software will start in M-mode and Legacy, attempt to write (e.g.) mepcc's address only using the standard RISC-V addresses and jump to S/U mode; this operation will fail if those registers are not Infinite. I am less certain about dpcc/dddc because these are just buffers for pcc/ddc when entering Debug mode. So my thinking is that you would, at least conceptually, come out of reset with pcc/ddc set to Infinite and, if needed, immediately go to Debug mode at which point Infinite is written into dpcc/dddc. Cap-unaware software would work in this case, but it depends on how this sentence from the RISC-V debug spec is interpreted:
|
so
|
@tariqkurd-repo : Good spot! jvtc was missing too. Here is the updated table:
I will create a PR to fix this. |
In fact the rule is simple - anything which currently resets to NULL_CAP can be a tag clear, anything which resets to INFINITY needs to be kept. |
I would expect use of JVTC in legacy code to be constrained by DDC, not be a capability. Not including it in my list was a deliberate choice. |
So you are suggesting that in Legacy mode the address to access is
|
Yes; treat it as just another pointer. Otherwise it's a strange special case from every other load that's authorised by DDC. |
(especially since legacy code will access it as an integer not a capability) |
@jrtc27 : Then would you expect DDC to grant X permission even though it is supposed to be a data capability? @sorear explained here that the X permission is required to access JVTC because:
|
No. The X requirement for the PTEs is a wart on the Zcmt spec that I do not want to see grow further and infect CHERI. |
This seems odd to me, would a simple core that needs this kind of "jump into a special decoding mode" workaround have a MMU that needs to be consulted? Since it's already splitting the instruction wouldn't it be easier to inject a xlen-load+jr? Even if we use DDC metadata in legacy mode, we still need jvtc to be a capability in purecap, so can't we just initialize it to infinity and keep DDC and JVTC metadata separate so that it can be constrained separately by a higher privilege mode? |
You could, but why should it? GPRs are capability registers in purecap code but aren't initialised to infinity. |
My reasoning for it is that it seems a bit odd to me that the access permissions for the jump table are either the CLEN-extended CSR for purecap or DDC for legacy. Using the same CSR for authorization seems like the cleaner approach to me even if it comes at the cost of an additional CSR that needs explicit initialization logic? But I don't have a strong opinion here since both cases work just fine, so happy to go with whatever is simpler for the uarch. |
We could shrink jvtc back to XLEN bits and leave it UNSPECIFIED whether jump table accesses use pcc metadata or ddc metadata for the fetch. (I'll only accept an attempt to use CHERI as a vehicle for relitigating the controversial decisions in already ratified specifications if I'm allowed to do the same thing with the AUIPC low bits.) We could move away from "legacy writes to CLEN-bit CSRs preserve the metadata" and towards "legacy writes to CLEN-bit CSRs copy metadata from pcc". Then the jvtc metadata would be initialized automatically when legacy code initializes the jvtc address. We could keep the current write rules and initialize jvtc to Infinity. This poses system security problems, because if jvtc is added to the hardware but not privileged software support, unprivileged software can use the uninitialized jvtc as a source of Infinity at runtime. It could be initialized to Null, which would have the benefit of being fail-secure in the absence of privileged software support. |
#101 still has JVTC as infinity but fixes everything else to do with reset values. There's no point in going against ratified specs - the purpose of this exercise is to get CHERI ratified. All such things will need to be undone later. I'm very aware that a lot of things will change when this finally gets to ARC review (whenever that is) but I don't see any point in making decisions which we know with certainty will be rejected. |
All CSRs which used to reset to NULL_CAP now just have a tag clear with unspecified data. All CSRs which reset to infinity are unchanged. Fixes #43
Since we did not resolve all the comments in this issue I've file #110 for the JVTC open issue. |
The base privileged architecture does not specify reset values for CSRs if M-mode code can ensure that they are not used until they have been written with a value. While defining the initial values of the capability system is important for lower modes, M-mode is likely to run before RAM initialization and erasing tags in RAM is unlikely to be performed in a way transparent to the earliest M-mode code, so M-mode code which runs immediately after reset must already be prepared to deal with garbage capabilities.
For consistency with the base ISA, remove reset values from capability CSRs that can be safely initialized by M-mode at the same time as RAM.
This applies to mscratchc, sscratchc, mepcc, sepcc, stvecc, jvtc, ddc, stdc, mtdc straightforwardly as they are not used prior to the execution of CSR instructions or of a MRET. It also applies to mtvecc, since M-mode code is responsible for not enabling interrupts or doing anything that could generate an exception until a trap handler is installed. (This may be controversial since somebody decided to file CVE-2021-1104. If there is overwhelming demand for a mtvecc reset value, it should be Null not Infinity to ensure that trap loops are harmless; pcc provides the initial Infinity capability and clearly must have a reset value.)
The text was updated successfully, but these errors were encountered: