@@ -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