~ubuntu-branches/ubuntu/karmic/linux-ports/karmic

« back to all changes in this revision

Viewing changes to arch/x86/kernel/reboot.c

  • Committer: Bazaar Package Importer
  • Author(s): Luke Yelavich, Luke Yelavich, Michael Casadevall, Tim Gardner, Upstream Kernel Changes
  • Date: 2009-05-06 18:18:55 UTC
  • Revision ID: james.westby@ubuntu.com-20090506181855-t00baeevpnvd9o7a
Tags: 2.6.30-1.1
[ Luke Yelavich ]
* initial release for karmic
* SAUCE: rebase-ports - adjust for the karmic ports kernel
* SAUCE: rebase-ports - also remove abi dirs/files on rebase
* Update configs after rebase against mainline Jaunty tree
* [Config] Disable CONFIG_BLK_DEV_UB and CONFIG_USB_LIBUSUAL as per
  mainline jaunty
* forward-port patch to drbd for powerpc compilation
* [Config] disable CONFIG_LENOVO_SL_LAPTOP for i386 due to FTBFS
* add .o files found in arch/powerpc/lib to all powerpc kernel header
  packages
* [Config] enable CONFIG_DRM_I915_KMS for i386 as per karmic mainline

[ Michael Casadevall ]

* Disable kgdb on sparc64
* [sparc] [Config] Disable GPIO LEDS
* [ia64] Rename -ia64-generic to -ia64 in line with other architectures
* Correct kernel image path for sparc builds
* [hppa] Fix HPPA config files to build modules for all udebian

Rebase on top of karmic mainline 2.6.30-1.1

[ Tim Gardner ]

* [Config] armel: disable staging drivers, fixes FTBS
* [Config] armel imx51: Disable CONFIG_MTD_NAND_MXC, fixes FTBS

[ Upstream Kernel Changes ]

* mpt2sas: Change reset_type enum to avoid namespace collision.
  Submitted upstream.

* Initial release after rebasing against v2.6.30-rc3

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#include <asm/proto.h>
13
13
#include <asm/reboot_fixups.h>
14
14
#include <asm/reboot.h>
 
15
#include <asm/pci_x86.h>
 
16
#include <asm/virtext.h>
 
17
#include <asm/cpu.h>
15
18
 
16
19
#ifdef CONFIG_X86_32
17
20
# include <linux/dmi.h>
36
39
static int reboot_cpu = -1;
37
40
#endif
38
41
 
39
 
/* reboot=b[ios] | s[mp] | t[riple] | k[bd] | e[fi] [, [w]arm | [c]old]
 
42
/* This is set if we need to go through the 'emergency' path.
 
43
 * When machine_emergency_restart() is called, we may be on
 
44
 * an inconsistent state and won't be able to do a clean cleanup
 
45
 */
 
46
static int reboot_emergency;
 
47
 
 
48
/* This is set by the PCI code if either type 1 or type 2 PCI is detected */
 
49
bool port_cf9_safe = false;
 
50
 
 
51
/* reboot=b[ios] | s[mp] | t[riple] | k[bd] | e[fi] [, [w]arm | [c]old] | p[ci]
40
52
   warm   Don't set the cold reboot flag
41
53
   cold   Set the cold reboot flag
42
54
   bios   Reboot by jumping through the BIOS (only for X86_32)
45
57
   kbd    Use the keyboard controller. cold reset (default)
46
58
   acpi   Use the RESET_REG in the FADT
47
59
   efi    Use efi reset_system runtime service
 
60
   pci    Use the so-called "PCI reset register", CF9
48
61
   force  Avoid anything that could hang.
49
62
 */
50
63
static int __init reboot_setup(char *str)
79
92
                case 'k':
80
93
                case 't':
81
94
                case 'e':
 
95
                case 'p':
82
96
                        reboot_type = *str;
83
97
                        break;
84
98
 
211
225
                        DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
212
226
                },
213
227
        },
 
228
        {       /* Handle problems with rebooting on Dell XPS710 */
 
229
                .callback = set_bios_reboot,
 
230
                .ident = "Dell XPS710",
 
231
                .matches = {
 
232
                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 
233
                        DMI_MATCH(DMI_PRODUCT_NAME, "Dell XPS710"),
 
234
                },
 
235
        },
 
236
        {       /* Handle problems with rebooting on Dell DXP061 */
 
237
                .callback = set_bios_reboot,
 
238
                .ident = "Dell DXP061",
 
239
                .matches = {
 
240
                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 
241
                        DMI_MATCH(DMI_PRODUCT_NAME, "Dell DXP061"),
 
242
                },
 
243
        },
214
244
#ifdef CONFIG_X86_LPIA
215
245
        {       /* Handle problems with rebooting on Intel Crown Beach board */
216
246
                .callback = set_bios_reboot,
389
419
        }
390
420
}
391
421
 
 
422
static void vmxoff_nmi(int cpu, struct die_args *args)
 
423
{
 
424
        cpu_emergency_vmxoff();
 
425
}
 
426
 
 
427
/* Use NMIs as IPIs to tell all CPUs to disable virtualization
 
428
 */
 
429
static void emergency_vmx_disable_all(void)
 
430
{
 
431
        /* Just make sure we won't change CPUs while doing this */
 
432
        local_irq_disable();
 
433
 
 
434
        /* We need to disable VMX on all CPUs before rebooting, otherwise
 
435
         * we risk hanging up the machine, because the CPU ignore INIT
 
436
         * signals when VMX is enabled.
 
437
         *
 
438
         * We can't take any locks and we may be on an inconsistent
 
439
         * state, so we use NMIs as IPIs to tell the other CPUs to disable
 
440
         * VMX and halt.
 
441
         *
 
442
         * For safety, we will avoid running the nmi_shootdown_cpus()
 
443
         * stuff unnecessarily, but we don't have a way to check
 
444
         * if other CPUs have VMX enabled. So we will call it only if the
 
445
         * CPU we are running on has VMX enabled.
 
446
         *
 
447
         * We will miss cases where VMX is not enabled on all CPUs. This
 
448
         * shouldn't do much harm because KVM always enable VMX on all
 
449
         * CPUs anyway. But we can miss it on the small window where KVM
 
450
         * is still enabling VMX.
 
451
         */
 
452
        if (cpu_has_vmx() && cpu_vmx_enabled()) {
 
453
                /* Disable VMX on this CPU.
 
454
                 */
 
455
                cpu_vmxoff();
 
456
 
 
457
                /* Halt and disable VMX on the other CPUs */
 
458
                nmi_shootdown_cpus(vmxoff_nmi);
 
459
 
 
460
        }
 
461
}
 
462
 
 
463
 
392
464
void __attribute__((weak)) mach_reboot_fixups(void)
393
465
{
394
466
}
397
469
{
398
470
        int i;
399
471
 
 
472
        if (reboot_emergency)
 
473
                emergency_vmx_disable_all();
 
474
 
400
475
        /* Tell the BIOS if we want cold or warm reboot */
401
476
        *((unsigned short *)__va(0x472)) = reboot_mode;
402
477
 
433
508
                        reboot_type = BOOT_KBD;
434
509
                        break;
435
510
 
436
 
 
437
511
                case BOOT_EFI:
438
512
                        if (efi_enabled)
439
 
                                efi.reset_system(reboot_mode ? EFI_RESET_WARM : EFI_RESET_COLD,
 
513
                                efi.reset_system(reboot_mode ?
 
514
                                                 EFI_RESET_WARM :
 
515
                                                 EFI_RESET_COLD,
440
516
                                                 EFI_SUCCESS, 0, NULL);
441
 
 
 
517
                        reboot_type = BOOT_KBD;
 
518
                        break;
 
519
 
 
520
                case BOOT_CF9:
 
521
                        port_cf9_safe = true;
 
522
                        /* fall through */
 
523
 
 
524
                case BOOT_CF9_COND:
 
525
                        if (port_cf9_safe) {
 
526
                                u8 cf9 = inb(0xcf9) & ~6;
 
527
                                outb(cf9|2, 0xcf9); /* Request hard reset */
 
528
                                udelay(50);
 
529
                                outb(cf9|6, 0xcf9); /* Actually do the reset */
 
530
                                udelay(50);
 
531
                        }
442
532
                        reboot_type = BOOT_KBD;
443
533
                        break;
444
534
                }
455
545
 
456
546
#ifdef CONFIG_X86_32
457
547
        /* See if there has been given a command line override */
458
 
        if ((reboot_cpu != -1) && (reboot_cpu < NR_CPUS) &&
 
548
        if ((reboot_cpu != -1) && (reboot_cpu < nr_cpu_ids) &&
459
549
                cpu_online(reboot_cpu))
460
550
                reboot_cpu_id = reboot_cpu;
461
551
#endif
465
555
                reboot_cpu_id = smp_processor_id();
466
556
 
467
557
        /* Make certain I only run on the appropriate processor */
468
 
        set_cpus_allowed_ptr(current, &cpumask_of_cpu(reboot_cpu_id));
 
558
        set_cpus_allowed_ptr(current, cpumask_of(reboot_cpu_id));
469
559
 
470
560
        /* O.K Now that I'm on the appropriate processor,
471
561
         * stop all of the others.
488
578
#endif
489
579
}
490
580
 
 
581
static void __machine_emergency_restart(int emergency)
 
582
{
 
583
        reboot_emergency = emergency;
 
584
        machine_ops.emergency_restart();
 
585
}
 
586
 
491
587
static void native_machine_restart(char *__unused)
492
588
{
493
589
        printk("machine restart\n");
494
590
 
495
591
        if (!reboot_force)
496
592
                machine_shutdown();
497
 
        machine_emergency_restart();
 
593
        __machine_emergency_restart(0);
498
594
}
499
595
 
500
596
static void native_machine_halt(void)
501
597
{
 
598
        /* stop other cpus and apics */
 
599
        machine_shutdown();
 
600
 
 
601
        /* stop this cpu */
 
602
        stop_this_cpu(NULL);
502
603
}
503
604
 
504
605
static void native_machine_power_off(void)
533
634
 
534
635
void machine_emergency_restart(void)
535
636
{
536
 
        machine_ops.emergency_restart();
 
637
        __machine_emergency_restart(1);
537
638
}
538
639
 
539
640
void machine_restart(char *cmd)
552
653
        machine_ops.crash_shutdown(regs);
553
654
}
554
655
#endif
 
656
 
 
657
 
 
658
#if defined(CONFIG_SMP)
 
659
 
 
660
/* This keeps a track of which one is crashing cpu. */
 
661
static int crashing_cpu;
 
662
static nmi_shootdown_cb shootdown_callback;
 
663
 
 
664
static atomic_t waiting_for_crash_ipi;
 
665
 
 
666
static int crash_nmi_callback(struct notifier_block *self,
 
667
                        unsigned long val, void *data)
 
668
{
 
669
        int cpu;
 
670
 
 
671
        if (val != DIE_NMI_IPI)
 
672
                return NOTIFY_OK;
 
673
 
 
674
        cpu = raw_smp_processor_id();
 
675
 
 
676
        /* Don't do anything if this handler is invoked on crashing cpu.
 
677
         * Otherwise, system will completely hang. Crashing cpu can get
 
678
         * an NMI if system was initially booted with nmi_watchdog parameter.
 
679
         */
 
680
        if (cpu == crashing_cpu)
 
681
                return NOTIFY_STOP;
 
682
        local_irq_disable();
 
683
 
 
684
        shootdown_callback(cpu, (struct die_args *)data);
 
685
 
 
686
        atomic_dec(&waiting_for_crash_ipi);
 
687
        /* Assume hlt works */
 
688
        halt();
 
689
        for (;;)
 
690
                cpu_relax();
 
691
 
 
692
        return 1;
 
693
}
 
694
 
 
695
static void smp_send_nmi_allbutself(void)
 
696
{
 
697
        apic->send_IPI_allbutself(NMI_VECTOR);
 
698
}
 
699
 
 
700
static struct notifier_block crash_nmi_nb = {
 
701
        .notifier_call = crash_nmi_callback,
 
702
};
 
703
 
 
704
/* Halt all other CPUs, calling the specified function on each of them
 
705
 *
 
706
 * This function can be used to halt all other CPUs on crash
 
707
 * or emergency reboot time. The function passed as parameter
 
708
 * will be called inside a NMI handler on all CPUs.
 
709
 */
 
710
void nmi_shootdown_cpus(nmi_shootdown_cb callback)
 
711
{
 
712
        unsigned long msecs;
 
713
        local_irq_disable();
 
714
 
 
715
        /* Make a note of crashing cpu. Will be used in NMI callback.*/
 
716
        crashing_cpu = safe_smp_processor_id();
 
717
 
 
718
        shootdown_callback = callback;
 
719
 
 
720
        atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
 
721
        /* Would it be better to replace the trap vector here? */
 
722
        if (register_die_notifier(&crash_nmi_nb))
 
723
                return;         /* return what? */
 
724
        /* Ensure the new callback function is set before sending
 
725
         * out the NMI
 
726
         */
 
727
        wmb();
 
728
 
 
729
        smp_send_nmi_allbutself();
 
730
 
 
731
        msecs = 1000; /* Wait at most a second for the other cpus to stop */
 
732
        while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
 
733
                mdelay(1);
 
734
                msecs--;
 
735
        }
 
736
 
 
737
        /* Leave the nmi callback set */
 
738
}
 
739
#else /* !CONFIG_SMP */
 
740
void nmi_shootdown_cpus(nmi_shootdown_cb callback)
 
741
{
 
742
        /* No other CPUs to shoot down */
 
743
}
 
744
#endif