-
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
Corner cases for narrow XLENs #141
base: main
Are you sure you want to change the base?
Conversation
src/riscv-legacy-integration.adoc
Outdated
corresponding extended CSRs have a variable width address field. If the width | ||
changes, the address field is truncated to the new width and zero extended to | ||
XLENMAX bits. The CSR's tag will be cleared at the time of the width change if | ||
the new address is not representable. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or the CSR is sealed and the original and modulated addresses differ
The address behavior is dictated by the base ISA and the desire to keep Legacy and Capability mode as close as possible. This just defines metadata and CHERI exception behavior in some cases that aren't covered by Zcheri_purecap. Signed-off-by: Stefan O'Rear <[email protected]>
2f9054c
to
fe17fe6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks this looks good to me, will merge if @jrtc27 is happy.
but the <<pcc>> becomes unrepresentable afterward, and a tag violation CHERI | ||
exception is taken on the next instruction unless an interrupt or higher | ||
priority synchronous exception is taken instead; in all cases `__x__epcc` will | ||
have an address of 0 or 2^XLEN^/2 and a tag of zero. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It won't always be unrepresentable, e.g. if PCC's bounds are [0, (2^XLEN)/2)
and you attempt to cross the middle of the address space?
but the <<pcc>> becomes unrepresentable afterward, and a tag violation CHERI | |
exception is taken on the next instruction unless an interrupt or higher | |
priority synchronous exception is taken instead; in all cases `__x__epcc` will | |
have an address of 0 or 2^XLEN^/2 and a tag of zero. | |
but the <<pcc>> becomes out of bounds or unrepresentable afterward, and a length or tag violation CHERI | |
exception is taken on the next instruction unless an interrupt or higher | |
priority synchronous exception is taken instead; in all cases `__x__epcc` will | |
have an address of 0 or 2^XLEN^/2 and, in the unrepresentable case, a tag of zero. |
Also that "all cases" doesn't apply to the "unless an interrupt or ..." case.
==== Bounds checking | ||
|
||
Each byte address of a load, store, or instruction fetch is individually sign | ||
extended from XLEN bits to XLENMAX bits prior to bounds checking. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, the Supervisor spec says:
If UXLEN \(<\) SXLEN, user-mode instruction-fetch addresses and load and store effective addresses are taken modulo \(2^{\text{UXLEN}}\). For example, when UXLEN=32 and SXLEN=64, user-mode memory accesses reference the lowest 4 GiB of the address space.
Should we not do the same here? Otherwise this lets you access memory that is in reality outside the bounds of the capability in use. Though I note this is at odds with:
Similarly, pc bits above XLEN are ignored, and when the pc is written, it is sign-extended to fill the widest supported XLEN.
So an OS needs to know to mask those bits off in xEPC when figuring out what actual address was being fetched from (but not xTVAL). Which is particularly silly when switching to RV32 then back to RV64 in the more privileged mode discards said upper bits of xEPC. This sounds to me like an oversight in the spec and that PC should have been regarded like a CSR not a GPR (or at least in the cases where it is used for CSRs, as opposed to AUIPC and JALR where I can understand the desire to have it pre-sign-extended, but that's a hardware implementation optimisation and already specified by virtue of writes to GPRs sign-extending the value).
I wonder if there's appetite for making that saner in the base spec. Otherwise we probably need some ludicrous "PCC's address will be sign-extended, as visible when put into xEPCC, but gets masked when the bounds check is performed, so both need to be representable (though only the latter in bounds)" requirement.
The address behavior is dictated by the base ISA and the desire to keep Legacy and Capability mode as close as possible. This just defines metadata and CHERI exception behavior in some cases that aren't covered by Zcheri_purecap.
I think there are currently five semantically distinct places where representability checks are needed:
Cases 3-5 are only possible if multiple XLEN values are supported. 3-4 are only possible if there are multiple SXLEN or (for 3 only) Zcmt is implemented. 3 can share significant logic with 2 since it operates on the same input capability. Depending on the pipeline design it may be possible to combine 1 with 2, 1 with 5, or 3 with 4.