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

Commit 95648c0e 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 Peter Anvin:
 "A small collection of minor fixes.  The FPU stuff is still pending, I
  fear.  I haven't heard anything from Suresh so I suspect I'm going to
  have to dig into the init specifics myself and fix up the patchset"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86: Ignore NMIs that come in during early boot
  x86, trace: Further robustify CR2 handling vs tracing
  x86, trace: Fix CR2 corruption when tracing page faults
  x86/efi: Quirk out SGI UV
parents 9579f10d 5fa10196
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -134,6 +134,7 @@ extern void efi_setup_page_tables(void);
extern void __init old_map_region(efi_memory_desc_t *md);
extern void __init runtime_code_page_mkexec(void);
extern void __init efi_runtime_mkexec(void);
extern void __init efi_apply_memmap_quirks(void);

struct efi_setup_data {
	u64 fw_vendor;
+6 −1
Original line number Diff line number Diff line
@@ -544,6 +544,10 @@ ENDPROC(early_idt_handlers)
	/* This is global to keep gas from relaxing the jumps */
ENTRY(early_idt_handler)
	cld

	cmpl $X86_TRAP_NMI,(%esp)
	je is_nmi		# Ignore NMI

	cmpl $2,%ss:early_recursion_flag
	je hlt_loop
	incl %ss:early_recursion_flag
@@ -594,8 +598,9 @@ ex_entry:
	pop %edx
	pop %ecx
	pop %eax
	addl $8,%esp		/* drop vector number and error code */
	decl %ss:early_recursion_flag
is_nmi:
	addl $8,%esp		/* drop vector number and error code */
	iret
ENDPROC(early_idt_handler)

+5 −1
Original line number Diff line number Diff line
@@ -343,6 +343,9 @@ early_idt_handlers:
ENTRY(early_idt_handler)
	cld

	cmpl $X86_TRAP_NMI,(%rsp)
	je is_nmi		# Ignore NMI

	cmpl $2,early_recursion_flag(%rip)
	jz  1f
	incl early_recursion_flag(%rip)
@@ -405,8 +408,9 @@ ENTRY(early_idt_handler)
	popq %rdx
	popq %rcx
	popq %rax
	addq $16,%rsp		# drop vector number and error code
	decl early_recursion_flag(%rip)
is_nmi:
	addq $16,%rsp		# drop vector number and error code
	INTERRUPT_RETURN
ENDPROC(early_idt_handler)

+2 −8
Original line number Diff line number Diff line
@@ -1239,14 +1239,8 @@ void __init setup_arch(char **cmdline_p)
	register_refined_jiffies(CLOCK_TICK_RATE);

#ifdef CONFIG_EFI
	/* Once setup is done above, unmap the EFI memory map on
	 * mismatched firmware/kernel archtectures since there is no
	 * support for runtime services.
	 */
	if (efi_enabled(EFI_BOOT) && !efi_is_native()) {
		pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n");
		efi_unmap_memmap();
	}
	if (efi_enabled(EFI_BOOT))
		efi_apply_memmap_quirks();
#endif
}

+33 −14
Original line number Diff line number Diff line
@@ -1020,13 +1020,17 @@ static inline bool smap_violation(int error_code, struct pt_regs *regs)
 * This routine handles page faults.  It determines the address,
 * and the problem, and then passes it off to one of the appropriate
 * routines.
 *
 * This function must have noinline because both callers
 * {,trace_}do_page_fault() have notrace on. Having this an actual function
 * guarantees there's a function trace entry.
 */
static void __kprobes
__do_page_fault(struct pt_regs *regs, unsigned long error_code)
static void __kprobes noinline
__do_page_fault(struct pt_regs *regs, unsigned long error_code,
		unsigned long address)
{
	struct vm_area_struct *vma;
	struct task_struct *tsk;
	unsigned long address;
	struct mm_struct *mm;
	int fault;
	unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
@@ -1034,9 +1038,6 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code)
	tsk = current;
	mm = tsk->mm;

	/* Get the faulting address: */
	address = read_cr2();

	/*
	 * Detect and handle instructions that would cause a page fault for
	 * both a tracked kernel page and a userspace page.
@@ -1248,32 +1249,50 @@ good_area:
	up_read(&mm->mmap_sem);
}

dotraplinkage void __kprobes
dotraplinkage void __kprobes notrace
do_page_fault(struct pt_regs *regs, unsigned long error_code)
{
	unsigned long address = read_cr2(); /* Get the faulting address */
	enum ctx_state prev_state;

	/*
	 * We must have this function tagged with __kprobes, notrace and call
	 * read_cr2() before calling anything else. To avoid calling any kind
	 * of tracing machinery before we've observed the CR2 value.
	 *
	 * exception_{enter,exit}() contain all sorts of tracepoints.
	 */

	prev_state = exception_enter();
	__do_page_fault(regs, error_code);
	__do_page_fault(regs, error_code, address);
	exception_exit(prev_state);
}

static void trace_page_fault_entries(struct pt_regs *regs,
#ifdef CONFIG_TRACING
static void trace_page_fault_entries(unsigned long address, struct pt_regs *regs,
				     unsigned long error_code)
{
	if (user_mode(regs))
		trace_page_fault_user(read_cr2(), regs, error_code);
		trace_page_fault_user(address, regs, error_code);
	else
		trace_page_fault_kernel(read_cr2(), regs, error_code);
		trace_page_fault_kernel(address, regs, error_code);
}

dotraplinkage void __kprobes
dotraplinkage void __kprobes notrace
trace_do_page_fault(struct pt_regs *regs, unsigned long error_code)
{
	/*
	 * The exception_enter and tracepoint processing could
	 * trigger another page faults (user space callchain
	 * reading) and destroy the original cr2 value, so read
	 * the faulting address now.
	 */
	unsigned long address = read_cr2();
	enum ctx_state prev_state;

	prev_state = exception_enter();
	trace_page_fault_entries(regs, error_code);
	__do_page_fault(regs, error_code);
	trace_page_fault_entries(address, regs, error_code);
	__do_page_fault(regs, error_code, address);
	exception_exit(prev_state);
}
#endif /* CONFIG_TRACING */
Loading