Skip to content

Commit

Permalink
Memory-tagging support in herd and diy
Browse files Browse the repository at this point in the history
This patch introduces support for the Memory Tagging
Extension (MTE). More precisely, loads and stores can
now be checked against a "tag" and fault if their tag
does not match. The extension also adds the LDG and STG
instructions which handle tags directly.

Co-autored-by: Luc Maranget <luc.maranget@inria.fr>
Signed-off-by: Jade Alglave <jade.alglave@arm.com>
Signed-off-by: Luc Maranget <luc.maranget@inria.fr>
  • Loading branch information
jalglave authored and maranget committed Oct 8, 2019
1 parent 0182a8c commit 6378f2f
Show file tree
Hide file tree
Showing 32 changed files with 349 additions and 73 deletions.
20 changes: 11 additions & 9 deletions gen/AArch64Arch_gen.ml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ module Mixed =
(* AArch64 has more atoms that others *)
let bellatom = false
type atom_rw = PP | PL | AP | AL
type atom_acc = Plain | Acq | AcqPc | Rel | Atomic of atom_rw
type atom_acc = Plain | Acq | AcqPc | Rel | Atomic of atom_rw | Tag
type atom = atom_acc * MachMixed.t option

let default_atom = Atomic PP,None
Expand All @@ -59,7 +59,7 @@ let applies_atom (a,_) d = match a,d with
| Acq,R
| AcqPc,R
| Rel,W
| (Plain|Atomic _),(R|W)
| (Plain|Atomic _|Tag),(R|W)
-> true
| _ -> false

Expand All @@ -79,6 +79,7 @@ let applies_atom (a,_) d = match a,d with
| Acq -> "A"
| AcqPc -> "Q"
| Plain -> "P"
| Tag -> "T"

let pp_atom (a,m) = match a with
| Plain ->
Expand All @@ -104,7 +105,7 @@ let applies_atom (a,_) d = match a,d with
let fold_atom_rw f r = f PP (f PL (f AP (f AL r)))

let fold_acc f r =
f Acq (f AcqPc (f Rel (fold_atom_rw (fun rw -> f (Atomic rw)) r)))
f Tag (f Acq (f AcqPc (f Rel (fold_atom_rw (fun rw -> f (Atomic rw)) r))))

let fold_non_mixed f r = fold_acc (fun acc r -> f (acc,None) r) r

Expand All @@ -118,7 +119,7 @@ let applies_atom (a,_) d = match a,d with

let worth_final (a,_) = match a with
| Atomic _ -> true
| Acq|AcqPc|Rel|Plain -> false
| Acq|AcqPc|Rel|Plain|Tag -> false


let varatom_dir _d f r = f None r
Expand All @@ -145,13 +146,14 @@ let applies_atom (a,_) d = match a,d with
end)

let overwrite_value v ao w = match ao with
| None| Some ((Atomic _|Acq|AcqPc|Rel|Plain),None) -> w (* total overwrite *)
| Some ((Atomic _|Acq|AcqPc|Rel|Plain),Some (sz,o)) ->
ValsMixed.overwrite_value v sz o w
| None| Some ((Atomic _|Acq|AcqPc|Rel|Plain|Tag),None)
-> w (* total overwrite *)
| Some ((Atomic _|Acq|AcqPc|Rel|Plain|Tag),Some (sz,o)) ->
ValsMixed.overwrite_value v sz o w

let extract_value v ao = match ao with
| None| Some ((Atomic _|Acq|AcqPc|Rel|Plain),None) -> v
| Some ((Atomic _|Acq|AcqPc|Rel|Plain),Some (sz,o)) ->
| None| Some ((Atomic _|Acq|AcqPc|Rel|Plain|Tag),None) -> v
| Some ((Atomic _|Acq|AcqPc|Rel|Plain|Tag),Some (sz,o)) ->
ValsMixed.extract_value v sz o

(* End of atoms *)
Expand Down
41 changes: 37 additions & 4 deletions gen/AArch64Compile_gen.ml
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,14 @@ module Make(Cfg:Config) : XXXCompile_gen.S =
| Quad -> I_LDR (V64,r1,r2,K o)

let ldr r1 r2 = I_LDR (vloc,r1,r2,K 0)
let ldg r1 r2 = I_LDG (r1,r2,K 0)
let ldar r1 r2 = I_LDAR (vloc,AA,r1,r2)
let ldapr r1 r2 = I_LDAR (vloc,AQ,r1,r2)
let ldxr r1 r2 = I_LDAR (vloc,XX,r1,r2)
let ldaxr r1 r2 = I_LDAR (vloc,AX,r1,r2)
let sxtw r1 r2 = I_SXTW (r1,r2)
let ldr_idx r1 r2 idx = I_LDR (vloc,r1,r2,RV (vloc,idx))
let ldg_idx r1 r2 idx = I_LDG (r1,r2,RV (vloc,idx))

let ldr_mixed_idx v r1 r2 idx sz =
let open MachSize in
Expand All @@ -135,8 +137,10 @@ module Make(Cfg:Config) : XXXCompile_gen.S =
| Quad -> I_STR (V64,r1,r2,K o)

let str r1 r2 = I_STR (vloc,r1,r2,K 0)
let stg r1 r2 = I_STG (r1,r2,K 0)
let stlr r1 r2 = I_STLR (vloc,r1,r2)
let str_idx r1 r2 idx = I_STR (vloc,r1,r2,RV (vloc,idx))
let stg_idx r1 r2 idx = I_STG (r1,r2,RV (vloc,idx))
let stxr r1 r2 r3 = I_STXR (vloc,YY,r1,r2,r3)
let stlxr r1 r2 r3 = I_STXR (vloc,LY,r1,r2,r3)

Expand Down Expand Up @@ -298,8 +302,6 @@ module Make(Cfg:Config) : XXXCompile_gen.S =
[] in
rA,init,cs,st



let emit_load_not_zero st p init x =
let rA,st = next_reg st in
let rB,init,st = U.next_init st p init x in
Expand Down Expand Up @@ -364,6 +366,14 @@ module Make(Cfg:Config) : XXXCompile_gen.S =
let load_idx st rA rB idx = [ldr_idx rA rB idx],st
end)

module LDG =
LOAD
(struct
let load = wrap_st ldg
let load_idx st rA rB idx = [ldg_idx rA rB idx],st
end)


(* For export *)
let emit_load_one = LDR.emit_load_one
let emit_load = LDR.emit_load
Expand Down Expand Up @@ -442,6 +452,13 @@ module Make(Cfg:Config) : XXXCompile_gen.S =
let store_idx st rA rB idx = [str_idx rA rB idx],st
end)

module STG =
STORE
(struct
let store = wrap_st stg
let store_idx st rA rB idx = [stg_idx rA rB idx],st
end)

module STLR =
STORE
(struct
Expand All @@ -451,8 +468,6 @@ module Make(Cfg:Config) : XXXCompile_gen.S =
ins@[stlr rA r],st
end)



(***************************)
(* Atomic loads and stores *)
(***************************)
Expand Down Expand Up @@ -731,6 +746,9 @@ module Make(Cfg:Config) : XXXCompile_gen.S =
| R,Some (Plain,Some (sz,o)) ->
let r,init,cs,st = emit_load_mixed sz o st p init loc in
Some r,init,cs,st
| R,Some (Tag,Some (sz,o)) ->
let r,init,cs,st = LDG.emit_load st p init loc in
Some r,init,cs,st
| W,None ->
let init,cs,st = STR.emit_store st p init loc e.v in
None,init,cs,st
Expand Down Expand Up @@ -762,7 +780,11 @@ module Make(Cfg:Config) : XXXCompile_gen.S =
end) in
let init,cs,st = S.emit_store st p init loc e.v in
None,init,cs,st
| W,Some (Tag,Some (sz,o)) ->
let init,cs,st = STG.emit_store st p init loc e.v in
None,init,cs,st
| _,Some (Plain,None) -> assert false
| _,Some (Tag,None) -> assert false
| J,_ -> emit_joker st init
end

Expand Down Expand Up @@ -947,6 +969,9 @@ module Make(Cfg:Config) : XXXCompile_gen.S =
| R,Some (Atomic rw,Some (sz,o)) ->
let r,init,cs,st = emit_lda_mixed_idx sz o rw st p init loc r2 in
Some r,init, Instruction c::cs,st
| R,Some (Tag,(Some (sz,o))) ->
let r,init,cs,st = LDG.emit_load_idx st p init loc r2 in
Some r,init, Instruction c::cs,st
| W,None ->
let init,cs,st = STR.emit_store_idx st p init loc r2 e.v in
None,init,Instruction c::cs,st
Expand Down Expand Up @@ -1005,8 +1030,12 @@ module Make(Cfg:Config) : XXXCompile_gen.S =
let rA,init,cs_mov,st = U.emit_mov_sz sz st p init e.v in
let init,cs,st = S.emit_store_idx_reg st p init loc r2 rA in
None,init,Instruction c::cs_mov@cs,st
| W,Some (Tag, Some (sz,o)) ->
let init,cs,st = STG.emit_store_idx st p init loc r2 e.v in
None,init,Instruction c::cs,st
| J,_ -> emit_joker st init
| _,Some (Plain,None) -> assert false
| _,Some (Tag,None) -> assert false
end
| _,Code _ -> Warn.fatal "No dependency to code location"

Expand Down Expand Up @@ -1086,7 +1115,11 @@ module Make(Cfg:Config) : XXXCompile_gen.S =
end) in
let init,cs,st = S.emit_store_reg st p init loc r2 in
None,init,cs2@cs,st
| Some (Tag, Some (sz,o)) ->
let init,cs,st = STG.emit_store_reg st p init loc r2 in
None,init,cs2@cs,st
| Some (Plain,None) -> assert false
| Some (Tag,None) -> assert false
end
| Some J,_ -> emit_joker st init
| _,Code _ -> Warn.fatal "Not Yet (%s,dep_data)" (C.debug_evt e)
Expand Down
5 changes: 4 additions & 1 deletion gen/config.ml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ let optcoherence = ref false
let bell = ref None
let scope = ref Scope.No
let variant = ref (fun (_:Variant_gen.t) -> false)
let mtags = ref false

type do_observers =
| Avoid (* was false *)
Expand Down Expand Up @@ -165,7 +166,9 @@ let common_specs =
("-hexa", Arg.Unit (fun () -> hexa := true),"hexadecimal output")::
("-o", Arg.String (fun s -> tarfile := Some s),
"<name.tar> output litmus tests in archive <name.tar> (default, output in curent directory)")::
("-c", Arg.Bool (fun b -> canonical_only := b),
("-mtags", Arg.Bool (fun b -> mtags := b),
sprintf "<bool> initialise tags (default %b)" !mtags)::
("-c", Arg.Bool (fun b -> canonical_only := b),
sprintf "<b> avoid equivalent cycles (default %b)" !canonical_only)::
("-list",
Arg.Unit (fun () -> show := Some ShowGen.Edges),
Expand Down
1 change: 1 addition & 0 deletions gen/diy.ml
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ let () =
let docheck = !Config.docheck
let typ = !Config.typ
let hexa = !Config.hexa
let mtags = !Config.mtags
end in
let module C = struct
let verbose = !Config.verbose
Expand Down
1 change: 1 addition & 0 deletions gen/diycross.ml
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ let () =
let cpp = match !Config.arch with `CPP -> true | _ -> false
let scope = !Config.scope
let variant = !Config.variant
let mtags = !Config.mtags
end in
let module T = Top_gen.Make(C) in
begin match !Config.arch with
Expand Down
1 change: 1 addition & 0 deletions gen/diyone.ml
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ let () =
let neg = !Config.neg
let typ = !Config.typ
let hexa = !Config.hexa
let mtags = !Config.mtags
(* Specific *)
let norm = !norm
let cpp = cpp
Expand Down
6 changes: 5 additions & 1 deletion gen/top_gen.ml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ module type Config = sig
val typ : TypBase.t
val hexa : bool
val variant : Variant_gen.t -> bool
val mtags : bool
end

module Make (O:Config) (Comp:XXXCompile_gen.S) : Builder.S
Expand Down Expand Up @@ -526,7 +527,7 @@ let min_max xs =
in do_rec oks k'
in do_rec oks []

let compile_cycle ok n =
let compile_cycle ok n =
let open Config in
Label.reset () ;
let splitted = C.split_procs n in
Expand Down Expand Up @@ -651,6 +652,9 @@ let dump_init chan inits env =
let p = get_proc left in
if p <> q then fprintf chan "\n" else fprintf chan " " ;
fprintf chan "%s=%s;" (A.pp_location left) loc ;
if !Config.mtags then
if not(List.exists (fun (a,b) -> b=loc) rem)
then fprintf chan " %s.atag;" loc ;
p_rec p rem in
p_rec (-1) inits

Expand Down
8 changes: 7 additions & 1 deletion herd/AArch64Arch_herd.ml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module Make (C:sig include Arch_herd.Config val moreedges : bool end) (V:Value.S
let pp_barrier_short = pp_barrier
let reject_mixed = true

type annot = A | XA | L | XL | X | N | Q | NoRet
type annot = A | XA | L | XL | X | N | Q | NoRet | T
type lannot = annot

let empty_annot = N
Expand Down Expand Up @@ -52,6 +52,10 @@ module Make (C:sig include Arch_herd.Config val moreedges : bool end) (V:Value.S
| L | XL -> true
| _ -> false

let is_tag = function
| T -> true
| _ -> false

let barrier_sets =
do_fold_dmb_dsb C.moreedges
(fun b k ->
Expand All @@ -65,6 +69,7 @@ module Make (C:sig include Arch_herd.Config val moreedges : bool end) (V:Value.S
"Q", wrap_is is_acquire_pc;
"L", wrap_is is_release;
"NoRet", wrap_is is_noreturn;
"T", wrap_is is_tag
]

let is_isync = is_barrier ISB
Expand All @@ -79,6 +84,7 @@ module Make (C:sig include Arch_herd.Config val moreedges : bool end) (V:Value.S
| X -> "*"
| N -> ""
| NoRet -> "NoRet"
| T -> "Tag"

module V = V

Expand Down
Loading

0 comments on commit 6378f2f

Please sign in to comment.