diff options
Diffstat (limited to 'arch/x86/kernel/cpu')
| -rw-r--r-- | arch/x86/kernel/cpu/amd.c | 7 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/common.c | 96 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/microcode/amd.c | 4 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/microcode/intel.c | 13 | 
4 files changed, 49 insertions, 71 deletions
| diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index d58184b7cd44..bcb75dc97d44 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -804,8 +804,11 @@ static void init_amd(struct cpuinfo_x86 *c)  	case 0x17: init_amd_zn(c); break;  	} -	/* Enable workaround for FXSAVE leak */ -	if (c->x86 >= 6) +	/* +	 * Enable workaround for FXSAVE leak on CPUs +	 * without a XSaveErPtr feature +	 */ +	if ((c->x86 >= 6) && (!cpu_has(c, X86_FEATURE_XSAVEERPTR)))  		set_cpu_bug(c, X86_BUG_FXSAVE_LEAK);  	cpu_detect_cache_sizes(c); diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index fa998ca8aa5a..c9757f07d738 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -476,8 +476,8 @@ static const char *table_lookup_model(struct cpuinfo_x86 *c)  	return NULL;		/* Not found */  } -__u32 cpu_caps_cleared[NCAPINTS]; -__u32 cpu_caps_set[NCAPINTS]; +__u32 cpu_caps_cleared[NCAPINTS + NBUGINTS]; +__u32 cpu_caps_set[NCAPINTS + NBUGINTS];  void load_percpu_segment(int cpu)  { @@ -490,28 +490,23 @@ void load_percpu_segment(int cpu)  	load_stack_canary_segment();  } -/* Setup the fixmap mapping only once per-processor */ -static inline void setup_fixmap_gdt(int cpu) -{ -#ifdef CONFIG_X86_64 -	/* On 64-bit systems, we use a read-only fixmap GDT. */ -	pgprot_t prot = PAGE_KERNEL_RO; -#else -	/* -	 * On native 32-bit systems, the GDT cannot be read-only because -	 * our double fault handler uses a task gate, and entering through -	 * a task gate needs to change an available TSS to busy.  If the GDT -	 * is read-only, that will triple fault. -	 * -	 * On Xen PV, the GDT must be read-only because the hypervisor requires -	 * it. -	 */ -	pgprot_t prot = boot_cpu_has(X86_FEATURE_XENPV) ? -		PAGE_KERNEL_RO : PAGE_KERNEL; +#ifdef CONFIG_X86_32 +/* The 32-bit entry code needs to find cpu_entry_area. */ +DEFINE_PER_CPU(struct cpu_entry_area *, cpu_entry_area);  #endif -	__set_fixmap(get_cpu_gdt_ro_index(cpu), get_cpu_gdt_paddr(cpu), prot); -} +#ifdef CONFIG_X86_64 +/* + * Special IST stacks which the CPU switches to when it calls + * an IST-marked descriptor entry. Up to 7 stacks (hardware + * limit), all of them are 4K, except the debug stack which + * is 8K. + */ +static const unsigned int exception_stack_sizes[N_EXCEPTION_STACKS] = { +	  [0 ... N_EXCEPTION_STACKS - 1]	= EXCEPTION_STKSZ, +	  [DEBUG_STACK - 1]			= DEBUG_STKSZ +}; +#endif  /* Load the original GDT from the per-cpu structure */  void load_direct_gdt(int cpu) @@ -747,7 +742,7 @@ static void apply_forced_caps(struct cpuinfo_x86 *c)  {  	int i; -	for (i = 0; i < NCAPINTS; i++) { +	for (i = 0; i < NCAPINTS + NBUGINTS; i++) {  		c->x86_capability[i] &= ~cpu_caps_cleared[i];  		c->x86_capability[i] |= cpu_caps_set[i];  	} @@ -1250,7 +1245,7 @@ void enable_sep_cpu(void)  		return;  	cpu = get_cpu(); -	tss = &per_cpu(cpu_tss, cpu); +	tss = &per_cpu(cpu_tss_rw, cpu);  	/*  	 * We cache MSR_IA32_SYSENTER_CS's value in the TSS's ss1 field -- @@ -1259,11 +1254,7 @@ void enable_sep_cpu(void)  	tss->x86_tss.ss1 = __KERNEL_CS;  	wrmsr(MSR_IA32_SYSENTER_CS, tss->x86_tss.ss1, 0); - -	wrmsr(MSR_IA32_SYSENTER_ESP, -	      (unsigned long)tss + offsetofend(struct tss_struct, SYSENTER_stack), -	      0); - +	wrmsr(MSR_IA32_SYSENTER_ESP, (unsigned long)(cpu_entry_stack(cpu) + 1), 0);  	wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long)entry_SYSENTER_32, 0);  	put_cpu(); @@ -1357,25 +1348,19 @@ DEFINE_PER_CPU(unsigned int, irq_count) __visible = -1;  DEFINE_PER_CPU(int, __preempt_count) = INIT_PREEMPT_COUNT;  EXPORT_PER_CPU_SYMBOL(__preempt_count); -/* - * Special IST stacks which the CPU switches to when it calls - * an IST-marked descriptor entry. Up to 7 stacks (hardware - * limit), all of them are 4K, except the debug stack which - * is 8K. - */ -static const unsigned int exception_stack_sizes[N_EXCEPTION_STACKS] = { -	  [0 ... N_EXCEPTION_STACKS - 1]	= EXCEPTION_STKSZ, -	  [DEBUG_STACK - 1]			= DEBUG_STKSZ -}; - -static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks -	[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]); -  /* May not be marked __init: used by software suspend */  void syscall_init(void)  { +	extern char _entry_trampoline[]; +	extern char entry_SYSCALL_64_trampoline[]; + +	int cpu = smp_processor_id(); +	unsigned long SYSCALL64_entry_trampoline = +		(unsigned long)get_cpu_entry_area(cpu)->entry_trampoline + +		(entry_SYSCALL_64_trampoline - _entry_trampoline); +  	wrmsr(MSR_STAR, 0, (__USER32_CS << 16) | __KERNEL_CS); -	wrmsrl(MSR_LSTAR, (unsigned long)entry_SYSCALL_64); +	wrmsrl(MSR_LSTAR, SYSCALL64_entry_trampoline);  #ifdef CONFIG_IA32_EMULATION  	wrmsrl(MSR_CSTAR, (unsigned long)entry_SYSCALL_compat); @@ -1386,7 +1371,7 @@ void syscall_init(void)  	 * AMD doesn't allow SYSENTER in long mode (either 32- or 64-bit).  	 */  	wrmsrl_safe(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS); -	wrmsrl_safe(MSR_IA32_SYSENTER_ESP, 0ULL); +	wrmsrl_safe(MSR_IA32_SYSENTER_ESP, (unsigned long)(cpu_entry_stack(cpu) + 1));  	wrmsrl_safe(MSR_IA32_SYSENTER_EIP, (u64)entry_SYSENTER_compat);  #else  	wrmsrl(MSR_CSTAR, (unsigned long)ignore_sysret); @@ -1530,7 +1515,7 @@ void cpu_init(void)  	if (cpu)  		load_ucode_ap(); -	t = &per_cpu(cpu_tss, cpu); +	t = &per_cpu(cpu_tss_rw, cpu);  	oist = &per_cpu(orig_ist, cpu);  #ifdef CONFIG_NUMA @@ -1569,7 +1554,7 @@ void cpu_init(void)  	 * set up and load the per-CPU TSS  	 */  	if (!oist->ist[0]) { -		char *estacks = per_cpu(exception_stacks, cpu); +		char *estacks = get_cpu_entry_area(cpu)->exception_stacks;  		for (v = 0; v < N_EXCEPTION_STACKS; v++) {  			estacks += exception_stack_sizes[v]; @@ -1580,7 +1565,7 @@ void cpu_init(void)  		}  	} -	t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap); +	t->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET;  	/*  	 * <= is required because the CPU will access up to @@ -1596,11 +1581,12 @@ void cpu_init(void)  	enter_lazy_tlb(&init_mm, me);  	/* -	 * Initialize the TSS.  Don't bother initializing sp0, as the initial -	 * task never enters user mode. +	 * Initialize the TSS.  sp0 points to the entry trampoline stack +	 * regardless of what task is running.  	 */ -	set_tss_desc(cpu, t); +	set_tss_desc(cpu, &get_cpu_entry_area(cpu)->tss.x86_tss);  	load_TR_desc(); +	load_sp0((unsigned long)(cpu_entry_stack(cpu) + 1));  	load_mm_ldt(&init_mm); @@ -1612,7 +1598,6 @@ void cpu_init(void)  	if (is_uv_system())  		uv_cpu_init(); -	setup_fixmap_gdt(cpu);  	load_fixmap_gdt(cpu);  } @@ -1622,7 +1607,7 @@ void cpu_init(void)  {  	int cpu = smp_processor_id();  	struct task_struct *curr = current; -	struct tss_struct *t = &per_cpu(cpu_tss, cpu); +	struct tss_struct *t = &per_cpu(cpu_tss_rw, cpu);  	wait_for_master_cpu(cpu); @@ -1657,12 +1642,12 @@ void cpu_init(void)  	 * Initialize the TSS.  Don't bother initializing sp0, as the initial  	 * task never enters user mode.  	 */ -	set_tss_desc(cpu, t); +	set_tss_desc(cpu, &get_cpu_entry_area(cpu)->tss.x86_tss);  	load_TR_desc();  	load_mm_ldt(&init_mm); -	t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap); +	t->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET;  #ifdef CONFIG_DOUBLEFAULT  	/* Set up doublefault TSS pointer in the GDT */ @@ -1674,7 +1659,6 @@ void cpu_init(void)  	fpu__init_cpu(); -	setup_fixmap_gdt(cpu);  	load_fixmap_gdt(cpu);  }  #endif diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index c6daec4bdba5..330b8462d426 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -470,6 +470,7 @@ static unsigned int verify_patch_size(u8 family, u32 patch_size,  #define F14H_MPB_MAX_SIZE 1824  #define F15H_MPB_MAX_SIZE 4096  #define F16H_MPB_MAX_SIZE 3458 +#define F17H_MPB_MAX_SIZE 3200  	switch (family) {  	case 0x14: @@ -481,6 +482,9 @@ static unsigned int verify_patch_size(u8 family, u32 patch_size,  	case 0x16:  		max_size = F16H_MPB_MAX_SIZE;  		break; +	case 0x17: +		max_size = F17H_MPB_MAX_SIZE; +		break;  	default:  		max_size = F1XH_MPB_MAX_SIZE;  		break; diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c index 7dbcb7adf797..8ccdca6d3f9e 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -565,15 +565,6 @@ static void print_ucode(struct ucode_cpu_info *uci)  }  #else -/* - * Flush global tlb. We only do this in x86_64 where paging has been enabled - * already and PGE should be enabled as well. - */ -static inline void flush_tlb_early(void) -{ -	__native_flush_tlb_global_irq_disabled(); -} -  static inline void print_ucode(struct ucode_cpu_info *uci)  {  	struct microcode_intel *mc; @@ -602,10 +593,6 @@ static int apply_microcode_early(struct ucode_cpu_info *uci, bool early)  	if (rev != mc->hdr.rev)  		return -1; -#ifdef CONFIG_X86_64 -	/* Flush global tlb. This is precaution. */ -	flush_tlb_early(); -#endif  	uci->cpu_sig.rev = rev;  	if (early) |