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

Commit 650e5455 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Ingo Molnar:
 "A handful of x86 fixes:

   - a syscall ABI fix, fixing an Android breakage
   - a Xen PV guest fix relating to the RTC device, causing a
     non-working console
   - a Xen guest syscall stack frame fix
   - an MCE hotplug CPU crash fix"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/numachip: Fix NumaConnect2 MMCFG PCI access
  x86/entry: Restore traditional SYSENTER calling convention
  x86/entry: Fix some comments
  x86/paravirt: Prevent rtc_cmos platform device init on PV guests
  x86/xen: Avoid fast syscall path for Xen PV guests
  x86/mce: Ensure offline CPUs don't participate in rendezvous process
parents de030179 dd7a5ab4
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -421,7 +421,7 @@ __visible long do_fast_syscall_32(struct pt_regs *regs)
	regs->ip = landing_pad;

	/*
	 * Fetch ECX from where the vDSO stashed it.
	 * Fetch EBP from where the vDSO stashed it.
	 *
	 * WARNING: We are in CONTEXT_USER and RCU isn't paying attention!
	 */
@@ -432,10 +432,10 @@ __visible long do_fast_syscall_32(struct pt_regs *regs)
		 * Micro-optimization: the pointer we're following is explicitly
		 * 32 bits, so it can't be out of range.
		 */
		__get_user(*(u32 *)&regs->cx,
		__get_user(*(u32 *)&regs->bp,
			    (u32 __user __force *)(unsigned long)(u32)regs->sp)
#else
		get_user(*(u32 *)&regs->cx,
		get_user(*(u32 *)&regs->bp,
			 (u32 __user __force *)(unsigned long)(u32)regs->sp)
#endif
		) {
+4 −3
Original line number Diff line number Diff line
@@ -292,7 +292,7 @@ ENTRY(entry_SYSENTER_32)
	movl	TSS_sysenter_sp0(%esp), %esp
sysenter_past_esp:
	pushl	$__USER_DS		/* pt_regs->ss */
	pushl	%ecx			/* pt_regs->cx */
	pushl	%ebp			/* pt_regs->sp (stashed in bp) */
	pushfl				/* pt_regs->flags (except IF = 0) */
	orl	$X86_EFLAGS_IF, (%esp)	/* Fix IF */
	pushl	$__USER_CS		/* pt_regs->cs */
@@ -308,8 +308,9 @@ sysenter_past_esp:

	movl	%esp, %eax
	call	do_fast_syscall_32
	testl	%eax, %eax
	jz	.Lsyscall_32_done
	/* XEN PV guests always use IRET path */
	ALTERNATIVE "testl %eax, %eax; jz .Lsyscall_32_done", \
		    "jmp .Lsyscall_32_done", X86_FEATURE_XENPV

/* Opportunistic SYSEXIT */
	TRACE_IRQS_ON			/* User mode traces as IRQs on. */
+11 −9
Original line number Diff line number Diff line
@@ -63,7 +63,7 @@ ENTRY(entry_SYSENTER_compat)

	/* Construct struct pt_regs on stack */
	pushq	$__USER32_DS		/* pt_regs->ss */
	pushq	%rcx			/* pt_regs->sp */
	pushq	%rbp			/* pt_regs->sp (stashed in bp) */

	/*
	 * Push flags.  This is nasty.  First, interrupts are currently
@@ -82,14 +82,14 @@ ENTRY(entry_SYSENTER_compat)
	pushq	%rdi			/* pt_regs->di */
	pushq	%rsi			/* pt_regs->si */
	pushq	%rdx			/* pt_regs->dx */
	pushq	%rcx			/* pt_regs->cx (will be overwritten) */
	pushq	%rcx			/* pt_regs->cx */
	pushq	$-ENOSYS		/* pt_regs->ax */
	pushq   %r8                     /* pt_regs->r8  = 0 */
	pushq   %r8                     /* pt_regs->r9  = 0 */
	pushq   %r8                     /* pt_regs->r10 = 0 */
	pushq   %r8                     /* pt_regs->r11 = 0 */
	pushq   %rbx                    /* pt_regs->rbx */
	pushq   %rbp                    /* pt_regs->rbp */
	pushq   %rbp                    /* pt_regs->rbp (will be overwritten) */
	pushq   %r8                     /* pt_regs->r12 = 0 */
	pushq   %r8                     /* pt_regs->r13 = 0 */
	pushq   %r8                     /* pt_regs->r14 = 0 */
@@ -121,8 +121,9 @@ sysenter_flags_fixed:

	movq	%rsp, %rdi
	call	do_fast_syscall_32
	testl	%eax, %eax
	jz	.Lsyscall_32_done
	/* XEN PV guests always use IRET path */
	ALTERNATIVE "testl %eax, %eax; jz .Lsyscall_32_done", \
		    "jmp .Lsyscall_32_done", X86_FEATURE_XENPV
	jmp	sysret32_from_system_call

sysenter_fix_flags:
@@ -178,7 +179,7 @@ ENTRY(entry_SYSCALL_compat)
	pushq	%rdi			/* pt_regs->di */
	pushq	%rsi			/* pt_regs->si */
	pushq	%rdx			/* pt_regs->dx */
	pushq	%rcx			/* pt_regs->cx (will be overwritten) */
	pushq	%rbp			/* pt_regs->cx (stashed in bp) */
	pushq	$-ENOSYS		/* pt_regs->ax */
	xorq    %r8,%r8
	pushq   %r8                     /* pt_regs->r8  = 0 */
@@ -186,7 +187,7 @@ ENTRY(entry_SYSCALL_compat)
	pushq   %r8                     /* pt_regs->r10 = 0 */
	pushq   %r8                     /* pt_regs->r11 = 0 */
	pushq   %rbx                    /* pt_regs->rbx */
	pushq   %rbp                    /* pt_regs->rbp */
	pushq   %rbp                    /* pt_regs->rbp (will be overwritten) */
	pushq   %r8                     /* pt_regs->r12 = 0 */
	pushq   %r8                     /* pt_regs->r13 = 0 */
	pushq   %r8                     /* pt_regs->r14 = 0 */
@@ -200,8 +201,9 @@ ENTRY(entry_SYSCALL_compat)

	movq	%rsp, %rdi
	call	do_fast_syscall_32
	testl	%eax, %eax
	jz	.Lsyscall_32_done
	/* XEN PV guests always use IRET path */
	ALTERNATIVE "testl %eax, %eax; jz .Lsyscall_32_done", \
		    "jmp .Lsyscall_32_done", X86_FEATURE_XENPV

	/* Opportunistic SYSRET */
sysret32_from_system_call:
+43 −11
Original line number Diff line number Diff line
/*
 * Code for the vDSO.  This version uses the old int $0x80 method.
 * AT_SYSINFO entry point
*/

#include <asm/dwarf2.h>
@@ -21,35 +21,67 @@ __kernel_vsyscall:
	/*
	 * Reshuffle regs so that all of any of the entry instructions
	 * will preserve enough state.
	 *
	 * A really nice entry sequence would be:
	 *  pushl %edx
	 *  pushl %ecx
	 *  movl  %esp, %ecx
	 *
	 * Unfortunately, naughty Android versions between July and December
	 * 2015 actually hardcode the traditional Linux SYSENTER entry
	 * sequence.  That is severely broken for a number of reasons (ask
	 * anyone with an AMD CPU, for example).  Nonetheless, we try to keep
	 * it working approximately as well as it ever worked.
	 *
	 * This link may eludicate some of the history:
	 *   https://android-review.googlesource.com/#/q/Iac3295376d61ef83e713ac9b528f3b50aa780cd7
	 * personally, I find it hard to understand what's going on there.
	 *
	 * Note to future user developers: DO NOT USE SYSENTER IN YOUR CODE.
	 * Execute an indirect call to the address in the AT_SYSINFO auxv
	 * entry.  That is the ONLY correct way to make a fast 32-bit system
	 * call on Linux.  (Open-coding int $0x80 is also fine, but it's
	 * slow.)
	 */
	pushl	%ecx
	CFI_ADJUST_CFA_OFFSET	4
	CFI_REL_OFFSET		ecx, 0
	pushl	%edx
	CFI_ADJUST_CFA_OFFSET	4
	CFI_REL_OFFSET		edx, 0
	pushl	%ecx
	pushl	%ebp
	CFI_ADJUST_CFA_OFFSET	4
	CFI_REL_OFFSET		ecx, 0
	movl	%esp, %ecx
	CFI_REL_OFFSET		ebp, 0

	#define SYSENTER_SEQUENCE	"movl %esp, %ebp; sysenter"
	#define SYSCALL_SEQUENCE	"movl %ecx, %ebp; syscall"

#ifdef CONFIG_X86_64
	/* If SYSENTER (Intel) or SYSCALL32 (AMD) is available, use it. */
	ALTERNATIVE_2 "", "sysenter", X86_FEATURE_SYSENTER32, \
	                  "syscall",  X86_FEATURE_SYSCALL32
	ALTERNATIVE_2 "", SYSENTER_SEQUENCE, X86_FEATURE_SYSENTER32, \
	                  SYSCALL_SEQUENCE,  X86_FEATURE_SYSCALL32
#else
	ALTERNATIVE "", "sysenter", X86_FEATURE_SEP
	ALTERNATIVE "", SYSENTER_SEQUENCE, X86_FEATURE_SEP
#endif

	/* Enter using int $0x80 */
	movl	(%esp), %ecx
	int	$0x80
GLOBAL(int80_landing_pad)

	/* Restore ECX and EDX in case they were clobbered. */
	popl	%ecx
	CFI_RESTORE		ecx
	/*
	 * Restore EDX and ECX in case they were clobbered.  EBP is not
	 * clobbered (the kernel restores it), but it's cleaner and
	 * probably faster to pop it than to adjust ESP using addl.
	 */
	popl	%ebp
	CFI_RESTORE		ebp
	CFI_ADJUST_CFA_OFFSET	-4
	popl	%edx
	CFI_RESTORE		edx
	CFI_ADJUST_CFA_OFFSET	-4
	popl	%ecx
	CFI_RESTORE		ecx
	CFI_ADJUST_CFA_OFFSET	-4
	ret
	CFI_ENDPROC

+1 −0
Original line number Diff line number Diff line
@@ -216,6 +216,7 @@
#define X86_FEATURE_PAUSEFILTER ( 8*32+13) /* AMD filtered pause intercept */
#define X86_FEATURE_PFTHRESHOLD ( 8*32+14) /* AMD pause filter threshold */
#define X86_FEATURE_VMMCALL     ( 8*32+15) /* Prefer vmmcall to vmcall */
#define X86_FEATURE_XENPV       ( 8*32+16) /* "" Xen paravirtual guest */


/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */
Loading