aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/include/asm/mmzone_32.h2
-rw-r--r--arch/x86/kernel/acpi/realmode/wakeup.S14
-rw-r--r--arch/x86/kernel/acpi/realmode/wakeup.h6
-rw-r--r--arch/x86/kernel/acpi/sleep.c6
-rw-r--r--arch/x86/kernel/reboot.c8
-rw-r--r--arch/x86/oprofile/nmi_int.c14
-rw-r--r--arch/x86/pci/xen.c56
-rw-r--r--arch/x86/platform/efi/efi.c3
8 files changed, 74 insertions, 35 deletions
diff --git a/arch/x86/include/asm/mmzone_32.h b/arch/x86/include/asm/mmzone_32.h
index 224e8c5eb307..ffa037f28d39 100644
--- a/arch/x86/include/asm/mmzone_32.h
+++ b/arch/x86/include/asm/mmzone_32.h
@@ -57,6 +57,8 @@ static inline int pfn_valid(int pfn)
57 return 0; 57 return 0;
58} 58}
59 59
60#define early_pfn_valid(pfn) pfn_valid((pfn))
61
60#endif /* CONFIG_DISCONTIGMEM */ 62#endif /* CONFIG_DISCONTIGMEM */
61 63
62#ifdef CONFIG_NEED_MULTIPLE_NODES 64#ifdef CONFIG_NEED_MULTIPLE_NODES
diff --git a/arch/x86/kernel/acpi/realmode/wakeup.S b/arch/x86/kernel/acpi/realmode/wakeup.S
index ead21b663117..b4fd836e4053 100644
--- a/arch/x86/kernel/acpi/realmode/wakeup.S
+++ b/arch/x86/kernel/acpi/realmode/wakeup.S
@@ -28,6 +28,8 @@ pmode_cr3: .long 0 /* Saved %cr3 */
28pmode_cr4: .long 0 /* Saved %cr4 */ 28pmode_cr4: .long 0 /* Saved %cr4 */
29pmode_efer: .quad 0 /* Saved EFER */ 29pmode_efer: .quad 0 /* Saved EFER */
30pmode_gdt: .quad 0 30pmode_gdt: .quad 0
31pmode_misc_en: .quad 0 /* Saved MISC_ENABLE MSR */
32pmode_behavior: .long 0 /* Wakeup behavior flags */
31realmode_flags: .long 0 33realmode_flags: .long 0
32real_magic: .long 0 34real_magic: .long 0
33trampoline_segment: .word 0 35trampoline_segment: .word 0
@@ -91,6 +93,18 @@ wakeup_code:
91 /* Call the C code */ 93 /* Call the C code */
92 calll main 94 calll main
93 95
96 /* Restore MISC_ENABLE before entering protected mode, in case
97 BIOS decided to clear XD_DISABLE during S3. */
98 movl pmode_behavior, %eax
99 btl $WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE, %eax
100 jnc 1f
101
102 movl pmode_misc_en, %eax
103 movl pmode_misc_en + 4, %edx
104 movl $MSR_IA32_MISC_ENABLE, %ecx
105 wrmsr
1061:
107
94 /* Do any other stuff... */ 108 /* Do any other stuff... */
95 109
96#ifndef CONFIG_64BIT 110#ifndef CONFIG_64BIT
diff --git a/arch/x86/kernel/acpi/realmode/wakeup.h b/arch/x86/kernel/acpi/realmode/wakeup.h
index e1828c07e79c..97a29e1430e3 100644
--- a/arch/x86/kernel/acpi/realmode/wakeup.h
+++ b/arch/x86/kernel/acpi/realmode/wakeup.h
@@ -21,6 +21,9 @@ struct wakeup_header {
21 u32 pmode_efer_low; /* Protected mode EFER */ 21 u32 pmode_efer_low; /* Protected mode EFER */
22 u32 pmode_efer_high; 22 u32 pmode_efer_high;
23 u64 pmode_gdt; 23 u64 pmode_gdt;
24 u32 pmode_misc_en_low; /* Protected mode MISC_ENABLE */
25 u32 pmode_misc_en_high;
26 u32 pmode_behavior; /* Wakeup routine behavior flags */
24 u32 realmode_flags; 27 u32 realmode_flags;
25 u32 real_magic; 28 u32 real_magic;
26 u16 trampoline_segment; /* segment with trampoline code, 64-bit only */ 29 u16 trampoline_segment; /* segment with trampoline code, 64-bit only */
@@ -39,4 +42,7 @@ extern struct wakeup_header wakeup_header;
39#define WAKEUP_HEADER_SIGNATURE 0x51ee1111 42#define WAKEUP_HEADER_SIGNATURE 0x51ee1111
40#define WAKEUP_END_SIGNATURE 0x65a22c82 43#define WAKEUP_END_SIGNATURE 0x65a22c82
41 44
45/* Wakeup behavior bits */
46#define WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE 0
47
42#endif /* ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H */ 48#endif /* ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H */
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index 18a857ba7a25..103b6ab368d3 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -77,6 +77,12 @@ int acpi_suspend_lowlevel(void)
77 77
78 header->pmode_cr0 = read_cr0(); 78 header->pmode_cr0 = read_cr0();
79 header->pmode_cr4 = read_cr4_safe(); 79 header->pmode_cr4 = read_cr4_safe();
80 header->pmode_behavior = 0;
81 if (!rdmsr_safe(MSR_IA32_MISC_ENABLE,
82 &header->pmode_misc_en_low,
83 &header->pmode_misc_en_high))
84 header->pmode_behavior |=
85 (1 << WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE);
80 header->realmode_flags = acpi_realmode_flags; 86 header->realmode_flags = acpi_realmode_flags;
81 header->real_magic = 0x12345678; 87 header->real_magic = 0x12345678;
82 88
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 0c016f727695..4f0d46fefa7f 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -294,6 +294,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
294 DMI_MATCH(DMI_BOARD_NAME, "VersaLogic Menlow board"), 294 DMI_MATCH(DMI_BOARD_NAME, "VersaLogic Menlow board"),
295 }, 295 },
296 }, 296 },
297 { /* Handle reboot issue on Acer Aspire one */
298 .callback = set_bios_reboot,
299 .ident = "Acer Aspire One A110",
300 .matches = {
301 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
302 DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"),
303 },
304 },
297 { } 305 { }
298}; 306};
299 307
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index cf9750004a08..68894fdc034b 100644
--- a/arch/x86/oprofile/nmi_int.c
+++ b/arch/x86/oprofile/nmi_int.c
@@ -112,8 +112,10 @@ static void nmi_cpu_start(void *dummy)
112static int nmi_start(void) 112static int nmi_start(void)
113{ 113{
114 get_online_cpus(); 114 get_online_cpus();
115 on_each_cpu(nmi_cpu_start, NULL, 1);
116 ctr_running = 1; 115 ctr_running = 1;
116 /* make ctr_running visible to the nmi handler: */
117 smp_mb();
118 on_each_cpu(nmi_cpu_start, NULL, 1);
117 put_online_cpus(); 119 put_online_cpus();
118 return 0; 120 return 0;
119} 121}
@@ -504,15 +506,18 @@ static int nmi_setup(void)
504 506
505 nmi_enabled = 0; 507 nmi_enabled = 0;
506 ctr_running = 0; 508 ctr_running = 0;
507 barrier(); 509 /* make variables visible to the nmi handler: */
510 smp_mb();
508 err = register_die_notifier(&profile_exceptions_nb); 511 err = register_die_notifier(&profile_exceptions_nb);
509 if (err) 512 if (err)
510 goto fail; 513 goto fail;
511 514
512 get_online_cpus(); 515 get_online_cpus();
513 register_cpu_notifier(&oprofile_cpu_nb); 516 register_cpu_notifier(&oprofile_cpu_nb);
514 on_each_cpu(nmi_cpu_setup, NULL, 1);
515 nmi_enabled = 1; 517 nmi_enabled = 1;
518 /* make nmi_enabled visible to the nmi handler: */
519 smp_mb();
520 on_each_cpu(nmi_cpu_setup, NULL, 1);
516 put_online_cpus(); 521 put_online_cpus();
517 522
518 return 0; 523 return 0;
@@ -531,7 +536,8 @@ static void nmi_shutdown(void)
531 nmi_enabled = 0; 536 nmi_enabled = 0;
532 ctr_running = 0; 537 ctr_running = 0;
533 put_online_cpus(); 538 put_online_cpus();
534 barrier(); 539 /* make variables visible to the nmi handler: */
540 smp_mb();
535 unregister_die_notifier(&profile_exceptions_nb); 541 unregister_die_notifier(&profile_exceptions_nb);
536 msrs = &get_cpu_var(cpu_msrs); 542 msrs = &get_cpu_var(cpu_msrs);
537 model->shutdown(msrs); 543 model->shutdown(msrs);
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index fe008309ffec..f567965c0620 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -327,13 +327,12 @@ int __init pci_xen_hvm_init(void)
327} 327}
328 328
329#ifdef CONFIG_XEN_DOM0 329#ifdef CONFIG_XEN_DOM0
330static int xen_register_pirq(u32 gsi, int triggering) 330static int xen_register_pirq(u32 gsi, int gsi_override, int triggering)
331{ 331{
332 int rc, pirq, irq = -1; 332 int rc, pirq, irq = -1;
333 struct physdev_map_pirq map_irq; 333 struct physdev_map_pirq map_irq;
334 int shareable = 0; 334 int shareable = 0;
335 char *name; 335 char *name;
336 bool gsi_override = false;
337 336
338 if (!xen_pv_domain()) 337 if (!xen_pv_domain())
339 return -1; 338 return -1;
@@ -345,31 +344,12 @@ static int xen_register_pirq(u32 gsi, int triggering)
345 shareable = 1; 344 shareable = 1;
346 name = "ioapic-level"; 345 name = "ioapic-level";
347 } 346 }
348
349 pirq = xen_allocate_pirq_gsi(gsi); 347 pirq = xen_allocate_pirq_gsi(gsi);
350 if (pirq < 0) 348 if (pirq < 0)
351 goto out; 349 goto out;
352 350
353 /* Before we bind the GSI to a Linux IRQ, check whether 351 if (gsi_override >= 0)
354 * we need to override it with bus_irq (IRQ) value. Usually for 352 irq = xen_bind_pirq_gsi_to_irq(gsi_override, pirq, shareable, name);
355 * IRQs below IRQ_LEGACY_IRQ this holds IRQ == GSI, as so:
356 * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 low level)
357 * but there are oddballs where the IRQ != GSI:
358 * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 20 low level)
359 * which ends up being: gsi_to_irq[9] == 20
360 * (which is what acpi_gsi_to_irq ends up calling when starting the
361 * the ACPI interpreter and keels over since IRQ 9 has not been
362 * setup as we had setup IRQ 20 for it).
363 */
364 if (gsi == acpi_sci_override_gsi) {
365 /* Check whether the GSI != IRQ */
366 acpi_gsi_to_irq(gsi, &irq);
367 if (irq != gsi)
368 /* Bugger, we MUST have that IRQ. */
369 gsi_override = true;
370 }
371 if (gsi_override)
372 irq = xen_bind_pirq_gsi_to_irq(irq, pirq, shareable, name);
373 else 353 else
374 irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name); 354 irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name);
375 if (irq < 0) 355 if (irq < 0)
@@ -392,7 +372,7 @@ out:
392 return irq; 372 return irq;
393} 373}
394 374
395static int xen_register_gsi(u32 gsi, int triggering, int polarity) 375static int xen_register_gsi(u32 gsi, int gsi_override, int triggering, int polarity)
396{ 376{
397 int rc, irq; 377 int rc, irq;
398 struct physdev_setup_gsi setup_gsi; 378 struct physdev_setup_gsi setup_gsi;
@@ -403,7 +383,7 @@ static int xen_register_gsi(u32 gsi, int triggering, int polarity)
403 printk(KERN_DEBUG "xen: registering gsi %u triggering %d polarity %d\n", 383 printk(KERN_DEBUG "xen: registering gsi %u triggering %d polarity %d\n",
404 gsi, triggering, polarity); 384 gsi, triggering, polarity);
405 385
406 irq = xen_register_pirq(gsi, triggering); 386 irq = xen_register_pirq(gsi, gsi_override, triggering);
407 387
408 setup_gsi.gsi = gsi; 388 setup_gsi.gsi = gsi;
409 setup_gsi.triggering = (triggering == ACPI_EDGE_SENSITIVE ? 0 : 1); 389 setup_gsi.triggering = (triggering == ACPI_EDGE_SENSITIVE ? 0 : 1);
@@ -425,6 +405,8 @@ static __init void xen_setup_acpi_sci(void)
425 int rc; 405 int rc;
426 int trigger, polarity; 406 int trigger, polarity;
427 int gsi = acpi_sci_override_gsi; 407 int gsi = acpi_sci_override_gsi;
408 int irq = -1;
409 int gsi_override = -1;
428 410
429 if (!gsi) 411 if (!gsi)
430 return; 412 return;
@@ -441,7 +423,25 @@ static __init void xen_setup_acpi_sci(void)
441 printk(KERN_INFO "xen: sci override: global_irq=%d trigger=%d " 423 printk(KERN_INFO "xen: sci override: global_irq=%d trigger=%d "
442 "polarity=%d\n", gsi, trigger, polarity); 424 "polarity=%d\n", gsi, trigger, polarity);
443 425
444 gsi = xen_register_gsi(gsi, trigger, polarity); 426 /* Before we bind the GSI to a Linux IRQ, check whether
427 * we need to override it with bus_irq (IRQ) value. Usually for
428 * IRQs below IRQ_LEGACY_IRQ this holds IRQ == GSI, as so:
429 * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 low level)
430 * but there are oddballs where the IRQ != GSI:
431 * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 20 low level)
432 * which ends up being: gsi_to_irq[9] == 20
433 * (which is what acpi_gsi_to_irq ends up calling when starting the
434 * the ACPI interpreter and keels over since IRQ 9 has not been
435 * setup as we had setup IRQ 20 for it).
436 */
437 /* Check whether the GSI != IRQ */
438 if (acpi_gsi_to_irq(gsi, &irq) == 0) {
439 if (irq >= 0 && irq != gsi)
440 /* Bugger, we MUST have that IRQ. */
441 gsi_override = irq;
442 }
443
444 gsi = xen_register_gsi(gsi, gsi_override, trigger, polarity);
445 printk(KERN_INFO "xen: acpi sci %d\n", gsi); 445 printk(KERN_INFO "xen: acpi sci %d\n", gsi);
446 446
447 return; 447 return;
@@ -450,7 +450,7 @@ static __init void xen_setup_acpi_sci(void)
450static int acpi_register_gsi_xen(struct device *dev, u32 gsi, 450static int acpi_register_gsi_xen(struct device *dev, u32 gsi,
451 int trigger, int polarity) 451 int trigger, int polarity)
452{ 452{
453 return xen_register_gsi(gsi, trigger, polarity); 453 return xen_register_gsi(gsi, -1 /* no GSI override */, trigger, polarity);
454} 454}
455 455
456static int __init pci_xen_initial_domain(void) 456static int __init pci_xen_initial_domain(void)
@@ -489,7 +489,7 @@ void __init xen_setup_pirqs(void)
489 if (acpi_get_override_irq(irq, &trigger, &polarity) == -1) 489 if (acpi_get_override_irq(irq, &trigger, &polarity) == -1)
490 continue; 490 continue;
491 491
492 xen_register_pirq(irq, 492 xen_register_pirq(irq, -1 /* no GSI override */,
493 trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE); 493 trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE);
494 } 494 }
495} 495}
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 474356b98ede..899e393d8e73 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -504,9 +504,6 @@ void __init efi_init(void)
504 x86_platform.set_wallclock = efi_set_rtc_mmss; 504 x86_platform.set_wallclock = efi_set_rtc_mmss;
505#endif 505#endif
506 506
507 /* Setup for EFI runtime service */
508 reboot_type = BOOT_EFI;
509
510#if EFI_DEBUG 507#if EFI_DEBUG
511 print_efi_memmap(); 508 print_efi_memmap();
512#endif 509#endif