@@ -105,6 +105,7 @@ module Make
105105 (* Semantics proper *)
106106 module Mixed(SZ:ByteSize.S) : sig
107107 val build_semantics : test -> A.inst_instance_id -> (proc * branch) M.t
108+ val can_unset_af_loc : event -> V.v option
108109 val spurious_setaf : V.v -> unit M.t
109110 end = struct
110111
@@ -1120,14 +1121,15 @@ module Make
11201121 check_cond cond)
11211122 end in
11221123 if pte2 then mvirt
1123- else
1124- M.op1 Op.IsVirtual a_virt >>= fun cond ->
1125- M.choiceT cond mvirt
1124+ else begin
1125+ let mdirect =
11261126 (* Non-virtual accesses are disallowed from EL0.
11271127 For instance, user code cannot access the page table. *)
1128- (if is_el0 then mk_pte_fault a_virt ma dir an ii domain
1129- else mdirect)
1130-
1128+ if is_el0 then mk_pte_fault a_virt ma dir an ii domain
1129+ else mdirect in
1130+ M.op1 Op.IsVirtual a_virt >>= fun cond ->
1131+ M.choiceT cond mvirt mdirect
1132+ end
11311133(* Read memory, return value read *)
11321134 let do_read_mem_ret sz an anexp ac a ii =
11331135 let m a =
@@ -1444,25 +1446,22 @@ module Make
14441446
14451447(* KVM mode *)
14461448
1447- let some_ha = dirty.DirtyBit.some_ha || dirty.DirtyBit.some_hd
1449+ let can_be_pt v =
1450+ match V.as_constant v with
1451+ | None -> true
1452+ | Some c -> Constant.is_pt c
14481453
1449- let fire_spurious_af dir a m domain =
1450- if
1451- some_ha &&
1452- (let v = C.variant Variant.PhantomOnLoad in
1453- match dir with Dir.W -> not v | Dir.R -> v)
1454- then
1455- (m >>|
1456- M.altT (test_and_set_af_succeeds a E.IdSpurious domain) (M.unitT ())) >>=
1457- fun (r,_) -> M.unitT r
1458- else m
1454+ let can_af0 v =
1455+ (match V.as_constant v with
1456+ | Some (Constant.PteVal p) ->
1457+ p.AArch64PteVal.valid <> 0 && p.AArch64PteVal.af = 0
1458+ | _ -> true)
14591459
1460- let lift_kvm dir updatedb mop ma an ii mphy branch domain =
1460+ let lift_kvm _tag dir updatedb mop ma an ii mphy branch domain =
14611461 let mfault ma a ft = emit_fault a ma dir an ft None ii in
14621462 let maccess a ma =
14631463 check_ptw ii.AArch64.proc dir updatedb false a ma an ii
1464- ((let m = mop (Access.PTE domain) ma in
1465- fire_spurious_af dir a m domain) |> branch)
1464+ (mop (Access.PTE domain) ma |> branch)
14661465 mphy
14671466 mfault
14681467 domain in
@@ -1515,8 +1514,7 @@ module Make
15151514 (* tag checks only apply to data *)
15161515 let domain = DISide.Data in
15171516 let mdirect =
1518- let m = mop (Access.PTE domain) ma in
1519- fire_spurious_af dir a m domain >>= M.ignore >>= B.next1T in
1517+ mop (Access.PTE domain) ma >>= M.ignore >>= B.next1T in
15201518 check_ptw ii.AArch64.proc Dir.R false true a ma an ii
15211519 mdirect
15221520 cond_check_tag
@@ -1617,7 +1615,7 @@ Arguments:
16171615 when translating for instruction fetches.
16181616- domain: Whether the translation is for data or instruction access.
16191617*)
1620- let do_lift_memop rA (* Base address register *)
1618+ let do_lift_memop ?tag rA (* Base address register *)
16211619 dir updatedb checked mop perms ma mv an ii branch domain =
16221620 if morello then
16231621 lift_morello mop perms ma mv dir an ii branch
@@ -1630,15 +1628,15 @@ Arguments:
16301628 M.op1 Op.IsVirtual a_virt >>= fun c ->
16311629 M.choiceT c
16321630 (mop Access.PHY ma)
1633- (fire_spurious_af dir a_virt (mop Access.PHY_PTE ma) domain) |> branch
1631+ (mop Access.PHY_PTE ma)
1632+ |> branch
16341633 else
1635- mop Access.PHY ma
1636- |> branch in
1634+ mop Access.PHY ma |> branch in
16371635 let mphy =
16381636 if checked then lift_memtag_phy dir mop ma an ii mphy
16391637 else mphy
16401638 in
1641- let m = lift_kvm dir updatedb mop ma an ii mphy branch domain in
1639+ let m = lift_kvm tag dir updatedb mop ma an ii mphy branch domain in
16421640 (* M.short will add an iico_data only if memtag is enabled *)
16431641 M.short (is_this_reg rA) (E.is_pred_txt (Some "color")) m
16441642 else if pac then
@@ -1648,10 +1646,10 @@ Arguments:
16481646 else
16491647 mop Access.VIR ma |> branch
16501648
1651- let lift_memop rA (* Base address register *)
1649+ let lift_memop ?(tag = "") rA (* Base address register *)
16521650 dir updatedb checked mop perms ma mv an ii =
16531651 let domain = DISide.Data in
1654- do_lift_memop rA dir updatedb checked mop perms ma mv an ii
1652+ do_lift_memop ~tag rA dir updatedb checked mop perms ma mv an ii
16551653 (fun a -> a >>= M.ignore >>= B.next1T) domain
16561654
16571655 (* Address translation instruction *)
@@ -1679,8 +1677,7 @@ Arguments:
16791677 let domain = DISide.Data in
16801678 let maccess a ma =
16811679 check_ptw ii.AArch64.proc dir false false a ma Annot.N ii
1682- ((let m = mop (Access.PTE domain) ma in
1683- fire_spurious_af dir a m domain) >>= M.ignore >>= B.next1T)
1680+ (mop (Access.PTE domain) ma >>= M.ignore >>= B.next1T)
16841681 mphy
16851682 mfault
16861683 domain in
@@ -1694,7 +1691,7 @@ Arguments:
16941691 if memtag && C.mte_store_only then
16951692 ma >>= fun a -> loc_extract a
16961693 else ma in
1697- lift_memop rA Dir.R false checked
1694+ lift_memop ~tag:"LD" rA Dir.R false checked
16981695 (fun ac ma _mv -> (* value fake here *)
16991696 let open Precision in
17001697 let memtag_sync =
@@ -1709,7 +1706,7 @@ Arguments:
17091706
17101707(* Generic store *)
17111708 let do_str rA mop sz an ma mv ii =
1712- lift_memop rA Dir.W true memtag
1709+ lift_memop ~tag:"ST" rA Dir.W true memtag
17131710 (fun ac ma mv ->
17141711 let open Precision in
17151712 let memtag_sync = memtag && C.mte_precision = Synchronous in
@@ -1994,12 +1991,12 @@ Arguments:
19941991
19951992 let str_simple sz rs rd m_ea ii =
19961993 do_str rd
1997- (fun ac a _ ii ->
1998- M.data_input_next
1999- (read_reg_data_sz sz rs ii )
2000- (fun v -> do_write_mem sz Annot.N aexp ac a v ii))
1994+ (fun ac a v ii ->
1995+ M.data_input_next
1996+ (M.unitT v )
1997+ (fun v -> do_write_mem sz Annot.N aexp ac a v ii))
20011998 sz Annot.N
2002- m_ea (M.unitT V.zero ) ii
1999+ m_ea (read_reg_data_sz sz rs ii ) ii
20032000
20042001 let str sz rs rd e ii =
20052002 let open AArch64Base in
@@ -2013,14 +2010,14 @@ Arguments:
20132010 (read_reg_addr rd ii)
20142011 (fun a_virt ma ->
20152012 do_str rd
2016- (fun ac a _ ii ->
2013+ (fun ac a v ii ->
20172014 M.add a_virt (V.intToV k) >>= fun b -> write_reg rd b ii
20182015 >>|
20192016 M.data_input_next
2020- (read_reg_data_sz sz rs ii )
2017+ (M.unitT v )
20212018 (fun v -> do_write_mem sz Annot.N aexp ac a v ii))
20222019 sz Annot.N
2023- ma (M.unitT V.zero ) ii) in
2020+ ma (read_reg_data_sz sz rs ii ) ii) in
20242021 if kvm then M.upOneRW (is_this_reg rd) m
20252022 else m
20262023 | Imm (k,PreIdx) ->
@@ -2117,9 +2114,9 @@ Arguments:
21172114 (write_reg ResAddr V.zero ii)
21182115 (fun v -> write_reg rr v ii)
21192116 (mw an ac))
2120- (to_perms "w" sz)
2121- (read_reg_addr rd ii)
2122- ms an ii
2117+ (to_perms "w" sz)
2118+ (read_reg_addr rd ii)
2119+ ms an ii
21232120
21242121 let stxr sz t rr rs rd ii =
21252122 do_stxr
@@ -2193,7 +2190,7 @@ Arguments:
21932190 (* Dir.W would force check for dbm bit: *)
21942191 (* - if set then either update or not db bit per R_TXGHB *)
21952192 (* - if unset raise Permission fault *)
2196- lift_memop rn Dir.W updatedb checked mop (to_perms "rw" sz) ma mv an ii
2193+ lift_memop ~tag:"FAIL" rn Dir.W updatedb checked mop (to_perms "rw" sz) ma mv an ii
21972194 in
21982195 if do_wb then
21992196 do_action true checked ma
@@ -2234,7 +2231,7 @@ Arguments:
22342231 M.altT (
22352232 (* CAS succeeds and generates an Explicit Write Effect *)
22362233 (* there must be an update to the dirty bit of the TTD *)
2237- lift_memop rn Dir.W true memtag mop_success (to_perms "rw" sz) ma mv an ii
2234+ lift_memop ~tag:"CAS" rn Dir.W true memtag mop_success (to_perms "rw" sz) ma mv an ii
22382235 )( (* CAS fails *)
22392236 M.altT (
22402237 (* CAS generates an Explicit Write Effect *)
@@ -4881,6 +4878,19 @@ Arguments:
48814878 else do_build_semantics test ii.A.inst ii
48824879 end
48834880
4881+ let can_unset_af_loc e =
4882+ match E.access_of e with
4883+ | Some Access.(PTE _|PHY_PTE)
4884+ ->
4885+ begin
4886+ match E.location_of e,E.written_of e with
4887+ | Some (A.Location_global loc),Some v ->
4888+ if E.is_explicit e && can_be_pt loc && can_af0 v then Some loc
4889+ else None
4890+ | _ -> None
4891+ end
4892+ | _ -> None
4893+
48844894 let spurious_setaf v =
48854895 test_and_set_af_succeeds v E.IdSpurious DISide.Data
48864896
0 commit comments