diff options
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/Kconfig | 4 | ||||
-rw-r--r-- | arch/i386/kernel/apm.c | 26 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/mtrr/generic.c | 4 | ||||
-rw-r--r-- | arch/i386/kernel/efi_stub.S | 1 | ||||
-rw-r--r-- | arch/i386/kernel/reboot.c | 12 | ||||
-rw-r--r-- | arch/i386/kernel/setup.c | 23 | ||||
-rw-r--r-- | arch/i386/kernel/smp.c | 66 | ||||
-rw-r--r-- | arch/i386/kernel/smpboot.c | 6 | ||||
-rw-r--r-- | arch/i386/kernel/srat.c | 5 | ||||
-rw-r--r-- | arch/i386/kernel/time.c | 50 | ||||
-rw-r--r-- | arch/i386/kernel/time_hpet.c | 37 | ||||
-rw-r--r-- | arch/i386/kernel/traps.c | 11 | ||||
-rw-r--r-- | arch/i386/kernel/vmlinux.lds.S | 12 | ||||
-rw-r--r-- | arch/i386/mach-voyager/voyager_thread.c | 1 | ||||
-rw-r--r-- | arch/i386/mm/boot_ioremap.c | 7 | ||||
-rw-r--r-- | arch/i386/mm/discontig.c | 33 | ||||
-rw-r--r-- | arch/i386/mm/init.c | 44 | ||||
-rw-r--r-- | arch/i386/mm/pgtable.c | 30 | ||||
-rw-r--r-- | arch/i386/power/swsusp.S | 2 |
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 | |||
494 | endchoice | 494 | endchoice |
495 | 495 | ||
496 | choice | 496 | choice |
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 | |||
794 | config COMPAT_VDSO | 795 | config 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 | ||
1155 | static void set_time(void) | 1155 | static 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 | ||
246 | static void prepare_set(void) | 246 | static 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 | ||
277 | static void post_set(void) | 277 | static 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 | ||
148 | static struct | 148 | static struct Xgt_desc_struct |
149 | { | 149 | real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries }, |
150 | unsigned short size __attribute__ ((packed)); | 150 | real_mode_idt = { 0x3ff, 0 }, |
151 | unsigned long long * base __attribute__ ((packed)); | 151 | no_idt = { 0, 0 }; |
152 | } | ||
153 | real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, real_mode_gdt_entries }, | ||
154 | real_mode_idt = { 0x3ff, NULL }, | ||
155 | no_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 | */ | ||
942 | static 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 | } | ||
953 | early_param("reservetop", parse_reservetop); | ||
954 | |||
955 | /* | ||
937 | * Callback for efi_memory_walk. | 956 | * Callback for efi_memory_walk. |
938 | */ | 957 | */ |
939 | static int __init | 958 | static int __init |
@@ -1181,7 +1200,7 @@ static unsigned long __init setup_memory(void) | |||
1181 | 1200 | ||
1182 | void __init zone_sizes_init(void) | 1201 | void __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 | */ | ||
643 | static 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 | |||
686 | int 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 | } | ||
702 | EXPORT_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 | ||
650 | static void unmap_cpu_to_logical_apicid(int cpu) | 654 | static 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) |
43 | static u8 pxm_bitmap[PXM_BITMAP_LEN]; /* bitmap of proximity domains */ | 43 | static 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) |
47 | struct node_memory_chunk_s { | 47 | struct 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 | ||
273 | static long clock_cmos_diff, sleep_start; | 273 | static long clock_cmos_diff; |
274 | static unsigned long sleep_start; | ||
274 | 275 | ||
275 | static int timer_suspend(struct sys_device *dev, pm_message_t state) | 276 | static 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 */ |
335 | static void __init hpet_time_init(void) | 349 | static 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 | ||
350 | void __init time_init(void) | 365 | void __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 | ||
318 | static void hpet_rtc_timer_reinit(void) | 320 | static 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") | |||
13 | OUTPUT_ARCH(i386) | 13 | OUTPUT_ARCH(i386) |
14 | ENTRY(phys_startup_32) | 14 | ENTRY(phys_startup_32) |
15 | jiffies = jiffies_64; | 15 | jiffies = jiffies_64; |
16 | |||
17 | PHDRS { | ||
18 | text PT_LOAD FLAGS(5); /* R_E */ | ||
19 | data PT_LOAD FLAGS(7); /* RWE */ | ||
20 | note PT_NOTE FLAGS(4); /* R__ */ | ||
21 | } | ||
16 | SECTIONS | 22 | SECTIONS |
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(¤t->blocked); | 132 | sigfillset(¤t->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)) | 33 | static unsigned long boot_pte_index(unsigned long vaddr) |
34 | { | ||
35 | return __pa(vaddr) >> PAGE_SHIFT; | ||
36 | } | ||
34 | 37 | ||
35 | static inline boot_pte_t* boot_vaddr_to_pte(void *address) | 38 | static 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 | ||
118 | void *node_remap_end_vaddr[MAX_NUMNODES]; | 118 | void *node_remap_end_vaddr[MAX_NUMNODES]; |
119 | void *node_remap_alloc_vaddr[MAX_NUMNODES]; | 119 | void *node_remap_alloc_vaddr[MAX_NUMNODES]; |
120 | 120 | static unsigned long kva_start_pfn; | |
121 | static 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 | ||
359 | void __init numa_kva_reserve(void) | ||
360 | { | ||
361 | reserve_bootmem(PFN_PHYS(kva_start_pfn),PFN_PHYS(kva_pages)); | ||
362 | } | ||
363 | |||
351 | void __init zone_sizes_init(void) | 364 | void __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) | |||
657 | int arch_add_memory(int nid, u64 start, u64 size) | 699 | int 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 | ||
143 | static int fixmaps; | ||
144 | #ifndef CONFIG_COMPAT_VDSO | ||
145 | unsigned long __FIXADDR_TOP = 0xfffff000; | ||
146 | EXPORT_SYMBOL(__FIXADDR_TOP); | ||
147 | #endif | ||
148 | |||
140 | void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags) | 149 | void __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 | */ | ||
168 | void 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 | ||
151 | pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | 179 | pte_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 | ||
38 | copy_loop: | 38 | copy_loop: |