Commit efb9666e authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'x86-urgent-2020-07-19' of...

Merge tag 'x86-urgent-2020-07-19' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip into master

Pull x86 fixes from Thomas Gleixner:
 "A pile of fixes for x86:

   - Fix the I/O bitmap invalidation on XEN PV, which was overlooked in
     the recent ioperm/iopl rework. This caused the TSS and XEN's I/O
     bitmap to get out of sync.

   - Use the proper vectors for HYPERV.

   - Make disabling of stack protector for the entry code work with GCC
     builds which enable stack protector by default. Removing the option
     is not sufficient, it needs an explicit -fno-stack-protector to
     shut it off.

   - Mark check_user_regs() noinstr as it is called from noinstr code.
     The missing annotation causes it to be placed in the text section
     which makes it instrumentable.

   - Add the missing interrupt disable in exc_alignment_check()

   - Fixup a XEN_PV build dependency in the 32bit entry code

   - A few fixes to make the Clang integrated assembler happy

   - Move EFI stub build to the right place for out of tree builds

   - Make prepare_exit_to_usermode() static. It's not longer called from
     ASM code"

* tag 'x86-urgent-2020-07-19' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/boot: Don't add the EFI stub to targets
  x86/entry: Actually disable stack protector
  x86/ioperm: Fix io bitmap invalidation on Xen PV
  x86: math-emu: Fix up 'cmp' insn for clang ias
  x86/entry: Fix vectors to IDTENTRY_SYSVEC for CONFIG_HYPERV
  x86/entry: Add compatibility with IAS
  x86/entry/common: Make prepare_exit_to_usermode() static
  x86/entry: Mark check_user_regs() noinstr
  x86/traps: Disable interrupts in exc_aligment_check()
  x86/entry/32: Fix XEN_PV build dependency
parents 66e4b636 da05b143
...@@ -90,8 +90,8 @@ endif ...@@ -90,8 +90,8 @@ endif
vmlinux-objs-$(CONFIG_ACPI) += $(obj)/acpi.o vmlinux-objs-$(CONFIG_ACPI) += $(obj)/acpi.o
vmlinux-objs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
vmlinux-objs-$(CONFIG_EFI_MIXED) += $(obj)/efi_thunk_$(BITS).o vmlinux-objs-$(CONFIG_EFI_MIXED) += $(obj)/efi_thunk_$(BITS).o
efi-obj-$(CONFIG_EFI_STUB) = $(objtree)/drivers/firmware/efi/libstub/lib.a
# The compressed kernel is built with -fPIC/-fPIE so that a boot loader # The compressed kernel is built with -fPIC/-fPIE so that a boot loader
# can place it anywhere in memory and it will still run. However, since # can place it anywhere in memory and it will still run. However, since
...@@ -115,7 +115,7 @@ endef ...@@ -115,7 +115,7 @@ endef
quiet_cmd_check-and-link-vmlinux = LD $@ quiet_cmd_check-and-link-vmlinux = LD $@
cmd_check-and-link-vmlinux = $(cmd_check_data_rel); $(cmd_ld) cmd_check-and-link-vmlinux = $(cmd_check_data_rel); $(cmd_ld)
$(obj)/vmlinux: $(vmlinux-objs-y) FORCE $(obj)/vmlinux: $(vmlinux-objs-y) $(efi-obj-y) FORCE
$(call if_changed,check-and-link-vmlinux) $(call if_changed,check-and-link-vmlinux)
OBJCOPYFLAGS_vmlinux.bin := -R .comment -S OBJCOPYFLAGS_vmlinux.bin := -R .comment -S
......
...@@ -7,12 +7,20 @@ KASAN_SANITIZE := n ...@@ -7,12 +7,20 @@ KASAN_SANITIZE := n
UBSAN_SANITIZE := n UBSAN_SANITIZE := n
KCOV_INSTRUMENT := n KCOV_INSTRUMENT := n
CFLAGS_REMOVE_common.o = $(CC_FLAGS_FTRACE) -fstack-protector -fstack-protector-strong CFLAGS_REMOVE_common.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_syscall_32.o = $(CC_FLAGS_FTRACE) -fstack-protector -fstack-protector-strong CFLAGS_REMOVE_syscall_64.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_syscall_64.o = $(CC_FLAGS_FTRACE) -fstack-protector -fstack-protector-strong CFLAGS_REMOVE_syscall_32.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_syscall_x32.o = $(CC_FLAGS_FTRACE)
CFLAGS_common.o += -fno-stack-protector
CFLAGS_syscall_64.o += -fno-stack-protector
CFLAGS_syscall_32.o += -fno-stack-protector
CFLAGS_syscall_x32.o += -fno-stack-protector
CFLAGS_syscall_64.o += $(call cc-option,-Wno-override-init,) CFLAGS_syscall_64.o += $(call cc-option,-Wno-override-init,)
CFLAGS_syscall_32.o += $(call cc-option,-Wno-override-init,) CFLAGS_syscall_32.o += $(call cc-option,-Wno-override-init,)
CFLAGS_syscall_x32.o += $(call cc-option,-Wno-override-init,)
obj-y := entry_$(BITS).o thunk_$(BITS).o syscall_$(BITS).o obj-y := entry_$(BITS).o thunk_$(BITS).o syscall_$(BITS).o
obj-y += common.o obj-y += common.o
......
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
#include <trace/events/syscalls.h> #include <trace/events/syscalls.h>
/* Check that the stack and regs on entry from user mode are sane. */ /* Check that the stack and regs on entry from user mode are sane. */
static void check_user_regs(struct pt_regs *regs) static noinstr void check_user_regs(struct pt_regs *regs)
{ {
if (IS_ENABLED(CONFIG_DEBUG_ENTRY)) { if (IS_ENABLED(CONFIG_DEBUG_ENTRY)) {
/* /*
...@@ -294,7 +294,7 @@ static void __prepare_exit_to_usermode(struct pt_regs *regs) ...@@ -294,7 +294,7 @@ static void __prepare_exit_to_usermode(struct pt_regs *regs)
#endif #endif
} }
__visible noinstr void prepare_exit_to_usermode(struct pt_regs *regs) static noinstr void prepare_exit_to_usermode(struct pt_regs *regs)
{ {
instrumentation_begin(); instrumentation_begin();
__prepare_exit_to_usermode(regs); __prepare_exit_to_usermode(regs);
......
...@@ -469,16 +469,15 @@ __visible noinstr void func(struct pt_regs *regs, \ ...@@ -469,16 +469,15 @@ __visible noinstr void func(struct pt_regs *regs, \
.align 8 .align 8
SYM_CODE_START(irq_entries_start) SYM_CODE_START(irq_entries_start)
vector=FIRST_EXTERNAL_VECTOR vector=FIRST_EXTERNAL_VECTOR
pos = .
.rept (FIRST_SYSTEM_VECTOR - FIRST_EXTERNAL_VECTOR) .rept (FIRST_SYSTEM_VECTOR - FIRST_EXTERNAL_VECTOR)
UNWIND_HINT_IRET_REGS UNWIND_HINT_IRET_REGS
0 :
.byte 0x6a, vector .byte 0x6a, vector
jmp asm_common_interrupt jmp asm_common_interrupt
nop nop
/* Ensure that the above is 8 bytes max */ /* Ensure that the above is 8 bytes max */
. = pos + 8 . = 0b + 8
pos=pos+8 vector = vector+1
vector=vector+1
.endr .endr
SYM_CODE_END(irq_entries_start) SYM_CODE_END(irq_entries_start)
...@@ -486,16 +485,15 @@ SYM_CODE_END(irq_entries_start) ...@@ -486,16 +485,15 @@ SYM_CODE_END(irq_entries_start)
.align 8 .align 8
SYM_CODE_START(spurious_entries_start) SYM_CODE_START(spurious_entries_start)
vector=FIRST_SYSTEM_VECTOR vector=FIRST_SYSTEM_VECTOR
pos = .
.rept (NR_VECTORS - FIRST_SYSTEM_VECTOR) .rept (NR_VECTORS - FIRST_SYSTEM_VECTOR)
UNWIND_HINT_IRET_REGS UNWIND_HINT_IRET_REGS
0 :
.byte 0x6a, vector .byte 0x6a, vector
jmp asm_spurious_interrupt jmp asm_spurious_interrupt
nop nop
/* Ensure that the above is 8 bytes max */ /* Ensure that the above is 8 bytes max */
. = pos + 8 . = 0b + 8
pos=pos+8 vector = vector+1
vector=vector+1
.endr .endr
SYM_CODE_END(spurious_entries_start) SYM_CODE_END(spurious_entries_start)
#endif #endif
...@@ -553,7 +551,7 @@ DECLARE_IDTENTRY_RAW(X86_TRAP_MC, exc_machine_check); ...@@ -553,7 +551,7 @@ DECLARE_IDTENTRY_RAW(X86_TRAP_MC, exc_machine_check);
/* NMI */ /* NMI */
DECLARE_IDTENTRY_NMI(X86_TRAP_NMI, exc_nmi); DECLARE_IDTENTRY_NMI(X86_TRAP_NMI, exc_nmi);
#ifdef CONFIG_XEN_PV #if defined(CONFIG_XEN_PV) && defined(CONFIG_X86_64)
DECLARE_IDTENTRY_RAW(X86_TRAP_NMI, xenpv_exc_nmi); DECLARE_IDTENTRY_RAW(X86_TRAP_NMI, xenpv_exc_nmi);
#endif #endif
...@@ -563,7 +561,7 @@ DECLARE_IDTENTRY_DEBUG(X86_TRAP_DB, exc_debug); ...@@ -563,7 +561,7 @@ DECLARE_IDTENTRY_DEBUG(X86_TRAP_DB, exc_debug);
#else #else
DECLARE_IDTENTRY_RAW(X86_TRAP_DB, exc_debug); DECLARE_IDTENTRY_RAW(X86_TRAP_DB, exc_debug);
#endif #endif
#ifdef CONFIG_XEN_PV #if defined(CONFIG_XEN_PV) && defined(CONFIG_X86_64)
DECLARE_IDTENTRY_RAW(X86_TRAP_DB, xenpv_exc_debug); DECLARE_IDTENTRY_RAW(X86_TRAP_DB, xenpv_exc_debug);
#endif #endif
...@@ -626,8 +624,8 @@ DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_NESTED_VECTOR, sysvec_kvm_posted_intr_nested ...@@ -626,8 +624,8 @@ DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_NESTED_VECTOR, sysvec_kvm_posted_intr_nested
#if IS_ENABLED(CONFIG_HYPERV) #if IS_ENABLED(CONFIG_HYPERV)
DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR, sysvec_hyperv_callback); DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR, sysvec_hyperv_callback);
DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_REENLIGHTENMENT_VECTOR, sysvec_hyperv_reenlightenment); DECLARE_IDTENTRY_SYSVEC(HYPERV_REENLIGHTENMENT_VECTOR, sysvec_hyperv_reenlightenment);
DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_STIMER0_VECTOR, sysvec_hyperv_stimer0); DECLARE_IDTENTRY_SYSVEC(HYPERV_STIMER0_VECTOR, sysvec_hyperv_stimer0);
#endif #endif
#if IS_ENABLED(CONFIG_ACRN_GUEST) #if IS_ENABLED(CONFIG_ACRN_GUEST)
......
...@@ -19,12 +19,28 @@ struct task_struct; ...@@ -19,12 +19,28 @@ struct task_struct;
void io_bitmap_share(struct task_struct *tsk); void io_bitmap_share(struct task_struct *tsk);
void io_bitmap_exit(struct task_struct *tsk); void io_bitmap_exit(struct task_struct *tsk);
static inline void native_tss_invalidate_io_bitmap(void)
{
/*
* Invalidate the I/O bitmap by moving io_bitmap_base outside the
* TSS limit so any subsequent I/O access from user space will
* trigger a #GP.
*
* This is correct even when VMEXIT rewrites the TSS limit
* to 0x67 as the only requirement is that the base points
* outside the limit.
*/
this_cpu_write(cpu_tss_rw.x86_tss.io_bitmap_base,
IO_BITMAP_OFFSET_INVALID);
}
void native_tss_update_io_bitmap(void); void native_tss_update_io_bitmap(void);
#ifdef CONFIG_PARAVIRT_XXL #ifdef CONFIG_PARAVIRT_XXL
#include <asm/paravirt.h> #include <asm/paravirt.h>
#else #else
#define tss_update_io_bitmap native_tss_update_io_bitmap #define tss_update_io_bitmap native_tss_update_io_bitmap
#define tss_invalidate_io_bitmap native_tss_invalidate_io_bitmap
#endif #endif
#else #else
......
...@@ -302,6 +302,11 @@ static inline void write_idt_entry(gate_desc *dt, int entry, const gate_desc *g) ...@@ -302,6 +302,11 @@ static inline void write_idt_entry(gate_desc *dt, int entry, const gate_desc *g)
} }
#ifdef CONFIG_X86_IOPL_IOPERM #ifdef CONFIG_X86_IOPL_IOPERM
static inline void tss_invalidate_io_bitmap(void)
{
PVOP_VCALL0(cpu.invalidate_io_bitmap);
}
static inline void tss_update_io_bitmap(void) static inline void tss_update_io_bitmap(void)
{ {
PVOP_VCALL0(cpu.update_io_bitmap); PVOP_VCALL0(cpu.update_io_bitmap);
......
...@@ -141,6 +141,7 @@ struct pv_cpu_ops { ...@@ -141,6 +141,7 @@ struct pv_cpu_ops {
void (*load_sp0)(unsigned long sp0); void (*load_sp0)(unsigned long sp0);
#ifdef CONFIG_X86_IOPL_IOPERM #ifdef CONFIG_X86_IOPL_IOPERM
void (*invalidate_io_bitmap)(void);
void (*update_io_bitmap)(void); void (*update_io_bitmap)(void);
#endif #endif
......
...@@ -324,6 +324,7 @@ struct paravirt_patch_template pv_ops = { ...@@ -324,6 +324,7 @@ struct paravirt_patch_template pv_ops = {
.cpu.swapgs = native_swapgs, .cpu.swapgs = native_swapgs,
#ifdef CONFIG_X86_IOPL_IOPERM #ifdef CONFIG_X86_IOPL_IOPERM
.cpu.invalidate_io_bitmap = native_tss_invalidate_io_bitmap,
.cpu.update_io_bitmap = native_tss_update_io_bitmap, .cpu.update_io_bitmap = native_tss_update_io_bitmap,
#endif #endif
......
...@@ -322,20 +322,6 @@ void arch_setup_new_exec(void) ...@@ -322,20 +322,6 @@ void arch_setup_new_exec(void)
} }
#ifdef CONFIG_X86_IOPL_IOPERM #ifdef CONFIG_X86_IOPL_IOPERM
static inline void tss_invalidate_io_bitmap(struct tss_struct *tss)
{
/*
* Invalidate the I/O bitmap by moving io_bitmap_base outside the
* TSS limit so any subsequent I/O access from user space will
* trigger a #GP.
*
* This is correct even when VMEXIT rewrites the TSS limit
* to 0x67 as the only requirement is that the base points
* outside the limit.
*/
tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET_INVALID;
}
static inline void switch_to_bitmap(unsigned long tifp) static inline void switch_to_bitmap(unsigned long tifp)
{ {
/* /*
...@@ -346,7 +332,7 @@ static inline void switch_to_bitmap(unsigned long tifp) ...@@ -346,7 +332,7 @@ static inline void switch_to_bitmap(unsigned long tifp)
* user mode. * user mode.
*/ */
if (tifp & _TIF_IO_BITMAP) if (tifp & _TIF_IO_BITMAP)
tss_invalidate_io_bitmap(this_cpu_ptr(&cpu_tss_rw)); tss_invalidate_io_bitmap();
} }
static void tss_copy_io_bitmap(struct tss_struct *tss, struct io_bitmap *iobm) static void tss_copy_io_bitmap(struct tss_struct *tss, struct io_bitmap *iobm)
...@@ -380,7 +366,7 @@ void native_tss_update_io_bitmap(void) ...@@ -380,7 +366,7 @@ void native_tss_update_io_bitmap(void)
u16 *base = &tss->x86_tss.io_bitmap_base; u16 *base = &tss->x86_tss.io_bitmap_base;
if (!test_thread_flag(TIF_IO_BITMAP)) { if (!test_thread_flag(TIF_IO_BITMAP)) {
tss_invalidate_io_bitmap(tss); native_tss_invalidate_io_bitmap();
return; return;
} }
......
...@@ -303,6 +303,8 @@ DEFINE_IDTENTRY_ERRORCODE(exc_alignment_check) ...@@ -303,6 +303,8 @@ DEFINE_IDTENTRY_ERRORCODE(exc_alignment_check)
do_trap(X86_TRAP_AC, SIGBUS, "alignment check", regs, do_trap(X86_TRAP_AC, SIGBUS, "alignment check", regs,
error_code, BUS_ADRALN, NULL); error_code, BUS_ADRALN, NULL);
local_irq_disable();
} }
#ifdef CONFIG_VMAP_STACK #ifdef CONFIG_VMAP_STACK
......
...@@ -209,7 +209,7 @@ sqrt_stage_2_finish: ...@@ -209,7 +209,7 @@ sqrt_stage_2_finish:
#ifdef PARANOID #ifdef PARANOID
/* It should be possible to get here only if the arg is ffff....ffff */ /* It should be possible to get here only if the arg is ffff....ffff */
cmp $0xffffffff,FPU_fsqrt_arg_1 cmpl $0xffffffff,FPU_fsqrt_arg_1
jnz sqrt_stage_2_error jnz sqrt_stage_2_error
#endif /* PARANOID */ #endif /* PARANOID */
......
...@@ -870,6 +870,17 @@ static void xen_load_sp0(unsigned long sp0) ...@@ -870,6 +870,17 @@ static void xen_load_sp0(unsigned long sp0)
} }
#ifdef CONFIG_X86_IOPL_IOPERM #ifdef CONFIG_X86_IOPL_IOPERM
static void xen_invalidate_io_bitmap(void)
{
struct physdev_set_iobitmap iobitmap = {
.bitmap = 0,
.nr_ports = 0,
};
native_tss_invalidate_io_bitmap();
HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &iobitmap);
}
static void xen_update_io_bitmap(void) static void xen_update_io_bitmap(void)
{ {
struct physdev_set_iobitmap iobitmap; struct physdev_set_iobitmap iobitmap;
...@@ -1099,6 +1110,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = { ...@@ -1099,6 +1110,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = {
.load_sp0 = xen_load_sp0, .load_sp0 = xen_load_sp0,
#ifdef CONFIG_X86_IOPL_IOPERM #ifdef CONFIG_X86_IOPL_IOPERM
.invalidate_io_bitmap = xen_invalidate_io_bitmap,
.update_io_bitmap = xen_update_io_bitmap, .update_io_bitmap = xen_update_io_bitmap,
#endif #endif
.io_delay = xen_io_delay, .io_delay = xen_io_delay,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment