Skip to content

Commit 9e628cc

Browse files
committed
Apply code reviews
1 parent 4923fac commit 9e628cc

File tree

1 file changed

+64
-57
lines changed

1 file changed

+64
-57
lines changed

ArchSemArm/VMPromising.v

Lines changed: 64 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,12 @@ Definition prefix_to_va {n : N} (is_upper : bool) (p : bv n) : bv 64 :=
712712
let varange_bit := if is_upper then (bv_1 16) else (bv_0 16) in
713713
bv_concat 64 varange_bit (bv_concat 48 p (bv_0 (48 - n))).
714714

715+
Definition is_upper_va (va : bv 64) : option bool :=
716+
let top_bits := bv_extract 48 16 va in
717+
if top_bits =? (-1)%bv then Some true
718+
else if top_bits =? 0%bv then Some false
719+
else None.
720+
715721
Definition level_prefix {n : N} (va : bv n) (lvl : Level) : prefix lvl :=
716722
bv_extract (12 + 9 * (3 - lvl)) (9 * (lvl + 1)) va.
717723

@@ -768,10 +774,12 @@ Module TLB.
768774
Module NDCtxt.
769775
Record t (lvl : Level) :=
770776
make {
777+
is_upper : bool;
771778
va : prefix lvl;
772779
asid : option (bv 16);
773780
}.
774781
Arguments make {_} _ _.
782+
Arguments is_upper {_}.
775783
Arguments va {_}.
776784
Arguments asid {_}.
777785

@@ -783,8 +791,8 @@ Module TLB.
783791

784792
#[global] Instance count lvl : Countable (t lvl).
785793
Proof.
786-
eapply (inj_countable' (fun ndc => (va ndc, asid ndc))
787-
(fun x => make x.1 x.2)).
794+
eapply (inj_countable' (fun ndc => (is_upper ndc, va ndc, asid ndc))
795+
(fun x => make x.1.1 x.1.2 x.2)).
788796
abstract sauto.
789797
Defined.
790798
End NDCtxt.
@@ -795,20 +803,17 @@ Module TLB.
795803
Definition nd (ctxt : t) : NDCtxt.t (lvl ctxt) := projT2 ctxt.
796804
Definition va (ctxt : t) : prefix (lvl ctxt) := NDCtxt.va (nd ctxt).
797805
Definition asid (ctxt : t) : option (bv 16) := NDCtxt.asid (nd ctxt).
806+
Definition is_upper (ctxt : t) : bool := NDCtxt.is_upper (nd ctxt).
798807
End Ctxt.
799808
#[export] Typeclasses Transparent Ctxt.t.
800809

801810
Module Entry.
802-
Record t (lvl : Level) :=
811+
Record t {lvl : Level} :=
803812
make {
804-
is_upper : bool;
805813
val_ttbr : val;
806814
ptes : vec val (S lvl);
807815
}.
808-
Arguments make {_} _ _ _.
809-
Arguments is_upper {_}.
810-
Arguments val_ttbr {_}.
811-
Arguments ptes {_}.
816+
Arguments t : clear implicits.
812817

813818
#[global] Instance eq_dec lvl : EqDecision (t lvl).
814819
Proof. solve_decision. Defined.
@@ -818,18 +823,18 @@ Module TLB.
818823

819824
#[global] Instance count lvl : Countable (t lvl).
820825
Proof.
821-
eapply (inj_countable' (fun ent => (is_upper ent, val_ttbr ent, ptes ent))
822-
(fun x => make x.1.1 x.1.2 x.2)).
826+
eapply (inj_countable' (fun ent => (val_ttbr ent, ptes ent))
827+
(fun x => make lvl x.1 x.2)).
823828
abstract sauto.
824829
Defined.
825830

826831
Definition pte {lvl} (tlbe : t lvl) := Vector.last tlbe.(ptes).
827832

828833
Program Definition append {lvl clvl : Level}
829-
(tlbe : t lvl)
834+
(tlbe : @t lvl)
830835
(pte : val)
831-
(CHILD : lvl + 1 = clvl) : t clvl :=
832-
make tlbe.(is_upper) tlbe.(val_ttbr) (ctrans _ (tlbe.(ptes) +++ [#pte])).
836+
(CHILD : lvl + 1 = clvl) : @t clvl :=
837+
make _ tlbe.(val_ttbr) (ctrans _ (tlbe.(ptes) +++ [#pte])).
833838
Solve All Obligations with lia.
834839
End Entry.
835840
Export (hints) Entry.
@@ -971,10 +976,10 @@ Module TLB.
971976
if (Memory.read_at loc init mem time) is Some (memval, _) then
972977
if decide (is_table memval) then
973978
let asid := bv_extract 48 16 val_ttbr in
974-
let ndctxt := NDCtxt.make va (Some asid) in
979+
let ndctxt := NDCtxt.make is_upper va (Some asid) in
975980
let ctxt := existT root_lvl ndctxt in
976981
let entry : Entry.t (Ctxt.lvl ctxt) :=
977-
Entry.make is_upper val_ttbr ([#memval] : vec val (S root_lvl)) in
982+
Entry.make _ val_ttbr ([#memval] : vec val (S root_lvl)) in
978983
(* add the entry to vatlb only when it is not in the original vatlb *)
979984
if decide (entry ∉ (VATLB.get ctxt vatlb)) then
980985
Ok (VATLB.insert ctxt entry vatlb, true)
@@ -998,11 +1003,6 @@ Module TLB.
9981003
(te : Entry.t (Ctxt.lvl ctxt))
9991004
(index : bv 9)
10001005
(ttbr : reg) : result string (VATLB.t * bool) :=
1001-
(* guard_or "ASID is not active"
1002-
$ is_active_asid ts (Ctxt.asid ctxt) ttbr time;; *)
1003-
guard_or "The translation entry is not in the TLB"
1004-
(te ∈ VATLB.get ctxt vatlb);;
1005-
10061006
if decide (¬is_table (Entry.pte te)) then Ok (vatlb, false)
10071007
else
10081008
let entry_addr := next_entry_addr (Entry.pte te) index in
@@ -1015,7 +1015,7 @@ Module TLB.
10151015
let va := next_va ctxt index (child_lvl_add_one _ _ e) in
10161016
let asid := if bool_decide (is_global clvl next_pte) then None
10171017
else Ctxt.asid ctxt in
1018-
let ndctxt := NDCtxt.make va asid in
1018+
let ndctxt := NDCtxt.make (Ctxt.is_upper ctxt) va asid in
10191019
let ctxt := existT clvl ndctxt in
10201020
let entry := Entry.append te next_pte (child_lvl_add_one _ _ e) in
10211021
(* add the entry to vatlb only when it is not in the original vatlb *)
@@ -1047,11 +1047,12 @@ Module TLB.
10471047
let index := level_index va lvl in
10481048
sregs ← othrow "TTBR should exist in initial state"
10491049
$ TState.read_sreg_at ts ttbr time;
1050+
is_upper ← othrow "The register is not TTBR" (is_upper_ttbr ttbr);
10501051
foldlM (λ prev sreg,
10511052
val_ttbr ← othrow "TTBR should be a 64 bit value"
10521053
$ regval_to_val ttbr sreg.1;
10531054
let asid := bv_extract 48 16 val_ttbr in
1054-
let ndctxt := NDCtxt.make pva (Some asid) in
1055+
let ndctxt := NDCtxt.make is_upper pva (Some asid) in
10551056
let ctxt := existT plvl ndctxt in
10561057
(* parent entries should be from the original TLB (in the parent level) *)
10571058
let tes := elements (VATLB.get ctxt tlb.(vatlb)) in
@@ -1194,7 +1195,6 @@ Module TLB.
11941195
| (ev, t) :: tl =>
11951196
match ev with
11961197
| Ev.Tlbi tlbi =>
1197-
let va := prefix_to_va (Entry.is_upper te) (Ctxt.va ctxt) in
11981198
if decide (is_te_invalidated_by_tlbi tlbi tid ctxt te) then
11991199
mret (Some t)
12001200
else
@@ -1239,8 +1239,10 @@ Module TLB.
12391239
(lvl : Level)
12401240
(va : bv 64) (asid : bv 16) :
12411241
result string (list (val * list val * (option nat))) :=
1242-
let ndctxt_asid := NDCtxt.make (level_prefix va lvl) (Some asid) in
1243-
let ndctxt_global := NDCtxt.make (level_prefix va lvl) None in
1242+
is_upper ← othrow ("VA is not in the range: " ++ (pretty va))%string
1243+
(is_upper_va va);
1244+
let ndctxt_asid := NDCtxt.make is_upper (level_prefix va lvl) (Some asid) in
1245+
let ndctxt_global := NDCtxt.make is_upper (level_prefix va lvl) None in
12441246
candidates_asid ←
12451247
get_leaf_ptes_with_inv_time_by_ctxt mem tid tlb trans_time lvl ndctxt_asid;
12461248
candidates_global ←
@@ -1277,7 +1279,9 @@ Module TLB.
12771279
(ttbr : reg) :
12781280
result string (list (val * list val * (option nat))) :=
12791281
if parent_lvl lvl is Some parent_lvl then
1280-
let ndctxt := NDCtxt.make (level_prefix va parent_lvl) asid in
1282+
is_upper ← othrow ("VA is not in the range: " ++ (pretty va))%string
1283+
(is_upper_va va);
1284+
let ndctxt := NDCtxt.make is_upper (level_prefix va parent_lvl) asid in
12811285
let ctxt := existT parent_lvl ndctxt in
12821286
let tes := VATLB.get ctxt tlb.(TLB.vatlb) in
12831287
let tes := filter (λ te, is_table (TLB.Entry.pte te)) tes in
@@ -1376,7 +1380,7 @@ Module TLB.
13761380
candidates ← TLB.lookup mem tid tlb trans_time va asid;
13771381
let new :=
13781382
omap (λ '(val_ttbr, path, ti_opt),
1379-
if (is_new_entry val_ttbr path ti_opt entries) then
1383+
if is_new_entry val_ttbr path ti_opt entries then
13801384
Some (val_ttbr, path, trans_time, ti_opt)
13811385
else None
13821386
) candidates in
@@ -1397,7 +1401,7 @@ Module TLB.
13971401
candidates ← TLB.get_invalid_ptes_with_inv_time ts init mem tid tlb trans_time va asid ttbr;
13981402
let new :=
13991403
omap (λ '(val_ttbr, path, ti_opt),
1400-
if decide (is_new_entry val_ttbr path ti_opt entries) then
1404+
if is_new_entry val_ttbr path ti_opt entries then
14011405
Some (val_ttbr, path, trans_time, ti_opt)
14021406
else None
14031407
) candidates in
@@ -1420,8 +1424,7 @@ Module IIS.
14201424
va : bv 36;
14211425
time : nat;
14221426
root : option {ttbr : reg & reg_type ttbr};
1423-
remaining : list (bv 64);
1424-
invalidation : option nat
1427+
remaining : list (bv 64)
14251428
}.
14261429

14271430
Definition pop : Exec.t t string (bv 64) :=
@@ -1436,10 +1439,11 @@ Module IIS.
14361439
make {
14371440
strict : view;
14381441
(* The translations results of the latest translation *)
1439-
trs : option TransRes.t
1442+
trs : option TransRes.t;
1443+
inv_time : option nat
14401444
}.
14411445

1442-
Definition init : t := make 0 None.
1446+
Definition init : t := make 0 None None.
14431447

14441448
(** Add a new view to the IIS *)
14451449
Definition add (v : view) (iis : t) : t :=
@@ -1448,6 +1452,9 @@ Module IIS.
14481452
Definition set_trs (tres : TransRes.t) :=
14491453
setv trs (Some tres).
14501454

1455+
Definition set_inv_time (ti_opt : option nat) :=
1456+
setv inv_time ti_opt.
1457+
14511458
End IIS.
14521459

14531460
Import UMPromising(view_if, read_fwd_view).
@@ -1520,14 +1527,17 @@ Definition run_reg_general_read (reg : reg) (racc : reg_acc) :
15201527
Definition run_reg_trans_read (reg : reg) (racc : reg_acc)
15211528
(trs : IIS.TransRes.t) :
15221529
Exec.t TState.t string (reg_type reg * view) :=
1523-
guard_or "Translation read during the translation should be implicit"
1530+
guard_or "Register read during the translation should be implicit"
15241531
(¬ (is_Some racc));;
15251532
root ← othrow "Could not find the translation root: error in translation assumptions"
15261533
(trs.(IIS.TransRes.root));
1527-
if decide (projT1 root = reg) is left eq then
1528-
mret (ctrans eq (projT2 root), 0%nat)
1534+
if decide (root.T1 = reg) is left eq then
1535+
mret (ctrans eq root.T2, 0%nat)
15291536
else
15301537
ts ← mGet;
1538+
guard_or
1539+
("The register should niether be relaxed nor strict: " ++ pretty reg)%string
1540+
$ (reg ∉ strict_regs ∨ reg ∉ relaxed_regs);;
15311541
othrow
15321542
("Register " ++ pretty reg ++ " unmapped; cannot read")%string
15331543
$ TState.read_reg ts reg.
@@ -1588,18 +1598,14 @@ Definition run_mem_read (addr : address) (macc : mem_acc) (init : Memory.initial
15881598
iis ← mget PPState.iis;
15891599
let vaddr := iis.(IIS.strict) in
15901600
if is_explicit macc then
1591-
tres_opt ← mget (IIS.trs ∘ PPState.iis);
1592-
trans_res ← othrow "Explicit access before translation" tres_opt;
1593-
let invalidation := trans_res.(IIS.TransRes.invalidation) in
15941601
'(view, val) ←
15951602
Exec.liftSt (PPState.state ×× PPState.mem)
1596-
$ read_mem_explicit loc vaddr invalidation macc init;
1603+
$ read_mem_explicit loc vaddr iis.(IIS.inv_time) macc init;
15971604
mset PPState.iis $ IIS.add view;;
15981605
mret val
15991606
else if is_ttw macc then
16001607
ts ← mget PPState.state;
1601-
tres_option ← mget (IIS.trs ∘ PPState.iis);
1602-
tres ← othrow "TTW read before translation start" tres_option;
1608+
tres ← othrow "TTW read before translation start" iis.(IIS.trs);
16031609
'(view, val) ←
16041610
read_pte vaddr (ts, tres)
16051611
|> Exec.lift_res_set_full
@@ -1828,27 +1834,28 @@ Definition run_trans_start (trans_start : TranslationStartInfo)
18281834
valid_entries ← mlift $ TLB.get_valid_entries_from_snapshots snapshots mem tid va asid;
18291835
invalid_entries ← mlift $
18301836
TLB.get_invalid_entries_from_snapshots snapshots ts init mem tid is_ets2 va asid ttbr;
1831-
(* update IIS with either a valid translation result or a fault *)
1832-
valid_trs
1837+
(* update IIS with either a valid translation result or an invalid result *)
1838+
valid_res
18331839
for (val_ttbr, path, t, ti) in valid_entries do
18341840
val_ttbr ← othrow
18351841
"TTBR value type does not match with the value from the translation"
18361842
(val_to_regval ttbr val_ttbr);
18371843
let root := (Some (existT ttbr val_ttbr)) in
1838-
mret $ IIS.TransRes.make (va_to_vpn va) t root path ti
1844+
mret $ (IIS.TransRes.make (va_to_vpn va) t root path, ti)
18391845
end;
1840-
invalid_trs
1846+
invalid_res
18411847
for (val_ttbr, path, t, ti) in invalid_entries do
18421848
val_ttbr ← othrow
18431849
"TTBR value type does not match with the value from the translation"
18441850
(val_to_regval ttbr val_ttbr);
18451851
let root := (Some (existT ttbr val_ttbr)) in
1846-
mret $ IIS.TransRes.make (va_to_vpn va) t root path ti
1852+
mret $ (IIS.TransRes.make (va_to_vpn va) t root path, ti)
18471853
end;
1848-
mchoosel (valid_trs ++ invalid_trs)
1854+
mchoosel (valid_res ++ invalid_res)
18491855
else
1850-
mret $ IIS.TransRes.make (va_to_vpn va) vpre_t None [] None;
1851-
mset PPState.iis $ IIS.set_trs trans_res.
1856+
mret $ (IIS.TransRes.make (va_to_vpn va) vpre_t None [], None);
1857+
mset PPState.iis $ IIS.set_trs trans_res.1;;
1858+
mset PPState.iis $ IIS.set_inv_time trans_res.2.
18521859

18531860
Definition read_fault_vpre (is_acq : bool)
18541861
(trans_time : nat) : Exec.t (TState.t * IIS.t) string view :=
@@ -1876,7 +1883,7 @@ Definition run_trans_end (trans_end : trans_end) :
18761883
let trans_time := trs.(IIS.TransRes.time) in
18771884
let fault := trans_end.(AddressDescriptor_fault) in
18781885
if decide (fault.(FaultRecord_statuscode) = Fault_None) then
1879-
mret ()
1886+
mset snd $ setv IIS.trs None
18801887
else
18811888
is_ets3 ← mlift (ets3 ts);
18821889
if is_ets3 && (trans_time <? (ts.(TState.vrd) ⊔ ts.(TState.vwr)))
@@ -1893,16 +1900,18 @@ Definition run_trans_end (trans_end : trans_end) :
18931900
let is_write := fault.(FaultRecord_access).(AccessDescriptor_write) in
18941901
let is_rel := fault.(FaultRecord_access).(AccessDescriptor_relsc) in
18951902
write_view ← write_fault_vpre is_rel trans_time;
1896-
mset snd $ IIS.add (view_if is_write write_view)
1903+
mset snd $ IIS.add (view_if is_write write_view);;
1904+
mset snd $ setv IIS.trs None
18971905
else
18981906
mthrow "Translation ends with an empty translation".
18991907

1908+
(* TODO: check translation fault using `fault` and handle other cases *)
19001909
Definition run_take_exception (fault : exn) (vmax_t : view) :
19011910
Exec.t (TState.t * IIS.t) string () :=
19021911
iis ← mget snd;
19031912
if iis.(IIS.trs) is Some trans_res then
1904-
match trans_res.(IIS.TransRes.invalidation) with
1905-
| Some invalidation => run_cse invalidation
1913+
match iis.(IIS.inv_time) with
1914+
| Some inv_time => run_cse inv_time
19061915
| None => mret ()
19071916
end
19081917
else
@@ -1940,11 +1949,9 @@ Section RunOutcome.
19401949
addr ← othrow "Address not supported" $ Loc.from_addr addr;
19411950
viio ← mget (IIS.strict ∘ PPState.iis);
19421951
if is_explicit macc then
1943-
tres_opt ← mget (IIS.trs ∘ PPState.iis);
1944-
trans_res ← othrow "Explicit access before translation" tres_opt;
1945-
let invalidation := trans_res.(IIS.TransRes.invalidation) in
1952+
inv_time ← mget (IIS.inv_time ∘ PPState.iis);
19461953
vpre_opt ← Exec.liftSt (PPState.state ×× PPState.mem) $
1947-
write_mem_xcl tid addr viio invalidation macc val;
1954+
write_mem_xcl tid addr viio inv_time macc val;
19481955
mret (Ok (), vpre_opt)
19491956
else mthrow "Unsupported non-explicit write"
19501957
| MemWrite _ _ _ => mthrow "Memory write of size other than 8, or with tags"

0 commit comments

Comments
 (0)