Merge branch 'tag-clear' into CHERI
This commit is contained in:
Submodule libs/cheri-cap-lib updated: 806b687e8a...f11156ef9a
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user