HW: SPRR and GXF - AsahiLinux/docs GitHub Wiki
Guarded execution
Guarded execution mode is a lateral exception level next to EL1 and EL2 which uses the same pagetables but different permissions (see SPRR). These levels are called GL1 and GL2. It's enabled with bit 1 in S3_6_C15_1_2.
The instruction 0x00201420
is genter and switches from EL to GL and sets the PC to S3_6_C15_C8_1
.
0x00201420
is gexit which returns to EL.
#define SYS_GXF_ENTER_EL1 sys_reg(3, 6, 15, 8, 1)
Guarded mode has a separate set of ELR, FAR, ESR, SPSR, VBAR and TPIDR registers just like EL1/2. Additionally the ASPSR register indicates if gexit should return to GL or EL.
#define SYS_TPIDR_GL1 sys_reg(3, 6, 15, 10, 1)
#define SYS_VBAR_GL1 sys_reg(3, 6, 15, 10, 2)
#define SYS_SPSR_GL1 sys_reg(3, 6, 15, 10, 3)
#define SYS_ASPSR_GL1 sys_reg(3, 6, 15, 10, 4)
#define SYS_ESR_GL1 sys_reg(3, 6, 15, 10, 5)
#define SYS_ELR_GL1 sys_reg(3, 6, 15, 10, 6)
#define SYS_FAR_GL1 sys_reg(3, 6, 15, 10, 7)
SPRR
SPRR takes the permission bits from pagetable entries and converts them into an attribute index similar to how MAIR works:
3 2 1 0
AP[1] AP[0] UXN PXN
Note that UXN and PXN are flipped compared to APRR!
This is then used to index into a system register where each entry has four bits:
3 2 1 0
GL[1] GL[0] EL[1] EL[0]
GL/EL can be treated mostly separate but there are two exceptions where a specific GL permissions modifies what the two EL bits usually mean.
register value | EL page permissions | GL page permissions |
---|---|---|
0000 |
--- |
--- |
0001 |
r-x |
--- |
0010 |
r-- |
--- |
0011 |
rw- |
--- |
0100 |
--- |
r-x |
0101 |
r-x |
r-x |
0110 |
r-- |
r-x |
0111 |
--- |
r-x |
1000 |
--- |
r-- |
1001 |
--x |
r-- |
1010 |
r-- |
r-- |
1011 |
rw- |
r-- |
1100 |
--- |
rw- |
1101 |
r-x |
rw- |
1110 |
r-- |
rw- |
1111 |
rw- |
rw- |
These four bits indicate the actual permissions when running in EL or GL mode. EL0 and EL1 have separate registers such that the permissions are decoupled.
bit 1 in S3_6_C15_C1_0 / SPRR_CONFIG_EL1 enables SPRR and access to new system registers.
S3_6_C15_1_5 is the permissions register for EL0 and S3_6_C15_1_6 is for EL1/GL1.
#define SYS_SPRR_CONFIG_EL1 sys_reg(3, 6, 15, 1, 0)
#define SPRR_CONFIG_EN BIT(0)
#define SPRR_CONFIG_LOCK_CONFIG BIT(1)
#define SPRR_CONFIG_LOCK_PERM_EL0 BIT(4)
#define SPRR_CONFIG_LOCK_PERM_EL1 BIT(5)
#define SYS_SPRR_PERM_EL0 sys_reg(3, 6, 15, 1, 5)
#define SYS_SPRR_PERM_EL1 sys_reg(3, 6, 15, 1, 6)