Skip to content

Commit 77f73f2

Browse files
committed
TTBR is read from the TLB results during the translation
1 parent 7e5d7ed commit 77f73f2

File tree

1 file changed

+112
-55
lines changed

1 file changed

+112
-55
lines changed

ArchSemArm/VMPromising.v

Lines changed: 112 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -800,10 +800,12 @@ Module TLB.
800800
Module Entry.
801801
Record t (lvl : Level) :=
802802
make {
803+
is_upper : bool;
803804
val_ttbr : val;
804805
ptes : vec val (S lvl);
805806
}.
806-
Arguments make {_} _ _.
807+
Arguments make {_} _ _ _.
808+
Arguments is_upper {_}.
807809
Arguments val_ttbr {_}.
808810
Arguments ptes {_}.
809811

@@ -815,8 +817,8 @@ Module TLB.
815817

816818
#[global] Instance count lvl : Countable (t lvl).
817819
Proof.
818-
eapply (inj_countable' (fun ent => (val_ttbr ent, ptes ent))
819-
(fun x => make x.1 x.2)).
820+
eapply (inj_countable' (fun ent => (is_upper ent, val_ttbr ent, ptes ent))
821+
(fun x => make x.1.1 x.1.2 x.2)).
820822
abstract sauto.
821823
Defined.
822824

@@ -826,7 +828,7 @@ Module TLB.
826828
(tlbe : t lvl)
827829
(pte : val)
828830
(CHILD : lvl + 1 = clvl) : t clvl :=
829-
make tlbe.(val_ttbr) (ctrans _ (tlbe.(ptes) +++ [#pte])).
831+
make tlbe.(is_upper) tlbe.(val_ttbr) (ctrans _ (tlbe.(ptes) +++ [#pte])).
830832
Solve All Obligations with lia.
831833
End Entry.
832834
Export (hints) Entry.
@@ -934,6 +936,15 @@ Module TLB.
934936
(CHILD : (Ctxt.lvl ctxt) + 1 = clvl) : prefix clvl :=
935937
bv_concat (level_length clvl) (Ctxt.va ctxt) index.
936938

939+
Definition is_upper_ttbr (ttbr : reg) : option bool :=
940+
if decide
941+
(ttbr = TTBR0_EL1 ∨
942+
ttbr = TTBR0_EL2 ∨
943+
ttbr = TTBR0_EL3) then Some false
944+
else if decide
945+
(ttbr = TTBR1_EL1 ∨
946+
ttbr = TTBR1_EL2) then Some true
947+
else None.
937948

938949
(** Seed root-level TLB entries from [ttbr].
939950
- Reads [ttbr] at [time], checks it is 64-bit.
@@ -950,6 +961,7 @@ Module TLB.
950961
(ttbr : reg) : result string (VATLB.t * bool) :=
951962
sregs ← othrow "TTBR should exist in initial state"
952963
$ TState.read_sreg_at ts ttbr time;
964+
is_upper ← othrow "The register is not TTBR" (is_upper_ttbr ttbr);
953965
foldlM (λ '(vatlb, is_changed) sreg,
954966
val_ttbr ← othrow "TTBR should be a 64 bit value"
955967
$ regval_to_val ttbr sreg.1;
@@ -961,7 +973,7 @@ Module TLB.
961973
let ndctxt := NDCtxt.make va (Some asid) in
962974
let ctxt := existT root_lvl ndctxt in
963975
let entry : Entry.t (Ctxt.lvl ctxt) :=
964-
Entry.make val_ttbr ([#memval] : vec val (S root_lvl)) in
976+
Entry.make is_upper val_ttbr ([#memval] : vec val (S root_lvl)) in
965977
(* add the entry to vatlb only when it is not in the original vatlb *)
966978
if decide (entry ∉ (VATLB.get ctxt vatlb)) then
967979
Ok (VATLB.insert ctxt entry vatlb, true)
@@ -1207,26 +1219,27 @@ Module TLB.
12071219
(tlb : t) (trans_time : nat)
12081220
(lvl : Level)
12091221
(ndctxt : NDCtxt.t lvl) :
1210-
result string (list (list val * (option nat))) :=
1222+
result string (list (val * list val * (option nat))) :=
12111223
let ctxt := existT lvl ndctxt in
12121224
let tes := VATLB.get ctxt tlb.(TLB.vatlb) in
12131225
let tes := if decide (lvl = leaf_lvl) then tes
12141226
else filter (λ te, is_block (TLB.Entry.pte te)) tes in
12151227
for te in (elements tes) do
12161228
ti ← invalidation_time mem tid trans_time ctxt te;
1217-
mret ((vec_to_list (Entry.ptes te)), ti)
1229+
mret ((Entry.val_ttbr te), (vec_to_list (Entry.ptes te)), ti)
12181230
end.
12191231

1220-
(** Get all the TLB entries that could translate the given VA
1221-
at the provided level and in the provided ASID context.
1232+
(** Get all the TLB entries and the corresponding TTBR value that
1233+
could translate the given VA at the provided level
1234+
and in the provided ASID context.
12221235
Return each TLB entry as a list of descriptors [list val] with
12231236
the invalidation time [nat] *)
12241237
Definition get_leaf_ptes_with_inv_time (mem : Memory.t)
12251238
(tid : nat)
12261239
(tlb : t) (trans_time : nat)
12271240
(lvl : Level)
12281241
(va : bv 64) (asid : bv 16) :
1229-
result string (list (list val * (option nat))) :=
1242+
result string (list (val * list val * (option nat))) :=
12301243
let ndctxt_asid := NDCtxt.make (level_prefix va lvl) (Some asid) in
12311244
let ndctxt_global := NDCtxt.make (level_prefix va lvl) None in
12321245
candidates_asid ←
@@ -1235,21 +1248,22 @@ Module TLB.
12351248
get_leaf_ptes_with_inv_time_by_ctxt mem tid tlb trans_time lvl ndctxt_global;
12361249
mret (candidates_asid ++ candidates_global)%list.
12371250

1238-
(** Get all the TLB entries that could translate the given VA
1239-
in the provided ASID context.
1251+
(** Get all the TLB entries and the corresponding TTBR value that
1252+
could translate the given VA in the provided ASID context.
12401253
Return each TLB entry as a list of descriptors [list val] with
12411254
the invalidation time [nat] *)
12421255
Definition lookup (mem : Memory.t)
12431256
(tid : nat)
12441257
(tlb : TLB.t) (trans_time : nat)
12451258
(va : bv 64) (asid : bv 16) :
1246-
result string (list (list val * (option nat))) :=
1259+
result string (list (val * list val * (option nat))) :=
12471260
res1 ← get_leaf_ptes_with_inv_time mem tid tlb trans_time 1%fin va asid;
12481261
res2 ← get_leaf_ptes_with_inv_time mem tid tlb trans_time 2%fin va asid;
12491262
res3 ← get_leaf_ptes_with_inv_time mem tid tlb trans_time leaf_lvl va asid;
12501263
mret (res1 ++ res2 ++ res3).
12511264

1252-
(** Get all the TLB entries that trigger fault from the given VA
1265+
(** Get all the TLB entries and the corresponding TTBR value that
1266+
trigger fault from the given VA
12531267
at the provided level and in the provided ASID context.
12541268
Return each TLB entry as a list of descriptors [list val] with
12551269
the invalidation time [option nat] *)
@@ -1261,7 +1275,8 @@ Module TLB.
12611275
(lvl : Level)
12621276
(va : bv 64)
12631277
(asid : option (bv 16))
1264-
(ttbr : reg) : result string (list (list val * (option nat))) :=
1278+
(ttbr : reg) :
1279+
result string (list (val * list val * (option nat))) :=
12651280
if parent_lvl lvl is Some parent_lvl then
12661281
let ndctxt := NDCtxt.make (level_prefix va parent_lvl) asid in
12671282
let ctxt := existT parent_lvl ndctxt in
@@ -1276,7 +1291,8 @@ Module TLB.
12761291
if decide (is_valid memval) then mret None
12771292
else
12781293
ti ← invalidation_time mem tid trans_time ctxt te;
1279-
mret $ Some ((vec_to_list (Entry.ptes te)) ++ [memval], ti)
1294+
let vals := (vec_to_list (Entry.ptes te)) ++ [memval] in
1295+
mret $ Some (Entry.val_ttbr te, vals, ti)
12801296
else
12811297
mthrow "The PTE is missing"
12821298
end;
@@ -1294,22 +1310,25 @@ Module TLB.
12941310
if (Memory.read_at loc init mem trans_time) is Some (memval, _) then
12951311
if decide (is_valid memval) then mret None
12961312
else
1297-
mret $ Some ([memval], None)
1313+
mret $ Some (val_ttbr, [memval], None)
12981314
else mthrow "The root PTE is missing"
12991315
end;
13001316
mret $ omap id invalid_ptes.
13011317

1302-
(** Get all the TLB entries that trigger fault from the given VA
1318+
(** Get all the TLB entries and the corresponding TTBR value that
1319+
trigger fault from the given VA
13031320
in the provided ASID context.
13041321
Return each TLB entry as a list of descriptors [list val] with
13051322
the invalidation time [option nat] *)
1306-
Definition get_invalid_ptes_with_inv_time_by_lvl (ts : TState.t) (init : Memory.initial)
1323+
Definition get_invalid_ptes_with_inv_time_by_lvl (ts : TState.t)
1324+
(init : Memory.initial)
13071325
(mem : Memory.t)
13081326
(tid : nat)
13091327
(tlb : t) (trans_time : nat)
13101328
(lvl : Level)
13111329
(va : bv 64) (asid : bv 16)
1312-
(ttbr : reg) : result string (list (list val * (option nat))) :=
1330+
(ttbr : reg) :
1331+
result string (list (val * list val * (option nat))) :=
13131332
candidates_asid ←
13141333
get_invalid_ptes_with_inv_time_by_lvl_asid
13151334
ts init mem tid tlb trans_time lvl va (Some asid) ttbr;
@@ -1324,7 +1343,7 @@ Module TLB.
13241343
(tlb : TLB.t) (time : nat)
13251344
(va : bv 64) (asid : bv 16)
13261345
(ttbr : reg) :
1327-
result string (list (list val * (option nat))) :=
1346+
result string (list (val * list val * (option nat))) :=
13281347
fault_ptes ←
13291348
for lvl in enum Level do
13301349
get_invalid_ptes_with_inv_time_by_lvl ts init mem tid tlb time lvl va asid ttbr
@@ -1339,25 +1358,27 @@ Module TLB.
13391358
| Some _, None => true
13401359
end.
13411360

1342-
Definition is_new_entry (path : list val) (ti_new : option nat)
1343-
(entries : list (list val * nat * option nat)) : bool :=
1361+
Definition is_new_entry (val_ttbr : val) (path : list val) (ti_new : option nat)
1362+
(entries : list (val * list val * nat * option nat)) : bool :=
13441363
forallb
1345-
(λ '(p, t, ti),
1346-
negb(path =? p) || invalidation_time_lt ti ti_new) entries.
1364+
(λ '(vt, p, t, ti),
1365+
negb(val_ttbr =? vt)
1366+
|| negb(path =? p)
1367+
|| invalidation_time_lt ti ti_new) entries.
13471368

13481369
(* Snapshots are sorted in the descending order of [trans_time].
13491370
Thus, we do not have to use [trans_time] to check the interval *)
13501371
Definition get_valid_entries_from_snapshots (snapshots : list (t * nat))
13511372
(mem : Memory.t)
13521373
(tid : nat)
13531374
(va : bv 64) (asid : bv 16) :
1354-
result string (list (list val * nat * option nat)) :=
1375+
result string (list (val * list val * nat * option nat)) :=
13551376
foldrM (λ '(tlb, trans_time) entries,
13561377
candidates ← TLB.lookup mem tid tlb trans_time va asid;
13571378
let new :=
1358-
omap (λ '(path, ti_opt),
1359-
if decide (is_new_entry path ti_opt entries) then
1360-
Some (path, trans_time, ti_opt)
1379+
omap (λ '(val_ttbr, path, ti_opt),
1380+
if (is_new_entry val_ttbr path ti_opt entries) then
1381+
Some (val_ttbr, path, trans_time, ti_opt)
13611382
else None
13621383
) candidates in
13631384
mret (new ++ entries)
@@ -1369,16 +1390,16 @@ Module TLB.
13691390
(mem : Memory.t)
13701391
(tid : nat) (is_ets2 : bool)
13711392
(va : bv 64) (asid : bv 16) (ttbr : reg) :
1372-
result string (list (list val * nat * option nat)) :=
1393+
result string (list (val * list val * nat * option nat)) :=
13731394
foldrM (λ '(tlb, trans_time) entries,
13741395
if decide (is_ets2 ∧ trans_time < ts.(TState.vwr) ⊔ ts.(TState.vrd)) then
13751396
mret entries
13761397
else
13771398
candidates ← TLB.get_invalid_ptes_with_inv_time ts init mem tid tlb trans_time va asid ttbr;
13781399
let new :=
1379-
omap (λ '(path, ti_opt),
1380-
if decide (is_new_entry path ti_opt entries) then
1381-
Some (path, trans_time, ti_opt)
1400+
omap (λ '(val_ttbr, path, ti_opt),
1401+
if decide (is_new_entry val_ttbr path ti_opt entries) then
1402+
Some (val_ttbr, path, trans_time, ti_opt)
13821403
else None
13831404
) candidates in
13841405
mret (new ++ entries)
@@ -1399,7 +1420,8 @@ Module IIS.
13991420
make {
14001421
va : bv 36;
14011422
time : nat;
1402-
remaining : list (bv 64); (* NOTE: translation memory read - ptes *)
1423+
root : option {ttbr : reg & reg_type ttbr};
1424+
remaining : list (bv 64);
14031425
invalidation : option nat
14041426
}.
14051427

@@ -1478,26 +1500,50 @@ Definition read_pte (vaddr : view) :
14781500
mset fst $ TState.update TState.vspec vpost;;
14791501
mret (vpost, val).
14801502

1503+
Definition run_reg_general_read (reg : reg) (racc : reg_acc) :
1504+
Exec.t (TState.t * IIS.t) string (reg_type reg * view) :=
1505+
ts ← mget fst;
1506+
if decide (reg ∈ relaxed_regs) then
1507+
if decide (is_Some racc)
1508+
then othrow
1509+
("Register " ++ pretty reg ++ " unmapped on direct read")%string
1510+
$ TState.read_sreg_direct ts reg
1511+
else
1512+
valvs ← othrow
1513+
("Register " ++ pretty reg ++ " unmapped on indirect read")%string
1514+
$ TState.read_sreg_indirect ts reg;
1515+
mchoosel valvs
1516+
else
1517+
othrow
1518+
("Register " ++ pretty reg ++ " unmapped; cannot read")%string
1519+
$ TState.read_reg ts reg.
1520+
1521+
Definition run_reg_trans_read (reg : reg) (racc : reg_acc)
1522+
(trs : IIS.TransRes.t) :
1523+
Exec.t TState.t string (reg_type reg * view) :=
1524+
guard_or "Translation read during the translation should be implicit"
1525+
(¬ (is_Some racc));;
1526+
root ← othrow "Could not find the translation root: error in translation assumptions"
1527+
(trs.(IIS.TransRes.root));
1528+
if decide (projT1 root = reg) is left eq then
1529+
mret (ctrans eq (projT2 root), 0%nat)
1530+
else
1531+
ts ← mGet;
1532+
othrow
1533+
("Register " ++ pretty reg ++ " unmapped; cannot read")%string
1534+
$ TState.read_reg ts reg.
1535+
14811536
(** Run a RegRead outcome.
14821537
Returns the register value based on the type of register and the access type. *)
14831538
Definition run_reg_read (reg : reg) (racc : reg_acc) :
14841539
Exec.t (TState.t * IIS.t) string (reg_type reg) :=
1485-
ts ← mget fst;
14861540
'(val, view) ←
1487-
(if decide (reg ∈ relaxed_regs) then
1488-
if decide (is_Some racc)
1489-
then othrow
1490-
("Register " ++ pretty reg ++ " unmapped on direct read")%string
1491-
$ TState.read_sreg_direct ts reg
1492-
else
1493-
valvs ← othrow
1494-
("Register " ++ pretty reg ++ " unmapped on indirect read")%string
1495-
$ TState.read_sreg_indirect ts reg;
1496-
mchoosel valvs
1541+
(* Check if the register is read during the translation *)
1542+
iis ← mget snd;
1543+
if iis.(IIS.trs) is Some trs then
1544+
Exec.liftSt fst $ run_reg_trans_read reg racc trs
14971545
else
1498-
othrow
1499-
("Register " ++ pretty reg ++ " unmapped; cannot read")%string
1500-
$ TState.read_reg ts reg);
1546+
run_reg_general_read reg racc;
15011547
mset snd $ IIS.add view;;
15021548
mret val.
15031549

@@ -1781,6 +1827,7 @@ Definition run_trans_start (trans_start : TranslationStartInfo)
17811827
(* lookup (successful results or faults) *)
17821828
let asid := trans_start.(TranslationStartInfo_asid) in
17831829
let va : bv 64 := trans_start.(TranslationStartInfo_va) in
1830+
17841831
trans_res ←
17851832
if decide (va_in_range va) then
17861833
ttbr ← mlift $ ttbr_of_regime va trans_start.(TranslationStartInfo_regime);
@@ -1791,15 +1838,25 @@ Definition run_trans_start (trans_start : TranslationStartInfo)
17911838
invalid_entries ← mlift $
17921839
TLB.get_invalid_entries_from_snapshots snapshots ts init mem tid is_ets2 va asid ttbr;
17931840
(* update IIS with either a valid translation result or a fault *)
1794-
let valid_trs :=
1795-
map (λ '(path, t, ti),
1796-
IIS.TransRes.make (va_to_vpn va) t path ti) valid_entries in
1797-
let invalid_trs :=
1798-
map (λ '(path, t, ti),
1799-
IIS.TransRes.make (va_to_vpn va) t path ti) invalid_entries in
1841+
valid_trs ←
1842+
for (val_ttbr, path, t, ti) in valid_entries do
1843+
val_ttbr ← othrow
1844+
"TTBR value type does not match with the value from the translation"
1845+
(val_to_regval ttbr val_ttbr);
1846+
let root := (Some (existT ttbr val_ttbr)) in
1847+
mret $ IIS.TransRes.make (va_to_vpn va) t root path ti
1848+
end;
1849+
invalid_trs ←
1850+
for (val_ttbr, path, t, ti) in invalid_entries do
1851+
val_ttbr ← othrow
1852+
"TTBR value type does not match with the value from the translation"
1853+
(val_to_regval ttbr val_ttbr);
1854+
let root := (Some (existT ttbr val_ttbr)) in
1855+
mret $ IIS.TransRes.make (va_to_vpn va) t root path ti
1856+
end;
18001857
mchoosel (valid_trs ++ invalid_trs)
18011858
else
1802-
mret $ IIS.TransRes.make (va_to_vpn va) vpre_t [] None;
1859+
mret $ IIS.TransRes.make (va_to_vpn va) vpre_t None [] None;
18031860
mset PPState.iis $ IIS.set_trs trans_res.
18041861

18051862
Definition read_fault_vpre (is_acq : bool)

0 commit comments

Comments
 (0)