Replies: 3 comments 45 replies
-
That’s an interesting question. I don’t believe anything in software requires untagged capabilities if you modify them. The memcpy requirement is specifically for things that are only loaded and stored but not modified in registers. The other requirement is that, after a tag-clearing operation, the cget* instructions should hopefully give something useful for debugging. I believe cincoffset on an untagged capability modifies only the lower bits (so that it can be used for add on an intptr_t). I also believe csetbounds on an untagged thing does not change the top fields. Candperm should not modify anything except for the permissions field. I presume that you have in mind a microarchitecture that keeps registers in a [partially] expanded state for faster operations and decompresses later? We did have an earlier CHERI prototype that did this and hit a number of corner cases, which is part of the reason that so much later work went into ensuring that the capability manipulation instructions can be done on the compressed representation. I would expect that such an implementation would keep the original bounds encoding around until it did a bounds-manipulation instruction and then recompress into some canonical form. I believe the specification permits this and requires that the bounds remain in a canonical form. @rmn30? |
Beta Was this translation helpful? Give feedback.
-
I think really the point is more about whether the "current" pcc bounds are expanded or compressed. To me the former makes sense as otherwise we may have to do a representability check on every PC movement (including incrementing), which is error-prone and wastes power/gates. In this case, we only update/expand the pcc bounds on "installing" new PCC (CJALR/exceptions/mret). And to me it makes sense to clear pcc tag on bound violations instead of doing a representability check (as we need to do bound check anyway, and if bound checking passes then we know it's representable). @vmurali in this context, line 4 (PC=516) of your example will result in a fetch violation since we are still runing on the "current" pcc. |
Beta Was this translation helpful? Give feedback.
-
That's exactly what I meant. I'm also giving Kunyan the option of either a check against top (preferable for sw) or against the representable limit depending on which is easier in hw. We definitely need to check against base as it is the lower representable limit. |
Beta Was this translation helpful? Give feedback.
-
TL;DR: Can I change the bit patterns of an untagged cap whenever I use any cap-modifying-instruction on that cap?
Detailed question:
It is unclear what bit patterns should be kept intact when storing a cap back into the memory, especially if one keeps the expanded caps for PC (see CHERIoT-Platform/cheriot-sail@0185917; this necessarily needs expanded caps for PC; otherwise, one has to store previous PC and make sure that a new Jump address is in the same representable region as the previous PC's cap) and registers.
The need for preserving the bit pattern arises because multiple combinations of T, B and E represent the same cap (for instance, when T = 1, B = 0, E = 1 is the same bounds as T = 2, B = 0, E = 0).
CLC and CSC are forced to keep the bit patterns for untagged caps because they are used in memcpy (since we don't have a language level distinction between caps and data). This leads to corner cases which are troublesome:
For instance, if one does a
CAndPerm
and the permissions remain intact, and if it were an untagged cap, should a later CSC maintain the original bit pattern for T, B and E?In general, if an instruction is supposed to change some fields of the cap, but the specific values keep the value of those fields unchanged, can the bit pattern of T, B and E change?
What if the values of the other fields change, but
CSetBounds
was not used? What ifCIncOffset
is used on an untagged cap?Beta Was this translation helpful? Give feedback.
All reactions