@@ -42,14 +42,40 @@ bitfield PTE_Bits : pteAttribs = {
42
42
* gate their capability-load traps on the PTE bits (and sccsr.gclg[su]); that
43
43
* is, we permit relaxing only the dependence on the tag bit itself.
44
44
*
45
+ * While for StoreCap* the behaviors are as follows. Again, SCI is an inhibit.
46
+ *
47
+ * SCI SC_Mod Action
48
+ *
49
+ * 0 0 Permit tagged capability store
50
+ * 0 1 [Reserved]
51
+ *
52
+ * 1 0 Trap on tagged capability store
53
+ * 1 1 CAS the PTE to SC=0, SC_Mod=0 (i.e., reset both bits)
54
+ *
55
+ * It is permitted for implementations to ignore SC_Mod and behave as if it
56
+ * were always 0, at the expense of traps on cap-dirtying stores. Note that
57
+ * SCI and SC_Mod are not quite like W and D: SCI is both the (negated)
58
+ * permission and dirty bit; SC_Mod just encapsulates a particular trap
59
+ * handler behavior. This is again done for simplicity of gradual roll-out:
60
+ * permitting SC_Mod to be treated as always zero means fewer things to
61
+ * initially implement.
62
+ *
63
+ * The SCI=1 SC_Mod=1 behavior is described as a CAS of the PTE to close race
64
+ * conditions, much as with W and D. Should the TLB have this state cached
65
+ * and then observe a SCI=0 SC_Mod=0 PTE, no PTE write is necessary. On the
66
+ * other hand, if SCI=1 SC_Mod=0 is observed, the store operation must trap
67
+ * rather than transition the PTE to SCI=0 SC_Mod=0.
68
+ *
69
+ * At present, SC_Mod is ignored by the code below.
45
70
*/
46
71
type extPte = bits (10 )
47
72
48
73
bitfield Ext_PTE_Bits : extPte = {
49
74
LoadCapInh : 9 , /* Inhibit capability loads */
50
- StoreCap : 8 , /* Permit capability stores */
75
+ StoreCapInh : 8 , /* Inhibit capability stores */
51
76
LoadCap_Mod : 7 , /* Modify capability load inhibit; see above table */
52
77
LoadCap_LCLG : 6 , /* When cap. load gens. are in use, the "local" CLG */
78
+ StoreCap_Mod : 5 , /* Modify capability store inhibit; see above table */
53
79
}
54
80
55
81
function isPTEPtr (p : pteAttribs , ext : extPte ) -> bool = {
@@ -118,7 +144,7 @@ function checkPTEPermission(ac : AccessType(ext_access_type), priv : Privilege,
118
144
(Write (Cap ), User ) => { if p . U () == 0b1 & p . W () == 0b1
119
145
then {
120
146
let e = Mk_Ext_PTE_Bits (ext );
121
- if e . StoreCap () == 0b1
147
+ if e . StoreCapInh () == 0b0
122
148
then (true , PTE_CAP_OK )
123
149
else {
124
150
/* Do not allow the address translation to proceed */
@@ -132,9 +158,9 @@ function checkPTEPermission(ac : AccessType(ext_access_type), priv : Privilege,
132
158
then {
133
159
let e = Mk_Ext_PTE_Bits (ext );
134
160
let lcm = checkPTEPermission_LC (p , e );
135
- if e . StoreCap () == 0b1 & lcm == PTE_CAP_OK
161
+ if e . StoreCapInh () == 0b0 & lcm == PTE_CAP_OK
136
162
then (true , PTE_CAP_OK )
137
- else if e . StoreCap () == 0b0
163
+ else if e . StoreCapInh () == 0b1
138
164
/* return a failure since we should cause an exception */
139
165
then (false , PTE_STORE_CAP_ERR )
140
166
/* return a success since the translation should proceed */
@@ -154,7 +180,7 @@ function checkPTEPermission(ac : AccessType(ext_access_type), priv : Privilege,
154
180
(Write (Cap ), Supervisor ) => { let e = Mk_Ext_PTE_Bits (ext );
155
181
if (p . U () == 0b0 | do_sum ) & p . W () == 0b1
156
182
then {
157
- if e . StoreCap () == 0b1
183
+ if e . StoreCapInh () == 0b0
158
184
then (true , PTE_CAP_OK )
159
185
else (false , PTE_STORE_CAP_ERR )
160
186
}
@@ -165,9 +191,9 @@ function checkPTEPermission(ac : AccessType(ext_access_type), priv : Privilege,
165
191
if (p . U () == 0b0 | do_sum ) & p . R () == 0b1 & p . W () == 0b1
166
192
then {
167
193
let lcm = checkPTEPermission_LC (p , e );
168
- if e . StoreCap () == 0b1 & lcm == PTE_CAP_OK
194
+ if e . StoreCapInh () == 0b0 & lcm == PTE_CAP_OK
169
195
then (true , PTE_CAP_OK )
170
- else if e . StoreCap () == 0b0
196
+ else if e . StoreCapInh () == 0b1
171
197
/* return a failure since we should cause an exception */
172
198
then (false , PTE_STORE_CAP_ERR )
173
199
/* return a success since the translation should proceed */
0 commit comments