amd64 ef_rt_arch_call: Preserve %rflags around call into EFI RT service.
If service code faulted, we might end up unwinding with interrupts disabled. Top-level kernel code should have interrupts enabled, which is enforced by checks. Save %rflags before entering EFI, and restore to the known good value on return. This handles situation with disabled interrupts on fault and perhaps other potential bugs, e.g. invalid value for PSL_D. Reported and tested by: Jan Martin Mikkelsen <janm@transactionware.com> Sponsored by: The FreeBSD Foundation MFC after: 1 week
This commit is contained in:
parent
f6e5ddff6b
commit
185f7e0a9d
@ -47,6 +47,9 @@ ENTRY(efi_rt_arch_call)
|
||||
movq %r13, EC_R13(%rdi)
|
||||
movq %r14, EC_R14(%rdi)
|
||||
movq %r15, EC_R15(%rdi)
|
||||
pushfq
|
||||
popq %rax
|
||||
movq %rax, EC_RFLAGS(%rdi)
|
||||
movq PCPU(CURTHREAD), %rax
|
||||
movq %rdi, TD_MD+MD_EFIRT_TMP(%rax)
|
||||
movq PCPU(CURPCB), %rsi
|
||||
@ -98,6 +101,8 @@ efi_rt_arch_call_tail:
|
||||
movq EC_RBP(%rdi), %rbp
|
||||
movq EC_RSP(%rdi), %rsp
|
||||
movq EC_RBX(%rdi), %rbx
|
||||
pushq EC_RFLAGS(%rdi)
|
||||
popfq
|
||||
|
||||
popq %rbp
|
||||
ret
|
||||
|
@ -272,3 +272,4 @@ ASSYM(EC_R12, offsetof(struct efirt_callinfo, ec_r12));
|
||||
ASSYM(EC_R13, offsetof(struct efirt_callinfo, ec_r13));
|
||||
ASSYM(EC_R14, offsetof(struct efirt_callinfo, ec_r14));
|
||||
ASSYM(EC_R15, offsetof(struct efirt_callinfo, ec_r15));
|
||||
ASSYM(EC_RFLAGS, offsetof(struct efirt_callinfo, ec_rflags));
|
||||
|
@ -72,6 +72,7 @@ struct efirt_callinfo {
|
||||
register_t ec_r13;
|
||||
register_t ec_r14;
|
||||
register_t ec_r15;
|
||||
register_t ec_rflags;
|
||||
};
|
||||
|
||||
#endif /* __AMD64_INCLUDE_EFI_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user