Skip to content

Commit 5e33498

Browse files
committed
Indirect sentries, Load-PCC flavor
1 parent 9350ea7 commit 5e33498

File tree

3 files changed

+95
-1
lines changed

3 files changed

+95
-1
lines changed

src/cheri_cap_common.sail

+4
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,10 @@ function isCapSealed(cap) = signed(cap.otype) != otype_unsealed
416416
val hasReservedOType : Capability -> bool
417417
function hasReservedOType(cap) = unsigned(cap.otype) > cap_max_otype
418418

419+
function isCapSentryOrIsentry(cap) : Capability -> bool =
420+
let sotype = signed(cap.otype) in
421+
(sotype == otype_sentry) | (sotype == otype_isentry_pcc)
422+
419423
function sealCap(cap, otyp) : (Capability, bits(cap_otype_width)) -> Capability =
420424
{cap with otype=otyp}
421425

src/cheri_insts.sail

+90-1
Original file line numberDiff line numberDiff line change
@@ -933,7 +933,7 @@ function clause execute (CBuildCap(cd, cs1, cs2)) = {
933933
RETIRE_FAIL
934934
} else {
935935
assert(exact, "CBuildCap: setCapBounds was not exact"); /* base and top came from cs2 originally so will be exact */
936-
let cd5 = if signed(cs2_val.otype) == otype_sentry then sealCap(cd4, to_bits(cap_otype_width, otype_sentry)) else cd4;
936+
let cd5 = if isCapSentryOrIsentry(cs2_val) then sealCap(cd4, cs2_val.otype) else cd4;
937937
C(cd) = cd5;
938938
RETIRE_SUCCESS
939939
}
@@ -1695,6 +1695,89 @@ function clause execute (CLoadTags(rd, cs1)) = {
16951695
}
16961696
}
16971697

1698+
/*
1699+
* Indirect sentries.
1700+
*
1701+
* At the risk of becoming CISC, the invocation instructions load, unseal, and
1702+
* transfer control. They depend on helpers above for most of those tasks.
1703+
*/
1704+
1705+
union clause ast = CSealL : (regidx, regidx)
1706+
/*!
1707+
* Capability register *cd* is replaced with capability register *cs1* and
1708+
* sealed as an indirect, points-to-PCC sentry
1709+
*
1710+
* ## Exceptions
1711+
*
1712+
* An exception is raised if:
1713+
* - *cs1*.**tag** is not set.
1714+
* - *cs1* is sealed.
1715+
* - *cs1*.**perms** does not grant both **Permit_Load** and
1716+
* **Permit_Load_Capability**.
1717+
*/
1718+
function clause execute (CSealL(cd, cs1)) = {
1719+
let cs1_val = C(cs1);
1720+
if not (cs1_val.tag) then {
1721+
handle_cheri_reg_exception(CapEx_TagViolation, cs1);
1722+
RETIRE_FAIL
1723+
} else if (isCapSealed(cs1_val)) then {
1724+
handle_cheri_reg_exception(CapEx_SealViolation, cs1);
1725+
RETIRE_FAIL
1726+
} else if not (cs1_val.permit_load) then {
1727+
handle_cheri_reg_exception(CapEx_PermitLoadViolation, cs1);
1728+
RETIRE_FAIL
1729+
} else if not (cs1_val.permit_load_cap) then {
1730+
handle_cheri_reg_exception(CapEx_PermitLoadCapViolation, cs1);
1731+
RETIRE_FAIL
1732+
} else {
1733+
C(cd) = sealCap(cs1_val, to_bits(cap_otype_width, otype_isentry_pcc));
1734+
RETIRE_SUCCESS
1735+
}
1736+
}
1737+
1738+
union clause ast = CInvokeLAL : (regidx, regidx)
1739+
/*!
1740+
* Jump through an indirect, points-to-PCC sentry capability held in
1741+
* capability register cs.
1742+
*/
1743+
function clause execute (CInvokeLAL(cd, cs)) = {
1744+
let cs_val = C(cs);
1745+
1746+
if not (cs_val.tag) then {
1747+
handle_cheri_reg_exception(CapEx_TagViolation, cs);
1748+
RETIRE_FAIL
1749+
} else if not (isCapSealed(cs_val)) |
1750+
signed(cs_val.otype) != otype_isentry_pcc then {
1751+
handle_cheri_reg_exception(CapEx_SealViolation, cs);
1752+
RETIRE_FAIL
1753+
} else {
1754+
let idc = unsealCap(cs_val);
1755+
let idcaddr = cs_val.address;
1756+
1757+
if not (idc.permit_load) | not (idc.permit_load_cap) then {
1758+
handle_cheri_reg_exception(CapEx_PermitLoadViolation, cs);
1759+
RETIRE_FAIL
1760+
} else if not(inCapBounds(idc, idcaddr, cap_size)) then {
1761+
handle_cheri_reg_exception(CapEx_LengthViolation, cs);
1762+
RETIRE_FAIL
1763+
} else if not(is_aligned_addr(idcaddr, cap_size)) then {
1764+
handle_mem_exception(idcaddr, E_Load_Addr_Align());
1765+
RETIRE_FAIL
1766+
} else {
1767+
match load_cap_via_cap(0b0 @ cs, cs_val, idcaddr) {
1768+
None() => RETIRE_FAIL,
1769+
Some(v) => match cjalr_worker(cd, cs, v, zeros()) {
1770+
RETIRE_FAIL => RETIRE_FAIL,
1771+
RETIRE_SUCCESS => {
1772+
C(31) = idc;
1773+
RETIRE_SUCCESS
1774+
}
1775+
}
1776+
}
1777+
}
1778+
}
1779+
}
1780+
16981781
/* avoid platform checks for reservation address misalignment */
16991782
function check_res_misaligned(vaddr : xlenbits, width : word_width) -> bool =
17001783
match width {
@@ -2376,6 +2459,9 @@ mapping clause encdec = JALR_PCC(rd, rs1) if (haveXcheri()) <-> 0b1111111 @ 0b
23762459

23772460
mapping clause encdec = CLoadTags(rd, cs1) if (haveXcheri()) <-> 0b1111111 @ 0b10010 @ cs1 @ 0b000 @ rd @ 0b1011011 if (haveXcheri())
23782461

2462+
mapping clause encdec = CSealL(cd, cs1) if (haveXcheri()) <-> 0b1111111 @ 0b11000 @ cs1 @ 0b000 @ cd @ 0b1011011 if (haveXcheri())
2463+
mapping clause encdec = CInvokeLAL(cd, cs1) if (haveXcheri()) <-> 0b1111111 @ 0b11001 @ cs1 @ 0b000 @ cd @ 0b1011011 if (haveXcheri())
2464+
23792465
mapping clause encdec = CRRL(rd, rs1) if (haveXcheri()) <-> 0b1111111 @ 0b01000 @ rs1 @ 0b000 @ rd @ 0b1011011 if (haveXcheri())
23802466
mapping clause encdec = CRAM(rd, rs1) if (haveXcheri()) <-> 0b1111111 @ 0b01001 @ rs1 @ 0b000 @ rd @ 0b1011011 if (haveXcheri())
23812467

@@ -2403,6 +2489,9 @@ mapping clause assembly = JALR_PCC(rd, rs1) <-> "jalr.pcc" ^ spc() ^ reg_
24032489

24042490
mapping clause assembly = CLoadTags(rd, cs1) <-> "cloadtags" ^ spc() ^ reg_name(rd) ^ sep() ^ "(" ^ cap_reg_name(cs1) ^ ")"
24052491

2492+
mapping clause assembly = CSealL(rd, cs1) <-> "cseall" ^ spc() ^ reg_name(rd) ^ sep() ^ "(" ^ cap_reg_name(cs1) ^ ")"
2493+
mapping clause assembly = CInvokeLAL(rd, cs1) <-> "cinvokelal" ^ spc() ^ reg_name(rd) ^ sep() ^ "(" ^ cap_reg_name(cs1) ^ ")"
2494+
24062495
mapping clause assembly = CRRL(rd, rs1) <-> "crrl" ^ spc() ^ reg_name(rd) ^ sep() ^ reg_name(rs1)
24072496
mapping clause assembly = CRAM(rd, rs1) <-> "cram" ^ spc() ^ reg_name(rd) ^ sep() ^ reg_name(rs1)
24082497

src/cheri_types.sail

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
let reserved_otypes = 4
6464
let otype_unsealed = -1
6565
let otype_sentry = -2 /* Sealed erstwhile or prospective PCC */
66+
let otype_isentry_pcc = -3 /* Sealed erstwhile IDC pointing at PCC */
6667

6768
enum CPtrCmpOp = {
6869
CEQ,

0 commit comments

Comments
 (0)