diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-03-18 05:37:43 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-03-18 05:37:43 -0400 |
commit | 04dfcfcb54b073133bcca2c8f25b55e904558931 (patch) | |
tree | 123d13f9e242751f629924e92fcb297dc669d767 /arch/x86 | |
parent | 0bd5c4f7c874cf48ff7904dcf8a59988c8fea0e8 (diff) | |
parent | ee568b25ee9e160b32d1aef73d8b2ee9c05d34db (diff) |
Merge branch 'linus' into core/iommu
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/include/asm/efi.h | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/fixmap_64.h | 4 | ||||
-rw-r--r-- | arch/x86/include/asm/i387.h | 8 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/cpufreq/p4-clockmod.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/ds.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/efi.c | 7 | ||||
-rw-r--r-- | arch/x86/kernel/efi_64.c | 21 | ||||
-rw-r--r-- | arch/x86/kernel/i387.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/kprobes.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/reboot.c | 8 | ||||
-rw-r--r-- | arch/x86/kernel/setup.c | 5 | ||||
-rw-r--r-- | arch/x86/kernel/tsc.c | 110 | ||||
-rw-r--r-- | arch/x86/lguest/boot.c | 21 | ||||
-rw-r--r-- | arch/x86/math-emu/fpu_aux.c | 31 | ||||
-rw-r--r-- | arch/x86/mm/kmmio.c | 15 | ||||
-rw-r--r-- | arch/x86/mm/pageattr.c | 11 |
16 files changed, 150 insertions, 102 deletions
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index ca5ffb2856b6..edc90f23e708 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h | |||
@@ -37,8 +37,6 @@ extern unsigned long asmlinkage efi_call_phys(void *, ...); | |||
37 | 37 | ||
38 | #else /* !CONFIG_X86_32 */ | 38 | #else /* !CONFIG_X86_32 */ |
39 | 39 | ||
40 | #define MAX_EFI_IO_PAGES 100 | ||
41 | |||
42 | extern u64 efi_call0(void *fp); | 40 | extern u64 efi_call0(void *fp); |
43 | extern u64 efi_call1(void *fp, u64 arg1); | 41 | extern u64 efi_call1(void *fp, u64 arg1); |
44 | extern u64 efi_call2(void *fp, u64 arg1, u64 arg2); | 42 | extern u64 efi_call2(void *fp, u64 arg1, u64 arg2); |
diff --git a/arch/x86/include/asm/fixmap_64.h b/arch/x86/include/asm/fixmap_64.h index 00a30ab9b1a5..8be740977db8 100644 --- a/arch/x86/include/asm/fixmap_64.h +++ b/arch/x86/include/asm/fixmap_64.h | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <asm/apicdef.h> | 16 | #include <asm/apicdef.h> |
17 | #include <asm/page.h> | 17 | #include <asm/page.h> |
18 | #include <asm/vsyscall.h> | 18 | #include <asm/vsyscall.h> |
19 | #include <asm/efi.h> | ||
20 | 19 | ||
21 | /* | 20 | /* |
22 | * Here we define all the compile-time 'special' virtual | 21 | * Here we define all the compile-time 'special' virtual |
@@ -43,9 +42,6 @@ enum fixed_addresses { | |||
43 | FIX_APIC_BASE, /* local (CPU) APIC) -- required for SMP or not */ | 42 | FIX_APIC_BASE, /* local (CPU) APIC) -- required for SMP or not */ |
44 | FIX_IO_APIC_BASE_0, | 43 | FIX_IO_APIC_BASE_0, |
45 | FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS - 1, | 44 | FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS - 1, |
46 | FIX_EFI_IO_MAP_LAST_PAGE, | ||
47 | FIX_EFI_IO_MAP_FIRST_PAGE = FIX_EFI_IO_MAP_LAST_PAGE | ||
48 | + MAX_EFI_IO_PAGES - 1, | ||
49 | #ifdef CONFIG_PARAVIRT | 45 | #ifdef CONFIG_PARAVIRT |
50 | FIX_PARAVIRT_BOOTMAP, | 46 | FIX_PARAVIRT_BOOTMAP, |
51 | #endif | 47 | #endif |
diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h index 48f0004db8c9..71c9e5183982 100644 --- a/arch/x86/include/asm/i387.h +++ b/arch/x86/include/asm/i387.h | |||
@@ -172,7 +172,13 @@ static inline void __save_init_fpu(struct task_struct *tsk) | |||
172 | 172 | ||
173 | #else /* CONFIG_X86_32 */ | 173 | #else /* CONFIG_X86_32 */ |
174 | 174 | ||
175 | extern void finit(void); | 175 | #ifdef CONFIG_MATH_EMULATION |
176 | extern void finit_task(struct task_struct *tsk); | ||
177 | #else | ||
178 | static inline void finit_task(struct task_struct *tsk) | ||
179 | { | ||
180 | } | ||
181 | #endif | ||
176 | 182 | ||
177 | static inline void tolerant_fwait(void) | 183 | static inline void tolerant_fwait(void) |
178 | { | 184 | { |
diff --git a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c index b585e04cbc9e..3178c3acd97e 100644 --- a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c +++ b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c | |||
@@ -277,7 +277,6 @@ static struct cpufreq_driver p4clockmod_driver = { | |||
277 | .name = "p4-clockmod", | 277 | .name = "p4-clockmod", |
278 | .owner = THIS_MODULE, | 278 | .owner = THIS_MODULE, |
279 | .attr = p4clockmod_attr, | 279 | .attr = p4clockmod_attr, |
280 | .hide_interface = 1, | ||
281 | }; | 280 | }; |
282 | 281 | ||
283 | 282 | ||
diff --git a/arch/x86/kernel/ds.c b/arch/x86/kernel/ds.c index 169a120587be..87b67e3a765a 100644 --- a/arch/x86/kernel/ds.c +++ b/arch/x86/kernel/ds.c | |||
@@ -729,7 +729,7 @@ struct pebs_tracer *ds_request_pebs(struct task_struct *task, | |||
729 | 729 | ||
730 | spin_unlock_irqrestore(&ds_lock, irq); | 730 | spin_unlock_irqrestore(&ds_lock, irq); |
731 | 731 | ||
732 | ds_write_config(tracer->ds.context, &tracer->trace.ds, ds_bts); | 732 | ds_write_config(tracer->ds.context, &tracer->trace.ds, ds_pebs); |
733 | ds_resume_pebs(tracer); | 733 | ds_resume_pebs(tracer); |
734 | 734 | ||
735 | return tracer; | 735 | return tracer; |
@@ -1029,5 +1029,4 @@ void ds_copy_thread(struct task_struct *tsk, struct task_struct *father) | |||
1029 | 1029 | ||
1030 | void ds_exit_thread(struct task_struct *tsk) | 1030 | void ds_exit_thread(struct task_struct *tsk) |
1031 | { | 1031 | { |
1032 | WARN_ON(tsk->thread.ds_ctx); | ||
1033 | } | 1032 | } |
diff --git a/arch/x86/kernel/efi.c b/arch/x86/kernel/efi.c index 1119d247fe11..eb1ef3b67dd5 100644 --- a/arch/x86/kernel/efi.c +++ b/arch/x86/kernel/efi.c | |||
@@ -467,7 +467,7 @@ void __init efi_enter_virtual_mode(void) | |||
467 | efi_memory_desc_t *md; | 467 | efi_memory_desc_t *md; |
468 | efi_status_t status; | 468 | efi_status_t status; |
469 | unsigned long size; | 469 | unsigned long size; |
470 | u64 end, systab, addr, npages; | 470 | u64 end, systab, addr, npages, end_pfn; |
471 | void *p, *va; | 471 | void *p, *va; |
472 | 472 | ||
473 | efi.systab = NULL; | 473 | efi.systab = NULL; |
@@ -479,7 +479,10 @@ void __init efi_enter_virtual_mode(void) | |||
479 | size = md->num_pages << EFI_PAGE_SHIFT; | 479 | size = md->num_pages << EFI_PAGE_SHIFT; |
480 | end = md->phys_addr + size; | 480 | end = md->phys_addr + size; |
481 | 481 | ||
482 | if (PFN_UP(end) <= max_low_pfn_mapped) | 482 | end_pfn = PFN_UP(end); |
483 | if (end_pfn <= max_low_pfn_mapped | ||
484 | || (end_pfn > (1UL << (32 - PAGE_SHIFT)) | ||
485 | && end_pfn <= max_pfn_mapped)) | ||
483 | va = __va(md->phys_addr); | 486 | va = __va(md->phys_addr); |
484 | else | 487 | else |
485 | va = efi_ioremap(md->phys_addr, size); | 488 | va = efi_ioremap(md->phys_addr, size); |
diff --git a/arch/x86/kernel/efi_64.c b/arch/x86/kernel/efi_64.c index 652c5287215f..cb783b92c50c 100644 --- a/arch/x86/kernel/efi_64.c +++ b/arch/x86/kernel/efi_64.c | |||
@@ -99,24 +99,11 @@ void __init efi_call_phys_epilog(void) | |||
99 | 99 | ||
100 | void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size) | 100 | void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size) |
101 | { | 101 | { |
102 | static unsigned pages_mapped __initdata; | 102 | unsigned long last_map_pfn; |
103 | unsigned i, pages; | ||
104 | unsigned long offset; | ||
105 | 103 | ||
106 | pages = PFN_UP(phys_addr + size) - PFN_DOWN(phys_addr); | 104 | last_map_pfn = init_memory_mapping(phys_addr, phys_addr + size); |
107 | offset = phys_addr & ~PAGE_MASK; | 105 | if ((last_map_pfn << PAGE_SHIFT) < phys_addr + size) |
108 | phys_addr &= PAGE_MASK; | ||
109 | |||
110 | if (pages_mapped + pages > MAX_EFI_IO_PAGES) | ||
111 | return NULL; | 106 | return NULL; |
112 | 107 | ||
113 | for (i = 0; i < pages; i++) { | 108 | return (void __iomem *)__va(phys_addr); |
114 | __set_fixmap(FIX_EFI_IO_MAP_FIRST_PAGE - pages_mapped, | ||
115 | phys_addr, PAGE_KERNEL); | ||
116 | phys_addr += PAGE_SIZE; | ||
117 | pages_mapped++; | ||
118 | } | ||
119 | |||
120 | return (void __iomem *)__fix_to_virt(FIX_EFI_IO_MAP_FIRST_PAGE - \ | ||
121 | (pages_mapped - pages)) + offset; | ||
122 | } | 109 | } |
diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index b0f61f0dcd0a..f2f8540a7f3d 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c | |||
@@ -136,7 +136,7 @@ int init_fpu(struct task_struct *tsk) | |||
136 | #ifdef CONFIG_X86_32 | 136 | #ifdef CONFIG_X86_32 |
137 | if (!HAVE_HWFP) { | 137 | if (!HAVE_HWFP) { |
138 | memset(tsk->thread.xstate, 0, xstate_size); | 138 | memset(tsk->thread.xstate, 0, xstate_size); |
139 | finit(); | 139 | finit_task(tsk); |
140 | set_stopped_child_used_math(tsk); | 140 | set_stopped_child_used_math(tsk); |
141 | return 0; | 141 | return 0; |
142 | } | 142 | } |
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c index e948b28a5a9a..4558dd3918cf 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c | |||
@@ -193,6 +193,9 @@ static int __kprobes can_boost(kprobe_opcode_t *opcodes) | |||
193 | kprobe_opcode_t opcode; | 193 | kprobe_opcode_t opcode; |
194 | kprobe_opcode_t *orig_opcodes = opcodes; | 194 | kprobe_opcode_t *orig_opcodes = opcodes; |
195 | 195 | ||
196 | if (search_exception_tables(opcodes)) | ||
197 | return 0; /* Page fault may occur on this address. */ | ||
198 | |||
196 | retry: | 199 | retry: |
197 | if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1) | 200 | if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1) |
198 | return 0; | 201 | return 0; |
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 2b46eb41643b..4526b3a75ed2 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
@@ -217,6 +217,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { | |||
217 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"), | 217 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"), |
218 | }, | 218 | }, |
219 | }, | 219 | }, |
220 | { /* Handle problems with rebooting on Dell XPS710 */ | ||
221 | .callback = set_bios_reboot, | ||
222 | .ident = "Dell XPS710", | ||
223 | .matches = { | ||
224 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
225 | DMI_MATCH(DMI_PRODUCT_NAME, "Dell XPS710"), | ||
226 | }, | ||
227 | }, | ||
220 | { } | 228 | { } |
221 | }; | 229 | }; |
222 | 230 | ||
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index c461f6d69074..6a8811a69324 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -770,6 +770,9 @@ void __init setup_arch(char **cmdline_p) | |||
770 | 770 | ||
771 | finish_e820_parsing(); | 771 | finish_e820_parsing(); |
772 | 772 | ||
773 | if (efi_enabled) | ||
774 | efi_init(); | ||
775 | |||
773 | dmi_scan_machine(); | 776 | dmi_scan_machine(); |
774 | 777 | ||
775 | dmi_check_system(bad_bios_dmi_table); | 778 | dmi_check_system(bad_bios_dmi_table); |
@@ -789,8 +792,6 @@ void __init setup_arch(char **cmdline_p) | |||
789 | insert_resource(&iomem_resource, &data_resource); | 792 | insert_resource(&iomem_resource, &data_resource); |
790 | insert_resource(&iomem_resource, &bss_resource); | 793 | insert_resource(&iomem_resource, &bss_resource); |
791 | 794 | ||
792 | if (efi_enabled) | ||
793 | efi_init(); | ||
794 | 795 | ||
795 | #ifdef CONFIG_X86_32 | 796 | #ifdef CONFIG_X86_32 |
796 | if (ppro_with_ram_bug()) { | 797 | if (ppro_with_ram_bug()) { |
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 599e58168631..d5cebb52d45b 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c | |||
@@ -273,30 +273,43 @@ static unsigned long pit_calibrate_tsc(u32 latch, unsigned long ms, int loopmin) | |||
273 | * use the TSC value at the transitions to calculate a pretty | 273 | * use the TSC value at the transitions to calculate a pretty |
274 | * good value for the TSC frequencty. | 274 | * good value for the TSC frequencty. |
275 | */ | 275 | */ |
276 | static inline int pit_expect_msb(unsigned char val) | 276 | static inline int pit_expect_msb(unsigned char val, u64 *tscp, unsigned long *deltap) |
277 | { | 277 | { |
278 | int count = 0; | 278 | int count; |
279 | u64 tsc = 0; | ||
279 | 280 | ||
280 | for (count = 0; count < 50000; count++) { | 281 | for (count = 0; count < 50000; count++) { |
281 | /* Ignore LSB */ | 282 | /* Ignore LSB */ |
282 | inb(0x42); | 283 | inb(0x42); |
283 | if (inb(0x42) != val) | 284 | if (inb(0x42) != val) |
284 | break; | 285 | break; |
286 | tsc = get_cycles(); | ||
285 | } | 287 | } |
286 | return count > 50; | 288 | *deltap = get_cycles() - tsc; |
289 | *tscp = tsc; | ||
290 | |||
291 | /* | ||
292 | * We require _some_ success, but the quality control | ||
293 | * will be based on the error terms on the TSC values. | ||
294 | */ | ||
295 | return count > 5; | ||
287 | } | 296 | } |
288 | 297 | ||
289 | /* | 298 | /* |
290 | * How many MSB values do we want to see? We aim for a | 299 | * How many MSB values do we want to see? We aim for |
291 | * 15ms calibration, which assuming a 2us counter read | 300 | * a maximum error rate of 500ppm (in practice the |
292 | * error should give us roughly 150 ppm precision for | 301 | * real error is much smaller), but refuse to spend |
293 | * the calibration. | 302 | * more than 25ms on it. |
294 | */ | 303 | */ |
295 | #define QUICK_PIT_MS 15 | 304 | #define MAX_QUICK_PIT_MS 25 |
296 | #define QUICK_PIT_ITERATIONS (QUICK_PIT_MS * PIT_TICK_RATE / 1000 / 256) | 305 | #define MAX_QUICK_PIT_ITERATIONS (MAX_QUICK_PIT_MS * PIT_TICK_RATE / 1000 / 256) |
297 | 306 | ||
298 | static unsigned long quick_pit_calibrate(void) | 307 | static unsigned long quick_pit_calibrate(void) |
299 | { | 308 | { |
309 | int i; | ||
310 | u64 tsc, delta; | ||
311 | unsigned long d1, d2; | ||
312 | |||
300 | /* Set the Gate high, disable speaker */ | 313 | /* Set the Gate high, disable speaker */ |
301 | outb((inb(0x61) & ~0x02) | 0x01, 0x61); | 314 | outb((inb(0x61) & ~0x02) | 0x01, 0x61); |
302 | 315 | ||
@@ -315,45 +328,52 @@ static unsigned long quick_pit_calibrate(void) | |||
315 | outb(0xff, 0x42); | 328 | outb(0xff, 0x42); |
316 | outb(0xff, 0x42); | 329 | outb(0xff, 0x42); |
317 | 330 | ||
318 | if (pit_expect_msb(0xff)) { | 331 | /* |
319 | int i; | 332 | * The PIT starts counting at the next edge, so we |
320 | u64 t1, t2, delta; | 333 | * need to delay for a microsecond. The easiest way |
321 | unsigned char expect = 0xfe; | 334 | * to do that is to just read back the 16-bit counter |
322 | 335 | * once from the PIT. | |
323 | t1 = get_cycles(); | 336 | */ |
324 | for (i = 0; i < QUICK_PIT_ITERATIONS; i++, expect--) { | 337 | inb(0x42); |
325 | if (!pit_expect_msb(expect)) | 338 | inb(0x42); |
326 | goto failed; | 339 | |
340 | if (pit_expect_msb(0xff, &tsc, &d1)) { | ||
341 | for (i = 1; i <= MAX_QUICK_PIT_ITERATIONS; i++) { | ||
342 | if (!pit_expect_msb(0xff-i, &delta, &d2)) | ||
343 | break; | ||
344 | |||
345 | /* | ||
346 | * Iterate until the error is less than 500 ppm | ||
347 | */ | ||
348 | delta -= tsc; | ||
349 | if (d1+d2 < delta >> 11) | ||
350 | goto success; | ||
327 | } | 351 | } |
328 | t2 = get_cycles(); | ||
329 | |||
330 | /* | ||
331 | * Make sure we can rely on the second TSC timestamp: | ||
332 | */ | ||
333 | if (!pit_expect_msb(expect)) | ||
334 | goto failed; | ||
335 | |||
336 | /* | ||
337 | * Ok, if we get here, then we've seen the | ||
338 | * MSB of the PIT decrement QUICK_PIT_ITERATIONS | ||
339 | * times, and each MSB had many hits, so we never | ||
340 | * had any sudden jumps. | ||
341 | * | ||
342 | * As a result, we can depend on there not being | ||
343 | * any odd delays anywhere, and the TSC reads are | ||
344 | * reliable. | ||
345 | * | ||
346 | * kHz = ticks / time-in-seconds / 1000; | ||
347 | * kHz = (t2 - t1) / (QPI * 256 / PIT_TICK_RATE) / 1000 | ||
348 | * kHz = ((t2 - t1) * PIT_TICK_RATE) / (QPI * 256 * 1000) | ||
349 | */ | ||
350 | delta = (t2 - t1)*PIT_TICK_RATE; | ||
351 | do_div(delta, QUICK_PIT_ITERATIONS*256*1000); | ||
352 | printk("Fast TSC calibration using PIT\n"); | ||
353 | return delta; | ||
354 | } | 352 | } |
355 | failed: | 353 | printk("Fast TSC calibration failed\n"); |
356 | return 0; | 354 | return 0; |
355 | |||
356 | success: | ||
357 | /* | ||
358 | * Ok, if we get here, then we've seen the | ||
359 | * MSB of the PIT decrement 'i' times, and the | ||
360 | * error has shrunk to less than 500 ppm. | ||
361 | * | ||
362 | * As a result, we can depend on there not being | ||
363 | * any odd delays anywhere, and the TSC reads are | ||
364 | * reliable (within the error). We also adjust the | ||
365 | * delta to the middle of the error bars, just | ||
366 | * because it looks nicer. | ||
367 | * | ||
368 | * kHz = ticks / time-in-seconds / 1000; | ||
369 | * kHz = (t2 - t1) / (I * 256 / PIT_TICK_RATE) / 1000 | ||
370 | * kHz = ((t2 - t1) * PIT_TICK_RATE) / (I * 256 * 1000) | ||
371 | */ | ||
372 | delta += (long)(d2 - d1)/2; | ||
373 | delta *= PIT_TICK_RATE; | ||
374 | do_div(delta, i*256*1000); | ||
375 | printk("Fast TSC calibration using PIT\n"); | ||
376 | return delta; | ||
357 | } | 377 | } |
358 | 378 | ||
359 | /** | 379 | /** |
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 92f1c6f3e19d..960a8d9c049c 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -343,6 +343,11 @@ static void lguest_cpuid(unsigned int *ax, unsigned int *bx, | |||
343 | * flush_tlb_user() for both user and kernel mappings unless | 343 | * flush_tlb_user() for both user and kernel mappings unless |
344 | * the Page Global Enable (PGE) feature bit is set. */ | 344 | * the Page Global Enable (PGE) feature bit is set. */ |
345 | *dx |= 0x00002000; | 345 | *dx |= 0x00002000; |
346 | /* We also lie, and say we're family id 5. 6 or greater | ||
347 | * leads to a rdmsr in early_init_intel which we can't handle. | ||
348 | * Family ID is returned as bits 8-12 in ax. */ | ||
349 | *ax &= 0xFFFFF0FF; | ||
350 | *ax |= 0x00000500; | ||
346 | break; | 351 | break; |
347 | case 0x80000000: | 352 | case 0x80000000: |
348 | /* Futureproof this a little: if they ask how much extended | 353 | /* Futureproof this a little: if they ask how much extended |
@@ -589,19 +594,21 @@ static void __init lguest_init_IRQ(void) | |||
589 | /* Some systems map "vectors" to interrupts weirdly. Lguest has | 594 | /* Some systems map "vectors" to interrupts weirdly. Lguest has |
590 | * a straightforward 1 to 1 mapping, so force that here. */ | 595 | * a straightforward 1 to 1 mapping, so force that here. */ |
591 | __get_cpu_var(vector_irq)[vector] = i; | 596 | __get_cpu_var(vector_irq)[vector] = i; |
592 | if (vector != SYSCALL_VECTOR) { | 597 | if (vector != SYSCALL_VECTOR) |
593 | set_intr_gate(vector, | 598 | set_intr_gate(vector, interrupt[i]); |
594 | interrupt[vector-FIRST_EXTERNAL_VECTOR]); | ||
595 | set_irq_chip_and_handler_name(i, &lguest_irq_controller, | ||
596 | handle_level_irq, | ||
597 | "level"); | ||
598 | } | ||
599 | } | 599 | } |
600 | /* This call is required to set up for 4k stacks, where we have | 600 | /* This call is required to set up for 4k stacks, where we have |
601 | * separate stacks for hard and soft interrupts. */ | 601 | * separate stacks for hard and soft interrupts. */ |
602 | irq_ctx_init(smp_processor_id()); | 602 | irq_ctx_init(smp_processor_id()); |
603 | } | 603 | } |
604 | 604 | ||
605 | void lguest_setup_irq(unsigned int irq) | ||
606 | { | ||
607 | irq_to_desc_alloc_cpu(irq, 0); | ||
608 | set_irq_chip_and_handler_name(irq, &lguest_irq_controller, | ||
609 | handle_level_irq, "level"); | ||
610 | } | ||
611 | |||
605 | /* | 612 | /* |
606 | * Time. | 613 | * Time. |
607 | * | 614 | * |
diff --git a/arch/x86/math-emu/fpu_aux.c b/arch/x86/math-emu/fpu_aux.c index 491e737ce547..aa0987088774 100644 --- a/arch/x86/math-emu/fpu_aux.c +++ b/arch/x86/math-emu/fpu_aux.c | |||
@@ -30,20 +30,29 @@ static void fclex(void) | |||
30 | } | 30 | } |
31 | 31 | ||
32 | /* Needs to be externally visible */ | 32 | /* Needs to be externally visible */ |
33 | void finit(void) | 33 | void finit_task(struct task_struct *tsk) |
34 | { | 34 | { |
35 | control_word = 0x037f; | 35 | struct i387_soft_struct *soft = &tsk->thread.xstate->soft; |
36 | partial_status = 0; | 36 | struct address *oaddr, *iaddr; |
37 | top = 0; /* We don't keep top in the status word internally. */ | 37 | soft->cwd = 0x037f; |
38 | fpu_tag_word = 0xffff; | 38 | soft->swd = 0; |
39 | soft->ftop = 0; /* We don't keep top in the status word internally. */ | ||
40 | soft->twd = 0xffff; | ||
39 | /* The behaviour is different from that detailed in | 41 | /* The behaviour is different from that detailed in |
40 | Section 15.1.6 of the Intel manual */ | 42 | Section 15.1.6 of the Intel manual */ |
41 | operand_address.offset = 0; | 43 | oaddr = (struct address *)&soft->foo; |
42 | operand_address.selector = 0; | 44 | oaddr->offset = 0; |
43 | instruction_address.offset = 0; | 45 | oaddr->selector = 0; |
44 | instruction_address.selector = 0; | 46 | iaddr = (struct address *)&soft->fip; |
45 | instruction_address.opcode = 0; | 47 | iaddr->offset = 0; |
46 | no_ip_update = 1; | 48 | iaddr->selector = 0; |
49 | iaddr->opcode = 0; | ||
50 | soft->no_update = 1; | ||
51 | } | ||
52 | |||
53 | void finit(void) | ||
54 | { | ||
55 | finit_task(current); | ||
47 | } | 56 | } |
48 | 57 | ||
49 | /* | 58 | /* |
diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c index 9f205030d9aa..6a518dd08a36 100644 --- a/arch/x86/mm/kmmio.c +++ b/arch/x86/mm/kmmio.c | |||
@@ -451,23 +451,24 @@ static void rcu_free_kmmio_fault_pages(struct rcu_head *head) | |||
451 | 451 | ||
452 | static void remove_kmmio_fault_pages(struct rcu_head *head) | 452 | static void remove_kmmio_fault_pages(struct rcu_head *head) |
453 | { | 453 | { |
454 | struct kmmio_delayed_release *dr = container_of( | 454 | struct kmmio_delayed_release *dr = |
455 | head, | 455 | container_of(head, struct kmmio_delayed_release, rcu); |
456 | struct kmmio_delayed_release, | ||
457 | rcu); | ||
458 | struct kmmio_fault_page *p = dr->release_list; | 456 | struct kmmio_fault_page *p = dr->release_list; |
459 | struct kmmio_fault_page **prevp = &dr->release_list; | 457 | struct kmmio_fault_page **prevp = &dr->release_list; |
460 | unsigned long flags; | 458 | unsigned long flags; |
459 | |||
461 | spin_lock_irqsave(&kmmio_lock, flags); | 460 | spin_lock_irqsave(&kmmio_lock, flags); |
462 | while (p) { | 461 | while (p) { |
463 | if (!p->count) | 462 | if (!p->count) { |
464 | list_del_rcu(&p->list); | 463 | list_del_rcu(&p->list); |
465 | else | 464 | prevp = &p->release_next; |
465 | } else { | ||
466 | *prevp = p->release_next; | 466 | *prevp = p->release_next; |
467 | prevp = &p->release_next; | 467 | } |
468 | p = p->release_next; | 468 | p = p->release_next; |
469 | } | 469 | } |
470 | spin_unlock_irqrestore(&kmmio_lock, flags); | 470 | spin_unlock_irqrestore(&kmmio_lock, flags); |
471 | |||
471 | /* This is the real RCU destroy call. */ | 472 | /* This is the real RCU destroy call. */ |
472 | call_rcu(&dr->rcu, rcu_free_kmmio_fault_pages); | 473 | call_rcu(&dr->rcu, rcu_free_kmmio_fault_pages); |
473 | } | 474 | } |
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 7be47d1a97e4..7233bd7e357b 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
@@ -515,6 +515,17 @@ static int split_large_page(pte_t *kpte, unsigned long address) | |||
515 | * primary protection behavior: | 515 | * primary protection behavior: |
516 | */ | 516 | */ |
517 | __set_pmd_pte(kpte, address, mk_pte(base, __pgprot(_KERNPG_TABLE))); | 517 | __set_pmd_pte(kpte, address, mk_pte(base, __pgprot(_KERNPG_TABLE))); |
518 | |||
519 | /* | ||
520 | * Intel Atom errata AAH41 workaround. | ||
521 | * | ||
522 | * The real fix should be in hw or in a microcode update, but | ||
523 | * we also probabilistically try to reduce the window of having | ||
524 | * a large TLB mixed with 4K TLBs while instruction fetches are | ||
525 | * going on. | ||
526 | */ | ||
527 | __flush_tlb_all(); | ||
528 | |||
518 | base = NULL; | 529 | base = NULL; |
519 | 530 | ||
520 | out_unlock: | 531 | out_unlock: |