From: Zhenzhong Duan <zhenzhong.duan@xxxxxxxxx> According to TDX spec, specific instructions are simulated in #VE handler. To avoid missing single step on these instructions, such as cpuid(0xb) and wrmsr(0x1a0), we have to simulate #DB processing in #VE handler. Move declaration of do_handle_exception() in header file, so it can be used in #VE handler for #DB processing. Signed-off-by: Zhenzhong Duan <zhenzhong.duan@xxxxxxxxx> Reviewed-by: Yu Zhang <yu.c.zhang@xxxxxxxxx> Link: https://lore.kernel.org/r/20220303071907.650203-7-zhenzhong.duan@xxxxxxxxx Signed-off-by: Qian Wen <qian.wen@xxxxxxxxx> --- lib/x86/desc.c | 5 ----- lib/x86/desc.h | 5 +++++ lib/x86/tdx.c | 6 ++++++ 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/x86/desc.c b/lib/x86/desc.c index 14edac0c..d8a7f8ef 100644 --- a/lib/x86/desc.c +++ b/lib/x86/desc.c @@ -52,11 +52,6 @@ struct descriptor_table_ptr gdt_descr = { .base = (unsigned long)gdt, }; -#ifndef __x86_64__ -__attribute__((regparm(1))) -#endif -void do_handle_exception(struct ex_regs *regs); - /* * Fill an idt_entry_t or call gate entry, clearing e_sz bytes first. * diff --git a/lib/x86/desc.h b/lib/x86/desc.h index 54b3166f..8d6ea824 100644 --- a/lib/x86/desc.h +++ b/lib/x86/desc.h @@ -255,6 +255,11 @@ void set_gdt_entry(int sel, unsigned long base, u32 limit, u8 access, u8 gran); void load_gdt_tss(size_t tss_offset); void set_intr_alt_stack(int e, void *fn); void print_current_tss_info(void); + +#ifndef __x86_64__ +__attribute__((regparm(1))) +#endif +void do_handle_exception(struct ex_regs *regs); handler handle_exception(u8 v, handler fn); void unhandled_exception(struct ex_regs *regs, bool cpu); const char* exception_mnemonic(int vector); diff --git a/lib/x86/tdx.c b/lib/x86/tdx.c index 3909e283..dc722653 100644 --- a/lib/x86/tdx.c +++ b/lib/x86/tdx.c @@ -398,6 +398,12 @@ static bool tdx_handle_virt_exception(struct ex_regs *regs, /* After successful #VE handling, move the IP */ regs->rip += insn_len; + /* Simulate single step on simulated instruction */ + if (regs->rflags & X86_EFLAGS_TF) { + regs->vector = DB_VECTOR; + write_dr6(read_dr6() | (1 << 14)); + do_handle_exception(regs); + } return true; } -- 2.25.1