aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386')
-rw-r--r--arch/i386/Kconfig4
-rw-r--r--arch/i386/kernel/apm.c26
-rw-r--r--arch/i386/kernel/cpu/mtrr/generic.c4
-rw-r--r--arch/i386/kernel/efi_stub.S1
-rw-r--r--arch/i386/kernel/reboot.c12
-rw-r--r--arch/i386/kernel/setup.c23
-rw-r--r--arch/i386/kernel/smp.c66
-rw-r--r--arch/i386/kernel/smpboot.c6
-rw-r--r--arch/i386/kernel/srat.c5
-rw-r--r--arch/i386/kernel/time.c50
-rw-r--r--arch/i386/kernel/time_hpet.c37
-rw-r--r--arch/i386/kernel/traps.c11
-rw-r--r--arch/i386/kernel/vmlinux.lds.S12
-rw-r--r--arch/i386/mach-voyager/voyager_thread.c1
-rw-r--r--arch/i386/mm/boot_ioremap.c7
-rw-r--r--arch/i386/mm/discontig.c33
-rw-r--r--arch/i386/mm/init.c44
-rw-r--r--arch/i386/mm/pgtable.c30
-rw-r--r--arch/i386/power/swsusp.S2
19 files changed, 298 insertions, 76 deletions
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index b2751eadbc56..6189b0c28d6f 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -494,7 +494,7 @@ config HIGHMEM64G
494endchoice 494endchoice
495 495
496choice 496choice
497 depends on EXPERIMENTAL && !X86_PAE 497 depends on EXPERIMENTAL
498 prompt "Memory split" if EMBEDDED 498 prompt "Memory split" if EMBEDDED
499 default VMSPLIT_3G 499 default VMSPLIT_3G
500 help 500 help
@@ -516,6 +516,7 @@ choice
516 config VMSPLIT_3G 516 config VMSPLIT_3G
517 bool "3G/1G user/kernel split" 517 bool "3G/1G user/kernel split"
518 config VMSPLIT_3G_OPT 518 config VMSPLIT_3G_OPT
519 depends on !HIGHMEM
519 bool "3G/1G user/kernel split (for full 1G low memory)" 520 bool "3G/1G user/kernel split (for full 1G low memory)"
520 config VMSPLIT_2G 521 config VMSPLIT_2G
521 bool "2G/2G user/kernel split" 522 bool "2G/2G user/kernel split"
@@ -794,6 +795,7 @@ config HOTPLUG_CPU
794config COMPAT_VDSO 795config COMPAT_VDSO
795 bool "Compat VDSO support" 796 bool "Compat VDSO support"
796 default y 797 default y
798 depends on !PARAVIRT
797 help 799 help
798 Map the VDSO to the predictable old-style address too. 800 Map the VDSO to the predictable old-style address too.
799 ---help--- 801 ---help---
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index 8591f2fa920c..ff9ce4b5eaa8 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -1154,9 +1154,11 @@ out:
1154 1154
1155static void set_time(void) 1155static void set_time(void)
1156{ 1156{
1157 struct timespec ts;
1157 if (got_clock_diff) { /* Must know time zone in order to set clock */ 1158 if (got_clock_diff) { /* Must know time zone in order to set clock */
1158 xtime.tv_sec = get_cmos_time() + clock_cmos_diff; 1159 ts.tv_sec = get_cmos_time() + clock_cmos_diff;
1159 xtime.tv_nsec = 0; 1160 ts.tv_nsec = 0;
1161 do_settimeofday(&ts);
1160 } 1162 }
1161} 1163}
1162 1164
@@ -1232,13 +1234,8 @@ static int suspend(int vetoable)
1232 restore_processor_state(); 1234 restore_processor_state();
1233 1235
1234 local_irq_disable(); 1236 local_irq_disable();
1235 write_seqlock(&xtime_lock);
1236 spin_lock(&i8253_lock);
1237 reinit_timer();
1238 set_time(); 1237 set_time();
1239 1238 reinit_timer();
1240 spin_unlock(&i8253_lock);
1241 write_sequnlock(&xtime_lock);
1242 1239
1243 if (err == APM_NO_ERROR) 1240 if (err == APM_NO_ERROR)
1244 err = APM_SUCCESS; 1241 err = APM_SUCCESS;
@@ -1365,9 +1362,7 @@ static void check_events(void)
1365 ignore_bounce = 1; 1362 ignore_bounce = 1;
1366 if ((event != APM_NORMAL_RESUME) 1363 if ((event != APM_NORMAL_RESUME)
1367 || (ignore_normal_resume == 0)) { 1364 || (ignore_normal_resume == 0)) {
1368 write_seqlock_irq(&xtime_lock);
1369 set_time(); 1365 set_time();
1370 write_sequnlock_irq(&xtime_lock);
1371 device_resume(); 1366 device_resume();
1372 pm_send_all(PM_RESUME, (void *)0); 1367 pm_send_all(PM_RESUME, (void *)0);
1373 queue_event(event, NULL); 1368 queue_event(event, NULL);
@@ -1383,9 +1378,7 @@ static void check_events(void)
1383 break; 1378 break;
1384 1379
1385 case APM_UPDATE_TIME: 1380 case APM_UPDATE_TIME:
1386 write_seqlock_irq(&xtime_lock);
1387 set_time(); 1381 set_time();
1388 write_sequnlock_irq(&xtime_lock);
1389 break; 1382 break;
1390 1383
1391 case APM_CRITICAL_SUSPEND: 1384 case APM_CRITICAL_SUSPEND:
@@ -2339,6 +2332,7 @@ static int __init apm_init(void)
2339 ret = kernel_thread(apm, NULL, CLONE_KERNEL | SIGCHLD); 2332 ret = kernel_thread(apm, NULL, CLONE_KERNEL | SIGCHLD);
2340 if (ret < 0) { 2333 if (ret < 0) {
2341 printk(KERN_ERR "apm: disabled - Unable to start kernel thread.\n"); 2334 printk(KERN_ERR "apm: disabled - Unable to start kernel thread.\n");
2335 remove_proc_entry("apm", NULL);
2342 return -ENOMEM; 2336 return -ENOMEM;
2343 } 2337 }
2344 2338
@@ -2348,7 +2342,13 @@ static int __init apm_init(void)
2348 return 0; 2342 return 0;
2349 } 2343 }
2350 2344
2351 misc_register(&apm_device); 2345 /*
2346 * Note we don't actually care if the misc_device cannot be registered.
2347 * this driver can do its job without it, even if userspace can't
2348 * control it. just log the error
2349 */
2350 if (misc_register(&apm_device))
2351 printk(KERN_WARNING "apm: Could not register misc device.\n");
2352 2352
2353 if (HZ != 100) 2353 if (HZ != 100)
2354 idle_period = (idle_period * HZ) / 100; 2354 idle_period = (idle_period * HZ) / 100;
diff --git a/arch/i386/kernel/cpu/mtrr/generic.c b/arch/i386/kernel/cpu/mtrr/generic.c
index 169ac8e0db68..0b61eed8bbd8 100644
--- a/arch/i386/kernel/cpu/mtrr/generic.c
+++ b/arch/i386/kernel/cpu/mtrr/generic.c
@@ -243,7 +243,7 @@ static DEFINE_SPINLOCK(set_atomicity_lock);
243 * has been called. 243 * has been called.
244 */ 244 */
245 245
246static void prepare_set(void) 246static void prepare_set(void) __acquires(set_atomicity_lock)
247{ 247{
248 unsigned long cr0; 248 unsigned long cr0;
249 249
@@ -274,7 +274,7 @@ static void prepare_set(void)
274 mtrr_wrmsr(MTRRdefType_MSR, deftype_lo & 0xf300UL, deftype_hi); 274 mtrr_wrmsr(MTRRdefType_MSR, deftype_lo & 0xf300UL, deftype_hi);
275} 275}
276 276
277static void post_set(void) 277static void post_set(void) __releases(set_atomicity_lock)
278{ 278{
279 /* Flush TLBs (no need to flush caches - they are disabled) */ 279 /* Flush TLBs (no need to flush caches - they are disabled) */
280 __flush_tlb(); 280 __flush_tlb();
diff --git a/arch/i386/kernel/efi_stub.S b/arch/i386/kernel/efi_stub.S
index d3ee73a3eee3..ef00bb77d7e4 100644
--- a/arch/i386/kernel/efi_stub.S
+++ b/arch/i386/kernel/efi_stub.S
@@ -7,7 +7,6 @@
7 7
8#include <linux/linkage.h> 8#include <linux/linkage.h>
9#include <asm/page.h> 9#include <asm/page.h>
10#include <asm/pgtable.h>
11 10
12/* 11/*
13 * efi_call_phys(void *, ...) is a function with variable parameters. 12 * efi_call_phys(void *, ...) is a function with variable parameters.
diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c
index 54cfeabbc5e4..84278e0093a2 100644
--- a/arch/i386/kernel/reboot.c
+++ b/arch/i386/kernel/reboot.c
@@ -145,14 +145,10 @@ real_mode_gdt_entries [3] =
145 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */ 145 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
146}; 146};
147 147
148static struct 148static struct Xgt_desc_struct
149{ 149real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries },
150 unsigned short size __attribute__ ((packed)); 150real_mode_idt = { 0x3ff, 0 },
151 unsigned long long * base __attribute__ ((packed)); 151no_idt = { 0, 0 };
152}
153real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, real_mode_gdt_entries },
154real_mode_idt = { 0x3ff, NULL },
155no_idt = { 0, NULL };
156 152
157 153
158/* This is 16-bit protected mode code to disable paging and the cache, 154/* This is 16-bit protected mode code to disable paging and the cache,
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index f1682206d304..16d99444cf66 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -53,6 +53,7 @@
53#include <asm/apic.h> 53#include <asm/apic.h>
54#include <asm/e820.h> 54#include <asm/e820.h>
55#include <asm/mpspec.h> 55#include <asm/mpspec.h>
56#include <asm/mmzone.h>
56#include <asm/setup.h> 57#include <asm/setup.h>
57#include <asm/arch_hooks.h> 58#include <asm/arch_hooks.h>
58#include <asm/sections.h> 59#include <asm/sections.h>
@@ -934,6 +935,24 @@ static void __init parse_cmdline_early (char ** cmdline_p)
934} 935}
935 936
936/* 937/*
938 * reservetop=size reserves a hole at the top of the kernel address space which
939 * a hypervisor can load into later. Needed for dynamically loaded hypervisors,
940 * so relocating the fixmap can be done before paging initialization.
941 */
942static int __init parse_reservetop(char *arg)
943{
944 unsigned long address;
945
946 if (!arg)
947 return -EINVAL;
948
949 address = memparse(arg, &arg);
950 reserve_top_address(address);
951 return 0;
952}
953early_param("reservetop", parse_reservetop);
954
955/*
937 * Callback for efi_memory_walk. 956 * Callback for efi_memory_walk.
938 */ 957 */
939static int __init 958static int __init
@@ -1181,7 +1200,7 @@ static unsigned long __init setup_memory(void)
1181 1200
1182void __init zone_sizes_init(void) 1201void __init zone_sizes_init(void)
1183{ 1202{
1184 unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; 1203 unsigned long zones_size[MAX_NR_ZONES] = { 0, };
1185 unsigned int max_dma, low; 1204 unsigned int max_dma, low;
1186 1205
1187 max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; 1206 max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
@@ -1258,7 +1277,7 @@ void __init setup_bootmem_allocator(void)
1258 */ 1277 */
1259 find_smp_config(); 1278 find_smp_config();
1260#endif 1279#endif
1261 1280 numa_kva_reserve();
1262#ifdef CONFIG_BLK_DEV_INITRD 1281#ifdef CONFIG_BLK_DEV_INITRD
1263 if (LOADER_TYPE && INITRD_START) { 1282 if (LOADER_TYPE && INITRD_START) {
1264 if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) { 1283 if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
index c10789d7a9d3..465188e2d701 100644
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -634,3 +634,69 @@ fastcall void smp_call_function_interrupt(struct pt_regs *regs)
634 } 634 }
635} 635}
636 636
637/*
638 * this function sends a 'generic call function' IPI to one other CPU
639 * in the system.
640 *
641 * cpu is a standard Linux logical CPU number.
642 */
643static void
644__smp_call_function_single(int cpu, void (*func) (void *info), void *info,
645 int nonatomic, int wait)
646{
647 struct call_data_struct data;
648 int cpus = 1;
649
650 data.func = func;
651 data.info = info;
652 atomic_set(&data.started, 0);
653 data.wait = wait;
654 if (wait)
655 atomic_set(&data.finished, 0);
656
657 call_data = &data;
658 wmb();
659 /* Send a message to all other CPUs and wait for them to respond */
660 send_IPI_mask(cpumask_of_cpu(cpu), CALL_FUNCTION_VECTOR);
661
662 /* Wait for response */
663 while (atomic_read(&data.started) != cpus)
664 cpu_relax();
665
666 if (!wait)
667 return;
668
669 while (atomic_read(&data.finished) != cpus)
670 cpu_relax();
671}
672
673/*
674 * smp_call_function_single - Run a function on another CPU
675 * @func: The function to run. This must be fast and non-blocking.
676 * @info: An arbitrary pointer to pass to the function.
677 * @nonatomic: Currently unused.
678 * @wait: If true, wait until function has completed on other CPUs.
679 *
680 * Retrurns 0 on success, else a negative status code.
681 *
682 * Does not return until the remote CPU is nearly ready to execute <func>
683 * or is or has executed.
684 */
685
686int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
687 int nonatomic, int wait)
688{
689 /* prevent preemption and reschedule on another processor */
690 int me = get_cpu();
691 if (cpu == me) {
692 WARN_ON(1);
693 put_cpu();
694 return -EBUSY;
695 }
696 spin_lock_bh(&call_lock);
697 __smp_call_function_single(cpu, func, info, nonatomic, wait);
698 spin_unlock_bh(&call_lock);
699 put_cpu();
700 return 0;
701}
702EXPORT_SYMBOL(smp_call_function_single);
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index f948419c888a..efe07990e7fc 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -642,9 +642,13 @@ static void map_cpu_to_logical_apicid(void)
642{ 642{
643 int cpu = smp_processor_id(); 643 int cpu = smp_processor_id();
644 int apicid = logical_smp_processor_id(); 644 int apicid = logical_smp_processor_id();
645 int node = apicid_to_node(apicid);
646
647 if (!node_online(node))
648 node = first_online_node;
645 649
646 cpu_2_logical_apicid[cpu] = apicid; 650 cpu_2_logical_apicid[cpu] = apicid;
647 map_cpu_to_node(cpu, apicid_to_node(apicid)); 651 map_cpu_to_node(cpu, node);
648} 652}
649 653
650static void unmap_cpu_to_logical_apicid(int cpu) 654static void unmap_cpu_to_logical_apicid(int cpu)
diff --git a/arch/i386/kernel/srat.c b/arch/i386/kernel/srat.c
index b1809c9a0899..83db411b3aa7 100644
--- a/arch/i386/kernel/srat.c
+++ b/arch/i386/kernel/srat.c
@@ -42,7 +42,7 @@
42#define PXM_BITMAP_LEN (MAX_PXM_DOMAINS / 8) 42#define PXM_BITMAP_LEN (MAX_PXM_DOMAINS / 8)
43static u8 pxm_bitmap[PXM_BITMAP_LEN]; /* bitmap of proximity domains */ 43static u8 pxm_bitmap[PXM_BITMAP_LEN]; /* bitmap of proximity domains */
44 44
45#define MAX_CHUNKS_PER_NODE 4 45#define MAX_CHUNKS_PER_NODE 3
46#define MAXCHUNKS (MAX_CHUNKS_PER_NODE * MAX_NUMNODES) 46#define MAXCHUNKS (MAX_CHUNKS_PER_NODE * MAX_NUMNODES)
47struct node_memory_chunk_s { 47struct node_memory_chunk_s {
48 unsigned long start_pfn; 48 unsigned long start_pfn;
@@ -135,9 +135,6 @@ static void __init parse_memory_affinity_structure (char *sratp)
135 "enabled and removable" : "enabled" ) ); 135 "enabled and removable" : "enabled" ) );
136} 136}
137 137
138#if MAX_NR_ZONES != 4
139#error "MAX_NR_ZONES != 4, chunk_to_zone requires review"
140#endif
141/* Take a chunk of pages from page frame cstart to cend and count the number 138/* Take a chunk of pages from page frame cstart to cend and count the number
142 * of pages in each zone, returned via zones[]. 139 * of pages in each zone, returned via zones[].
143 */ 140 */
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
index edd00f6cee37..1302e4ab3c4f 100644
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -270,16 +270,19 @@ void notify_arch_cmos_timer(void)
270 mod_timer(&sync_cmos_timer, jiffies + 1); 270 mod_timer(&sync_cmos_timer, jiffies + 1);
271} 271}
272 272
273static long clock_cmos_diff, sleep_start; 273static long clock_cmos_diff;
274static unsigned long sleep_start;
274 275
275static int timer_suspend(struct sys_device *dev, pm_message_t state) 276static int timer_suspend(struct sys_device *dev, pm_message_t state)
276{ 277{
277 /* 278 /*
278 * Estimate time zone so that set_time can update the clock 279 * Estimate time zone so that set_time can update the clock
279 */ 280 */
280 clock_cmos_diff = -get_cmos_time(); 281 unsigned long ctime = get_cmos_time();
282
283 clock_cmos_diff = -ctime;
281 clock_cmos_diff += get_seconds(); 284 clock_cmos_diff += get_seconds();
282 sleep_start = get_cmos_time(); 285 sleep_start = ctime;
283 return 0; 286 return 0;
284} 287}
285 288
@@ -287,18 +290,29 @@ static int timer_resume(struct sys_device *dev)
287{ 290{
288 unsigned long flags; 291 unsigned long flags;
289 unsigned long sec; 292 unsigned long sec;
290 unsigned long sleep_length; 293 unsigned long ctime = get_cmos_time();
291 294 long sleep_length = (ctime - sleep_start) * HZ;
295 struct timespec ts;
296
297 if (sleep_length < 0) {
298 printk(KERN_WARNING "CMOS clock skew detected in timer resume!\n");
299 /* The time after the resume must not be earlier than the time
300 * before the suspend or some nasty things will happen
301 */
302 sleep_length = 0;
303 ctime = sleep_start;
304 }
292#ifdef CONFIG_HPET_TIMER 305#ifdef CONFIG_HPET_TIMER
293 if (is_hpet_enabled()) 306 if (is_hpet_enabled())
294 hpet_reenable(); 307 hpet_reenable();
295#endif 308#endif
296 setup_pit_timer(); 309 setup_pit_timer();
297 sec = get_cmos_time() + clock_cmos_diff; 310
298 sleep_length = (get_cmos_time() - sleep_start) * HZ; 311 sec = ctime + clock_cmos_diff;
312 ts.tv_sec = sec;
313 ts.tv_nsec = 0;
314 do_settimeofday(&ts);
299 write_seqlock_irqsave(&xtime_lock, flags); 315 write_seqlock_irqsave(&xtime_lock, flags);
300 xtime.tv_sec = sec;
301 xtime.tv_nsec = 0;
302 jiffies_64 += sleep_length; 316 jiffies_64 += sleep_length;
303 wall_jiffies += sleep_length; 317 wall_jiffies += sleep_length;
304 write_sequnlock_irqrestore(&xtime_lock, flags); 318 write_sequnlock_irqrestore(&xtime_lock, flags);
@@ -334,10 +348,11 @@ extern void (*late_time_init)(void);
334/* Duplicate of time_init() below, with hpet_enable part added */ 348/* Duplicate of time_init() below, with hpet_enable part added */
335static void __init hpet_time_init(void) 349static void __init hpet_time_init(void)
336{ 350{
337 xtime.tv_sec = get_cmos_time(); 351 struct timespec ts;
338 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); 352 ts.tv_sec = get_cmos_time();
339 set_normalized_timespec(&wall_to_monotonic, 353 ts.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
340 -xtime.tv_sec, -xtime.tv_nsec); 354
355 do_settimeofday(&ts);
341 356
342 if ((hpet_enable() >= 0) && hpet_use_timer) { 357 if ((hpet_enable() >= 0) && hpet_use_timer) {
343 printk("Using HPET for base-timer\n"); 358 printk("Using HPET for base-timer\n");
@@ -349,6 +364,7 @@ static void __init hpet_time_init(void)
349 364
350void __init time_init(void) 365void __init time_init(void)
351{ 366{
367 struct timespec ts;
352#ifdef CONFIG_HPET_TIMER 368#ifdef CONFIG_HPET_TIMER
353 if (is_hpet_capable()) { 369 if (is_hpet_capable()) {
354 /* 370 /*
@@ -359,10 +375,10 @@ void __init time_init(void)
359 return; 375 return;
360 } 376 }
361#endif 377#endif
362 xtime.tv_sec = get_cmos_time(); 378 ts.tv_sec = get_cmos_time();
363 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); 379 ts.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
364 set_normalized_timespec(&wall_to_monotonic, 380
365 -xtime.tv_sec, -xtime.tv_nsec); 381 do_settimeofday(&ts);
366 382
367 time_init_hook(); 383 time_init_hook();
368} 384}
diff --git a/arch/i386/kernel/time_hpet.c b/arch/i386/kernel/time_hpet.c
index 14a1376fedd1..6bf14a4e995e 100644
--- a/arch/i386/kernel/time_hpet.c
+++ b/arch/i386/kernel/time_hpet.c
@@ -301,23 +301,25 @@ int hpet_rtc_timer_init(void)
301 hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ; 301 hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
302 302
303 local_irq_save(flags); 303 local_irq_save(flags);
304
304 cnt = hpet_readl(HPET_COUNTER); 305 cnt = hpet_readl(HPET_COUNTER);
305 cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq); 306 cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq);
306 hpet_writel(cnt, HPET_T1_CMP); 307 hpet_writel(cnt, HPET_T1_CMP);
307 hpet_t1_cmp = cnt; 308 hpet_t1_cmp = cnt;
308 local_irq_restore(flags);
309 309
310 cfg = hpet_readl(HPET_T1_CFG); 310 cfg = hpet_readl(HPET_T1_CFG);
311 cfg &= ~HPET_TN_PERIODIC; 311 cfg &= ~HPET_TN_PERIODIC;
312 cfg |= HPET_TN_ENABLE | HPET_TN_32BIT; 312 cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
313 hpet_writel(cfg, HPET_T1_CFG); 313 hpet_writel(cfg, HPET_T1_CFG);
314 314
315 local_irq_restore(flags);
316
315 return 1; 317 return 1;
316} 318}
317 319
318static void hpet_rtc_timer_reinit(void) 320static void hpet_rtc_timer_reinit(void)
319{ 321{
320 unsigned int cfg, cnt; 322 unsigned int cfg, cnt, ticks_per_int, lost_ints;
321 323
322 if (unlikely(!(PIE_on | AIE_on | UIE_on))) { 324 if (unlikely(!(PIE_on | AIE_on | UIE_on))) {
323 cfg = hpet_readl(HPET_T1_CFG); 325 cfg = hpet_readl(HPET_T1_CFG);
@@ -332,10 +334,33 @@ static void hpet_rtc_timer_reinit(void)
332 hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ; 334 hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
333 335
334 /* It is more accurate to use the comparator value than current count.*/ 336 /* It is more accurate to use the comparator value than current count.*/
335 cnt = hpet_t1_cmp; 337 ticks_per_int = hpet_tick * HZ / hpet_rtc_int_freq;
336 cnt += hpet_tick*HZ/hpet_rtc_int_freq; 338 hpet_t1_cmp += ticks_per_int;
337 hpet_writel(cnt, HPET_T1_CMP); 339 hpet_writel(hpet_t1_cmp, HPET_T1_CMP);
338 hpet_t1_cmp = cnt; 340
341 /*
342 * If the interrupt handler was delayed too long, the write above tries
343 * to schedule the next interrupt in the past and the hardware would
344 * not interrupt until the counter had wrapped around.
345 * So we have to check that the comparator wasn't set to a past time.
346 */
347 cnt = hpet_readl(HPET_COUNTER);
348 if (unlikely((int)(cnt - hpet_t1_cmp) > 0)) {
349 lost_ints = (cnt - hpet_t1_cmp) / ticks_per_int + 1;
350 /* Make sure that, even with the time needed to execute
351 * this code, the next scheduled interrupt has been moved
352 * back to the future: */
353 lost_ints++;
354
355 hpet_t1_cmp += lost_ints * ticks_per_int;
356 hpet_writel(hpet_t1_cmp, HPET_T1_CMP);
357
358 if (PIE_on)
359 PIE_count += lost_ints;
360
361 printk(KERN_WARNING "rtc: lost some interrupts at %ldHz.\n",
362 hpet_rtc_int_freq);
363 }
339} 364}
340 365
341/* 366/*
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 7e9edafffd8a..4fcc6690be99 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -313,6 +313,8 @@ void show_registers(struct pt_regs *regs)
313 */ 313 */
314 if (in_kernel) { 314 if (in_kernel) {
315 u8 __user *eip; 315 u8 __user *eip;
316 int code_bytes = 64;
317 unsigned char c;
316 318
317 printk("\n" KERN_EMERG "Stack: "); 319 printk("\n" KERN_EMERG "Stack: ");
318 show_stack_log_lvl(NULL, regs, (unsigned long *)esp, KERN_EMERG); 320 show_stack_log_lvl(NULL, regs, (unsigned long *)esp, KERN_EMERG);
@@ -320,9 +322,12 @@ void show_registers(struct pt_regs *regs)
320 printk(KERN_EMERG "Code: "); 322 printk(KERN_EMERG "Code: ");
321 323
322 eip = (u8 __user *)regs->eip - 43; 324 eip = (u8 __user *)regs->eip - 43;
323 for (i = 0; i < 64; i++, eip++) { 325 if (eip < (u8 __user *)PAGE_OFFSET || __get_user(c, eip)) {
324 unsigned char c; 326 /* try starting at EIP */
325 327 eip = (u8 __user *)regs->eip;
328 code_bytes = 32;
329 }
330 for (i = 0; i < code_bytes; i++, eip++) {
326 if (eip < (u8 __user *)PAGE_OFFSET || __get_user(c, eip)) { 331 if (eip < (u8 __user *)PAGE_OFFSET || __get_user(c, eip)) {
327 printk(" Bad EIP value."); 332 printk(" Bad EIP value.");
328 break; 333 break;
diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S
index 2d4f1386e2b1..1e7ac1c44ddc 100644
--- a/arch/i386/kernel/vmlinux.lds.S
+++ b/arch/i386/kernel/vmlinux.lds.S
@@ -13,6 +13,12 @@ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
13OUTPUT_ARCH(i386) 13OUTPUT_ARCH(i386)
14ENTRY(phys_startup_32) 14ENTRY(phys_startup_32)
15jiffies = jiffies_64; 15jiffies = jiffies_64;
16
17PHDRS {
18 text PT_LOAD FLAGS(5); /* R_E */
19 data PT_LOAD FLAGS(7); /* RWE */
20 note PT_NOTE FLAGS(4); /* R__ */
21}
16SECTIONS 22SECTIONS
17{ 23{
18 . = __KERNEL_START; 24 . = __KERNEL_START;
@@ -26,7 +32,7 @@ SECTIONS
26 KPROBES_TEXT 32 KPROBES_TEXT
27 *(.fixup) 33 *(.fixup)
28 *(.gnu.warning) 34 *(.gnu.warning)
29 } = 0x9090 35 } :text = 0x9090
30 36
31 _etext = .; /* End of text section */ 37 _etext = .; /* End of text section */
32 38
@@ -48,7 +54,7 @@ SECTIONS
48 .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */ 54 .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
49 *(.data) 55 *(.data)
50 CONSTRUCTORS 56 CONSTRUCTORS
51 } 57 } :data
52 58
53 . = ALIGN(4096); 59 . = ALIGN(4096);
54 __nosave_begin = .; 60 __nosave_begin = .;
@@ -184,4 +190,6 @@ SECTIONS
184 STABS_DEBUG 190 STABS_DEBUG
185 191
186 DWARF_DEBUG 192 DWARF_DEBUG
193
194 NOTES
187} 195}
diff --git a/arch/i386/mach-voyager/voyager_thread.c b/arch/i386/mach-voyager/voyager_thread.c
index 50f6de6ff64d..f39887359e8e 100644
--- a/arch/i386/mach-voyager/voyager_thread.c
+++ b/arch/i386/mach-voyager/voyager_thread.c
@@ -130,7 +130,6 @@ thread(void *unused)
130 init_timer(&wakeup_timer); 130 init_timer(&wakeup_timer);
131 131
132 sigfillset(&current->blocked); 132 sigfillset(&current->blocked);
133 current->signal->tty = NULL;
134 133
135 printk(KERN_NOTICE "Voyager starting monitor thread\n"); 134 printk(KERN_NOTICE "Voyager starting monitor thread\n");
136 135
diff --git a/arch/i386/mm/boot_ioremap.c b/arch/i386/mm/boot_ioremap.c
index 5d44f4f5ff59..4de11f508c3a 100644
--- a/arch/i386/mm/boot_ioremap.c
+++ b/arch/i386/mm/boot_ioremap.c
@@ -29,8 +29,11 @@
29 */ 29 */
30 30
31#define BOOT_PTE_PTRS (PTRS_PER_PTE*2) 31#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
32#define boot_pte_index(address) \ 32
33 (((address) >> PAGE_SHIFT) & (BOOT_PTE_PTRS - 1)) 33static unsigned long boot_pte_index(unsigned long vaddr)
34{
35 return __pa(vaddr) >> PAGE_SHIFT;
36}
34 37
35static inline boot_pte_t* boot_vaddr_to_pte(void *address) 38static inline boot_pte_t* boot_vaddr_to_pte(void *address)
36{ 39{
diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c
index 7c392dc553b8..fb5d8b747de4 100644
--- a/arch/i386/mm/discontig.c
+++ b/arch/i386/mm/discontig.c
@@ -117,7 +117,8 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags);
117 117
118void *node_remap_end_vaddr[MAX_NUMNODES]; 118void *node_remap_end_vaddr[MAX_NUMNODES];
119void *node_remap_alloc_vaddr[MAX_NUMNODES]; 119void *node_remap_alloc_vaddr[MAX_NUMNODES];
120 120static unsigned long kva_start_pfn;
121static unsigned long kva_pages;
121/* 122/*
122 * FLAT - support for basic PC memory model with discontig enabled, essentially 123 * FLAT - support for basic PC memory model with discontig enabled, essentially
123 * a single node with all available processors in it with a flat 124 * a single node with all available processors in it with a flat
@@ -286,7 +287,6 @@ unsigned long __init setup_memory(void)
286{ 287{
287 int nid; 288 int nid;
288 unsigned long system_start_pfn, system_max_low_pfn; 289 unsigned long system_start_pfn, system_max_low_pfn;
289 unsigned long reserve_pages;
290 290
291 /* 291 /*
292 * When mapping a NUMA machine we allocate the node_mem_map arrays 292 * When mapping a NUMA machine we allocate the node_mem_map arrays
@@ -298,14 +298,23 @@ unsigned long __init setup_memory(void)
298 find_max_pfn(); 298 find_max_pfn();
299 get_memcfg_numa(); 299 get_memcfg_numa();
300 300
301 reserve_pages = calculate_numa_remap_pages(); 301 kva_pages = calculate_numa_remap_pages();
302 302
303 /* partially used pages are not usable - thus round upwards */ 303 /* partially used pages are not usable - thus round upwards */
304 system_start_pfn = min_low_pfn = PFN_UP(init_pg_tables_end); 304 system_start_pfn = min_low_pfn = PFN_UP(init_pg_tables_end);
305 305
306 system_max_low_pfn = max_low_pfn = find_max_low_pfn() - reserve_pages; 306 kva_start_pfn = find_max_low_pfn() - kva_pages;
307 printk("reserve_pages = %ld find_max_low_pfn() ~ %ld\n", 307
308 reserve_pages, max_low_pfn + reserve_pages); 308#ifdef CONFIG_BLK_DEV_INITRD
309 /* Numa kva area is below the initrd */
310 if (LOADER_TYPE && INITRD_START)
311 kva_start_pfn = PFN_DOWN(INITRD_START) - kva_pages;
312#endif
313 kva_start_pfn -= kva_start_pfn & (PTRS_PER_PTE-1);
314
315 system_max_low_pfn = max_low_pfn = find_max_low_pfn();
316 printk("kva_start_pfn ~ %ld find_max_low_pfn() ~ %ld\n",
317 kva_start_pfn, max_low_pfn);
309 printk("max_pfn = %ld\n", max_pfn); 318 printk("max_pfn = %ld\n", max_pfn);
310#ifdef CONFIG_HIGHMEM 319#ifdef CONFIG_HIGHMEM
311 highstart_pfn = highend_pfn = max_pfn; 320 highstart_pfn = highend_pfn = max_pfn;
@@ -323,7 +332,7 @@ unsigned long __init setup_memory(void)
323 (ulong) pfn_to_kaddr(max_low_pfn)); 332 (ulong) pfn_to_kaddr(max_low_pfn));
324 for_each_online_node(nid) { 333 for_each_online_node(nid) {
325 node_remap_start_vaddr[nid] = pfn_to_kaddr( 334 node_remap_start_vaddr[nid] = pfn_to_kaddr(
326 highstart_pfn + node_remap_offset[nid]); 335 kva_start_pfn + node_remap_offset[nid]);
327 /* Init the node remap allocator */ 336 /* Init the node remap allocator */
328 node_remap_end_vaddr[nid] = node_remap_start_vaddr[nid] + 337 node_remap_end_vaddr[nid] = node_remap_start_vaddr[nid] +
329 (node_remap_size[nid] * PAGE_SIZE); 338 (node_remap_size[nid] * PAGE_SIZE);
@@ -338,7 +347,6 @@ unsigned long __init setup_memory(void)
338 } 347 }
339 printk("High memory starts at vaddr %08lx\n", 348 printk("High memory starts at vaddr %08lx\n",
340 (ulong) pfn_to_kaddr(highstart_pfn)); 349 (ulong) pfn_to_kaddr(highstart_pfn));
341 vmalloc_earlyreserve = reserve_pages * PAGE_SIZE;
342 for_each_online_node(nid) 350 for_each_online_node(nid)
343 find_max_pfn_node(nid); 351 find_max_pfn_node(nid);
344 352
@@ -348,13 +356,18 @@ unsigned long __init setup_memory(void)
348 return max_low_pfn; 356 return max_low_pfn;
349} 357}
350 358
359void __init numa_kva_reserve(void)
360{
361 reserve_bootmem(PFN_PHYS(kva_start_pfn),PFN_PHYS(kva_pages));
362}
363
351void __init zone_sizes_init(void) 364void __init zone_sizes_init(void)
352{ 365{
353 int nid; 366 int nid;
354 367
355 368
356 for_each_online_node(nid) { 369 for_each_online_node(nid) {
357 unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; 370 unsigned long zones_size[MAX_NR_ZONES] = {0, };
358 unsigned long *zholes_size; 371 unsigned long *zholes_size;
359 unsigned int max_dma; 372 unsigned int max_dma;
360 373
@@ -409,7 +422,7 @@ void __init set_highmem_pages_init(int bad_ppro)
409 zone_end_pfn = zone_start_pfn + zone->spanned_pages; 422 zone_end_pfn = zone_start_pfn + zone->spanned_pages;
410 423
411 printk("Initializing %s for node %d (%08lx:%08lx)\n", 424 printk("Initializing %s for node %d (%08lx:%08lx)\n",
412 zone->name, zone->zone_pgdat->node_id, 425 zone->name, zone_to_nid(zone),
413 zone_start_pfn, zone_end_pfn); 426 zone_start_pfn, zone_end_pfn);
414 427
415 for (node_pfn = zone_start_pfn; node_pfn < zone_end_pfn; node_pfn++) { 428 for (node_pfn = zone_start_pfn; node_pfn < zone_end_pfn; node_pfn++) {
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 89e8486aac34..efd0bcdac65d 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -629,6 +629,48 @@ void __init mem_init(void)
629 (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)) 629 (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
630 ); 630 );
631 631
632#if 1 /* double-sanity-check paranoia */
633 printk("virtual kernel memory layout:\n"
634 " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
635#ifdef CONFIG_HIGHMEM
636 " pkmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
637#endif
638 " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n"
639 " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n"
640 " .init : 0x%08lx - 0x%08lx (%4ld kB)\n"
641 " .data : 0x%08lx - 0x%08lx (%4ld kB)\n"
642 " .text : 0x%08lx - 0x%08lx (%4ld kB)\n",
643 FIXADDR_START, FIXADDR_TOP,
644 (FIXADDR_TOP - FIXADDR_START) >> 10,
645
646#ifdef CONFIG_HIGHMEM
647 PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE,
648 (LAST_PKMAP*PAGE_SIZE) >> 10,
649#endif
650
651 VMALLOC_START, VMALLOC_END,
652 (VMALLOC_END - VMALLOC_START) >> 20,
653
654 (unsigned long)__va(0), (unsigned long)high_memory,
655 ((unsigned long)high_memory - (unsigned long)__va(0)) >> 20,
656
657 (unsigned long)&__init_begin, (unsigned long)&__init_end,
658 ((unsigned long)&__init_end - (unsigned long)&__init_begin) >> 10,
659
660 (unsigned long)&_etext, (unsigned long)&_edata,
661 ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
662
663 (unsigned long)&_text, (unsigned long)&_etext,
664 ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
665
666#ifdef CONFIG_HIGHMEM
667 BUG_ON(PKMAP_BASE+LAST_PKMAP*PAGE_SIZE > FIXADDR_START);
668 BUG_ON(VMALLOC_END > PKMAP_BASE);
669#endif
670 BUG_ON(VMALLOC_START > VMALLOC_END);
671 BUG_ON((unsigned long)high_memory > VMALLOC_START);
672#endif /* double-sanity-check paranoia */
673
632#ifdef CONFIG_X86_PAE 674#ifdef CONFIG_X86_PAE
633 if (!cpu_has_pae) 675 if (!cpu_has_pae)
634 panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!"); 676 panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
@@ -657,7 +699,7 @@ void __init mem_init(void)
657int arch_add_memory(int nid, u64 start, u64 size) 699int arch_add_memory(int nid, u64 start, u64 size)
658{ 700{
659 struct pglist_data *pgdata = &contig_page_data; 701 struct pglist_data *pgdata = &contig_page_data;
660 struct zone *zone = pgdata->node_zones + MAX_NR_ZONES-1; 702 struct zone *zone = pgdata->node_zones + ZONE_HIGHMEM;
661 unsigned long start_pfn = start >> PAGE_SHIFT; 703 unsigned long start_pfn = start >> PAGE_SHIFT;
662 unsigned long nr_pages = size >> PAGE_SHIFT; 704 unsigned long nr_pages = size >> PAGE_SHIFT;
663 705
diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c
index bd98768d8764..10126e3f8174 100644
--- a/arch/i386/mm/pgtable.c
+++ b/arch/i386/mm/pgtable.c
@@ -12,6 +12,7 @@
12#include <linux/slab.h> 12#include <linux/slab.h>
13#include <linux/pagemap.h> 13#include <linux/pagemap.h>
14#include <linux/spinlock.h> 14#include <linux/spinlock.h>
15#include <linux/module.h>
15 16
16#include <asm/system.h> 17#include <asm/system.h>
17#include <asm/pgtable.h> 18#include <asm/pgtable.h>
@@ -60,7 +61,9 @@ void show_mem(void)
60 printk(KERN_INFO "%lu pages writeback\n", 61 printk(KERN_INFO "%lu pages writeback\n",
61 global_page_state(NR_WRITEBACK)); 62 global_page_state(NR_WRITEBACK));
62 printk(KERN_INFO "%lu pages mapped\n", global_page_state(NR_FILE_MAPPED)); 63 printk(KERN_INFO "%lu pages mapped\n", global_page_state(NR_FILE_MAPPED));
63 printk(KERN_INFO "%lu pages slab\n", global_page_state(NR_SLAB)); 64 printk(KERN_INFO "%lu pages slab\n",
65 global_page_state(NR_SLAB_RECLAIMABLE) +
66 global_page_state(NR_SLAB_UNRECLAIMABLE));
64 printk(KERN_INFO "%lu pages pagetables\n", 67 printk(KERN_INFO "%lu pages pagetables\n",
65 global_page_state(NR_PAGETABLE)); 68 global_page_state(NR_PAGETABLE));
66} 69}
@@ -137,6 +140,12 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
137 __flush_tlb_one(vaddr); 140 __flush_tlb_one(vaddr);
138} 141}
139 142
143static int fixmaps;
144#ifndef CONFIG_COMPAT_VDSO
145unsigned long __FIXADDR_TOP = 0xfffff000;
146EXPORT_SYMBOL(__FIXADDR_TOP);
147#endif
148
140void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags) 149void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
141{ 150{
142 unsigned long address = __fix_to_virt(idx); 151 unsigned long address = __fix_to_virt(idx);
@@ -146,6 +155,25 @@ void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
146 return; 155 return;
147 } 156 }
148 set_pte_pfn(address, phys >> PAGE_SHIFT, flags); 157 set_pte_pfn(address, phys >> PAGE_SHIFT, flags);
158 fixmaps++;
159}
160
161/**
162 * reserve_top_address - reserves a hole in the top of kernel address space
163 * @reserve - size of hole to reserve
164 *
165 * Can be used to relocate the fixmap area and poke a hole in the top
166 * of kernel address space to make room for a hypervisor.
167 */
168void reserve_top_address(unsigned long reserve)
169{
170 BUG_ON(fixmaps > 0);
171#ifdef CONFIG_COMPAT_VDSO
172 BUG_ON(reserve != 0);
173#else
174 __FIXADDR_TOP = -reserve - PAGE_SIZE;
175 __VMALLOC_RESERVE += reserve;
176#endif
149} 177}
150 178
151pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) 179pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
diff --git a/arch/i386/power/swsusp.S b/arch/i386/power/swsusp.S
index c893b897217f..8a2b50a0aaad 100644
--- a/arch/i386/power/swsusp.S
+++ b/arch/i386/power/swsusp.S
@@ -32,7 +32,7 @@ ENTRY(swsusp_arch_resume)
32 movl $swsusp_pg_dir-__PAGE_OFFSET, %ecx 32 movl $swsusp_pg_dir-__PAGE_OFFSET, %ecx
33 movl %ecx, %cr3 33 movl %ecx, %cr3
34 34
35 movl pagedir_nosave, %edx 35 movl restore_pblist, %edx
36 .p2align 4,,7 36 .p2align 4,,7
37 37
38copy_loop: 38copy_loop: