Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5878d5d6 authored by Juergen Gross's avatar Juergen Gross Committed by Thomas Gleixner
Browse files

x86/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.

[ tglx: Merged through tip to avoid ugly merge conflict ]

Signed-off-by: default avatarJuergen Gross <jgross@suse.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Cc: xen-devel@lists.xenproject.org
Cc: boris.ostrovsky@oracle.com
Cc: luto@amacapital.net
Link: http://lkml.kernel.org/r/20170831174249.26853-1-jg@pfupf.net
parent ef1d4dea
Loading
Loading
Loading
Loading
+4 −19
Original line number Diff line number Diff line
@@ -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)
	movq	8(%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=0 paranoid=1 shift_ist=DEBUG_STACK
idtentry stack_segment		do_stack_segment	has_error_code=1

#ifdef CONFIG_XEN
idtentry xen_debug		do_debug		has_error_code=0
idtentry xen_int3		do_int3			has_error_code=0
idtentry xen_stack_segment	do_stack_segment	has_error_code=1
idtentry xendebug		do_debug		has_error_code=0
idtentry xenint3		do_int3			has_error_code=0
#endif

idtentry general_protection	do_general_protection	has_error_code=1
@@ -1232,20 +1228,9 @@ 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.
+0 −1
Original line number Diff line number Diff line
@@ -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

+0 −5
Original line number Diff line number Diff line
@@ -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, PV_CPU_usergs_sysret64),	\
		  CLBR_NONE,						\
+0 −3
Original line number Diff line number Diff line
@@ -196,9 +196,6 @@ struct pv_irq_ops {
	void (*safe_halt)(void);
	void (*halt)(void);

#ifdef CONFIG_X86_64
	void (*adjust_exception_frame)(void);
#endif
} __no_randomize_layout;

struct pv_mmu_ops {
+3 −0
Original line number Diff line number Diff line
@@ -24,6 +24,9 @@ void entry_SYSENTER_compat(void);
void __end_entry_SYSENTER_compat(void);
void entry_SYSCALL_compat(void);
void entry_INT80_compat(void);
#if defined(CONFIG_X86_64) && defined(CONFIG_XEN_PV)
void xen_entry_INT80_compat(void);
#endif
#endif

void x86_configure_nx(void);
Loading