@@ -1058,14 +1058,15 @@ module Make
10581058 check_cond cond)
10591059 end in
10601060 if pte2 then mvirt
1061- else
1062- M.op1 Op.IsVirtual a_virt >>= fun cond ->
1063- M.choiceT cond mvirt
1061+ else begin
1062+ let mdirect =
10641063 (* Non-virtual accesses are disallowed from EL0.
10651064 For instance, user code cannot access the page table. *)
1066- (if is_el0 then mk_pte_fault a_virt ma dir an ii
1067- else mdirect)
1068-
1065+ if is_el0 then mk_pte_fault a_virt ma dir an ii
1066+ else mdirect in
1067+ M.op1 Op.IsVirtual a_virt >>= fun cond ->
1068+ M.choiceT cond mvirt mdirect
1069+ end
10691070(* Read memory, return value read *)
10701071 let do_read_mem_ret sz an anexp ac a ii =
10711072 let m a =
@@ -1385,23 +1386,37 @@ module Make
13851386
13861387 let some_ha = dirty.DirtyBit.some_ha || dirty.DirtyBit.some_hd
13871388
1388- let fire_spurious_af dir a m =
1389- if
1389+ let can_be_pt v =
1390+ match V.as_constant v with
1391+ | None -> true
1392+ | Some c -> Constant.is_pt c
1393+
1394+ let can_af0 _tag v =
1395+ pte2 ||
1396+ (match V.as_constant v with
1397+ | Some (Constant.PteVal p) -> p.AArch64PteVal.af = 0
1398+ | _ -> true)
1399+
1400+ let fire_spurious_af tag v dir a m =
1401+ let do_fire =
13901402 some_ha &&
1391- (let v = C.variant Variant.PhantomOnLoad in
1392- match dir with Dir.W -> not v | Dir.R -> v)
1403+ (let b = C.variant Variant.PhantomOnLoad in
1404+ match dir with
1405+ | Dir.W -> not b && can_be_pt a && can_af0 tag v
1406+ | Dir.R -> b) in
1407+ if do_fire
13931408 then
13941409 (m >>|
13951410 M.altT (test_and_set_af_succeeds a E.IdSpurious) (M.unitT ())) >>=
13961411 fun (r,_) -> M.unitT r
13971412 else m
13981413
1399- let lift_kvm dir updatedb mop ma an ii mphy =
1414+ let lift_kvm tag v dir updatedb mop ma an ii mphy =
14001415 let mfault ma a ft = emit_fault a ma dir an ft None ii in
14011416 let maccess a ma =
14021417 check_ptw ii.AArch64.proc dir updatedb false a ma an ii
14031418 ((let m = mop Access.PTE ma in
1404- fire_spurious_af dir a m) >>= M.ignore >>= B.next1T)
1419+ fire_spurious_af (tag^"1") v dir a m) >>= M.ignore >>= B.next1T)
14051420 mphy
14061421 mfault in
14071422 M.delay_kont "6" ma (
@@ -1415,7 +1430,7 @@ module Make
14151430 mop ac ma >>= M.ignore >>= B.next1T
14161431 )
14171432
1418- let lift_memtag_phy dir mop ma an ii mphy =
1433+ let lift_memtag_phy v dir mop ma an ii mphy =
14191434 let checked_op mpte_d a_virt =
14201435 let mok mpte_t =
14211436 let ma = M.para_bind_output_right mpte_t (fun _ -> mpte_d) in
@@ -1448,7 +1463,7 @@ module Make
14481463 M.delay_kont "tag_ptw" ma @@ fun a ma ->
14491464 let mdirect =
14501465 let m = mop Access.PTE ma in
1451- fire_spurious_af dir a m >>= M.ignore >>= B.next1T in
1466+ fire_spurious_af "2" v dir a m >>= M.ignore >>= B.next1T in
14521467 check_ptw ii.AArch64.proc Dir.R false true a ma an ii
14531468 mdirect
14541469 cond_check_tag
@@ -1545,36 +1560,42 @@ Arguments:
15451560- an: Annotation for the event structure.
15461561- ii: Instruction metadata.
15471562*)
1548- let lift_memop rA dir updatedb checked mop perms ma mv an ii =
1563+ let lift_memop ?(tag="") rA dir updatedb checked mop perms ma mv an ii =
15491564 if morello then
15501565 lift_morello mop perms ma mv dir an ii
15511566 else
1552- let mop = apply_mv mop mv in
1553- if kvm then
1554- let mphy ma a_virt =
1555- let ma = get_oa a_virt ma in
1556- if pte2 then
1557- M.op1 Op.IsVirtual a_virt >>= fun c ->
1558- M.choiceT c
1559- (mop Access.PHY ma)
1560- (fire_spurious_af dir a_virt (mop Access.PHY_PTE ma))
1561- >>= M.ignore >>= B.next1T
1562- else
1563- mop Access.PHY ma
1564- >>= M.ignore >>= B.next1T in
1565- let mphy =
1566- if checked then lift_memtag_phy dir mop ma an ii mphy
1567- else mphy
1568- in
1569- let m = lift_kvm dir updatedb mop ma an ii mphy in
1567+ (match dir with
1568+ | Dir.W ->
1569+ M.delay_kont "MV" mv
1570+ | _ ->
1571+ fun f -> f V.zero mv)
1572+ (fun v mv ->
1573+ let mop = apply_mv mop mv in
1574+ if kvm then
1575+ let mphy ma a_virt =
1576+ let ma = get_oa a_virt ma in
1577+ if pte2 then
1578+ M.op1 Op.IsVirtual a_virt >>= fun c ->
1579+ M.choiceT c
1580+ (mop Access.PHY ma)
1581+ (fire_spurious_af "3" v dir a_virt (mop Access.PHY_PTE ma))
1582+ >>= M.ignore >>= B.next1T
1583+ else
1584+ mop Access.PHY ma
1585+ >>= M.ignore >>= B.next1T in
1586+ let mphy =
1587+ if checked then lift_memtag_phy v dir mop ma an ii mphy
1588+ else mphy
1589+ in
1590+ let m = lift_kvm tag v dir updatedb mop ma an ii mphy in
15701591 (* M.short will add an iico_data only if memtag is enabled *)
1571- M.short (is_this_reg rA) (E.is_pred_txt (Some "color")) m
1572- else if pac then
1573- lift_pac_virt mop ma dir an ii
1574- else if checked then
1575- lift_memtag_virt mop ma dir an ii
1576- else
1577- mop Access.VIR ma >>= M.ignore >>= B.next1T
1592+ M.short (is_this_reg rA) (E.is_pred_txt (Some "color")) m
1593+ else if pac then
1594+ lift_pac_virt mop ma dir an ii
1595+ else if checked then
1596+ lift_memtag_virt mop ma dir an ii
1597+ else
1598+ mop Access.VIR ma >>= M.ignore >>= B.next1T)
15781599
15791600 (* Address translation instruction *)
15801601 let do_at op rd ii =
@@ -1601,7 +1622,7 @@ Arguments:
16011622 let maccess a ma =
16021623 check_ptw ii.AArch64.proc dir false false a ma Annot.N ii
16031624 ((let m = mop Access.PTE ma in
1604- fire_spurious_af dir a m) >>= M.ignore >>= B.next1T)
1625+ (* fire_spurious_af "4" v dir a *) m) >>= M.ignore >>= B.next1T)
16051626 mphy
16061627 mfault in
16071628 M.delay_kont "at::check_ptw" ma maccess
@@ -1614,7 +1635,7 @@ Arguments:
16141635 if memtag && C.mte_store_only then
16151636 ma >>= fun a -> loc_extract a
16161637 else ma in
1617- lift_memop rA Dir.R false checked
1638+ lift_memop ~tag:"LD" rA Dir.R false checked
16181639 (fun ac ma _mv -> (* value fake here *)
16191640 let open Precision in
16201641 let memtag_sync =
@@ -1629,7 +1650,7 @@ Arguments:
16291650
16301651(* Generic store *)
16311652 let do_str rA mop sz an ma mv ii =
1632- lift_memop rA Dir.W true memtag
1653+ lift_memop ~tag:"ST" rA Dir.W true memtag
16331654 (fun ac ma mv ->
16341655 let open Precision in
16351656 let memtag_sync = memtag && C.mte_precision = Synchronous in
@@ -1914,12 +1935,12 @@ Arguments:
19141935
19151936 let str_simple sz rs rd m_ea ii =
19161937 do_str rd
1917- (fun ac a _ ii ->
1918- M.data_input_next
1919- (read_reg_data_sz sz rs ii )
1920- (fun v -> do_write_mem sz Annot.N aexp ac a v ii))
1938+ (fun ac a v ii ->
1939+ M.data_input_next
1940+ (M.unitT v )
1941+ (fun v -> do_write_mem sz Annot.N aexp ac a v ii))
19211942 sz Annot.N
1922- m_ea (M.unitT V.zero ) ii
1943+ m_ea (read_reg_data_sz sz rs ii ) ii
19231944
19241945 let str sz rs rd e ii =
19251946 let open AArch64Base in
@@ -1933,14 +1954,14 @@ Arguments:
19331954 (read_reg_addr rd ii)
19341955 (fun a_virt ma ->
19351956 do_str rd
1936- (fun ac a _ ii ->
1957+ (fun ac a v ii ->
19371958 M.add a_virt (V.intToV k) >>= fun b -> write_reg rd b ii
19381959 >>|
19391960 M.data_input_next
1940- (read_reg_data_sz sz rs ii )
1961+ (M.unitT v )
19411962 (fun v -> do_write_mem sz Annot.N aexp ac a v ii))
19421963 sz Annot.N
1943- ma (M.unitT V.zero ) ii) in
1964+ ma (read_reg_data_sz sz rs ii ) ii) in
19441965 if kvm then M.upOneRW (is_this_reg rd) m
19451966 else m
19461967 | Imm (k,PreIdx) ->
@@ -2037,9 +2058,9 @@ Arguments:
20372058 (write_reg ResAddr V.zero ii)
20382059 (fun v -> write_reg rr v ii)
20392060 (mw an ac))
2040- (to_perms "w" sz)
2041- (read_reg_addr rd ii)
2042- ms an ii
2061+ (to_perms "w" sz)
2062+ (read_reg_addr rd ii)
2063+ ms an ii
20432064
20442065 let stxr sz t rr rs rd ii =
20452066 do_stxr
@@ -2113,7 +2134,7 @@ Arguments:
21132134 (* Dir.W would force check for dbm bit: *)
21142135 (* - if set then either update or not db bit per R_TXGHB *)
21152136 (* - if unset raise Permission fault *)
2116- lift_memop rn Dir.W updatedb checked mop (to_perms "rw" sz) ma mv an ii
2137+ lift_memop ~tag:"FAIL" rn Dir.W updatedb checked mop (to_perms "rw" sz) ma mv an ii
21172138 in
21182139 if do_wb then
21192140 do_action true checked ma
@@ -2154,7 +2175,7 @@ Arguments:
21542175 M.altT (
21552176 (* CAS succeeds and generates an Explicit Write Effect *)
21562177 (* there must be an update to the dirty bit of the TTD *)
2157- lift_memop rn Dir.W true memtag mop_success (to_perms "rw" sz) ma mv an ii
2178+ lift_memop ~tag:"CAS" rn Dir.W true memtag mop_success (to_perms "rw" sz) ma mv an ii
21582179 )( (* CAS fails *)
21592180 M.altT (
21602181 (* CAS generates an Explicit Write Effect *)
0 commit comments