From 338b98e0d2f9e41985ecaadbff0072dd176bc960 Mon Sep 17 00:00:00 2001 From: Peter Rugg Date: Mon, 16 May 2022 11:40:13 +0100 Subject: [PATCH 01/14] Remove tag-assertions when manipulating capabilities --- src_Core/RISCY_OOO/procs/lib/Decode.bsv | 12 ------------ src_Core/RISCY_OOO/procs/lib/Exec.bsv | 2 +- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src_Core/RISCY_OOO/procs/lib/Decode.bsv b/src_Core/RISCY_OOO/procs/lib/Decode.bsv index b9d84df..f5616cc 100644 --- a/src_Core/RISCY_OOO/procs/lib/Decode.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Decode.bsv @@ -957,7 +957,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapModify (ModifyOffset (IncOffset)); end f3_cap_CSetBoundsImmediate: begin - dInst.capChecks.src1_tag = True; dInst.capChecks.src1_unsealed = True; dInst.capChecks.check_enable = True; @@ -998,7 +997,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapModify (SpecialRW (scrType)); end f7_cap_CSetBounds: begin - dInst.capChecks.src1_tag = True; dInst.capChecks.src1_unsealed = True; dInst.capChecks.check_enable = True; @@ -1014,7 +1012,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapModify (SetBounds (SetBounds)); end f7_cap_CSetBoundsExact: begin - dInst.capChecks.src1_tag = True; dInst.capChecks.src1_unsealed = True; dInst.capChecks.cap_exact = True; @@ -1058,7 +1055,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapModify (ModifyOffset (IncOffset)); end f7_cap_CSeal: begin - dInst.capChecks.src1_tag = True; dInst.capChecks.src2_tag = True; dInst.capChecks.src1_unsealed = True; dInst.capChecks.src2_unsealed = True; @@ -1078,8 +1074,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapModify (Seal); end f7_cap_CCSeal: begin - dInst.capChecks.src1_tag = True; - dInst.capChecks.src1_unsealed = True; dInst.capChecks.src2_unsealed = True; dInst.capChecks.src2_addr_valid_type = True; @@ -1131,7 +1125,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); endcase end f7_cap_CUnseal: begin - dInst.capChecks.src1_tag = True; dInst.capChecks.src2_tag = True; dInst.capChecks.src1_sealed_with_type = True; dInst.capChecks.src2_unsealed = True; @@ -1166,7 +1159,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapInspect (SetEqualExact); end f7_cap_CCopyType: begin - dInst.capChecks.src2_tag = True; dInst.capChecks.src2_unsealed = True; dInst.capChecks.check_enable = True; @@ -1183,7 +1175,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapModify (SetAddr (Src1Type)); end f7_cap_CAndPerm: begin - dInst.capChecks.src1_tag = True; dInst.capChecks.src1_unsealed = True; dInst.iType = Cap; @@ -1218,7 +1209,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapInspect (ToPtr); end f7_cap_CFromPtr: begin - dInst.capChecks.src2_tag = True; dInst.capChecks.src2_unsealed = True; dInst.capChecks.cfromptr_bypass = True; @@ -1238,7 +1228,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.execFunc = Alu (Sub); end f7_cap_CBuildCap: begin - dInst.capChecks.src2_tag = True; dInst.capChecks.src2_unsealed = True; dInst.capChecks.src1_perm_subset_src2 = True; dInst.capChecks.src1_derivable = True; @@ -1349,7 +1338,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapInspect (GetAddr); end f5rs2_cap_CSealEntry: begin - dInst.capChecks.src1_tag = True; dInst.capChecks.src1_unsealed = True; dInst.capChecks.src1_permit_x = True; diff --git a/src_Core/RISCY_OOO/procs/lib/Exec.bsv b/src_Core/RISCY_OOO/procs/lib/Exec.bsv index de79c83..f250f8f 100644 --- a/src_Core/RISCY_OOO/procs/lib/Exec.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Exec.bsv @@ -274,7 +274,7 @@ function Tuple2#(CapPipe,Bool) capModify(CapPipe a, CapPipe b, CapModifyFunc fun tagged FromPtr : t(getAddr(a) == 0 ? nullCap : setOffset(b, getAddr(a)).value); tagged BuildCap : - t(setKind(setValidCap(a, True), getKind(a)==SENTRY ? SENTRY : UNSEALED)); + t(setKind(setValidCap(a, isValidCap(b)), getKind(a)==SENTRY ? SENTRY : UNSEALED)); tagged Move : t(a); tagged ClearTag : From e37339b14727f71f2785c65796cd97031b694772 Mon Sep 17 00:00:00 2001 From: Peter Rugg Date: Mon, 16 May 2022 11:42:35 +0100 Subject: [PATCH 02/14] Return 0 on CToPtr if authority tag unset --- src_Core/RISCY_OOO/procs/lib/Decode.bsv | 1 - src_Core/RISCY_OOO/procs/lib/Exec.bsv | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src_Core/RISCY_OOO/procs/lib/Decode.bsv b/src_Core/RISCY_OOO/procs/lib/Decode.bsv index f5616cc..55109a7 100644 --- a/src_Core/RISCY_OOO/procs/lib/Decode.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Decode.bsv @@ -1194,7 +1194,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); end f7_cap_CToPtr: begin dInst.capChecks.src1_unsealed = True; - dInst.capChecks.src2_tag = True; dInst.iType = Cap; regs.dst = Valid(tagged Gpr rd); diff --git a/src_Core/RISCY_OOO/procs/lib/Exec.bsv b/src_Core/RISCY_OOO/procs/lib/Exec.bsv index f250f8f..3918bae 100644 --- a/src_Core/RISCY_OOO/procs/lib/Exec.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Exec.bsv @@ -320,7 +320,7 @@ function Data capInspect(CapPipe a, CapPipe b, CapInspectFunc func); tagged SEALED_WITH_TYPE .t: zeroExtend(t); endcase tagged ToPtr : - (isValidCap(a) ? (getAddr(a) - getBase(b)) : 0); + (isValidCap(a) && isValidCap(b) ? (getAddr(a) - getBase(b)) : 0); default: ?; endcase); return res; From 04ba0cb7ab1bc2553c6ee166e52062024ef60d3d Mon Sep 17 00:00:00 2001 From: Peter Rugg Date: Tue, 18 Oct 2022 15:48:35 +0100 Subject: [PATCH 03/14] Prefer tag clearing to trapping when manipulating a sealed capability This causes the behaviour of CCSeal and CSeal to diverge in non-trapping cases, meaning an extra case is added to CapModify. --- src_Core/RISCY_OOO/procs/lib/Decode.bsv | 26 ---------------------- src_Core/RISCY_OOO/procs/lib/Exec.bsv | 22 ++++++++++-------- src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv | 1 + 3 files changed, 14 insertions(+), 35 deletions(-) diff --git a/src_Core/RISCY_OOO/procs/lib/Decode.bsv b/src_Core/RISCY_OOO/procs/lib/Decode.bsv index 55109a7..bb1a00e 100644 --- a/src_Core/RISCY_OOO/procs/lib/Decode.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Decode.bsv @@ -948,8 +948,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); opcOpCHERI: begin case (funct3) f3_cap_CIncOffsetImmediate: begin - dInst.capChecks.src1_unsealed = True; - dInst.iType = Cap; regs.dst = Valid(tagged Gpr rd); regs.src1 = Valid(tagged Gpr rs1); @@ -957,8 +955,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapModify (ModifyOffset (IncOffset)); end f3_cap_CSetBoundsImmediate: begin - dInst.capChecks.src1_unsealed = True; - dInst.capChecks.check_enable = True; dInst.capChecks.check_authority_src = Src1; dInst.capChecks.check_low_src = Src1Addr; @@ -997,8 +993,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapModify (SpecialRW (scrType)); end f7_cap_CSetBounds: begin - dInst.capChecks.src1_unsealed = True; - dInst.capChecks.check_enable = True; dInst.capChecks.check_authority_src = Src1; dInst.capChecks.check_low_src = Src1Addr; @@ -1012,7 +1006,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapModify (SetBounds (SetBounds)); end f7_cap_CSetBoundsExact: begin - dInst.capChecks.src1_unsealed = True; dInst.capChecks.cap_exact = True; dInst.capChecks.check_enable = True; @@ -1028,8 +1021,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapModify (SetBounds (SetBounds)); end f7_cap_CSetOffset: begin - dInst.capChecks.src1_unsealed = True; - dInst.iType = Cap; regs.dst = Valid(tagged Gpr rd); regs.src1 = Valid(tagged Gpr rs1); @@ -1037,8 +1028,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapModify (ModifyOffset (SetOffset)); end f7_cap_CSetAddr: begin - dInst.capChecks.src2_unsealed = True; - dInst.iType = Cap; regs.dst = Valid(tagged Gpr rd); regs.src1 = Valid(tagged Gpr rs2); @@ -1046,8 +1035,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapModify (SetAddr (Src1Addr)); end f7_cap_CIncOffset: begin - dInst.capChecks.src1_unsealed = True; - dInst.iType = Cap; regs.dst = Valid(tagged Gpr rd); regs.src1 = Valid(tagged Gpr rs1); @@ -1056,7 +1043,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); end f7_cap_CSeal: begin dInst.capChecks.src2_tag = True; - dInst.capChecks.src1_unsealed = True; dInst.capChecks.src2_unsealed = True; dInst.capChecks.src2_permit_seal = True; dInst.capChecks.src2_addr_valid_type = True; @@ -1074,7 +1060,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapModify (Seal); end f7_cap_CCSeal: begin - dInst.capChecks.src1_unsealed = True; dInst.capChecks.src2_unsealed = True; dInst.capChecks.src2_addr_valid_type = True; dInst.capChecks.src2_permit_seal = True; @@ -1159,8 +1144,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapInspect (SetEqualExact); end f7_cap_CCopyType: begin - dInst.capChecks.src2_unsealed = True; - dInst.capChecks.check_enable = True; dInst.capChecks.check_authority_src = Src2; dInst.capChecks.check_low_src = Src1Type; @@ -1175,8 +1158,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapModify (SetAddr (Src1Type)); end f7_cap_CAndPerm: begin - dInst.capChecks.src1_unsealed = True; - dInst.iType = Cap; regs.dst = Valid(tagged Gpr rd); regs.src1 = Valid(tagged Gpr rs1); @@ -1184,8 +1165,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapModify (AndPerm); end f7_cap_CSetFlags: begin - dInst.capChecks.src1_unsealed = True; - dInst.iType = Cap; regs.dst = Valid(tagged Gpr rd); regs.src1 = Valid(tagged Gpr rs1); @@ -1193,8 +1172,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapModify (SetFlags); end f7_cap_CToPtr: begin - dInst.capChecks.src1_unsealed = True; - dInst.iType = Cap; regs.dst = Valid(tagged Gpr rd); regs.src1 = Valid(tagged Gpr rs1); @@ -1208,7 +1185,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapInspect (ToPtr); end f7_cap_CFromPtr: begin - dInst.capChecks.src2_unsealed = True; dInst.capChecks.cfromptr_bypass = True; dInst.iType = Cap; @@ -1227,7 +1203,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.execFunc = Alu (Sub); end f7_cap_CBuildCap: begin - dInst.capChecks.src2_unsealed = True; dInst.capChecks.src1_perm_subset_src2 = True; dInst.capChecks.src1_derivable = True; @@ -1337,7 +1312,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapInspect (GetAddr); end f5rs2_cap_CSealEntry: begin - dInst.capChecks.src1_unsealed = True; dInst.capChecks.src1_permit_x = True; dInst.iType = Cap; diff --git a/src_Core/RISCY_OOO/procs/lib/Exec.bsv b/src_Core/RISCY_OOO/procs/lib/Exec.bsv index 3918bae..9ab39bb 100644 --- a/src_Core/RISCY_OOO/procs/lib/Exec.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Exec.bsv @@ -240,11 +240,13 @@ endfunction (* noinline *) function Tuple2#(CapPipe,Bool) capModify(CapPipe a, CapPipe b, CapModifyFunc func); function t (x) = tuple2(x, ?); + let a_mut = setValidCap(a, isValidCap(a) && getKind(a) == UNSEALED); + let b_mut = setValidCap(b, isValidCap(b) && getKind(b) == UNSEALED); Tuple2#(CapPipe, Bool) res = (case(func) matches tagged ModifyOffset .offsetOp : - t(modifyOffset(a, getAddr(b), offsetOp == IncOffset).value); + t(modifyOffset(a_mut, getAddr(b), offsetOp == IncOffset).value); tagged SetBounds .boundsOp : - setBoundsALU(a, getAddr(b), boundsOp); + setBoundsALU(a_mut, getAddr(b), boundsOp); tagged SpecialRW .scrType : t(case (scrType) matches tagged TCC: b; @@ -258,23 +260,25 @@ function Tuple2#(CapPipe,Bool) capModify(CapPipe a, CapPipe b, CapModifyFunc fun else if (addrSource == Src1Type && (getKind(a) == SENTRY )) return t(nullWithAddr(otype_sentry_ext)); else if (addrSource == Src1Type && (getKind(a) == RES0 )) return t(nullWithAddr(otype_res0_ext)); else if (addrSource == Src1Type && (getKind(a) == RES1 )) return t(nullWithAddr(otype_res1_ext)); - else return t(setAddr(b, (addrSource == Src1Type) ? zeroExtend(getKind(a).SEALED_WITH_TYPE) : getAddr(a) ).value); + else return t(setAddr(b_mut, (addrSource == Src1Type) ? zeroExtend(getKind(a).SEALED_WITH_TYPE) : getAddr(a) ).value); tagged SealEntry : - t(setKind(a, SENTRY)); + t(setKind(a_mut, SENTRY)); tagged Seal : + t(setKind(a_mut, SEALED_WITH_TYPE (truncate(getAddr(b))))); + tagged CSeal : t((validAsType(b, getAddr(b)) && isValidCap(b) && getKind(a) == UNSEALED) ? - setKind(a, SEALED_WITH_TYPE (truncate(getAddr(b)))) + setKind(a_mut, SEALED_WITH_TYPE (truncate(getAddr(b)))) : a); tagged Unseal .src : t(setKind(((src == Src1) ? a:b), UNSEALED)); tagged AndPerm : - t(setPerms(a, pack(getPerms(a)) & truncate(getAddr(b)))); + t(setPerms(a_mut, pack(getPerms(a)) & truncate(getAddr(b)))); tagged SetFlags : - t(setFlags(a, truncate(getAddr(b)))); + t(setFlags(a_mut, truncate(getAddr(b)))); tagged FromPtr : - t(getAddr(a) == 0 ? nullCap : setOffset(b, getAddr(a)).value); + t(getAddr(a_mut) == 0 ? nullCap : setOffset(b, getAddr(a)).value); tagged BuildCap : - t(setKind(setValidCap(a, isValidCap(b)), getKind(a)==SENTRY ? SENTRY : UNSEALED)); + t(setKind(setValidCap(a_mut, isValidCap(b_mut)), getKind(a)==SENTRY ? SENTRY : UNSEALED)); tagged Move : t(a); tagged ClearTag : diff --git a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv index 7f159e6..0a3b903 100644 --- a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv +++ b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv @@ -330,6 +330,7 @@ typedef union tagged { SpecialRWFunc SpecialRW; AddrSource SetAddr; void Seal; + void CSeal; void SealEntry; SrcSelector Unseal; void AndPerm; From 2b471b0196f0adc8b12f9d47c04685c4df107d04 Mon Sep 17 00:00:00 2001 From: Peter Rugg Date: Tue, 18 Oct 2022 15:51:52 +0100 Subject: [PATCH 04/14] Don't require permit_x when constructing sentries --- src_Core/RISCY_OOO/procs/lib/Decode.bsv | 2 -- 1 file changed, 2 deletions(-) diff --git a/src_Core/RISCY_OOO/procs/lib/Decode.bsv b/src_Core/RISCY_OOO/procs/lib/Decode.bsv index bb1a00e..f645a93 100644 --- a/src_Core/RISCY_OOO/procs/lib/Decode.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Decode.bsv @@ -1312,8 +1312,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapInspect (GetAddr); end f5rs2_cap_CSealEntry: begin - dInst.capChecks.src1_permit_x = True; - dInst.iType = Cap; regs.dst = Valid(tagged Gpr rd); regs.src1 = Valid(tagged Gpr rs1); From b0233a01c4b1535b05e6489dea4c57e8a25bd0fa Mon Sep 17 00:00:00 2001 From: Peter Rugg Date: Tue, 25 Oct 2022 22:03:31 +0100 Subject: [PATCH 05/14] Remove trap on CSetBounds* --- libs/cheri-cap-lib | 2 +- src_Core/RISCY_OOO/procs/lib/Decode.bsv | 26 +------- src_Core/RISCY_OOO/procs/lib/Exec.bsv | 78 +++++++++++----------- src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv | 2 +- 4 files changed, 43 insertions(+), 65 deletions(-) diff --git a/libs/cheri-cap-lib b/libs/cheri-cap-lib index b80c1b3..d9ee2ea 160000 --- a/libs/cheri-cap-lib +++ b/libs/cheri-cap-lib @@ -1 +1 @@ -Subproject commit b80c1b3c5977b3aad0cf38125788566458e01493 +Subproject commit d9ee2ea339c75682b0eb0e7cb3d1d61ab3bc14c1 diff --git a/src_Core/RISCY_OOO/procs/lib/Decode.bsv b/src_Core/RISCY_OOO/procs/lib/Decode.bsv index f645a93..603e54b 100644 --- a/src_Core/RISCY_OOO/procs/lib/Decode.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Decode.bsv @@ -955,17 +955,11 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapModify (ModifyOffset (IncOffset)); end f3_cap_CSetBoundsImmediate: begin - dInst.capChecks.check_enable = True; - dInst.capChecks.check_authority_src = Src1; - dInst.capChecks.check_low_src = Src1Addr; - dInst.capChecks.check_high_src = ResultTop; - dInst.capChecks.check_inclusive = True; - dInst.iType = Cap; regs.dst = Valid(tagged Gpr rd); regs.src1 = Valid(tagged Gpr rs1); dInst.imm = Valid (immIunsigned); - dInst.capFunc = CapModify (SetBounds (SetBounds)); + dInst.capFunc = CapModify (SetBounds (SetBoundsRounding)); end f3_cap_ThreeOp: begin case (funct7) @@ -993,32 +987,18 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapModify (SpecialRW (scrType)); end f7_cap_CSetBounds: begin - dInst.capChecks.check_enable = True; - dInst.capChecks.check_authority_src = Src1; - dInst.capChecks.check_low_src = Src1Addr; - dInst.capChecks.check_high_src = ResultTop; - dInst.capChecks.check_inclusive = True; - dInst.iType = Cap; regs.dst = Valid(tagged Gpr rd); regs.src1 = Valid(tagged Gpr rs1); regs.src2 = Valid(tagged Gpr rs2); - dInst.capFunc = CapModify (SetBounds (SetBounds)); + dInst.capFunc = CapModify (SetBounds (SetBoundsRounding)); end f7_cap_CSetBoundsExact: begin - dInst.capChecks.cap_exact = True; - - dInst.capChecks.check_enable = True; - dInst.capChecks.check_authority_src = Src1; - dInst.capChecks.check_low_src = Src1Addr; - dInst.capChecks.check_high_src = ResultTop; - dInst.capChecks.check_inclusive = True; - dInst.iType = Cap; regs.dst = Valid(tagged Gpr rd); regs.src1 = Valid(tagged Gpr rs1); regs.src2 = Valid(tagged Gpr rs2); - dInst.capFunc = CapModify (SetBounds (SetBounds)); + dInst.capFunc = CapModify (SetBounds (SetBoundsExact)); end f7_cap_CSetOffset: begin dInst.iType = Cap; diff --git a/src_Core/RISCY_OOO/procs/lib/Exec.bsv b/src_Core/RISCY_OOO/procs/lib/Exec.bsv index 9ab39bb..99c01b9 100644 --- a/src_Core/RISCY_OOO/procs/lib/Exec.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Exec.bsv @@ -47,7 +47,7 @@ import ISA_Decls_CHERI::*; import CacheUtils::*; // For CLoadTags alignment (* noinline *) -function Maybe#(CSR_XCapCause) capChecksExec(CapPipe a, CapPipe b, CapPipe ddc, CapChecks toCheck, Bool cap_exact, ImmData imm); +function Maybe#(CSR_XCapCause) capChecksExec(CapPipe a, CapPipe b, CapPipe ddc, CapChecks toCheck, ImmData imm); function Maybe#(CSR_XCapCause) e1(CHERIException e) = Valid(CSR_XCapCause{cheri_exc_reg: toCheck.rn1, cheri_exc_code: e}); function Maybe#(CSR_XCapCause) e2(CHERIException e) = Valid(CSR_XCapCause{cheri_exc_reg: toCheck.rn2, cheri_exc_code: e}); function Maybe#(CSR_XCapCause) eDDC(CHERIException e) = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1, pack(scrAddrDDC)}, cheri_exc_code: e}); @@ -96,8 +96,6 @@ function Maybe#(CSR_XCapCause) capChecksExec(CapPipe a, CapPipe b, CapPipe ddc, result = e2(cheriExcSoftwarePermViolation); else if (toCheck.src1_derivable && !isDerivable(a)) result = e1(cheriExcLengthViolation); - else if (toCheck.cap_exact && !cap_exact) - result = e1(cheriExcRepresentViolation); return result; endfunction @@ -207,14 +205,17 @@ function Data alu(Data a, Data b, AluFunc func); endfunction (* noinline *) -function Tuple2#(CapPipe, Bool) setBoundsALU(CapPipe cap, Data len, SetBoundsFunc boundsOp); +function CapPipe setBoundsALU(CapPipe cap, Data len, SetBoundsFunc boundsOp); let combinedResult = setBoundsCombined(cap, len); CapPipe res = (case (boundsOp) matches - SetBounds: combinedResult.cap; + SetBoundsRounding: combinedResult.cap; + SetBoundsExact: combinedResult.cap; CRRL: nullWithAddr(combinedResult.length); CRAM: nullWithAddr(combinedResult.mask); endcase); - return tuple2(res, combinedResult.exact); + if (!combinedResult.inBounds) res = setValidCap(res, False); + if (boundsOp == SetBoundsExact && !combinedResult.exact) res = setValidCap(res, False); + return res; endfunction (* noinline *) @@ -238,51 +239,50 @@ function CapPipe specialRWALU(CapPipe cap, CapPipe oldCap, SpecialRWFunc scrType endfunction (* noinline *) -function Tuple2#(CapPipe,Bool) capModify(CapPipe a, CapPipe b, CapModifyFunc func); - function t (x) = tuple2(x, ?); +function CapPipe capModify(CapPipe a, CapPipe b, CapModifyFunc func); let a_mut = setValidCap(a, isValidCap(a) && getKind(a) == UNSEALED); let b_mut = setValidCap(b, isValidCap(b) && getKind(b) == UNSEALED); - Tuple2#(CapPipe, Bool) res = (case(func) matches + CapPipe res = (case(func) matches tagged ModifyOffset .offsetOp : - t(modifyOffset(a_mut, getAddr(b), offsetOp == IncOffset).value); + modifyOffset(a_mut, getAddr(b), offsetOp == IncOffset).value; tagged SetBounds .boundsOp : setBoundsALU(a_mut, getAddr(b), boundsOp); tagged SpecialRW .scrType : - t(case (scrType) matches + case (scrType) matches tagged TCC: b; tagged EPCC: b; tagged Normal: b; tagged TVEC ._: nullWithAddr(getOffset(b)); tagged EPC ._: nullWithAddr(getOffset(b)); - endcase); + endcase tagged SetAddr .addrSource : - if (addrSource == Src1Type && (getKind(a) == UNSEALED)) return t(nullWithAddr(otype_unsealed_ext)); - else if (addrSource == Src1Type && (getKind(a) == SENTRY )) return t(nullWithAddr(otype_sentry_ext)); - else if (addrSource == Src1Type && (getKind(a) == RES0 )) return t(nullWithAddr(otype_res0_ext)); - else if (addrSource == Src1Type && (getKind(a) == RES1 )) return t(nullWithAddr(otype_res1_ext)); - else return t(setAddr(b_mut, (addrSource == Src1Type) ? zeroExtend(getKind(a).SEALED_WITH_TYPE) : getAddr(a) ).value); + if (addrSource == Src1Type && (getKind(a) == UNSEALED)) return nullWithAddr(otype_unsealed_ext); + else if (addrSource == Src1Type && (getKind(a) == SENTRY )) return nullWithAddr(otype_sentry_ext); + else if (addrSource == Src1Type && (getKind(a) == RES0 )) return nullWithAddr(otype_res0_ext); + else if (addrSource == Src1Type && (getKind(a) == RES1 )) return nullWithAddr(otype_res1_ext); + else return setAddr(b_mut, (addrSource == Src1Type) ? zeroExtend(getKind(a).SEALED_WITH_TYPE) : getAddr(a) ).value; tagged SealEntry : - t(setKind(a_mut, SENTRY)); + setKind(a_mut, SENTRY); tagged Seal : - t(setKind(a_mut, SEALED_WITH_TYPE (truncate(getAddr(b))))); + setKind(a_mut, SEALED_WITH_TYPE (truncate(getAddr(b)))); tagged CSeal : - t((validAsType(b, getAddr(b)) && isValidCap(b) && getKind(a) == UNSEALED) ? - setKind(a_mut, SEALED_WITH_TYPE (truncate(getAddr(b)))) - : a); + ((validAsType(b, getAddr(b)) && isValidCap(b) && getKind(a) == UNSEALED) ? + setKind(a_mut, SEALED_WITH_TYPE (truncate(getAddr(b)))) + : a); tagged Unseal .src : - t(setKind(((src == Src1) ? a:b), UNSEALED)); + setKind(((src == Src1) ? a:b), UNSEALED); tagged AndPerm : - t(setPerms(a_mut, pack(getPerms(a)) & truncate(getAddr(b)))); + setPerms(a_mut, pack(getPerms(a)) & truncate(getAddr(b))); tagged SetFlags : - t(setFlags(a_mut, truncate(getAddr(b)))); + setFlags(a_mut, truncate(getAddr(b))); tagged FromPtr : - t(getAddr(a_mut) == 0 ? nullCap : setOffset(b, getAddr(a)).value); + (getAddr(a_mut) == 0 ? nullCap : setOffset(b, getAddr(a)).value); tagged BuildCap : - t(setKind(setValidCap(a_mut, isValidCap(b_mut)), getKind(a)==SENTRY ? SENTRY : UNSEALED)); + setKind(setValidCap(a_mut, isValidCap(b_mut)), getKind(a)==SENTRY ? SENTRY : UNSEALED); tagged Move : - t(a); + a; tagged ClearTag : - t(setValidCap(a, False)); + setValidCap(a, False); default: ?; endcase); return res; @@ -330,13 +330,13 @@ function Data capInspect(CapPipe a, CapPipe b, CapInspectFunc func); return res; endfunction -function Tuple2#(CapPipe, Bool) capALU(CapPipe a, CapPipe b, CapFunc func); - Tuple2#(CapPipe, Bool) res = (case (func) matches - tagged CapInspect .x: - tuple2(nullWithAddr(capInspect(a,b,func.CapInspect)),?); - default: - capModify(a,b,func.CapModify); - endcase); +function CapPipe capALU(CapPipe a, CapPipe b, CapFunc func); + CapPipe res = (case (func) matches + tagged CapInspect .x: + nullWithAddr(capInspect(a,b,func.CapInspect)); + default: + capModify(a,b,func.CapModify); + endcase); return res; endfunction @@ -417,9 +417,7 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C AluFunc alu_f = dInst.execFunc matches tagged Alu .alu_f ? alu_f : Add; Data alu_result = alu(getAddr(rVal1), getAddr(aluVal2), alu_f); - Tuple2#(CapPipe,Bool) cap_alu_result_with_exact = capALU(rVal1, aluVal2, dInst.capFunc); - CapPipe cap_alu_result = tpl_1(cap_alu_result_with_exact); - Bool cap_exact = tpl_2(cap_alu_result_with_exact); + CapPipe cap_alu_result = capALU(rVal1, aluVal2, dInst.capFunc); CapPipe link_pcc = addPc(pcc, ((orig_inst [1:0] == 2'b11) ? 4 : 2)); // Default branch function is not taken @@ -427,7 +425,7 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C cf.taken = aluBr(getAddr(rVal1), getAddr(rVal2), br_f); cf.nextPc = brAddrCalc(pcc, rVal1, dInst.iType, fromMaybe(0,getDInstImm(dInst)), cf.taken, orig_inst, newPcc); - Maybe#(CSR_XCapCause) capException = capChecksExec(rVal1, aluVal2, nullCap, dInst.capChecks, cap_exact, dInst.imm.Valid); + Maybe#(CSR_XCapCause) capException = capChecksExec(rVal1, aluVal2, nullCap, dInst.capChecks, dInst.imm.Valid); if (dInst.execFunc matches tagged Br .unused) begin rVal1 = cf.nextPc; if (!cf.taken) dInst.capChecks.check_enable = False; diff --git a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv index 0a3b903..ba191ad 100644 --- a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv +++ b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv @@ -301,7 +301,7 @@ typedef enum { } ModifyOffsetFunc deriving(Bits, Eq, FShow); typedef enum { - SetBounds, CRRL, CRAM + SetBoundsExact, SetBoundsRounding, CRRL, CRAM } SetBoundsFunc deriving(Bits, Eq, FShow); typedef enum { From de0c0315f4871a4f63e751772bdf5c355d7ef613 Mon Sep 17 00:00:00 2001 From: Peter Rugg Date: Tue, 25 Oct 2022 22:11:58 +0100 Subject: [PATCH 06/14] Remove trap conditions for CCopyType --- src_Core/RISCY_OOO/procs/lib/Decode.bsv | 7 ------- src_Core/RISCY_OOO/procs/lib/Exec.bsv | 4 ---- 2 files changed, 11 deletions(-) diff --git a/src_Core/RISCY_OOO/procs/lib/Decode.bsv b/src_Core/RISCY_OOO/procs/lib/Decode.bsv index 603e54b..9b75433 100644 --- a/src_Core/RISCY_OOO/procs/lib/Decode.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Decode.bsv @@ -1124,13 +1124,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapInspect (SetEqualExact); end f7_cap_CCopyType: begin - dInst.capChecks.check_enable = True; - dInst.capChecks.check_authority_src = Src2; - dInst.capChecks.check_low_src = Src1Type; - dInst.capChecks.check_high_src = Src1Type; - dInst.capChecks.check_inclusive = False; - dInst.capChecks.ccopytype_bypass = True; - dInst.iType = Cap; regs.dst = Valid(tagged Gpr rd); regs.src1 = Valid(tagged Gpr rs2); diff --git a/src_Core/RISCY_OOO/procs/lib/Exec.bsv b/src_Core/RISCY_OOO/procs/lib/Exec.bsv index 99c01b9..2009adf 100644 --- a/src_Core/RISCY_OOO/procs/lib/Exec.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Exec.bsv @@ -440,10 +440,6 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C capException = Invalid; boundsCheck = Invalid; end - if (dInst.capChecks.ccopytype_bypass && isValidCap(rVal2) && getKind(rVal2) == UNSEALED && (getKind(rVal1) matches tagged SEALED_WITH_TYPE .t ? !validAsType(rVal2, zeroExtend(t)) : True)) begin - capException = Invalid; - boundsCheck = Invalid; - end cf.nextPc = setKind(cf.nextPc, UNSEALED); cf.mispredict = cf.nextPc != ppc; From 4c166c95b97ea618b3b794a083f71280b989b1f9 Mon Sep 17 00:00:00 2001 From: Peter Rugg Date: Wed, 11 Jan 2023 17:40:51 +0000 Subject: [PATCH 07/14] Change treatment of reserved types in CCopyType --- src_Core/RISCY_OOO/procs/lib/Exec.bsv | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src_Core/RISCY_OOO/procs/lib/Exec.bsv b/src_Core/RISCY_OOO/procs/lib/Exec.bsv index 2009adf..7bd801b 100644 --- a/src_Core/RISCY_OOO/procs/lib/Exec.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Exec.bsv @@ -238,10 +238,23 @@ function CapPipe specialRWALU(CapPipe cap, CapPipe oldCap, SpecialRWFunc scrType return res; endfunction +function Tuple2#(Data, Bool) extractType(CapPipe a); + if (getKind(a) == UNSEALED) return tuple2(otype_unsealed_ext, True); + else if (getKind(a) == SENTRY ) return tuple2(otype_sentry_ext, True); + else if (getKind(a) == RES0 ) return tuple2(otype_res0_ext, True); + else if (getKind(a) == RES1 ) return tuple2(otype_res1_ext, True); + else return tuple2(zeroExtend(getKind(a).SEALED_WITH_TYPE), False); +endfunction + +function CapPipe clearTagIf(CapPipe a, Bool cond); + return setValidCap(a, isValidCap(a) && !cond); +endfunction + (* noinline *) function CapPipe capModify(CapPipe a, CapPipe b, CapModifyFunc func); let a_mut = setValidCap(a, isValidCap(a) && getKind(a) == UNSEALED); let b_mut = setValidCap(b, isValidCap(b) && getKind(b) == UNSEALED); + match {.a_type, .a_res} = extractType(a); CapPipe res = (case(func) matches tagged ModifyOffset .offsetOp : modifyOffset(a_mut, getAddr(b), offsetOp == IncOffset).value; @@ -256,11 +269,7 @@ function CapPipe capModify(CapPipe a, CapPipe b, CapModifyFunc func); tagged EPC ._: nullWithAddr(getOffset(b)); endcase tagged SetAddr .addrSource : - if (addrSource == Src1Type && (getKind(a) == UNSEALED)) return nullWithAddr(otype_unsealed_ext); - else if (addrSource == Src1Type && (getKind(a) == SENTRY )) return nullWithAddr(otype_sentry_ext); - else if (addrSource == Src1Type && (getKind(a) == RES0 )) return nullWithAddr(otype_res0_ext); - else if (addrSource == Src1Type && (getKind(a) == RES1 )) return nullWithAddr(otype_res1_ext); - else return setAddr(b_mut, (addrSource == Src1Type) ? zeroExtend(getKind(a).SEALED_WITH_TYPE) : getAddr(a) ).value; + clearTagIf(setAddr(b_mut, (addrSource == Src1Type) ? a_type : getAddr(a) ).value, a_res); tagged SealEntry : setKind(a_mut, SENTRY); tagged Seal : @@ -316,13 +325,7 @@ function Data capInspect(CapPipe a, CapPipe b, CapInspectFunc func); tagged GetPerm : zeroExtend(getPerms(a)); tagged GetType : - case (getKind(a)) matches - tagged UNSEALED: otype_unsealed_ext; - tagged SENTRY: otype_sentry_ext; - tagged RES0: otype_res0_ext; - tagged RES1: otype_res1_ext; - tagged SEALED_WITH_TYPE .t: zeroExtend(t); - endcase + tpl_1(extractType(a)); tagged ToPtr : (isValidCap(a) && isValidCap(b) ? (getAddr(a) - getBase(b)) : 0); default: ?; From ecdc2e010757276290018204952836a9ec116d60 Mon Sep 17 00:00:00 2001 From: Peter Rugg Date: Wed, 11 Jan 2023 17:50:37 +0000 Subject: [PATCH 08/14] Remove remaining unsealed checks --- src_Core/RISCY_OOO/procs/lib/Decode.bsv | 3 --- src_Core/RISCY_OOO/procs/lib/Exec.bsv | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src_Core/RISCY_OOO/procs/lib/Decode.bsv b/src_Core/RISCY_OOO/procs/lib/Decode.bsv index 9b75433..1b12d5c 100644 --- a/src_Core/RISCY_OOO/procs/lib/Decode.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Decode.bsv @@ -1023,7 +1023,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); end f7_cap_CSeal: begin dInst.capChecks.src2_tag = True; - dInst.capChecks.src2_unsealed = True; dInst.capChecks.src2_permit_seal = True; dInst.capChecks.src2_addr_valid_type = True; @@ -1040,7 +1039,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapModify (Seal); end f7_cap_CCSeal: begin - dInst.capChecks.src2_unsealed = True; dInst.capChecks.src2_addr_valid_type = True; dInst.capChecks.src2_permit_seal = True; dInst.capChecks.ccseal_bypass = True; @@ -1092,7 +1090,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); f7_cap_CUnseal: begin dInst.capChecks.src2_tag = True; dInst.capChecks.src1_sealed_with_type = True; - dInst.capChecks.src2_unsealed = True; dInst.capChecks.src2_points_to_src1_type = True; dInst.capChecks.src2_permit_unseal = True; diff --git a/src_Core/RISCY_OOO/procs/lib/Exec.bsv b/src_Core/RISCY_OOO/procs/lib/Exec.bsv index 7bd801b..4188152 100644 --- a/src_Core/RISCY_OOO/procs/lib/Exec.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Exec.bsv @@ -273,13 +273,13 @@ function CapPipe capModify(CapPipe a, CapPipe b, CapModifyFunc func); tagged SealEntry : setKind(a_mut, SENTRY); tagged Seal : - setKind(a_mut, SEALED_WITH_TYPE (truncate(getAddr(b)))); + clearTagIf(setKind(a_mut, SEALED_WITH_TYPE (truncate(getAddr(b)))), getKind(b) != UNSEALED); tagged CSeal : ((validAsType(b, getAddr(b)) && isValidCap(b) && getKind(a) == UNSEALED) ? setKind(a_mut, SEALED_WITH_TYPE (truncate(getAddr(b)))) : a); tagged Unseal .src : - setKind(((src == Src1) ? a:b), UNSEALED); + clearTagIf(setKind(((src == Src1) ? a:b), UNSEALED), (src == Src1) && (getKind(b) != UNSEALED)); tagged AndPerm : setPerms(a_mut, pack(getPerms(a)) & truncate(getAddr(b))); tagged SetFlags : From 9f24a516e6e9b3a933da30a0943edfa86a45cb4b Mon Sep 17 00:00:00 2001 From: Peter Rugg Date: Mon, 16 Jan 2023 10:43:32 +0000 Subject: [PATCH 09/14] Remove traps from CSeal and CCSeal --- src_Core/RISCY_OOO/procs/lib/Decode.bsv | 20 -------------------- src_Core/RISCY_OOO/procs/lib/Exec.bsv | 14 ++++++-------- 2 files changed, 6 insertions(+), 28 deletions(-) diff --git a/src_Core/RISCY_OOO/procs/lib/Decode.bsv b/src_Core/RISCY_OOO/procs/lib/Decode.bsv index 1b12d5c..c58b934 100644 --- a/src_Core/RISCY_OOO/procs/lib/Decode.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Decode.bsv @@ -1022,16 +1022,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapModify (ModifyOffset (IncOffset)); end f7_cap_CSeal: begin - dInst.capChecks.src2_tag = True; - dInst.capChecks.src2_permit_seal = True; - dInst.capChecks.src2_addr_valid_type = True; - - dInst.capChecks.check_enable = True; - dInst.capChecks.check_authority_src = Src2; - dInst.capChecks.check_low_src = Src2Addr; - dInst.capChecks.check_high_src = Src2Addr; - dInst.capChecks.check_inclusive = False; - dInst.iType = Cap; regs.dst = Valid(tagged Gpr rd); regs.src1 = Valid(tagged Gpr rs1); @@ -1039,16 +1029,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapModify (Seal); end f7_cap_CCSeal: begin - dInst.capChecks.src2_addr_valid_type = True; - dInst.capChecks.src2_permit_seal = True; - dInst.capChecks.ccseal_bypass = True; - - dInst.capChecks.check_enable = True; - dInst.capChecks.check_authority_src = Src2; - dInst.capChecks.check_low_src = Src2Addr; - dInst.capChecks.check_high_src = Src2Addr; - dInst.capChecks.check_inclusive = False; - dInst.iType = Cap; regs.dst = Valid(tagged Gpr rd); regs.src1 = Valid(tagged Gpr rs1); diff --git a/src_Core/RISCY_OOO/procs/lib/Exec.bsv b/src_Core/RISCY_OOO/procs/lib/Exec.bsv index 4188152..a2f12f9 100644 --- a/src_Core/RISCY_OOO/procs/lib/Exec.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Exec.bsv @@ -255,6 +255,8 @@ function CapPipe capModify(CapPipe a, CapPipe b, CapModifyFunc func); let a_mut = setValidCap(a, isValidCap(a) && getKind(a) == UNSEALED); let b_mut = setValidCap(b, isValidCap(b) && getKind(b) == UNSEALED); match {.a_type, .a_res} = extractType(a); + Bool sealPassthrough = !isValidCap(b) || getKind(a) != UNSEALED || !isInBounds(b, False) || getAddr(b) == otype_unsealed_ext; + Bool sealIllegal = getKind(b) != UNSEALED || !getHardPerms(b).permitSeal || !validAsType(b, getAddr(b)); CapPipe res = (case(func) matches tagged ModifyOffset .offsetOp : modifyOffset(a_mut, getAddr(b), offsetOp == IncOffset).value; @@ -273,11 +275,11 @@ function CapPipe capModify(CapPipe a, CapPipe b, CapModifyFunc func); tagged SealEntry : setKind(a_mut, SENTRY); tagged Seal : - clearTagIf(setKind(a_mut, SEALED_WITH_TYPE (truncate(getAddr(b)))), getKind(b) != UNSEALED); + clearTagIf( setKind(a_mut, SEALED_WITH_TYPE (truncate(getAddr(b)))) + , sealPassthrough || sealIllegal); tagged CSeal : - ((validAsType(b, getAddr(b)) && isValidCap(b) && getKind(a) == UNSEALED) ? - setKind(a_mut, SEALED_WITH_TYPE (truncate(getAddr(b)))) - : a); + (sealPassthrough ? a : + clearTagIf(setKind(a_mut, SEALED_WITH_TYPE (truncate(getAddr(b)))), sealIllegal)); tagged Unseal .src : clearTagIf(setKind(((src == Src1) ? a:b), UNSEALED), (src == Src1) && (getKind(b) != UNSEALED)); tagged AndPerm : @@ -439,10 +441,6 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C if (dInst.capChecks.cfromptr_bypass && getAddr(rVal1) == 0) begin capException = Invalid; end - if (dInst.capChecks.ccseal_bypass && (!isValidCap(rVal2) || getAddr(rVal2) == -1 || getKind(rVal1) != UNSEALED || !isInBounds(rVal2, False)) && isValidCap(rVal1)) begin - capException = Invalid; - boundsCheck = Invalid; - end cf.nextPc = setKind(cf.nextPc, UNSEALED); cf.mispredict = cf.nextPc != ppc; From ca711eab2abf346af2f27a66df9dd6b4fcbc9d0f Mon Sep 17 00:00:00 2001 From: Peter Rugg Date: Tue, 20 Jun 2023 09:45:48 +0100 Subject: [PATCH 10/14] Remove exceptions from CToPtr and CFromPtr --- src_Core/RISCY_OOO/procs/lib/Decode.bsv | 2 -- src_Core/RISCY_OOO/procs/lib/Exec.bsv | 7 ++----- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src_Core/RISCY_OOO/procs/lib/Decode.bsv b/src_Core/RISCY_OOO/procs/lib/Decode.bsv index c58b934..557ba20 100644 --- a/src_Core/RISCY_OOO/procs/lib/Decode.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Decode.bsv @@ -1135,8 +1135,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapInspect (ToPtr); end f7_cap_CFromPtr: begin - dInst.capChecks.cfromptr_bypass = True; - dInst.iType = Cap; regs.dst = Valid(tagged Gpr rd); regs.src1 = Valid(tagged Gpr rs2); diff --git a/src_Core/RISCY_OOO/procs/lib/Exec.bsv b/src_Core/RISCY_OOO/procs/lib/Exec.bsv index a2f12f9..ac5a8e6 100644 --- a/src_Core/RISCY_OOO/procs/lib/Exec.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Exec.bsv @@ -287,7 +287,7 @@ function CapPipe capModify(CapPipe a, CapPipe b, CapModifyFunc func); tagged SetFlags : setFlags(a_mut, truncate(getAddr(b))); tagged FromPtr : - (getAddr(a_mut) == 0 ? nullCap : setOffset(b, getAddr(a)).value); + (getAddr(a) == 0 ? nullCap : setOffset(b_mut, getAddr(a)).value); tagged BuildCap : setKind(setValidCap(a_mut, isValidCap(b_mut)), getKind(a)==SENTRY ? SENTRY : UNSEALED); tagged Move : @@ -329,7 +329,7 @@ function Data capInspect(CapPipe a, CapPipe b, CapInspectFunc func); tagged GetType : tpl_1(extractType(a)); tagged ToPtr : - (isValidCap(a) && isValidCap(b) ? (getAddr(a) - getBase(b)) : 0); + (isValidCap(a) ? getAddr(a) - getBase(b) : 0); default: ?; endcase); return res; @@ -438,9 +438,6 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C Maybe#(BoundsCheck) boundsCheck = prepareBoundsCheck(rVal1, aluVal2, pcc, nullCap, 0, 0, // These three are only used in the memory pipe dInst.capChecks); - if (dInst.capChecks.cfromptr_bypass && getAddr(rVal1) == 0) begin - capException = Invalid; - end cf.nextPc = setKind(cf.nextPc, UNSEALED); cf.mispredict = cf.nextPc != ppc; From f3ac024b732f75fa20cccca13dc280d7354bf8e0 Mon Sep 17 00:00:00 2001 From: Peter Rugg Date: Tue, 20 Jun 2023 12:32:49 +0100 Subject: [PATCH 11/14] Remove exceptions from CUnseal --- src_Core/RISCY_OOO/procs/lib/Decode.bsv | 11 ----------- src_Core/RISCY_OOO/procs/lib/Exec.bsv | 3 ++- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src_Core/RISCY_OOO/procs/lib/Decode.bsv b/src_Core/RISCY_OOO/procs/lib/Decode.bsv index 557ba20..1c7b72b 100644 --- a/src_Core/RISCY_OOO/procs/lib/Decode.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Decode.bsv @@ -1068,17 +1068,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); endcase end f7_cap_CUnseal: begin - dInst.capChecks.src2_tag = True; - dInst.capChecks.src1_sealed_with_type = True; - dInst.capChecks.src2_points_to_src1_type = True; - dInst.capChecks.src2_permit_unseal = True; - - dInst.capChecks.check_enable = True; - dInst.capChecks.check_authority_src = Src2; - dInst.capChecks.check_low_src = Src2Addr; - dInst.capChecks.check_high_src = Src2Addr; - dInst.capChecks.check_inclusive = False; - dInst.iType = Cap; regs.dst = Valid(tagged Gpr rd); regs.src1 = Valid(tagged Gpr rs1); diff --git a/src_Core/RISCY_OOO/procs/lib/Exec.bsv b/src_Core/RISCY_OOO/procs/lib/Exec.bsv index ac5a8e6..1347f7a 100644 --- a/src_Core/RISCY_OOO/procs/lib/Exec.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Exec.bsv @@ -257,6 +257,7 @@ function CapPipe capModify(CapPipe a, CapPipe b, CapModifyFunc func); match {.a_type, .a_res} = extractType(a); Bool sealPassthrough = !isValidCap(b) || getKind(a) != UNSEALED || !isInBounds(b, False) || getAddr(b) == otype_unsealed_ext; Bool sealIllegal = getKind(b) != UNSEALED || !getHardPerms(b).permitSeal || !validAsType(b, getAddr(b)); + Bool unsealIllegal = !isValidCap(b) || getKind(a) != UNSEALED || getKind(b) == UNSEALED || a_res || getAddr(b) != a_type || !getHardPerms(b).permitUnseal || !isInBounds(b, False); CapPipe res = (case(func) matches tagged ModifyOffset .offsetOp : modifyOffset(a_mut, getAddr(b), offsetOp == IncOffset).value; @@ -281,7 +282,7 @@ function CapPipe capModify(CapPipe a, CapPipe b, CapModifyFunc func); (sealPassthrough ? a : clearTagIf(setKind(a_mut, SEALED_WITH_TYPE (truncate(getAddr(b)))), sealIllegal)); tagged Unseal .src : - clearTagIf(setKind(((src == Src1) ? a:b), UNSEALED), (src == Src1) && (getKind(b) != UNSEALED)); + clearTagIf(setKind(((src == Src1) ? a:b), UNSEALED), (src == Src1) && sealIllegal); tagged AndPerm : setPerms(a_mut, pack(getPerms(a)) & truncate(getAddr(b))); tagged SetFlags : From c8b0e12f792b992d74f2cf2147b778e3ad54f35a Mon Sep 17 00:00:00 2001 From: Peter Rugg Date: Tue, 20 Jun 2023 16:23:44 +0100 Subject: [PATCH 12/14] Remove traps for CBuildCap This will be very expensive in terms of area and possibly timing. Ideally this instruction would be multi-cycle or optimised to reduce the overhead. --- src_Core/RISCY_OOO/procs/lib/Decode.bsv | 9 --------- src_Core/RISCY_OOO/procs/lib/Exec.bsv | 3 ++- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src_Core/RISCY_OOO/procs/lib/Decode.bsv b/src_Core/RISCY_OOO/procs/lib/Decode.bsv index 1c7b72b..d134464 100644 --- a/src_Core/RISCY_OOO/procs/lib/Decode.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Decode.bsv @@ -1140,15 +1140,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.execFunc = Alu (Sub); end f7_cap_CBuildCap: begin - dInst.capChecks.src1_perm_subset_src2 = True; - dInst.capChecks.src1_derivable = True; - - dInst.capChecks.check_enable = True; - dInst.capChecks.check_authority_src = Src2; - dInst.capChecks.check_low_src = Src1Base; - dInst.capChecks.check_high_src = Src1Top; - dInst.capChecks.check_inclusive = True; - // Swap arguments so SCR possibly goes in RS2 dInst.iType = Cap; regs.dst = Valid(tagged Gpr rd); diff --git a/src_Core/RISCY_OOO/procs/lib/Exec.bsv b/src_Core/RISCY_OOO/procs/lib/Exec.bsv index 1347f7a..ae9ea52 100644 --- a/src_Core/RISCY_OOO/procs/lib/Exec.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Exec.bsv @@ -258,6 +258,7 @@ function CapPipe capModify(CapPipe a, CapPipe b, CapModifyFunc func); Bool sealPassthrough = !isValidCap(b) || getKind(a) != UNSEALED || !isInBounds(b, False) || getAddr(b) == otype_unsealed_ext; Bool sealIllegal = getKind(b) != UNSEALED || !getHardPerms(b).permitSeal || !validAsType(b, getAddr(b)); Bool unsealIllegal = !isValidCap(b) || getKind(a) != UNSEALED || getKind(b) == UNSEALED || a_res || getAddr(b) != a_type || !getHardPerms(b).permitUnseal || !isInBounds(b, False); + Bool buildCapIllegal = !isValidCap(b) || getKind(b) != UNSEALED || !isDerivable(a) || (getPerms(a) & getPerms(b)) != getPerms(a) || getBase(a) < getBase(b) || getTop(a) > getTop(b); // XXX needs optimisation CapPipe res = (case(func) matches tagged ModifyOffset .offsetOp : modifyOffset(a_mut, getAddr(b), offsetOp == IncOffset).value; @@ -290,7 +291,7 @@ function CapPipe capModify(CapPipe a, CapPipe b, CapModifyFunc func); tagged FromPtr : (getAddr(a) == 0 ? nullCap : setOffset(b_mut, getAddr(a)).value); tagged BuildCap : - setKind(setValidCap(a_mut, isValidCap(b_mut)), getKind(a)==SENTRY ? SENTRY : UNSEALED); + setKind(setValidCap(a_mut, !buildCapIllegal), getKind(a)==SENTRY ? SENTRY : UNSEALED); tagged Move : a; tagged ClearTag : From 86782f9bb50a498a270f8525e19e6a14d6e7bede Mon Sep 17 00:00:00 2001 From: Peter Rugg Date: Tue, 20 Jun 2023 16:46:39 +0100 Subject: [PATCH 13/14] Cleanup unused exception code --- src_Core/ISA/CHERIExceptions.bsvi | 6 +++--- src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi | 14 ------------- src_Core/RISCY_OOO/procs/lib/Exec.bsv | 22 +-------------------- 3 files changed, 4 insertions(+), 38 deletions(-) diff --git a/src_Core/ISA/CHERIExceptions.bsvi b/src_Core/ISA/CHERIExceptions.bsvi index b4376ee..fa810c6 100644 --- a/src_Core/ISA/CHERIExceptions.bsvi +++ b/src_Core/ISA/CHERIExceptions.bsvi @@ -8,7 +8,7 @@ `CHERIException(StackUnderflow, 5'd7) `CHERIException(SoftwarePermViolation, 5'd8) `CHERIException(MMUStoreCapProhibit, 5'd9) -`CHERIException(RepresentViolation, 5'd10) +// 5'd10 reserved (obsolete InexactBoundsViolation) `CHERIException(UnalignedBase, 5'd11) // 5'd12 - 5'd15 reserved `CHERIException(GlobalViolation, 5'd16) @@ -18,10 +18,10 @@ `CHERIException(PermitRCapViolation, 5'd20) `CHERIException(PermitWCapViolation, 5'd21) `CHERIException(PermitWLocalCapViolation, 5'd22) -`CHERIException(PermitSealViolation, 5'd23) +// 5'd23 reserved (obsolete PermitSealViolation) `CHERIException(PermitASRViolation, 5'd24) `CHERIException(PermitCCallViolation, 5'd25) // 5'd26 reserved (obsolete CCallAccessIDCViolation) -`CHERIException(PermitUnsealViolation, 5'd27) +// 5'd27 reserved (obsolete PermitUnsealViolation) `CHERIException(PermitSetCIDViolation, 5'd28) // 5'd29 - 5'd31 reserved diff --git a/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi b/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi index c13ed2c..26a1298 100644 --- a/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi +++ b/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi @@ -1,26 +1,12 @@ -`CAP_CHECK_FIELD(ddc_tag,"ddc_tag") `CAP_CHECK_FIELD(src1_tag,"src1_tag") `CAP_CHECK_FIELD(src2_tag,"src2_tag") `CAP_CHECK_FIELD(src1_sealed_with_type,"src1_sealed_with_type") `CAP_CHECK_FIELD(src2_sealed_with_type,"src2_sealed_with_type") -`CAP_CHECK_FIELD(ddc_unsealed,"ddc_unsealed") -`CAP_CHECK_FIELD(src1_unsealed,"src1_unsealed") `CAP_CHECK_FIELD(src1_unsealed_or_sentry,"src1_unsealed_or_sentry") `CAP_CHECK_FIELD(src1_unsealed_or_imm_zero,"src1_unsealed_or_imm_zero") -`CAP_CHECK_FIELD(src2_unsealed,"src2_unsealed") `CAP_CHECK_FIELD(src1_src2_types_match,"src1_src2_types_match") `CAP_CHECK_FIELD(src1_permit_ccall,"src1_permit_ccall") `CAP_CHECK_FIELD(src2_permit_ccall,"src2_permit_ccall") `CAP_CHECK_FIELD(src1_permit_x,"src1_permit_x") `CAP_CHECK_FIELD(src2_no_permit_x,"src2_no_permit_x") -`CAP_CHECK_FIELD(src2_permit_unseal,"src2_permit_unseal") -`CAP_CHECK_FIELD(src2_permit_seal,"src2_permit_seal") -`CAP_CHECK_FIELD(src2_points_to_src1_type,"src2_points_to_src1_type") -`CAP_CHECK_FIELD(src2_addr_valid_type,"src2_addr_valid_type") `CAP_CHECK_FIELD(src1_type_not_reserved,"src1_type_not_reserved") -`CAP_CHECK_FIELD(src1_perm_subset_src2,"src1_perm_subset_src2") -`CAP_CHECK_FIELD(src1_derivable,"src1_derivable") -`CAP_CHECK_FIELD(cfromptr_bypass,"cfromptr_bypass") -`CAP_CHECK_FIELD(ccseal_bypass,"ccseal_bypass") -`CAP_CHECK_FIELD(ccopytype_bypass,"ccopytype_bypass") -`CAP_CHECK_FIELD(cap_exact,"cap_exact") diff --git a/src_Core/RISCY_OOO/procs/lib/Exec.bsv b/src_Core/RISCY_OOO/procs/lib/Exec.bsv index ae9ea52..a072729 100644 --- a/src_Core/RISCY_OOO/procs/lib/Exec.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Exec.bsv @@ -52,22 +52,14 @@ function Maybe#(CSR_XCapCause) capChecksExec(CapPipe a, CapPipe b, CapPipe ddc, function Maybe#(CSR_XCapCause) e2(CHERIException e) = Valid(CSR_XCapCause{cheri_exc_reg: toCheck.rn2, cheri_exc_code: e}); function Maybe#(CSR_XCapCause) eDDC(CHERIException e) = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1, pack(scrAddrDDC)}, cheri_exc_code: e}); Maybe#(CSR_XCapCause) result = Invalid; - if (toCheck.ddc_tag && !isValidCap(ddc)) - result = eDDC(cheriExcTagViolation); - else if (toCheck.src1_tag && !isValidCap(a)) + if (toCheck.src1_tag && !isValidCap(a)) result = e1(cheriExcTagViolation); else if (toCheck.src2_tag && !isValidCap(b)) result = e2(cheriExcTagViolation); - else if (toCheck.ddc_unsealed && isValidCap(ddc) && (getKind(ddc) != UNSEALED)) - result = eDDC(cheriExcSealViolation); - else if (toCheck.src1_unsealed && isValidCap(a) && (getKind(a) != UNSEALED)) - result = e1(cheriExcSealViolation); else if (toCheck.src1_unsealed_or_sentry && isValidCap(a) && (getKind(a) != UNSEALED) && (getKind(a) != SENTRY)) result = e1(cheriExcSealViolation); else if (toCheck.src1_unsealed_or_imm_zero && isValidCap(a) && (getKind(a) != UNSEALED) && (imm != 0)) result = e1(cheriExcSealViolation); - else if (toCheck.src2_unsealed && isValidCap(b) && (getKind(b) != UNSEALED)) - result = e2(cheriExcSealViolation); else if (toCheck.src1_sealed_with_type && (getKind (a) matches tagged SEALED_WITH_TYPE .t ? False : True)) result = e1(cheriExcSealViolation); else if (toCheck.src2_sealed_with_type && (getKind (b) matches tagged SEALED_WITH_TYPE .t ? False : True)) @@ -84,18 +76,6 @@ function Maybe#(CSR_XCapCause) capChecksExec(CapPipe a, CapPipe b, CapPipe ddc, result = e1(cheriExcPermitXViolation); else if (toCheck.src2_no_permit_x && getHardPerms(b).permitExecute) result = e2(cheriExcPermitXViolation); - else if (toCheck.src2_permit_unseal && !getHardPerms(b).permitUnseal) - result = e2(cheriExcPermitUnsealViolation); - else if (toCheck.src2_permit_seal && !getHardPerms(b).permitSeal) - result = e2(cheriExcPermitSealViolation); - else if (toCheck.src2_points_to_src1_type && getAddr(b) != zeroExtend(getKind(a).SEALED_WITH_TYPE)) - result = e2(cheriExcTypeViolation); - else if (toCheck.src2_addr_valid_type && !validAsType(b, truncate(getAddr(b)))) - result = e2(cheriExcLengthViolation); - else if (toCheck.src1_perm_subset_src2 && (getPerms(a) & getPerms(b)) != getPerms(a)) - result = e2(cheriExcSoftwarePermViolation); - else if (toCheck.src1_derivable && !isDerivable(a)) - result = e1(cheriExcLengthViolation); return result; endfunction From ec4eacac9c2523af6b6d6265bbe298fc2bd6fd7d Mon Sep 17 00:00:00 2001 From: Peter Rugg Date: Mon, 26 Jun 2023 18:01:56 +0100 Subject: [PATCH 14/14] Fix CSetAddr tag clear bug --- src_Core/RISCY_OOO/procs/lib/Exec.bsv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src_Core/RISCY_OOO/procs/lib/Exec.bsv b/src_Core/RISCY_OOO/procs/lib/Exec.bsv index a072729..c408936 100644 --- a/src_Core/RISCY_OOO/procs/lib/Exec.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Exec.bsv @@ -253,7 +253,7 @@ function CapPipe capModify(CapPipe a, CapPipe b, CapModifyFunc func); tagged EPC ._: nullWithAddr(getOffset(b)); endcase tagged SetAddr .addrSource : - clearTagIf(setAddr(b_mut, (addrSource == Src1Type) ? a_type : getAddr(a) ).value, a_res); + clearTagIf(setAddr(b_mut, (addrSource == Src1Type) ? a_type : getAddr(a) ).value, (addrSource == Src1Type) ? a_res : False); tagged SealEntry : setKind(a_mut, SENTRY); tagged Seal :