[Xen-devel] [PATCH v5] xen: get rid of paravirt op adjust_exception_frame
When running as Xen pv-guest the exception frame on the stack contains %r11 and %rcx additional to the other data pushed by the processor. Instead of having a paravirt op being called for each exception type prepend the Xen specific code to each exception entry. When running as Xen pv-guest just use the exception entry with prepended instructions, otherwise use the entry without the Xen specific code. Signed-off-by: Juergen Gross--- arch/x86/entry/entry_64.S | 23 ++-- arch/x86/entry/entry_64_compat.S | 1 - arch/x86/include/asm/paravirt.h | 5 -- arch/x86/include/asm/paravirt_types.h | 3 -- arch/x86/include/asm/proto.h | 3 ++ arch/x86/include/asm/traps.h | 28 -- arch/x86/kernel/asm-offsets_64.c | 1 - arch/x86/kernel/paravirt.c| 3 -- arch/x86/xen/enlighten_pv.c | 98 +++ arch/x86/xen/irq.c| 3 -- arch/x86/xen/xen-asm_64.S | 41 +-- arch/x86/xen/xen-ops.h| 1 - 12 files changed, 133 insertions(+), 77 deletions(-) diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 7a1d383c2192..bdd024a9afc9 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -821,7 +821,6 @@ ENTRY(\sym) .endif ASM_CLAC - PARAVIRT_ADJUST_EXCEPTION_FRAME .ifeq \has_error_code pushq $-1 /* ORIG_RAX: no syscall to restart */ @@ -967,7 +966,7 @@ ENTRY(do_softirq_own_stack) ENDPROC(do_softirq_own_stack) #ifdef CONFIG_XEN -idtentry xen_hypervisor_callback xen_do_hypervisor_callback has_error_code=0 +idtentry hypervisor_callback xen_do_hypervisor_callback has_error_code=0 /* * A note on the "critical region" in our callback handler. @@ -1034,8 +1033,6 @@ ENTRY(xen_failsafe_callback) movq8(%rsp), %r11 addq$0x30, %rsp pushq $0 /* RIP */ - pushq %r11 - pushq %rcx UNWIND_HINT_IRET_REGS offset=8 jmp general_protection 1: /* Segment mismatch => Category 1 (Bad segment). Retry the IRET. */ @@ -1066,9 +1063,8 @@ idtentry int3 do_int3 has_error_code=0paranoid=1 shift_ist=DEBUG_STACK idtentry stack_segment do_stack_segmenthas_error_code=1 #ifdef CONFIG_XEN -idtentry xen_debug do_debughas_error_code=0 -idtentry xen_int3 do_int3 has_error_code=0 -idtentry xen_stack_segment do_stack_segmenthas_error_code=1 +idtentry xendebug do_debughas_error_code=0 +idtentry xenint3 do_int3 has_error_code=0 #endif idtentry general_protectiondo_general_protection has_error_code=1 @@ -1232,21 +1228,10 @@ ENTRY(error_exit) END(error_exit) /* Runs on exception stack */ +/* XXX: broken on Xen PV */ ENTRY(nmi) UNWIND_HINT_IRET_REGS /* -* Fix up the exception frame if we're on Xen. -* PARAVIRT_ADJUST_EXCEPTION_FRAME is guaranteed to push at most -* one value to the stack on native, so it may clobber the rdx -* scratch slot, but it won't clobber any of the important -* slots past it. -* -* Xen is a different story, because the Xen frame itself overlaps -* the "NMI executing" variable. -*/ - PARAVIRT_ADJUST_EXCEPTION_FRAME - - /* * We allow breakpoints in NMIs. If a breakpoint occurs, then * the iretq it performs will take us out of NMI context. * This means that we can have nested NMIs where the next diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S index 5314d7b8e5ad..d8468ba24be0 100644 --- a/arch/x86/entry/entry_64_compat.S +++ b/arch/x86/entry/entry_64_compat.S @@ -293,7 +293,6 @@ ENTRY(entry_INT80_compat) /* * Interrupts are off on entry. */ - PARAVIRT_ADJUST_EXCEPTION_FRAME ASM_CLAC/* Do this early to minimize exposure */ SWAPGS diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 9ccac1926587..c25dd22f7c70 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h @@ -960,11 +960,6 @@ extern void default_banner(void); #define GET_CR2_INTO_RAX \ call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr2) -#define PARAVIRT_ADJUST_EXCEPTION_FRAME \ - PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_adjust_exception_frame), \ - CLBR_NONE,\ - call PARA_INDIRECT(pv_irq_ops+PV_IRQ_adjust_exception_frame)) - #define USERGS_SYSRET64 \ PARA_SITE(PARA_PATCH(pv_cpu_ops,
[Xen-devel] [PATCH v5] xen: get rid of paravirt op adjust_exception_frame
From: Juergen GrossWhen running as Xen pv-guest the exception frame on the stack contains %r11 and %rcx additional to the other data pushed by the processor. Instead of having a paravirt op being called for each exception type prepend the Xen specific code to each exception entry. When running as Xen pv-guest just use the exception entry with prepended instructions, otherwise use the entry without the Xen specific code. Signed-off-by: Juergen Gross --- arch/x86/entry/entry_64.S | 23 ++-- arch/x86/entry/entry_64_compat.S | 1 - arch/x86/include/asm/paravirt.h | 5 -- arch/x86/include/asm/paravirt_types.h | 3 -- arch/x86/include/asm/proto.h | 3 ++ arch/x86/include/asm/traps.h | 28 -- arch/x86/kernel/asm-offsets_64.c | 1 - arch/x86/kernel/paravirt.c| 3 -- arch/x86/xen/enlighten_pv.c | 98 +++ arch/x86/xen/irq.c| 3 -- arch/x86/xen/xen-asm_64.S | 41 +-- arch/x86/xen/xen-ops.h| 1 - 12 files changed, 133 insertions(+), 77 deletions(-) diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 7a1d383c2192..bdd024a9afc9 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -821,7 +821,6 @@ ENTRY(\sym) .endif ASM_CLAC - PARAVIRT_ADJUST_EXCEPTION_FRAME .ifeq \has_error_code pushq $-1 /* ORIG_RAX: no syscall to restart */ @@ -967,7 +966,7 @@ ENTRY(do_softirq_own_stack) ENDPROC(do_softirq_own_stack) #ifdef CONFIG_XEN -idtentry xen_hypervisor_callback xen_do_hypervisor_callback has_error_code=0 +idtentry hypervisor_callback xen_do_hypervisor_callback has_error_code=0 /* * A note on the "critical region" in our callback handler. @@ -1034,8 +1033,6 @@ ENTRY(xen_failsafe_callback) movq8(%rsp), %r11 addq$0x30, %rsp pushq $0 /* RIP */ - pushq %r11 - pushq %rcx UNWIND_HINT_IRET_REGS offset=8 jmp general_protection 1: /* Segment mismatch => Category 1 (Bad segment). Retry the IRET. */ @@ -1066,9 +1063,8 @@ idtentry int3 do_int3 has_error_code=0paranoid=1 shift_ist=DEBUG_STACK idtentry stack_segment do_stack_segmenthas_error_code=1 #ifdef CONFIG_XEN -idtentry xen_debug do_debughas_error_code=0 -idtentry xen_int3 do_int3 has_error_code=0 -idtentry xen_stack_segment do_stack_segmenthas_error_code=1 +idtentry xendebug do_debughas_error_code=0 +idtentry xenint3 do_int3 has_error_code=0 #endif idtentry general_protectiondo_general_protection has_error_code=1 @@ -1232,21 +1228,10 @@ ENTRY(error_exit) END(error_exit) /* Runs on exception stack */ +/* XXX: broken on Xen PV */ ENTRY(nmi) UNWIND_HINT_IRET_REGS /* -* Fix up the exception frame if we're on Xen. -* PARAVIRT_ADJUST_EXCEPTION_FRAME is guaranteed to push at most -* one value to the stack on native, so it may clobber the rdx -* scratch slot, but it won't clobber any of the important -* slots past it. -* -* Xen is a different story, because the Xen frame itself overlaps -* the "NMI executing" variable. -*/ - PARAVIRT_ADJUST_EXCEPTION_FRAME - - /* * We allow breakpoints in NMIs. If a breakpoint occurs, then * the iretq it performs will take us out of NMI context. * This means that we can have nested NMIs where the next diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S index 5314d7b8e5ad..d8468ba24be0 100644 --- a/arch/x86/entry/entry_64_compat.S +++ b/arch/x86/entry/entry_64_compat.S @@ -293,7 +293,6 @@ ENTRY(entry_INT80_compat) /* * Interrupts are off on entry. */ - PARAVIRT_ADJUST_EXCEPTION_FRAME ASM_CLAC/* Do this early to minimize exposure */ SWAPGS diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 9ccac1926587..c25dd22f7c70 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h @@ -960,11 +960,6 @@ extern void default_banner(void); #define GET_CR2_INTO_RAX \ call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr2) -#define PARAVIRT_ADJUST_EXCEPTION_FRAME \ - PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_adjust_exception_frame), \ - CLBR_NONE,\ - call PARA_INDIRECT(pv_irq_ops+PV_IRQ_adjust_exception_frame)) - #define USERGS_SYSRET64 \