Skip to content

Commit 7b04a62

Browse files
committed
exception: Preserve PSTATE bits on EL0 & EL1 calls
Signed-off-by: Hector Martin <marcan@marcan.st>
1 parent 28652ee commit 7b04a62

File tree

2 files changed

+36
-11
lines changed

2 files changed

+36
-11
lines changed

src/exception.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -243,18 +243,33 @@ void exc_sync(u64 *regs)
243243
u64 esr = in_gl ? mrs(SYS_IMP_APL_ESR_GL1) : (el3 ? mrs(ESR_EL3) : mrs(ESR_EL1));
244244
u64 elr = in_gl ? mrs(SYS_IMP_APL_ELR_GL1) : (el3 ? mrs(ELR_EL3) : mrs(ELR_EL1));
245245

246-
if ((spsr & 0xf) == 0 && ((esr >> 26) & 0x3f) == 0x3c) {
246+
u32 iss = esr & 0xffffff;
247+
248+
if ((spsr & 0xf) == 0 && ((esr >> 26) & 0x3f) == 0x3c && iss == 0) {
249+
// brk 0
247250
// On clean EL0 return, let the normal exception return
248251
// path take us back to the return thunk.
249-
if (has_el2())
250-
msr(SPSR_EL1, 0x09 | (0xf << 6)); // EL2h
251-
else
252-
msr(SPSR_EL1, 0x05 | (0xf << 6)); // EL1h
252+
253+
spsr &= ~0x1f;
254+
spsr |= 0xf << 6;
255+
if (has_el2()) {
256+
spsr |= 0x09; // EL2h
257+
} else {
258+
spsr |= 0x05; // EL1h
259+
}
260+
261+
msr(SPSR_EL1, spsr);
253262

254263
msr(ELR_EL1, el0_ret);
255264
return;
256265
}
257266

267+
if (((esr >> 26) & 0x3f) == 0x3c && iss == 1) {
268+
// brk 1: Capture PSTATE
269+
regs[0] = spsr;
270+
return;
271+
}
272+
258273
if (in_el2() && !in_gl12() && (spsr & 0xf) == 5 && ((esr >> 26) & 0x3f) == 0x16) {
259274
// Hypercall
260275
u32 imm = mrs(ESR_EL2) & 0xffff;

src/exception_asm.S

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,14 @@ el0_call:
112112
isb
113113

114114
1:
115-
mrs x29, daif
115+
// Capture PSTATE
116+
mov x6, x0
117+
brk 1
118+
mov x29, x0
119+
bic x5, x0, #0xf
116120
msr daifset, #0xf
117-
msr spsr_el1, x29
121+
msr spsr_el1, x5
122+
mov x0, x6
118123

119124
ldr x5, =_el0_thunk
120125
msr elr_el1, x5
@@ -170,11 +175,16 @@ el1_call:
170175
isb
171176

172177
1:
173-
mrs x29, daif
174-
msr daifset, #0xf
178+
// Capture PSTATE
179+
mov x6, x0
180+
brk 1
181+
mov x29, x0
182+
bic x5, x0, #0xf
175183
mov x6, #5
176-
orr x5, x29, x6 // EL1h
177-
msr spsr_el2, x5
184+
orr x5, x5, x6 // EL1h
185+
msr daifset, #0xf
186+
msr spsr_el1, x5
187+
mov x0, x6
178188

179189
ldr x5, =_el1_thunk
180190
msr elr_el2, x5

0 commit comments

Comments
 (0)