Merge branch 'tag-clear' into CHERI

This commit is contained in:
Peter Rugg
2023-06-27 11:38:42 +01:00
6 changed files with 67 additions and 226 deletions

View File

@@ -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

View File

@@ -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")

View File

@@ -954,8 +954,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);
@@ -963,20 +961,11 @@ 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;
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)
@@ -1004,41 +993,20 @@ 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;
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.src1_tag = True;
dInst.capChecks.src1_unsealed = True;
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.capChecks.src1_unsealed = True;
dInst.iType = Cap;
regs.dst = Valid(tagged Gpr rd);
regs.src1 = Valid(tagged Gpr rs1);
@@ -1046,8 +1014,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);
@@ -1055,8 +1021,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);
@@ -1064,19 +1028,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;
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);
@@ -1084,20 +1035,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;
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);
@@ -1137,19 +1074,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;
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);
@@ -1172,16 +1096,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;
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);
@@ -1189,9 +1103,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;
regs.dst = Valid(tagged Gpr rd);
regs.src1 = Valid(tagged Gpr rs1);
@@ -1199,8 +1110,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);
@@ -1208,9 +1117,6 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.capFunc = CapModify (SetFlags);
end
f7_cap_CToPtr: begin
dInst.capChecks.src1_unsealed = True;
dInst.capChecks.src2_tag = True;
dInst.iType = Cap;
regs.dst = Valid(tagged Gpr rd);
regs.src1 = Valid(tagged Gpr rs1);
@@ -1224,10 +1130,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;
dInst.iType = Cap;
regs.dst = Valid(tagged Gpr rd);
regs.src1 = Valid(tagged Gpr rs2);
@@ -1244,17 +1146,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;
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);
@@ -1355,10 +1246,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;
dInst.iType = Cap;
regs.dst = Valid(tagged Gpr rd);
regs.src1 = Valid(tagged Gpr rs1);

View File

@@ -47,27 +47,19 @@ 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});
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,20 +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);
else if (toCheck.cap_exact && !cap_exact)
result = e1(cheriExcRepresentViolation);
return result;
endfunction
@@ -207,14 +185,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 *)
@@ -237,48 +218,64 @@ 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 Tuple2#(CapPipe,Bool) capModify(CapPipe a, CapPipe b, CapModifyFunc func);
function t (x) = tuple2(x, ?);
Tuple2#(CapPipe, Bool) res = (case(func) matches
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));
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 :
t(modifyOffset(a, getAddr(b), offsetOp == IncOffset).value);
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
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, (addrSource == Src1Type) ? zeroExtend(getKind(a).SEALED_WITH_TYPE) : getAddr(a) ).value);
clearTagIf(setAddr(b_mut, (addrSource == Src1Type) ? a_type : getAddr(a) ).value, (addrSource == Src1Type) ? a_res : False);
tagged SealEntry :
t(setKind(a, SENTRY));
setKind(a_mut, SENTRY);
tagged Seal :
t((validAsType(b, getAddr(b)) && isValidCap(b) && getKind(a) == UNSEALED) ?
setKind(a, SEALED_WITH_TYPE (truncate(getAddr(b))))
: a);
clearTagIf( setKind(a_mut, SEALED_WITH_TYPE (truncate(getAddr(b))))
, sealPassthrough || sealIllegal);
tagged CSeal :
(sealPassthrough ? a :
clearTagIf(setKind(a_mut, SEALED_WITH_TYPE (truncate(getAddr(b)))), sealIllegal));
tagged Unseal .src :
t(setKind(((src == Src1) ? a:b), UNSEALED));
clearTagIf(setKind(((src == Src1) ? a:b), UNSEALED), (src == Src1) && sealIllegal);
tagged AndPerm :
t(setPerms(a, pack(getPerms(a)) & truncate(getAddr(b))));
setPerms(a_mut, pack(getPerms(a)) & truncate(getAddr(b)));
tagged SetFlags :
t(setFlags(a, truncate(getAddr(b))));
setFlags(a_mut, truncate(getAddr(b)));
tagged FromPtr :
t(getAddr(a) == 0 ? nullCap : setOffset(b, getAddr(a)).value);
(getAddr(a) == 0 ? nullCap : setOffset(b_mut, getAddr(a)).value);
tagged BuildCap :
t(setKind(setValidCap(a, True), getKind(a)==SENTRY ? SENTRY : UNSEALED));
setKind(setValidCap(a_mut, !buildCapIllegal), getKind(a)==SENTRY ? SENTRY : UNSEALED);
tagged Move :
t(a);
a;
tagged ClearTag :
t(setValidCap(a, False));
setValidCap(a, False);
default: ?;
endcase);
return res;
@@ -312,27 +309,21 @@ 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) ? (getAddr(a) - getBase(b)) : 0);
(isValidCap(a) ? getAddr(a) - getBase(b) : 0);
default: ?;
endcase);
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
@@ -413,9 +404,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
@@ -423,7 +412,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;
@@ -431,28 +420,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);
`ifdef MELTDOWN_CF
if (boundsCheck matches tagged Valid .check &&& capException matches tagged Invalid) begin
if (!( (check.check_low >= check.authority_base) &&
(check.check_inclusive ? (check.check_high <= check.authority_top )
: (check.check_high < check.authority_top ))))
capException = Valid(CSR_XCapCause{cheri_exc_reg: check.authority_idx, cheri_exc_code: cheriExcLengthViolation});
end
`endif
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
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
`ifdef MELTDOWN_CF
if (isValid(capException)) cap_alu_result = setValidCap(cap_alu_result, False);
`endif
cf.nextPc = setKind(cf.nextPc, UNSEALED);
cf.mispredict = cf.nextPc != ppc;

View File

@@ -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 {
@@ -330,6 +330,7 @@ typedef union tagged {
SpecialRWFunc SpecialRW;
AddrSource SetAddr;
void Seal;
void CSeal;
void SealEntry;
SrcSelector Unseal;
void AndPerm;