forked from Imagelibrary/seL4
aarch64: avoid saving CPACR to a disabled VCPU
seL4_VCPUReg_CPACR was sometimes saved to an inactive current VCPU, overwriting the previous value and erroneously enabling FPU access. Signed-off-by: Ryan Barry <ryan.barry@proofcraft.systems>
This commit is contained in:
10
CHANGES.md
10
CHANGES.md
@@ -53,6 +53,16 @@ description indicates whether it is SOURCE-COMPATIBLE, BINARY-COMPATIBLE, or BRE
|
||||
|
||||
This was found by Alison Felizzi and independently by Ryan Barry during the integrity proofs for AArch64 hyp mode.
|
||||
|
||||
* Fixed: under some circumstances, `seL4_VCPUReg_CPACR` is saved twice to the current VCPU. The value of this
|
||||
register may change between saves, causing the latter save to unintentionally grant EL0/1 access to the FPU.
|
||||
|
||||
1. A thread with an active current VCPU switches to a thread without a VCPU. The current VCPU is disabled.
|
||||
1.1. `seL4_VCPUReg_CPACR` is saved to the current VCPU.
|
||||
1.2. `enableFpuEL01` updates the register, enabling FPU access in EL0 and EL1.
|
||||
2. The thread without a VCPU switches to a thread with a different VCPU to the first
|
||||
2.1. All registers from `seL4_VCPUReg_TTBR0` to `seL4_VCPUReg_SPSR_EL1` are saved. This range includes
|
||||
`seL4_VCPUReg_CPACR`, which overwrites the previously saved value and grants FPU access at EL0 and EL1.
|
||||
|
||||
### Upgrade Notes
|
||||
|
||||
---
|
||||
|
||||
@@ -630,8 +630,12 @@ static inline void armv_vcpu_boot_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void armv_vcpu_save(vcpu_t *vcpu, UNUSED bool_t active)
|
||||
static inline void armv_vcpu_save(vcpu_t *vcpu, bool_t active)
|
||||
{
|
||||
/* If we aren't active then this state already got stored when we were disabled */
|
||||
if (active) {
|
||||
vcpu_save_reg(vcpu, seL4_VCPUReg_CPACR);
|
||||
}
|
||||
vcpu_save_reg_range(vcpu, seL4_VCPUReg_TTBR0, seL4_VCPUReg_SPSR_EL1);
|
||||
|
||||
#ifdef ARM_HYP_CP14_SAVE_AND_RESTORE_VCPU_THREADS
|
||||
|
||||
@@ -72,18 +72,16 @@ typedef enum {
|
||||
} seL4_VCPUFault_Msg;
|
||||
|
||||
typedef enum {
|
||||
/* VM control registers EL1 */
|
||||
/* System control registers EL1 */
|
||||
seL4_VCPUReg_SCTLR = 0,
|
||||
seL4_VCPUReg_CPACR,
|
||||
seL4_VCPUReg_TTBR0,
|
||||
seL4_VCPUReg_TTBR1,
|
||||
seL4_VCPUReg_TCR,
|
||||
seL4_VCPUReg_MAIR,
|
||||
seL4_VCPUReg_AMAIR,
|
||||
seL4_VCPUReg_CIDR,
|
||||
|
||||
/* other system registers EL1 */
|
||||
seL4_VCPUReg_ACTLR,
|
||||
seL4_VCPUReg_CPACR,
|
||||
|
||||
/* exception handling registers EL1 */
|
||||
seL4_VCPUReg_AFSR0,
|
||||
|
||||
Reference in New Issue
Block a user