Skip to content

Commit fee2449

Browse files
committed
Indirect Sentries: load pair flavor
1 parent 66646f2 commit fee2449

File tree

2 files changed

+86
-2
lines changed

2 files changed

+86
-2
lines changed

src/cheri_insts.sail

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -887,8 +887,8 @@ function sealCapIfAmbient(cap, otyp) : (Capability, bits(cap_otype_width)) -> Am
887887
if cap.permit_execute
888888
then seal_ok
889889
else AmbientSeal_CapEx(CapEx_PermitExecuteViolation)
890-
} else if sotype == otype_isentry_load then {
891-
// CSealL requires PermitLoad and PermitLoadCap
890+
} else if sotype == otype_isentry_load | sotype == otype_isentry_load_pair then {
891+
// CSealL and CSealLP require PermitLoad and PermitLoadCap
892892
if cap.permit_load then {
893893
if cap.permit_load_cap
894894
then seal_ok
@@ -1809,6 +1809,89 @@ function clause execute (CInvokeLAL(cd, cs)) = {
18091809
}
18101810
}
18111811

1812+
union clause ast = CInvokeLPAL : (regidx, regidx)
1813+
/*!
1814+
* Jump through an indirect, points-to-pair sentry capability held in
1815+
* capability register cs.
1816+
*/
1817+
function clause execute (CInvokeLAL(cd, cs)) = {
1818+
let cs_val = C(cs);
1819+
1820+
if not (cs_val.tag) then {
1821+
handle_cheri_reg_exception(CapEx_TagViolation, cs);
1822+
RETIRE_FAIL
1823+
} else if not (isCapSealed(cs_val)) |
1824+
signed(cs_val.otype) != otype_isentry_load_pair then {
1825+
handle_cheri_reg_exception(CapEx_SealViolation, cs);
1826+
RETIRE_FAIL
1827+
} else {
1828+
let pair = unsealCap(cs_val);
1829+
let pairaddr = cs_val.address;
1830+
1831+
if not (pair.permit_load) | not (pair.permit_load_cap) then {
1832+
handle_cheri_reg_exception(CapEx_PermitLoadViolation, cs);
1833+
RETIRE_FAIL
1834+
} else if not(inCapBounds(pair, pairaddr, 2 * cap_size)) then {
1835+
handle_cheri_reg_exception(CapEx_LengthViolation, cs);
1836+
RETIRE_FAIL
1837+
} else if not(is_aligned_addr(pairaddr, cap_size)) then {
1838+
handle_mem_exception(pairaddr, E_Load_Addr_Align());
1839+
RETIRE_FAIL
1840+
} else {
1841+
match load_cap_via_cap(0b0 @ cs, cs_val, pairaddr, false, false, PrivDefault()) {
1842+
None() => RETIRE_FAIL,
1843+
Some(_,npcc) => {
1844+
match load_cap_via_cap(0b0 @ cs, cs_val, pairaddr + cap_size, false, false, PrivDefault()) {
1845+
None() => RETIRE_FAIL,
1846+
Some(_,nidc) => match cjalr_worker(cd, cs, npcc, zeros()) {
1847+
RETIRE_FAIL => RETIRE_FAIL,
1848+
RETIRE_SUCCESS => {
1849+
C(31) = nidc;
1850+
RETIRE_SUCCESS
1851+
}
1852+
}
1853+
}
1854+
}
1855+
}
1856+
}
1857+
}
1858+
}
1859+
1860+
1861+
union clause ast = CSealLP : (regidx, regidx)
1862+
/*!
1863+
* Capability register *cd* is replaced with capability register *cs1* and
1864+
* sealed as an indirect, points-to-pair sentry
1865+
*
1866+
* ## Exceptions
1867+
*
1868+
* An exception is raised if:
1869+
* - *cs1*.**tag** is not set.
1870+
* - *cs1* is sealed.
1871+
* - *cs1*.**perms** does not grant both **Permit_Load** and
1872+
* **Permit_Load_Capability**.
1873+
*/
1874+
function clause execute (CSealLP(cd, cs1)) = {
1875+
let cs1_val = C(cs1);
1876+
if not (cs1_val.tag) then {
1877+
handle_cheri_reg_exception(CapEx_TagViolation, cs1);
1878+
RETIRE_FAIL
1879+
} else if (isCapSealed(cs1_val)) then {
1880+
handle_cheri_reg_exception(CapEx_SealViolation, cs1);
1881+
RETIRE_FAIL
1882+
} else if not (cs1_val.permit_load) then {
1883+
handle_cheri_reg_exception(CapEx_PermitLoadViolation, cs1);
1884+
RETIRE_FAIL
1885+
} else if not (cs1_val.permit_load_cap) then {
1886+
handle_cheri_reg_exception(CapEx_PermitLoadCapViolation, cs1);
1887+
RETIRE_FAIL
1888+
} else {
1889+
C(cd) = sealCap(cs1_val, to_bits(cap_otype_width, otype_isentry_load_pair));
1890+
RETIRE_SUCCESS
1891+
}
1892+
}
1893+
1894+
18121895
/* avoid platform checks for reservation address misalignment */
18131896
function check_res_misaligned(vaddr : xlenbits, width : word_width) -> bool =
18141897
match width {

src/cheri_types.sail

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ let reserved_otypes = 4
6464
let otype_unsealed = -1
6565
let otype_sentry = -2 /* Sealed erstwhile or prospective PCC */
6666
let otype_isentry_load = -3 /* Sealed erstwhile IDC pointing at PCC */
67+
let otype_isentry_load_pair = -4 /* Sealed pointer to pair of PCC and IDC */
6768

6869
enum CPtrCmpOp = {
6970
CEQ,

0 commit comments

Comments
 (0)