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>
This commit is contained in:
Andrew Cooper committed 2023-09-18 16:43:01 +01:00
1 parent 7aa28849a1
commit 21bdc25b05
3 files changed
+41 -3

No files matched your search

+13
View File
@@ -2259,6 +2259,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 < X86_EXC_NUM) && ((1U << ev) & ist_mask);
ASSERT(is_ist == ist_exit);
}
#endif
/*
* Local variables:
* mode: C
+8 -1
View File
@@ -117,8 +117,15 @@ compat_process_trap:
call compat_create_bounce_frame
jmp compat_test_all_events
/* %rbx: struct vcpu, interrupts disabled */
/* %rbx: struct vcpu, %r12: ist_exit, interrupts disabled */
ENTRY(compat_restore_all_guest)
#ifdef CONFIG_DEBUG
mov %rsp, %rdi
mov %r12, %rsi
call check_ist_exit
#endif
ASSERT_INTERRUPTS_DISABLED
mov $~(X86_EFLAGS_IOPL | X86_EFLAGS_VM), %r11d
and UREGS_eflags(%rsp),%r11d
+20 -2
View File
@@ -142,8 +142,15 @@ process_trap:
.section .text.entry, "ax", @progbits
/* %rbx: struct vcpu, interrupts disabled */
/* %rbx: struct vcpu, %r12: ist_exit, interrupts disabled */
restore_all_guest:
#ifdef CONFIG_DEBUG
mov %rsp, %rdi
mov %r12, %rsi
call check_ist_exit
#endif
ASSERT_INTERRUPTS_DISABLED
/* Stash guest SPEC_CTRL value while we can read struct vcpu. */
@@ -659,8 +666,15 @@ ENTRY(early_page_fault)
.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).
@@ -1087,6 +1101,10 @@ handle_ist_exception:
.L_ist_dispatch_done:
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 $X86_EXC_NMI, UREGS_entry_vector(%rsp)
jne ret_from_intr
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.