diff options
Diffstat (limited to 'arch/x86/include/asm')
31 files changed, 370 insertions, 195 deletions
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 44f5d79d5105..11881726ed37 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -94,7 +94,7 @@ static inline unsigned int acpi_processor_cstate_check(unsigned int max_cstate)  	if (boot_cpu_data.x86 == 0x0F &&  	    boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&  	    boot_cpu_data.x86_model <= 0x05 && -	    boot_cpu_data.x86_mask < 0x0A) +	    boot_cpu_data.x86_stepping < 0x0A)  		return 1;  	else if (boot_cpu_has(X86_BUG_AMD_APIC_C1E))  		return 1; diff --git a/arch/x86/include/asm/apm.h b/arch/x86/include/asm/apm.h index 4d4015ddcf26..c356098b6fb9 100644 --- a/arch/x86/include/asm/apm.h +++ b/arch/x86/include/asm/apm.h @@ -7,6 +7,8 @@  #ifndef _ASM_X86_MACH_DEFAULT_APM_H  #define _ASM_X86_MACH_DEFAULT_APM_H +#include <asm/nospec-branch.h> +  #ifdef APM_ZERO_SEGS  #	define APM_DO_ZERO_SEGS \  		"pushl %%ds\n\t" \ @@ -32,6 +34,7 @@ static inline void apm_bios_call_asm(u32 func, u32 ebx_in, u32 ecx_in,  	 * N.B. We do NOT need a cld after the BIOS call  	 * because we always save and restore the flags.  	 */ +	firmware_restrict_branch_speculation_start();  	__asm__ __volatile__(APM_DO_ZERO_SEGS  		"pushl %%edi\n\t"  		"pushl %%ebp\n\t" @@ -44,6 +47,7 @@ static inline void apm_bios_call_asm(u32 func, u32 ebx_in, u32 ecx_in,  		  "=S" (*esi)  		: "a" (func), "b" (ebx_in), "c" (ecx_in)  		: "memory", "cc"); +	firmware_restrict_branch_speculation_end();  }  static inline bool apm_bios_call_simple_asm(u32 func, u32 ebx_in, @@ -56,6 +60,7 @@ static inline bool apm_bios_call_simple_asm(u32 func, u32 ebx_in,  	 * N.B. We do NOT need a cld after the BIOS call  	 * because we always save and restore the flags.  	 */ +	firmware_restrict_branch_speculation_start();  	__asm__ __volatile__(APM_DO_ZERO_SEGS  		"pushl %%edi\n\t"  		"pushl %%ebp\n\t" @@ -68,6 +73,7 @@ static inline bool apm_bios_call_simple_asm(u32 func, u32 ebx_in,  		  "=S" (si)  		: "a" (func), "b" (ebx_in), "c" (ecx_in)  		: "memory", "cc"); +	firmware_restrict_branch_speculation_end();  	return error;  } diff --git a/arch/x86/include/asm/asm-prototypes.h b/arch/x86/include/asm/asm-prototypes.h index 4d111616524b..1908214b9125 100644 --- a/arch/x86/include/asm/asm-prototypes.h +++ b/arch/x86/include/asm/asm-prototypes.h @@ -38,7 +38,4 @@ INDIRECT_THUNK(dx)  INDIRECT_THUNK(si)  INDIRECT_THUNK(di)  INDIRECT_THUNK(bp) -asmlinkage void __fill_rsb(void); -asmlinkage void __clear_rsb(void); -  #endif /* CONFIG_RETPOLINE */ diff --git a/arch/x86/include/asm/barrier.h b/arch/x86/include/asm/barrier.h index 30d406146016..042b5e892ed1 100644 --- a/arch/x86/include/asm/barrier.h +++ b/arch/x86/include/asm/barrier.h @@ -40,7 +40,7 @@ static inline unsigned long array_index_mask_nospec(unsigned long index,  	asm ("cmp %1,%2; sbb %0,%0;"  			:"=r" (mask) -			:"r"(size),"r" (index) +			:"g"(size),"r" (index)  			:"cc");  	return mask;  } @@ -52,11 +52,7 @@ static inline unsigned long array_index_mask_nospec(unsigned long index,  #define barrier_nospec() alternative_2("", "mfence", X86_FEATURE_MFENCE_RDTSC, \  					   "lfence", X86_FEATURE_LFENCE_RDTSC) -#ifdef CONFIG_X86_PPRO_FENCE -#define dma_rmb()	rmb() -#else  #define dma_rmb()	barrier() -#endif  #define dma_wmb()	barrier()  #ifdef CONFIG_X86_32 @@ -68,30 +64,6 @@ static inline unsigned long array_index_mask_nospec(unsigned long index,  #define __smp_wmb()	barrier()  #define __smp_store_mb(var, value) do { (void)xchg(&var, value); } while (0) -#if defined(CONFIG_X86_PPRO_FENCE) - -/* - * For this option x86 doesn't have a strong TSO memory - * model and we should fall back to full barriers. - */ - -#define __smp_store_release(p, v)					\ -do {									\ -	compiletime_assert_atomic_type(*p);				\ -	__smp_mb();							\ -	WRITE_ONCE(*p, v);						\ -} while (0) - -#define __smp_load_acquire(p)						\ -({									\ -	typeof(*p) ___p1 = READ_ONCE(*p);				\ -	compiletime_assert_atomic_type(*p);				\ -	__smp_mb();							\ -	___p1;								\ -}) - -#else /* regular x86 TSO memory ordering */ -  #define __smp_store_release(p, v)					\  do {									\  	compiletime_assert_atomic_type(*p);				\ @@ -107,8 +79,6 @@ do {									\  	___p1;								\  }) -#endif -  /* Atomic operations are already serializing on x86 */  #define __smp_mb__before_atomic()	barrier()  #define __smp_mb__after_atomic()	barrier() diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h index 3fa039855b8f..9f645ba57dbb 100644 --- a/arch/x86/include/asm/bitops.h +++ b/arch/x86/include/asm/bitops.h @@ -78,7 +78,7 @@ set_bit(long nr, volatile unsigned long *addr)  			: "iq" ((u8)CONST_MASK(nr))  			: "memory");  	} else { -		asm volatile(LOCK_PREFIX "bts %1,%0" +		asm volatile(LOCK_PREFIX __ASM_SIZE(bts) " %1,%0"  			: BITOP_ADDR(addr) : "Ir" (nr) : "memory");  	}  } @@ -94,7 +94,7 @@ set_bit(long nr, volatile unsigned long *addr)   */  static __always_inline void __set_bit(long nr, volatile unsigned long *addr)  { -	asm volatile("bts %1,%0" : ADDR : "Ir" (nr) : "memory"); +	asm volatile(__ASM_SIZE(bts) " %1,%0" : ADDR : "Ir" (nr) : "memory");  }  /** @@ -115,7 +115,7 @@ clear_bit(long nr, volatile unsigned long *addr)  			: CONST_MASK_ADDR(nr, addr)  			: "iq" ((u8)~CONST_MASK(nr)));  	} else { -		asm volatile(LOCK_PREFIX "btr %1,%0" +		asm volatile(LOCK_PREFIX __ASM_SIZE(btr) " %1,%0"  			: BITOP_ADDR(addr)  			: "Ir" (nr));  	} @@ -137,7 +137,7 @@ static __always_inline void clear_bit_unlock(long nr, volatile unsigned long *ad  static __always_inline void __clear_bit(long nr, volatile unsigned long *addr)  { -	asm volatile("btr %1,%0" : ADDR : "Ir" (nr)); +	asm volatile(__ASM_SIZE(btr) " %1,%0" : ADDR : "Ir" (nr));  }  static __always_inline bool clear_bit_unlock_is_negative_byte(long nr, volatile unsigned long *addr) @@ -182,7 +182,7 @@ static __always_inline void __clear_bit_unlock(long nr, volatile unsigned long *   */  static __always_inline void __change_bit(long nr, volatile unsigned long *addr)  { -	asm volatile("btc %1,%0" : ADDR : "Ir" (nr)); +	asm volatile(__ASM_SIZE(btc) " %1,%0" : ADDR : "Ir" (nr));  }  /** @@ -201,7 +201,7 @@ static __always_inline void change_bit(long nr, volatile unsigned long *addr)  			: CONST_MASK_ADDR(nr, addr)  			: "iq" ((u8)CONST_MASK(nr)));  	} else { -		asm volatile(LOCK_PREFIX "btc %1,%0" +		asm volatile(LOCK_PREFIX __ASM_SIZE(btc) " %1,%0"  			: BITOP_ADDR(addr)  			: "Ir" (nr));  	} @@ -217,7 +217,8 @@ static __always_inline void change_bit(long nr, volatile unsigned long *addr)   */  static __always_inline bool test_and_set_bit(long nr, volatile unsigned long *addr)  { -	GEN_BINARY_RMWcc(LOCK_PREFIX "bts", *addr, "Ir", nr, "%0", c); +	GEN_BINARY_RMWcc(LOCK_PREFIX __ASM_SIZE(bts), +	                 *addr, "Ir", nr, "%0", c);  }  /** @@ -246,7 +247,7 @@ static __always_inline bool __test_and_set_bit(long nr, volatile unsigned long *  {  	bool oldbit; -	asm("bts %2,%1" +	asm(__ASM_SIZE(bts) " %2,%1"  	    CC_SET(c)  	    : CC_OUT(c) (oldbit), ADDR  	    : "Ir" (nr)); @@ -263,7 +264,8 @@ static __always_inline bool __test_and_set_bit(long nr, volatile unsigned long *   */  static __always_inline bool test_and_clear_bit(long nr, volatile unsigned long *addr)  { -	GEN_BINARY_RMWcc(LOCK_PREFIX "btr", *addr, "Ir", nr, "%0", c); +	GEN_BINARY_RMWcc(LOCK_PREFIX __ASM_SIZE(btr), +	                 *addr, "Ir", nr, "%0", c);  }  /** @@ -286,7 +288,7 @@ static __always_inline bool __test_and_clear_bit(long nr, volatile unsigned long  {  	bool oldbit; -	asm volatile("btr %2,%1" +	asm volatile(__ASM_SIZE(btr) " %2,%1"  		     CC_SET(c)  		     : CC_OUT(c) (oldbit), ADDR  		     : "Ir" (nr)); @@ -298,7 +300,7 @@ static __always_inline bool __test_and_change_bit(long nr, volatile unsigned lon  {  	bool oldbit; -	asm volatile("btc %2,%1" +	asm volatile(__ASM_SIZE(btc) " %2,%1"  		     CC_SET(c)  		     : CC_OUT(c) (oldbit), ADDR  		     : "Ir" (nr) : "memory"); @@ -316,7 +318,8 @@ static __always_inline bool __test_and_change_bit(long nr, volatile unsigned lon   */  static __always_inline bool test_and_change_bit(long nr, volatile unsigned long *addr)  { -	GEN_BINARY_RMWcc(LOCK_PREFIX "btc", *addr, "Ir", nr, "%0", c); +	GEN_BINARY_RMWcc(LOCK_PREFIX __ASM_SIZE(btc), +	                 *addr, "Ir", nr, "%0", c);  }  static __always_inline bool constant_test_bit(long nr, const volatile unsigned long *addr) @@ -329,7 +332,7 @@ static __always_inline bool variable_test_bit(long nr, volatile const unsigned l  {  	bool oldbit; -	asm volatile("bt %2,%1" +	asm volatile(__ASM_SIZE(bt) " %2,%1"  		     CC_SET(c)  		     : CC_OUT(c) (oldbit)  		     : "m" (*(unsigned long *)addr), "Ir" (nr)); diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h index 34d99af43994..6804d6642767 100644 --- a/arch/x86/include/asm/bug.h +++ b/arch/x86/include/asm/bug.h @@ -5,23 +5,20 @@  #include <linux/stringify.h>  /* - * Since some emulators terminate on UD2, we cannot use it for WARN. - * Since various instruction decoders disagree on the length of UD1, - * we cannot use it either. So use UD0 for WARN. + * Despite that some emulators terminate on UD2, we use it for WARN().   * - * (binutils knows about "ud1" but {en,de}codes it as 2 bytes, whereas - *  our kernel decoder thinks it takes a ModRM byte, which seems consistent - *  with various things like the Intel SDM instruction encoding rules) + * Since various instruction decoders/specs disagree on the encoding of + * UD0/UD1.   */ -#define ASM_UD0		".byte 0x0f, 0xff" +#define ASM_UD0		".byte 0x0f, 0xff" /* + ModRM (for Intel) */  #define ASM_UD1		".byte 0x0f, 0xb9" /* + ModRM */  #define ASM_UD2		".byte 0x0f, 0x0b"  #define INSN_UD0	0xff0f  #define INSN_UD2	0x0b0f -#define LEN_UD0		2 +#define LEN_UD2		2  #ifdef CONFIG_GENERIC_BUG @@ -77,7 +74,11 @@ do {								\  	unreachable();						\  } while (0) -#define __WARN_FLAGS(flags)	_BUG_FLAGS(ASM_UD0, BUGFLAG_WARNING|(flags)) +#define __WARN_FLAGS(flags)					\ +do {								\ +	_BUG_FLAGS(ASM_UD2, BUGFLAG_WARNING|(flags));		\ +	annotate_reachable();					\ +} while (0)  #include <asm-generic/bug.h> diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 70eddb3922ff..736771c9822e 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -148,45 +148,46 @@ extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit);   */  static __always_inline __pure bool _static_cpu_has(u16 bit)  { -		asm_volatile_goto("1: jmp 6f\n" -			 "2:\n" -			 ".skip -(((5f-4f) - (2b-1b)) > 0) * " -			         "((5f-4f) - (2b-1b)),0x90\n" -			 "3:\n" -			 ".section .altinstructions,\"a\"\n" -			 " .long 1b - .\n"		/* src offset */ -			 " .long 4f - .\n"		/* repl offset */ -			 " .word %P1\n"			/* always replace */ -			 " .byte 3b - 1b\n"		/* src len */ -			 " .byte 5f - 4f\n"		/* repl len */ -			 " .byte 3b - 2b\n"		/* pad len */ -			 ".previous\n" -			 ".section .altinstr_replacement,\"ax\"\n" -			 "4: jmp %l[t_no]\n" -			 "5:\n" -			 ".previous\n" -			 ".section .altinstructions,\"a\"\n" -			 " .long 1b - .\n"		/* src offset */ -			 " .long 0\n"			/* no replacement */ -			 " .word %P0\n"			/* feature bit */ -			 " .byte 3b - 1b\n"		/* src len */ -			 " .byte 0\n"			/* repl len */ -			 " .byte 0\n"			/* pad len */ -			 ".previous\n" -			 ".section .altinstr_aux,\"ax\"\n" -			 "6:\n" -			 " testb %[bitnum],%[cap_byte]\n" -			 " jnz %l[t_yes]\n" -			 " jmp %l[t_no]\n" -			 ".previous\n" -			 : : "i" (bit), "i" (X86_FEATURE_ALWAYS), -			     [bitnum] "i" (1 << (bit & 7)), -			     [cap_byte] "m" (((const char *)boot_cpu_data.x86_capability)[bit >> 3]) -			 : : t_yes, t_no); -	t_yes: -		return true; -	t_no: -		return false; +	asm_volatile_goto("1: jmp 6f\n" +		 "2:\n" +		 ".skip -(((5f-4f) - (2b-1b)) > 0) * " +			 "((5f-4f) - (2b-1b)),0x90\n" +		 "3:\n" +		 ".section .altinstructions,\"a\"\n" +		 " .long 1b - .\n"		/* src offset */ +		 " .long 4f - .\n"		/* repl offset */ +		 " .word %P[always]\n"		/* always replace */ +		 " .byte 3b - 1b\n"		/* src len */ +		 " .byte 5f - 4f\n"		/* repl len */ +		 " .byte 3b - 2b\n"		/* pad len */ +		 ".previous\n" +		 ".section .altinstr_replacement,\"ax\"\n" +		 "4: jmp %l[t_no]\n" +		 "5:\n" +		 ".previous\n" +		 ".section .altinstructions,\"a\"\n" +		 " .long 1b - .\n"		/* src offset */ +		 " .long 0\n"			/* no replacement */ +		 " .word %P[feature]\n"		/* feature bit */ +		 " .byte 3b - 1b\n"		/* src len */ +		 " .byte 0\n"			/* repl len */ +		 " .byte 0\n"			/* pad len */ +		 ".previous\n" +		 ".section .altinstr_aux,\"ax\"\n" +		 "6:\n" +		 " testb %[bitnum],%[cap_byte]\n" +		 " jnz %l[t_yes]\n" +		 " jmp %l[t_no]\n" +		 ".previous\n" +		 : : [feature]  "i" (bit), +		     [always]   "i" (X86_FEATURE_ALWAYS), +		     [bitnum]   "i" (1 << (bit & 7)), +		     [cap_byte] "m" (((const char *)boot_cpu_data.x86_capability)[bit >> 3]) +		 : : t_yes, t_no); +t_yes: +	return true; +t_no: +	return false;  }  #define static_cpu_has(bit)					\ diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h index 0dfe4d3f74e2..d554c11e01ff 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h @@ -213,6 +213,7 @@  #define X86_FEATURE_SEV			( 7*32+20) /* AMD Secure Encrypted Virtualization */  #define X86_FEATURE_USE_IBPB		( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled */ +#define X86_FEATURE_USE_IBRS_FW		( 7*32+22) /* "" Use IBRS during runtime firmware calls */  /* Virtualization flags: Linux defined, word 8 */  #define X86_FEATURE_TPR_SHADOW		( 8*32+ 0) /* Intel TPR Shadow */ @@ -315,6 +316,7 @@  #define X86_FEATURE_VPCLMULQDQ		(16*32+10) /* Carry-Less Multiplication Double Quadword */  #define X86_FEATURE_AVX512_VNNI		(16*32+11) /* Vector Neural Network Instructions */  #define X86_FEATURE_AVX512_BITALG	(16*32+12) /* Support for VPOPCNT[B,W] and VPSHUF-BITQMB instructions */ +#define X86_FEATURE_TME			(16*32+13) /* Intel Total Memory Encryption */  #define X86_FEATURE_AVX512_VPOPCNTDQ	(16*32+14) /* POPCNT for vectors of DW/QW */  #define X86_FEATURE_LA57		(16*32+16) /* 5-level page tables */  #define X86_FEATURE_RDPID		(16*32+22) /* RDPID instruction */ @@ -327,6 +329,7 @@  /* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */  #define X86_FEATURE_AVX512_4VNNIW	(18*32+ 2) /* AVX-512 Neural Network Instructions */  #define X86_FEATURE_AVX512_4FMAPS	(18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */ +#define X86_FEATURE_PCONFIG		(18*32+18) /* Intel PCONFIG */  #define X86_FEATURE_SPEC_CTRL		(18*32+26) /* "" Speculation Control (IBRS + IBPB) */  #define X86_FEATURE_INTEL_STIBP		(18*32+27) /* "" Single Thread Indirect Branch Predictors */  #define X86_FEATURE_ARCH_CAPABILITIES	(18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */ diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 85f6ccb80b91..a399c1ebf6f0 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -6,6 +6,7 @@  #include <asm/pgtable.h>  #include <asm/processor-flags.h>  #include <asm/tlb.h> +#include <asm/nospec-branch.h>  /*   * We map the EFI regions needed for runtime services non-contiguously, @@ -36,8 +37,18 @@  extern asmlinkage unsigned long efi_call_phys(void *, ...); -#define arch_efi_call_virt_setup()	kernel_fpu_begin() -#define arch_efi_call_virt_teardown()	kernel_fpu_end() +#define arch_efi_call_virt_setup()					\ +({									\ +	kernel_fpu_begin();						\ +	firmware_restrict_branch_speculation_start();			\ +}) + +#define arch_efi_call_virt_teardown()					\ +({									\ +	firmware_restrict_branch_speculation_end();			\ +	kernel_fpu_end();						\ +}) +  /*   * Wrap all the virtual calls in a way that forces the parameters on the stack. @@ -73,6 +84,7 @@ struct efi_scratch {  	efi_sync_low_kernel_mappings();					\  	preempt_disable();						\  	__kernel_fpu_begin();						\ +	firmware_restrict_branch_speculation_start();			\  									\  	if (efi_scratch.use_pgd) {					\  		efi_scratch.prev_cr3 = __read_cr3();			\ @@ -91,6 +103,7 @@ struct efi_scratch {  		__flush_tlb_all();					\  	}								\  									\ +	firmware_restrict_branch_speculation_end();			\  	__kernel_fpu_end();						\  	preempt_enable();						\  }) diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index 95e948627fd0..f6e5b9375d8c 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -232,21 +232,6 @@ extern void set_iounmap_nonlazy(void);   */  #define __ISA_IO_base ((char __iomem *)(PAGE_OFFSET)) -/* - *	Cache management - * - *	This needed for two cases - *	1. Out of order aware processors - *	2. Accidentally out of order processors (PPro errata #51) - */ - -static inline void flush_write_buffers(void) -{ -#if defined(CONFIG_X86_PPRO_FENCE) -	asm volatile("lock; addl $0,0(%%esp)": : :"memory"); -#endif -} -  #endif /* __KERNEL__ */  extern void native_io_delay(void); diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index dd6f57a54a26..b605a5b6a30c 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -507,6 +507,7 @@ struct kvm_vcpu_arch {  	u64 smi_count;  	bool tpr_access_reporting;  	u64 ia32_xss; +	u64 microcode_version;  	/*  	 * Paging state of the vcpu @@ -1095,6 +1096,8 @@ struct kvm_x86_ops {  	int (*mem_enc_op)(struct kvm *kvm, void __user *argp);  	int (*mem_enc_reg_region)(struct kvm *kvm, struct kvm_enc_region *argp);  	int (*mem_enc_unreg_region)(struct kvm *kvm, struct kvm_enc_region *argp); + +	int (*get_msr_feature)(struct kvm_msr_entry *entry);  };  struct kvm_arch_async_pf { @@ -1464,7 +1467,4 @@ static inline int kvm_cpu_get_apicid(int mps_cpu)  #define put_smstate(type, buf, offset, val)                      \  	*(type *)((buf) + (offset) - 0x7e00) = val -void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm, -		unsigned long start, unsigned long end); -  #endif /* _ASM_X86_KVM_HOST_H */ diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h index 55520cec8b27..6cf0e4cb7b97 100644 --- a/arch/x86/include/asm/microcode.h +++ b/arch/x86/include/asm/microcode.h @@ -37,7 +37,13 @@ struct cpu_signature {  struct device; -enum ucode_state { UCODE_ERROR, UCODE_OK, UCODE_NFOUND }; +enum ucode_state { +	UCODE_OK	= 0, +	UCODE_NEW, +	UCODE_UPDATED, +	UCODE_NFOUND, +	UCODE_ERROR, +};  struct microcode_ops {  	enum ucode_state (*request_microcode_user) (int cpu, @@ -54,7 +60,7 @@ struct microcode_ops {  	 * are being called.  	 * See also the "Synchronization" section in microcode_core.c.  	 */ -	int (*apply_microcode) (int cpu); +	enum ucode_state (*apply_microcode) (int cpu);  	int (*collect_cpu_info) (int cpu, struct cpu_signature *csig);  }; diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index c931b88982a0..1de72ce514cd 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h @@ -74,6 +74,7 @@ static inline void *ldt_slot_va(int slot)  	return (void *)(LDT_BASE_ADDR + LDT_SLOT_STRIDE * slot);  #else  	BUG(); +	return (void *)fix_to_virt(FIX_HOLE);  #endif  } diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h index 4d57894635f2..f928ad9b143f 100644 --- a/arch/x86/include/asm/nospec-branch.h +++ b/arch/x86/include/asm/nospec-branch.h @@ -6,6 +6,51 @@  #include <asm/alternative.h>  #include <asm/alternative-asm.h>  #include <asm/cpufeatures.h> +#include <asm/msr-index.h> + +/* + * Fill the CPU return stack buffer. + * + * Each entry in the RSB, if used for a speculative 'ret', contains an + * infinite 'pause; lfence; jmp' loop to capture speculative execution. + * + * This is required in various cases for retpoline and IBRS-based + * mitigations for the Spectre variant 2 vulnerability. Sometimes to + * eliminate potentially bogus entries from the RSB, and sometimes + * purely to ensure that it doesn't get empty, which on some CPUs would + * allow predictions from other (unwanted!) sources to be used. + * + * We define a CPP macro such that it can be used from both .S files and + * inline assembly. It's possible to do a .macro and then include that + * from C via asm(".include <asm/nospec-branch.h>") but let's not go there. + */ + +#define RSB_CLEAR_LOOPS		32	/* To forcibly overwrite all entries */ +#define RSB_FILL_LOOPS		16	/* To avoid underflow */ + +/* + * Google experimented with loop-unrolling and this turned out to be + * the optimal version — two calls, each with their own speculation + * trap should their return address end up getting used, in a loop. + */ +#define __FILL_RETURN_BUFFER(reg, nr, sp)	\ +	mov	$(nr/2), reg;			\ +771:						\ +	call	772f;				\ +773:	/* speculation trap */			\ +	pause;					\ +	lfence;					\ +	jmp	773b;				\ +772:						\ +	call	774f;				\ +775:	/* speculation trap */			\ +	pause;					\ +	lfence;					\ +	jmp	775b;				\ +774:						\ +	dec	reg;				\ +	jnz	771b;				\ +	add	$(BITS_PER_LONG/8) * nr, sp;  #ifdef __ASSEMBLY__ @@ -23,6 +68,18 @@  .endm  /* + * This should be used immediately before an indirect jump/call. It tells + * objtool the subsequent indirect jump/call is vouched safe for retpoline + * builds. + */ +.macro ANNOTATE_RETPOLINE_SAFE +	.Lannotate_\@: +	.pushsection .discard.retpoline_safe +	_ASM_PTR .Lannotate_\@ +	.popsection +.endm + +/*   * These are the bare retpoline primitives for indirect jmp and call.   * Do not use these directly; they only exist to make the ALTERNATIVE   * invocation below less ugly. @@ -58,9 +115,9 @@  .macro JMP_NOSPEC reg:req  #ifdef CONFIG_RETPOLINE  	ANNOTATE_NOSPEC_ALTERNATIVE -	ALTERNATIVE_2 __stringify(jmp *\reg),				\ +	ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *\reg),	\  		__stringify(RETPOLINE_JMP \reg), X86_FEATURE_RETPOLINE,	\ -		__stringify(lfence; jmp *\reg), X86_FEATURE_RETPOLINE_AMD +		__stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *\reg), X86_FEATURE_RETPOLINE_AMD  #else  	jmp	*\reg  #endif @@ -69,18 +126,25 @@  .macro CALL_NOSPEC reg:req  #ifdef CONFIG_RETPOLINE  	ANNOTATE_NOSPEC_ALTERNATIVE -	ALTERNATIVE_2 __stringify(call *\reg),				\ +	ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; call *\reg),	\  		__stringify(RETPOLINE_CALL \reg), X86_FEATURE_RETPOLINE,\ -		__stringify(lfence; call *\reg), X86_FEATURE_RETPOLINE_AMD +		__stringify(lfence; ANNOTATE_RETPOLINE_SAFE; call *\reg), X86_FEATURE_RETPOLINE_AMD  #else  	call	*\reg  #endif  .endm -/* This clobbers the BX register */ -.macro FILL_RETURN_BUFFER nr:req ftr:req + /* +  * A simpler FILL_RETURN_BUFFER macro. Don't make people use the CPP +  * monstrosity above, manually. +  */ +.macro FILL_RETURN_BUFFER reg:req nr:req ftr:req  #ifdef CONFIG_RETPOLINE -	ALTERNATIVE "", "call __clear_rsb", \ftr +	ANNOTATE_NOSPEC_ALTERNATIVE +	ALTERNATIVE "jmp .Lskip_rsb_\@",				\ +		__stringify(__FILL_RETURN_BUFFER(\reg,\nr,%_ASM_SP))	\ +		\ftr +.Lskip_rsb_\@:  #endif  .endm @@ -92,6 +156,12 @@  	".long 999b - .\n\t"					\  	".popsection\n\t" +#define ANNOTATE_RETPOLINE_SAFE					\ +	"999:\n\t"						\ +	".pushsection .discard.retpoline_safe\n\t"		\ +	_ASM_PTR " 999b\n\t"					\ +	".popsection\n\t" +  #if defined(CONFIG_X86_64) && defined(RETPOLINE)  /* @@ -101,6 +171,7 @@  # define CALL_NOSPEC						\  	ANNOTATE_NOSPEC_ALTERNATIVE				\  	ALTERNATIVE(						\ +	ANNOTATE_RETPOLINE_SAFE					\  	"call *%[thunk_target]\n",				\  	"call __x86_indirect_thunk_%V[thunk_target]\n",		\  	X86_FEATURE_RETPOLINE) @@ -112,7 +183,10 @@   * otherwise we'll run out of registers. We don't care about CET   * here, anyway.   */ -# define CALL_NOSPEC ALTERNATIVE("call *%[thunk_target]\n",	\ +# define CALL_NOSPEC						\ +	ALTERNATIVE(						\ +	ANNOTATE_RETPOLINE_SAFE					\ +	"call *%[thunk_target]\n",				\  	"       jmp    904f;\n"					\  	"       .align 16\n"					\  	"901:	call   903f;\n"					\ @@ -155,20 +229,90 @@ extern char __indirect_thunk_end[];  static inline void vmexit_fill_RSB(void)  {  #ifdef CONFIG_RETPOLINE -	alternative_input("", -			  "call __fill_rsb", -			  X86_FEATURE_RETPOLINE, -			  ASM_NO_INPUT_CLOBBER(_ASM_BX, "memory")); +	unsigned long loops; + +	asm volatile (ANNOTATE_NOSPEC_ALTERNATIVE +		      ALTERNATIVE("jmp 910f", +				  __stringify(__FILL_RETURN_BUFFER(%0, RSB_CLEAR_LOOPS, %1)), +				  X86_FEATURE_RETPOLINE) +		      "910:" +		      : "=r" (loops), ASM_CALL_CONSTRAINT +		      : : "memory" );  #endif  } +#define alternative_msr_write(_msr, _val, _feature)		\ +	asm volatile(ALTERNATIVE("",				\ +				 "movl %[msr], %%ecx\n\t"	\ +				 "movl %[val], %%eax\n\t"	\ +				 "movl $0, %%edx\n\t"		\ +				 "wrmsr",			\ +				 _feature)			\ +		     : : [msr] "i" (_msr), [val] "i" (_val)	\ +		     : "eax", "ecx", "edx", "memory") +  static inline void indirect_branch_prediction_barrier(void)  { -	alternative_input("", -			  "call __ibp_barrier", -			  X86_FEATURE_USE_IBPB, -			  ASM_NO_INPUT_CLOBBER("eax", "ecx", "edx", "memory")); +	alternative_msr_write(MSR_IA32_PRED_CMD, PRED_CMD_IBPB, +			      X86_FEATURE_USE_IBPB);  } +/* + * With retpoline, we must use IBRS to restrict branch prediction + * before calling into firmware. + * + * (Implemented as CPP macros due to header hell.) + */ +#define firmware_restrict_branch_speculation_start()			\ +do {									\ +	preempt_disable();						\ +	alternative_msr_write(MSR_IA32_SPEC_CTRL, SPEC_CTRL_IBRS,	\ +			      X86_FEATURE_USE_IBRS_FW);			\ +} while (0) + +#define firmware_restrict_branch_speculation_end()			\ +do {									\ +	alternative_msr_write(MSR_IA32_SPEC_CTRL, 0,			\ +			      X86_FEATURE_USE_IBRS_FW);			\ +	preempt_enable();						\ +} while (0) +  #endif /* __ASSEMBLY__ */ + +/* + * Below is used in the eBPF JIT compiler and emits the byte sequence + * for the following assembly: + * + * With retpolines configured: + * + *    callq do_rop + *  spec_trap: + *    pause + *    lfence + *    jmp spec_trap + *  do_rop: + *    mov %rax,(%rsp) + *    retq + * + * Without retpolines configured: + * + *    jmp *%rax + */ +#ifdef CONFIG_RETPOLINE +# define RETPOLINE_RAX_BPF_JIT_SIZE	17 +# define RETPOLINE_RAX_BPF_JIT()				\ +	EMIT1_off32(0xE8, 7);	 /* callq do_rop */		\ +	/* spec_trap: */					\ +	EMIT2(0xF3, 0x90);       /* pause */			\ +	EMIT3(0x0F, 0xAE, 0xE8); /* lfence */			\ +	EMIT2(0xEB, 0xF9);       /* jmp spec_trap */		\ +	/* do_rop: */						\ +	EMIT4(0x48, 0x89, 0x04, 0x24); /* mov %rax,(%rsp) */	\ +	EMIT1(0xC3);             /* retq */ +#else +# define RETPOLINE_RAX_BPF_JIT_SIZE	2 +# define RETPOLINE_RAX_BPF_JIT()				\ +	EMIT2(0xFF, 0xE0);	 /* jmp *%rax */ +#endif +  #endif /* _ASM_X86_NOSPEC_BRANCH_H_ */ diff --git a/arch/x86/include/asm/page_64.h b/arch/x86/include/asm/page_64.h index 4baa6bceb232..d652a3808065 100644 --- a/arch/x86/include/asm/page_64.h +++ b/arch/x86/include/asm/page_64.h @@ -52,10 +52,6 @@ static inline void clear_page(void *page)  void copy_page(void *to, void *from); -#ifdef CONFIG_X86_MCE -#define arch_unmap_kpfn arch_unmap_kpfn -#endif -  #endif	/* !__ASSEMBLY__ */  #ifdef CONFIG_X86_VSYSCALL_EMULATION diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 892df375b615..c83a2f418cea 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h @@ -7,6 +7,7 @@  #ifdef CONFIG_PARAVIRT  #include <asm/pgtable_types.h>  #include <asm/asm.h> +#include <asm/nospec-branch.h>  #include <asm/paravirt_types.h> @@ -297,9 +298,9 @@ static inline void __flush_tlb_global(void)  {  	PVOP_VCALL0(pv_mmu_ops.flush_tlb_kernel);  } -static inline void __flush_tlb_single(unsigned long addr) +static inline void __flush_tlb_one_user(unsigned long addr)  { -	PVOP_VCALL1(pv_mmu_ops.flush_tlb_single, addr); +	PVOP_VCALL1(pv_mmu_ops.flush_tlb_one_user, addr);  }  static inline void flush_tlb_others(const struct cpumask *cpumask, @@ -879,23 +880,27 @@ extern void default_banner(void);  #define INTERRUPT_RETURN						\  	PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_iret), CLBR_NONE,	\ -		  jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_iret)) +		  ANNOTATE_RETPOLINE_SAFE;					\ +		  jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_iret);)  #define DISABLE_INTERRUPTS(clobbers)					\  	PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \  		  PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE);		\ +		  ANNOTATE_RETPOLINE_SAFE;					\  		  call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_disable);	\  		  PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);)  #define ENABLE_INTERRUPTS(clobbers)					\  	PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers,	\  		  PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE);		\ +		  ANNOTATE_RETPOLINE_SAFE;					\  		  call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_enable);	\  		  PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);)  #ifdef CONFIG_X86_32  #define GET_CR0_INTO_EAX				\  	push %ecx; push %edx;				\ +	ANNOTATE_RETPOLINE_SAFE;				\  	call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0);	\  	pop %edx; pop %ecx  #else	/* !CONFIG_X86_32 */ @@ -917,21 +922,25 @@ extern void default_banner(void);   */  #define SWAPGS								\  	PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_swapgs), CLBR_NONE,	\ -		  call PARA_INDIRECT(pv_cpu_ops+PV_CPU_swapgs)		\ +		  ANNOTATE_RETPOLINE_SAFE;					\ +		  call PARA_INDIRECT(pv_cpu_ops+PV_CPU_swapgs);		\  		 )  #define GET_CR2_INTO_RAX				\ -	call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr2) +	ANNOTATE_RETPOLINE_SAFE;				\ +	call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr2);  #define USERGS_SYSRET64							\  	PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usergs_sysret64),	\  		  CLBR_NONE,						\ -		  jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_usergs_sysret64)) +		  ANNOTATE_RETPOLINE_SAFE;					\ +		  jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_usergs_sysret64);)  #ifdef CONFIG_DEBUG_ENTRY  #define SAVE_FLAGS(clobbers)                                        \  	PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_save_fl), clobbers, \  		  PV_SAVE_REGS(clobbers | CLBR_CALLEE_SAVE);        \ +		  ANNOTATE_RETPOLINE_SAFE;				    \  		  call PARA_INDIRECT(pv_irq_ops+PV_IRQ_save_fl);    \  		  PV_RESTORE_REGS(clobbers | CLBR_CALLEE_SAVE);)  #endif diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 6ec54d01972d..180bc0bff0fb 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h @@ -43,6 +43,7 @@  #include <asm/desc_defs.h>  #include <asm/kmap_types.h>  #include <asm/pgtable_types.h> +#include <asm/nospec-branch.h>  struct page;  struct thread_struct; @@ -217,7 +218,7 @@ struct pv_mmu_ops {  	/* TLB operations */  	void (*flush_tlb_user)(void);  	void (*flush_tlb_kernel)(void); -	void (*flush_tlb_single)(unsigned long addr); +	void (*flush_tlb_one_user)(unsigned long addr);  	void (*flush_tlb_others)(const struct cpumask *cpus,  				 const struct flush_tlb_info *info); @@ -392,7 +393,9 @@ int paravirt_disable_iospace(void);   * offset into the paravirt_patch_template structure, and can therefore be   * freely converted back into a structure offset.   */ -#define PARAVIRT_CALL	"call *%c[paravirt_opptr];" +#define PARAVIRT_CALL					\ +	ANNOTATE_RETPOLINE_SAFE				\ +	"call *%c[paravirt_opptr];"  /*   * These macros are intended to wrap calls through one of the paravirt diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index ba3c523aaf16..a06b07399d17 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h @@ -526,7 +526,7 @@ static inline bool x86_this_cpu_variable_test_bit(int nr,  {  	bool oldbit; -	asm volatile("bt "__percpu_arg(2)",%1" +	asm volatile("btl "__percpu_arg(2)",%1"  			CC_SET(c)  			: CC_OUT(c) (oldbit)  			: "m" (*(unsigned long __percpu *)addr), "Ir" (nr)); diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 63c2552b6b65..b444d83cfc95 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -350,14 +350,14 @@ static inline pmd_t pmd_set_flags(pmd_t pmd, pmdval_t set)  {  	pmdval_t v = native_pmd_val(pmd); -	return __pmd(v | set); +	return native_make_pmd(v | set);  }  static inline pmd_t pmd_clear_flags(pmd_t pmd, pmdval_t clear)  {  	pmdval_t v = native_pmd_val(pmd); -	return __pmd(v & ~clear); +	return native_make_pmd(v & ~clear);  }  static inline pmd_t pmd_mkold(pmd_t pmd) @@ -409,14 +409,14 @@ static inline pud_t pud_set_flags(pud_t pud, pudval_t set)  {  	pudval_t v = native_pud_val(pud); -	return __pud(v | set); +	return native_make_pud(v | set);  }  static inline pud_t pud_clear_flags(pud_t pud, pudval_t clear)  {  	pudval_t v = native_pud_val(pud); -	return __pud(v & ~clear); +	return native_make_pud(v & ~clear);  }  static inline pud_t pud_mkold(pud_t pud) diff --git a/arch/x86/include/asm/pgtable_32.h b/arch/x86/include/asm/pgtable_32.h index e67c0620aec2..b3ec519e3982 100644 --- a/arch/x86/include/asm/pgtable_32.h +++ b/arch/x86/include/asm/pgtable_32.h @@ -32,6 +32,7 @@ extern pmd_t initial_pg_pmd[];  static inline void pgtable_cache_init(void) { }  static inline void check_pgt_cache(void) { }  void paging_init(void); +void sync_initial_page_table(void);  /*   * Define this if things work differently on an i386 and an i486: @@ -61,7 +62,7 @@ void paging_init(void);  #define kpte_clear_flush(ptep, vaddr)		\  do {						\  	pte_clear(&init_mm, (vaddr), (ptep));	\ -	__flush_tlb_one((vaddr));		\ +	__flush_tlb_one_kernel((vaddr));		\  } while (0)  #endif /* !__ASSEMBLY__ */ diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h index 81462e9a34f6..1149d2112b2e 100644 --- a/arch/x86/include/asm/pgtable_64.h +++ b/arch/x86/include/asm/pgtable_64.h @@ -28,6 +28,7 @@ extern pgd_t init_top_pgt[];  #define swapper_pg_dir init_top_pgt  extern void paging_init(void); +static inline void sync_initial_page_table(void) { }  #define pte_ERROR(e)					\  	pr_err("%s:%d: bad pte %p(%016lx)\n",		\ diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h index 3696398a9475..acfe755562a6 100644 --- a/arch/x86/include/asm/pgtable_types.h +++ b/arch/x86/include/asm/pgtable_types.h @@ -174,7 +174,6 @@ enum page_cache_mode {  #define __PAGE_KERNEL_RO		(__PAGE_KERNEL & ~_PAGE_RW)  #define __PAGE_KERNEL_RX		(__PAGE_KERNEL_EXEC & ~_PAGE_RW)  #define __PAGE_KERNEL_NOCACHE		(__PAGE_KERNEL | _PAGE_NOCACHE) -#define __PAGE_KERNEL_VSYSCALL		(__PAGE_KERNEL_RX | _PAGE_USER)  #define __PAGE_KERNEL_VVAR		(__PAGE_KERNEL_RO | _PAGE_USER)  #define __PAGE_KERNEL_LARGE		(__PAGE_KERNEL | _PAGE_PSE)  #define __PAGE_KERNEL_LARGE_EXEC	(__PAGE_KERNEL_EXEC | _PAGE_PSE) @@ -206,7 +205,6 @@ enum page_cache_mode {  #define PAGE_KERNEL_NOCACHE	__pgprot(__PAGE_KERNEL_NOCACHE | _PAGE_ENC)  #define PAGE_KERNEL_LARGE	__pgprot(__PAGE_KERNEL_LARGE | _PAGE_ENC)  #define PAGE_KERNEL_LARGE_EXEC	__pgprot(__PAGE_KERNEL_LARGE_EXEC | _PAGE_ENC) -#define PAGE_KERNEL_VSYSCALL	__pgprot(__PAGE_KERNEL_VSYSCALL | _PAGE_ENC)  #define PAGE_KERNEL_VVAR	__pgprot(__PAGE_KERNEL_VVAR | _PAGE_ENC)  #define PAGE_KERNEL_IO		__pgprot(__PAGE_KERNEL_IO) @@ -323,6 +321,11 @@ static inline pudval_t native_pud_val(pud_t pud)  #else  #include <asm-generic/pgtable-nopud.h> +static inline pud_t native_make_pud(pudval_t val) +{ +	return (pud_t) { .p4d.pgd = native_make_pgd(val) }; +} +  static inline pudval_t native_pud_val(pud_t pud)  {  	return native_pgd_val(pud.p4d.pgd); @@ -344,6 +347,11 @@ static inline pmdval_t native_pmd_val(pmd_t pmd)  #else  #include <asm-generic/pgtable-nopmd.h> +static inline pmd_t native_make_pmd(pmdval_t val) +{ +	return (pmd_t) { .pud.p4d.pgd = native_make_pgd(val) }; +} +  static inline pmdval_t native_pmd_val(pmd_t pmd)  {  	return native_pgd_val(pmd.pud.p4d.pgd); diff --git a/arch/x86/include/asm/platform_sst_audio.h b/arch/x86/include/asm/platform_sst_audio.h index 5973a2f3db3d..059823bb8af7 100644 --- a/arch/x86/include/asm/platform_sst_audio.h +++ b/arch/x86/include/asm/platform_sst_audio.h @@ -135,6 +135,7 @@ struct sst_platform_info {  	const struct sst_res_info *res_info;  	const struct sst_lib_dnld_info *lib_info;  	const char *platform; +	bool streams_lost_on_suspend;  };  int add_sst_platform_device(void);  #endif diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 793bae7e7ce3..b0ccd4847a58 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -91,7 +91,7 @@ struct cpuinfo_x86 {  	__u8			x86;		/* CPU family */  	__u8			x86_vendor;	/* CPU vendor */  	__u8			x86_model; -	__u8			x86_mask; +	__u8			x86_stepping;  #ifdef CONFIG_X86_64  	/* Number of 4K pages in DTLB/ITLB combined(in pages): */  	int			x86_tlbsize; @@ -109,7 +109,7 @@ struct cpuinfo_x86 {  	char			x86_vendor_id[16];  	char			x86_model_id[64];  	/* in KB - valid for CPUS which support this call: */ -	int			x86_cache_size; +	unsigned int		x86_cache_size;  	int			x86_cache_alignment;	/* In bytes */  	/* Cache QoS architectural values: */  	int			x86_cache_max_rmid;	/* max index */ @@ -977,7 +977,5 @@ bool xen_set_default_idle(void);  void stop_this_cpu(void *dummy);  void df_debug(struct pt_regs *regs, long error_code); - -void __ibp_barrier(void); - +void microcode_check(void);  #endif /* _ASM_X86_PROCESSOR_H */ diff --git a/arch/x86/include/asm/refcount.h b/arch/x86/include/asm/refcount.h index 4e44250e7d0d..4cf11d88d3b3 100644 --- a/arch/x86/include/asm/refcount.h +++ b/arch/x86/include/asm/refcount.h @@ -17,7 +17,7 @@  #define _REFCOUNT_EXCEPTION				\  	".pushsection .text..refcount\n"		\  	"111:\tlea %[counter], %%" _ASM_CX "\n"		\ -	"112:\t" ASM_UD0 "\n"				\ +	"112:\t" ASM_UD2 "\n"				\  	ASM_UNREACHABLE					\  	".popsection\n"					\  	"113:\n"					\ @@ -67,13 +67,13 @@ static __always_inline __must_check  bool refcount_sub_and_test(unsigned int i, refcount_t *r)  {  	GEN_BINARY_SUFFIXED_RMWcc(LOCK_PREFIX "subl", REFCOUNT_CHECK_LT_ZERO, -				  r->refs.counter, "er", i, "%0", e); +				  r->refs.counter, "er", i, "%0", e, "cx");  }  static __always_inline __must_check bool refcount_dec_and_test(refcount_t *r)  {  	GEN_UNARY_SUFFIXED_RMWcc(LOCK_PREFIX "decl", REFCOUNT_CHECK_LT_ZERO, -				 r->refs.counter, "%0", e); +				 r->refs.counter, "%0", e, "cx");  }  static __always_inline __must_check diff --git a/arch/x86/include/asm/rmwcc.h b/arch/x86/include/asm/rmwcc.h index f91c365e57c3..4914a3e7c803 100644 --- a/arch/x86/include/asm/rmwcc.h +++ b/arch/x86/include/asm/rmwcc.h @@ -2,8 +2,7 @@  #ifndef _ASM_X86_RMWcc  #define _ASM_X86_RMWcc -#define __CLOBBERS_MEM		"memory" -#define __CLOBBERS_MEM_CC_CX	"memory", "cc", "cx" +#define __CLOBBERS_MEM(clb...)	"memory", ## clb  #if !defined(__GCC_ASM_FLAG_OUTPUTS__) && defined(CC_HAVE_ASM_GOTO) @@ -40,18 +39,19 @@ do {									\  #endif /* defined(__GCC_ASM_FLAG_OUTPUTS__) || !defined(CC_HAVE_ASM_GOTO) */  #define GEN_UNARY_RMWcc(op, var, arg0, cc)				\ -	__GEN_RMWcc(op " " arg0, var, cc, __CLOBBERS_MEM) +	__GEN_RMWcc(op " " arg0, var, cc, __CLOBBERS_MEM()) -#define GEN_UNARY_SUFFIXED_RMWcc(op, suffix, var, arg0, cc)		\ +#define GEN_UNARY_SUFFIXED_RMWcc(op, suffix, var, arg0, cc, clobbers...)\  	__GEN_RMWcc(op " " arg0 "\n\t" suffix, var, cc,			\ -		    __CLOBBERS_MEM_CC_CX) +		    __CLOBBERS_MEM(clobbers))  #define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc)			\  	__GEN_RMWcc(op __BINARY_RMWcc_ARG arg0, var, cc,		\ -		    __CLOBBERS_MEM, vcon (val)) +		    __CLOBBERS_MEM(), vcon (val)) -#define GEN_BINARY_SUFFIXED_RMWcc(op, suffix, var, vcon, val, arg0, cc)	\ +#define GEN_BINARY_SUFFIXED_RMWcc(op, suffix, var, vcon, val, arg0, cc,	\ +				  clobbers...)				\  	__GEN_RMWcc(op __BINARY_RMWcc_ARG arg0 "\n\t" suffix, var, cc,	\ -		    __CLOBBERS_MEM_CC_CX, vcon (val)) +		    __CLOBBERS_MEM(clobbers), vcon (val))  #endif /* _ASM_X86_RMWcc */ diff --git a/arch/x86/include/asm/sections.h b/arch/x86/include/asm/sections.h index d6baf23782bc..5c019d23d06b 100644 --- a/arch/x86/include/asm/sections.h +++ b/arch/x86/include/asm/sections.h @@ -10,6 +10,7 @@ extern struct exception_table_entry __stop___ex_table[];  #if defined(CONFIG_X86_64)  extern char __end_rodata_hpage_align[]; +extern char __entry_trampoline_start[], __entry_trampoline_end[];  #endif  #endif	/* _ASM_X86_SECTIONS_H */ diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index 461f53d27708..a4189762b266 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -129,6 +129,7 @@ static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask)  void cpu_disable_common(void);  void native_smp_prepare_boot_cpu(void);  void native_smp_prepare_cpus(unsigned int max_cpus); +void calculate_max_logical_packages(void);  void native_smp_cpus_done(unsigned int max_cpus);  void common_cpu_up(unsigned int cpunum, struct task_struct *tidle);  int native_cpu_up(unsigned int cpunum, struct task_struct *tidle); diff --git a/arch/x86/include/asm/sys_ia32.h b/arch/x86/include/asm/sys_ia32.h index 82c34ee25a65..906794aa034e 100644 --- a/arch/x86/include/asm/sys_ia32.h +++ b/arch/x86/include/asm/sys_ia32.h @@ -20,31 +20,43 @@  #include <asm/ia32.h>  /* ia32/sys_ia32.c */ -asmlinkage long sys32_truncate64(const char __user *, unsigned long, unsigned long); -asmlinkage long sys32_ftruncate64(unsigned int, unsigned long, unsigned long); +asmlinkage long compat_sys_x86_truncate64(const char __user *, unsigned long, +					  unsigned long); +asmlinkage long compat_sys_x86_ftruncate64(unsigned int, unsigned long, +					   unsigned long); -asmlinkage long sys32_stat64(const char __user *, struct stat64 __user *); -asmlinkage long sys32_lstat64(const char __user *, struct stat64 __user *); -asmlinkage long sys32_fstat64(unsigned int, struct stat64 __user *); -asmlinkage long sys32_fstatat(unsigned int, const char __user *, +asmlinkage long compat_sys_x86_stat64(const char __user *, +				      struct stat64 __user *); +asmlinkage long compat_sys_x86_lstat64(const char __user *, +				       struct stat64 __user *); +asmlinkage long compat_sys_x86_fstat64(unsigned int, struct stat64 __user *); +asmlinkage long compat_sys_x86_fstatat(unsigned int, const char __user *,  			      struct stat64 __user *, int);  struct mmap_arg_struct32; -asmlinkage long sys32_mmap(struct mmap_arg_struct32 __user *); +asmlinkage long compat_sys_x86_mmap(struct mmap_arg_struct32 __user *); -asmlinkage long sys32_waitpid(compat_pid_t, unsigned int __user *, int); +asmlinkage long compat_sys_x86_waitpid(compat_pid_t, unsigned int __user *, +				       int); -asmlinkage long sys32_pread(unsigned int, char __user *, u32, u32, u32); -asmlinkage long sys32_pwrite(unsigned int, const char __user *, u32, u32, u32); +asmlinkage long compat_sys_x86_pread(unsigned int, char __user *, u32, u32, +				     u32); +asmlinkage long compat_sys_x86_pwrite(unsigned int, const char __user *, u32, +				      u32, u32); -long sys32_fadvise64_64(int, __u32, __u32, __u32, __u32, int); -long sys32_vm86_warning(void); +asmlinkage long compat_sys_x86_fadvise64_64(int, __u32, __u32, __u32, __u32, +					    int); -asmlinkage ssize_t sys32_readahead(int, unsigned, unsigned, size_t); -asmlinkage long sys32_sync_file_range(int, unsigned, unsigned, -				      unsigned, unsigned, int); -asmlinkage long sys32_fadvise64(int, unsigned, unsigned, size_t, int); -asmlinkage long sys32_fallocate(int, int, unsigned, -				unsigned, unsigned, unsigned); +asmlinkage ssize_t compat_sys_x86_readahead(int, unsigned int, unsigned int, +					    size_t); +asmlinkage long compat_sys_x86_sync_file_range(int, unsigned int, unsigned int, +					       unsigned int, unsigned int, +					       int); +asmlinkage long compat_sys_x86_fadvise64(int, unsigned int, unsigned int, +					 size_t, int); +asmlinkage long compat_sys_x86_fallocate(int, int, unsigned int, unsigned int, +					 unsigned int, unsigned int); +asmlinkage long compat_sys_x86_clone(unsigned long, unsigned long, int __user *, +				     unsigned long, int __user *);  /* ia32/ia32_signal.c */  asmlinkage long sys32_sigreturn(void); diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index 2b8f18ca5874..84137c22fdfa 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h @@ -140,7 +140,7 @@ static inline unsigned long build_cr3_noflush(pgd_t *pgd, u16 asid)  #else  #define __flush_tlb() __native_flush_tlb()  #define __flush_tlb_global() __native_flush_tlb_global() -#define __flush_tlb_single(addr) __native_flush_tlb_single(addr) +#define __flush_tlb_one_user(addr) __native_flush_tlb_one_user(addr)  #endif  static inline bool tlb_defer_switch_to_init_mm(void) @@ -400,7 +400,7 @@ static inline void __native_flush_tlb_global(void)  /*   * flush one page in the user mapping   */ -static inline void __native_flush_tlb_single(unsigned long addr) +static inline void __native_flush_tlb_one_user(unsigned long addr)  {  	u32 loaded_mm_asid = this_cpu_read(cpu_tlbstate.loaded_mm_asid); @@ -437,18 +437,31 @@ static inline void __flush_tlb_all(void)  /*   * flush one page in the kernel mapping   */ -static inline void __flush_tlb_one(unsigned long addr) +static inline void __flush_tlb_one_kernel(unsigned long addr)  {  	count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ONE); -	__flush_tlb_single(addr); + +	/* +	 * If PTI is off, then __flush_tlb_one_user() is just INVLPG or its +	 * paravirt equivalent.  Even with PCID, this is sufficient: we only +	 * use PCID if we also use global PTEs for the kernel mapping, and +	 * INVLPG flushes global translations across all address spaces. +	 * +	 * If PTI is on, then the kernel is mapped with non-global PTEs, and +	 * __flush_tlb_one_user() will flush the given address for the current +	 * kernel address space and for its usermode counterpart, but it does +	 * not flush it for other address spaces. +	 */ +	__flush_tlb_one_user(addr);  	if (!static_cpu_has(X86_FEATURE_PTI))  		return;  	/* -	 * __flush_tlb_single() will have cleared the TLB entry for this ASID, -	 * but since kernel space is replicated across all, we must also -	 * invalidate all others. +	 * See above.  We need to propagate the flush to all other address +	 * spaces.  In principle, we only need to propagate it to kernelmode +	 * address spaces, but the extra bookkeeping we would need is not +	 * worth it.  	 */  	invalidate_other_asid();  } diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index 8b6780751132..5db8b0b10766 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -352,6 +352,7 @@ enum vmcs_field {  #define INTR_TYPE_NMI_INTR		(2 << 8) /* NMI */  #define INTR_TYPE_HARD_EXCEPTION	(3 << 8) /* processor exception */  #define INTR_TYPE_SOFT_INTR             (4 << 8) /* software interrupt */ +#define INTR_TYPE_PRIV_SW_EXCEPTION	(5 << 8) /* ICE breakpoint - undocumented */  #define INTR_TYPE_SOFT_EXCEPTION	(6 << 8) /* software exception */  /* GUEST_INTERRUPTIBILITY_INFO flags. */  | 

