[Xen-devel] [PATCH v5] xen: get rid of paravirt op adjust_exception_frame

2017-08-31 Thread Juergen Gross
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

2017-08-31 Thread Juergen Gross
From: Juergen Gross 

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
\