diff options
Diffstat (limited to 'arch/x86/kernel')
| -rw-r--r-- | arch/x86/kernel/amd_nb.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/aperture_64.c | 20 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/amd.c | 5 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/centaur.c | 272 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/common.c | 7 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/intel.c | 10 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/microcode/amd_early.c | 43 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mtrr/generic.c | 4 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 11 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event.h | 1 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel.c | 11 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel_uncore.c | 13 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event_p6.c | 48 | ||||
| -rw-r--r-- | arch/x86/kernel/ftrace.c | 83 | ||||
| -rw-r--r-- | arch/x86/kernel/head_32.S | 7 | ||||
| -rw-r--r-- | arch/x86/kernel/head_64.S | 6 | ||||
| -rw-r--r-- | arch/x86/kernel/i387.c | 15 | ||||
| -rw-r--r-- | arch/x86/kernel/irq.c | 9 | ||||
| -rw-r--r-- | arch/x86/kernel/machine_kexec_64.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/pci-dma.c | 4 | ||||
| -rw-r--r-- | arch/x86/kernel/quirks.c | 39 | ||||
| -rw-r--r-- | arch/x86/kernel/setup.c | 10 | ||||
| -rw-r--r-- | arch/x86/kernel/tsc.c | 11 | ||||
| -rw-r--r-- | arch/x86/kernel/tsc_msr.c | 30 | 
24 files changed, 242 insertions, 421 deletions
diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index 59554dca96ec..dec8de4e1663 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -179,7 +179,7 @@ int amd_get_subcaches(int cpu)  	return (mask >> (4 * cuid)) & 0xf;  } -int amd_set_subcaches(int cpu, int mask) +int amd_set_subcaches(int cpu, unsigned long mask)  {  	static unsigned int reset, ban;  	struct amd_northbridge *nb = node_to_amd_nb(amd_get_nb_id(cpu)); diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c index fd972a3e4cbb..9fa8aa051f54 100644 --- a/arch/x86/kernel/aperture_64.c +++ b/arch/x86/kernel/aperture_64.c @@ -18,7 +18,6 @@  #include <linux/pci_ids.h>  #include <linux/pci.h>  #include <linux/bitops.h> -#include <linux/ioport.h>  #include <linux/suspend.h>  #include <asm/e820.h>  #include <asm/io.h> @@ -54,18 +53,6 @@ int fallback_aper_force __initdata;  int fix_aperture __initdata = 1; -static struct resource gart_resource = { -	.name	= "GART", -	.flags	= IORESOURCE_MEM, -}; - -static void __init insert_aperture_resource(u32 aper_base, u32 aper_size) -{ -	gart_resource.start = aper_base; -	gart_resource.end = aper_base + aper_size - 1; -	insert_resource(&iomem_resource, &gart_resource); -} -  /* This code runs before the PCI subsystem is initialized, so just     access the northbridge directly. */ @@ -96,7 +83,6 @@ static u32 __init allocate_aperture(void)  	memblock_reserve(addr, aper_size);  	printk(KERN_INFO "Mapping aperture over %d KB of RAM @ %lx\n",  			aper_size >> 10, addr); -	insert_aperture_resource((u32)addr, aper_size);  	register_nosave_region(addr >> PAGE_SHIFT,  			       (addr+aper_size) >> PAGE_SHIFT); @@ -444,12 +430,8 @@ int __init gart_iommu_hole_init(void)  out:  	if (!fix && !fallback_aper_force) { -		if (last_aper_base) { -			unsigned long n = (32 * 1024 * 1024) << last_aper_order; - -			insert_aperture_resource((u32)last_aper_base, n); +		if (last_aper_base)  			return 1; -		}  		return 0;  	} diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index d3153e281d72..c67ffa686064 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -767,10 +767,7 @@ static unsigned int amd_size_cache(struct cpuinfo_x86 *c, unsigned int size)  static void cpu_set_tlb_flushall_shift(struct cpuinfo_x86 *c)  { -	tlb_flushall_shift = 5; - -	if (c->x86 <= 0x11) -		tlb_flushall_shift = 4; +	tlb_flushall_shift = 6;  }  static void cpu_detect_tlb_amd(struct cpuinfo_x86 *c) diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c index 8779edab684e..d8fba5c15fbd 100644 --- a/arch/x86/kernel/cpu/centaur.c +++ b/arch/x86/kernel/cpu/centaur.c @@ -8,236 +8,6 @@  #include "cpu.h" -#ifdef CONFIG_X86_OOSTORE - -static u32 power2(u32 x) -{ -	u32 s = 1; - -	while (s <= x) -		s <<= 1; - -	return s >>= 1; -} - - -/* - * Set up an actual MCR - */ -static void centaur_mcr_insert(int reg, u32 base, u32 size, int key) -{ -	u32 lo, hi; - -	hi = base & ~0xFFF; -	lo = ~(size-1);		/* Size is a power of 2 so this makes a mask */ -	lo &= ~0xFFF;		/* Remove the ctrl value bits */ -	lo |= key;		/* Attribute we wish to set */ -	wrmsr(reg+MSR_IDT_MCR0, lo, hi); -	mtrr_centaur_report_mcr(reg, lo, hi);	/* Tell the mtrr driver */ -} - -/* - * Figure what we can cover with MCR's - * - * Shortcut: We know you can't put 4Gig of RAM on a winchip - */ -static u32 ramtop(void) -{ -	u32 clip = 0xFFFFFFFFUL; -	u32 top = 0; -	int i; - -	for (i = 0; i < e820.nr_map; i++) { -		unsigned long start, end; - -		if (e820.map[i].addr > 0xFFFFFFFFUL) -			continue; -		/* -		 * Don't MCR over reserved space. Ignore the ISA hole -		 * we frob around that catastrophe already -		 */ -		if (e820.map[i].type == E820_RESERVED) { -			if (e820.map[i].addr >= 0x100000UL && -			    e820.map[i].addr < clip) -				clip = e820.map[i].addr; -			continue; -		} -		start = e820.map[i].addr; -		end = e820.map[i].addr + e820.map[i].size; -		if (start >= end) -			continue; -		if (end > top) -			top = end; -	} -	/* -	 * Everything below 'top' should be RAM except for the ISA hole. -	 * Because of the limited MCR's we want to map NV/ACPI into our -	 * MCR range for gunk in RAM -	 * -	 * Clip might cause us to MCR insufficient RAM but that is an -	 * acceptable failure mode and should only bite obscure boxes with -	 * a VESA hole at 15Mb -	 * -	 * The second case Clip sometimes kicks in is when the EBDA is marked -	 * as reserved. Again we fail safe with reasonable results -	 */ -	if (top > clip) -		top = clip; - -	return top; -} - -/* - * Compute a set of MCR's to give maximum coverage - */ -static int centaur_mcr_compute(int nr, int key) -{ -	u32 mem = ramtop(); -	u32 root = power2(mem); -	u32 base = root; -	u32 top = root; -	u32 floor = 0; -	int ct = 0; - -	while (ct < nr) { -		u32 fspace = 0; -		u32 high; -		u32 low; - -		/* -		 * Find the largest block we will fill going upwards -		 */ -		high = power2(mem-top); - -		/* -		 * Find the largest block we will fill going downwards -		 */ -		low = base/2; - -		/* -		 * Don't fill below 1Mb going downwards as there -		 * is an ISA hole in the way. -		 */ -		if (base <= 1024*1024) -			low = 0; - -		/* -		 * See how much space we could cover by filling below -		 * the ISA hole -		 */ - -		if (floor == 0) -			fspace = 512*1024; -		else if (floor == 512*1024) -			fspace = 128*1024; - -		/* And forget ROM space */ - -		/* -		 * Now install the largest coverage we get -		 */ -		if (fspace > high && fspace > low) { -			centaur_mcr_insert(ct, floor, fspace, key); -			floor += fspace; -		} else if (high > low) { -			centaur_mcr_insert(ct, top, high, key); -			top += high; -		} else if (low > 0) { -			base -= low; -			centaur_mcr_insert(ct, base, low, key); -		} else -			break; -		ct++; -	} -	/* -	 * We loaded ct values. We now need to set the mask. The caller -	 * must do this bit. -	 */ -	return ct; -} - -static void centaur_create_optimal_mcr(void) -{ -	int used; -	int i; - -	/* -	 * Allocate up to 6 mcrs to mark as much of ram as possible -	 * as write combining and weak write ordered. -	 * -	 * To experiment with: Linux never uses stack operations for -	 * mmio spaces so we could globally enable stack operation wc -	 * -	 * Load the registers with type 31 - full write combining, all -	 * writes weakly ordered. -	 */ -	used = centaur_mcr_compute(6, 31); - -	/* -	 * Wipe unused MCRs -	 */ -	for (i = used; i < 8; i++) -		wrmsr(MSR_IDT_MCR0+i, 0, 0); -} - -static void winchip2_create_optimal_mcr(void) -{ -	u32 lo, hi; -	int used; -	int i; - -	/* -	 * Allocate up to 6 mcrs to mark as much of ram as possible -	 * as write combining, weak store ordered. -	 * -	 * Load the registers with type 25 -	 *	8	-	weak write ordering -	 *	16	-	weak read ordering -	 *	1	-	write combining -	 */ -	used = centaur_mcr_compute(6, 25); - -	/* -	 * Mark the registers we are using. -	 */ -	rdmsr(MSR_IDT_MCR_CTRL, lo, hi); -	for (i = 0; i < used; i++) -		lo |= 1<<(9+i); -	wrmsr(MSR_IDT_MCR_CTRL, lo, hi); - -	/* -	 * Wipe unused MCRs -	 */ - -	for (i = used; i < 8; i++) -		wrmsr(MSR_IDT_MCR0+i, 0, 0); -} - -/* - * Handle the MCR key on the Winchip 2. - */ -static void winchip2_unprotect_mcr(void) -{ -	u32 lo, hi; -	u32 key; - -	rdmsr(MSR_IDT_MCR_CTRL, lo, hi); -	lo &= ~0x1C0;	/* blank bits 8-6 */ -	key = (lo>>17) & 7; -	lo |= key<<6;	/* replace with unlock key */ -	wrmsr(MSR_IDT_MCR_CTRL, lo, hi); -} - -static void winchip2_protect_mcr(void) -{ -	u32 lo, hi; - -	rdmsr(MSR_IDT_MCR_CTRL, lo, hi); -	lo &= ~0x1C0;	/* blank bits 8-6 */ -	wrmsr(MSR_IDT_MCR_CTRL, lo, hi); -} -#endif /* CONFIG_X86_OOSTORE */ -  #define ACE_PRESENT	(1 << 6)  #define ACE_ENABLED	(1 << 7)  #define ACE_FCR		(1 << 28)	/* MSR_VIA_FCR */ @@ -362,20 +132,6 @@ static void init_centaur(struct cpuinfo_x86 *c)  			fcr_clr = DPDC;  			printk(KERN_NOTICE "Disabling bugged TSC.\n");  			clear_cpu_cap(c, X86_FEATURE_TSC); -#ifdef CONFIG_X86_OOSTORE -			centaur_create_optimal_mcr(); -			/* -			 * Enable: -			 *	write combining on non-stack, non-string -			 *	write combining on string, all types -			 *	weak write ordering -			 * -			 * The C6 original lacks weak read order -			 * -			 * Note 0x120 is write only on Winchip 1 -			 */ -			wrmsr(MSR_IDT_MCR_CTRL, 0x01F0001F, 0); -#endif  			break;  		case 8:  			switch (c->x86_mask) { @@ -392,40 +148,12 @@ static void init_centaur(struct cpuinfo_x86 *c)  			fcr_set = ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK|  				  E2MMX|EAMD3D;  			fcr_clr = DPDC; -#ifdef CONFIG_X86_OOSTORE -			winchip2_unprotect_mcr(); -			winchip2_create_optimal_mcr(); -			rdmsr(MSR_IDT_MCR_CTRL, lo, hi); -			/* -			 * Enable: -			 *	write combining on non-stack, non-string -			 *	write combining on string, all types -			 *	weak write ordering -			 */ -			lo |= 31; -			wrmsr(MSR_IDT_MCR_CTRL, lo, hi); -			winchip2_protect_mcr(); -#endif  			break;  		case 9:  			name = "3";  			fcr_set = ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK|  				  E2MMX|EAMD3D;  			fcr_clr = DPDC; -#ifdef CONFIG_X86_OOSTORE -			winchip2_unprotect_mcr(); -			winchip2_create_optimal_mcr(); -			rdmsr(MSR_IDT_MCR_CTRL, lo, hi); -			/* -			 * Enable: -			 *	write combining on non-stack, non-string -			 *	write combining on string, all types -			 *	weak write ordering -			 */ -			lo |= 31; -			wrmsr(MSR_IDT_MCR_CTRL, lo, hi); -			winchip2_protect_mcr(); -#endif  			break;  		default:  			name = "??"; diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 24b6fd10625a..8e28bf2fc3ef 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -284,8 +284,13 @@ static __always_inline void setup_smap(struct cpuinfo_x86 *c)  	raw_local_save_flags(eflags);  	BUG_ON(eflags & X86_EFLAGS_AC); -	if (cpu_has(c, X86_FEATURE_SMAP)) +	if (cpu_has(c, X86_FEATURE_SMAP)) { +#ifdef CONFIG_X86_SMAP  		set_in_cr4(X86_CR4_SMAP); +#else +		clear_in_cr4(X86_CR4_SMAP); +#endif +	}  }  /* diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 3db61c644e44..5cd9bfabd645 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -640,21 +640,17 @@ static void intel_tlb_flushall_shift_set(struct cpuinfo_x86 *c)  	case 0x61d: /* six-core 45 nm xeon "Dunnington" */  		tlb_flushall_shift = -1;  		break; +	case 0x63a: /* Ivybridge */ +		tlb_flushall_shift = 2; +		break;  	case 0x61a: /* 45 nm nehalem, "Bloomfield" */  	case 0x61e: /* 45 nm nehalem, "Lynnfield" */  	case 0x625: /* 32 nm nehalem, "Clarkdale" */  	case 0x62c: /* 32 nm nehalem, "Gulftown" */  	case 0x62e: /* 45 nm nehalem-ex, "Beckton" */  	case 0x62f: /* 32 nm Xeon E7 */ -		tlb_flushall_shift = 6; -		break;  	case 0x62a: /* SandyBridge */  	case 0x62d: /* SandyBridge, "Romely-EP" */ -		tlb_flushall_shift = 5; -		break; -	case 0x63a: /* Ivybridge */ -		tlb_flushall_shift = 1; -		break;  	default:  		tlb_flushall_shift = 6;  	} diff --git a/arch/x86/kernel/cpu/microcode/amd_early.c b/arch/x86/kernel/cpu/microcode/amd_early.c index 8384c0fa206f..617a9e284245 100644 --- a/arch/x86/kernel/cpu/microcode/amd_early.c +++ b/arch/x86/kernel/cpu/microcode/amd_early.c @@ -285,6 +285,15 @@ static void __init collect_cpu_sig_on_bsp(void *arg)  	uci->cpu_sig.sig = cpuid_eax(0x00000001);  } + +static void __init get_bsp_sig(void) +{ +	unsigned int bsp = boot_cpu_data.cpu_index; +	struct ucode_cpu_info *uci = ucode_cpu_info + bsp; + +	if (!uci->cpu_sig.sig) +		smp_call_function_single(bsp, collect_cpu_sig_on_bsp, NULL, 1); +}  #else  void load_ucode_amd_ap(void)  { @@ -337,31 +346,37 @@ void load_ucode_amd_ap(void)  int __init save_microcode_in_initrd_amd(void)  { +	unsigned long cont;  	enum ucode_state ret;  	u32 eax; -#ifdef CONFIG_X86_32 -	unsigned int bsp = boot_cpu_data.cpu_index; -	struct ucode_cpu_info *uci = ucode_cpu_info + bsp; - -	if (!uci->cpu_sig.sig) -		smp_call_function_single(bsp, collect_cpu_sig_on_bsp, NULL, 1); +	if (!container) +		return -EINVAL; +#ifdef CONFIG_X86_32 +	get_bsp_sig(); +	cont = (unsigned long)container; +#else  	/* -	 * Take into account the fact that the ramdisk might get relocated -	 * and therefore we need to recompute the container's position in -	 * virtual memory space. +	 * We need the physical address of the container for both bitness since +	 * boot_params.hdr.ramdisk_image is a physical address.  	 */ -	container = (u8 *)(__va((u32)relocated_ramdisk) + -			   ((u32)container - boot_params.hdr.ramdisk_image)); +	cont = __pa(container);  #endif + +	/* +	 * Take into account the fact that the ramdisk might get relocated and +	 * therefore we need to recompute the container's position in virtual +	 * memory space. +	 */ +	if (relocated_ramdisk) +		container = (u8 *)(__va(relocated_ramdisk) + +			     (cont - boot_params.hdr.ramdisk_image)); +  	if (ucode_new_rev)  		pr_info("microcode: updated early to new patch_level=0x%08x\n",  			ucode_new_rev); -	if (!container) -		return -EINVAL; -  	eax   = cpuid_eax(0x00000001);  	eax   = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff); diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index ce2d0a2c3e4f..0e25a1bc5ab5 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -683,7 +683,7 @@ static void prepare_set(void) __acquires(set_atomicity_lock)  	}  	/* Flush all TLBs via a mov %cr3, %reg; mov %reg, %cr3 */ -	count_vm_event(NR_TLB_LOCAL_FLUSH_ALL); +	count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL);  	__flush_tlb();  	/* Save MTRR state */ @@ -697,7 +697,7 @@ static void prepare_set(void) __acquires(set_atomicity_lock)  static void post_set(void) __releases(set_atomicity_lock)  {  	/* Flush TLBs (no need to flush caches - they are disabled) */ -	count_vm_event(NR_TLB_LOCAL_FLUSH_ALL); +	count_vm_tlb_event(NR_TLB_LOCAL_FLUSH_ALL);  	__flush_tlb();  	/* Intel (P6) standard MTRRs */ diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index b88645191fe5..79f9f848bee4 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1192,6 +1192,9 @@ static void x86_pmu_del(struct perf_event *event, int flags)  	for (i = 0; i < cpuc->n_events; i++) {  		if (event == cpuc->event_list[i]) { +			if (i >= cpuc->n_events - cpuc->n_added) +				--cpuc->n_added; +  			if (x86_pmu.put_event_constraints)  				x86_pmu.put_event_constraints(cpuc, event); @@ -1521,6 +1524,8 @@ static int __init init_hw_perf_events(void)  	pr_cont("%s PMU driver.\n", x86_pmu.name); +	x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */ +  	for (quirk = x86_pmu.quirks; quirk; quirk = quirk->next)  		quirk->func(); @@ -1534,7 +1539,6 @@ static int __init init_hw_perf_events(void)  		__EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1,  				   0, x86_pmu.num_counters, 0, 0); -	x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */  	x86_pmu_format_group.attrs = x86_pmu.format_attrs;  	if (x86_pmu.event_attrs) @@ -1820,9 +1824,12 @@ static ssize_t set_attr_rdpmc(struct device *cdev,  	if (ret)  		return ret; +	if (x86_pmu.attr_rdpmc_broken) +		return -ENOTSUPP; +  	if (!!val != !!x86_pmu.attr_rdpmc) {  		x86_pmu.attr_rdpmc = !!val; -		smp_call_function(change_rdpmc, (void *)val, 1); +		on_each_cpu(change_rdpmc, (void *)val, 1);  	}  	return count; diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index c1a861829d81..4972c244d0bc 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h @@ -409,6 +409,7 @@ struct x86_pmu {  	/*  	 * sysfs attrs  	 */ +	int		attr_rdpmc_broken;  	int		attr_rdpmc;  	struct attribute **format_attrs;  	struct attribute **event_attrs; diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 0fa4f242f050..aa333d966886 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -1361,10 +1361,8 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)  	intel_pmu_disable_all();  	handled = intel_pmu_drain_bts_buffer();  	status = intel_pmu_get_status(); -	if (!status) { -		intel_pmu_enable_all(0); -		return handled; -	} +	if (!status) +		goto done;  	loops = 0;  again: @@ -2310,10 +2308,7 @@ __init int intel_pmu_init(void)  	if (version > 1)  		x86_pmu.num_counters_fixed = max((int)edx.split.num_counters_fixed, 3); -	/* -	 * v2 and above have a perf capabilities MSR -	 */ -	if (version > 1) { +	if (boot_cpu_has(X86_FEATURE_PDCM)) {  		u64 capabilities;  		rdmsrl(MSR_IA32_PERF_CAPABILITIES, capabilities); diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index 29c248799ced..047f540cf3f7 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -501,8 +501,11 @@ static struct extra_reg snbep_uncore_cbox_extra_regs[] = {  	SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,  				  SNBEP_CBO_PMON_CTL_TID_EN, 0x1),  	SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4), +	SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0x6),  	SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4), +	SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0x6),  	SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4), +	SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0x6),  	SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0x6),  	SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x8),  	SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x8), @@ -1178,10 +1181,15 @@ static struct extra_reg ivt_uncore_cbox_extra_regs[] = {  	SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN,  				  SNBEP_CBO_PMON_CTL_TID_EN, 0x1),  	SNBEP_CBO_EVENT_EXTRA_REG(0x1031, 0x10ff, 0x2), +	SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4), +	SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0xc), +	SNBEP_CBO_EVENT_EXTRA_REG(0x5134, 0xffff, 0xc),  	SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4), +	SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0xc),  	SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4), +	SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0xc),  	SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4), -	SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0xc), +	SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0xc),  	SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x10),  	SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x10),  	SNBEP_CBO_EVENT_EXTRA_REG(0x2135, 0xffff, 0x10), @@ -3326,6 +3334,8 @@ static int __init uncore_type_init(struct intel_uncore_type *type)  	if (!pmus)  		return -ENOMEM; +	type->pmus = pmus; +  	type->unconstrainted = (struct event_constraint)  		__EVENT_CONSTRAINT(0, (1ULL << type->num_counters) - 1,  				0, type->num_counters, 0, 0); @@ -3361,7 +3371,6 @@ static int __init uncore_type_init(struct intel_uncore_type *type)  	}  	type->pmu_group = &uncore_pmu_attr_group; -	type->pmus = pmus;  	return 0;  fail:  	uncore_type_exit(type); diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c index b1e2fe115323..7c1a0c07b607 100644 --- a/arch/x86/kernel/cpu/perf_event_p6.c +++ b/arch/x86/kernel/cpu/perf_event_p6.c @@ -231,31 +231,49 @@ static __initconst const struct x86_pmu p6_pmu = {  }; +static __init void p6_pmu_rdpmc_quirk(void) +{ +	if (boot_cpu_data.x86_mask < 9) { +		/* +		 * PPro erratum 26; fixed in stepping 9 and above. +		 */ +		pr_warn("Userspace RDPMC support disabled due to a CPU erratum\n"); +		x86_pmu.attr_rdpmc_broken = 1; +		x86_pmu.attr_rdpmc = 0; +	} +} +  __init int p6_pmu_init(void)  { +	x86_pmu = p6_pmu; +  	switch (boot_cpu_data.x86_model) { -	case 1: -	case 3:  /* Pentium Pro */ -	case 5: -	case 6:  /* Pentium II */ -	case 7: -	case 8: -	case 11: /* Pentium III */ -	case 9: -	case 13: -		/* Pentium M */ +	case  1: /* Pentium Pro */ +		x86_add_quirk(p6_pmu_rdpmc_quirk); +		break; + +	case  3: /* Pentium II - Klamath */ +	case  5: /* Pentium II - Deschutes */ +	case  6: /* Pentium II - Mendocino */  		break; + +	case  7: /* Pentium III - Katmai */ +	case  8: /* Pentium III - Coppermine */ +	case 10: /* Pentium III Xeon */ +	case 11: /* Pentium III - Tualatin */ +		break; + +	case  9: /* Pentium M - Banias */ +	case 13: /* Pentium M - Dothan */ +		break; +  	default: -		pr_cont("unsupported p6 CPU model %d ", -			boot_cpu_data.x86_model); +		pr_cont("unsupported p6 CPU model %d ", boot_cpu_data.x86_model);  		return -ENODEV;  	} -	x86_pmu = p6_pmu; -  	memcpy(hw_cache_event_ids, p6_hw_cache_event_ids,  		sizeof(hw_cache_event_ids)); -  	return 0;  } diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index d4bdd253fea7..e6253195a301 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -77,8 +77,7 @@ within(unsigned long addr, unsigned long start, unsigned long end)  	return addr >= start && addr < end;  } -static int -do_ftrace_mod_code(unsigned long ip, const void *new_code) +static unsigned long text_ip_addr(unsigned long ip)  {  	/*  	 * On x86_64, kernel text mappings are mapped read-only with @@ -91,7 +90,7 @@ do_ftrace_mod_code(unsigned long ip, const void *new_code)  	if (within(ip, (unsigned long)_text, (unsigned long)_etext))  		ip = (unsigned long)__va(__pa_symbol(ip)); -	return probe_kernel_write((void *)ip, new_code, MCOUNT_INSN_SIZE); +	return ip;  }  static const unsigned char *ftrace_nop_replace(void) @@ -123,8 +122,10 @@ ftrace_modify_code_direct(unsigned long ip, unsigned const char *old_code,  	if (memcmp(replaced, old_code, MCOUNT_INSN_SIZE) != 0)  		return -EINVAL; +	ip = text_ip_addr(ip); +  	/* replace the text with the new text */ -	if (do_ftrace_mod_code(ip, new_code)) +	if (probe_kernel_write((void *)ip, new_code, MCOUNT_INSN_SIZE))  		return -EPERM;  	sync_core(); @@ -221,37 +222,51 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,  	return -EINVAL;  } -int ftrace_update_ftrace_func(ftrace_func_t func) +static unsigned long ftrace_update_func; + +static int update_ftrace_func(unsigned long ip, void *new)  { -	unsigned long ip = (unsigned long)(&ftrace_call); -	unsigned char old[MCOUNT_INSN_SIZE], *new; +	unsigned char old[MCOUNT_INSN_SIZE];  	int ret; -	memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE); -	new = ftrace_call_replace(ip, (unsigned long)func); +	memcpy(old, (void *)ip, MCOUNT_INSN_SIZE); + +	ftrace_update_func = ip; +	/* Make sure the breakpoints see the ftrace_update_func update */ +	smp_wmb();  	/* See comment above by declaration of modifying_ftrace_code */  	atomic_inc(&modifying_ftrace_code);  	ret = ftrace_modify_code(ip, old, new); +	atomic_dec(&modifying_ftrace_code); + +	return ret; +} + +int ftrace_update_ftrace_func(ftrace_func_t func) +{ +	unsigned long ip = (unsigned long)(&ftrace_call); +	unsigned char *new; +	int ret; + +	new = ftrace_call_replace(ip, (unsigned long)func); +	ret = update_ftrace_func(ip, new); +  	/* Also update the regs callback function */  	if (!ret) {  		ip = (unsigned long)(&ftrace_regs_call); -		memcpy(old, &ftrace_regs_call, MCOUNT_INSN_SIZE);  		new = ftrace_call_replace(ip, (unsigned long)func); -		ret = ftrace_modify_code(ip, old, new); +		ret = update_ftrace_func(ip, new);  	} -	atomic_dec(&modifying_ftrace_code); -  	return ret;  }  static int is_ftrace_caller(unsigned long ip)  { -	if (ip == (unsigned long)(&ftrace_call) || -		ip == (unsigned long)(&ftrace_regs_call)) +	if (ip == ftrace_update_func)  		return 1;  	return 0; @@ -677,45 +692,41 @@ int __init ftrace_dyn_arch_init(void *data)  #ifdef CONFIG_DYNAMIC_FTRACE  extern void ftrace_graph_call(void); -static int ftrace_mod_jmp(unsigned long ip, -			  int old_offset, int new_offset) +static unsigned char *ftrace_jmp_replace(unsigned long ip, unsigned long addr)  { -	unsigned char code[MCOUNT_INSN_SIZE]; +	static union ftrace_code_union calc; -	if (probe_kernel_read(code, (void *)ip, MCOUNT_INSN_SIZE)) -		return -EFAULT; +	/* Jmp not a call (ignore the .e8) */ +	calc.e8		= 0xe9; +	calc.offset	= ftrace_calc_offset(ip + MCOUNT_INSN_SIZE, addr); -	if (code[0] != 0xe9 || old_offset != *(int *)(&code[1])) -		return -EINVAL; +	/* +	 * ftrace external locks synchronize the access to the static variable. +	 */ +	return calc.code; +} -	*(int *)(&code[1]) = new_offset; +static int ftrace_mod_jmp(unsigned long ip, void *func) +{ +	unsigned char *new; -	if (do_ftrace_mod_code(ip, &code)) -		return -EPERM; +	new = ftrace_jmp_replace(ip, (unsigned long)func); -	return 0; +	return update_ftrace_func(ip, new);  }  int ftrace_enable_ftrace_graph_caller(void)  {  	unsigned long ip = (unsigned long)(&ftrace_graph_call); -	int old_offset, new_offset; -	old_offset = (unsigned long)(&ftrace_stub) - (ip + MCOUNT_INSN_SIZE); -	new_offset = (unsigned long)(&ftrace_graph_caller) - (ip + MCOUNT_INSN_SIZE); - -	return ftrace_mod_jmp(ip, old_offset, new_offset); +	return ftrace_mod_jmp(ip, &ftrace_graph_caller);  }  int ftrace_disable_ftrace_graph_caller(void)  {  	unsigned long ip = (unsigned long)(&ftrace_graph_call); -	int old_offset, new_offset; - -	old_offset = (unsigned long)(&ftrace_graph_caller) - (ip + MCOUNT_INSN_SIZE); -	new_offset = (unsigned long)(&ftrace_stub) - (ip + MCOUNT_INSN_SIZE); -	return ftrace_mod_jmp(ip, old_offset, new_offset); +	return ftrace_mod_jmp(ip, &ftrace_stub);  }  #endif /* !CONFIG_DYNAMIC_FTRACE */ diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 81ba27679f18..f36bd42d6f0c 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -544,6 +544,10 @@ ENDPROC(early_idt_handlers)  	/* This is global to keep gas from relaxing the jumps */  ENTRY(early_idt_handler)  	cld + +	cmpl $2,(%esp)		# X86_TRAP_NMI +	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) diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index e1aabdb314c8..a468c0a65c42 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -343,6 +343,9 @@ early_idt_handlers:  ENTRY(early_idt_handler)  	cld +	cmpl $2,(%rsp)		# X86_TRAP_NMI +	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) diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index e8368c6dd2a2..d5dd80814419 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c @@ -86,10 +86,19 @@ EXPORT_SYMBOL(__kernel_fpu_begin);  void __kernel_fpu_end(void)  { -	if (use_eager_fpu()) -		math_state_restore(); -	else +	if (use_eager_fpu()) { +		/* +		 * For eager fpu, most the time, tsk_used_math() is true. +		 * Restore the user math as we are done with the kernel usage. +		 * At few instances during thread exit, signal handling etc, +		 * tsk_used_math() is false. Those few places will take proper +		 * actions, so we don't need to restore the math here. +		 */ +		if (likely(tsk_used_math(current))) +			math_state_restore(); +	} else {  		stts(); +	}  }  EXPORT_SYMBOL(__kernel_fpu_end); diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index dbb60878b744..d99f31d9a750 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -266,6 +266,14 @@ __visible void smp_trace_x86_platform_ipi(struct pt_regs *regs)  EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq);  #ifdef CONFIG_HOTPLUG_CPU + +/* These two declarations are only used in check_irq_vectors_for_cpu_disable() + * below, which is protected by stop_machine().  Putting them on the stack + * results in a stack frame overflow.  Dynamically allocating could result in a + * failure so declare these two cpumasks as global. + */ +static struct cpumask affinity_new, online_new; +  /*   * This cpu is going to be removed and its vectors migrated to the remaining   * online cpus.  Check to see if there are enough vectors in the remaining cpus. @@ -277,7 +285,6 @@ int check_irq_vectors_for_cpu_disable(void)  	unsigned int this_cpu, vector, this_count, count;  	struct irq_desc *desc;  	struct irq_data *data; -	struct cpumask affinity_new, online_new;  	this_cpu = smp_processor_id();  	cpumask_copy(&online_new, cpu_online_mask); diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c index 4eabc160696f..679cef0791cd 100644 --- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c @@ -279,5 +279,7 @@ void arch_crash_save_vmcoreinfo(void)  	VMCOREINFO_SYMBOL(node_data);  	VMCOREINFO_LENGTH(node_data, MAX_NUMNODES);  #endif +	vmcoreinfo_append_str("KERNELOFFSET=%lx\n", +			      (unsigned long)&_text - __START_KERNEL);  } diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 872079a67e4d..f7d0672481fd 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -100,8 +100,10 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size,  	flag |= __GFP_ZERO;  again:  	page = NULL; -	if (!(flag & GFP_ATOMIC)) +	/* CMA can be used only in the context which permits sleeping */ +	if (flag & __GFP_WAIT)  		page = dma_alloc_from_contiguous(dev, count, get_order(size)); +	/* fallback */  	if (!page)  		page = alloc_pages_node(dev_to_node(dev), flag, get_order(size));  	if (!page) diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c index 04ee1e2e4c02..ff898bbf579d 100644 --- a/arch/x86/kernel/quirks.c +++ b/arch/x86/kernel/quirks.c @@ -529,7 +529,7 @@ static void quirk_amd_nb_node(struct pci_dev *dev)  		return;  	pci_read_config_dword(nb_ht, 0x60, &val); -	node = val & 7; +	node = pcibus_to_node(dev->bus) | (val & 7);  	/*  	 * Some hardware may return an invalid node ID,  	 * so check it first: @@ -571,3 +571,40 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F5,  			quirk_amd_nb_node);  #endif + +#ifdef CONFIG_PCI +/* + * Processor does not ensure DRAM scrub read/write sequence + * is atomic wrt accesses to CC6 save state area. Therefore + * if a concurrent scrub read/write access is to same address + * the entry may appear as if it is not written. This quirk + * applies to Fam16h models 00h-0Fh + * + * See "Revision Guide" for AMD F16h models 00h-0fh, + * document 51810 rev. 3.04, Nov 2013 + */ +static void amd_disable_seq_and_redirect_scrub(struct pci_dev *dev) +{ +	u32 val; + +	/* +	 * Suggested workaround: +	 * set D18F3x58[4:0] = 00h and set D18F3x5C[0] = 0b +	 */ +	pci_read_config_dword(dev, 0x58, &val); +	if (val & 0x1F) { +		val &= ~(0x1F); +		pci_write_config_dword(dev, 0x58, val); +	} + +	pci_read_config_dword(dev, 0x5C, &val); +	if (val & BIT(0)) { +		val &= ~BIT(0); +		pci_write_config_dword(dev, 0x5c, val); +	} +} + +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F3, +			amd_disable_seq_and_redirect_scrub); + +#endif diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 06853e670354..ce72964b2f46 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -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  } diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 19e5adb49a27..cfbe99f88830 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -209,7 +209,7 @@ static inline unsigned long long cycles_2_ns(unsigned long long cyc)  	 * dance when its actually needed.  	 */ -	preempt_disable(); +	preempt_disable_notrace();  	data = this_cpu_read(cyc2ns.head);  	tail = this_cpu_read(cyc2ns.tail); @@ -229,7 +229,7 @@ static inline unsigned long long cycles_2_ns(unsigned long long cyc)  		if (!--data->__count)  			this_cpu_write(cyc2ns.tail, data);  	} -	preempt_enable(); +	preempt_enable_notrace();  	return ns;  } @@ -653,13 +653,10 @@ unsigned long native_calibrate_tsc(void)  	/* Calibrate TSC using MSR for Intel Atom SoCs */  	local_irq_save(flags); -	i = try_msr_calibrate_tsc(&fast_calibrate); +	fast_calibrate = try_msr_calibrate_tsc();  	local_irq_restore(flags); -	if (i >= 0) { -		if (i == 0) -			pr_warn("Fast TSC calibration using MSR failed\n"); +	if (fast_calibrate)  		return fast_calibrate; -	}  	local_irq_save(flags);  	fast_calibrate = quick_pit_calibrate(); diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c index 8b5434f4389f..92ae6acac8a7 100644 --- a/arch/x86/kernel/tsc_msr.c +++ b/arch/x86/kernel/tsc_msr.c @@ -53,7 +53,7 @@ static struct freq_desc freq_desc_tables[] = {  	/* TNG */  	{ 6, 0x4a, 1, { 0, FREQ_100, FREQ_133, 0, 0, 0, 0, 0 } },  	/* VLV2 */ -	{ 6, 0x37, 1, { 0, FREQ_100, FREQ_133, FREQ_166, 0, 0, 0, 0 } }, +	{ 6, 0x37, 1, { FREQ_83, FREQ_100, FREQ_133, FREQ_166, 0, 0, 0, 0 } },  	/* ANN */  	{ 6, 0x5a, 1, { FREQ_83, FREQ_100, FREQ_133, FREQ_100, 0, 0, 0, 0 } },  }; @@ -77,21 +77,18 @@ static int match_cpu(u8 family, u8 model)  /*   * Do MSR calibration only for known/supported CPUs. - * Return values: - * -1: CPU is unknown/unsupported for MSR based calibration - *  0: CPU is known/supported, but calibration failed - *  1: CPU is known/supported, and calibration succeeded + * + * Returns the calibration value or 0 if MSR calibration failed.   */ -int try_msr_calibrate_tsc(unsigned long *fast_calibrate) +unsigned long try_msr_calibrate_tsc(void)  { -	int cpu_index;  	u32 lo, hi, ratio, freq_id, freq; +	unsigned long res; +	int cpu_index;  	cpu_index = match_cpu(boot_cpu_data.x86, boot_cpu_data.x86_model);  	if (cpu_index < 0) -		return -1; - -	*fast_calibrate = 0; +		return 0;  	if (freq_desc_tables[cpu_index].msr_plat) {  		rdmsr(MSR_PLATFORM_INFO, lo, hi); @@ -103,7 +100,7 @@ int try_msr_calibrate_tsc(unsigned long *fast_calibrate)  	pr_info("Maximum core-clock to bus-clock ratio: 0x%x\n", ratio);  	if (!ratio) -		return 0; +		goto fail;  	/* Get FSB FREQ ID */  	rdmsr(MSR_FSB_FREQ, lo, hi); @@ -112,16 +109,19 @@ int try_msr_calibrate_tsc(unsigned long *fast_calibrate)  	pr_info("Resolved frequency ID: %u, frequency: %u KHz\n",  				freq_id, freq);  	if (!freq) -		return 0; +		goto fail;  	/* TSC frequency = maximum resolved freq * maximum resolved bus ratio */ -	*fast_calibrate = freq * ratio; -	pr_info("TSC runs at %lu KHz\n", *fast_calibrate); +	res = freq * ratio; +	pr_info("TSC runs at %lu KHz\n", res);  #ifdef CONFIG_X86_LOCAL_APIC  	lapic_timer_frequency = (freq * 1000) / HZ;  	pr_info("lapic_timer_frequency = %d\n", lapic_timer_frequency);  #endif +	return res; -	return 1; +fail: +	pr_warn("Fast TSC calibration using MSR failed\n"); +	return 0;  }  | 
