mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
x86/entry: Track the IST-ness of an entry for the exit paths
Use %r12 to hold an ist_exit boolean. This register is zero elsewhere in the entry/exit asm, so it only needs setting in the IST path. As this is subtle and fragile, add check_ist_exit() to be used in debugging builds to cross-check that the ist_exit boolean matches the entry vector. Write check_ist_exit() it in C, because it's debug only and the logic more complicated than I care to maintain in asm. For now, we only need to use this signal in the exit-to-Xen path, but some exit-to-guest paths happen in IST context too. Check the correctness in all exit paths to avoid the logic bit-rotting. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> (cherry picked from commit21bdc25b05) x86/entry: Partially revert IST-exit checks The patch adding check_ist_exit() didn't account for the fact that reset_stack_and_jump() is not an ABI-preserving boundary. The IST-ness in %r12 doesn't survive into the next context, and is a stale value C. This shows up in Gitlab CI for the Clang build: https://gitlab.com/xen-project/people/andyhhp/xen/-/jobs/5112783827 and in OSSTest for GCC 8: http://logs.test-lab.xenproject.org/osstest/logs/183045/test-amd64-amd64-xl-qemuu-debianhvm-amd64/serial-pinot0.log There's no straightforward way to reconstruct the IST-exit-ness on the exit-to-guest path after a context switch. For now, we only need IST-exit on the return-to-Xen path. Fixes:21bdc25b05("x86/entry: Track the IST-ness of an entry for the exit paths") Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> (cherry picked from commit9b57c800b7)
This commit is contained in:
1 parent
19aca8f327
commit
8064cbdbef
2 files changed
+25
-1
No files matched your search
@@ -2348,6 +2348,19 @@ void asm_domain_crash_synchronous(unsigned long addr)
|
||||
do_softirq();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
void check_ist_exit(const struct cpu_user_regs *regs, bool ist_exit)
|
||||
{
|
||||
const unsigned int ist_mask =
|
||||
(1U << X86_EXC_NMI) | (1U << X86_EXC_DB) |
|
||||
(1U << X86_EXC_DF) | (1U << X86_EXC_MC);
|
||||
uint8_t ev = regs->entry_vector;
|
||||
bool is_ist = (ev < TRAP_nr) && ((1U << ev) & ist_mask);
|
||||
|
||||
ASSERT(is_ist == ist_exit);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
|
||||
@@ -650,8 +650,15 @@ ret_from_intr:
|
||||
.section .text.entry, "ax", @progbits
|
||||
|
||||
ALIGN
|
||||
/* No special register assumptions. */
|
||||
/* %r12=ist_exit */
|
||||
restore_all_xen:
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
mov %rsp, %rdi
|
||||
mov %r12, %rsi
|
||||
call check_ist_exit
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check whether we need to switch to the per-CPU page tables, in
|
||||
* case we return to late PV exit code (from an NMI or #MC).
|
||||
@@ -1032,6 +1039,10 @@ handle_ist_exception:
|
||||
INDIRECT_CALL %rdx
|
||||
mov %r15, STACK_CPUINFO_FIELD(xen_cr3)(%r14)
|
||||
mov %bl, STACK_CPUINFO_FIELD(use_pv_cr3)(%r14)
|
||||
|
||||
/* This is an IST exit */
|
||||
mov $1, %r12d
|
||||
|
||||
cmpb $TRAP_nmi,UREGS_entry_vector(%rsp)
|
||||
jne ret_from_intr
|
||||
|
||||
|
||||