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

Commit 51d0f0cb 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:
 "Misc fixes:

   - early_idt_handlers[] fix that fixes the build with bleeding edge
     tooling

   - build warning fix on GCC 5.1

   - vm86 fix plus self-test to make it harder to break it again"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/asm/irq: Stop relying on magic JMP behavior for early_idt_handlers
  x86/asm/entry/32, selftests: Add a selftest for kernel entries from VM86 mode
  x86/boot: Add CONFIG_PARAVIRT_SPINLOCKS quirk to arch/x86/boot/compressed/misc.h
  x86/asm/entry/32: Really make user_mode() work correctly for VM86 mode
parents a0e9c6ef 425be567
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -2,15 +2,14 @@
#define BOOT_COMPRESSED_MISC_H

/*
 * we have to be careful, because no indirections are allowed here, and
 * paravirt_ops is a kind of one. As it will only run in baremetal anyway,
 * we just keep it from happening
 * Special hack: we have to be careful, because no indirections are allowed here,
 * and paravirt_ops is a kind of one. As it will only run in baremetal anyway,
 * we just keep it from happening. (This list needs to be extended when new
 * paravirt and debugging variants are added.)
 */
#undef CONFIG_PARAVIRT
#undef CONFIG_PARAVIRT_SPINLOCKS
#undef CONFIG_KASAN
#ifdef CONFIG_X86_32
#define _ASM_X86_DESC_H 1
#endif

#include <linux/linkage.h>
#include <linux/screen_info.h>
+1 −1
Original line number Diff line number Diff line
@@ -107,7 +107,7 @@ static inline unsigned long regs_return_value(struct pt_regs *regs)
static inline int user_mode(struct pt_regs *regs)
{
#ifdef CONFIG_X86_32
	return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL;
	return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >= USER_RPL;
#else
	return !!(regs->cs & 3);
#endif
+12 −2
Original line number Diff line number Diff line
@@ -231,11 +231,21 @@
#define TLS_SIZE			(GDT_ENTRY_TLS_ENTRIES* 8)

#ifdef __KERNEL__

/*
 * early_idt_handler_array is an array of entry points referenced in the
 * early IDT.  For simplicity, it's a real array with one entry point
 * every nine bytes.  That leaves room for an optional 'push $0' if the
 * vector has no error code (two bytes), a 'push $vector_number' (two
 * bytes), and a jump to the common entry code (up to five bytes).
 */
#define EARLY_IDT_HANDLER_SIZE 9

#ifndef __ASSEMBLY__

extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][2+2+5];
extern const char early_idt_handler_array[NUM_EXCEPTION_VECTORS][EARLY_IDT_HANDLER_SIZE];
#ifdef CONFIG_TRACING
# define trace_early_idt_handlers early_idt_handlers
# define trace_early_idt_handler_array early_idt_handler_array
#endif

/*
+1 −1
Original line number Diff line number Diff line
@@ -167,7 +167,7 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data)
	clear_bss();

	for (i = 0; i < NUM_EXCEPTION_VECTORS; i++)
		set_intr_gate(i, early_idt_handlers[i]);
		set_intr_gate(i, early_idt_handler_array[i]);
	load_idt((const struct desc_ptr *)&idt_descr);

	copy_bootdata(__va(real_mode_data));
+18 −15
Original line number Diff line number Diff line
@@ -478,21 +478,22 @@ is486:
__INIT
setup_once:
	/*
	 * Set up a idt with 256 entries pointing to ignore_int,
	 * interrupt gates. It doesn't actually load idt - that needs
	 * to be done on each CPU. Interrupts are enabled elsewhere,
	 * when we can be relatively sure everything is ok.
	 * Set up a idt with 256 interrupt gates that push zero if there
	 * is no error code and then jump to early_idt_handler_common.
	 * It doesn't actually load the idt - that needs to be done on
	 * each CPU. Interrupts are enabled elsewhere, when we can be
	 * relatively sure everything is ok.
	 */

	movl $idt_table,%edi
	movl $early_idt_handlers,%eax
	movl $early_idt_handler_array,%eax
	movl $NUM_EXCEPTION_VECTORS,%ecx
1:
	movl %eax,(%edi)
	movl %eax,4(%edi)
	/* interrupt gate, dpl=0, present */
	movl $(0x8E000000 + __KERNEL_CS),2(%edi)
	addl $9,%eax
	addl $EARLY_IDT_HANDLER_SIZE,%eax
	addl $8,%edi
	loop 1b

@@ -524,26 +525,28 @@ setup_once:
	andl $0,setup_once_ref	/* Once is enough, thanks */
	ret

ENTRY(early_idt_handlers)
ENTRY(early_idt_handler_array)
	# 36(%esp) %eflags
	# 32(%esp) %cs
	# 28(%esp) %eip
	# 24(%rsp) error code
	i = 0
	.rept NUM_EXCEPTION_VECTORS
	.if (EXCEPTION_ERRCODE_MASK >> i) & 1
	ASM_NOP2
	.else
	.ifeq (EXCEPTION_ERRCODE_MASK >> i) & 1
	pushl $0		# Dummy error code, to make stack frame uniform
	.endif
	pushl $i		# 20(%esp) Vector number
	jmp early_idt_handler
	jmp early_idt_handler_common
	i = i + 1
	.fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc
	.endr
ENDPROC(early_idt_handlers)
ENDPROC(early_idt_handler_array)
	
	/* This is global to keep gas from relaxing the jumps */
ENTRY(early_idt_handler)
early_idt_handler_common:
	/*
	 * The stack is the hardware frame, an error code or zero, and the
	 * vector number.
	 */
	cld

	cmpl $2,(%esp)		# X86_TRAP_NMI
@@ -603,7 +606,7 @@ ex_entry:
is_nmi:
	addl $8,%esp		/* drop vector number and error code */
	iret
ENDPROC(early_idt_handler)
ENDPROC(early_idt_handler_common)

/* This is the default interrupt "handler" :-) */
	ALIGN
Loading