aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel')
-rw-r--r--arch/i386/kernel/Makefile1
-rw-r--r--arch/i386/kernel/acpi/boot.c220
-rw-r--r--arch/i386/kernel/acpi/sleep.c27
-rw-r--r--arch/i386/kernel/apic.c80
-rw-r--r--arch/i386/kernel/apm.c8
-rw-r--r--arch/i386/kernel/cpu/common.c45
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k7.c4
-rw-r--r--arch/i386/kernel/cpu/intel.c12
-rw-r--r--arch/i386/kernel/cpu/intel_cacheinfo.c4
-rw-r--r--arch/i386/kernel/cpu/mcheck/k7.c2
-rw-r--r--arch/i386/kernel/cpu/mcheck/mce.c4
-rw-r--r--arch/i386/kernel/cpu/mcheck/p4.c4
-rw-r--r--arch/i386/kernel/cpu/mcheck/p5.c2
-rw-r--r--arch/i386/kernel/cpu/mcheck/p6.c2
-rw-r--r--arch/i386/kernel/cpu/mcheck/winchip.c2
-rw-r--r--arch/i386/kernel/cpu/mtrr/generic.c3
-rw-r--r--arch/i386/kernel/crash.c223
-rw-r--r--arch/i386/kernel/dmi_scan.c391
-rw-r--r--arch/i386/kernel/efi.c4
-rw-r--r--arch/i386/kernel/head.S6
-rw-r--r--arch/i386/kernel/i8259.c12
-rw-r--r--arch/i386/kernel/io_apic.c43
-rw-r--r--arch/i386/kernel/irq.c72
-rw-r--r--arch/i386/kernel/machine_kexec.c226
-rw-r--r--arch/i386/kernel/mpparse.c2
-rw-r--r--arch/i386/kernel/process.c39
-rw-r--r--arch/i386/kernel/reboot.c82
-rw-r--r--arch/i386/kernel/relocate_kernel.S120
-rw-r--r--arch/i386/kernel/setup.c69
-rw-r--r--arch/i386/kernel/signal.c4
-rw-r--r--arch/i386/kernel/smp.c34
-rw-r--r--arch/i386/kernel/smpboot.c349
-rw-r--r--arch/i386/kernel/syscall_table.S2
-rw-r--r--arch/i386/kernel/sysenter.c12
-rw-r--r--arch/i386/kernel/time_hpet.c2
-rw-r--r--arch/i386/kernel/timers/common.c2
-rw-r--r--arch/i386/kernel/timers/timer_tsc.c2
-rw-r--r--arch/i386/kernel/traps.c51
-rw-r--r--arch/i386/kernel/vmlinux.lds.S59
39 files changed, 1632 insertions, 594 deletions
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
index 51ecd512603d..4cc83b322b36 100644
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_X86_MPPARSE) += mpparse.o
24obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o 24obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o
25obj-$(CONFIG_X86_IO_APIC) += io_apic.o 25obj-$(CONFIG_X86_IO_APIC) += io_apic.o
26obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups.o 26obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups.o
27obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o
27obj-$(CONFIG_X86_NUMAQ) += numaq.o 28obj-$(CONFIG_X86_NUMAQ) += numaq.o
28obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o 29obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o
29obj-$(CONFIG_KPROBES) += kprobes.o 30obj-$(CONFIG_KPROBES) += kprobes.o
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index 848bb97af7ca..9f63ae0f404b 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -29,6 +29,7 @@
29#include <linux/efi.h> 29#include <linux/efi.h>
30#include <linux/irq.h> 30#include <linux/irq.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/dmi.h>
32 33
33#include <asm/pgtable.h> 34#include <asm/pgtable.h>
34#include <asm/io_apic.h> 35#include <asm/io_apic.h>
@@ -815,6 +816,219 @@ acpi_process_madt(void)
815 return; 816 return;
816} 817}
817 818
819extern int acpi_force;
820
821#ifdef __i386__
822
823#ifdef CONFIG_ACPI_PCI
824static int __init disable_acpi_irq(struct dmi_system_id *d)
825{
826 if (!acpi_force) {
827 printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n",
828 d->ident);
829 acpi_noirq_set();
830 }
831 return 0;
832}
833
834static int __init disable_acpi_pci(struct dmi_system_id *d)
835{
836 if (!acpi_force) {
837 printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n",
838 d->ident);
839 acpi_disable_pci();
840 }
841 return 0;
842}
843#endif
844
845static int __init dmi_disable_acpi(struct dmi_system_id *d)
846{
847 if (!acpi_force) {
848 printk(KERN_NOTICE "%s detected: acpi off\n",d->ident);
849 disable_acpi();
850 } else {
851 printk(KERN_NOTICE
852 "Warning: DMI blacklist says broken, but acpi forced\n");
853 }
854 return 0;
855}
856
857/*
858 * Limit ACPI to CPU enumeration for HT
859 */
860static int __init force_acpi_ht(struct dmi_system_id *d)
861{
862 if (!acpi_force) {
863 printk(KERN_NOTICE "%s detected: force use of acpi=ht\n", d->ident);
864 disable_acpi();
865 acpi_ht = 1;
866 } else {
867 printk(KERN_NOTICE
868 "Warning: acpi=force overrules DMI blacklist: acpi=ht\n");
869 }
870 return 0;
871}
872
873/*
874 * If your system is blacklisted here, but you find that acpi=force
875 * works for you, please contact acpi-devel@sourceforge.net
876 */
877static struct dmi_system_id __initdata acpi_dmi_table[] = {
878 /*
879 * Boxes that need ACPI disabled
880 */
881 {
882 .callback = dmi_disable_acpi,
883 .ident = "IBM Thinkpad",
884 .matches = {
885 DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
886 DMI_MATCH(DMI_BOARD_NAME, "2629H1G"),
887 },
888 },
889
890 /*
891 * Boxes that need acpi=ht
892 */
893 {
894 .callback = force_acpi_ht,
895 .ident = "FSC Primergy T850",
896 .matches = {
897 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
898 DMI_MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"),
899 },
900 },
901 {
902 .callback = force_acpi_ht,
903 .ident = "DELL GX240",
904 .matches = {
905 DMI_MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"),
906 DMI_MATCH(DMI_BOARD_NAME, "OptiPlex GX240"),
907 },
908 },
909 {
910 .callback = force_acpi_ht,
911 .ident = "HP VISUALIZE NT Workstation",
912 .matches = {
913 DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
914 DMI_MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"),
915 },
916 },
917 {
918 .callback = force_acpi_ht,
919 .ident = "Compaq Workstation W8000",
920 .matches = {
921 DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
922 DMI_MATCH(DMI_PRODUCT_NAME, "Workstation W8000"),
923 },
924 },
925 {
926 .callback = force_acpi_ht,
927 .ident = "ASUS P4B266",
928 .matches = {
929 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
930 DMI_MATCH(DMI_BOARD_NAME, "P4B266"),
931 },
932 },
933 {
934 .callback = force_acpi_ht,
935 .ident = "ASUS P2B-DS",
936 .matches = {
937 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
938 DMI_MATCH(DMI_BOARD_NAME, "P2B-DS"),
939 },
940 },
941 {
942 .callback = force_acpi_ht,
943 .ident = "ASUS CUR-DLS",
944 .matches = {
945 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
946 DMI_MATCH(DMI_BOARD_NAME, "CUR-DLS"),
947 },
948 },
949 {
950 .callback = force_acpi_ht,
951 .ident = "ABIT i440BX-W83977",
952 .matches = {
953 DMI_MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"),
954 DMI_MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"),
955 },
956 },
957 {
958 .callback = force_acpi_ht,
959 .ident = "IBM Bladecenter",
960 .matches = {
961 DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
962 DMI_MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"),
963 },
964 },
965 {
966 .callback = force_acpi_ht,
967 .ident = "IBM eServer xSeries 360",
968 .matches = {
969 DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
970 DMI_MATCH(DMI_BOARD_NAME, "eServer xSeries 360"),
971 },
972 },
973 {
974 .callback = force_acpi_ht,
975 .ident = "IBM eserver xSeries 330",
976 .matches = {
977 DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
978 DMI_MATCH(DMI_BOARD_NAME, "eserver xSeries 330"),
979 },
980 },
981 {
982 .callback = force_acpi_ht,
983 .ident = "IBM eserver xSeries 440",
984 .matches = {
985 DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
986 DMI_MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"),
987 },
988 },
989
990#ifdef CONFIG_ACPI_PCI
991 /*
992 * Boxes that need ACPI PCI IRQ routing disabled
993 */
994 {
995 .callback = disable_acpi_irq,
996 .ident = "ASUS A7V",
997 .matches = {
998 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
999 DMI_MATCH(DMI_BOARD_NAME, "<A7V>"),
1000 /* newer BIOS, Revision 1011, does work */
1001 DMI_MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"),
1002 },
1003 },
1004
1005 /*
1006 * Boxes that need ACPI PCI IRQ routing and PCI scan disabled
1007 */
1008 { /* _BBN 0 bug */
1009 .callback = disable_acpi_pci,
1010 .ident = "ASUS PR-DLS",
1011 .matches = {
1012 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
1013 DMI_MATCH(DMI_BOARD_NAME, "PR-DLS"),
1014 DMI_MATCH(DMI_BIOS_VERSION, "ASUS PR-DLS ACPI BIOS Revision 1010"),
1015 DMI_MATCH(DMI_BIOS_DATE, "03/21/2003")
1016 },
1017 },
1018 {
1019 .callback = disable_acpi_pci,
1020 .ident = "Acer TravelMate 36x Laptop",
1021 .matches = {
1022 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
1023 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
1024 },
1025 },
1026#endif
1027 { }
1028};
1029
1030#endif /* __i386__ */
1031
818/* 1032/*
819 * acpi_boot_table_init() and acpi_boot_init() 1033 * acpi_boot_table_init() and acpi_boot_init()
820 * called from setup_arch(), always. 1034 * called from setup_arch(), always.
@@ -843,6 +1057,10 @@ acpi_boot_table_init(void)
843{ 1057{
844 int error; 1058 int error;
845 1059
1060#ifdef __i386__
1061 dmi_check_system(acpi_dmi_table);
1062#endif
1063
846 /* 1064 /*
847 * If acpi_disabled, bail out 1065 * If acpi_disabled, bail out
848 * One exception: acpi=ht continues far enough to enumerate LAPICs 1066 * One exception: acpi=ht continues far enough to enumerate LAPICs
@@ -870,8 +1088,6 @@ acpi_boot_table_init(void)
870 */ 1088 */
871 error = acpi_blacklisted(); 1089 error = acpi_blacklisted();
872 if (error) { 1090 if (error) {
873 extern int acpi_force;
874
875 if (acpi_force) { 1091 if (acpi_force) {
876 printk(KERN_WARNING PREFIX "acpi=force override\n"); 1092 printk(KERN_WARNING PREFIX "acpi=force override\n");
877 } else { 1093 } else {
diff --git a/arch/i386/kernel/acpi/sleep.c b/arch/i386/kernel/acpi/sleep.c
index 28bb0514bb6e..c1af93032ff3 100644
--- a/arch/i386/kernel/acpi/sleep.c
+++ b/arch/i386/kernel/acpi/sleep.c
@@ -7,6 +7,7 @@
7 7
8#include <linux/acpi.h> 8#include <linux/acpi.h>
9#include <linux/bootmem.h> 9#include <linux/bootmem.h>
10#include <linux/dmi.h>
10#include <asm/smp.h> 11#include <asm/smp.h>
11#include <asm/tlbflush.h> 12#include <asm/tlbflush.h>
12 13
@@ -91,3 +92,29 @@ static int __init acpi_sleep_setup(char *str)
91 92
92 93
93__setup("acpi_sleep=", acpi_sleep_setup); 94__setup("acpi_sleep=", acpi_sleep_setup);
95
96
97static __init int reset_videomode_after_s3(struct dmi_system_id *d)
98{
99 acpi_video_flags |= 2;
100 return 0;
101}
102
103static __initdata struct dmi_system_id acpisleep_dmi_table[] = {
104 { /* Reset video mode after returning from ACPI S3 sleep */
105 .callback = reset_videomode_after_s3,
106 .ident = "Toshiba Satellite 4030cdt",
107 .matches = {
108 DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
109 },
110 },
111 { }
112};
113
114static int __init acpisleep_dmi_init(void)
115{
116 dmi_check_system(acpisleep_dmi_table);
117 return 0;
118}
119
120core_initcall(acpisleep_dmi_init);
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index 8d993fa71754..93df90bbb87e 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -26,6 +26,7 @@
26#include <linux/mc146818rtc.h> 26#include <linux/mc146818rtc.h>
27#include <linux/kernel_stat.h> 27#include <linux/kernel_stat.h>
28#include <linux/sysdev.h> 28#include <linux/sysdev.h>
29#include <linux/cpu.h>
29 30
30#include <asm/atomic.h> 31#include <asm/atomic.h>
31#include <asm/smp.h> 32#include <asm/smp.h>
@@ -40,6 +41,11 @@
40#include "io_ports.h" 41#include "io_ports.h"
41 42
42/* 43/*
44 * Knob to control our willingness to enable the local APIC.
45 */
46int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */
47
48/*
43 * Debug level 49 * Debug level
44 */ 50 */
45int apic_verbosity; 51int apic_verbosity;
@@ -205,7 +211,7 @@ void __init connect_bsp_APIC(void)
205 enable_apic_mode(); 211 enable_apic_mode();
206} 212}
207 213
208void disconnect_bsp_APIC(void) 214void disconnect_bsp_APIC(int virt_wire_setup)
209{ 215{
210 if (pic_mode) { 216 if (pic_mode) {
211 /* 217 /*
@@ -219,6 +225,42 @@ void disconnect_bsp_APIC(void)
219 outb(0x70, 0x22); 225 outb(0x70, 0x22);
220 outb(0x00, 0x23); 226 outb(0x00, 0x23);
221 } 227 }
228 else {
229 /* Go back to Virtual Wire compatibility mode */
230 unsigned long value;
231
232 /* For the spurious interrupt use vector F, and enable it */
233 value = apic_read(APIC_SPIV);
234 value &= ~APIC_VECTOR_MASK;
235 value |= APIC_SPIV_APIC_ENABLED;
236 value |= 0xf;
237 apic_write_around(APIC_SPIV, value);
238
239 if (!virt_wire_setup) {
240 /* For LVT0 make it edge triggered, active high, external and enabled */
241 value = apic_read(APIC_LVT0);
242 value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
243 APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
244 APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED );
245 value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
246 value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT);
247 apic_write_around(APIC_LVT0, value);
248 }
249 else {
250 /* Disable LVT0 */
251 apic_write_around(APIC_LVT0, APIC_LVT_MASKED);
252 }
253
254 /* For LVT1 make it edge triggered, active high, nmi and enabled */
255 value = apic_read(APIC_LVT1);
256 value &= ~(
257 APIC_MODE_MASK | APIC_SEND_PENDING |
258 APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
259 APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
260 value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
261 value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI);
262 apic_write_around(APIC_LVT1, value);
263 }
222} 264}
223 265
224void disable_local_APIC(void) 266void disable_local_APIC(void)
@@ -363,7 +405,7 @@ void __init init_bsp_APIC(void)
363 apic_write_around(APIC_LVT1, value); 405 apic_write_around(APIC_LVT1, value);
364} 406}
365 407
366void __init setup_local_APIC (void) 408void __devinit setup_local_APIC(void)
367{ 409{
368 unsigned long oldvalue, value, ver, maxlvt; 410 unsigned long oldvalue, value, ver, maxlvt;
369 411
@@ -634,7 +676,7 @@ static struct sys_device device_lapic = {
634 .cls = &lapic_sysclass, 676 .cls = &lapic_sysclass,
635}; 677};
636 678
637static void __init apic_pm_activate(void) 679static void __devinit apic_pm_activate(void)
638{ 680{
639 apic_pm_state.active = 1; 681 apic_pm_state.active = 1;
640} 682}
@@ -665,26 +707,6 @@ static void apic_pm_activate(void) { }
665 * Original code written by Keir Fraser. 707 * Original code written by Keir Fraser.
666 */ 708 */
667 709
668/*
669 * Knob to control our willingness to enable the local APIC.
670 */
671int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */
672
673static int __init lapic_disable(char *str)
674{
675 enable_local_apic = -1;
676 clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
677 return 0;
678}
679__setup("nolapic", lapic_disable);
680
681static int __init lapic_enable(char *str)
682{
683 enable_local_apic = 1;
684 return 0;
685}
686__setup("lapic", lapic_enable);
687
688static int __init apic_set_verbosity(char *str) 710static int __init apic_set_verbosity(char *str)
689{ 711{
690 if (strcmp("debug", str) == 0) 712 if (strcmp("debug", str) == 0)
@@ -855,7 +877,7 @@ fake_ioapic_page:
855 * but we do not accept timer interrupts yet. We only allow the BP 877 * but we do not accept timer interrupts yet. We only allow the BP
856 * to calibrate. 878 * to calibrate.
857 */ 879 */
858static unsigned int __init get_8254_timer_count(void) 880static unsigned int __devinit get_8254_timer_count(void)
859{ 881{
860 extern spinlock_t i8253_lock; 882 extern spinlock_t i8253_lock;
861 unsigned long flags; 883 unsigned long flags;
@@ -874,7 +896,7 @@ static unsigned int __init get_8254_timer_count(void)
874} 896}
875 897
876/* next tick in 8254 can be caught by catching timer wraparound */ 898/* next tick in 8254 can be caught by catching timer wraparound */
877static void __init wait_8254_wraparound(void) 899static void __devinit wait_8254_wraparound(void)
878{ 900{
879 unsigned int curr_count, prev_count; 901 unsigned int curr_count, prev_count;
880 902
@@ -894,7 +916,7 @@ static void __init wait_8254_wraparound(void)
894 * Default initialization for 8254 timers. If we use other timers like HPET, 916 * Default initialization for 8254 timers. If we use other timers like HPET,
895 * we override this later 917 * we override this later
896 */ 918 */
897void (*wait_timer_tick)(void) __initdata = wait_8254_wraparound; 919void (*wait_timer_tick)(void) __devinitdata = wait_8254_wraparound;
898 920
899/* 921/*
900 * This function sets up the local APIC timer, with a timeout of 922 * This function sets up the local APIC timer, with a timeout of
@@ -930,7 +952,7 @@ static void __setup_APIC_LVTT(unsigned int clocks)
930 apic_write_around(APIC_TMICT, clocks/APIC_DIVISOR); 952 apic_write_around(APIC_TMICT, clocks/APIC_DIVISOR);
931} 953}
932 954
933static void __init setup_APIC_timer(unsigned int clocks) 955static void __devinit setup_APIC_timer(unsigned int clocks)
934{ 956{
935 unsigned long flags; 957 unsigned long flags;
936 958
@@ -1043,12 +1065,12 @@ void __init setup_boot_APIC_clock(void)
1043 local_irq_enable(); 1065 local_irq_enable();
1044} 1066}
1045 1067
1046void __init setup_secondary_APIC_clock(void) 1068void __devinit setup_secondary_APIC_clock(void)
1047{ 1069{
1048 setup_APIC_timer(calibration_result); 1070 setup_APIC_timer(calibration_result);
1049} 1071}
1050 1072
1051void __init disable_APIC_timer(void) 1073void __devinit disable_APIC_timer(void)
1052{ 1074{
1053 if (using_apic_timer) { 1075 if (using_apic_timer) {
1054 unsigned long v; 1076 unsigned long v;
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index 0ff65abcd56c..d48ce9290963 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -346,10 +346,10 @@ extern int (*console_blank_hook)(int);
346struct apm_user { 346struct apm_user {
347 int magic; 347 int magic;
348 struct apm_user * next; 348 struct apm_user * next;
349 int suser: 1; 349 unsigned int suser: 1;
350 int writer: 1; 350 unsigned int writer: 1;
351 int reader: 1; 351 unsigned int reader: 1;
352 int suspend_wait: 1; 352 unsigned int suspend_wait: 1;
353 int suspend_result; 353 int suspend_result;
354 int suspends_pending; 354 int suspends_pending;
355 int standbys_pending; 355 int standbys_pending;
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index b9954248d0aa..2203a9d20212 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -24,9 +24,9 @@ EXPORT_PER_CPU_SYMBOL(cpu_gdt_table);
24DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); 24DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
25EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack); 25EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack);
26 26
27static int cachesize_override __initdata = -1; 27static int cachesize_override __devinitdata = -1;
28static int disable_x86_fxsr __initdata = 0; 28static int disable_x86_fxsr __devinitdata = 0;
29static int disable_x86_serial_nr __initdata = 1; 29static int disable_x86_serial_nr __devinitdata = 1;
30 30
31struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {}; 31struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
32 32
@@ -59,7 +59,7 @@ static int __init cachesize_setup(char *str)
59} 59}
60__setup("cachesize=", cachesize_setup); 60__setup("cachesize=", cachesize_setup);
61 61
62int __init get_model_name(struct cpuinfo_x86 *c) 62int __devinit get_model_name(struct cpuinfo_x86 *c)
63{ 63{
64 unsigned int *v; 64 unsigned int *v;
65 char *p, *q; 65 char *p, *q;
@@ -89,7 +89,7 @@ int __init get_model_name(struct cpuinfo_x86 *c)
89} 89}
90 90
91 91
92void __init display_cacheinfo(struct cpuinfo_x86 *c) 92void __devinit display_cacheinfo(struct cpuinfo_x86 *c)
93{ 93{
94 unsigned int n, dummy, ecx, edx, l2size; 94 unsigned int n, dummy, ecx, edx, l2size;
95 95
@@ -130,7 +130,7 @@ void __init display_cacheinfo(struct cpuinfo_x86 *c)
130/* in particular, if CPUID levels 0x80000002..4 are supported, this isn't used */ 130/* in particular, if CPUID levels 0x80000002..4 are supported, this isn't used */
131 131
132/* Look up CPU names by table lookup. */ 132/* Look up CPU names by table lookup. */
133static char __init *table_lookup_model(struct cpuinfo_x86 *c) 133static char __devinit *table_lookup_model(struct cpuinfo_x86 *c)
134{ 134{
135 struct cpu_model_info *info; 135 struct cpu_model_info *info;
136 136
@@ -151,7 +151,7 @@ static char __init *table_lookup_model(struct cpuinfo_x86 *c)
151} 151}
152 152
153 153
154void __init get_cpu_vendor(struct cpuinfo_x86 *c, int early) 154void __devinit get_cpu_vendor(struct cpuinfo_x86 *c, int early)
155{ 155{
156 char *v = c->x86_vendor_id; 156 char *v = c->x86_vendor_id;
157 int i; 157 int i;
@@ -202,7 +202,7 @@ static inline int flag_is_changeable_p(u32 flag)
202 202
203 203
204/* Probe for the CPUID instruction */ 204/* Probe for the CPUID instruction */
205static int __init have_cpuid_p(void) 205static int __devinit have_cpuid_p(void)
206{ 206{
207 return flag_is_changeable_p(X86_EFLAGS_ID); 207 return flag_is_changeable_p(X86_EFLAGS_ID);
208} 208}
@@ -249,7 +249,7 @@ static void __init early_cpu_detect(void)
249#endif 249#endif
250} 250}
251 251
252void __init generic_identify(struct cpuinfo_x86 * c) 252void __devinit generic_identify(struct cpuinfo_x86 * c)
253{ 253{
254 u32 tfms, xlvl; 254 u32 tfms, xlvl;
255 int junk; 255 int junk;
@@ -296,7 +296,7 @@ void __init generic_identify(struct cpuinfo_x86 * c)
296 } 296 }
297} 297}
298 298
299static void __init squash_the_stupid_serial_number(struct cpuinfo_x86 *c) 299static void __devinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
300{ 300{
301 if (cpu_has(c, X86_FEATURE_PN) && disable_x86_serial_nr ) { 301 if (cpu_has(c, X86_FEATURE_PN) && disable_x86_serial_nr ) {
302 /* Disable processor serial number */ 302 /* Disable processor serial number */
@@ -324,7 +324,7 @@ __setup("serialnumber", x86_serial_nr_setup);
324/* 324/*
325 * This does the hard work of actually picking apart the CPU stuff... 325 * This does the hard work of actually picking apart the CPU stuff...
326 */ 326 */
327void __init identify_cpu(struct cpuinfo_x86 *c) 327void __devinit identify_cpu(struct cpuinfo_x86 *c)
328{ 328{
329 int i; 329 int i;
330 330
@@ -432,10 +432,13 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
432#ifdef CONFIG_X86_MCE 432#ifdef CONFIG_X86_MCE
433 mcheck_init(c); 433 mcheck_init(c);
434#endif 434#endif
435 if (c == &boot_cpu_data)
436 sysenter_setup();
437 enable_sep_cpu();
435} 438}
436 439
437#ifdef CONFIG_X86_HT 440#ifdef CONFIG_X86_HT
438void __init detect_ht(struct cpuinfo_x86 *c) 441void __devinit detect_ht(struct cpuinfo_x86 *c)
439{ 442{
440 u32 eax, ebx, ecx, edx; 443 u32 eax, ebx, ecx, edx;
441 int index_msb, tmp; 444 int index_msb, tmp;
@@ -490,7 +493,7 @@ void __init detect_ht(struct cpuinfo_x86 *c)
490} 493}
491#endif 494#endif
492 495
493void __init print_cpu_info(struct cpuinfo_x86 *c) 496void __devinit print_cpu_info(struct cpuinfo_x86 *c)
494{ 497{
495 char *vendor = NULL; 498 char *vendor = NULL;
496 499
@@ -513,7 +516,7 @@ void __init print_cpu_info(struct cpuinfo_x86 *c)
513 printk("\n"); 516 printk("\n");
514} 517}
515 518
516cpumask_t cpu_initialized __initdata = CPU_MASK_NONE; 519cpumask_t cpu_initialized __devinitdata = CPU_MASK_NONE;
517 520
518/* This is hacky. :) 521/* This is hacky. :)
519 * We're emulating future behavior. 522 * We're emulating future behavior.
@@ -560,7 +563,7 @@ void __init early_cpu_init(void)
560 * and IDT. We reload them nevertheless, this function acts as a 563 * and IDT. We reload them nevertheless, this function acts as a
561 * 'CPU state barrier', nothing should get across. 564 * 'CPU state barrier', nothing should get across.
562 */ 565 */
563void __init cpu_init (void) 566void __devinit cpu_init(void)
564{ 567{
565 int cpu = smp_processor_id(); 568 int cpu = smp_processor_id();
566 struct tss_struct * t = &per_cpu(init_tss, cpu); 569 struct tss_struct * t = &per_cpu(init_tss, cpu);
@@ -648,3 +651,15 @@ void __init cpu_init (void)
648 clear_used_math(); 651 clear_used_math();
649 mxcsr_feature_mask_init(); 652 mxcsr_feature_mask_init();
650} 653}
654
655#ifdef CONFIG_HOTPLUG_CPU
656void __devinit cpu_uninit(void)
657{
658 int cpu = raw_smp_processor_id();
659 cpu_clear(cpu, cpu_initialized);
660
661 /* lazy TLB state */
662 per_cpu(cpu_tlbstate, cpu).state = 0;
663 per_cpu(cpu_tlbstate, cpu).active_mm = &init_mm;
664}
665#endif
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
index 5c530064eb74..73a5dc5b26b8 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
@@ -648,9 +648,7 @@ static int powernow_cpu_exit (struct cpufreq_policy *policy) {
648 } 648 }
649#endif 649#endif
650 650
651 if (powernow_table) 651 kfree(powernow_table);
652 kfree(powernow_table);
653
654 return 0; 652 return 0;
655} 653}
656 654
diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c
index 121aa2176e69..96a75d045835 100644
--- a/arch/i386/kernel/cpu/intel.c
+++ b/arch/i386/kernel/cpu/intel.c
@@ -28,7 +28,7 @@ extern int trap_init_f00f_bug(void);
28struct movsl_mask movsl_mask; 28struct movsl_mask movsl_mask;
29#endif 29#endif
30 30
31void __init early_intel_workaround(struct cpuinfo_x86 *c) 31void __devinit early_intel_workaround(struct cpuinfo_x86 *c)
32{ 32{
33 if (c->x86_vendor != X86_VENDOR_INTEL) 33 if (c->x86_vendor != X86_VENDOR_INTEL)
34 return; 34 return;
@@ -43,7 +43,7 @@ void __init early_intel_workaround(struct cpuinfo_x86 *c)
43 * This is called before we do cpu ident work 43 * This is called before we do cpu ident work
44 */ 44 */
45 45
46int __init ppro_with_ram_bug(void) 46int __devinit ppro_with_ram_bug(void)
47{ 47{
48 /* Uses data from early_cpu_detect now */ 48 /* Uses data from early_cpu_detect now */
49 if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && 49 if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
@@ -61,7 +61,7 @@ int __init ppro_with_ram_bug(void)
61 * P4 Xeon errata 037 workaround. 61 * P4 Xeon errata 037 workaround.
62 * Hardware prefetcher may cause stale data to be loaded into the cache. 62 * Hardware prefetcher may cause stale data to be loaded into the cache.
63 */ 63 */
64static void __init Intel_errata_workarounds(struct cpuinfo_x86 *c) 64static void __devinit Intel_errata_workarounds(struct cpuinfo_x86 *c)
65{ 65{
66 unsigned long lo, hi; 66 unsigned long lo, hi;
67 67
@@ -80,7 +80,7 @@ static void __init Intel_errata_workarounds(struct cpuinfo_x86 *c)
80/* 80/*
81 * find out the number of processor cores on the die 81 * find out the number of processor cores on the die
82 */ 82 */
83static int __init num_cpu_cores(struct cpuinfo_x86 *c) 83static int __devinit num_cpu_cores(struct cpuinfo_x86 *c)
84{ 84{
85 unsigned int eax; 85 unsigned int eax;
86 86
@@ -98,7 +98,7 @@ static int __init num_cpu_cores(struct cpuinfo_x86 *c)
98 return 1; 98 return 1;
99} 99}
100 100
101static void __init init_intel(struct cpuinfo_x86 *c) 101static void __devinit init_intel(struct cpuinfo_x86 *c)
102{ 102{
103 unsigned int l2 = 0; 103 unsigned int l2 = 0;
104 char *p = NULL; 104 char *p = NULL;
@@ -204,7 +204,7 @@ static unsigned int intel_size_cache(struct cpuinfo_x86 * c, unsigned int size)
204 return size; 204 return size;
205} 205}
206 206
207static struct cpu_dev intel_cpu_dev __initdata = { 207static struct cpu_dev intel_cpu_dev __devinitdata = {
208 .c_vendor = "Intel", 208 .c_vendor = "Intel",
209 .c_ident = { "GenuineIntel" }, 209 .c_ident = { "GenuineIntel" },
210 .c_models = { 210 .c_models = {
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c
index a710dc4eb20e..1d768b263269 100644
--- a/arch/i386/kernel/cpu/intel_cacheinfo.c
+++ b/arch/i386/kernel/cpu/intel_cacheinfo.c
@@ -28,7 +28,7 @@ struct _cache_table
28}; 28};
29 29
30/* all the cache descriptor types we care about (no TLB or trace cache entries) */ 30/* all the cache descriptor types we care about (no TLB or trace cache entries) */
31static struct _cache_table cache_table[] __initdata = 31static struct _cache_table cache_table[] __devinitdata =
32{ 32{
33 { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */ 33 { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */
34 { 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */ 34 { 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */
@@ -160,7 +160,7 @@ static int __init find_num_cache_leaves(void)
160 return retval; 160 return retval;
161} 161}
162 162
163unsigned int __init init_intel_cacheinfo(struct cpuinfo_x86 *c) 163unsigned int __devinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
164{ 164{
165 unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */ 165 unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
166 unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ 166 unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
diff --git a/arch/i386/kernel/cpu/mcheck/k7.c b/arch/i386/kernel/cpu/mcheck/k7.c
index 8df52e86c4d2..c4abe7657397 100644
--- a/arch/i386/kernel/cpu/mcheck/k7.c
+++ b/arch/i386/kernel/cpu/mcheck/k7.c
@@ -69,7 +69,7 @@ static fastcall void k7_machine_check(struct pt_regs * regs, long error_code)
69 69
70 70
71/* AMD K7 machine check is Intel like */ 71/* AMD K7 machine check is Intel like */
72void __init amd_mcheck_init(struct cpuinfo_x86 *c) 72void __devinit amd_mcheck_init(struct cpuinfo_x86 *c)
73{ 73{
74 u32 l, h; 74 u32 l, h;
75 int i; 75 int i;
diff --git a/arch/i386/kernel/cpu/mcheck/mce.c b/arch/i386/kernel/cpu/mcheck/mce.c
index bf6d1aefafc0..2cf25d2ba0f1 100644
--- a/arch/i386/kernel/cpu/mcheck/mce.c
+++ b/arch/i386/kernel/cpu/mcheck/mce.c
@@ -16,7 +16,7 @@
16 16
17#include "mce.h" 17#include "mce.h"
18 18
19int mce_disabled __initdata = 0; 19int mce_disabled __devinitdata = 0;
20int nr_mce_banks; 20int nr_mce_banks;
21 21
22EXPORT_SYMBOL_GPL(nr_mce_banks); /* non-fatal.o */ 22EXPORT_SYMBOL_GPL(nr_mce_banks); /* non-fatal.o */
@@ -31,7 +31,7 @@ static fastcall void unexpected_machine_check(struct pt_regs * regs, long error_
31void fastcall (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check; 31void fastcall (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check;
32 32
33/* This has to be run for each processor */ 33/* This has to be run for each processor */
34void __init mcheck_init(struct cpuinfo_x86 *c) 34void __devinit mcheck_init(struct cpuinfo_x86 *c)
35{ 35{
36 if (mce_disabled==1) 36 if (mce_disabled==1)
37 return; 37 return;
diff --git a/arch/i386/kernel/cpu/mcheck/p4.c b/arch/i386/kernel/cpu/mcheck/p4.c
index 8b16ceb929b4..0abccb6fdf9e 100644
--- a/arch/i386/kernel/cpu/mcheck/p4.c
+++ b/arch/i386/kernel/cpu/mcheck/p4.c
@@ -78,7 +78,7 @@ fastcall void smp_thermal_interrupt(struct pt_regs *regs)
78} 78}
79 79
80/* P4/Xeon Thermal regulation detect and init */ 80/* P4/Xeon Thermal regulation detect and init */
81static void __init intel_init_thermal(struct cpuinfo_x86 *c) 81static void __devinit intel_init_thermal(struct cpuinfo_x86 *c)
82{ 82{
83 u32 l, h; 83 u32 l, h;
84 unsigned int cpu = smp_processor_id(); 84 unsigned int cpu = smp_processor_id();
@@ -232,7 +232,7 @@ static fastcall void intel_machine_check(struct pt_regs * regs, long error_code)
232} 232}
233 233
234 234
235void __init intel_p4_mcheck_init(struct cpuinfo_x86 *c) 235void __devinit intel_p4_mcheck_init(struct cpuinfo_x86 *c)
236{ 236{
237 u32 l, h; 237 u32 l, h;
238 int i; 238 int i;
diff --git a/arch/i386/kernel/cpu/mcheck/p5.c b/arch/i386/kernel/cpu/mcheck/p5.c
index c45a1b485c80..ec0614cd2925 100644
--- a/arch/i386/kernel/cpu/mcheck/p5.c
+++ b/arch/i386/kernel/cpu/mcheck/p5.c
@@ -29,7 +29,7 @@ static fastcall void pentium_machine_check(struct pt_regs * regs, long error_cod
29} 29}
30 30
31/* Set up machine check reporting for processors with Intel style MCE */ 31/* Set up machine check reporting for processors with Intel style MCE */
32void __init intel_p5_mcheck_init(struct cpuinfo_x86 *c) 32void __devinit intel_p5_mcheck_init(struct cpuinfo_x86 *c)
33{ 33{
34 u32 l, h; 34 u32 l, h;
35 35
diff --git a/arch/i386/kernel/cpu/mcheck/p6.c b/arch/i386/kernel/cpu/mcheck/p6.c
index 46640f8c2494..f01b73f947e1 100644
--- a/arch/i386/kernel/cpu/mcheck/p6.c
+++ b/arch/i386/kernel/cpu/mcheck/p6.c
@@ -80,7 +80,7 @@ static fastcall void intel_machine_check(struct pt_regs * regs, long error_code)
80} 80}
81 81
82/* Set up machine check reporting for processors with Intel style MCE */ 82/* Set up machine check reporting for processors with Intel style MCE */
83void __init intel_p6_mcheck_init(struct cpuinfo_x86 *c) 83void __devinit intel_p6_mcheck_init(struct cpuinfo_x86 *c)
84{ 84{
85 u32 l, h; 85 u32 l, h;
86 int i; 86 int i;
diff --git a/arch/i386/kernel/cpu/mcheck/winchip.c b/arch/i386/kernel/cpu/mcheck/winchip.c
index 753fa7acb984..7bae68fa168f 100644
--- a/arch/i386/kernel/cpu/mcheck/winchip.c
+++ b/arch/i386/kernel/cpu/mcheck/winchip.c
@@ -23,7 +23,7 @@ static fastcall void winchip_machine_check(struct pt_regs * regs, long error_cod
23} 23}
24 24
25/* Set up machine check reporting on the Winchip C6 series */ 25/* Set up machine check reporting on the Winchip C6 series */
26void __init winchip_mcheck_init(struct cpuinfo_x86 *c) 26void __devinit winchip_mcheck_init(struct cpuinfo_x86 *c)
27{ 27{
28 u32 lo, hi; 28 u32 lo, hi;
29 machine_check_vector = winchip_machine_check; 29 machine_check_vector = winchip_machine_check;
diff --git a/arch/i386/kernel/cpu/mtrr/generic.c b/arch/i386/kernel/cpu/mtrr/generic.c
index f468a979e9aa..64d91f73a0a4 100644
--- a/arch/i386/kernel/cpu/mtrr/generic.c
+++ b/arch/i386/kernel/cpu/mtrr/generic.c
@@ -70,8 +70,7 @@ void __init get_mtrr_state(void)
70/* Free resources associated with a struct mtrr_state */ 70/* Free resources associated with a struct mtrr_state */
71void __init finalize_mtrr_state(void) 71void __init finalize_mtrr_state(void)
72{ 72{
73 if (mtrr_state.var_ranges) 73 kfree(mtrr_state.var_ranges);
74 kfree(mtrr_state.var_ranges);
75 mtrr_state.var_ranges = NULL; 74 mtrr_state.var_ranges = NULL;
76} 75}
77 76
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c
new file mode 100644
index 000000000000..e5fab12f7926
--- /dev/null
+++ b/arch/i386/kernel/crash.c
@@ -0,0 +1,223 @@
1/*
2 * Architecture specific (i386) functions for kexec based crash dumps.
3 *
4 * Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
5 *
6 * Copyright (C) IBM Corporation, 2004. All rights reserved.
7 *
8 */
9
10#include <linux/init.h>
11#include <linux/types.h>
12#include <linux/kernel.h>
13#include <linux/smp.h>
14#include <linux/irq.h>
15#include <linux/reboot.h>
16#include <linux/kexec.h>
17#include <linux/irq.h>
18#include <linux/delay.h>
19#include <linux/elf.h>
20#include <linux/elfcore.h>
21
22#include <asm/processor.h>
23#include <asm/hardirq.h>
24#include <asm/nmi.h>
25#include <asm/hw_irq.h>
26#include <asm/apic.h>
27#include <mach_ipi.h>
28
29
30note_buf_t crash_notes[NR_CPUS];
31/* This keeps a track of which one is crashing cpu. */
32static int crashing_cpu;
33
34static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data,
35 size_t data_len)
36{
37 struct elf_note note;
38
39 note.n_namesz = strlen(name) + 1;
40 note.n_descsz = data_len;
41 note.n_type = type;
42 memcpy(buf, &note, sizeof(note));
43 buf += (sizeof(note) +3)/4;
44 memcpy(buf, name, note.n_namesz);
45 buf += (note.n_namesz + 3)/4;
46 memcpy(buf, data, note.n_descsz);
47 buf += (note.n_descsz + 3)/4;
48
49 return buf;
50}
51
52static void final_note(u32 *buf)
53{
54 struct elf_note note;
55
56 note.n_namesz = 0;
57 note.n_descsz = 0;
58 note.n_type = 0;
59 memcpy(buf, &note, sizeof(note));
60}
61
62static void crash_save_this_cpu(struct pt_regs *regs, int cpu)
63{
64 struct elf_prstatus prstatus;
65 u32 *buf;
66
67 if ((cpu < 0) || (cpu >= NR_CPUS))
68 return;
69
70 /* Using ELF notes here is opportunistic.
71 * I need a well defined structure format
72 * for the data I pass, and I need tags
73 * on the data to indicate what information I have
74 * squirrelled away. ELF notes happen to provide
75 * all of that that no need to invent something new.
76 */
77 buf = &crash_notes[cpu][0];
78 memset(&prstatus, 0, sizeof(prstatus));
79 prstatus.pr_pid = current->pid;
80 elf_core_copy_regs(&prstatus.pr_reg, regs);
81 buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus,
82 sizeof(prstatus));
83 final_note(buf);
84}
85
86static void crash_get_current_regs(struct pt_regs *regs)
87{
88 __asm__ __volatile__("movl %%ebx,%0" : "=m"(regs->ebx));
89 __asm__ __volatile__("movl %%ecx,%0" : "=m"(regs->ecx));
90 __asm__ __volatile__("movl %%edx,%0" : "=m"(regs->edx));
91 __asm__ __volatile__("movl %%esi,%0" : "=m"(regs->esi));
92 __asm__ __volatile__("movl %%edi,%0" : "=m"(regs->edi));
93 __asm__ __volatile__("movl %%ebp,%0" : "=m"(regs->ebp));
94 __asm__ __volatile__("movl %%eax,%0" : "=m"(regs->eax));
95 __asm__ __volatile__("movl %%esp,%0" : "=m"(regs->esp));
96 __asm__ __volatile__("movw %%ss, %%ax;" :"=a"(regs->xss));
97 __asm__ __volatile__("movw %%cs, %%ax;" :"=a"(regs->xcs));
98 __asm__ __volatile__("movw %%ds, %%ax;" :"=a"(regs->xds));
99 __asm__ __volatile__("movw %%es, %%ax;" :"=a"(regs->xes));
100 __asm__ __volatile__("pushfl; popl %0" :"=m"(regs->eflags));
101
102 regs->eip = (unsigned long)current_text_addr();
103}
104
105/* CPU does not save ss and esp on stack if execution is already
106 * running in kernel mode at the time of NMI occurrence. This code
107 * fixes it.
108 */
109static void crash_setup_regs(struct pt_regs *newregs, struct pt_regs *oldregs)
110{
111 memcpy(newregs, oldregs, sizeof(*newregs));
112 newregs->esp = (unsigned long)&(oldregs->esp);
113 __asm__ __volatile__("xorl %eax, %eax;");
114 __asm__ __volatile__ ("movw %%ss, %%ax;" :"=a"(newregs->xss));
115}
116
117/* We may have saved_regs from where the error came from
118 * or it is NULL if via a direct panic().
119 */
120static void crash_save_self(struct pt_regs *saved_regs)
121{
122 struct pt_regs regs;
123 int cpu;
124
125 cpu = smp_processor_id();
126 if (saved_regs)
127 crash_setup_regs(&regs, saved_regs);
128 else
129 crash_get_current_regs(&regs);
130 crash_save_this_cpu(&regs, cpu);
131}
132
133#ifdef CONFIG_SMP
134static atomic_t waiting_for_crash_ipi;
135
136static int crash_nmi_callback(struct pt_regs *regs, int cpu)
137{
138 struct pt_regs fixed_regs;
139
140 /* Don't do anything if this handler is invoked on crashing cpu.
141 * Otherwise, system will completely hang. Crashing cpu can get
142 * an NMI if system was initially booted with nmi_watchdog parameter.
143 */
144 if (cpu == crashing_cpu)
145 return 1;
146 local_irq_disable();
147
148 if (!user_mode(regs)) {
149 crash_setup_regs(&fixed_regs, regs);
150 regs = &fixed_regs;
151 }
152 crash_save_this_cpu(regs, cpu);
153 disable_local_APIC();
154 atomic_dec(&waiting_for_crash_ipi);
155 /* Assume hlt works */
156 __asm__("hlt");
157 for(;;);
158
159 return 1;
160}
161
162/*
163 * By using the NMI code instead of a vector we just sneak thru the
164 * word generator coming out with just what we want. AND it does
165 * not matter if clustered_apic_mode is set or not.
166 */
167static void smp_send_nmi_allbutself(void)
168{
169 send_IPI_allbutself(APIC_DM_NMI);
170}
171
172static void nmi_shootdown_cpus(void)
173{
174 unsigned long msecs;
175
176 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
177 /* Would it be better to replace the trap vector here? */
178 set_nmi_callback(crash_nmi_callback);
179 /* Ensure the new callback function is set before sending
180 * out the NMI
181 */
182 wmb();
183
184 smp_send_nmi_allbutself();
185
186 msecs = 1000; /* Wait at most a second for the other cpus to stop */
187 while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
188 mdelay(1);
189 msecs--;
190 }
191
192 /* Leave the nmi callback set */
193 disable_local_APIC();
194}
195#else
196static void nmi_shootdown_cpus(void)
197{
198 /* There are no cpus to shootdown */
199}
200#endif
201
202void machine_crash_shutdown(struct pt_regs *regs)
203{
204 /* This function is only called after the system
205 * has paniced or is otherwise in a critical state.
206 * The minimum amount of code to allow a kexec'd kernel
207 * to run successfully needs to happen here.
208 *
209 * In practice this means shooting down the other cpus in
210 * an SMP system.
211 */
212 /* The kernel is broken so disable interrupts */
213 local_irq_disable();
214
215 /* Make a note of crashing cpu. Will be used in NMI callback.*/
216 crashing_cpu = smp_processor_id();
217 nmi_shootdown_cpus();
218 lapic_shutdown();
219#if defined(CONFIG_X86_IO_APIC)
220 disable_IO_APIC();
221#endif
222 crash_save_self(regs);
223}
diff --git a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c
index 6ed7e28f306c..a3cdf894302b 100644
--- a/arch/i386/kernel/dmi_scan.c
+++ b/arch/i386/kernel/dmi_scan.c
@@ -1,22 +1,15 @@
1#include <linux/types.h> 1#include <linux/types.h>
2#include <linux/kernel.h>
3#include <linux/string.h> 2#include <linux/string.h>
4#include <linux/init.h> 3#include <linux/init.h>
5#include <linux/module.h> 4#include <linux/module.h>
6#include <linux/slab.h>
7#include <linux/acpi.h>
8#include <asm/io.h>
9#include <linux/pm.h>
10#include <asm/system.h>
11#include <linux/dmi.h> 5#include <linux/dmi.h>
12#include <linux/bootmem.h> 6#include <linux/bootmem.h>
13 7
14 8
15struct dmi_header 9struct dmi_header {
16{ 10 u8 type;
17 u8 type; 11 u8 length;
18 u8 length; 12 u16 handle;
19 u16 handle;
20}; 13};
21 14
22#undef DMI_DEBUG 15#undef DMI_DEBUG
@@ -29,15 +22,13 @@ struct dmi_header
29 22
30static char * __init dmi_string(struct dmi_header *dm, u8 s) 23static char * __init dmi_string(struct dmi_header *dm, u8 s)
31{ 24{
32 u8 *bp=(u8 *)dm; 25 u8 *bp = ((u8 *) dm) + dm->length;
33 bp+=dm->length; 26
34 if(!s) 27 if (!s)
35 return ""; 28 return "";
36 s--; 29 s--;
37 while(s>0 && *bp) 30 while (s > 0 && *bp) {
38 { 31 bp += strlen(bp) + 1;
39 bp+=strlen(bp);
40 bp++;
41 s--; 32 s--;
42 } 33 }
43 return bp; 34 return bp;
@@ -47,16 +38,14 @@ static char * __init dmi_string(struct dmi_header *dm, u8 s)
47 * We have to be cautious here. We have seen BIOSes with DMI pointers 38 * We have to be cautious here. We have seen BIOSes with DMI pointers
48 * pointing to completely the wrong place for example 39 * pointing to completely the wrong place for example
49 */ 40 */
50 41static int __init dmi_table(u32 base, int len, int num,
51static int __init dmi_table(u32 base, int len, int num, void (*decode)(struct dmi_header *)) 42 void (*decode)(struct dmi_header *))
52{ 43{
53 u8 *buf; 44 u8 *buf, *data;
54 struct dmi_header *dm; 45 int i = 0;
55 u8 *data;
56 int i=0;
57 46
58 buf = bt_ioremap(base, len); 47 buf = bt_ioremap(base, len);
59 if(buf==NULL) 48 if (buf == NULL)
60 return -1; 49 return -1;
61 50
62 data = buf; 51 data = buf;
@@ -65,36 +54,34 @@ static int __init dmi_table(u32 base, int len, int num, void (*decode)(struct dm
65 * Stop when we see all the items the table claimed to have 54 * Stop when we see all the items the table claimed to have
66 * OR we run off the end of the table (also happens) 55 * OR we run off the end of the table (also happens)
67 */ 56 */
68 57 while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) {
69 while(i<num && data-buf+sizeof(struct dmi_header)<=len) 58 struct dmi_header *dm = (struct dmi_header *)data;
70 {
71 dm=(struct dmi_header *)data;
72 /* 59 /*
73 * We want to know the total length (formated area and strings) 60 * We want to know the total length (formated area and strings)
74 * before decoding to make sure we won't run off the table in 61 * before decoding to make sure we won't run off the table in
75 * dmi_decode or dmi_string 62 * dmi_decode or dmi_string
76 */ 63 */
77 data+=dm->length; 64 data += dm->length;
78 while(data-buf<len-1 && (data[0] || data[1])) 65 while ((data - buf < len - 1) && (data[0] || data[1]))
79 data++; 66 data++;
80 if(data-buf<len-1) 67 if (data - buf < len - 1)
81 decode(dm); 68 decode(dm);
82 data+=2; 69 data += 2;
83 i++; 70 i++;
84 } 71 }
85 bt_iounmap(buf, len); 72 bt_iounmap(buf, len);
86 return 0; 73 return 0;
87} 74}
88 75
89 76static int __init dmi_checksum(u8 *buf)
90inline static int __init dmi_checksum(u8 *buf)
91{ 77{
92 u8 sum=0; 78 u8 sum = 0;
93 int a; 79 int a;
94 80
95 for(a=0; a<15; a++) 81 for (a = 0; a < 15; a++)
96 sum+=buf[a]; 82 sum += buf[a];
97 return (sum==0); 83
84 return sum == 0;
98} 85}
99 86
100static int __init dmi_iterate(void (*decode)(struct dmi_header *)) 87static int __init dmi_iterate(void (*decode)(struct dmi_header *))
@@ -110,28 +97,30 @@ static int __init dmi_iterate(void (*decode)(struct dmi_header *))
110 p = ioremap(0xF0000, 0x10000); 97 p = ioremap(0xF0000, 0x10000);
111 if (p == NULL) 98 if (p == NULL)
112 return -1; 99 return -1;
100
113 for (q = p; q < p + 0x10000; q += 16) { 101 for (q = p; q < p + 0x10000; q += 16) {
114 memcpy_fromio(buf, q, 15); 102 memcpy_fromio(buf, q, 15);
115 if(memcmp(buf, "_DMI_", 5)==0 && dmi_checksum(buf)) 103 if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) {
116 { 104 u16 num = (buf[13] << 8) | buf[12];
117 u16 num=buf[13]<<8|buf[12]; 105 u16 len = (buf[7] << 8) | buf[6];
118 u16 len=buf[7]<<8|buf[6]; 106 u32 base = (buf[11] << 24) | (buf[10] << 16) |
119 u32 base=buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8]; 107 (buf[9] << 8) | buf[8];
120 108
121 /* 109 /*
122 * DMI version 0.0 means that the real version is taken from 110 * DMI version 0.0 means that the real version is taken from
123 * the SMBIOS version, which we don't know at this point. 111 * the SMBIOS version, which we don't know at this point.
124 */ 112 */
125 if(buf[14]!=0) 113 if (buf[14] != 0)
126 printk(KERN_INFO "DMI %d.%d present.\n", 114 printk(KERN_INFO "DMI %d.%d present.\n",
127 buf[14]>>4, buf[14]&0x0F); 115 buf[14] >> 4, buf[14] & 0xF);
128 else 116 else
129 printk(KERN_INFO "DMI present.\n"); 117 printk(KERN_INFO "DMI present.\n");
118
130 dmi_printk((KERN_INFO "%d structures occupying %d bytes.\n", 119 dmi_printk((KERN_INFO "%d structures occupying %d bytes.\n",
131 num, len)); 120 num, len));
132 dmi_printk((KERN_INFO "DMI table at 0x%08X.\n", 121 dmi_printk((KERN_INFO "DMI table at 0x%08X.\n", base));
133 base)); 122
134 if(dmi_table(base,len, num, decode)==0) 123 if (dmi_table(base,len, num, decode) == 0)
135 return 0; 124 return 0;
136 } 125 }
137 } 126 }
@@ -143,16 +132,17 @@ static char *dmi_ident[DMI_STRING_MAX];
143/* 132/*
144 * Save a DMI string 133 * Save a DMI string
145 */ 134 */
146
147static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string) 135static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string)
148{ 136{
149 char *d = (char*)dm; 137 char *d = (char*)dm;
150 char *p = dmi_string(dm, d[string]); 138 char *p = dmi_string(dm, d[string]);
151 if(p==NULL || *p == 0) 139
140 if (p == NULL || *p == 0)
152 return; 141 return;
153 if (dmi_ident[slot]) 142 if (dmi_ident[slot])
154 return; 143 return;
155 dmi_ident[slot] = alloc_bootmem(strlen(p)+1); 144
145 dmi_ident[slot] = alloc_bootmem(strlen(p) + 1);
156 if(dmi_ident[slot]) 146 if(dmi_ident[slot])
157 strcpy(dmi_ident[slot], p); 147 strcpy(dmi_ident[slot], p);
158 else 148 else
@@ -160,281 +150,47 @@ static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string)
160} 150}
161 151
162/* 152/*
163 * Ugly compatibility crap.
164 */
165#define dmi_blacklist dmi_system_id
166#define NO_MATCH { DMI_NONE, NULL}
167#define MATCH DMI_MATCH
168
169/*
170 * Toshiba keyboard likes to repeat keys when they are not repeated.
171 */
172
173static __init int broken_toshiba_keyboard(struct dmi_blacklist *d)
174{
175 printk(KERN_WARNING "Toshiba with broken keyboard detected. If your keyboard sometimes generates 3 keypresses instead of one, see http://davyd.ucc.asn.au/projects/toshiba/README\n");
176 return 0;
177}
178
179
180#ifdef CONFIG_ACPI_SLEEP
181static __init int reset_videomode_after_s3(struct dmi_blacklist *d)
182{
183 /* See acpi_wakeup.S */
184 extern long acpi_video_flags;
185 acpi_video_flags |= 2;
186 return 0;
187}
188#endif
189
190
191#ifdef CONFIG_ACPI_BOOT
192extern int acpi_force;
193
194static __init __attribute__((unused)) int dmi_disable_acpi(struct dmi_blacklist *d)
195{
196 if (!acpi_force) {
197 printk(KERN_NOTICE "%s detected: acpi off\n",d->ident);
198 disable_acpi();
199 } else {
200 printk(KERN_NOTICE
201 "Warning: DMI blacklist says broken, but acpi forced\n");
202 }
203 return 0;
204}
205
206/*
207 * Limit ACPI to CPU enumeration for HT
208 */
209static __init __attribute__((unused)) int force_acpi_ht(struct dmi_blacklist *d)
210{
211 if (!acpi_force) {
212 printk(KERN_NOTICE "%s detected: force use of acpi=ht\n", d->ident);
213 disable_acpi();
214 acpi_ht = 1;
215 } else {
216 printk(KERN_NOTICE
217 "Warning: acpi=force overrules DMI blacklist: acpi=ht\n");
218 }
219 return 0;
220}
221#endif
222
223#ifdef CONFIG_ACPI_PCI
224static __init int disable_acpi_irq(struct dmi_blacklist *d)
225{
226 if (!acpi_force) {
227 printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n",
228 d->ident);
229 acpi_noirq_set();
230 }
231 return 0;
232}
233static __init int disable_acpi_pci(struct dmi_blacklist *d)
234{
235 if (!acpi_force) {
236 printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n",
237 d->ident);
238 acpi_disable_pci();
239 }
240 return 0;
241}
242#endif
243
244/*
245 * Process the DMI blacklists
246 */
247
248
249/*
250 * This will be expanded over time to force things like the APM
251 * interrupt mask settings according to the laptop
252 */
253
254static __initdata struct dmi_blacklist dmi_blacklist[]={
255
256 { broken_toshiba_keyboard, "Toshiba Satellite 4030cdt", { /* Keyboard generates spurious repeats */
257 MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
258 NO_MATCH, NO_MATCH, NO_MATCH
259 } },
260#ifdef CONFIG_ACPI_SLEEP
261 { reset_videomode_after_s3, "Toshiba Satellite 4030cdt", { /* Reset video mode after returning from ACPI S3 sleep */
262 MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
263 NO_MATCH, NO_MATCH, NO_MATCH
264 } },
265#endif
266
267#ifdef CONFIG_ACPI_BOOT
268 /*
269 * If your system is blacklisted here, but you find that acpi=force
270 * works for you, please contact acpi-devel@sourceforge.net
271 */
272
273 /*
274 * Boxes that need ACPI disabled
275 */
276
277 { dmi_disable_acpi, "IBM Thinkpad", {
278 MATCH(DMI_BOARD_VENDOR, "IBM"),
279 MATCH(DMI_BOARD_NAME, "2629H1G"),
280 NO_MATCH, NO_MATCH }},
281
282 /*
283 * Boxes that need acpi=ht
284 */
285
286 { force_acpi_ht, "FSC Primergy T850", {
287 MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
288 MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"),
289 NO_MATCH, NO_MATCH }},
290
291 { force_acpi_ht, "DELL GX240", {
292 MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"),
293 MATCH(DMI_BOARD_NAME, "OptiPlex GX240"),
294 NO_MATCH, NO_MATCH }},
295
296 { force_acpi_ht, "HP VISUALIZE NT Workstation", {
297 MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
298 MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"),
299 NO_MATCH, NO_MATCH }},
300
301 { force_acpi_ht, "Compaq Workstation W8000", {
302 MATCH(DMI_SYS_VENDOR, "Compaq"),
303 MATCH(DMI_PRODUCT_NAME, "Workstation W8000"),
304 NO_MATCH, NO_MATCH }},
305
306 { force_acpi_ht, "ASUS P4B266", {
307 MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
308 MATCH(DMI_BOARD_NAME, "P4B266"),
309 NO_MATCH, NO_MATCH }},
310
311 { force_acpi_ht, "ASUS P2B-DS", {
312 MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
313 MATCH(DMI_BOARD_NAME, "P2B-DS"),
314 NO_MATCH, NO_MATCH }},
315
316 { force_acpi_ht, "ASUS CUR-DLS", {
317 MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
318 MATCH(DMI_BOARD_NAME, "CUR-DLS"),
319 NO_MATCH, NO_MATCH }},
320
321 { force_acpi_ht, "ABIT i440BX-W83977", {
322 MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"),
323 MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"),
324 NO_MATCH, NO_MATCH }},
325
326 { force_acpi_ht, "IBM Bladecenter", {
327 MATCH(DMI_BOARD_VENDOR, "IBM"),
328 MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"),
329 NO_MATCH, NO_MATCH }},
330
331 { force_acpi_ht, "IBM eServer xSeries 360", {
332 MATCH(DMI_BOARD_VENDOR, "IBM"),
333 MATCH(DMI_BOARD_NAME, "eServer xSeries 360"),
334 NO_MATCH, NO_MATCH }},
335
336 { force_acpi_ht, "IBM eserver xSeries 330", {
337 MATCH(DMI_BOARD_VENDOR, "IBM"),
338 MATCH(DMI_BOARD_NAME, "eserver xSeries 330"),
339 NO_MATCH, NO_MATCH }},
340
341 { force_acpi_ht, "IBM eserver xSeries 440", {
342 MATCH(DMI_BOARD_VENDOR, "IBM"),
343 MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"),
344 NO_MATCH, NO_MATCH }},
345
346#endif // CONFIG_ACPI_BOOT
347
348#ifdef CONFIG_ACPI_PCI
349 /*
350 * Boxes that need ACPI PCI IRQ routing disabled
351 */
352
353 { disable_acpi_irq, "ASUS A7V", {
354 MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
355 MATCH(DMI_BOARD_NAME, "<A7V>"),
356 /* newer BIOS, Revision 1011, does work */
357 MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"),
358 NO_MATCH }},
359
360 /*
361 * Boxes that need ACPI PCI IRQ routing and PCI scan disabled
362 */
363 { disable_acpi_pci, "ASUS PR-DLS", { /* _BBN 0 bug */
364 MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
365 MATCH(DMI_BOARD_NAME, "PR-DLS"),
366 MATCH(DMI_BIOS_VERSION, "ASUS PR-DLS ACPI BIOS Revision 1010"),
367 MATCH(DMI_BIOS_DATE, "03/21/2003") }},
368
369 { disable_acpi_pci, "Acer TravelMate 36x Laptop", {
370 MATCH(DMI_SYS_VENDOR, "Acer"),
371 MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
372 NO_MATCH, NO_MATCH
373 } },
374
375#endif
376
377 { NULL, }
378};
379
380/*
381 * Process a DMI table entry. Right now all we care about are the BIOS 153 * Process a DMI table entry. Right now all we care about are the BIOS
382 * and machine entries. For 2.5 we should pull the smbus controller info 154 * and machine entries. For 2.5 we should pull the smbus controller info
383 * out of here. 155 * out of here.
384 */ 156 */
385
386static void __init dmi_decode(struct dmi_header *dm) 157static void __init dmi_decode(struct dmi_header *dm)
387{ 158{
388#ifdef DMI_DEBUG 159 u8 *data __attribute__((__unused__)) = (u8 *)dm;
389 u8 *data = (u8 *)dm;
390#endif
391 160
392 switch(dm->type) 161 switch(dm->type) {
393 { 162 case 0:
394 case 0: 163 dmi_printk(("BIOS Vendor: %s\n", dmi_string(dm, data[4])));
395 dmi_printk(("BIOS Vendor: %s\n", 164 dmi_save_ident(dm, DMI_BIOS_VENDOR, 4);
396 dmi_string(dm, data[4]))); 165 dmi_printk(("BIOS Version: %s\n", dmi_string(dm, data[5])));
397 dmi_save_ident(dm, DMI_BIOS_VENDOR, 4); 166 dmi_save_ident(dm, DMI_BIOS_VERSION, 5);
398 dmi_printk(("BIOS Version: %s\n", 167 dmi_printk(("BIOS Release: %s\n", dmi_string(dm, data[8])));
399 dmi_string(dm, data[5]))); 168 dmi_save_ident(dm, DMI_BIOS_DATE, 8);
400 dmi_save_ident(dm, DMI_BIOS_VERSION, 5); 169 break;
401 dmi_printk(("BIOS Release: %s\n", 170 case 1:
402 dmi_string(dm, data[8]))); 171 dmi_printk(("System Vendor: %s\n", dmi_string(dm, data[4])));
403 dmi_save_ident(dm, DMI_BIOS_DATE, 8); 172 dmi_save_ident(dm, DMI_SYS_VENDOR, 4);
404 break; 173 dmi_printk(("Product Name: %s\n", dmi_string(dm, data[5])));
405 case 1: 174 dmi_save_ident(dm, DMI_PRODUCT_NAME, 5);
406 dmi_printk(("System Vendor: %s\n", 175 dmi_printk(("Version: %s\n", dmi_string(dm, data[6])));
407 dmi_string(dm, data[4]))); 176 dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
408 dmi_save_ident(dm, DMI_SYS_VENDOR, 4); 177 dmi_printk(("Serial Number: %s\n", dmi_string(dm, data[7])));
409 dmi_printk(("Product Name: %s\n", 178 dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7);
410 dmi_string(dm, data[5]))); 179 break;
411 dmi_save_ident(dm, DMI_PRODUCT_NAME, 5); 180 case 2:
412 dmi_printk(("Version: %s\n", 181 dmi_printk(("Board Vendor: %s\n", dmi_string(dm, data[4])));
413 dmi_string(dm, data[6]))); 182 dmi_save_ident(dm, DMI_BOARD_VENDOR, 4);
414 dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6); 183 dmi_printk(("Board Name: %s\n", dmi_string(dm, data[5])));
415 dmi_printk(("Serial Number: %s\n", 184 dmi_save_ident(dm, DMI_BOARD_NAME, 5);
416 dmi_string(dm, data[7]))); 185 dmi_printk(("Board Version: %s\n", dmi_string(dm, data[6])));
417 break; 186 dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
418 case 2: 187 break;
419 dmi_printk(("Board Vendor: %s\n",
420 dmi_string(dm, data[4])));
421 dmi_save_ident(dm, DMI_BOARD_VENDOR, 4);
422 dmi_printk(("Board Name: %s\n",
423 dmi_string(dm, data[5])));
424 dmi_save_ident(dm, DMI_BOARD_NAME, 5);
425 dmi_printk(("Board Version: %s\n",
426 dmi_string(dm, data[6])));
427 dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
428 break;
429 } 188 }
430} 189}
431 190
432void __init dmi_scan_machine(void) 191void __init dmi_scan_machine(void)
433{ 192{
434 int err = dmi_iterate(dmi_decode); 193 if (dmi_iterate(dmi_decode))
435 if(err == 0)
436 dmi_check_system(dmi_blacklist);
437 else
438 printk(KERN_INFO "DMI not present.\n"); 194 printk(KERN_INFO "DMI not present.\n");
439} 195}
440 196
@@ -470,7 +226,6 @@ fail: d++;
470 226
471 return count; 227 return count;
472} 228}
473
474EXPORT_SYMBOL(dmi_check_system); 229EXPORT_SYMBOL(dmi_check_system);
475 230
476/** 231/**
@@ -480,8 +235,8 @@ EXPORT_SYMBOL(dmi_check_system);
480 * Returns one DMI data value, can be used to perform 235 * Returns one DMI data value, can be used to perform
481 * complex DMI data checks. 236 * complex DMI data checks.
482 */ 237 */
483char * dmi_get_system_info(int field) 238char *dmi_get_system_info(int field)
484{ 239{
485 return dmi_ident[field]; 240 return dmi_ident[field];
486} 241}
487 242EXPORT_SYMBOL(dmi_get_system_info);
diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c
index f732f427b418..385883ea8c19 100644
--- a/arch/i386/kernel/efi.c
+++ b/arch/i386/kernel/efi.c
@@ -30,6 +30,7 @@
30#include <linux/ioport.h> 30#include <linux/ioport.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/efi.h> 32#include <linux/efi.h>
33#include <linux/kexec.h>
33 34
34#include <asm/setup.h> 35#include <asm/setup.h>
35#include <asm/io.h> 36#include <asm/io.h>
@@ -598,6 +599,9 @@ efi_initialize_iomem_resources(struct resource *code_resource,
598 if (md->type == EFI_CONVENTIONAL_MEMORY) { 599 if (md->type == EFI_CONVENTIONAL_MEMORY) {
599 request_resource(res, code_resource); 600 request_resource(res, code_resource);
600 request_resource(res, data_resource); 601 request_resource(res, data_resource);
602#ifdef CONFIG_KEXEC
603 request_resource(res, &crashk_res);
604#endif
601 } 605 }
602 } 606 }
603} 607}
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
index e966fc8c44c4..4477bb107098 100644
--- a/arch/i386/kernel/head.S
+++ b/arch/i386/kernel/head.S
@@ -299,7 +299,6 @@ is386: movl $2,%ecx # set MP
299 movl %eax,%cr0 299 movl %eax,%cr0
300 300
301 call check_x87 301 call check_x87
302 incb ready
303 lgdt cpu_gdt_descr 302 lgdt cpu_gdt_descr
304 lidt idt_descr 303 lidt idt_descr
305 ljmp $(__KERNEL_CS),$1f 304 ljmp $(__KERNEL_CS),$1f
@@ -316,8 +315,9 @@ is386: movl $2,%ecx # set MP
316 lldt %ax 315 lldt %ax
317 cld # gcc2 wants the direction flag cleared at all times 316 cld # gcc2 wants the direction flag cleared at all times
318#ifdef CONFIG_SMP 317#ifdef CONFIG_SMP
319 movb ready, %cl 318 movb ready, %cl
320 cmpb $1,%cl 319 movb $1, ready
320 cmpb $0,%cl
321 je 1f # the first CPU calls start_kernel 321 je 1f # the first CPU calls start_kernel
322 # all other CPUs call initialize_secondary 322 # all other CPUs call initialize_secondary
323 call initialize_secondary 323 call initialize_secondary
diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c
index 2c4813b47e57..178f4e9bac9d 100644
--- a/arch/i386/kernel/i8259.c
+++ b/arch/i386/kernel/i8259.c
@@ -268,10 +268,22 @@ static int i8259A_suspend(struct sys_device *dev, pm_message_t state)
268 return 0; 268 return 0;
269} 269}
270 270
271static int i8259A_shutdown(struct sys_device *dev)
272{
273 /* Put the i8259A into a quiescent state that
274 * the kernel initialization code can get it
275 * out of.
276 */
277 outb(0xff, 0x21); /* mask all of 8259A-1 */
278 outb(0xff, 0xA1); /* mask all of 8259A-1 */
279 return 0;
280}
281
271static struct sysdev_class i8259_sysdev_class = { 282static struct sysdev_class i8259_sysdev_class = {
272 set_kset_name("i8259"), 283 set_kset_name("i8259"),
273 .suspend = i8259A_suspend, 284 .suspend = i8259A_suspend,
274 .resume = i8259A_resume, 285 .resume = i8259A_resume,
286 .shutdown = i8259A_shutdown,
275}; 287};
276 288
277static struct sys_device device_i8259A = { 289static struct sys_device device_i8259A = {
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 08540bc4ba3e..35eb8e29c485 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -573,12 +573,14 @@ static int balanced_irq(void *unused)
573 for ( ; ; ) { 573 for ( ; ; ) {
574 set_current_state(TASK_INTERRUPTIBLE); 574 set_current_state(TASK_INTERRUPTIBLE);
575 time_remaining = schedule_timeout(time_remaining); 575 time_remaining = schedule_timeout(time_remaining);
576 try_to_freeze(PF_FREEZE); 576 try_to_freeze();
577 if (time_after(jiffies, 577 if (time_after(jiffies,
578 prev_balance_time+balanced_irq_interval)) { 578 prev_balance_time+balanced_irq_interval)) {
579 preempt_disable();
579 do_irq_balance(); 580 do_irq_balance();
580 prev_balance_time = jiffies; 581 prev_balance_time = jiffies;
581 time_remaining = balanced_irq_interval; 582 time_remaining = balanced_irq_interval;
583 preempt_enable();
582 } 584 }
583 } 585 }
584 return 0; 586 return 0;
@@ -630,10 +632,8 @@ static int __init balanced_irq_init(void)
630 printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq"); 632 printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq");
631failed: 633failed:
632 for (i = 0; i < NR_CPUS; i++) { 634 for (i = 0; i < NR_CPUS; i++) {
633 if(irq_cpu_data[i].irq_delta) 635 kfree(irq_cpu_data[i].irq_delta);
634 kfree(irq_cpu_data[i].irq_delta); 636 kfree(irq_cpu_data[i].last_irq);
635 if(irq_cpu_data[i].last_irq)
636 kfree(irq_cpu_data[i].last_irq);
637 } 637 }
638 return 0; 638 return 0;
639} 639}
@@ -1634,12 +1634,43 @@ static void __init enable_IO_APIC(void)
1634 */ 1634 */
1635void disable_IO_APIC(void) 1635void disable_IO_APIC(void)
1636{ 1636{
1637 int pin;
1637 /* 1638 /*
1638 * Clear the IO-APIC before rebooting: 1639 * Clear the IO-APIC before rebooting:
1639 */ 1640 */
1640 clear_IO_APIC(); 1641 clear_IO_APIC();
1641 1642
1642 disconnect_bsp_APIC(); 1643 /*
1644 * If the i82559 is routed through an IOAPIC
1645 * Put that IOAPIC in virtual wire mode
1646 * so legacy interrups can be delivered.
1647 */
1648 pin = find_isa_irq_pin(0, mp_ExtINT);
1649 if (pin != -1) {
1650 struct IO_APIC_route_entry entry;
1651 unsigned long flags;
1652
1653 memset(&entry, 0, sizeof(entry));
1654 entry.mask = 0; /* Enabled */
1655 entry.trigger = 0; /* Edge */
1656 entry.irr = 0;
1657 entry.polarity = 0; /* High */
1658 entry.delivery_status = 0;
1659 entry.dest_mode = 0; /* Physical */
1660 entry.delivery_mode = 7; /* ExtInt */
1661 entry.vector = 0;
1662 entry.dest.physical.physical_dest = 0;
1663
1664
1665 /*
1666 * Add it to the IO-APIC irq-routing table:
1667 */
1668 spin_lock_irqsave(&ioapic_lock, flags);
1669 io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1));
1670 io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0));
1671 spin_unlock_irqrestore(&ioapic_lock, flags);
1672 }
1673 disconnect_bsp_APIC(pin != -1);
1643} 1674}
1644 1675
1645/* 1676/*
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
index 73945a3c53c4..ce66dcc26d90 100644
--- a/arch/i386/kernel/irq.c
+++ b/arch/i386/kernel/irq.c
@@ -15,6 +15,9 @@
15#include <linux/seq_file.h> 15#include <linux/seq_file.h>
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/kernel_stat.h> 17#include <linux/kernel_stat.h>
18#include <linux/notifier.h>
19#include <linux/cpu.h>
20#include <linux/delay.h>
18 21
19DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_maxaligned_in_smp; 22DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_maxaligned_in_smp;
20EXPORT_PER_CPU_SYMBOL(irq_stat); 23EXPORT_PER_CPU_SYMBOL(irq_stat);
@@ -153,6 +156,11 @@ void irq_ctx_init(int cpu)
153 cpu,hardirq_ctx[cpu],softirq_ctx[cpu]); 156 cpu,hardirq_ctx[cpu],softirq_ctx[cpu]);
154} 157}
155 158
159void irq_ctx_exit(int cpu)
160{
161 hardirq_ctx[cpu] = NULL;
162}
163
156extern asmlinkage void __do_softirq(void); 164extern asmlinkage void __do_softirq(void);
157 165
158asmlinkage void do_softirq(void) 166asmlinkage void do_softirq(void)
@@ -210,9 +218,8 @@ int show_interrupts(struct seq_file *p, void *v)
210 218
211 if (i == 0) { 219 if (i == 0) {
212 seq_printf(p, " "); 220 seq_printf(p, " ");
213 for (j=0; j<NR_CPUS; j++) 221 for_each_cpu(j)
214 if (cpu_online(j)) 222 seq_printf(p, "CPU%d ",j);
215 seq_printf(p, "CPU%d ",j);
216 seq_putc(p, '\n'); 223 seq_putc(p, '\n');
217 } 224 }
218 225
@@ -225,9 +232,8 @@ int show_interrupts(struct seq_file *p, void *v)
225#ifndef CONFIG_SMP 232#ifndef CONFIG_SMP
226 seq_printf(p, "%10u ", kstat_irqs(i)); 233 seq_printf(p, "%10u ", kstat_irqs(i));
227#else 234#else
228 for (j = 0; j < NR_CPUS; j++) 235 for_each_cpu(j)
229 if (cpu_online(j)) 236 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
230 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
231#endif 237#endif
232 seq_printf(p, " %14s", irq_desc[i].handler->typename); 238 seq_printf(p, " %14s", irq_desc[i].handler->typename);
233 seq_printf(p, " %s", action->name); 239 seq_printf(p, " %s", action->name);
@@ -240,16 +246,14 @@ skip:
240 spin_unlock_irqrestore(&irq_desc[i].lock, flags); 246 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
241 } else if (i == NR_IRQS) { 247 } else if (i == NR_IRQS) {
242 seq_printf(p, "NMI: "); 248 seq_printf(p, "NMI: ");
243 for (j = 0; j < NR_CPUS; j++) 249 for_each_cpu(j)
244 if (cpu_online(j)) 250 seq_printf(p, "%10u ", nmi_count(j));
245 seq_printf(p, "%10u ", nmi_count(j));
246 seq_putc(p, '\n'); 251 seq_putc(p, '\n');
247#ifdef CONFIG_X86_LOCAL_APIC 252#ifdef CONFIG_X86_LOCAL_APIC
248 seq_printf(p, "LOC: "); 253 seq_printf(p, "LOC: ");
249 for (j = 0; j < NR_CPUS; j++) 254 for_each_cpu(j)
250 if (cpu_online(j)) 255 seq_printf(p, "%10u ",
251 seq_printf(p, "%10u ", 256 per_cpu(irq_stat,j).apic_timer_irqs);
252 per_cpu(irq_stat,j).apic_timer_irqs);
253 seq_putc(p, '\n'); 257 seq_putc(p, '\n');
254#endif 258#endif
255 seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); 259 seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
@@ -259,3 +263,45 @@ skip:
259 } 263 }
260 return 0; 264 return 0;
261} 265}
266
267#ifdef CONFIG_HOTPLUG_CPU
268#include <mach_apic.h>
269
270void fixup_irqs(cpumask_t map)
271{
272 unsigned int irq;
273 static int warned;
274
275 for (irq = 0; irq < NR_IRQS; irq++) {
276 cpumask_t mask;
277 if (irq == 2)
278 continue;
279
280 cpus_and(mask, irq_affinity[irq], map);
281 if (any_online_cpu(mask) == NR_CPUS) {
282 printk("Breaking affinity for irq %i\n", irq);
283 mask = map;
284 }
285 if (irq_desc[irq].handler->set_affinity)
286 irq_desc[irq].handler->set_affinity(irq, mask);
287 else if (irq_desc[irq].action && !(warned++))
288 printk("Cannot set affinity for irq %i\n", irq);
289 }
290
291#if 0
292 barrier();
293 /* Ingo Molnar says: "after the IO-APIC masks have been redirected
294 [note the nop - the interrupt-enable boundary on x86 is two
295 instructions from sti] - to flush out pending hardirqs and
296 IPIs. After this point nothing is supposed to reach this CPU." */
297 __asm__ __volatile__("sti; nop; cli");
298 barrier();
299#else
300 /* That doesn't seem sufficient. Give it 1ms. */
301 local_irq_enable();
302 mdelay(1);
303 local_irq_disable();
304#endif
305}
306#endif
307
diff --git a/arch/i386/kernel/machine_kexec.c b/arch/i386/kernel/machine_kexec.c
new file mode 100644
index 000000000000..52ed18d8b511
--- /dev/null
+++ b/arch/i386/kernel/machine_kexec.c
@@ -0,0 +1,226 @@
1/*
2 * machine_kexec.c - handle transition of Linux booting another kernel
3 * Copyright (C) 2002-2005 Eric Biederman <ebiederm@xmission.com>
4 *
5 * This source code is licensed under the GNU General Public License,
6 * Version 2. See the file COPYING for more details.
7 */
8
9#include <linux/mm.h>
10#include <linux/kexec.h>
11#include <linux/delay.h>
12#include <asm/pgtable.h>
13#include <asm/pgalloc.h>
14#include <asm/tlbflush.h>
15#include <asm/mmu_context.h>
16#include <asm/io.h>
17#include <asm/apic.h>
18#include <asm/cpufeature.h>
19
20static inline unsigned long read_cr3(void)
21{
22 unsigned long cr3;
23 asm volatile("movl %%cr3,%0": "=r"(cr3));
24 return cr3;
25}
26
27#define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
28
29#define L0_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
30#define L1_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
31#define L2_ATTR (_PAGE_PRESENT)
32
33#define LEVEL0_SIZE (1UL << 12UL)
34
35#ifndef CONFIG_X86_PAE
36#define LEVEL1_SIZE (1UL << 22UL)
37static u32 pgtable_level1[1024] PAGE_ALIGNED;
38
39static void identity_map_page(unsigned long address)
40{
41 unsigned long level1_index, level2_index;
42 u32 *pgtable_level2;
43
44 /* Find the current page table */
45 pgtable_level2 = __va(read_cr3());
46
47 /* Find the indexes of the physical address to identity map */
48 level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE;
49 level2_index = address / LEVEL1_SIZE;
50
51 /* Identity map the page table entry */
52 pgtable_level1[level1_index] = address | L0_ATTR;
53 pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR;
54
55 /* Flush the tlb so the new mapping takes effect.
56 * Global tlb entries are not flushed but that is not an issue.
57 */
58 load_cr3(pgtable_level2);
59}
60
61#else
62#define LEVEL1_SIZE (1UL << 21UL)
63#define LEVEL2_SIZE (1UL << 30UL)
64static u64 pgtable_level1[512] PAGE_ALIGNED;
65static u64 pgtable_level2[512] PAGE_ALIGNED;
66
67static void identity_map_page(unsigned long address)
68{
69 unsigned long level1_index, level2_index, level3_index;
70 u64 *pgtable_level3;
71
72 /* Find the current page table */
73 pgtable_level3 = __va(read_cr3());
74
75 /* Find the indexes of the physical address to identity map */
76 level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE;
77 level2_index = (address % LEVEL2_SIZE)/LEVEL1_SIZE;
78 level3_index = address / LEVEL2_SIZE;
79
80 /* Identity map the page table entry */
81 pgtable_level1[level1_index] = address | L0_ATTR;
82 pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR;
83 set_64bit(&pgtable_level3[level3_index],
84 __pa(pgtable_level2) | L2_ATTR);
85
86 /* Flush the tlb so the new mapping takes effect.
87 * Global tlb entries are not flushed but that is not an issue.
88 */
89 load_cr3(pgtable_level3);
90}
91#endif
92
93
94static void set_idt(void *newidt, __u16 limit)
95{
96 unsigned char curidt[6];
97
98 /* ia32 supports unaliged loads & stores */
99 (*(__u16 *)(curidt)) = limit;
100 (*(__u32 *)(curidt +2)) = (unsigned long)(newidt);
101
102 __asm__ __volatile__ (
103 "lidt %0\n"
104 : "=m" (curidt)
105 );
106};
107
108
109static void set_gdt(void *newgdt, __u16 limit)
110{
111 unsigned char curgdt[6];
112
113 /* ia32 supports unaligned loads & stores */
114 (*(__u16 *)(curgdt)) = limit;
115 (*(__u32 *)(curgdt +2)) = (unsigned long)(newgdt);
116
117 __asm__ __volatile__ (
118 "lgdt %0\n"
119 : "=m" (curgdt)
120 );
121};
122
123static void load_segments(void)
124{
125#define __STR(X) #X
126#define STR(X) __STR(X)
127
128 __asm__ __volatile__ (
129 "\tljmp $"STR(__KERNEL_CS)",$1f\n"
130 "\t1:\n"
131 "\tmovl $"STR(__KERNEL_DS)",%eax\n"
132 "\tmovl %eax,%ds\n"
133 "\tmovl %eax,%es\n"
134 "\tmovl %eax,%fs\n"
135 "\tmovl %eax,%gs\n"
136 "\tmovl %eax,%ss\n"
137 );
138#undef STR
139#undef __STR
140}
141
142typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)(
143 unsigned long indirection_page,
144 unsigned long reboot_code_buffer,
145 unsigned long start_address,
146 unsigned int has_pae) ATTRIB_NORET;
147
148const extern unsigned char relocate_new_kernel[];
149extern void relocate_new_kernel_end(void);
150const extern unsigned int relocate_new_kernel_size;
151
152/*
153 * A architecture hook called to validate the
154 * proposed image and prepare the control pages
155 * as needed. The pages for KEXEC_CONTROL_CODE_SIZE
156 * have been allocated, but the segments have yet
157 * been copied into the kernel.
158 *
159 * Do what every setup is needed on image and the
160 * reboot code buffer to allow us to avoid allocations
161 * later.
162 *
163 * Currently nothing.
164 */
165int machine_kexec_prepare(struct kimage *image)
166{
167 return 0;
168}
169
170/*
171 * Undo anything leftover by machine_kexec_prepare
172 * when an image is freed.
173 */
174void machine_kexec_cleanup(struct kimage *image)
175{
176}
177
178/*
179 * Do not allocate memory (or fail in any way) in machine_kexec().
180 * We are past the point of no return, committed to rebooting now.
181 */
182NORET_TYPE void machine_kexec(struct kimage *image)
183{
184 unsigned long page_list;
185 unsigned long reboot_code_buffer;
186
187 relocate_new_kernel_t rnk;
188
189 /* Interrupts aren't acceptable while we reboot */
190 local_irq_disable();
191
192 /* Compute some offsets */
193 reboot_code_buffer = page_to_pfn(image->control_code_page)
194 << PAGE_SHIFT;
195 page_list = image->head;
196
197 /* Set up an identity mapping for the reboot_code_buffer */
198 identity_map_page(reboot_code_buffer);
199
200 /* copy it out */
201 memcpy((void *)reboot_code_buffer, relocate_new_kernel,
202 relocate_new_kernel_size);
203
204 /* The segment registers are funny things, they are
205 * automatically loaded from a table, in memory wherever you
206 * set them to a specific selector, but this table is never
207 * accessed again you set the segment to a different selector.
208 *
209 * The more common model is are caches where the behide
210 * the scenes work is done, but is also dropped at arbitrary
211 * times.
212 *
213 * I take advantage of this here by force loading the
214 * segments, before I zap the gdt with an invalid value.
215 */
216 load_segments();
217 /* The gdt & idt are now invalid.
218 * If you want to load them you must set up your own idt & gdt.
219 */
220 set_gdt(phys_to_virt(0),0);
221 set_idt(phys_to_virt(0),0);
222
223 /* now call it */
224 rnk = (relocate_new_kernel_t) reboot_code_buffer;
225 (*rnk)(page_list, reboot_code_buffer, image->start, cpu_has_pae);
226}
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index 383a11600d2c..af917f609c7d 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -67,7 +67,6 @@ unsigned long mp_lapic_addr;
67 67
68/* Processor that is doing the boot up */ 68/* Processor that is doing the boot up */
69unsigned int boot_cpu_physical_apicid = -1U; 69unsigned int boot_cpu_physical_apicid = -1U;
70unsigned int boot_cpu_logical_apicid = -1U;
71/* Internal processor count */ 70/* Internal processor count */
72static unsigned int __initdata num_processors; 71static unsigned int __initdata num_processors;
73 72
@@ -180,7 +179,6 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
180 if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { 179 if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
181 Dprintk(" Bootup CPU\n"); 180 Dprintk(" Bootup CPU\n");
182 boot_cpu_physical_apicid = m->mpc_apicid; 181 boot_cpu_physical_apicid = m->mpc_apicid;
183 boot_cpu_logical_apicid = apicid;
184 } 182 }
185 183
186 if (num_processors >= NR_CPUS) { 184 if (num_processors >= NR_CPUS) {
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index aea2ce1145df..5f8cfa6b7940 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -13,6 +13,7 @@
13 13
14#include <stdarg.h> 14#include <stdarg.h>
15 15
16#include <linux/cpu.h>
16#include <linux/errno.h> 17#include <linux/errno.h>
17#include <linux/sched.h> 18#include <linux/sched.h>
18#include <linux/fs.h> 19#include <linux/fs.h>
@@ -55,6 +56,9 @@
55#include <linux/irq.h> 56#include <linux/irq.h>
56#include <linux/err.h> 57#include <linux/err.h>
57 58
59#include <asm/tlbflush.h>
60#include <asm/cpu.h>
61
58asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); 62asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
59 63
60static int hlt_counter; 64static int hlt_counter;
@@ -143,14 +147,42 @@ static void poll_idle (void)
143 } 147 }
144} 148}
145 149
150#ifdef CONFIG_HOTPLUG_CPU
151#include <asm/nmi.h>
152/* We don't actually take CPU down, just spin without interrupts. */
153static inline void play_dead(void)
154{
155 /* This must be done before dead CPU ack */
156 cpu_exit_clear();
157 wbinvd();
158 mb();
159 /* Ack it */
160 __get_cpu_var(cpu_state) = CPU_DEAD;
161
162 /*
163 * With physical CPU hotplug, we should halt the cpu
164 */
165 local_irq_disable();
166 while (1)
167 __asm__ __volatile__("hlt":::"memory");
168}
169#else
170static inline void play_dead(void)
171{
172 BUG();
173}
174#endif /* CONFIG_HOTPLUG_CPU */
175
146/* 176/*
147 * The idle thread. There's no useful work to be 177 * The idle thread. There's no useful work to be
148 * done, so just try to conserve power and have a 178 * done, so just try to conserve power and have a
149 * low exit latency (ie sit in a loop waiting for 179 * low exit latency (ie sit in a loop waiting for
150 * somebody to say that they'd like to reschedule) 180 * somebody to say that they'd like to reschedule)
151 */ 181 */
152void cpu_idle (void) 182void cpu_idle(void)
153{ 183{
184 int cpu = raw_smp_processor_id();
185
154 /* endless idle loop with no priority at all */ 186 /* endless idle loop with no priority at all */
155 while (1) { 187 while (1) {
156 while (!need_resched()) { 188 while (!need_resched()) {
@@ -165,6 +197,9 @@ void cpu_idle (void)
165 if (!idle) 197 if (!idle)
166 idle = default_idle; 198 idle = default_idle;
167 199
200 if (cpu_is_offline(cpu))
201 play_dead();
202
168 __get_cpu_var(irq_stat).idle_timestamp = jiffies; 203 __get_cpu_var(irq_stat).idle_timestamp = jiffies;
169 idle(); 204 idle();
170 } 205 }
@@ -223,7 +258,7 @@ static void mwait_idle(void)
223 } 258 }
224} 259}
225 260
226void __init select_idle_routine(const struct cpuinfo_x86 *c) 261void __devinit select_idle_routine(const struct cpuinfo_x86 *c)
227{ 262{
228 if (cpu_has(c, X86_FEATURE_MWAIT)) { 263 if (cpu_has(c, X86_FEATURE_MWAIT)) {
229 printk("monitor/mwait feature present.\n"); 264 printk("monitor/mwait feature present.\n");
diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c
index db912209a8d3..b3e584849961 100644
--- a/arch/i386/kernel/reboot.c
+++ b/arch/i386/kernel/reboot.c
@@ -26,7 +26,6 @@ static int reboot_mode;
26static int reboot_thru_bios; 26static int reboot_thru_bios;
27 27
28#ifdef CONFIG_SMP 28#ifdef CONFIG_SMP
29int reboot_smp = 0;
30static int reboot_cpu = -1; 29static int reboot_cpu = -1;
31/* shamelessly grabbed from lib/vsprintf.c for readability */ 30/* shamelessly grabbed from lib/vsprintf.c for readability */
32#define is_digit(c) ((c) >= '0' && (c) <= '9') 31#define is_digit(c) ((c) >= '0' && (c) <= '9')
@@ -49,7 +48,6 @@ static int __init reboot_setup(char *str)
49 break; 48 break;
50#ifdef CONFIG_SMP 49#ifdef CONFIG_SMP
51 case 's': /* "smp" reboot by executing reset on BSP or other CPU*/ 50 case 's': /* "smp" reboot by executing reset on BSP or other CPU*/
52 reboot_smp = 1;
53 if (is_digit(*(str+1))) { 51 if (is_digit(*(str+1))) {
54 reboot_cpu = (int) (*(str+1) - '0'); 52 reboot_cpu = (int) (*(str+1) - '0');
55 if (is_digit(*(str+2))) 53 if (is_digit(*(str+2)))
@@ -88,33 +86,9 @@ static int __init set_bios_reboot(struct dmi_system_id *d)
88 return 0; 86 return 0;
89} 87}
90 88
91/*
92 * Some machines require the "reboot=s" commandline option, this quirk makes that automatic.
93 */
94static int __init set_smp_reboot(struct dmi_system_id *d)
95{
96#ifdef CONFIG_SMP
97 if (!reboot_smp) {
98 reboot_smp = 1;
99 printk(KERN_INFO "%s series board detected. Selecting SMP-method for reboots.\n", d->ident);
100 }
101#endif
102 return 0;
103}
104
105/*
106 * Some machines require the "reboot=b,s" commandline option, this quirk makes that automatic.
107 */
108static int __init set_smp_bios_reboot(struct dmi_system_id *d)
109{
110 set_smp_reboot(d);
111 set_bios_reboot(d);
112 return 0;
113}
114
115static struct dmi_system_id __initdata reboot_dmi_table[] = { 89static struct dmi_system_id __initdata reboot_dmi_table[] = {
116 { /* Handle problems with rebooting on Dell 1300's */ 90 { /* Handle problems with rebooting on Dell 1300's */
117 .callback = set_smp_bios_reboot, 91 .callback = set_bios_reboot,
118 .ident = "Dell PowerEdge 1300", 92 .ident = "Dell PowerEdge 1300",
119 .matches = { 93 .matches = {
120 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), 94 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
@@ -301,41 +275,32 @@ void machine_real_restart(unsigned char *code, int length)
301EXPORT_SYMBOL(machine_real_restart); 275EXPORT_SYMBOL(machine_real_restart);
302#endif 276#endif
303 277
304void machine_restart(char * __unused) 278void machine_shutdown(void)
305{ 279{
306#ifdef CONFIG_SMP 280#ifdef CONFIG_SMP
307 int cpuid; 281 int reboot_cpu_id;
308 282
309 cpuid = GET_APIC_ID(apic_read(APIC_ID)); 283 /* The boot cpu is always logical cpu 0 */
310 284 reboot_cpu_id = 0;
311 if (reboot_smp) { 285
312 286 /* See if there has been given a command line override */
313 /* check to see if reboot_cpu is valid 287 if ((reboot_cpu_id != -1) && (reboot_cpu < NR_CPUS) &&
314 if its not, default to the BSP */ 288 cpu_isset(reboot_cpu, cpu_online_map)) {
315 if ((reboot_cpu == -1) || 289 reboot_cpu_id = reboot_cpu;
316 (reboot_cpu > (NR_CPUS -1)) ||
317 !physid_isset(cpuid, phys_cpu_present_map))
318 reboot_cpu = boot_cpu_physical_apicid;
319
320 reboot_smp = 0; /* use this as a flag to only go through this once*/
321 /* re-run this function on the other CPUs
322 it will fall though this section since we have
323 cleared reboot_smp, and do the reboot if it is the
324 correct CPU, otherwise it halts. */
325 if (reboot_cpu != cpuid)
326 smp_call_function((void *)machine_restart , NULL, 1, 0);
327 } 290 }
328 291
329 /* if reboot_cpu is still -1, then we want a tradional reboot, 292 /* Make certain the cpu I'm rebooting on is online */
330 and if we are not running on the reboot_cpu,, halt */ 293 if (!cpu_isset(reboot_cpu_id, cpu_online_map)) {
331 if ((reboot_cpu != -1) && (cpuid != reboot_cpu)) { 294 reboot_cpu_id = smp_processor_id();
332 for (;;)
333 __asm__ __volatile__ ("hlt");
334 } 295 }
335 /* 296
336 * Stop all CPUs and turn off local APICs and the IO-APIC, so 297 /* Make certain I only run on the appropriate processor */
337 * other OSs see a clean IRQ state. 298 set_cpus_allowed(current, cpumask_of_cpu(reboot_cpu_id));
299
300 /* O.K. Now that I'm on the appropriate processor, stop
301 * all of the others, and disable their local APICs.
338 */ 302 */
303
339 smp_send_stop(); 304 smp_send_stop();
340#endif /* CONFIG_SMP */ 305#endif /* CONFIG_SMP */
341 306
@@ -344,6 +309,11 @@ void machine_restart(char * __unused)
344#ifdef CONFIG_X86_IO_APIC 309#ifdef CONFIG_X86_IO_APIC
345 disable_IO_APIC(); 310 disable_IO_APIC();
346#endif 311#endif
312}
313
314void machine_restart(char * __unused)
315{
316 machine_shutdown();
347 317
348 if (!reboot_thru_bios) { 318 if (!reboot_thru_bios) {
349 if (efi_enabled) { 319 if (efi_enabled) {
diff --git a/arch/i386/kernel/relocate_kernel.S b/arch/i386/kernel/relocate_kernel.S
new file mode 100644
index 000000000000..d312616effa1
--- /dev/null
+++ b/arch/i386/kernel/relocate_kernel.S
@@ -0,0 +1,120 @@
1/*
2 * relocate_kernel.S - put the kernel image in place to boot
3 * Copyright (C) 2002-2004 Eric Biederman <ebiederm@xmission.com>
4 *
5 * This source code is licensed under the GNU General Public License,
6 * Version 2. See the file COPYING for more details.
7 */
8
9#include <linux/linkage.h>
10
11 /*
12 * Must be relocatable PIC code callable as a C function, that once
13 * it starts can not use the previous processes stack.
14 */
15 .globl relocate_new_kernel
16relocate_new_kernel:
17 /* read the arguments and say goodbye to the stack */
18 movl 4(%esp), %ebx /* page_list */
19 movl 8(%esp), %ebp /* reboot_code_buffer */
20 movl 12(%esp), %edx /* start address */
21 movl 16(%esp), %ecx /* cpu_has_pae */
22
23 /* zero out flags, and disable interrupts */
24 pushl $0
25 popfl
26
27 /* set a new stack at the bottom of our page... */
28 lea 4096(%ebp), %esp
29
30 /* store the parameters back on the stack */
31 pushl %edx /* store the start address */
32
33 /* Set cr0 to a known state:
34 * 31 0 == Paging disabled
35 * 18 0 == Alignment check disabled
36 * 16 0 == Write protect disabled
37 * 3 0 == No task switch
38 * 2 0 == Don't do FP software emulation.
39 * 0 1 == Proctected mode enabled
40 */
41 movl %cr0, %eax
42 andl $~((1<<31)|(1<<18)|(1<<16)|(1<<3)|(1<<2)), %eax
43 orl $(1<<0), %eax
44 movl %eax, %cr0
45
46 /* clear cr4 if applicable */
47 testl %ecx, %ecx
48 jz 1f
49 /* Set cr4 to a known state:
50 * Setting everything to zero seems safe.
51 */
52 movl %cr4, %eax
53 andl $0, %eax
54 movl %eax, %cr4
55
56 jmp 1f
571:
58
59 /* Flush the TLB (needed?) */
60 xorl %eax, %eax
61 movl %eax, %cr3
62
63 /* Do the copies */
64 movl %ebx, %ecx
65 jmp 1f
66
670: /* top, read another word from the indirection page */
68 movl (%ebx), %ecx
69 addl $4, %ebx
701:
71 testl $0x1, %ecx /* is it a destination page */
72 jz 2f
73 movl %ecx, %edi
74 andl $0xfffff000, %edi
75 jmp 0b
762:
77 testl $0x2, %ecx /* is it an indirection page */
78 jz 2f
79 movl %ecx, %ebx
80 andl $0xfffff000, %ebx
81 jmp 0b
822:
83 testl $0x4, %ecx /* is it the done indicator */
84 jz 2f
85 jmp 3f
862:
87 testl $0x8, %ecx /* is it the source indicator */
88 jz 0b /* Ignore it otherwise */
89 movl %ecx, %esi /* For every source page do a copy */
90 andl $0xfffff000, %esi
91
92 movl $1024, %ecx
93 rep ; movsl
94 jmp 0b
95
963:
97
98 /* To be certain of avoiding problems with self-modifying code
99 * I need to execute a serializing instruction here.
100 * So I flush the TLB, it's handy, and not processor dependent.
101 */
102 xorl %eax, %eax
103 movl %eax, %cr3
104
105 /* set all of the registers to known values */
106 /* leave %esp alone */
107
108 xorl %eax, %eax
109 xorl %ebx, %ebx
110 xorl %ecx, %ecx
111 xorl %edx, %edx
112 xorl %esi, %esi
113 xorl %edi, %edi
114 xorl %ebp, %ebp
115 ret
116relocate_new_kernel_end:
117
118 .globl relocate_new_kernel_size
119relocate_new_kernel_size:
120 .long relocate_new_kernel_end - relocate_new_kernel
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 30406fd0b64c..7306353c520e 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -43,7 +43,12 @@
43#include <linux/init.h> 43#include <linux/init.h>
44#include <linux/edd.h> 44#include <linux/edd.h>
45#include <linux/nodemask.h> 45#include <linux/nodemask.h>
46#include <linux/kexec.h>
47#include <linux/crash_dump.h>
48
46#include <video/edid.h> 49#include <video/edid.h>
50
51#include <asm/apic.h>
47#include <asm/e820.h> 52#include <asm/e820.h>
48#include <asm/mpspec.h> 53#include <asm/mpspec.h>
49#include <asm/setup.h> 54#include <asm/setup.h>
@@ -55,12 +60,15 @@
55#include "setup_arch_pre.h" 60#include "setup_arch_pre.h"
56#include <bios_ebda.h> 61#include <bios_ebda.h>
57 62
63/* Forward Declaration. */
64void __init find_max_pfn(void);
65
58/* This value is set up by the early boot code to point to the value 66/* This value is set up by the early boot code to point to the value
59 immediately after the boot time page tables. It contains a *physical* 67 immediately after the boot time page tables. It contains a *physical*
60 address, and must not be in the .bss segment! */ 68 address, and must not be in the .bss segment! */
61unsigned long init_pg_tables_end __initdata = ~0UL; 69unsigned long init_pg_tables_end __initdata = ~0UL;
62 70
63int disable_pse __initdata = 0; 71int disable_pse __devinitdata = 0;
64 72
65/* 73/*
66 * Machine setup.. 74 * Machine setup..
@@ -732,6 +740,15 @@ static void __init parse_cmdline_early (char ** cmdline_p)
732 if (to != command_line) 740 if (to != command_line)
733 to--; 741 to--;
734 if (!memcmp(from+7, "exactmap", 8)) { 742 if (!memcmp(from+7, "exactmap", 8)) {
743#ifdef CONFIG_CRASH_DUMP
744 /* If we are doing a crash dump, we
745 * still need to know the real mem
746 * size before original memory map is
747 * reset.
748 */
749 find_max_pfn();
750 saved_max_pfn = max_pfn;
751#endif
735 from += 8+7; 752 from += 8+7;
736 e820.nr_map = 0; 753 e820.nr_map = 0;
737 userdef = 1; 754 userdef = 1;
@@ -835,6 +852,44 @@ static void __init parse_cmdline_early (char ** cmdline_p)
835#endif /* CONFIG_X86_LOCAL_APIC */ 852#endif /* CONFIG_X86_LOCAL_APIC */
836#endif /* CONFIG_ACPI_BOOT */ 853#endif /* CONFIG_ACPI_BOOT */
837 854
855#ifdef CONFIG_X86_LOCAL_APIC
856 /* enable local APIC */
857 else if (!memcmp(from, "lapic", 5))
858 lapic_enable();
859
860 /* disable local APIC */
861 else if (!memcmp(from, "nolapic", 6))
862 lapic_disable();
863#endif /* CONFIG_X86_LOCAL_APIC */
864
865#ifdef CONFIG_KEXEC
866 /* crashkernel=size@addr specifies the location to reserve for
867 * a crash kernel. By reserving this memory we guarantee
868 * that linux never set's it up as a DMA target.
869 * Useful for holding code to do something appropriate
870 * after a kernel panic.
871 */
872 else if (!memcmp(from, "crashkernel=", 12)) {
873 unsigned long size, base;
874 size = memparse(from+12, &from);
875 if (*from == '@') {
876 base = memparse(from+1, &from);
877 /* FIXME: Do I want a sanity check
878 * to validate the memory range?
879 */
880 crashk_res.start = base;
881 crashk_res.end = base + size - 1;
882 }
883 }
884#endif
885#ifdef CONFIG_CRASH_DUMP
886 /* elfcorehdr= specifies the location of elf core header
887 * stored by the crashed kernel.
888 */
889 else if (!memcmp(from, "elfcorehdr=", 11))
890 elfcorehdr_addr = memparse(from+11, &from);
891#endif
892
838 /* 893 /*
839 * highmem=size forces highmem to be exactly 'size' bytes. 894 * highmem=size forces highmem to be exactly 'size' bytes.
840 * This works even on boxes that have no highmem otherwise. 895 * This works even on boxes that have no highmem otherwise.
@@ -1113,8 +1168,8 @@ void __init setup_bootmem_allocator(void)
1113 * the (very unlikely) case of us accidentally initializing the 1168 * the (very unlikely) case of us accidentally initializing the
1114 * bootmem allocator with an invalid RAM area. 1169 * bootmem allocator with an invalid RAM area.
1115 */ 1170 */
1116 reserve_bootmem(HIGH_MEMORY, (PFN_PHYS(min_low_pfn) + 1171 reserve_bootmem(__PHYSICAL_START, (PFN_PHYS(min_low_pfn) +
1117 bootmap_size + PAGE_SIZE-1) - (HIGH_MEMORY)); 1172 bootmap_size + PAGE_SIZE-1) - (__PHYSICAL_START));
1118 1173
1119 /* 1174 /*
1120 * reserve physical page 0 - it's a special BIOS page on many boxes, 1175 * reserve physical page 0 - it's a special BIOS page on many boxes,
@@ -1170,6 +1225,11 @@ void __init setup_bootmem_allocator(void)
1170 } 1225 }
1171 } 1226 }
1172#endif 1227#endif
1228#ifdef CONFIG_KEXEC
1229 if (crashk_res.start != crashk_res.end)
1230 reserve_bootmem(crashk_res.start,
1231 crashk_res.end - crashk_res.start + 1);
1232#endif
1173} 1233}
1174 1234
1175/* 1235/*
@@ -1223,6 +1283,9 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
1223 */ 1283 */
1224 request_resource(res, code_resource); 1284 request_resource(res, code_resource);
1225 request_resource(res, data_resource); 1285 request_resource(res, data_resource);
1286#ifdef CONFIG_KEXEC
1287 request_resource(res, &crashk_res);
1288#endif
1226 } 1289 }
1227 } 1290 }
1228} 1291}
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
index b9b8f4e20fad..89ef7adc63a4 100644
--- a/arch/i386/kernel/signal.c
+++ b/arch/i386/kernel/signal.c
@@ -608,10 +608,8 @@ int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset)
608 if (!user_mode(regs)) 608 if (!user_mode(regs))
609 return 1; 609 return 1;
610 610
611 if (current->flags & PF_FREEZE) { 611 if (try_to_freeze())
612 refrigerator(0);
613 goto no_signal; 612 goto no_signal;
614 }
615 613
616 if (!oldset) 614 if (!oldset)
617 oldset = &current->blocked; 615 oldset = &current->blocked;
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
index 68be7d0c7238..cec4bde67161 100644
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -19,6 +19,7 @@
19#include <linux/mc146818rtc.h> 19#include <linux/mc146818rtc.h>
20#include <linux/cache.h> 20#include <linux/cache.h>
21#include <linux/interrupt.h> 21#include <linux/interrupt.h>
22#include <linux/cpu.h>
22#include <linux/module.h> 23#include <linux/module.h>
23 24
24#include <asm/mtrr.h> 25#include <asm/mtrr.h>
@@ -164,7 +165,7 @@ void send_IPI_mask_bitmask(cpumask_t cpumask, int vector)
164 unsigned long flags; 165 unsigned long flags;
165 166
166 local_irq_save(flags); 167 local_irq_save(flags);
167 168 WARN_ON(mask & ~cpus_addr(cpu_online_map)[0]);
168 /* 169 /*
169 * Wait for idle. 170 * Wait for idle.
170 */ 171 */
@@ -346,21 +347,21 @@ out:
346static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm, 347static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
347 unsigned long va) 348 unsigned long va)
348{ 349{
349 cpumask_t tmp;
350 /* 350 /*
351 * A couple of (to be removed) sanity checks: 351 * A couple of (to be removed) sanity checks:
352 * 352 *
353 * - we do not send IPIs to not-yet booted CPUs.
354 * - current CPU must not be in mask 353 * - current CPU must not be in mask
355 * - mask must exist :) 354 * - mask must exist :)
356 */ 355 */
357 BUG_ON(cpus_empty(cpumask)); 356 BUG_ON(cpus_empty(cpumask));
358
359 cpus_and(tmp, cpumask, cpu_online_map);
360 BUG_ON(!cpus_equal(cpumask, tmp));
361 BUG_ON(cpu_isset(smp_processor_id(), cpumask)); 357 BUG_ON(cpu_isset(smp_processor_id(), cpumask));
362 BUG_ON(!mm); 358 BUG_ON(!mm);
363 359
360 /* If a CPU which we ran on has gone down, OK. */
361 cpus_and(cpumask, cpumask, cpu_online_map);
362 if (cpus_empty(cpumask))
363 return;
364
364 /* 365 /*
365 * i'm not happy about this global shared spinlock in the 366 * i'm not happy about this global shared spinlock in the
366 * MM hot path, but we'll see how contended it is. 367 * MM hot path, but we'll see how contended it is.
@@ -476,6 +477,7 @@ void flush_tlb_all(void)
476 */ 477 */
477void smp_send_reschedule(int cpu) 478void smp_send_reschedule(int cpu)
478{ 479{
480 WARN_ON(cpu_is_offline(cpu));
479 send_IPI_mask(cpumask_of_cpu(cpu), RESCHEDULE_VECTOR); 481 send_IPI_mask(cpumask_of_cpu(cpu), RESCHEDULE_VECTOR);
480} 482}
481 483
@@ -493,6 +495,16 @@ struct call_data_struct {
493 int wait; 495 int wait;
494}; 496};
495 497
498void lock_ipi_call_lock(void)
499{
500 spin_lock_irq(&call_lock);
501}
502
503void unlock_ipi_call_lock(void)
504{
505 spin_unlock_irq(&call_lock);
506}
507
496static struct call_data_struct * call_data; 508static struct call_data_struct * call_data;
497 509
498/* 510/*
@@ -516,10 +528,15 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
516 */ 528 */
517{ 529{
518 struct call_data_struct data; 530 struct call_data_struct data;
519 int cpus = num_online_cpus()-1; 531 int cpus;
520 532
521 if (!cpus) 533 /* Holding any lock stops cpus from going down. */
534 spin_lock(&call_lock);
535 cpus = num_online_cpus() - 1;
536 if (!cpus) {
537 spin_unlock(&call_lock);
522 return 0; 538 return 0;
539 }
523 540
524 /* Can deadlock when called with interrupts disabled */ 541 /* Can deadlock when called with interrupts disabled */
525 WARN_ON(irqs_disabled()); 542 WARN_ON(irqs_disabled());
@@ -531,7 +548,6 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
531 if (wait) 548 if (wait)
532 atomic_set(&data.finished, 0); 549 atomic_set(&data.finished, 0);
533 550
534 spin_lock(&call_lock);
535 call_data = &data; 551 call_data = &data;
536 mb(); 552 mb();
537 553
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index c20d96d5c15c..d66bf489a2e9 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -44,6 +44,9 @@
44#include <linux/smp_lock.h> 44#include <linux/smp_lock.h>
45#include <linux/irq.h> 45#include <linux/irq.h>
46#include <linux/bootmem.h> 46#include <linux/bootmem.h>
47#include <linux/notifier.h>
48#include <linux/cpu.h>
49#include <linux/percpu.h>
47 50
48#include <linux/delay.h> 51#include <linux/delay.h>
49#include <linux/mc146818rtc.h> 52#include <linux/mc146818rtc.h>
@@ -56,18 +59,28 @@
56#include <smpboot_hooks.h> 59#include <smpboot_hooks.h>
57 60
58/* Set if we find a B stepping CPU */ 61/* Set if we find a B stepping CPU */
59static int __initdata smp_b_stepping; 62static int __devinitdata smp_b_stepping;
60 63
61/* Number of siblings per CPU package */ 64/* Number of siblings per CPU package */
62int smp_num_siblings = 1; 65int smp_num_siblings = 1;
63#ifdef CONFIG_X86_HT 66#ifdef CONFIG_X86_HT
64EXPORT_SYMBOL(smp_num_siblings); 67EXPORT_SYMBOL(smp_num_siblings);
65#endif 68#endif
66int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */ 69
70/* Package ID of each logical CPU */
71int phys_proc_id[NR_CPUS] = {[0 ... NR_CPUS-1] = BAD_APICID};
67EXPORT_SYMBOL(phys_proc_id); 72EXPORT_SYMBOL(phys_proc_id);
68int cpu_core_id[NR_CPUS]; /* Core ID of each logical CPU */ 73
74/* Core ID of each logical CPU */
75int cpu_core_id[NR_CPUS] = {[0 ... NR_CPUS-1] = BAD_APICID};
69EXPORT_SYMBOL(cpu_core_id); 76EXPORT_SYMBOL(cpu_core_id);
70 77
78cpumask_t cpu_sibling_map[NR_CPUS];
79EXPORT_SYMBOL(cpu_sibling_map);
80
81cpumask_t cpu_core_map[NR_CPUS];
82EXPORT_SYMBOL(cpu_core_map);
83
71/* bitmap of online cpus */ 84/* bitmap of online cpus */
72cpumask_t cpu_online_map; 85cpumask_t cpu_online_map;
73EXPORT_SYMBOL(cpu_online_map); 86EXPORT_SYMBOL(cpu_online_map);
@@ -77,6 +90,12 @@ cpumask_t cpu_callout_map;
77EXPORT_SYMBOL(cpu_callout_map); 90EXPORT_SYMBOL(cpu_callout_map);
78static cpumask_t smp_commenced_mask; 91static cpumask_t smp_commenced_mask;
79 92
93/* TSC's upper 32 bits can't be written in eariler CPU (before prescott), there
94 * is no way to resync one AP against BP. TBD: for prescott and above, we
95 * should use IA64's algorithm
96 */
97static int __devinitdata tsc_sync_disabled;
98
80/* Per CPU bogomips and other parameters */ 99/* Per CPU bogomips and other parameters */
81struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; 100struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
82EXPORT_SYMBOL(cpu_data); 101EXPORT_SYMBOL(cpu_data);
@@ -96,13 +115,16 @@ static int trampoline_exec;
96 115
97static void map_cpu_to_logical_apicid(void); 116static void map_cpu_to_logical_apicid(void);
98 117
118/* State of each CPU. */
119DEFINE_PER_CPU(int, cpu_state) = { 0 };
120
99/* 121/*
100 * Currently trivial. Write the real->protected mode 122 * Currently trivial. Write the real->protected mode
101 * bootstrap into the page concerned. The caller 123 * bootstrap into the page concerned. The caller
102 * has made sure it's suitably aligned. 124 * has made sure it's suitably aligned.
103 */ 125 */
104 126
105static unsigned long __init setup_trampoline(void) 127static unsigned long __devinit setup_trampoline(void)
106{ 128{
107 memcpy(trampoline_base, trampoline_data, trampoline_end - trampoline_data); 129 memcpy(trampoline_base, trampoline_data, trampoline_end - trampoline_data);
108 return virt_to_phys(trampoline_base); 130 return virt_to_phys(trampoline_base);
@@ -132,7 +154,7 @@ void __init smp_alloc_memory(void)
132 * a given CPU 154 * a given CPU
133 */ 155 */
134 156
135static void __init smp_store_cpu_info(int id) 157static void __devinit smp_store_cpu_info(int id)
136{ 158{
137 struct cpuinfo_x86 *c = cpu_data + id; 159 struct cpuinfo_x86 *c = cpu_data + id;
138 160
@@ -326,7 +348,7 @@ extern void calibrate_delay(void);
326 348
327static atomic_t init_deasserted; 349static atomic_t init_deasserted;
328 350
329static void __init smp_callin(void) 351static void __devinit smp_callin(void)
330{ 352{
331 int cpuid, phys_id; 353 int cpuid, phys_id;
332 unsigned long timeout; 354 unsigned long timeout;
@@ -411,16 +433,48 @@ static void __init smp_callin(void)
411 /* 433 /*
412 * Synchronize the TSC with the BP 434 * Synchronize the TSC with the BP
413 */ 435 */
414 if (cpu_has_tsc && cpu_khz) 436 if (cpu_has_tsc && cpu_khz && !tsc_sync_disabled)
415 synchronize_tsc_ap(); 437 synchronize_tsc_ap();
416} 438}
417 439
418static int cpucount; 440static int cpucount;
419 441
442static inline void
443set_cpu_sibling_map(int cpu)
444{
445 int i;
446
447 if (smp_num_siblings > 1) {
448 for (i = 0; i < NR_CPUS; i++) {
449 if (!cpu_isset(i, cpu_callout_map))
450 continue;
451 if (cpu_core_id[cpu] == cpu_core_id[i]) {
452 cpu_set(i, cpu_sibling_map[cpu]);
453 cpu_set(cpu, cpu_sibling_map[i]);
454 }
455 }
456 } else {
457 cpu_set(cpu, cpu_sibling_map[cpu]);
458 }
459
460 if (current_cpu_data.x86_num_cores > 1) {
461 for (i = 0; i < NR_CPUS; i++) {
462 if (!cpu_isset(i, cpu_callout_map))
463 continue;
464 if (phys_proc_id[cpu] == phys_proc_id[i]) {
465 cpu_set(i, cpu_core_map[cpu]);
466 cpu_set(cpu, cpu_core_map[i]);
467 }
468 }
469 } else {
470 cpu_core_map[cpu] = cpu_sibling_map[cpu];
471 }
472}
473
420/* 474/*
421 * Activate a secondary processor. 475 * Activate a secondary processor.
422 */ 476 */
423static void __init start_secondary(void *unused) 477static void __devinit start_secondary(void *unused)
424{ 478{
425 /* 479 /*
426 * Dont put anything before smp_callin(), SMP 480 * Dont put anything before smp_callin(), SMP
@@ -443,7 +497,23 @@ static void __init start_secondary(void *unused)
443 * the local TLBs too. 497 * the local TLBs too.
444 */ 498 */
445 local_flush_tlb(); 499 local_flush_tlb();
500
501 /* This must be done before setting cpu_online_map */
502 set_cpu_sibling_map(raw_smp_processor_id());
503 wmb();
504
505 /*
506 * We need to hold call_lock, so there is no inconsistency
507 * between the time smp_call_function() determines number of
508 * IPI receipients, and the time when the determination is made
509 * for which cpus receive the IPI. Holding this
510 * lock helps us to not include this cpu in a currently in progress
511 * smp_call_function().
512 */
513 lock_ipi_call_lock();
446 cpu_set(smp_processor_id(), cpu_online_map); 514 cpu_set(smp_processor_id(), cpu_online_map);
515 unlock_ipi_call_lock();
516 per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
447 517
448 /* We can take interrupts now: we're officially "up". */ 518 /* We can take interrupts now: we're officially "up". */
449 local_irq_enable(); 519 local_irq_enable();
@@ -458,7 +528,7 @@ static void __init start_secondary(void *unused)
458 * from the task structure 528 * from the task structure
459 * This function must not return. 529 * This function must not return.
460 */ 530 */
461void __init initialize_secondary(void) 531void __devinit initialize_secondary(void)
462{ 532{
463 /* 533 /*
464 * We don't actually need to load the full TSS, 534 * We don't actually need to load the full TSS,
@@ -572,7 +642,7 @@ static inline void __inquire_remote_apic(int apicid)
572 * INIT, INIT, STARTUP sequence will reset the chip hard for us, and this 642 * INIT, INIT, STARTUP sequence will reset the chip hard for us, and this
573 * won't ... remember to clear down the APIC, etc later. 643 * won't ... remember to clear down the APIC, etc later.
574 */ 644 */
575static int __init 645static int __devinit
576wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip) 646wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip)
577{ 647{
578 unsigned long send_status = 0, accept_status = 0; 648 unsigned long send_status = 0, accept_status = 0;
@@ -618,7 +688,7 @@ wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip)
618#endif /* WAKE_SECONDARY_VIA_NMI */ 688#endif /* WAKE_SECONDARY_VIA_NMI */
619 689
620#ifdef WAKE_SECONDARY_VIA_INIT 690#ifdef WAKE_SECONDARY_VIA_INIT
621static int __init 691static int __devinit
622wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) 692wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
623{ 693{
624 unsigned long send_status = 0, accept_status = 0; 694 unsigned long send_status = 0, accept_status = 0;
@@ -753,8 +823,43 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
753#endif /* WAKE_SECONDARY_VIA_INIT */ 823#endif /* WAKE_SECONDARY_VIA_INIT */
754 824
755extern cpumask_t cpu_initialized; 825extern cpumask_t cpu_initialized;
826static inline int alloc_cpu_id(void)
827{
828 cpumask_t tmp_map;
829 int cpu;
830 cpus_complement(tmp_map, cpu_present_map);
831 cpu = first_cpu(tmp_map);
832 if (cpu >= NR_CPUS)
833 return -ENODEV;
834 return cpu;
835}
836
837#ifdef CONFIG_HOTPLUG_CPU
838static struct task_struct * __devinitdata cpu_idle_tasks[NR_CPUS];
839static inline struct task_struct * alloc_idle_task(int cpu)
840{
841 struct task_struct *idle;
842
843 if ((idle = cpu_idle_tasks[cpu]) != NULL) {
844 /* initialize thread_struct. we really want to avoid destroy
845 * idle tread
846 */
847 idle->thread.esp = (unsigned long)(((struct pt_regs *)
848 (THREAD_SIZE + (unsigned long) idle->thread_info)) - 1);
849 init_idle(idle, cpu);
850 return idle;
851 }
852 idle = fork_idle(cpu);
853
854 if (!IS_ERR(idle))
855 cpu_idle_tasks[cpu] = idle;
856 return idle;
857}
858#else
859#define alloc_idle_task(cpu) fork_idle(cpu)
860#endif
756 861
757static int __init do_boot_cpu(int apicid) 862static int __devinit do_boot_cpu(int apicid, int cpu)
758/* 863/*
759 * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad 864 * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad
760 * (ie clustered apic addressing mode), this is a LOGICAL apic ID. 865 * (ie clustered apic addressing mode), this is a LOGICAL apic ID.
@@ -763,16 +868,17 @@ static int __init do_boot_cpu(int apicid)
763{ 868{
764 struct task_struct *idle; 869 struct task_struct *idle;
765 unsigned long boot_error; 870 unsigned long boot_error;
766 int timeout, cpu; 871 int timeout;
767 unsigned long start_eip; 872 unsigned long start_eip;
768 unsigned short nmi_high = 0, nmi_low = 0; 873 unsigned short nmi_high = 0, nmi_low = 0;
769 874
770 cpu = ++cpucount; 875 ++cpucount;
876
771 /* 877 /*
772 * We can't use kernel_thread since we must avoid to 878 * We can't use kernel_thread since we must avoid to
773 * reschedule the child. 879 * reschedule the child.
774 */ 880 */
775 idle = fork_idle(cpu); 881 idle = alloc_idle_task(cpu);
776 if (IS_ERR(idle)) 882 if (IS_ERR(idle))
777 panic("failed fork for CPU %d", cpu); 883 panic("failed fork for CPU %d", cpu);
778 idle->thread.eip = (unsigned long) start_secondary; 884 idle->thread.eip = (unsigned long) start_secondary;
@@ -839,13 +945,16 @@ static int __init do_boot_cpu(int apicid)
839 inquire_remote_apic(apicid); 945 inquire_remote_apic(apicid);
840 } 946 }
841 } 947 }
842 x86_cpu_to_apicid[cpu] = apicid; 948
843 if (boot_error) { 949 if (boot_error) {
844 /* Try to put things back the way they were before ... */ 950 /* Try to put things back the way they were before ... */
845 unmap_cpu_to_logical_apicid(cpu); 951 unmap_cpu_to_logical_apicid(cpu);
846 cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */ 952 cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */
847 cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */ 953 cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */
848 cpucount--; 954 cpucount--;
955 } else {
956 x86_cpu_to_apicid[cpu] = apicid;
957 cpu_set(cpu, cpu_present_map);
849 } 958 }
850 959
851 /* mark "stuck" area as not stuck */ 960 /* mark "stuck" area as not stuck */
@@ -854,6 +963,75 @@ static int __init do_boot_cpu(int apicid)
854 return boot_error; 963 return boot_error;
855} 964}
856 965
966#ifdef CONFIG_HOTPLUG_CPU
967void cpu_exit_clear(void)
968{
969 int cpu = raw_smp_processor_id();
970
971 idle_task_exit();
972
973 cpucount --;
974 cpu_uninit();
975 irq_ctx_exit(cpu);
976
977 cpu_clear(cpu, cpu_callout_map);
978 cpu_clear(cpu, cpu_callin_map);
979 cpu_clear(cpu, cpu_present_map);
980
981 cpu_clear(cpu, smp_commenced_mask);
982 unmap_cpu_to_logical_apicid(cpu);
983}
984
985struct warm_boot_cpu_info {
986 struct completion *complete;
987 int apicid;
988 int cpu;
989};
990
991static void __devinit do_warm_boot_cpu(void *p)
992{
993 struct warm_boot_cpu_info *info = p;
994 do_boot_cpu(info->apicid, info->cpu);
995 complete(info->complete);
996}
997
998int __devinit smp_prepare_cpu(int cpu)
999{
1000 DECLARE_COMPLETION(done);
1001 struct warm_boot_cpu_info info;
1002 struct work_struct task;
1003 int apicid, ret;
1004
1005 lock_cpu_hotplug();
1006 apicid = x86_cpu_to_apicid[cpu];
1007 if (apicid == BAD_APICID) {
1008 ret = -ENODEV;
1009 goto exit;
1010 }
1011
1012 info.complete = &done;
1013 info.apicid = apicid;
1014 info.cpu = cpu;
1015 INIT_WORK(&task, do_warm_boot_cpu, &info);
1016
1017 tsc_sync_disabled = 1;
1018
1019 /* init low mem mapping */
1020 memcpy(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
1021 sizeof(swapper_pg_dir[0]) * KERNEL_PGD_PTRS);
1022 flush_tlb_all();
1023 schedule_work(&task);
1024 wait_for_completion(&done);
1025
1026 tsc_sync_disabled = 0;
1027 zap_low_mappings();
1028 ret = 0;
1029exit:
1030 unlock_cpu_hotplug();
1031 return ret;
1032}
1033#endif
1034
857static void smp_tune_scheduling (void) 1035static void smp_tune_scheduling (void)
858{ 1036{
859 unsigned long cachesize; /* kB */ 1037 unsigned long cachesize; /* kB */
@@ -895,13 +1073,6 @@ void *xquad_portio;
895EXPORT_SYMBOL(xquad_portio); 1073EXPORT_SYMBOL(xquad_portio);
896#endif 1074#endif
897 1075
898cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
899#ifdef CONFIG_X86_HT
900EXPORT_SYMBOL(cpu_sibling_map);
901#endif
902cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
903EXPORT_SYMBOL(cpu_core_map);
904
905static void __init smp_boot_cpus(unsigned int max_cpus) 1076static void __init smp_boot_cpus(unsigned int max_cpus)
906{ 1077{
907 int apicid, cpu, bit, kicked; 1078 int apicid, cpu, bit, kicked;
@@ -1013,7 +1184,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
1013 if (max_cpus <= cpucount+1) 1184 if (max_cpus <= cpucount+1)
1014 continue; 1185 continue;
1015 1186
1016 if (do_boot_cpu(apicid)) 1187 if (((cpu = alloc_cpu_id()) <= 0) || do_boot_cpu(apicid, cpu))
1017 printk("CPU #%d not responding - cannot use it.\n", 1188 printk("CPU #%d not responding - cannot use it.\n",
1018 apicid); 1189 apicid);
1019 else 1190 else
@@ -1065,44 +1236,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
1065 cpus_clear(cpu_core_map[cpu]); 1236 cpus_clear(cpu_core_map[cpu]);
1066 } 1237 }
1067 1238
1068 for (cpu = 0; cpu < NR_CPUS; cpu++) { 1239 cpu_set(0, cpu_sibling_map[0]);
1069 struct cpuinfo_x86 *c = cpu_data + cpu; 1240 cpu_set(0, cpu_core_map[0]);
1070 int siblings = 0;
1071 int i;
1072 if (!cpu_isset(cpu, cpu_callout_map))
1073 continue;
1074
1075 if (smp_num_siblings > 1) {
1076 for (i = 0; i < NR_CPUS; i++) {
1077 if (!cpu_isset(i, cpu_callout_map))
1078 continue;
1079 if (cpu_core_id[cpu] == cpu_core_id[i]) {
1080 siblings++;
1081 cpu_set(i, cpu_sibling_map[cpu]);
1082 }
1083 }
1084 } else {
1085 siblings++;
1086 cpu_set(cpu, cpu_sibling_map[cpu]);
1087 }
1088
1089 if (siblings != smp_num_siblings) {
1090 printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings);
1091 smp_num_siblings = siblings;
1092 }
1093
1094 if (c->x86_num_cores > 1) {
1095 for (i = 0; i < NR_CPUS; i++) {
1096 if (!cpu_isset(i, cpu_callout_map))
1097 continue;
1098 if (phys_proc_id[cpu] == phys_proc_id[i]) {
1099 cpu_set(i, cpu_core_map[cpu]);
1100 }
1101 }
1102 } else {
1103 cpu_core_map[cpu] = cpu_sibling_map[cpu];
1104 }
1105 }
1106 1241
1107 smpboot_setup_io_apic(); 1242 smpboot_setup_io_apic();
1108 1243
@@ -1119,6 +1254,9 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
1119 who understands all this stuff should rewrite it properly. --RR 15/Jul/02 */ 1254 who understands all this stuff should rewrite it properly. --RR 15/Jul/02 */
1120void __init smp_prepare_cpus(unsigned int max_cpus) 1255void __init smp_prepare_cpus(unsigned int max_cpus)
1121{ 1256{
1257 smp_commenced_mask = cpumask_of_cpu(0);
1258 cpu_callin_map = cpumask_of_cpu(0);
1259 mb();
1122 smp_boot_cpus(max_cpus); 1260 smp_boot_cpus(max_cpus);
1123} 1261}
1124 1262
@@ -1126,23 +1264,98 @@ void __devinit smp_prepare_boot_cpu(void)
1126{ 1264{
1127 cpu_set(smp_processor_id(), cpu_online_map); 1265 cpu_set(smp_processor_id(), cpu_online_map);
1128 cpu_set(smp_processor_id(), cpu_callout_map); 1266 cpu_set(smp_processor_id(), cpu_callout_map);
1267 cpu_set(smp_processor_id(), cpu_present_map);
1268 per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
1129} 1269}
1130 1270
1131int __devinit __cpu_up(unsigned int cpu) 1271#ifdef CONFIG_HOTPLUG_CPU
1272static void
1273remove_siblinginfo(int cpu)
1132{ 1274{
1133 /* This only works at boot for x86. See "rewrite" above. */ 1275 int sibling;
1134 if (cpu_isset(cpu, smp_commenced_mask)) { 1276
1135 local_irq_enable(); 1277 for_each_cpu_mask(sibling, cpu_sibling_map[cpu])
1136 return -ENOSYS; 1278 cpu_clear(cpu, cpu_sibling_map[sibling]);
1279 for_each_cpu_mask(sibling, cpu_core_map[cpu])
1280 cpu_clear(cpu, cpu_core_map[sibling]);
1281 cpus_clear(cpu_sibling_map[cpu]);
1282 cpus_clear(cpu_core_map[cpu]);
1283 phys_proc_id[cpu] = BAD_APICID;
1284 cpu_core_id[cpu] = BAD_APICID;
1285}
1286
1287int __cpu_disable(void)
1288{
1289 cpumask_t map = cpu_online_map;
1290 int cpu = smp_processor_id();
1291
1292 /*
1293 * Perhaps use cpufreq to drop frequency, but that could go
1294 * into generic code.
1295 *
1296 * We won't take down the boot processor on i386 due to some
1297 * interrupts only being able to be serviced by the BSP.
1298 * Especially so if we're not using an IOAPIC -zwane
1299 */
1300 if (cpu == 0)
1301 return -EBUSY;
1302
1303 /* We enable the timer again on the exit path of the death loop */
1304 disable_APIC_timer();
1305 /* Allow any queued timer interrupts to get serviced */
1306 local_irq_enable();
1307 mdelay(1);
1308 local_irq_disable();
1309
1310 remove_siblinginfo(cpu);
1311
1312 cpu_clear(cpu, map);
1313 fixup_irqs(map);
1314 /* It's now safe to remove this processor from the online map */
1315 cpu_clear(cpu, cpu_online_map);
1316 return 0;
1317}
1318
1319void __cpu_die(unsigned int cpu)
1320{
1321 /* We don't do anything here: idle task is faking death itself. */
1322 unsigned int i;
1323
1324 for (i = 0; i < 10; i++) {
1325 /* They ack this in play_dead by setting CPU_DEAD */
1326 if (per_cpu(cpu_state, cpu) == CPU_DEAD) {
1327 printk ("CPU %d is now offline\n", cpu);
1328 return;
1329 }
1330 current->state = TASK_UNINTERRUPTIBLE;
1331 schedule_timeout(HZ/10);
1137 } 1332 }
1333 printk(KERN_ERR "CPU %u didn't die...\n", cpu);
1334}
1335#else /* ... !CONFIG_HOTPLUG_CPU */
1336int __cpu_disable(void)
1337{
1338 return -ENOSYS;
1339}
1340
1341void __cpu_die(unsigned int cpu)
1342{
1343 /* We said "no" in __cpu_disable */
1344 BUG();
1345}
1346#endif /* CONFIG_HOTPLUG_CPU */
1138 1347
1348int __devinit __cpu_up(unsigned int cpu)
1349{
1139 /* In case one didn't come up */ 1350 /* In case one didn't come up */
1140 if (!cpu_isset(cpu, cpu_callin_map)) { 1351 if (!cpu_isset(cpu, cpu_callin_map)) {
1352 printk(KERN_DEBUG "skipping cpu%d, didn't come online\n", cpu);
1141 local_irq_enable(); 1353 local_irq_enable();
1142 return -EIO; 1354 return -EIO;
1143 } 1355 }
1144 1356
1145 local_irq_enable(); 1357 local_irq_enable();
1358 per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
1146 /* Unleash the CPU! */ 1359 /* Unleash the CPU! */
1147 cpu_set(cpu, smp_commenced_mask); 1360 cpu_set(cpu, smp_commenced_mask);
1148 while (!cpu_isset(cpu, cpu_online_map)) 1361 while (!cpu_isset(cpu, cpu_online_map))
@@ -1156,10 +1369,12 @@ void __init smp_cpus_done(unsigned int max_cpus)
1156 setup_ioapic_dest(); 1369 setup_ioapic_dest();
1157#endif 1370#endif
1158 zap_low_mappings(); 1371 zap_low_mappings();
1372#ifndef CONFIG_HOTPLUG_CPU
1159 /* 1373 /*
1160 * Disable executability of the SMP trampoline: 1374 * Disable executability of the SMP trampoline:
1161 */ 1375 */
1162 set_kernel_exec((unsigned long)trampoline_base, trampoline_exec); 1376 set_kernel_exec((unsigned long)trampoline_base, trampoline_exec);
1377#endif
1163} 1378}
1164 1379
1165void __init smp_intr_init(void) 1380void __init smp_intr_init(void)
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S
index d408afaf6495..442a6e937b19 100644
--- a/arch/i386/kernel/syscall_table.S
+++ b/arch/i386/kernel/syscall_table.S
@@ -283,7 +283,7 @@ ENTRY(sys_call_table)
283 .long sys_mq_timedreceive /* 280 */ 283 .long sys_mq_timedreceive /* 280 */
284 .long sys_mq_notify 284 .long sys_mq_notify
285 .long sys_mq_getsetattr 285 .long sys_mq_getsetattr
286 .long sys_ni_syscall /* reserved for kexec */ 286 .long sys_kexec_load
287 .long sys_waitid 287 .long sys_waitid
288 .long sys_ni_syscall /* 285 */ /* available */ 288 .long sys_ni_syscall /* 285 */ /* available */
289 .long sys_add_key 289 .long sys_add_key
diff --git a/arch/i386/kernel/sysenter.c b/arch/i386/kernel/sysenter.c
index 960d8bd137d0..0bada1870bdf 100644
--- a/arch/i386/kernel/sysenter.c
+++ b/arch/i386/kernel/sysenter.c
@@ -21,11 +21,16 @@
21 21
22extern asmlinkage void sysenter_entry(void); 22extern asmlinkage void sysenter_entry(void);
23 23
24void enable_sep_cpu(void *info) 24void enable_sep_cpu(void)
25{ 25{
26 int cpu = get_cpu(); 26 int cpu = get_cpu();
27 struct tss_struct *tss = &per_cpu(init_tss, cpu); 27 struct tss_struct *tss = &per_cpu(init_tss, cpu);
28 28
29 if (!boot_cpu_has(X86_FEATURE_SEP)) {
30 put_cpu();
31 return;
32 }
33
29 tss->ss1 = __KERNEL_CS; 34 tss->ss1 = __KERNEL_CS;
30 tss->esp1 = sizeof(struct tss_struct) + (unsigned long) tss; 35 tss->esp1 = sizeof(struct tss_struct) + (unsigned long) tss;
31 wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0); 36 wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
@@ -41,7 +46,7 @@ void enable_sep_cpu(void *info)
41extern const char vsyscall_int80_start, vsyscall_int80_end; 46extern const char vsyscall_int80_start, vsyscall_int80_end;
42extern const char vsyscall_sysenter_start, vsyscall_sysenter_end; 47extern const char vsyscall_sysenter_start, vsyscall_sysenter_end;
43 48
44static int __init sysenter_setup(void) 49int __init sysenter_setup(void)
45{ 50{
46 void *page = (void *)get_zeroed_page(GFP_ATOMIC); 51 void *page = (void *)get_zeroed_page(GFP_ATOMIC);
47 52
@@ -58,8 +63,5 @@ static int __init sysenter_setup(void)
58 &vsyscall_sysenter_start, 63 &vsyscall_sysenter_start,
59 &vsyscall_sysenter_end - &vsyscall_sysenter_start); 64 &vsyscall_sysenter_end - &vsyscall_sysenter_start);
60 65
61 on_each_cpu(enable_sep_cpu, NULL, 1, 1);
62 return 0; 66 return 0;
63} 67}
64
65__initcall(sysenter_setup);
diff --git a/arch/i386/kernel/time_hpet.c b/arch/i386/kernel/time_hpet.c
index 10a0cbb88e75..658c0629ba6a 100644
--- a/arch/i386/kernel/time_hpet.c
+++ b/arch/i386/kernel/time_hpet.c
@@ -50,7 +50,7 @@ static void hpet_writel(unsigned long d, unsigned long a)
50 * comparator value and continue. Next tick can be caught by checking 50 * comparator value and continue. Next tick can be caught by checking
51 * for a change in the comparator value. Used in apic.c. 51 * for a change in the comparator value. Used in apic.c.
52 */ 52 */
53static void __init wait_hpet_tick(void) 53static void __devinit wait_hpet_tick(void)
54{ 54{
55 unsigned int start_cmp_val, end_cmp_val; 55 unsigned int start_cmp_val, end_cmp_val;
56 56
diff --git a/arch/i386/kernel/timers/common.c b/arch/i386/kernel/timers/common.c
index 37353bd31803..8163fe0cf1f0 100644
--- a/arch/i386/kernel/timers/common.c
+++ b/arch/i386/kernel/timers/common.c
@@ -86,7 +86,7 @@ bad_ctc:
86#define CALIBRATE_CNT_HPET (5 * hpet_tick) 86#define CALIBRATE_CNT_HPET (5 * hpet_tick)
87#define CALIBRATE_TIME_HPET (5 * KERNEL_TICK_USEC) 87#define CALIBRATE_TIME_HPET (5 * KERNEL_TICK_USEC)
88 88
89unsigned long __init calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr) 89unsigned long __devinit calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr)
90{ 90{
91 unsigned long tsc_startlow, tsc_starthigh; 91 unsigned long tsc_startlow, tsc_starthigh;
92 unsigned long tsc_endlow, tsc_endhigh; 92 unsigned long tsc_endlow, tsc_endhigh;
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c
index 54c36b182021..f46e625bab67 100644
--- a/arch/i386/kernel/timers/timer_tsc.c
+++ b/arch/i386/kernel/timers/timer_tsc.c
@@ -33,7 +33,7 @@ static struct timer_opts timer_tsc;
33 33
34static inline void cpufreq_delayed_get(void); 34static inline void cpufreq_delayed_get(void);
35 35
36int tsc_disable __initdata = 0; 36int tsc_disable __devinitdata = 0;
37 37
38extern spinlock_t i8253_lock; 38extern spinlock_t i8253_lock;
39 39
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index e4d4e2162c7a..a61f33d06ea3 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -27,6 +27,7 @@
27#include <linux/ptrace.h> 27#include <linux/ptrace.h>
28#include <linux/utsname.h> 28#include <linux/utsname.h>
29#include <linux/kprobes.h> 29#include <linux/kprobes.h>
30#include <linux/kexec.h>
30 31
31#ifdef CONFIG_EISA 32#ifdef CONFIG_EISA
32#include <linux/ioport.h> 33#include <linux/ioport.h>
@@ -234,22 +235,22 @@ void show_registers(struct pt_regs *regs)
234 * time of the fault.. 235 * time of the fault..
235 */ 236 */
236 if (in_kernel) { 237 if (in_kernel) {
237 u8 *eip; 238 u8 __user *eip;
238 239
239 printk("\nStack: "); 240 printk("\nStack: ");
240 show_stack(NULL, (unsigned long*)esp); 241 show_stack(NULL, (unsigned long*)esp);
241 242
242 printk("Code: "); 243 printk("Code: ");
243 244
244 eip = (u8 *)regs->eip - 43; 245 eip = (u8 __user *)regs->eip - 43;
245 for (i = 0; i < 64; i++, eip++) { 246 for (i = 0; i < 64; i++, eip++) {
246 unsigned char c; 247 unsigned char c;
247 248
248 if (eip < (u8 *)PAGE_OFFSET || __get_user(c, eip)) { 249 if (eip < (u8 __user *)PAGE_OFFSET || __get_user(c, eip)) {
249 printk(" Bad EIP value."); 250 printk(" Bad EIP value.");
250 break; 251 break;
251 } 252 }
252 if (eip == (u8 *)regs->eip) 253 if (eip == (u8 __user *)regs->eip)
253 printk("<%02x> ", c); 254 printk("<%02x> ", c);
254 else 255 else
255 printk("%02x ", c); 256 printk("%02x ", c);
@@ -273,13 +274,13 @@ static void handle_BUG(struct pt_regs *regs)
273 274
274 if (eip < PAGE_OFFSET) 275 if (eip < PAGE_OFFSET)
275 goto no_bug; 276 goto no_bug;
276 if (__get_user(ud2, (unsigned short *)eip)) 277 if (__get_user(ud2, (unsigned short __user *)eip))
277 goto no_bug; 278 goto no_bug;
278 if (ud2 != 0x0b0f) 279 if (ud2 != 0x0b0f)
279 goto no_bug; 280 goto no_bug;
280 if (__get_user(line, (unsigned short *)(eip + 2))) 281 if (__get_user(line, (unsigned short __user *)(eip + 2)))
281 goto bug; 282 goto bug;
282 if (__get_user(file, (char **)(eip + 4)) || 283 if (__get_user(file, (char * __user *)(eip + 4)) ||
283 (unsigned long)file < PAGE_OFFSET || __get_user(c, file)) 284 (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
284 file = "<bad filename>"; 285 file = "<bad filename>";
285 286
@@ -294,6 +295,9 @@ bug:
294 printk("Kernel BUG\n"); 295 printk("Kernel BUG\n");
295} 296}
296 297
298/* This is gone through when something in the kernel
299 * has done something bad and is about to be terminated.
300*/
297void die(const char * str, struct pt_regs * regs, long err) 301void die(const char * str, struct pt_regs * regs, long err)
298{ 302{
299 static struct { 303 static struct {
@@ -341,6 +345,10 @@ void die(const char * str, struct pt_regs * regs, long err)
341 bust_spinlocks(0); 345 bust_spinlocks(0);
342 die.lock_owner = -1; 346 die.lock_owner = -1;
343 spin_unlock_irq(&die.lock); 347 spin_unlock_irq(&die.lock);
348
349 if (kexec_should_crash(current))
350 crash_kexec(regs);
351
344 if (in_interrupt()) 352 if (in_interrupt())
345 panic("Fatal exception in interrupt"); 353 panic("Fatal exception in interrupt");
346 354
@@ -361,6 +369,10 @@ static inline void die_if_kernel(const char * str, struct pt_regs * regs, long e
361static void do_trap(int trapnr, int signr, char *str, int vm86, 369static void do_trap(int trapnr, int signr, char *str, int vm86,
362 struct pt_regs * regs, long error_code, siginfo_t *info) 370 struct pt_regs * regs, long error_code, siginfo_t *info)
363{ 371{
372 struct task_struct *tsk = current;
373 tsk->thread.error_code = error_code;
374 tsk->thread.trap_no = trapnr;
375
364 if (regs->eflags & VM_MASK) { 376 if (regs->eflags & VM_MASK) {
365 if (vm86) 377 if (vm86)
366 goto vm86_trap; 378 goto vm86_trap;
@@ -371,9 +383,6 @@ static void do_trap(int trapnr, int signr, char *str, int vm86,
371 goto kernel_trap; 383 goto kernel_trap;
372 384
373 trap_signal: { 385 trap_signal: {
374 struct task_struct *tsk = current;
375 tsk->thread.error_code = error_code;
376 tsk->thread.trap_no = trapnr;
377 if (info) 386 if (info)
378 force_sig_info(signr, info, tsk); 387 force_sig_info(signr, info, tsk);
379 else 388 else
@@ -486,6 +495,9 @@ fastcall void do_general_protection(struct pt_regs * regs, long error_code)
486 } 495 }
487 put_cpu(); 496 put_cpu();
488 497
498 current->thread.error_code = error_code;
499 current->thread.trap_no = 13;
500
489 if (regs->eflags & VM_MASK) 501 if (regs->eflags & VM_MASK)
490 goto gp_in_vm86; 502 goto gp_in_vm86;
491 503
@@ -570,6 +582,15 @@ void die_nmi (struct pt_regs *regs, const char *msg)
570 console_silent(); 582 console_silent();
571 spin_unlock(&nmi_print_lock); 583 spin_unlock(&nmi_print_lock);
572 bust_spinlocks(0); 584 bust_spinlocks(0);
585
586 /* If we are in kernel we are probably nested up pretty bad
587 * and might aswell get out now while we still can.
588 */
589 if (!user_mode(regs)) {
590 current->thread.trap_no = 2;
591 crash_kexec(regs);
592 }
593
573 do_exit(SIGSEGV); 594 do_exit(SIGSEGV);
574} 595}
575 596
@@ -625,6 +646,14 @@ fastcall void do_nmi(struct pt_regs * regs, long error_code)
625 nmi_enter(); 646 nmi_enter();
626 647
627 cpu = smp_processor_id(); 648 cpu = smp_processor_id();
649
650#ifdef CONFIG_HOTPLUG_CPU
651 if (!cpu_online(cpu)) {
652 nmi_exit();
653 return;
654 }
655#endif
656
628 ++nmi_count(cpu); 657 ++nmi_count(cpu);
629 658
630 if (!nmi_callback(regs, cpu)) 659 if (!nmi_callback(regs, cpu))
@@ -872,9 +901,9 @@ fastcall void do_simd_coprocessor_error(struct pt_regs * regs,
872 error_code); 901 error_code);
873 return; 902 return;
874 } 903 }
875 die_if_kernel("cache flush denied", regs, error_code);
876 current->thread.trap_no = 19; 904 current->thread.trap_no = 19;
877 current->thread.error_code = error_code; 905 current->thread.error_code = error_code;
906 die_if_kernel("cache flush denied", regs, error_code);
878 force_sig(SIGSEGV, current); 907 force_sig(SIGSEGV, current);
879 } 908 }
880} 909}
diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S
index e0512cc8bea7..7e01a528a83a 100644
--- a/arch/i386/kernel/vmlinux.lds.S
+++ b/arch/i386/kernel/vmlinux.lds.S
@@ -2,20 +2,23 @@
2 * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>; 2 * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
3 */ 3 */
4 4
5#define LOAD_OFFSET __PAGE_OFFSET
6
5#include <asm-generic/vmlinux.lds.h> 7#include <asm-generic/vmlinux.lds.h>
6#include <asm/thread_info.h> 8#include <asm/thread_info.h>
7#include <asm/page.h> 9#include <asm/page.h>
8 10
9OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") 11OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
10OUTPUT_ARCH(i386) 12OUTPUT_ARCH(i386)
11ENTRY(startup_32) 13ENTRY(phys_startup_32)
12jiffies = jiffies_64; 14jiffies = jiffies_64;
13SECTIONS 15SECTIONS
14{ 16{
15 . = __PAGE_OFFSET + 0x100000; 17 . = __KERNEL_START;
18 phys_startup_32 = startup_32 - LOAD_OFFSET;
16 /* read-only */ 19 /* read-only */
17 _text = .; /* Text and read-only data */ 20 _text = .; /* Text and read-only data */
18 .text : { 21 .text : AT(ADDR(.text) - LOAD_OFFSET) {
19 *(.text) 22 *(.text)
20 SCHED_TEXT 23 SCHED_TEXT
21 LOCK_TEXT 24 LOCK_TEXT
@@ -27,49 +30,55 @@ SECTIONS
27 30
28 . = ALIGN(16); /* Exception table */ 31 . = ALIGN(16); /* Exception table */
29 __start___ex_table = .; 32 __start___ex_table = .;
30 __ex_table : { *(__ex_table) } 33 __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
31 __stop___ex_table = .; 34 __stop___ex_table = .;
32 35
33 RODATA 36 RODATA
34 37
35 /* writeable */ 38 /* writeable */
36 .data : { /* Data */ 39 .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
37 *(.data) 40 *(.data)
38 CONSTRUCTORS 41 CONSTRUCTORS
39 } 42 }
40 43
41 . = ALIGN(4096); 44 . = ALIGN(4096);
42 __nosave_begin = .; 45 __nosave_begin = .;
43 .data_nosave : { *(.data.nosave) } 46 .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
44 . = ALIGN(4096); 47 . = ALIGN(4096);
45 __nosave_end = .; 48 __nosave_end = .;
46 49
47 . = ALIGN(4096); 50 . = ALIGN(4096);
48 .data.page_aligned : { *(.data.idt) } 51 .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
52 *(.data.idt)
53 }
49 54
50 . = ALIGN(32); 55 . = ALIGN(32);
51 .data.cacheline_aligned : { *(.data.cacheline_aligned) } 56 .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
57 *(.data.cacheline_aligned)
58 }
52 59
53 _edata = .; /* End of data section */ 60 _edata = .; /* End of data section */
54 61
55 . = ALIGN(THREAD_SIZE); /* init_task */ 62 . = ALIGN(THREAD_SIZE); /* init_task */
56 .data.init_task : { *(.data.init_task) } 63 .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
64 *(.data.init_task)
65 }
57 66
58 /* will be freed after init */ 67 /* will be freed after init */
59 . = ALIGN(4096); /* Init code and data */ 68 . = ALIGN(4096); /* Init code and data */
60 __init_begin = .; 69 __init_begin = .;
61 .init.text : { 70 .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
62 _sinittext = .; 71 _sinittext = .;
63 *(.init.text) 72 *(.init.text)
64 _einittext = .; 73 _einittext = .;
65 } 74 }
66 .init.data : { *(.init.data) } 75 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
67 . = ALIGN(16); 76 . = ALIGN(16);
68 __setup_start = .; 77 __setup_start = .;
69 .init.setup : { *(.init.setup) } 78 .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) }
70 __setup_end = .; 79 __setup_end = .;
71 __initcall_start = .; 80 __initcall_start = .;
72 .initcall.init : { 81 .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
73 *(.initcall1.init) 82 *(.initcall1.init)
74 *(.initcall2.init) 83 *(.initcall2.init)
75 *(.initcall3.init) 84 *(.initcall3.init)
@@ -80,33 +89,41 @@ SECTIONS
80 } 89 }
81 __initcall_end = .; 90 __initcall_end = .;
82 __con_initcall_start = .; 91 __con_initcall_start = .;
83 .con_initcall.init : { *(.con_initcall.init) } 92 .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
93 *(.con_initcall.init)
94 }
84 __con_initcall_end = .; 95 __con_initcall_end = .;
85 SECURITY_INIT 96 SECURITY_INIT
86 . = ALIGN(4); 97 . = ALIGN(4);
87 __alt_instructions = .; 98 __alt_instructions = .;
88 .altinstructions : { *(.altinstructions) } 99 .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
100 *(.altinstructions)
101 }
89 __alt_instructions_end = .; 102 __alt_instructions_end = .;
90 .altinstr_replacement : { *(.altinstr_replacement) } 103 .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
104 *(.altinstr_replacement)
105 }
91 /* .exit.text is discard at runtime, not link time, to deal with references 106 /* .exit.text is discard at runtime, not link time, to deal with references
92 from .altinstructions and .eh_frame */ 107 from .altinstructions and .eh_frame */
93 .exit.text : { *(.exit.text) } 108 .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
94 .exit.data : { *(.exit.data) } 109 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
95 . = ALIGN(4096); 110 . = ALIGN(4096);
96 __initramfs_start = .; 111 __initramfs_start = .;
97 .init.ramfs : { *(.init.ramfs) } 112 .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) }
98 __initramfs_end = .; 113 __initramfs_end = .;
99 . = ALIGN(32); 114 . = ALIGN(32);
100 __per_cpu_start = .; 115 __per_cpu_start = .;
101 .data.percpu : { *(.data.percpu) } 116 .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) }
102 __per_cpu_end = .; 117 __per_cpu_end = .;
103 . = ALIGN(4096); 118 . = ALIGN(4096);
104 __init_end = .; 119 __init_end = .;
105 /* freed after init ends here */ 120 /* freed after init ends here */
106 121
107 __bss_start = .; /* BSS */ 122 __bss_start = .; /* BSS */
108 .bss : { 123 .bss.page_aligned : AT(ADDR(.bss.page_aligned) - LOAD_OFFSET) {
109 *(.bss.page_aligned) 124 *(.bss.page_aligned)
125 }
126 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
110 *(.bss) 127 *(.bss)
111 } 128 }
112 . = ALIGN(4); 129 . = ALIGN(4);