aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386')
-rw-r--r--arch/i386/Kconfig14
-rw-r--r--arch/i386/boot/video.S2
-rw-r--r--arch/i386/defconfig7
-rw-r--r--arch/i386/kernel/apm.c36
-rw-r--r--arch/i386/kernel/crash.c10
-rw-r--r--arch/i386/kernel/efi.c4
-rw-r--r--arch/i386/kernel/i8237.c5
-rw-r--r--arch/i386/kernel/microcode.c774
-rw-r--r--arch/i386/kernel/nmi.c4
-rw-r--r--arch/i386/kernel/process.c5
-rw-r--r--arch/i386/kernel/setup.c36
-rw-r--r--arch/i386/kernel/smp.c27
-rw-r--r--arch/i386/kernel/smpboot.c7
-rw-r--r--arch/i386/kernel/srat.c104
-rw-r--r--arch/i386/kernel/time.c3
-rw-r--r--arch/i386/kernel/traps.c9
-rw-r--r--arch/i386/lib/delay.c1
-rw-r--r--arch/i386/lib/usercopy.c2
-rw-r--r--arch/i386/mach-voyager/voyager_smp.c7
-rw-r--r--arch/i386/mm/discontig.c69
-rw-r--r--arch/i386/mm/fault.c4
-rw-r--r--arch/i386/mm/highmem.c18
-rw-r--r--arch/i386/mm/init.c1
-rw-r--r--arch/i386/mm/ioremap.c84
-rw-r--r--arch/i386/oprofile/op_model_ppro.c20
-rw-r--r--arch/i386/pci/mmconfig.c5
26 files changed, 681 insertions, 577 deletions
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 758044f5e718..3fd2f256f2be 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -401,6 +401,7 @@ config X86_REBOOTFIXUPS
401 401
402config MICROCODE 402config MICROCODE
403 tristate "/dev/cpu/microcode - Intel IA32 CPU microcode support" 403 tristate "/dev/cpu/microcode - Intel IA32 CPU microcode support"
404 select FW_LOADER
404 ---help--- 405 ---help---
405 If you say Y here and also to "/dev file system support" in the 406 If you say Y here and also to "/dev file system support" in the
406 'File systems' section, you will be able to update the microcode on 407 'File systems' section, you will be able to update the microcode on
@@ -416,6 +417,11 @@ config MICROCODE
416 To compile this driver as a module, choose M here: the 417 To compile this driver as a module, choose M here: the
417 module will be called microcode. 418 module will be called microcode.
418 419
420config MICROCODE_OLD_INTERFACE
421 bool
422 depends on MICROCODE
423 default y
424
419config X86_MSR 425config X86_MSR
420 tristate "/dev/cpu/*/msr - Model-specific register support" 426 tristate "/dev/cpu/*/msr - Model-specific register support"
421 help 427 help
@@ -598,12 +604,10 @@ config ARCH_SELECT_MEMORY_MODEL
598 def_bool y 604 def_bool y
599 depends on ARCH_SPARSEMEM_ENABLE 605 depends on ARCH_SPARSEMEM_ENABLE
600 606
601source "mm/Kconfig" 607config ARCH_POPULATES_NODE_MAP
608 def_bool y
602 609
603config HAVE_ARCH_EARLY_PFN_TO_NID 610source "mm/Kconfig"
604 bool
605 default y
606 depends on NUMA
607 611
608config HIGHPTE 612config HIGHPTE
609 bool "Allocate 3rd-level pagetables from highmem" 613 bool "Allocate 3rd-level pagetables from highmem"
diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S
index 8c2a6faeeae5..2c5b5cc55f79 100644
--- a/arch/i386/boot/video.S
+++ b/arch/i386/boot/video.S
@@ -11,8 +11,6 @@
11 * 11 *
12 */ 12 */
13 13
14#include <linux/config.h> /* for CONFIG_VIDEO_* */
15
16/* Enable autodetection of SVGA adapters and modes. */ 14/* Enable autodetection of SVGA adapters and modes. */
17#undef CONFIG_VIDEO_SVGA 15#undef CONFIG_VIDEO_SVGA
18 16
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index 1a29bfa26d0c..ee2d79bd8af7 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.18-git5 3# Linux kernel version: 2.6.18-git7
4# Tue Sep 26 09:30:47 2006 4# Wed Sep 27 21:53:10 2006
5# 5#
6CONFIG_X86_32=y 6CONFIG_X86_32=y
7CONFIG_GENERIC_TIME=y 7CONFIG_GENERIC_TIME=y
@@ -210,6 +210,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
210CONFIG_PM=y 210CONFIG_PM=y
211CONFIG_PM_LEGACY=y 211CONFIG_PM_LEGACY=y
212# CONFIG_PM_DEBUG is not set 212# CONFIG_PM_DEBUG is not set
213CONFIG_PM_SYSFS_DEPRECATED=y
213 214
214# 215#
215# ACPI (Advanced Configuration and Power Interface) Support 216# ACPI (Advanced Configuration and Power Interface) Support
@@ -292,6 +293,7 @@ CONFIG_PCI_DIRECT=y
292CONFIG_PCI_MMCONFIG=y 293CONFIG_PCI_MMCONFIG=y
293# CONFIG_PCIEPORTBUS is not set 294# CONFIG_PCIEPORTBUS is not set
294CONFIG_PCI_MSI=y 295CONFIG_PCI_MSI=y
296# CONFIG_PCI_MULTITHREAD_PROBE is not set
295# CONFIG_PCI_DEBUG is not set 297# CONFIG_PCI_DEBUG is not set
296CONFIG_ISA_DMA_API=y 298CONFIG_ISA_DMA_API=y
297# CONFIG_ISA is not set 299# CONFIG_ISA is not set
@@ -1427,6 +1429,7 @@ CONFIG_KPROBES=y
1427# 1429#
1428CONFIG_TRACE_IRQFLAGS_SUPPORT=y 1430CONFIG_TRACE_IRQFLAGS_SUPPORT=y
1429# CONFIG_PRINTK_TIME is not set 1431# CONFIG_PRINTK_TIME is not set
1432# CONFIG_ENABLE_MUST_CHECK is not set
1430CONFIG_MAGIC_SYSRQ=y 1433CONFIG_MAGIC_SYSRQ=y
1431CONFIG_UNUSED_SYMBOLS=y 1434CONFIG_UNUSED_SYMBOLS=y
1432CONFIG_DEBUG_KERNEL=y 1435CONFIG_DEBUG_KERNEL=y
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index ff9ce4b5eaa8..b42f2d914af3 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -225,6 +225,7 @@
225#include <linux/smp_lock.h> 225#include <linux/smp_lock.h>
226#include <linux/dmi.h> 226#include <linux/dmi.h>
227#include <linux/suspend.h> 227#include <linux/suspend.h>
228#include <linux/kthread.h>
228 229
229#include <asm/system.h> 230#include <asm/system.h>
230#include <asm/uaccess.h> 231#include <asm/uaccess.h>
@@ -402,8 +403,6 @@ static int realmode_power_off = 1;
402#else 403#else
403static int realmode_power_off; 404static int realmode_power_off;
404#endif 405#endif
405static int exit_kapmd __read_mostly;
406static int kapmd_running __read_mostly;
407#ifdef CONFIG_APM_ALLOW_INTS 406#ifdef CONFIG_APM_ALLOW_INTS
408static int allow_ints = 1; 407static int allow_ints = 1;
409#else 408#else
@@ -419,6 +418,8 @@ static const struct desc_struct bad_bios_desc = { 0, 0x00409200 };
419 418
420static const char driver_version[] = "1.16ac"; /* no spaces */ 419static const char driver_version[] = "1.16ac"; /* no spaces */
421 420
421static struct task_struct *kapmd_task;
422
422/* 423/*
423 * APM event names taken from the APM 1.2 specification. These are 424 * APM event names taken from the APM 1.2 specification. These are
424 * the message codes that the BIOS uses to tell us about events 425 * the message codes that the BIOS uses to tell us about events
@@ -1423,7 +1424,7 @@ static void apm_mainloop(void)
1423 set_current_state(TASK_INTERRUPTIBLE); 1424 set_current_state(TASK_INTERRUPTIBLE);
1424 for (;;) { 1425 for (;;) {
1425 schedule_timeout(APM_CHECK_TIMEOUT); 1426 schedule_timeout(APM_CHECK_TIMEOUT);
1426 if (exit_kapmd) 1427 if (kthread_should_stop())
1427 break; 1428 break;
1428 /* 1429 /*
1429 * Ok, check all events, check for idle (and mark us sleeping 1430 * Ok, check all events, check for idle (and mark us sleeping
@@ -1706,12 +1707,6 @@ static int apm(void *unused)
1706 char * power_stat; 1707 char * power_stat;
1707 char * bat_stat; 1708 char * bat_stat;
1708 1709
1709 kapmd_running = 1;
1710
1711 daemonize("kapmd");
1712
1713 current->flags |= PF_NOFREEZE;
1714
1715#ifdef CONFIG_SMP 1710#ifdef CONFIG_SMP
1716 /* 2002/08/01 - WT 1711 /* 2002/08/01 - WT
1717 * This is to avoid random crashes at boot time during initialization 1712 * This is to avoid random crashes at boot time during initialization
@@ -1821,7 +1816,6 @@ static int apm(void *unused)
1821 console_blank_hook = NULL; 1816 console_blank_hook = NULL;
1822#endif 1817#endif
1823 } 1818 }
1824 kapmd_running = 0;
1825 1819
1826 return 0; 1820 return 0;
1827} 1821}
@@ -2220,7 +2214,7 @@ static int __init apm_init(void)
2220{ 2214{
2221 struct proc_dir_entry *apm_proc; 2215 struct proc_dir_entry *apm_proc;
2222 struct desc_struct *gdt; 2216 struct desc_struct *gdt;
2223 int ret; 2217 int err;
2224 2218
2225 dmi_check_system(apm_dmi_table); 2219 dmi_check_system(apm_dmi_table);
2226 2220
@@ -2329,12 +2323,17 @@ static int __init apm_init(void)
2329 if (apm_proc) 2323 if (apm_proc)
2330 apm_proc->owner = THIS_MODULE; 2324 apm_proc->owner = THIS_MODULE;
2331 2325
2332 ret = kernel_thread(apm, NULL, CLONE_KERNEL | SIGCHLD); 2326 kapmd_task = kthread_create(apm, NULL, "kapmd");
2333 if (ret < 0) { 2327 if (IS_ERR(kapmd_task)) {
2334 printk(KERN_ERR "apm: disabled - Unable to start kernel thread.\n"); 2328 printk(KERN_ERR "apm: disabled - Unable to start kernel "
2329 "thread.\n");
2330 err = PTR_ERR(kapmd_task);
2331 kapmd_task = NULL;
2335 remove_proc_entry("apm", NULL); 2332 remove_proc_entry("apm", NULL);
2336 return -ENOMEM; 2333 return err;
2337 } 2334 }
2335 kapmd_task->flags |= PF_NOFREEZE;
2336 wake_up_process(kapmd_task);
2338 2337
2339 if (num_online_cpus() > 1 && !smp ) { 2338 if (num_online_cpus() > 1 && !smp ) {
2340 printk(KERN_NOTICE 2339 printk(KERN_NOTICE
@@ -2384,9 +2383,10 @@ static void __exit apm_exit(void)
2384 remove_proc_entry("apm", NULL); 2383 remove_proc_entry("apm", NULL);
2385 if (power_off) 2384 if (power_off)
2386 pm_power_off = NULL; 2385 pm_power_off = NULL;
2387 exit_kapmd = 1; 2386 if (kapmd_task) {
2388 while (kapmd_running) 2387 kthread_stop(kapmd_task);
2389 schedule(); 2388 kapmd_task = NULL;
2389 }
2390#ifdef CONFIG_PM_LEGACY 2390#ifdef CONFIG_PM_LEGACY
2391 pm_active = 0; 2391 pm_active = 0;
2392#endif 2392#endif
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c
index 67d297dc1003..144b43288965 100644
--- a/arch/i386/kernel/crash.c
+++ b/arch/i386/kernel/crash.c
@@ -23,6 +23,7 @@
23#include <asm/hw_irq.h> 23#include <asm/hw_irq.h>
24#include <asm/apic.h> 24#include <asm/apic.h>
25#include <asm/kdebug.h> 25#include <asm/kdebug.h>
26#include <asm/smp.h>
26 27
27#include <mach_ipi.h> 28#include <mach_ipi.h>
28 29
@@ -88,7 +89,7 @@ static void crash_save_self(struct pt_regs *regs)
88{ 89{
89 int cpu; 90 int cpu;
90 91
91 cpu = smp_processor_id(); 92 cpu = safe_smp_processor_id();
92 crash_save_this_cpu(regs, cpu); 93 crash_save_this_cpu(regs, cpu);
93} 94}
94 95
@@ -133,7 +134,10 @@ static int crash_nmi_callback(struct notifier_block *self,
133 134
134static void smp_send_nmi_allbutself(void) 135static void smp_send_nmi_allbutself(void)
135{ 136{
136 send_IPI_allbutself(NMI_VECTOR); 137 cpumask_t mask = cpu_online_map;
138 cpu_clear(safe_smp_processor_id(), mask);
139 if (!cpus_empty(mask))
140 send_IPI_mask(mask, NMI_VECTOR);
137} 141}
138 142
139static struct notifier_block crash_nmi_nb = { 143static struct notifier_block crash_nmi_nb = {
@@ -185,7 +189,7 @@ void machine_crash_shutdown(struct pt_regs *regs)
185 local_irq_disable(); 189 local_irq_disable();
186 190
187 /* Make a note of crashing cpu. Will be used in NMI callback.*/ 191 /* Make a note of crashing cpu. Will be used in NMI callback.*/
188 crashing_cpu = smp_processor_id(); 192 crashing_cpu = safe_smp_processor_id();
189 nmi_shootdown_cpus(); 193 nmi_shootdown_cpus();
190 lapic_shutdown(); 194 lapic_shutdown();
191#if defined(CONFIG_X86_IO_APIC) 195#if defined(CONFIG_X86_IO_APIC)
diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c
index fe158042110b..f9436989473c 100644
--- a/arch/i386/kernel/efi.c
+++ b/arch/i386/kernel/efi.c
@@ -65,7 +65,7 @@ static unsigned long efi_rt_eflags;
65static DEFINE_SPINLOCK(efi_rt_lock); 65static DEFINE_SPINLOCK(efi_rt_lock);
66static pgd_t efi_bak_pg_dir_pointer[2]; 66static pgd_t efi_bak_pg_dir_pointer[2];
67 67
68static void efi_call_phys_prelog(void) 68static void efi_call_phys_prelog(void) __acquires(efi_rt_lock)
69{ 69{
70 unsigned long cr4; 70 unsigned long cr4;
71 unsigned long temp; 71 unsigned long temp;
@@ -109,7 +109,7 @@ static void efi_call_phys_prelog(void)
109 load_gdt(cpu_gdt_descr); 109 load_gdt(cpu_gdt_descr);
110} 110}
111 111
112static void efi_call_phys_epilog(void) 112static void efi_call_phys_epilog(void) __releases(efi_rt_lock)
113{ 113{
114 unsigned long cr4; 114 unsigned long cr4;
115 struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0); 115 struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0);
diff --git a/arch/i386/kernel/i8237.c b/arch/i386/kernel/i8237.c
index c36d1c006c2f..6f508e8d7c57 100644
--- a/arch/i386/kernel/i8237.c
+++ b/arch/i386/kernel/i8237.c
@@ -2,6 +2,11 @@
2 * i8237.c: 8237A DMA controller suspend functions. 2 * i8237.c: 8237A DMA controller suspend functions.
3 * 3 *
4 * Written by Pierre Ossman, 2005. 4 * Written by Pierre Ossman, 2005.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or (at
9 * your option) any later version.
5 */ 10 */
6 11
7#include <linux/init.h> 12#include <linux/init.h>
diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c
index 40b44cc0d14b..9b9479768d5e 100644
--- a/arch/i386/kernel/microcode.c
+++ b/arch/i386/kernel/microcode.c
@@ -2,6 +2,7 @@
2 * Intel CPU Microcode Update Driver for Linux 2 * Intel CPU Microcode Update Driver for Linux
3 * 3 *
4 * Copyright (C) 2000-2004 Tigran Aivazian 4 * Copyright (C) 2000-2004 Tigran Aivazian
5 * 2006 Shaohua Li <shaohua.li@intel.com>
5 * 6 *
6 * This driver allows to upgrade microcode on Intel processors 7 * This driver allows to upgrade microcode on Intel processors
7 * belonging to IA-32 family - PentiumPro, Pentium II, 8 * belonging to IA-32 family - PentiumPro, Pentium II,
@@ -82,6 +83,9 @@
82#include <linux/spinlock.h> 83#include <linux/spinlock.h>
83#include <linux/mm.h> 84#include <linux/mm.h>
84#include <linux/mutex.h> 85#include <linux/mutex.h>
86#include <linux/cpu.h>
87#include <linux/firmware.h>
88#include <linux/platform_device.h>
85 89
86#include <asm/msr.h> 90#include <asm/msr.h>
87#include <asm/uaccess.h> 91#include <asm/uaccess.h>
@@ -91,9 +95,6 @@ MODULE_DESCRIPTION("Intel CPU (IA-32) Microcode Update Driver");
91MODULE_AUTHOR("Tigran Aivazian <tigran@veritas.com>"); 95MODULE_AUTHOR("Tigran Aivazian <tigran@veritas.com>");
92MODULE_LICENSE("GPL"); 96MODULE_LICENSE("GPL");
93 97
94static int verbose;
95module_param(verbose, int, 0644);
96
97#define MICROCODE_VERSION "1.14a" 98#define MICROCODE_VERSION "1.14a"
98 99
99#define DEFAULT_UCODE_DATASIZE (2000) /* 2000 bytes */ 100#define DEFAULT_UCODE_DATASIZE (2000) /* 2000 bytes */
@@ -120,55 +121,40 @@ static DEFINE_SPINLOCK(microcode_update_lock);
120/* no concurrent ->write()s are allowed on /dev/cpu/microcode */ 121/* no concurrent ->write()s are allowed on /dev/cpu/microcode */
121static DEFINE_MUTEX(microcode_mutex); 122static DEFINE_MUTEX(microcode_mutex);
122 123
123static void __user *user_buffer; /* user area microcode data buffer */
124static unsigned int user_buffer_size; /* it's size */
125
126typedef enum mc_error_code {
127 MC_SUCCESS = 0,
128 MC_IGNORED = 1,
129 MC_NOTFOUND = 2,
130 MC_MARKED = 3,
131 MC_ALLOCATED = 4,
132} mc_error_code_t;
133
134static struct ucode_cpu_info { 124static struct ucode_cpu_info {
125 int valid;
135 unsigned int sig; 126 unsigned int sig;
136 unsigned int pf, orig_pf; 127 unsigned int pf;
137 unsigned int rev; 128 unsigned int rev;
138 unsigned int cksum;
139 mc_error_code_t err;
140 microcode_t *mc; 129 microcode_t *mc;
141} ucode_cpu_info[NR_CPUS]; 130} ucode_cpu_info[NR_CPUS];
142
143static int microcode_open (struct inode *unused1, struct file *unused2)
144{
145 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
146}
147 131
148static void collect_cpu_info (void *unused) 132static void collect_cpu_info(int cpu_num)
149{ 133{
150 int cpu_num = smp_processor_id();
151 struct cpuinfo_x86 *c = cpu_data + cpu_num; 134 struct cpuinfo_x86 *c = cpu_data + cpu_num;
152 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; 135 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
153 unsigned int val[2]; 136 unsigned int val[2];
154 137
155 uci->sig = uci->pf = uci->rev = uci->cksum = 0; 138 /* We should bind the task to the CPU */
156 uci->err = MC_NOTFOUND; 139 BUG_ON(raw_smp_processor_id() != cpu_num);
140 uci->pf = uci->rev = 0;
157 uci->mc = NULL; 141 uci->mc = NULL;
142 uci->valid = 1;
158 143
159 if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || 144 if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 ||
160 cpu_has(c, X86_FEATURE_IA64)) { 145 cpu_has(c, X86_FEATURE_IA64)) {
161 printk(KERN_ERR "microcode: CPU%d not a capable Intel processor\n", cpu_num); 146 printk(KERN_ERR "microcode: CPU%d not a capable Intel "
147 "processor\n", cpu_num);
148 uci->valid = 0;
162 return; 149 return;
163 } else { 150 }
164 uci->sig = cpuid_eax(0x00000001);
165 151
166 if ((c->x86_model >= 5) || (c->x86 > 6)) { 152 uci->sig = cpuid_eax(0x00000001);
167 /* get processor flags from MSR 0x17 */ 153
168 rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); 154 if ((c->x86_model >= 5) || (c->x86 > 6)) {
169 uci->pf = 1 << ((val[1] >> 18) & 7); 155 /* get processor flags from MSR 0x17 */
170 } 156 rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
171 uci->orig_pf = uci->pf; 157 uci->pf = 1 << ((val[1] >> 18) & 7);
172 } 158 }
173 159
174 wrmsr(MSR_IA32_UCODE_REV, 0, 0); 160 wrmsr(MSR_IA32_UCODE_REV, 0, 0);
@@ -180,218 +166,159 @@ static void collect_cpu_info (void *unused)
180 uci->sig, uci->pf, uci->rev); 166 uci->sig, uci->pf, uci->rev);
181} 167}
182 168
183static inline void mark_microcode_update (int cpu_num, microcode_header_t *mc_header, int sig, int pf, int cksum) 169static inline int microcode_update_match(int cpu_num,
170 microcode_header_t *mc_header, int sig, int pf)
184{ 171{
185 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; 172 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
186 173
187 pr_debug("Microcode Found.\n"); 174 if (!sigmatch(sig, uci->sig, pf, uci->pf)
188 pr_debug(" Header Revision 0x%x\n", mc_header->hdrver); 175 || mc_header->rev <= uci->rev)
189 pr_debug(" Loader Revision 0x%x\n", mc_header->ldrver); 176 return 0;
190 pr_debug(" Revision 0x%x \n", mc_header->rev); 177 return 1;
191 pr_debug(" Date %x/%x/%x\n",
192 ((mc_header->date >> 24 ) & 0xff),
193 ((mc_header->date >> 16 ) & 0xff),
194 (mc_header->date & 0xFFFF));
195 pr_debug(" Signature 0x%x\n", sig);
196 pr_debug(" Type 0x%x Family 0x%x Model 0x%x Stepping 0x%x\n",
197 ((sig >> 12) & 0x3),
198 ((sig >> 8) & 0xf),
199 ((sig >> 4) & 0xf),
200 ((sig & 0xf)));
201 pr_debug(" Processor Flags 0x%x\n", pf);
202 pr_debug(" Checksum 0x%x\n", cksum);
203
204 if (mc_header->rev < uci->rev) {
205 if (uci->err == MC_NOTFOUND) {
206 uci->err = MC_IGNORED;
207 uci->cksum = mc_header->rev;
208 } else if (uci->err == MC_IGNORED && uci->cksum < mc_header->rev)
209 uci->cksum = mc_header->rev;
210 } else if (mc_header->rev == uci->rev) {
211 if (uci->err < MC_MARKED) {
212 /* notify the caller of success on this cpu */
213 uci->err = MC_SUCCESS;
214 }
215 } else if (uci->err != MC_ALLOCATED || mc_header->rev > uci->mc->hdr.rev) {
216 pr_debug("microcode: CPU%d found a matching microcode update with "
217 " revision 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev);
218 uci->cksum = cksum;
219 uci->pf = pf; /* keep the original mc pf for cksum calculation */
220 uci->err = MC_MARKED; /* found the match */
221 for_each_online_cpu(cpu_num) {
222 if (ucode_cpu_info + cpu_num != uci
223 && ucode_cpu_info[cpu_num].mc == uci->mc) {
224 uci->mc = NULL;
225 break;
226 }
227 }
228 if (uci->mc != NULL) {
229 vfree(uci->mc);
230 uci->mc = NULL;
231 }
232 }
233 return;
234} 178}
235 179
236static int find_matching_ucodes (void) 180static int microcode_sanity_check(void *mc)
237{ 181{
238 int cursor = 0; 182 microcode_header_t *mc_header = mc;
239 int error = 0; 183 struct extended_sigtable *ext_header = NULL;
240 184 struct extended_signature *ext_sig;
241 while (cursor + MC_HEADER_SIZE < user_buffer_size) { 185 unsigned long total_size, data_size, ext_table_size;
242 microcode_header_t mc_header; 186 int sum, orig_sum, ext_sigcount = 0, i;
243 void *newmc = NULL; 187
244 int i, sum, cpu_num, allocated_flag, total_size, data_size, ext_table_size; 188 total_size = get_totalsize(mc_header);
189 data_size = get_datasize(mc_header);
190 if (data_size + MC_HEADER_SIZE > total_size) {
191 printk(KERN_ERR "microcode: error! "
192 "Bad data size in microcode data file\n");
193 return -EINVAL;
194 }
245 195
246 if (copy_from_user(&mc_header, user_buffer + cursor, MC_HEADER_SIZE)) { 196 if (mc_header->ldrver != 1 || mc_header->hdrver != 1) {
247 printk(KERN_ERR "microcode: error! Can not read user data\n"); 197 printk(KERN_ERR "microcode: error! "
248 error = -EFAULT; 198 "Unknown microcode update format\n");
249 goto out; 199 return -EINVAL;
200 }
201 ext_table_size = total_size - (MC_HEADER_SIZE + data_size);
202 if (ext_table_size) {
203 if ((ext_table_size < EXT_HEADER_SIZE)
204 || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) {
205 printk(KERN_ERR "microcode: error! "
206 "Small exttable size in microcode data file\n");
207 return -EINVAL;
250 } 208 }
251 209 ext_header = mc + MC_HEADER_SIZE + data_size;
252 total_size = get_totalsize(&mc_header); 210 if (ext_table_size != exttable_size(ext_header)) {
253 if ((cursor + total_size > user_buffer_size) || (total_size < DEFAULT_UCODE_TOTALSIZE)) { 211 printk(KERN_ERR "microcode: error! "
254 printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); 212 "Bad exttable size in microcode data file\n");
255 error = -EINVAL; 213 return -EFAULT;
256 goto out;
257 } 214 }
215 ext_sigcount = ext_header->count;
216 }
258 217
259 data_size = get_datasize(&mc_header); 218 /* check extended table checksum */
260 if ((data_size + MC_HEADER_SIZE > total_size) || (data_size < DEFAULT_UCODE_DATASIZE)) { 219 if (ext_table_size) {
261 printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); 220 int ext_table_sum = 0;
262 error = -EINVAL; 221 int *ext_tablep = (int *)ext_header;
263 goto out; 222
223 i = ext_table_size / DWSIZE;
224 while (i--)
225 ext_table_sum += ext_tablep[i];
226 if (ext_table_sum) {
227 printk(KERN_WARNING "microcode: aborting, "
228 "bad extended signature table checksum\n");
229 return -EINVAL;
264 } 230 }
231 }
265 232
266 if (mc_header.ldrver != 1 || mc_header.hdrver != 1) { 233 /* calculate the checksum */
267 printk(KERN_ERR "microcode: error! Unknown microcode update format\n"); 234 orig_sum = 0;
268 error = -EINVAL; 235 i = (MC_HEADER_SIZE + data_size) / DWSIZE;
269 goto out; 236 while (i--)
237 orig_sum += ((int *)mc)[i];
238 if (orig_sum) {
239 printk(KERN_ERR "microcode: aborting, bad checksum\n");
240 return -EINVAL;
241 }
242 if (!ext_table_size)
243 return 0;
244 /* check extended signature checksum */
245 for (i = 0; i < ext_sigcount; i++) {
246 ext_sig = (struct extended_signature *)((void *)ext_header
247 + EXT_HEADER_SIZE + EXT_SIGNATURE_SIZE * i);
248 sum = orig_sum
249 - (mc_header->sig + mc_header->pf + mc_header->cksum)
250 + (ext_sig->sig + ext_sig->pf + ext_sig->cksum);
251 if (sum) {
252 printk(KERN_ERR "microcode: aborting, bad checksum\n");
253 return -EINVAL;
270 } 254 }
255 }
256 return 0;
257}
271 258
272 for_each_online_cpu(cpu_num) { 259/*
273 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; 260 * return 0 - no update found
274 261 * return 1 - found update
275 if (sigmatch(mc_header.sig, uci->sig, mc_header.pf, uci->orig_pf)) 262 * return < 0 - error
276 mark_microcode_update(cpu_num, &mc_header, mc_header.sig, mc_header.pf, mc_header.cksum); 263 */
277 } 264static int get_maching_microcode(void *mc, int cpu)
265{
266 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
267 microcode_header_t *mc_header = mc;
268 struct extended_sigtable *ext_header;
269 unsigned long total_size = get_totalsize(mc_header);
270 int ext_sigcount, i;
271 struct extended_signature *ext_sig;
272 void *new_mc;
273
274 if (microcode_update_match(cpu, mc_header,
275 mc_header->sig, mc_header->pf))
276 goto find;
277
278 if (total_size <= get_datasize(mc_header) + MC_HEADER_SIZE)
279 return 0;
280
281 ext_header = (struct extended_sigtable *)(mc +
282 get_datasize(mc_header) + MC_HEADER_SIZE);
283 ext_sigcount = ext_header->count;
284 ext_sig = (struct extended_signature *)((void *)ext_header
285 + EXT_HEADER_SIZE);
286 for (i = 0; i < ext_sigcount; i++) {
287 if (microcode_update_match(cpu, mc_header,
288 ext_sig->sig, ext_sig->pf))
289 goto find;
290 ext_sig++;
291 }
292 return 0;
293find:
294 pr_debug("microcode: CPU %d found a matching microcode update with"
295 " version 0x%x (current=0x%x)\n", cpu, mc_header->rev,uci->rev);
296 new_mc = vmalloc(total_size);
297 if (!new_mc) {
298 printk(KERN_ERR "microcode: error! Can not allocate memory\n");
299 return -ENOMEM;
300 }
278 301
279 ext_table_size = total_size - (MC_HEADER_SIZE + data_size); 302 /* free previous update file */
280 if (ext_table_size) { 303 vfree(uci->mc);
281 struct extended_sigtable ext_header;
282 struct extended_signature ext_sig;
283 int ext_sigcount;
284 304
285 if ((ext_table_size < EXT_HEADER_SIZE) 305 memcpy(new_mc, mc, total_size);
286 || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) { 306 uci->mc = new_mc;
287 printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); 307 return 1;
288 error = -EINVAL;
289 goto out;
290 }
291 if (copy_from_user(&ext_header, user_buffer + cursor
292 + MC_HEADER_SIZE + data_size, EXT_HEADER_SIZE)) {
293 printk(KERN_ERR "microcode: error! Can not read user data\n");
294 error = -EFAULT;
295 goto out;
296 }
297 if (ext_table_size != exttable_size(&ext_header)) {
298 printk(KERN_ERR "microcode: error! Bad data in microcode data file\n");
299 error = -EFAULT;
300 goto out;
301 }
302
303 ext_sigcount = ext_header.count;
304
305 for (i = 0; i < ext_sigcount; i++) {
306 if (copy_from_user(&ext_sig, user_buffer + cursor + MC_HEADER_SIZE + data_size + EXT_HEADER_SIZE
307 + EXT_SIGNATURE_SIZE * i, EXT_SIGNATURE_SIZE)) {
308 printk(KERN_ERR "microcode: error! Can not read user data\n");
309 error = -EFAULT;
310 goto out;
311 }
312 for_each_online_cpu(cpu_num) {
313 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
314
315 if (sigmatch(ext_sig.sig, uci->sig, ext_sig.pf, uci->orig_pf)) {
316 mark_microcode_update(cpu_num, &mc_header, ext_sig.sig, ext_sig.pf, ext_sig.cksum);
317 }
318 }
319 }
320 }
321 /* now check if any cpu has matched */
322 allocated_flag = 0;
323 sum = 0;
324 for_each_online_cpu(cpu_num) {
325 if (ucode_cpu_info[cpu_num].err == MC_MARKED) {
326 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
327 if (!allocated_flag) {
328 allocated_flag = 1;
329 newmc = vmalloc(total_size);
330 if (!newmc) {
331 printk(KERN_ERR "microcode: error! Can not allocate memory\n");
332 error = -ENOMEM;
333 goto out;
334 }
335 if (copy_from_user(newmc + MC_HEADER_SIZE,
336 user_buffer + cursor + MC_HEADER_SIZE,
337 total_size - MC_HEADER_SIZE)) {
338 printk(KERN_ERR "microcode: error! Can not read user data\n");
339 vfree(newmc);
340 error = -EFAULT;
341 goto out;
342 }
343 memcpy(newmc, &mc_header, MC_HEADER_SIZE);
344 /* check extended table checksum */
345 if (ext_table_size) {
346 int ext_table_sum = 0;
347 int * ext_tablep = (((void *) newmc) + MC_HEADER_SIZE + data_size);
348 i = ext_table_size / DWSIZE;
349 while (i--) ext_table_sum += ext_tablep[i];
350 if (ext_table_sum) {
351 printk(KERN_WARNING "microcode: aborting, bad extended signature table checksum\n");
352 vfree(newmc);
353 error = -EINVAL;
354 goto out;
355 }
356 }
357
358 /* calculate the checksum */
359 i = (MC_HEADER_SIZE + data_size) / DWSIZE;
360 while (i--) sum += ((int *)newmc)[i];
361 sum -= (mc_header.sig + mc_header.pf + mc_header.cksum);
362 }
363 ucode_cpu_info[cpu_num].mc = newmc;
364 ucode_cpu_info[cpu_num].err = MC_ALLOCATED; /* mc updated */
365 if (sum + uci->sig + uci->pf + uci->cksum != 0) {
366 printk(KERN_ERR "microcode: CPU%d aborting, bad checksum\n", cpu_num);
367 error = -EINVAL;
368 goto out;
369 }
370 }
371 }
372 cursor += total_size; /* goto the next update patch */
373 } /* end of while */
374out:
375 return error;
376} 308}
377 309
378static void do_update_one (void * unused) 310static void apply_microcode(int cpu)
379{ 311{
380 unsigned long flags; 312 unsigned long flags;
381 unsigned int val[2]; 313 unsigned int val[2];
382 int cpu_num = smp_processor_id(); 314 int cpu_num = raw_smp_processor_id();
383 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; 315 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
384 316
385 if (uci->mc == NULL) { 317 /* We should bind the task to the CPU */
386 if (verbose) { 318 BUG_ON(cpu_num != cpu);
387 if (uci->err == MC_SUCCESS) 319
388 printk(KERN_INFO "microcode: CPU%d already at revision 0x%x\n", 320 if (uci->mc == NULL)
389 cpu_num, uci->rev);
390 else
391 printk(KERN_INFO "microcode: No new microcode data for CPU%d\n", cpu_num);
392 }
393 return; 321 return;
394 }
395 322
396 /* serialize access to the physical write to MSR 0x79 */ 323 /* serialize access to the physical write to MSR 0x79 */
397 spin_lock_irqsave(&microcode_update_lock, flags); 324 spin_lock_irqsave(&microcode_update_lock, flags);
@@ -408,68 +335,107 @@ static void do_update_one (void * unused)
408 /* get the current revision from MSR 0x8B */ 335 /* get the current revision from MSR 0x8B */
409 rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); 336 rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
410 337
411 /* notify the caller of success on this cpu */
412 uci->err = MC_SUCCESS;
413 spin_unlock_irqrestore(&microcode_update_lock, flags); 338 spin_unlock_irqrestore(&microcode_update_lock, flags);
414 printk(KERN_INFO "microcode: CPU%d updated from revision " 339 if (val[1] != uci->mc->hdr.rev) {
340 printk(KERN_ERR "microcode: CPU%d updated from revision "
341 "0x%x to 0x%x failed\n", cpu_num, uci->rev, val[1]);
342 return;
343 }
344 pr_debug("microcode: CPU%d updated from revision "
415 "0x%x to 0x%x, date = %08x \n", 345 "0x%x to 0x%x, date = %08x \n",
416 cpu_num, uci->rev, val[1], uci->mc->hdr.date); 346 cpu_num, uci->rev, val[1], uci->mc->hdr.date);
417 return; 347 uci->rev = val[1];
418} 348}
419 349
420static int do_microcode_update (void) 350#ifdef CONFIG_MICROCODE_OLD_INTERFACE
421{ 351static void __user *user_buffer; /* user area microcode data buffer */
422 int i, error; 352static unsigned int user_buffer_size; /* it's size */
423 353
424 if (on_each_cpu(collect_cpu_info, NULL, 1, 1) != 0) { 354static long get_next_ucode(void **mc, long offset)
425 printk(KERN_ERR "microcode: Error! Could not run on all processors\n"); 355{
426 error = -EIO; 356 microcode_header_t mc_header;
427 goto out; 357 unsigned long total_size;
358
359 /* No more data */
360 if (offset >= user_buffer_size)
361 return 0;
362 if (copy_from_user(&mc_header, user_buffer + offset, MC_HEADER_SIZE)) {
363 printk(KERN_ERR "microcode: error! Can not read user data\n");
364 return -EFAULT;
428 } 365 }
429 366 total_size = get_totalsize(&mc_header);
430 if ((error = find_matching_ucodes())) { 367 if (offset + total_size > user_buffer_size) {
431 printk(KERN_ERR "microcode: Error in the microcode data\n"); 368 printk(KERN_ERR "microcode: error! Bad total size in microcode "
432 goto out_free; 369 "data file\n");
370 return -EINVAL;
433 } 371 }
434 372 *mc = vmalloc(total_size);
435 if (on_each_cpu(do_update_one, NULL, 1, 1) != 0) { 373 if (!*mc)
436 printk(KERN_ERR "microcode: Error! Could not run on all processors\n"); 374 return -ENOMEM;
437 error = -EIO; 375 if (copy_from_user(*mc, user_buffer + offset, total_size)) {
376 printk(KERN_ERR "microcode: error! Can not read user data\n");
377 vfree(*mc);
378 return -EFAULT;
438 } 379 }
380 return offset + total_size;
381}
382
383static int do_microcode_update (void)
384{
385 long cursor = 0;
386 int error = 0;
387 void *new_mc;
388 int cpu;
389 cpumask_t old;
390
391 old = current->cpus_allowed;
439 392
440out_free: 393 while ((cursor = get_next_ucode(&new_mc, cursor)) > 0) {
441 for_each_online_cpu(i) { 394 error = microcode_sanity_check(new_mc);
442 if (ucode_cpu_info[i].mc) { 395 if (error)
443 int j; 396 goto out;
444 void *tmp = ucode_cpu_info[i].mc; 397 /*
445 vfree(tmp); 398 * It's possible the data file has multiple matching ucode,
446 for_each_online_cpu(j) { 399 * lets keep searching till the latest version
447 if (ucode_cpu_info[j].mc == tmp) 400 */
448 ucode_cpu_info[j].mc = NULL; 401 for_each_online_cpu(cpu) {
449 } 402 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
403
404 if (!uci->valid)
405 continue;
406 set_cpus_allowed(current, cpumask_of_cpu(cpu));
407 error = get_maching_microcode(new_mc, cpu);
408 if (error < 0)
409 goto out;
410 if (error == 1)
411 apply_microcode(cpu);
450 } 412 }
451 if (ucode_cpu_info[i].err == MC_IGNORED && verbose) 413 vfree(new_mc);
452 printk(KERN_WARNING "microcode: CPU%d not 'upgrading' to earlier revision"
453 " 0x%x (current=0x%x)\n", i, ucode_cpu_info[i].cksum, ucode_cpu_info[i].rev);
454 } 414 }
455out: 415out:
416 if (cursor > 0)
417 vfree(new_mc);
418 if (cursor < 0)
419 error = cursor;
420 set_cpus_allowed(current, old);
456 return error; 421 return error;
457} 422}
458 423
424static int microcode_open (struct inode *unused1, struct file *unused2)
425{
426 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
427}
428
459static ssize_t microcode_write (struct file *file, const char __user *buf, size_t len, loff_t *ppos) 429static ssize_t microcode_write (struct file *file, const char __user *buf, size_t len, loff_t *ppos)
460{ 430{
461 ssize_t ret; 431 ssize_t ret;
462 432
463 if (len < DEFAULT_UCODE_TOTALSIZE) {
464 printk(KERN_ERR "microcode: not enough data\n");
465 return -EINVAL;
466 }
467
468 if ((len >> PAGE_SHIFT) > num_physpages) { 433 if ((len >> PAGE_SHIFT) > num_physpages) {
469 printk(KERN_ERR "microcode: too much data (max %ld pages)\n", num_physpages); 434 printk(KERN_ERR "microcode: too much data (max %ld pages)\n", num_physpages);
470 return -EINVAL; 435 return -EINVAL;
471 } 436 }
472 437
438 lock_cpu_hotplug();
473 mutex_lock(&microcode_mutex); 439 mutex_lock(&microcode_mutex);
474 440
475 user_buffer = (void __user *) buf; 441 user_buffer = (void __user *) buf;
@@ -480,6 +446,7 @@ static ssize_t microcode_write (struct file *file, const char __user *buf, size_
480 ret = (ssize_t)len; 446 ret = (ssize_t)len;
481 447
482 mutex_unlock(&microcode_mutex); 448 mutex_unlock(&microcode_mutex);
449 unlock_cpu_hotplug();
483 450
484 return ret; 451 return ret;
485} 452}
@@ -496,7 +463,7 @@ static struct miscdevice microcode_dev = {
496 .fops = &microcode_fops, 463 .fops = &microcode_fops,
497}; 464};
498 465
499static int __init microcode_init (void) 466static int __init microcode_dev_init (void)
500{ 467{
501 int error; 468 int error;
502 469
@@ -508,6 +475,280 @@ static int __init microcode_init (void)
508 return error; 475 return error;
509 } 476 }
510 477
478 return 0;
479}
480
481static void __exit microcode_dev_exit (void)
482{
483 misc_deregister(&microcode_dev);
484}
485
486MODULE_ALIAS_MISCDEV(MICROCODE_MINOR);
487#else
488#define microcode_dev_init() 0
489#define microcode_dev_exit() do { } while(0)
490#endif
491
492static long get_next_ucode_from_buffer(void **mc, void *buf,
493 unsigned long size, long offset)
494{
495 microcode_header_t *mc_header;
496 unsigned long total_size;
497
498 /* No more data */
499 if (offset >= size)
500 return 0;
501 mc_header = (microcode_header_t *)(buf + offset);
502 total_size = get_totalsize(mc_header);
503
504 if (offset + total_size > size) {
505 printk(KERN_ERR "microcode: error! Bad data in microcode data file\n");
506 return -EINVAL;
507 }
508
509 *mc = vmalloc(total_size);
510 if (!*mc) {
511 printk(KERN_ERR "microcode: error! Can not allocate memory\n");
512 return -ENOMEM;
513 }
514 memcpy(*mc, buf + offset, total_size);
515 return offset + total_size;
516}
517
518/* fake device for request_firmware */
519static struct platform_device *microcode_pdev;
520
521static int cpu_request_microcode(int cpu)
522{
523 char name[30];
524 struct cpuinfo_x86 *c = cpu_data + cpu;
525 const struct firmware *firmware;
526 void *buf;
527 unsigned long size;
528 long offset = 0;
529 int error;
530 void *mc;
531
532 /* We should bind the task to the CPU */
533 BUG_ON(cpu != raw_smp_processor_id());
534 sprintf(name,"intel-ucode/%02x-%02x-%02x",
535 c->x86, c->x86_model, c->x86_mask);
536 error = request_firmware(&firmware, name, &microcode_pdev->dev);
537 if (error) {
538 pr_debug("ucode data file %s load failed\n", name);
539 return error;
540 }
541 buf = (void *)firmware->data;
542 size = firmware->size;
543 while ((offset = get_next_ucode_from_buffer(&mc, buf, size, offset))
544 > 0) {
545 error = microcode_sanity_check(mc);
546 if (error)
547 break;
548 error = get_maching_microcode(mc, cpu);
549 if (error < 0)
550 break;
551 /*
552 * It's possible the data file has multiple matching ucode,
553 * lets keep searching till the latest version
554 */
555 if (error == 1) {
556 apply_microcode(cpu);
557 error = 0;
558 }
559 vfree(mc);
560 }
561 if (offset > 0)
562 vfree(mc);
563 if (offset < 0)
564 error = offset;
565 release_firmware(firmware);
566
567 return error;
568}
569
570static void microcode_init_cpu(int cpu)
571{
572 cpumask_t old;
573 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
574
575 old = current->cpus_allowed;
576
577 set_cpus_allowed(current, cpumask_of_cpu(cpu));
578 mutex_lock(&microcode_mutex);
579 collect_cpu_info(cpu);
580 if (uci->valid)
581 cpu_request_microcode(cpu);
582 mutex_unlock(&microcode_mutex);
583 set_cpus_allowed(current, old);
584}
585
586static void microcode_fini_cpu(int cpu)
587{
588 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
589
590 mutex_lock(&microcode_mutex);
591 uci->valid = 0;
592 vfree(uci->mc);
593 uci->mc = NULL;
594 mutex_unlock(&microcode_mutex);
595}
596
597static ssize_t reload_store(struct sys_device *dev, const char *buf, size_t sz)
598{
599 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
600 char *end;
601 unsigned long val = simple_strtoul(buf, &end, 0);
602 int err = 0;
603 int cpu = dev->id;
604
605 if (end == buf)
606 return -EINVAL;
607 if (val == 1) {
608 cpumask_t old;
609
610 old = current->cpus_allowed;
611
612 lock_cpu_hotplug();
613 set_cpus_allowed(current, cpumask_of_cpu(cpu));
614
615 mutex_lock(&microcode_mutex);
616 if (uci->valid)
617 err = cpu_request_microcode(cpu);
618 mutex_unlock(&microcode_mutex);
619 unlock_cpu_hotplug();
620 set_cpus_allowed(current, old);
621 }
622 if (err)
623 return err;
624 return sz;
625}
626
627static ssize_t version_show(struct sys_device *dev, char *buf)
628{
629 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
630
631 return sprintf(buf, "0x%x\n", uci->rev);
632}
633
634static ssize_t pf_show(struct sys_device *dev, char *buf)
635{
636 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
637
638 return sprintf(buf, "0x%x\n", uci->pf);
639}
640
641static SYSDEV_ATTR(reload, 0200, NULL, reload_store);
642static SYSDEV_ATTR(version, 0400, version_show, NULL);
643static SYSDEV_ATTR(processor_flags, 0400, pf_show, NULL);
644
645static struct attribute *mc_default_attrs[] = {
646 &attr_reload.attr,
647 &attr_version.attr,
648 &attr_processor_flags.attr,
649 NULL
650};
651
652static struct attribute_group mc_attr_group = {
653 .attrs = mc_default_attrs,
654 .name = "microcode",
655};
656
657static int mc_sysdev_add(struct sys_device *sys_dev)
658{
659 int cpu = sys_dev->id;
660 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
661
662 if (!cpu_online(cpu))
663 return 0;
664 pr_debug("Microcode:CPU %d added\n", cpu);
665 memset(uci, 0, sizeof(*uci));
666 sysfs_create_group(&sys_dev->kobj, &mc_attr_group);
667
668 microcode_init_cpu(cpu);
669 return 0;
670}
671
672static int mc_sysdev_remove(struct sys_device *sys_dev)
673{
674 int cpu = sys_dev->id;
675
676 if (!cpu_online(cpu))
677 return 0;
678 pr_debug("Microcode:CPU %d removed\n", cpu);
679 microcode_fini_cpu(cpu);
680 sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);
681 return 0;
682}
683
684static int mc_sysdev_resume(struct sys_device *dev)
685{
686 int cpu = dev->id;
687
688 if (!cpu_online(cpu))
689 return 0;
690 pr_debug("Microcode:CPU %d resumed\n", cpu);
691 /* only CPU 0 will apply ucode here */
692 apply_microcode(0);
693 return 0;
694}
695
696static struct sysdev_driver mc_sysdev_driver = {
697 .add = mc_sysdev_add,
698 .remove = mc_sysdev_remove,
699 .resume = mc_sysdev_resume,
700};
701
702#ifdef CONFIG_HOTPLUG_CPU
703static __cpuinit int
704mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu)
705{
706 unsigned int cpu = (unsigned long)hcpu;
707 struct sys_device *sys_dev;
708
709 sys_dev = get_cpu_sysdev(cpu);
710 switch (action) {
711 case CPU_ONLINE:
712 case CPU_DOWN_FAILED:
713 mc_sysdev_add(sys_dev);
714 break;
715 case CPU_DOWN_PREPARE:
716 mc_sysdev_remove(sys_dev);
717 break;
718 }
719 return NOTIFY_OK;
720}
721
722static struct notifier_block mc_cpu_notifier = {
723 .notifier_call = mc_cpu_callback,
724};
725#endif
726
727static int __init microcode_init (void)
728{
729 int error;
730
731 error = microcode_dev_init();
732 if (error)
733 return error;
734 microcode_pdev = platform_device_register_simple("microcode", -1,
735 NULL, 0);
736 if (IS_ERR(microcode_pdev)) {
737 microcode_dev_exit();
738 return PTR_ERR(microcode_pdev);
739 }
740
741 lock_cpu_hotplug();
742 error = sysdev_driver_register(&cpu_sysdev_class, &mc_sysdev_driver);
743 unlock_cpu_hotplug();
744 if (error) {
745 microcode_dev_exit();
746 platform_device_unregister(microcode_pdev);
747 return error;
748 }
749
750 register_hotcpu_notifier(&mc_cpu_notifier);
751
511 printk(KERN_INFO 752 printk(KERN_INFO
512 "IA-32 Microcode Update Driver: v" MICROCODE_VERSION " <tigran@veritas.com>\n"); 753 "IA-32 Microcode Update Driver: v" MICROCODE_VERSION " <tigran@veritas.com>\n");
513 return 0; 754 return 0;
@@ -515,9 +756,16 @@ static int __init microcode_init (void)
515 756
516static void __exit microcode_exit (void) 757static void __exit microcode_exit (void)
517{ 758{
518 misc_deregister(&microcode_dev); 759 microcode_dev_exit();
760
761 unregister_hotcpu_notifier(&mc_cpu_notifier);
762
763 lock_cpu_hotplug();
764 sysdev_driver_unregister(&cpu_sysdev_class, &mc_sysdev_driver);
765 unlock_cpu_hotplug();
766
767 platform_device_unregister(microcode_pdev);
519} 768}
520 769
521module_init(microcode_init) 770module_init(microcode_init)
522module_exit(microcode_exit) 771module_exit(microcode_exit)
523MODULE_ALIAS_MISCDEV(MICROCODE_MINOR);
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index dbda706fdd14..3e8e3adb0489 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -13,7 +13,6 @@
13 * Mikael Pettersson : PM converted to driver model. Disable/enable API. 13 * Mikael Pettersson : PM converted to driver model. Disable/enable API.
14 */ 14 */
15 15
16#include <linux/config.h>
17#include <linux/delay.h> 16#include <linux/delay.h>
18#include <linux/interrupt.h> 17#include <linux/interrupt.h>
19#include <linux/module.h> 18#include <linux/module.h>
@@ -31,6 +30,9 @@
31 30
32#include "mach_traps.h" 31#include "mach_traps.h"
33 32
33int unknown_nmi_panic;
34int nmi_watchdog_enabled;
35
34/* perfctr_nmi_owner tracks the ownership of the perfctr registers: 36/* perfctr_nmi_owner tracks the ownership of the perfctr registers:
35 * evtsel_nmi_owner tracks the ownership of the event selection 37 * evtsel_nmi_owner tracks the ownership of the event selection
36 * - different performance counters/ event selection may be reserved for 38 * - different performance counters/ event selection may be reserved for
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 8c190ca7ae44..96cd0232e1e0 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -425,13 +425,12 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
425 425
426 tsk = current; 426 tsk = current;
427 if (unlikely(test_tsk_thread_flag(tsk, TIF_IO_BITMAP))) { 427 if (unlikely(test_tsk_thread_flag(tsk, TIF_IO_BITMAP))) {
428 p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL); 428 p->thread.io_bitmap_ptr = kmemdup(tsk->thread.io_bitmap_ptr,
429 IO_BITMAP_BYTES, GFP_KERNEL);
429 if (!p->thread.io_bitmap_ptr) { 430 if (!p->thread.io_bitmap_ptr) {
430 p->thread.io_bitmap_max = 0; 431 p->thread.io_bitmap_max = 0;
431 return -ENOMEM; 432 return -ENOMEM;
432 } 433 }
433 memcpy(p->thread.io_bitmap_ptr, tsk->thread.io_bitmap_ptr,
434 IO_BITMAP_BYTES);
435 set_tsk_thread_flag(p, TIF_IO_BITMAP); 434 set_tsk_thread_flag(p, TIF_IO_BITMAP);
436 } 435 }
437 436
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 76a524b4c90f..000cf03751fe 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -209,9 +209,6 @@ static struct resource adapter_rom_resources[] = { {
209 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM 209 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
210} }; 210} };
211 211
212#define ADAPTER_ROM_RESOURCES \
213 (sizeof adapter_rom_resources / sizeof adapter_rom_resources[0])
214
215static struct resource video_rom_resource = { 212static struct resource video_rom_resource = {
216 .name = "Video ROM", 213 .name = "Video ROM",
217 .start = 0xc0000, 214 .start = 0xc0000,
@@ -273,9 +270,6 @@ static struct resource standard_io_resources[] = { {
273 .flags = IORESOURCE_BUSY | IORESOURCE_IO 270 .flags = IORESOURCE_BUSY | IORESOURCE_IO
274} }; 271} };
275 272
276#define STANDARD_IO_RESOURCES \
277 (sizeof standard_io_resources / sizeof standard_io_resources[0])
278
279#define romsignature(x) (*(unsigned short *)(x) == 0xaa55) 273#define romsignature(x) (*(unsigned short *)(x) == 0xaa55)
280 274
281static int __init romchecksum(unsigned char *rom, unsigned long length) 275static int __init romchecksum(unsigned char *rom, unsigned long length)
@@ -332,7 +326,7 @@ static void __init probe_roms(void)
332 } 326 }
333 327
334 /* check for adapter roms on 2k boundaries */ 328 /* check for adapter roms on 2k boundaries */
335 for (i = 0; i < ADAPTER_ROM_RESOURCES && start < upper; start += 2048) { 329 for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) {
336 rom = isa_bus_to_virt(start); 330 rom = isa_bus_to_virt(start);
337 if (!romsignature(rom)) 331 if (!romsignature(rom))
338 continue; 332 continue;
@@ -1089,22 +1083,20 @@ static unsigned long __init setup_memory(void)
1089 1083
1090void __init zone_sizes_init(void) 1084void __init zone_sizes_init(void)
1091{ 1085{
1092 unsigned long zones_size[MAX_NR_ZONES] = { 0, };
1093 unsigned int max_dma, low;
1094
1095 max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
1096 low = max_low_pfn;
1097
1098 if (low < max_dma)
1099 zones_size[ZONE_DMA] = low;
1100 else {
1101 zones_size[ZONE_DMA] = max_dma;
1102 zones_size[ZONE_NORMAL] = low - max_dma;
1103#ifdef CONFIG_HIGHMEM 1086#ifdef CONFIG_HIGHMEM
1104 zones_size[ZONE_HIGHMEM] = highend_pfn - low; 1087 unsigned long max_zone_pfns[MAX_NR_ZONES] = {
1088 virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT,
1089 max_low_pfn,
1090 highend_pfn};
1091 add_active_range(0, 0, highend_pfn);
1092#else
1093 unsigned long max_zone_pfns[MAX_NR_ZONES] = {
1094 virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT,
1095 max_low_pfn};
1096 add_active_range(0, 0, max_low_pfn);
1105#endif 1097#endif
1106 } 1098
1107 free_area_init(zones_size); 1099 free_area_init_nodes(max_zone_pfns);
1108} 1100}
1109#else 1101#else
1110extern unsigned long __init setup_memory(void); 1102extern unsigned long __init setup_memory(void);
@@ -1274,7 +1266,7 @@ static int __init request_standard_resources(void)
1274 request_resource(&iomem_resource, &video_ram_resource); 1266 request_resource(&iomem_resource, &video_ram_resource);
1275 1267
1276 /* request I/O space for devices used on all i[345]86 PCs */ 1268 /* request I/O space for devices used on all i[345]86 PCs */
1277 for (i = 0; i < STANDARD_IO_RESOURCES; i++) 1269 for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++)
1278 request_resource(&ioport_resource, &standard_io_resources[i]); 1270 request_resource(&ioport_resource, &standard_io_resources[i]);
1279 return 0; 1271 return 0;
1280} 1272}
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
index 465188e2d701..1b080ab8a49f 100644
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -700,3 +700,30 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
700 return 0; 700 return 0;
701} 701}
702EXPORT_SYMBOL(smp_call_function_single); 702EXPORT_SYMBOL(smp_call_function_single);
703
704static int convert_apicid_to_cpu(int apic_id)
705{
706 int i;
707
708 for (i = 0; i < NR_CPUS; i++) {
709 if (x86_cpu_to_apicid[i] == apic_id)
710 return i;
711 }
712 return -1;
713}
714
715int safe_smp_processor_id(void)
716{
717 int apicid, cpuid;
718
719 if (!boot_cpu_has(X86_FEATURE_APIC))
720 return 0;
721
722 apicid = hard_smp_processor_id();
723 if (apicid == BAD_APICID)
724 return 0;
725
726 cpuid = convert_apicid_to_cpu(apicid);
727
728 return cpuid >= 0 ? cpuid : 0;
729}
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 020d873b7d21..0831f709f777 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -102,6 +102,8 @@ u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly =
102 { [0 ... NR_CPUS-1] = 0xff }; 102 { [0 ... NR_CPUS-1] = 0xff };
103EXPORT_SYMBOL(x86_cpu_to_apicid); 103EXPORT_SYMBOL(x86_cpu_to_apicid);
104 104
105u8 apicid_2_node[MAX_APICID];
106
105/* 107/*
106 * Trampoline 80x86 program as an array. 108 * Trampoline 80x86 program as an array.
107 */ 109 */
@@ -645,7 +647,7 @@ static void map_cpu_to_logical_apicid(void)
645{ 647{
646 int cpu = smp_processor_id(); 648 int cpu = smp_processor_id();
647 int apicid = logical_smp_processor_id(); 649 int apicid = logical_smp_processor_id();
648 int node = apicid_to_node(apicid); 650 int node = apicid_to_node(hard_smp_processor_id());
649 651
650 if (!node_online(node)) 652 if (!node_online(node))
651 node = first_online_node; 653 node = first_online_node;
@@ -954,6 +956,7 @@ static int __devinit do_boot_cpu(int apicid, int cpu)
954 956
955 irq_ctx_init(cpu); 957 irq_ctx_init(cpu);
956 958
959 x86_cpu_to_apicid[cpu] = apicid;
957 /* 960 /*
958 * This grunge runs the startup process for 961 * This grunge runs the startup process for
959 * the targeted processor. 962 * the targeted processor.
@@ -1058,7 +1061,7 @@ static void __cpuinit do_warm_boot_cpu(void *p)
1058 1061
1059static int __cpuinit __smp_prepare_cpu(int cpu) 1062static int __cpuinit __smp_prepare_cpu(int cpu)
1060{ 1063{
1061 DECLARE_COMPLETION(done); 1064 DECLARE_COMPLETION_ONSTACK(done);
1062 struct warm_boot_cpu_info info; 1065 struct warm_boot_cpu_info info;
1063 struct work_struct task; 1066 struct work_struct task;
1064 int apicid, ret; 1067 int apicid, ret;
diff --git a/arch/i386/kernel/srat.c b/arch/i386/kernel/srat.c
index 83db411b3aa7..f7e735c077c3 100644
--- a/arch/i386/kernel/srat.c
+++ b/arch/i386/kernel/srat.c
@@ -30,6 +30,7 @@
30#include <linux/nodemask.h> 30#include <linux/nodemask.h>
31#include <asm/srat.h> 31#include <asm/srat.h>
32#include <asm/topology.h> 32#include <asm/topology.h>
33#include <asm/smp.h>
33 34
34/* 35/*
35 * proximity macros and definitions 36 * proximity macros and definitions
@@ -54,8 +55,7 @@ struct node_memory_chunk_s {
54static struct node_memory_chunk_s node_memory_chunk[MAXCHUNKS]; 55static struct node_memory_chunk_s node_memory_chunk[MAXCHUNKS];
55 56
56static int num_memory_chunks; /* total number of memory chunks */ 57static int num_memory_chunks; /* total number of memory chunks */
57static int zholes_size_init; 58static u8 __initdata apicid_to_pxm[MAX_APICID];
58static unsigned long zholes_size[MAX_NUMNODES * MAX_NR_ZONES];
59 59
60extern void * boot_ioremap(unsigned long, unsigned long); 60extern void * boot_ioremap(unsigned long, unsigned long);
61 61
@@ -71,6 +71,8 @@ static void __init parse_cpu_affinity_structure(char *p)
71 /* mark this node as "seen" in node bitmap */ 71 /* mark this node as "seen" in node bitmap */
72 BMAP_SET(pxm_bitmap, cpu_affinity->proximity_domain); 72 BMAP_SET(pxm_bitmap, cpu_affinity->proximity_domain);
73 73
74 apicid_to_pxm[cpu_affinity->apic_id] = cpu_affinity->proximity_domain;
75
74 printk("CPU 0x%02X in proximity domain 0x%02X\n", 76 printk("CPU 0x%02X in proximity domain 0x%02X\n",
75 cpu_affinity->apic_id, cpu_affinity->proximity_domain); 77 cpu_affinity->apic_id, cpu_affinity->proximity_domain);
76} 78}
@@ -135,47 +137,6 @@ static void __init parse_memory_affinity_structure (char *sratp)
135 "enabled and removable" : "enabled" ) ); 137 "enabled and removable" : "enabled" ) );
136} 138}
137 139
138/* Take a chunk of pages from page frame cstart to cend and count the number
139 * of pages in each zone, returned via zones[].
140 */
141static __init void chunk_to_zones(unsigned long cstart, unsigned long cend,
142 unsigned long *zones)
143{
144 unsigned long max_dma;
145 extern unsigned long max_low_pfn;
146
147 int z;
148 unsigned long rend;
149
150 /* FIXME: MAX_DMA_ADDRESS and max_low_pfn are trying to provide
151 * similarly scoped information and should be handled in a consistant
152 * manner.
153 */
154 max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
155
156 /* Split the hole into the zones in which it falls. Repeatedly
157 * take the segment in which the remaining hole starts, round it
158 * to the end of that zone.
159 */
160 memset(zones, 0, MAX_NR_ZONES * sizeof(long));
161 while (cstart < cend) {
162 if (cstart < max_dma) {
163 z = ZONE_DMA;
164 rend = (cend < max_dma)? cend : max_dma;
165
166 } else if (cstart < max_low_pfn) {
167 z = ZONE_NORMAL;
168 rend = (cend < max_low_pfn)? cend : max_low_pfn;
169
170 } else {
171 z = ZONE_HIGHMEM;
172 rend = cend;
173 }
174 zones[z] += rend - cstart;
175 cstart = rend;
176 }
177}
178
179/* 140/*
180 * The SRAT table always lists ascending addresses, so can always 141 * The SRAT table always lists ascending addresses, so can always
181 * assume that the first "start" address that you see is the real 142 * assume that the first "start" address that you see is the real
@@ -220,7 +181,6 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp)
220 181
221 memset(pxm_bitmap, 0, sizeof(pxm_bitmap)); /* init proximity domain bitmap */ 182 memset(pxm_bitmap, 0, sizeof(pxm_bitmap)); /* init proximity domain bitmap */
222 memset(node_memory_chunk, 0, sizeof(node_memory_chunk)); 183 memset(node_memory_chunk, 0, sizeof(node_memory_chunk));
223 memset(zholes_size, 0, sizeof(zholes_size));
224 184
225 num_memory_chunks = 0; 185 num_memory_chunks = 0;
226 while (p < end) { 186 while (p < end) {
@@ -279,11 +239,15 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp)
279 printk("Number of logical nodes in system = %d\n", num_online_nodes()); 239 printk("Number of logical nodes in system = %d\n", num_online_nodes());
280 printk("Number of memory chunks in system = %d\n", num_memory_chunks); 240 printk("Number of memory chunks in system = %d\n", num_memory_chunks);
281 241
242 for (i = 0; i < MAX_APICID; i++)
243 apicid_2_node[i] = pxm_to_node(apicid_to_pxm[i]);
244
282 for (j = 0; j < num_memory_chunks; j++){ 245 for (j = 0; j < num_memory_chunks; j++){
283 struct node_memory_chunk_s * chunk = &node_memory_chunk[j]; 246 struct node_memory_chunk_s * chunk = &node_memory_chunk[j];
284 printk("chunk %d nid %d start_pfn %08lx end_pfn %08lx\n", 247 printk("chunk %d nid %d start_pfn %08lx end_pfn %08lx\n",
285 j, chunk->nid, chunk->start_pfn, chunk->end_pfn); 248 j, chunk->nid, chunk->start_pfn, chunk->end_pfn);
286 node_read_chunk(chunk->nid, chunk); 249 node_read_chunk(chunk->nid, chunk);
250 add_active_range(chunk->nid, chunk->start_pfn, chunk->end_pfn);
287 } 251 }
288 252
289 for_each_online_node(nid) { 253 for_each_online_node(nid) {
@@ -392,57 +356,7 @@ int __init get_memcfg_from_srat(void)
392 return acpi20_parse_srat((struct acpi_table_srat *)header); 356 return acpi20_parse_srat((struct acpi_table_srat *)header);
393 } 357 }
394out_err: 358out_err:
359 remove_all_active_ranges();
395 printk("failed to get NUMA memory information from SRAT table\n"); 360 printk("failed to get NUMA memory information from SRAT table\n");
396 return 0; 361 return 0;
397} 362}
398
399/* For each node run the memory list to determine whether there are
400 * any memory holes. For each hole determine which ZONE they fall
401 * into.
402 *
403 * NOTE#1: this requires knowledge of the zone boundries and so
404 * _cannot_ be performed before those are calculated in setup_memory.
405 *
406 * NOTE#2: we rely on the fact that the memory chunks are ordered by
407 * start pfn number during setup.
408 */
409static void __init get_zholes_init(void)
410{
411 int nid;
412 int c;
413 int first;
414 unsigned long end = 0;
415
416 for_each_online_node(nid) {
417 first = 1;
418 for (c = 0; c < num_memory_chunks; c++){
419 if (node_memory_chunk[c].nid == nid) {
420 if (first) {
421 end = node_memory_chunk[c].end_pfn;
422 first = 0;
423
424 } else {
425 /* Record any gap between this chunk
426 * and the previous chunk on this node
427 * against the zones it spans.
428 */
429 chunk_to_zones(end,
430 node_memory_chunk[c].start_pfn,
431 &zholes_size[nid * MAX_NR_ZONES]);
432 }
433 }
434 }
435 }
436}
437
438unsigned long * __init get_zholes_size(int nid)
439{
440 if (!zholes_size_init) {
441 zholes_size_init++;
442 get_zholes_init();
443 }
444 if (nid >= MAX_NUMNODES || !node_online(nid))
445 printk("%s: nid = %d is invalid/offline. num_online_nodes = %d",
446 __FUNCTION__, nid, num_online_nodes());
447 return &zholes_size[nid * MAX_NR_ZONES];
448}
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
index 86944acfb647..58a2d5582419 100644
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -76,8 +76,6 @@ int pit_latch_buggy; /* extern */
76unsigned int cpu_khz; /* Detected as we calibrate the TSC */ 76unsigned int cpu_khz; /* Detected as we calibrate the TSC */
77EXPORT_SYMBOL(cpu_khz); 77EXPORT_SYMBOL(cpu_khz);
78 78
79extern unsigned long wall_jiffies;
80
81DEFINE_SPINLOCK(rtc_lock); 79DEFINE_SPINLOCK(rtc_lock);
82EXPORT_SYMBOL(rtc_lock); 80EXPORT_SYMBOL(rtc_lock);
83 81
@@ -329,7 +327,6 @@ static int timer_resume(struct sys_device *dev)
329 do_settimeofday(&ts); 327 do_settimeofday(&ts);
330 write_seqlock_irqsave(&xtime_lock, flags); 328 write_seqlock_irqsave(&xtime_lock, flags);
331 jiffies_64 += sleep_length; 329 jiffies_64 += sleep_length;
332 wall_jiffies += sleep_length;
333 write_sequnlock_irqrestore(&xtime_lock, flags); 330 write_sequnlock_irqrestore(&xtime_lock, flags);
334 touch_softlockup_watchdog(); 331 touch_softlockup_watchdog();
335 return 0; 332 return 0;
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 21aa1cd57773..6820b8d643c7 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -28,6 +28,7 @@
28#include <linux/kprobes.h> 28#include <linux/kprobes.h>
29#include <linux/kexec.h> 29#include <linux/kexec.h>
30#include <linux/unwind.h> 30#include <linux/unwind.h>
31#include <linux/uaccess.h>
31 32
32#ifdef CONFIG_EISA 33#ifdef CONFIG_EISA
33#include <linux/ioport.h> 34#include <linux/ioport.h>
@@ -40,7 +41,6 @@
40 41
41#include <asm/processor.h> 42#include <asm/processor.h>
42#include <asm/system.h> 43#include <asm/system.h>
43#include <asm/uaccess.h>
44#include <asm/io.h> 44#include <asm/io.h>
45#include <asm/atomic.h> 45#include <asm/atomic.h>
46#include <asm/debugreg.h> 46#include <asm/debugreg.h>
@@ -57,6 +57,8 @@
57 57
58#include "mach_traps.h" 58#include "mach_traps.h"
59 59
60int panic_on_unrecovered_nmi;
61
60asmlinkage int system_call(void); 62asmlinkage int system_call(void);
61 63
62struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, 64struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
@@ -409,7 +411,7 @@ static void handle_BUG(struct pt_regs *regs)
409 411
410 if (eip < PAGE_OFFSET) 412 if (eip < PAGE_OFFSET)
411 return; 413 return;
412 if (__get_user(ud2, (unsigned short __user *)eip)) 414 if (probe_kernel_address((unsigned short __user *)eip, ud2))
413 return; 415 return;
414 if (ud2 != 0x0b0f) 416 if (ud2 != 0x0b0f)
415 return; 417 return;
@@ -422,7 +424,8 @@ static void handle_BUG(struct pt_regs *regs)
422 char *file; 424 char *file;
423 char c; 425 char c;
424 426
425 if (__get_user(line, (unsigned short __user *)(eip + 2))) 427 if (probe_kernel_address((unsigned short __user *)(eip + 2),
428 line))
426 break; 429 break;
427 if (__get_user(file, (char * __user *)(eip + 4)) || 430 if (__get_user(file, (char * __user *)(eip + 4)) ||
428 (unsigned long)file < PAGE_OFFSET || __get_user(c, file)) 431 (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
diff --git a/arch/i386/lib/delay.c b/arch/i386/lib/delay.c
index 3c0714c4b669..f6edb11364df 100644
--- a/arch/i386/lib/delay.c
+++ b/arch/i386/lib/delay.c
@@ -11,7 +11,6 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/config.h>
15#include <linux/sched.h> 14#include <linux/sched.h>
16#include <linux/delay.h> 15#include <linux/delay.h>
17 16
diff --git a/arch/i386/lib/usercopy.c b/arch/i386/lib/usercopy.c
index efc7e7d5f4d0..08502fc6d0cb 100644
--- a/arch/i386/lib/usercopy.c
+++ b/arch/i386/lib/usercopy.c
@@ -739,7 +739,7 @@ survive:
739 retval = get_user_pages(current, current->mm, 739 retval = get_user_pages(current, current->mm,
740 (unsigned long )to, 1, 1, 0, &pg, NULL); 740 (unsigned long )to, 1, 1, 0, &pg, NULL);
741 741
742 if (retval == -ENOMEM && current->pid == 1) { 742 if (retval == -ENOMEM && is_init(current)) {
743 up_read(&current->mm->mmap_sem); 743 up_read(&current->mm->mmap_sem);
744 blk_congestion_wait(WRITE, HZ/50); 744 blk_congestion_wait(WRITE, HZ/50);
745 goto survive; 745 goto survive;
diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c
index 6c86575ffdcb..856c73fcb7e7 100644
--- a/arch/i386/mach-voyager/voyager_smp.c
+++ b/arch/i386/mach-voyager/voyager_smp.c
@@ -99,6 +99,7 @@ static void do_boot_cpu(__u8 cpuid);
99static void do_quad_bootstrap(void); 99static void do_quad_bootstrap(void);
100 100
101int hard_smp_processor_id(void); 101int hard_smp_processor_id(void);
102int safe_smp_processor_id(void);
102 103
103/* Inline functions */ 104/* Inline functions */
104static inline void 105static inline void
@@ -1247,6 +1248,12 @@ hard_smp_processor_id(void)
1247 return 0; 1248 return 0;
1248} 1249}
1249 1250
1251int
1252safe_smp_processor_id(void)
1253{
1254 return hard_smp_processor_id();
1255}
1256
1250/* broadcast a halt to all other CPUs */ 1257/* broadcast a halt to all other CPUs */
1251void 1258void
1252smp_send_stop(void) 1259smp_send_stop(void)
diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c
index 941d1a5ebabb..51e3739dd227 100644
--- a/arch/i386/mm/discontig.c
+++ b/arch/i386/mm/discontig.c
@@ -157,21 +157,6 @@ static void __init find_max_pfn_node(int nid)
157 BUG(); 157 BUG();
158} 158}
159 159
160/* Find the owning node for a pfn. */
161int early_pfn_to_nid(unsigned long pfn)
162{
163 int nid;
164
165 for_each_node(nid) {
166 if (node_end_pfn[nid] == 0)
167 break;
168 if (node_start_pfn[nid] <= pfn && node_end_pfn[nid] >= pfn)
169 return nid;
170 }
171
172 return 0;
173}
174
175/* 160/*
176 * Allocate memory for the pg_data_t for this node via a crude pre-bootmem 161 * Allocate memory for the pg_data_t for this node via a crude pre-bootmem
177 * method. For node zero take this from the bottom of memory, for 162 * method. For node zero take this from the bottom of memory, for
@@ -227,6 +212,8 @@ static unsigned long calculate_numa_remap_pages(void)
227 unsigned long pfn; 212 unsigned long pfn;
228 213
229 for_each_online_node(nid) { 214 for_each_online_node(nid) {
215 unsigned old_end_pfn = node_end_pfn[nid];
216
230 /* 217 /*
231 * The acpi/srat node info can show hot-add memroy zones 218 * The acpi/srat node info can show hot-add memroy zones
232 * where memory could be added but not currently present. 219 * where memory could be added but not currently present.
@@ -276,6 +263,7 @@ static unsigned long calculate_numa_remap_pages(void)
276 263
277 node_end_pfn[nid] -= size; 264 node_end_pfn[nid] -= size;
278 node_remap_start_pfn[nid] = node_end_pfn[nid]; 265 node_remap_start_pfn[nid] = node_end_pfn[nid];
266 shrink_active_range(nid, old_end_pfn, node_end_pfn[nid]);
279 } 267 }
280 printk("Reserving total of %ld pages for numa KVA remap\n", 268 printk("Reserving total of %ld pages for numa KVA remap\n",
281 reserve_pages); 269 reserve_pages);
@@ -369,45 +357,22 @@ void __init numa_kva_reserve(void)
369void __init zone_sizes_init(void) 357void __init zone_sizes_init(void)
370{ 358{
371 int nid; 359 int nid;
372 360 unsigned long max_zone_pfns[MAX_NR_ZONES] = {
373 361 virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT,
374 for_each_online_node(nid) { 362 max_low_pfn,
375 unsigned long zones_size[MAX_NR_ZONES] = {0, }; 363 highend_pfn
376 unsigned long *zholes_size; 364 };
377 unsigned int max_dma; 365
378 366 /* If SRAT has not registered memory, register it now */
379 unsigned long low = max_low_pfn; 367 if (find_max_pfn_with_active_regions() == 0) {
380 unsigned long start = node_start_pfn[nid]; 368 for_each_online_node(nid) {
381 unsigned long high = node_end_pfn[nid]; 369 if (node_has_online_mem(nid))
382 370 add_active_range(nid, node_start_pfn[nid],
383 max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; 371 node_end_pfn[nid]);
384
385 if (node_has_online_mem(nid)){
386 if (start > low) {
387#ifdef CONFIG_HIGHMEM
388 BUG_ON(start > high);
389 zones_size[ZONE_HIGHMEM] = high - start;
390#endif
391 } else {
392 if (low < max_dma)
393 zones_size[ZONE_DMA] = low;
394 else {
395 BUG_ON(max_dma > low);
396 BUG_ON(low > high);
397 zones_size[ZONE_DMA] = max_dma;
398 zones_size[ZONE_NORMAL] = low - max_dma;
399#ifdef CONFIG_HIGHMEM
400 zones_size[ZONE_HIGHMEM] = high - low;
401#endif
402 }
403 }
404 } 372 }
405
406 zholes_size = get_zholes_size(nid);
407
408 free_area_init_node(nid, NODE_DATA(nid), zones_size, start,
409 zholes_size);
410 } 373 }
374
375 free_area_init_nodes(max_zone_pfns);
411 return; 376 return;
412} 377}
413 378
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
index 5e17a3f43b41..2581575786c1 100644
--- a/arch/i386/mm/fault.c
+++ b/arch/i386/mm/fault.c
@@ -440,7 +440,7 @@ good_area:
440 case 1: /* read, present */ 440 case 1: /* read, present */
441 goto bad_area; 441 goto bad_area;
442 case 0: /* read, not present */ 442 case 0: /* read, not present */
443 if (!(vma->vm_flags & (VM_READ | VM_EXEC))) 443 if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
444 goto bad_area; 444 goto bad_area;
445 } 445 }
446 446
@@ -589,7 +589,7 @@ no_context:
589 */ 589 */
590out_of_memory: 590out_of_memory:
591 up_read(&mm->mmap_sem); 591 up_read(&mm->mmap_sem);
592 if (tsk->pid == 1) { 592 if (is_init(tsk)) {
593 yield(); 593 yield();
594 down_read(&mm->mmap_sem); 594 down_read(&mm->mmap_sem);
595 goto survive; 595 goto survive;
diff --git a/arch/i386/mm/highmem.c b/arch/i386/mm/highmem.c
index ba44000b9069..f9f647cdbc7b 100644
--- a/arch/i386/mm/highmem.c
+++ b/arch/i386/mm/highmem.c
@@ -38,22 +38,19 @@ void *kmap_atomic(struct page *page, enum km_type type)
38 38
39 idx = type + KM_TYPE_NR*smp_processor_id(); 39 idx = type + KM_TYPE_NR*smp_processor_id();
40 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); 40 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
41#ifdef CONFIG_DEBUG_HIGHMEM
42 if (!pte_none(*(kmap_pte-idx))) 41 if (!pte_none(*(kmap_pte-idx)))
43 BUG(); 42 BUG();
44#endif
45 set_pte(kmap_pte-idx, mk_pte(page, kmap_prot)); 43 set_pte(kmap_pte-idx, mk_pte(page, kmap_prot));
46 __flush_tlb_one(vaddr);
47 44
48 return (void*) vaddr; 45 return (void*) vaddr;
49} 46}
50 47
51void kunmap_atomic(void *kvaddr, enum km_type type) 48void kunmap_atomic(void *kvaddr, enum km_type type)
52{ 49{
53#ifdef CONFIG_DEBUG_HIGHMEM
54 unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; 50 unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
55 enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); 51 enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
56 52
53#ifdef CONFIG_DEBUG_HIGHMEM
57 if (vaddr >= PAGE_OFFSET && vaddr < (unsigned long)high_memory) { 54 if (vaddr >= PAGE_OFFSET && vaddr < (unsigned long)high_memory) {
58 dec_preempt_count(); 55 dec_preempt_count();
59 preempt_check_resched(); 56 preempt_check_resched();
@@ -62,14 +59,14 @@ void kunmap_atomic(void *kvaddr, enum km_type type)
62 59
63 if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx)) 60 if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx))
64 BUG(); 61 BUG();
65 62#endif
66 /* 63 /*
67 * force other mappings to Oops if they'll try to access 64 * Force other mappings to Oops if they'll try to access this pte
68 * this pte without first remap it 65 * without first remap it. Keeping stale mappings around is a bad idea
66 * also, in case the page changes cacheability attributes or becomes
67 * a protected page in a hypervisor.
69 */ 68 */
70 pte_clear(&init_mm, vaddr, kmap_pte-idx); 69 kpte_clear_flush(kmap_pte-idx, vaddr);
71 __flush_tlb_one(vaddr);
72#endif
73 70
74 dec_preempt_count(); 71 dec_preempt_count();
75 preempt_check_resched(); 72 preempt_check_resched();
@@ -88,7 +85,6 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
88 idx = type + KM_TYPE_NR*smp_processor_id(); 85 idx = type + KM_TYPE_NR*smp_processor_id();
89 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); 86 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
90 set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot)); 87 set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
91 __flush_tlb_one(vaddr);
92 88
93 return (void*) vaddr; 89 return (void*) vaddr;
94} 90}
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 4a5a914b3432..90089c14c23d 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -493,6 +493,7 @@ int __init set_kernel_exec(unsigned long vaddr, int enable)
493 pte->pte_high &= ~(1 << (_PAGE_BIT_NX - 32)); 493 pte->pte_high &= ~(1 << (_PAGE_BIT_NX - 32));
494 else 494 else
495 pte->pte_high |= 1 << (_PAGE_BIT_NX - 32); 495 pte->pte_high |= 1 << (_PAGE_BIT_NX - 32);
496 pte_update_defer(&init_mm, vaddr, pte);
496 __flush_tlb_all(); 497 __flush_tlb_all();
497out: 498out:
498 return ret; 499 return ret;
diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c
index 247fde76aaed..fff08ae7b5ed 100644
--- a/arch/i386/mm/ioremap.c
+++ b/arch/i386/mm/ioremap.c
@@ -12,7 +12,7 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <asm/io.h> 15#include <linux/io.h>
16#include <asm/fixmap.h> 16#include <asm/fixmap.h>
17#include <asm/cacheflush.h> 17#include <asm/cacheflush.h>
18#include <asm/tlbflush.h> 18#include <asm/tlbflush.h>
@@ -21,82 +21,6 @@
21#define ISA_START_ADDRESS 0xa0000 21#define ISA_START_ADDRESS 0xa0000
22#define ISA_END_ADDRESS 0x100000 22#define ISA_END_ADDRESS 0x100000
23 23
24static int ioremap_pte_range(pmd_t *pmd, unsigned long addr,
25 unsigned long end, unsigned long phys_addr, unsigned long flags)
26{
27 pte_t *pte;
28 unsigned long pfn;
29
30 pfn = phys_addr >> PAGE_SHIFT;
31 pte = pte_alloc_kernel(pmd, addr);
32 if (!pte)
33 return -ENOMEM;
34 do {
35 BUG_ON(!pte_none(*pte));
36 set_pte(pte, pfn_pte(pfn, __pgprot(_PAGE_PRESENT | _PAGE_RW |
37 _PAGE_DIRTY | _PAGE_ACCESSED | flags)));
38 pfn++;
39 } while (pte++, addr += PAGE_SIZE, addr != end);
40 return 0;
41}
42
43static inline int ioremap_pmd_range(pud_t *pud, unsigned long addr,
44 unsigned long end, unsigned long phys_addr, unsigned long flags)
45{
46 pmd_t *pmd;
47 unsigned long next;
48
49 phys_addr -= addr;
50 pmd = pmd_alloc(&init_mm, pud, addr);
51 if (!pmd)
52 return -ENOMEM;
53 do {
54 next = pmd_addr_end(addr, end);
55 if (ioremap_pte_range(pmd, addr, next, phys_addr + addr, flags))
56 return -ENOMEM;
57 } while (pmd++, addr = next, addr != end);
58 return 0;
59}
60
61static inline int ioremap_pud_range(pgd_t *pgd, unsigned long addr,
62 unsigned long end, unsigned long phys_addr, unsigned long flags)
63{
64 pud_t *pud;
65 unsigned long next;
66
67 phys_addr -= addr;
68 pud = pud_alloc(&init_mm, pgd, addr);
69 if (!pud)
70 return -ENOMEM;
71 do {
72 next = pud_addr_end(addr, end);
73 if (ioremap_pmd_range(pud, addr, next, phys_addr + addr, flags))
74 return -ENOMEM;
75 } while (pud++, addr = next, addr != end);
76 return 0;
77}
78
79static int ioremap_page_range(unsigned long addr,
80 unsigned long end, unsigned long phys_addr, unsigned long flags)
81{
82 pgd_t *pgd;
83 unsigned long next;
84 int err;
85
86 BUG_ON(addr >= end);
87 flush_cache_all();
88 phys_addr -= addr;
89 pgd = pgd_offset_k(addr);
90 do {
91 next = pgd_addr_end(addr, end);
92 err = ioremap_pud_range(pgd, addr, next, phys_addr+addr, flags);
93 if (err)
94 break;
95 } while (pgd++, addr = next, addr != end);
96 flush_tlb_all();
97 return err;
98}
99
100/* 24/*
101 * Generic mapping function (not visible outside): 25 * Generic mapping function (not visible outside):
102 */ 26 */
@@ -115,6 +39,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
115 void __iomem * addr; 39 void __iomem * addr;
116 struct vm_struct * area; 40 struct vm_struct * area;
117 unsigned long offset, last_addr; 41 unsigned long offset, last_addr;
42 pgprot_t prot;
118 43
119 /* Don't allow wraparound or zero size */ 44 /* Don't allow wraparound or zero size */
120 last_addr = phys_addr + size - 1; 45 last_addr = phys_addr + size - 1;
@@ -142,6 +67,9 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
142 return NULL; 67 return NULL;
143 } 68 }
144 69
70 prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY
71 | _PAGE_ACCESSED | flags);
72
145 /* 73 /*
146 * Mappings have to be page-aligned 74 * Mappings have to be page-aligned
147 */ 75 */
@@ -158,7 +86,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
158 area->phys_addr = phys_addr; 86 area->phys_addr = phys_addr;
159 addr = (void __iomem *) area->addr; 87 addr = (void __iomem *) area->addr;
160 if (ioremap_page_range((unsigned long) addr, 88 if (ioremap_page_range((unsigned long) addr,
161 (unsigned long) addr + size, phys_addr, flags)) { 89 (unsigned long) addr + size, phys_addr, prot)) {
162 vunmap((void __force *) addr); 90 vunmap((void __force *) addr);
163 return NULL; 91 return NULL;
164 } 92 }
diff --git a/arch/i386/oprofile/op_model_ppro.c b/arch/i386/oprofile/op_model_ppro.c
index f88e05ba8eb3..ca2447e05e15 100644
--- a/arch/i386/oprofile/op_model_ppro.c
+++ b/arch/i386/oprofile/op_model_ppro.c
@@ -138,11 +138,14 @@ static int ppro_check_ctrs(struct pt_regs * const regs,
138static void ppro_start(struct op_msrs const * const msrs) 138static void ppro_start(struct op_msrs const * const msrs)
139{ 139{
140 unsigned int low,high; 140 unsigned int low,high;
141 int i;
141 142
142 if (reset_value[0]) { 143 for (i = 0; i < NUM_COUNTERS; ++i) {
143 CTRL_READ(low, high, msrs, 0); 144 if (reset_value[i]) {
144 CTRL_SET_ACTIVE(low); 145 CTRL_READ(low, high, msrs, i);
145 CTRL_WRITE(low, high, msrs, 0); 146 CTRL_SET_ACTIVE(low);
147 CTRL_WRITE(low, high, msrs, i);
148 }
146 } 149 }
147} 150}
148 151
@@ -150,11 +153,14 @@ static void ppro_start(struct op_msrs const * const msrs)
150static void ppro_stop(struct op_msrs const * const msrs) 153static void ppro_stop(struct op_msrs const * const msrs)
151{ 154{
152 unsigned int low,high; 155 unsigned int low,high;
156 int i;
153 157
154 if (reset_value[0]) { 158 for (i = 0; i < NUM_COUNTERS; ++i) {
155 CTRL_READ(low, high, msrs, 0); 159 if (!reset_value[i])
160 continue;
161 CTRL_READ(low, high, msrs, i);
156 CTRL_SET_INACTIVE(low); 162 CTRL_SET_INACTIVE(low);
157 CTRL_WRITE(low, high, msrs, 0); 163 CTRL_WRITE(low, high, msrs, i);
158 } 164 }
159} 165}
160 166
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c
index 05be8db58a8c..d0c3da3aa2aa 100644
--- a/arch/i386/pci/mmconfig.c
+++ b/arch/i386/pci/mmconfig.c
@@ -67,7 +67,10 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn)
67 return 0; 67 return 0;
68} 68}
69 69
70static inline void pci_exp_set_dev_base(unsigned int base, int bus, int devfn) 70/*
71 * This is always called under pci_config_lock
72 */
73static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn)
71{ 74{
72 u32 dev_base = base | (bus << 20) | (devfn << 12); 75 u32 dev_base = base | (bus << 20) | (devfn << 12);
73 if (dev_base != mmcfg_last_accessed_device) { 76 if (dev_base != mmcfg_last_accessed_device) {