@@ -1037,6 +1037,7 @@ Module TLB.
10371037 (time : nat)
10381038 (va : bv 64)
10391039 (ttbr : reg) : result string (t * bool) :=
1040+ (* make an incremental update *)
10401041 fold_left (λ prev lvl,
10411042 '(tlb_prev, is_changed_prev) ← prev;
10421043 '(tlb_new, is_changed) ← va_fill tlb_prev ts init mem time lvl va ttbr;
@@ -1109,6 +1110,7 @@ Module TLB.
11091110 '(tlb, is_changed) ←
11101111 match mem !! time_cur with
11111112 | Some ev =>
1113+ (* always true if tlbi is applied *)
11121114 let tlb_inv :=
11131115 if ev is Ev.Tlbi tlbi then tlbi_apply tlbi tlb_prev else tlb_prev
11141116 in
@@ -1679,6 +1681,61 @@ Definition ets3 (ts : TState.t) : result string bool :=
16791681 val ← othrow "The register value of ID_AA64MMFR1_EL1 is 64 bit" (regval_to_val mmfr1 regval);
16801682 mret (bv_extract 36 4 val =? 3%bv).
16811683
1684+ Definition new_invalidation_opt (ti_new ti_old : option nat) : bool :=
1685+ match ti_new, ti_old with
1686+ | Some ti_new, Some ti_old => ti_old <? ti_new
1687+ | None, None => false
1688+ | Some _, None => true
1689+ | None, Some _ => true
1690+ end .
1691+
1692+ Definition is_new_entry (path : list val) (ti_new : option nat)
1693+ (entries : list (list val * nat * option nat)) : bool :=
1694+ forallb
1695+ (λ '(p, t, ti),
1696+ negb(path =? p) || new_invalidation_opt ti_new ti) entries.
1697+
1698+ (* Snapshots are sorted in the descending order of `trans_time`.
1699+ Thus, we do not have to use `trans_time` to check the interval *)
1700+ Definition get_valid_entries_from_snapshots (snapshots : list (TLB.t * nat))
1701+ (mem : Memory.t)
1702+ (tid : nat)
1703+ (va : bv 64) (asid : bv 16) :
1704+ result string (list (list val * nat * option nat)) :=
1705+ fold_right (λ '(tlb, trans_time) entries,
1706+ candidates ← TLB.lookup mem tid tlb trans_time va asid;
1707+ prev ←@{result string} entries;
1708+ let new :=
1709+ omap (λ '(path, ti_opt),
1710+ if decide (is_new_entry path ti_opt prev) then
1711+ Some (path, trans_time, ti_opt)
1712+ else None
1713+ ) candidates in
1714+ mret (new ++ prev)
1715+ ) (mret nil) snapshots.
1716+
1717+ Definition get_invalid_entries_from_snapshots (snapshots : list (TLB.t * nat))
1718+ (ts : TState.t)
1719+ (init : Memory.initial)
1720+ (mem : Memory.t)
1721+ (tid : nat) (is_ets2 : bool)
1722+ (va : bv 64) (asid : bv 16) (ttbr : reg) :
1723+ result string (list (list val * nat * option nat)) :=
1724+ fold_right (λ '(tlb, trans_time) entries,
1725+ if decide (is_ets2 ∧ trans_time < ts.(TState.vwr) ⊔ ts.(TState.vrd)) then
1726+ entries
1727+ else
1728+ candidates ← TLB.get_invalid_ptes_with_inv_time ts init mem tid tlb trans_time va asid ttbr;
1729+ prev ←@{result string} entries;
1730+ let new :=
1731+ omap (λ '(path, ti_opt),
1732+ if decide (is_new_entry path ti_opt prev) then
1733+ Some (path, trans_time, ti_opt)
1734+ else None
1735+ ) candidates in
1736+ mret (new ++ prev)
1737+ ) (mret nil) snapshots.
1738+
16821739Definition run_trans_start (trans_start : TranslationStartInfo)
16831740 (tid : nat) (init : Memory.initial) :
16841741 Exec.t (PPState.t TState.t Ev.t IIS.t) string unit :=
@@ -1699,20 +1756,16 @@ Definition run_trans_start (trans_start : TranslationStartInfo)
16991756 if decide (va_in_range va) then
17001757 ttbr ← mlift $ ttbr_of_regime va trans_start.(TranslationStartInfo_regime);
17011758 snapshots ← mlift $ TLB.unique_snapshots_until_timestamp ts init mem vmax_t va ttbr;
1702- '(tlb, trans_time) ← mchoosel snapshots;
1703- valid_ptes ← mlift $ TLB.lookup mem tid tlb trans_time va asid;
1704- invalid_ptes ←
1705- if decide (is_ets2 ∧ trans_time < ts.(TState.vwr) ⊔ ts.(TState.vrd)) then
1706- mret []
1707- else
1708- mlift $ TLB.get_invalid_ptes_with_inv_time ts init mem tid tlb trans_time va asid ttbr;
1759+ valid_entries ← mlift $ get_valid_entries_from_snapshots snapshots mem tid va asid;
1760+ invalid_entries ← mlift $
1761+ get_invalid_entries_from_snapshots snapshots ts init mem tid is_ets2 va asid ttbr;
17091762 (* update IIS with either a valid translation result or a fault *)
17101763 let valid_trs :=
1711- map (λ '(path, ti),
1712- IIS.TransRes.make (va_to_vpn va) trans_time path ti) valid_ptes in
1764+ map (λ '(path, t, ti),
1765+ IIS.TransRes.make (va_to_vpn va) t path ti) valid_entries in
17131766 let invalid_trs :=
1714- map (λ '(path, ti),
1715- IIS.TransRes.make (va_to_vpn va) trans_time path ti) invalid_ptes in
1767+ map (λ '(path, t, ti),
1768+ IIS.TransRes.make (va_to_vpn va) t path ti) invalid_entries in
17161769 mchoosel (valid_trs ++ invalid_trs)
17171770 else
17181771 mret $ IIS.TransRes.make (va_to_vpn va) vpre_t [] None;
0 commit comments