diff options
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/Kconfig | 2 | ||||
-rw-r--r-- | arch/i386/boot/video.S | 14 | ||||
-rw-r--r-- | arch/i386/defconfig | 43 | ||||
-rw-r--r-- | arch/i386/kernel/acpi/boot.c | 23 | ||||
-rw-r--r-- | arch/i386/kernel/acpi/earlyquirk.c | 7 | ||||
-rw-r--r-- | arch/i386/kernel/apic.c | 117 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/amd.c | 34 | ||||
-rw-r--r-- | arch/i386/kernel/hpet.c | 70 | ||||
-rw-r--r-- | arch/i386/kernel/i386_ksyms.c | 2 | ||||
-rw-r--r-- | arch/i386/kernel/i8253.c | 10 | ||||
-rw-r--r-- | arch/i386/kernel/io_apic.c | 2 | ||||
-rw-r--r-- | arch/i386/kernel/microcode.c | 71 | ||||
-rw-r--r-- | arch/i386/kernel/nmi.c | 137 | ||||
-rw-r--r-- | arch/i386/kernel/smpboot.c | 16 | ||||
-rw-r--r-- | arch/i386/kernel/tsc.c | 9 | ||||
-rw-r--r-- | arch/i386/kernel/vmi.c | 40 | ||||
-rw-r--r-- | arch/i386/lib/usercopy.c | 9 | ||||
-rw-r--r-- | arch/i386/mm/highmem.c | 2 | ||||
-rw-r--r-- | arch/i386/pci/common.c | 14 |
19 files changed, 486 insertions, 136 deletions
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 27e8453274e6..53d62373a524 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig | |||
@@ -220,7 +220,7 @@ config PARAVIRT | |||
220 | 220 | ||
221 | config VMI | 221 | config VMI |
222 | bool "VMI Paravirt-ops support" | 222 | bool "VMI Paravirt-ops support" |
223 | depends on PARAVIRT | 223 | depends on PARAVIRT && !COMPAT_VDSO |
224 | help | 224 | help |
225 | VMI provides a paravirtualized interface to the VMware ESX server | 225 | VMI provides a paravirtualized interface to the VMware ESX server |
226 | (it could be used by other hypervisors in theory too, but is not | 226 | (it could be used by other hypervisors in theory too, but is not |
diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S index 2c5b5cc55f79..8143c9516cb4 100644 --- a/arch/i386/boot/video.S +++ b/arch/i386/boot/video.S | |||
@@ -571,6 +571,16 @@ setr1: lodsw | |||
571 | jmp _m_s | 571 | jmp _m_s |
572 | 572 | ||
573 | check_vesa: | 573 | check_vesa: |
574 | #ifdef CONFIG_FIRMWARE_EDID | ||
575 | leaw modelist+1024, %di | ||
576 | movw $0x4f00, %ax | ||
577 | int $0x10 | ||
578 | cmpw $0x004f, %ax | ||
579 | jnz setbad | ||
580 | |||
581 | movw 4(%di), %ax | ||
582 | movw %ax, vbe_version | ||
583 | #endif | ||
574 | leaw modelist+1024, %di | 584 | leaw modelist+1024, %di |
575 | subb $VIDEO_FIRST_VESA>>8, %bh | 585 | subb $VIDEO_FIRST_VESA>>8, %bh |
576 | movw %bx, %cx # Get mode information structure | 586 | movw %bx, %cx # Get mode information structure |
@@ -1945,6 +1955,9 @@ store_edid: | |||
1945 | rep | 1955 | rep |
1946 | stosl | 1956 | stosl |
1947 | 1957 | ||
1958 | cmpw $0x0200, vbe_version # only do EDID on >= VBE2.0 | ||
1959 | jl no_edid | ||
1960 | |||
1948 | pushw %es # save ES | 1961 | pushw %es # save ES |
1949 | xorw %di, %di # Report Capability | 1962 | xorw %di, %di # Report Capability |
1950 | pushw %di | 1963 | pushw %di |
@@ -1987,6 +2000,7 @@ do_restore: .byte 0 # Screen contents altered during mode change | |||
1987 | svga_prefix: .byte VIDEO_FIRST_BIOS>>8 # Default prefix for BIOS modes | 2000 | svga_prefix: .byte VIDEO_FIRST_BIOS>>8 # Default prefix for BIOS modes |
1988 | graphic_mode: .byte 0 # Graphic mode with a linear frame buffer | 2001 | graphic_mode: .byte 0 # Graphic mode with a linear frame buffer |
1989 | dac_size: .byte 6 # DAC bit depth | 2002 | dac_size: .byte 6 # DAC bit depth |
2003 | vbe_version: .word 0 # VBE bios version | ||
1990 | 2004 | ||
1991 | # Status messages | 2005 | # Status messages |
1992 | keymsg: .ascii "Press <RETURN> to see video modes available, " | 2006 | keymsg: .ascii "Press <RETURN> to see video modes available, " |
diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 5ae1e0bc8fd7..f4efd66e1ee5 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig | |||
@@ -1,10 +1,13 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.20-git8 | 3 | # Linux kernel version: 2.6.21-rc3 |
4 | # Tue Feb 13 11:25:18 2007 | 4 | # Wed Mar 7 15:29:47 2007 |
5 | # | 5 | # |
6 | CONFIG_X86_32=y | 6 | CONFIG_X86_32=y |
7 | CONFIG_GENERIC_TIME=y | 7 | CONFIG_GENERIC_TIME=y |
8 | CONFIG_CLOCKSOURCE_WATCHDOG=y | ||
9 | CONFIG_GENERIC_CLOCKEVENTS=y | ||
10 | CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y | ||
8 | CONFIG_LOCKDEP_SUPPORT=y | 11 | CONFIG_LOCKDEP_SUPPORT=y |
9 | CONFIG_STACKTRACE_SUPPORT=y | 12 | CONFIG_STACKTRACE_SUPPORT=y |
10 | CONFIG_SEMAPHORE_SLEEPERS=y | 13 | CONFIG_SEMAPHORE_SLEEPERS=y |
@@ -34,6 +37,7 @@ CONFIG_LOCALVERSION_AUTO=y | |||
34 | CONFIG_SWAP=y | 37 | CONFIG_SWAP=y |
35 | CONFIG_SYSVIPC=y | 38 | CONFIG_SYSVIPC=y |
36 | # CONFIG_IPC_NS is not set | 39 | # CONFIG_IPC_NS is not set |
40 | CONFIG_SYSVIPC_SYSCTL=y | ||
37 | CONFIG_POSIX_MQUEUE=y | 41 | CONFIG_POSIX_MQUEUE=y |
38 | # CONFIG_BSD_PROCESS_ACCT is not set | 42 | # CONFIG_BSD_PROCESS_ACCT is not set |
39 | # CONFIG_TASKSTATS is not set | 43 | # CONFIG_TASKSTATS is not set |
@@ -44,6 +48,7 @@ CONFIG_IKCONFIG_PROC=y | |||
44 | # CONFIG_CPUSETS is not set | 48 | # CONFIG_CPUSETS is not set |
45 | CONFIG_SYSFS_DEPRECATED=y | 49 | CONFIG_SYSFS_DEPRECATED=y |
46 | # CONFIG_RELAY is not set | 50 | # CONFIG_RELAY is not set |
51 | CONFIG_BLK_DEV_INITRD=y | ||
47 | CONFIG_INITRAMFS_SOURCE="" | 52 | CONFIG_INITRAMFS_SOURCE="" |
48 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | 53 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y |
49 | CONFIG_SYSCTL=y | 54 | CONFIG_SYSCTL=y |
@@ -103,6 +108,9 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" | |||
103 | # | 108 | # |
104 | # Processor type and features | 109 | # Processor type and features |
105 | # | 110 | # |
111 | # CONFIG_TICK_ONESHOT is not set | ||
112 | # CONFIG_NO_HZ is not set | ||
113 | # CONFIG_HIGH_RES_TIMERS is not set | ||
106 | CONFIG_SMP=y | 114 | CONFIG_SMP=y |
107 | # CONFIG_X86_PC is not set | 115 | # CONFIG_X86_PC is not set |
108 | # CONFIG_X86_ELAN is not set | 116 | # CONFIG_X86_ELAN is not set |
@@ -235,10 +243,8 @@ CONFIG_ACPI_PROCFS=y | |||
235 | CONFIG_ACPI_AC=y | 243 | CONFIG_ACPI_AC=y |
236 | CONFIG_ACPI_BATTERY=y | 244 | CONFIG_ACPI_BATTERY=y |
237 | CONFIG_ACPI_BUTTON=y | 245 | CONFIG_ACPI_BUTTON=y |
238 | # CONFIG_ACPI_HOTKEY is not set | ||
239 | CONFIG_ACPI_FAN=y | 246 | CONFIG_ACPI_FAN=y |
240 | # CONFIG_ACPI_DOCK is not set | 247 | # CONFIG_ACPI_DOCK is not set |
241 | # CONFIG_ACPI_BAY is not set | ||
242 | CONFIG_ACPI_PROCESSOR=y | 248 | CONFIG_ACPI_PROCESSOR=y |
243 | CONFIG_ACPI_THERMAL=y | 249 | CONFIG_ACPI_THERMAL=y |
244 | # CONFIG_ACPI_ASUS is not set | 250 | # CONFIG_ACPI_ASUS is not set |
@@ -289,6 +295,7 @@ CONFIG_X86_POWERNOW_K8_ACPI=y | |||
289 | # CONFIG_X86_CPUFREQ_NFORCE2 is not set | 295 | # CONFIG_X86_CPUFREQ_NFORCE2 is not set |
290 | # CONFIG_X86_LONGRUN is not set | 296 | # CONFIG_X86_LONGRUN is not set |
291 | # CONFIG_X86_LONGHAUL is not set | 297 | # CONFIG_X86_LONGHAUL is not set |
298 | # CONFIG_X86_E_POWERSAVER is not set | ||
292 | 299 | ||
293 | # | 300 | # |
294 | # shared options | 301 | # shared options |
@@ -368,7 +375,7 @@ CONFIG_IP_PNP_DHCP=y | |||
368 | # CONFIG_INET_ESP is not set | 375 | # CONFIG_INET_ESP is not set |
369 | # CONFIG_INET_IPCOMP is not set | 376 | # CONFIG_INET_IPCOMP is not set |
370 | # CONFIG_INET_XFRM_TUNNEL is not set | 377 | # CONFIG_INET_XFRM_TUNNEL is not set |
371 | # CONFIG_INET_TUNNEL is not set | 378 | CONFIG_INET_TUNNEL=y |
372 | CONFIG_INET_XFRM_MODE_TRANSPORT=y | 379 | CONFIG_INET_XFRM_MODE_TRANSPORT=y |
373 | CONFIG_INET_XFRM_MODE_TUNNEL=y | 380 | CONFIG_INET_XFRM_MODE_TUNNEL=y |
374 | # CONFIG_INET_XFRM_MODE_BEET is not set | 381 | # CONFIG_INET_XFRM_MODE_BEET is not set |
@@ -470,7 +477,13 @@ CONFIG_FW_LOADER=y | |||
470 | # | 477 | # |
471 | # Plug and Play support | 478 | # Plug and Play support |
472 | # | 479 | # |
473 | # CONFIG_PNP is not set | 480 | CONFIG_PNP=y |
481 | # CONFIG_PNP_DEBUG is not set | ||
482 | |||
483 | # | ||
484 | # Protocols | ||
485 | # | ||
486 | CONFIG_PNPACPI=y | ||
474 | 487 | ||
475 | # | 488 | # |
476 | # Block devices | 489 | # Block devices |
@@ -490,7 +503,6 @@ CONFIG_BLK_DEV_RAM=y | |||
490 | CONFIG_BLK_DEV_RAM_COUNT=16 | 503 | CONFIG_BLK_DEV_RAM_COUNT=16 |
491 | CONFIG_BLK_DEV_RAM_SIZE=4096 | 504 | CONFIG_BLK_DEV_RAM_SIZE=4096 |
492 | CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 | 505 | CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 |
493 | CONFIG_BLK_DEV_INITRD=y | ||
494 | # CONFIG_CDROM_PKTCDVD is not set | 506 | # CONFIG_CDROM_PKTCDVD is not set |
495 | # CONFIG_ATA_OVER_ETH is not set | 507 | # CONFIG_ATA_OVER_ETH is not set |
496 | 508 | ||
@@ -500,6 +512,7 @@ CONFIG_BLK_DEV_INITRD=y | |||
500 | # CONFIG_IBM_ASM is not set | 512 | # CONFIG_IBM_ASM is not set |
501 | # CONFIG_SGI_IOC4 is not set | 513 | # CONFIG_SGI_IOC4 is not set |
502 | # CONFIG_TIFM_CORE is not set | 514 | # CONFIG_TIFM_CORE is not set |
515 | # CONFIG_SONY_LAPTOP is not set | ||
503 | 516 | ||
504 | # | 517 | # |
505 | # ATA/ATAPI/MFM/RLL support | 518 | # ATA/ATAPI/MFM/RLL support |
@@ -526,6 +539,7 @@ CONFIG_BLK_DEV_IDEACPI=y | |||
526 | # | 539 | # |
527 | CONFIG_IDE_GENERIC=y | 540 | CONFIG_IDE_GENERIC=y |
528 | # CONFIG_BLK_DEV_CMD640 is not set | 541 | # CONFIG_BLK_DEV_CMD640 is not set |
542 | # CONFIG_BLK_DEV_IDEPNP is not set | ||
529 | CONFIG_BLK_DEV_IDEPCI=y | 543 | CONFIG_BLK_DEV_IDEPCI=y |
530 | # CONFIG_IDEPCI_SHARE_IRQ is not set | 544 | # CONFIG_IDEPCI_SHARE_IRQ is not set |
531 | # CONFIG_BLK_DEV_OFFBOARD is not set | 545 | # CONFIG_BLK_DEV_OFFBOARD is not set |
@@ -679,6 +693,7 @@ CONFIG_SATA_VIA=y | |||
679 | # CONFIG_SATA_VITESSE is not set | 693 | # CONFIG_SATA_VITESSE is not set |
680 | # CONFIG_SATA_INIC162X is not set | 694 | # CONFIG_SATA_INIC162X is not set |
681 | CONFIG_SATA_INTEL_COMBINED=y | 695 | CONFIG_SATA_INTEL_COMBINED=y |
696 | CONFIG_SATA_ACPI=y | ||
682 | # CONFIG_PATA_ALI is not set | 697 | # CONFIG_PATA_ALI is not set |
683 | # CONFIG_PATA_AMD is not set | 698 | # CONFIG_PATA_AMD is not set |
684 | # CONFIG_PATA_ARTOP is not set | 699 | # CONFIG_PATA_ARTOP is not set |
@@ -786,6 +801,7 @@ CONFIG_NETDEVICES=y | |||
786 | # CONFIG_BONDING is not set | 801 | # CONFIG_BONDING is not set |
787 | # CONFIG_EQUALIZER is not set | 802 | # CONFIG_EQUALIZER is not set |
788 | # CONFIG_TUN is not set | 803 | # CONFIG_TUN is not set |
804 | # CONFIG_NET_SB1000 is not set | ||
789 | 805 | ||
790 | # | 806 | # |
791 | # ARCnet devices | 807 | # ARCnet devices |
@@ -979,6 +995,7 @@ CONFIG_HW_CONSOLE=y | |||
979 | CONFIG_SERIAL_8250=y | 995 | CONFIG_SERIAL_8250=y |
980 | CONFIG_SERIAL_8250_CONSOLE=y | 996 | CONFIG_SERIAL_8250_CONSOLE=y |
981 | CONFIG_SERIAL_8250_PCI=y | 997 | CONFIG_SERIAL_8250_PCI=y |
998 | CONFIG_SERIAL_8250_PNP=y | ||
982 | CONFIG_SERIAL_8250_NR_UARTS=4 | 999 | CONFIG_SERIAL_8250_NR_UARTS=4 |
983 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 | 1000 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 |
984 | # CONFIG_SERIAL_8250_EXTENDED is not set | 1001 | # CONFIG_SERIAL_8250_EXTENDED is not set |
@@ -1065,6 +1082,11 @@ CONFIG_HANGCHECK_TIMER=y | |||
1065 | # CONFIG_HWMON_VID is not set | 1082 | # CONFIG_HWMON_VID is not set |
1066 | 1083 | ||
1067 | # | 1084 | # |
1085 | # Multifunction device drivers | ||
1086 | # | ||
1087 | # CONFIG_MFD_SM501 is not set | ||
1088 | |||
1089 | # | ||
1068 | # Multimedia devices | 1090 | # Multimedia devices |
1069 | # | 1091 | # |
1070 | # CONFIG_VIDEO_DEV is not set | 1092 | # CONFIG_VIDEO_DEV is not set |
@@ -1078,7 +1100,7 @@ CONFIG_HANGCHECK_TIMER=y | |||
1078 | # | 1100 | # |
1079 | # Graphics support | 1101 | # Graphics support |
1080 | # | 1102 | # |
1081 | CONFIG_FIRMWARE_EDID=y | 1103 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set |
1082 | # CONFIG_FB is not set | 1104 | # CONFIG_FB is not set |
1083 | 1105 | ||
1084 | # | 1106 | # |
@@ -1089,7 +1111,6 @@ CONFIG_VGACON_SOFT_SCROLLBACK=y | |||
1089 | CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=128 | 1111 | CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=128 |
1090 | CONFIG_VIDEO_SELECT=y | 1112 | CONFIG_VIDEO_SELECT=y |
1091 | CONFIG_DUMMY_CONSOLE=y | 1113 | CONFIG_DUMMY_CONSOLE=y |
1092 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | ||
1093 | 1114 | ||
1094 | # | 1115 | # |
1095 | # Sound | 1116 | # Sound |
@@ -1238,6 +1259,7 @@ CONFIG_USB_MON=y | |||
1238 | # CONFIG_USB_RIO500 is not set | 1259 | # CONFIG_USB_RIO500 is not set |
1239 | # CONFIG_USB_LEGOTOWER is not set | 1260 | # CONFIG_USB_LEGOTOWER is not set |
1240 | # CONFIG_USB_LCD is not set | 1261 | # CONFIG_USB_LCD is not set |
1262 | # CONFIG_USB_BERRY_CHARGE is not set | ||
1241 | # CONFIG_USB_LED is not set | 1263 | # CONFIG_USB_LED is not set |
1242 | # CONFIG_USB_CYPRESS_CY7C63 is not set | 1264 | # CONFIG_USB_CYPRESS_CY7C63 is not set |
1243 | # CONFIG_USB_CYTHERM is not set | 1265 | # CONFIG_USB_CYTHERM is not set |
@@ -1248,6 +1270,7 @@ CONFIG_USB_MON=y | |||
1248 | # CONFIG_USB_SISUSBVGA is not set | 1270 | # CONFIG_USB_SISUSBVGA is not set |
1249 | # CONFIG_USB_LD is not set | 1271 | # CONFIG_USB_LD is not set |
1250 | # CONFIG_USB_TRANCEVIBRATOR is not set | 1272 | # CONFIG_USB_TRANCEVIBRATOR is not set |
1273 | # CONFIG_USB_IOWARRIOR is not set | ||
1251 | # CONFIG_USB_TEST is not set | 1274 | # CONFIG_USB_TEST is not set |
1252 | 1275 | ||
1253 | # | 1276 | # |
@@ -1506,6 +1529,7 @@ CONFIG_DEBUG_KERNEL=y | |||
1506 | CONFIG_LOG_BUF_SHIFT=18 | 1529 | CONFIG_LOG_BUF_SHIFT=18 |
1507 | CONFIG_DETECT_SOFTLOCKUP=y | 1530 | CONFIG_DETECT_SOFTLOCKUP=y |
1508 | # CONFIG_SCHEDSTATS is not set | 1531 | # CONFIG_SCHEDSTATS is not set |
1532 | # CONFIG_TIMER_STATS is not set | ||
1509 | # CONFIG_DEBUG_SLAB is not set | 1533 | # CONFIG_DEBUG_SLAB is not set |
1510 | # CONFIG_DEBUG_RT_MUTEXES is not set | 1534 | # CONFIG_DEBUG_RT_MUTEXES is not set |
1511 | # CONFIG_RT_MUTEX_TESTER is not set | 1535 | # CONFIG_RT_MUTEX_TESTER is not set |
@@ -1525,6 +1549,7 @@ CONFIG_DEBUG_BUGVERBOSE=y | |||
1525 | # CONFIG_FORCED_INLINING is not set | 1549 | # CONFIG_FORCED_INLINING is not set |
1526 | # CONFIG_RCU_TORTURE_TEST is not set | 1550 | # CONFIG_RCU_TORTURE_TEST is not set |
1527 | # CONFIG_LKDTM is not set | 1551 | # CONFIG_LKDTM is not set |
1552 | # CONFIG_FAULT_INJECTION is not set | ||
1528 | CONFIG_EARLY_PRINTK=y | 1553 | CONFIG_EARLY_PRINTK=y |
1529 | CONFIG_DEBUG_STACKOVERFLOW=y | 1554 | CONFIG_DEBUG_STACKOVERFLOW=y |
1530 | # CONFIG_DEBUG_STACK_USAGE is not set | 1555 | # CONFIG_DEBUG_STACK_USAGE is not set |
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index e5eb97a910ed..9ea5b8ecc7e1 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
@@ -1072,7 +1072,28 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = { | |||
1072 | "ASUS A7V ACPI BIOS Revision 1007"), | 1072 | "ASUS A7V ACPI BIOS Revision 1007"), |
1073 | }, | 1073 | }, |
1074 | }, | 1074 | }, |
1075 | 1075 | { | |
1076 | /* | ||
1077 | * Latest BIOS for IBM 600E (1.16) has bad pcinum | ||
1078 | * for LPC bridge, which is needed for the PCI | ||
1079 | * interrupt links to work. DSDT fix is in bug 5966. | ||
1080 | * 2645, 2646 model numbers are shared with 600/600E/600X | ||
1081 | */ | ||
1082 | .callback = disable_acpi_irq, | ||
1083 | .ident = "IBM Thinkpad 600 Series 2645", | ||
1084 | .matches = { | ||
1085 | DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), | ||
1086 | DMI_MATCH(DMI_BOARD_NAME, "2645"), | ||
1087 | }, | ||
1088 | }, | ||
1089 | { | ||
1090 | .callback = disable_acpi_irq, | ||
1091 | .ident = "IBM Thinkpad 600 Series 2646", | ||
1092 | .matches = { | ||
1093 | DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), | ||
1094 | DMI_MATCH(DMI_BOARD_NAME, "2646"), | ||
1095 | }, | ||
1096 | }, | ||
1076 | /* | 1097 | /* |
1077 | * Boxes that need ACPI PCI IRQ routing and PCI scan disabled | 1098 | * Boxes that need ACPI PCI IRQ routing and PCI scan disabled |
1078 | */ | 1099 | */ |
diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c index bf86f7662d8b..a7d22d9f3d7e 100644 --- a/arch/i386/kernel/acpi/earlyquirk.c +++ b/arch/i386/kernel/acpi/earlyquirk.c | |||
@@ -14,11 +14,8 @@ | |||
14 | 14 | ||
15 | #ifdef CONFIG_ACPI | 15 | #ifdef CONFIG_ACPI |
16 | 16 | ||
17 | static int nvidia_hpet_detected __initdata; | ||
18 | |||
19 | static int __init nvidia_hpet_check(struct acpi_table_header *header) | 17 | static int __init nvidia_hpet_check(struct acpi_table_header *header) |
20 | { | 18 | { |
21 | nvidia_hpet_detected = 1; | ||
22 | return 0; | 19 | return 0; |
23 | } | 20 | } |
24 | #endif | 21 | #endif |
@@ -29,9 +26,7 @@ static int __init check_bridge(int vendor, int device) | |||
29 | /* According to Nvidia all timer overrides are bogus unless HPET | 26 | /* According to Nvidia all timer overrides are bogus unless HPET |
30 | is enabled. */ | 27 | is enabled. */ |
31 | if (!acpi_use_timer_override && vendor == PCI_VENDOR_ID_NVIDIA) { | 28 | if (!acpi_use_timer_override && vendor == PCI_VENDOR_ID_NVIDIA) { |
32 | nvidia_hpet_detected = 0; | 29 | if (acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check)) { |
33 | acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check); | ||
34 | if (nvidia_hpet_detected == 0) { | ||
35 | acpi_skip_timer_override = 1; | 30 | acpi_skip_timer_override = 1; |
36 | printk(KERN_INFO "Nvidia board " | 31 | printk(KERN_INFO "Nvidia board " |
37 | "detected. Ignoring ACPI " | 32 | "detected. Ignoring ACPI " |
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index 2383bcf18c5d..93aa911646ad 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/clockchips.h> | 28 | #include <linux/clockchips.h> |
29 | #include <linux/acpi_pmtmr.h> | 29 | #include <linux/acpi_pmtmr.h> |
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/dmi.h> | ||
31 | 32 | ||
32 | #include <asm/atomic.h> | 33 | #include <asm/atomic.h> |
33 | #include <asm/smp.h> | 34 | #include <asm/smp.h> |
@@ -61,6 +62,11 @@ static int enable_local_apic __initdata = 0; | |||
61 | 62 | ||
62 | /* Local APIC timer verification ok */ | 63 | /* Local APIC timer verification ok */ |
63 | static int local_apic_timer_verify_ok; | 64 | static int local_apic_timer_verify_ok; |
65 | /* Disable local APIC timer from the kernel commandline or via dmi quirk */ | ||
66 | static int local_apic_timer_disabled; | ||
67 | /* Local APIC timer works in C2 */ | ||
68 | int local_apic_timer_c2_ok; | ||
69 | EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok); | ||
64 | 70 | ||
65 | /* | 71 | /* |
66 | * Debug level, exported for io_apic.c | 72 | * Debug level, exported for io_apic.c |
@@ -338,6 +344,23 @@ void __init setup_boot_APIC_clock(void) | |||
338 | void (*real_handler)(struct clock_event_device *dev); | 344 | void (*real_handler)(struct clock_event_device *dev); |
339 | unsigned long deltaj; | 345 | unsigned long deltaj; |
340 | long delta, deltapm; | 346 | long delta, deltapm; |
347 | int pm_referenced = 0; | ||
348 | |||
349 | if (boot_cpu_has(X86_FEATURE_LAPIC_TIMER_BROKEN)) | ||
350 | local_apic_timer_disabled = 1; | ||
351 | |||
352 | /* | ||
353 | * The local apic timer can be disabled via the kernel | ||
354 | * commandline or from the test above. Register the lapic | ||
355 | * timer as a dummy clock event source on SMP systems, so the | ||
356 | * broadcast mechanism is used. On UP systems simply ignore it. | ||
357 | */ | ||
358 | if (local_apic_timer_disabled) { | ||
359 | /* No broadcast on UP ! */ | ||
360 | if (num_possible_cpus() > 1) | ||
361 | setup_APIC_timer(); | ||
362 | return; | ||
363 | } | ||
341 | 364 | ||
342 | apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n" | 365 | apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n" |
343 | "calibrating APIC timer ...\n"); | 366 | "calibrating APIC timer ...\n"); |
@@ -357,7 +380,8 @@ void __init setup_boot_APIC_clock(void) | |||
357 | /* Let the interrupts run */ | 380 | /* Let the interrupts run */ |
358 | local_irq_enable(); | 381 | local_irq_enable(); |
359 | 382 | ||
360 | while(lapic_cal_loops <= LAPIC_CAL_LOOPS); | 383 | while (lapic_cal_loops <= LAPIC_CAL_LOOPS) |
384 | cpu_relax(); | ||
361 | 385 | ||
362 | local_irq_disable(); | 386 | local_irq_disable(); |
363 | 387 | ||
@@ -394,6 +418,7 @@ void __init setup_boot_APIC_clock(void) | |||
394 | "%lu (%ld)\n", (unsigned long) res, delta); | 418 | "%lu (%ld)\n", (unsigned long) res, delta); |
395 | delta = (long) res; | 419 | delta = (long) res; |
396 | } | 420 | } |
421 | pm_referenced = 1; | ||
397 | } | 422 | } |
398 | 423 | ||
399 | /* Calculate the scaled math multiplication factor */ | 424 | /* Calculate the scaled math multiplication factor */ |
@@ -423,69 +448,43 @@ void __init setup_boot_APIC_clock(void) | |||
423 | calibration_result / (1000000 / HZ), | 448 | calibration_result / (1000000 / HZ), |
424 | calibration_result % (1000000 / HZ)); | 449 | calibration_result % (1000000 / HZ)); |
425 | 450 | ||
426 | |||
427 | apic_printk(APIC_VERBOSE, "... verify APIC timer\n"); | ||
428 | |||
429 | /* | ||
430 | * Setup the apic timer manually | ||
431 | */ | ||
432 | local_apic_timer_verify_ok = 1; | 451 | local_apic_timer_verify_ok = 1; |
433 | levt->event_handler = lapic_cal_handler; | ||
434 | lapic_timer_setup(CLOCK_EVT_MODE_PERIODIC, levt); | ||
435 | lapic_cal_loops = -1; | ||
436 | 452 | ||
437 | /* Let the interrupts run */ | 453 | /* We trust the pm timer based calibration */ |
438 | local_irq_enable(); | 454 | if (!pm_referenced) { |
455 | apic_printk(APIC_VERBOSE, "... verify APIC timer\n"); | ||
439 | 456 | ||
440 | while(lapic_cal_loops <= LAPIC_CAL_LOOPS); | 457 | /* |
458 | * Setup the apic timer manually | ||
459 | */ | ||
460 | levt->event_handler = lapic_cal_handler; | ||
461 | lapic_timer_setup(CLOCK_EVT_MODE_PERIODIC, levt); | ||
462 | lapic_cal_loops = -1; | ||
441 | 463 | ||
442 | local_irq_disable(); | 464 | /* Let the interrupts run */ |
465 | local_irq_enable(); | ||
443 | 466 | ||
444 | /* Stop the lapic timer */ | 467 | while(lapic_cal_loops <= LAPIC_CAL_LOOPS) |
445 | lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, levt); | 468 | cpu_relax(); |
446 | 469 | ||
447 | local_irq_enable(); | 470 | local_irq_disable(); |
448 | 471 | ||
449 | /* Jiffies delta */ | 472 | /* Stop the lapic timer */ |
450 | deltaj = lapic_cal_j2 - lapic_cal_j1; | 473 | lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, levt); |
451 | apic_printk(APIC_VERBOSE, "... jiffies delta = %lu\n", deltaj); | ||
452 | 474 | ||
453 | /* Check, if the PM timer is available */ | 475 | local_irq_enable(); |
454 | deltapm = lapic_cal_pm2 - lapic_cal_pm1; | ||
455 | apic_printk(APIC_VERBOSE, "... PM timer delta = %ld\n", deltapm); | ||
456 | 476 | ||
457 | local_apic_timer_verify_ok = 0; | 477 | /* Jiffies delta */ |
478 | deltaj = lapic_cal_j2 - lapic_cal_j1; | ||
479 | apic_printk(APIC_VERBOSE, "... jiffies delta = %lu\n", deltaj); | ||
458 | 480 | ||
459 | if (deltapm) { | ||
460 | if (deltapm > (pm_100ms - pm_thresh) && | ||
461 | deltapm < (pm_100ms + pm_thresh)) { | ||
462 | apic_printk(APIC_VERBOSE, "... PM timer result ok\n"); | ||
463 | /* Check, if the jiffies result is consistent */ | ||
464 | if (deltaj < LAPIC_CAL_LOOPS-2 || | ||
465 | deltaj > LAPIC_CAL_LOOPS+2) { | ||
466 | /* | ||
467 | * Not sure, what we can do about this one. | ||
468 | * When high resultion timers are active | ||
469 | * and the lapic timer does not stop in C3 | ||
470 | * we are fine. Otherwise more trouble might | ||
471 | * be waiting. -- tglx | ||
472 | */ | ||
473 | printk(KERN_WARNING "Global event device %s " | ||
474 | "has wrong frequency " | ||
475 | "(%lu ticks instead of %d)\n", | ||
476 | global_clock_event->name, deltaj, | ||
477 | LAPIC_CAL_LOOPS); | ||
478 | } | ||
479 | local_apic_timer_verify_ok = 1; | ||
480 | } | ||
481 | } else { | ||
482 | /* Check, if the jiffies result is consistent */ | 481 | /* Check, if the jiffies result is consistent */ |
483 | if (deltaj >= LAPIC_CAL_LOOPS-2 && | 482 | if (deltaj >= LAPIC_CAL_LOOPS-2 && deltaj <= LAPIC_CAL_LOOPS+2) |
484 | deltaj <= LAPIC_CAL_LOOPS+2) { | ||
485 | apic_printk(APIC_VERBOSE, "... jiffies result ok\n"); | 483 | apic_printk(APIC_VERBOSE, "... jiffies result ok\n"); |
486 | local_apic_timer_verify_ok = 1; | 484 | else |
487 | } | 485 | local_apic_timer_verify_ok = 0; |
488 | } | 486 | } else |
487 | local_irq_enable(); | ||
489 | 488 | ||
490 | if (!local_apic_timer_verify_ok) { | 489 | if (!local_apic_timer_verify_ok) { |
491 | printk(KERN_WARNING | 490 | printk(KERN_WARNING |
@@ -1203,6 +1202,20 @@ static int __init parse_nolapic(char *arg) | |||
1203 | } | 1202 | } |
1204 | early_param("nolapic", parse_nolapic); | 1203 | early_param("nolapic", parse_nolapic); |
1205 | 1204 | ||
1205 | static int __init parse_disable_lapic_timer(char *arg) | ||
1206 | { | ||
1207 | local_apic_timer_disabled = 1; | ||
1208 | return 0; | ||
1209 | } | ||
1210 | early_param("nolapic_timer", parse_disable_lapic_timer); | ||
1211 | |||
1212 | static int __init parse_lapic_timer_c2_ok(char *arg) | ||
1213 | { | ||
1214 | local_apic_timer_c2_ok = 1; | ||
1215 | return 0; | ||
1216 | } | ||
1217 | early_param("lapic_timer_c2_ok", parse_lapic_timer_c2_ok); | ||
1218 | |||
1206 | static int __init apic_set_verbosity(char *str) | 1219 | static int __init apic_set_verbosity(char *str) |
1207 | { | 1220 | { |
1208 | if (strcmp("debug", str) == 0) | 1221 | if (strcmp("debug", str) == 0) |
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c index 41cfea57232b..2d47db482972 100644 --- a/arch/i386/kernel/cpu/amd.c +++ b/arch/i386/kernel/cpu/amd.c | |||
@@ -22,6 +22,37 @@ | |||
22 | extern void vide(void); | 22 | extern void vide(void); |
23 | __asm__(".align 4\nvide: ret"); | 23 | __asm__(".align 4\nvide: ret"); |
24 | 24 | ||
25 | #define ENABLE_C1E_MASK 0x18000000 | ||
26 | #define CPUID_PROCESSOR_SIGNATURE 1 | ||
27 | #define CPUID_XFAM 0x0ff00000 | ||
28 | #define CPUID_XFAM_K8 0x00000000 | ||
29 | #define CPUID_XFAM_10H 0x00100000 | ||
30 | #define CPUID_XFAM_11H 0x00200000 | ||
31 | #define CPUID_XMOD 0x000f0000 | ||
32 | #define CPUID_XMOD_REV_F 0x00040000 | ||
33 | |||
34 | /* AMD systems with C1E don't have a working lAPIC timer. Check for that. */ | ||
35 | static __cpuinit int amd_apic_timer_broken(void) | ||
36 | { | ||
37 | u32 lo, hi; | ||
38 | u32 eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); | ||
39 | switch (eax & CPUID_XFAM) { | ||
40 | case CPUID_XFAM_K8: | ||
41 | if ((eax & CPUID_XMOD) < CPUID_XMOD_REV_F) | ||
42 | break; | ||
43 | case CPUID_XFAM_10H: | ||
44 | case CPUID_XFAM_11H: | ||
45 | rdmsr(MSR_K8_ENABLE_C1E, lo, hi); | ||
46 | if (lo & ENABLE_C1E_MASK) | ||
47 | return 1; | ||
48 | break; | ||
49 | default: | ||
50 | /* err on the side of caution */ | ||
51 | return 1; | ||
52 | } | ||
53 | return 0; | ||
54 | } | ||
55 | |||
25 | static void __cpuinit init_amd(struct cpuinfo_x86 *c) | 56 | static void __cpuinit init_amd(struct cpuinfo_x86 *c) |
26 | { | 57 | { |
27 | u32 l, h; | 58 | u32 l, h; |
@@ -241,6 +272,9 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) | |||
241 | 272 | ||
242 | if (cpuid_eax(0x80000000) >= 0x80000006) | 273 | if (cpuid_eax(0x80000000) >= 0x80000006) |
243 | num_cache_leaves = 3; | 274 | num_cache_leaves = 3; |
275 | |||
276 | if (amd_apic_timer_broken()) | ||
277 | set_bit(X86_FEATURE_LAPIC_TIMER_BROKEN, c->x86_capability); | ||
244 | } | 278 | } |
245 | 279 | ||
246 | static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) | 280 | static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) |
diff --git a/arch/i386/kernel/hpet.c b/arch/i386/kernel/hpet.c index f3ab61ee7498..17d73459fc5f 100644 --- a/arch/i386/kernel/hpet.c +++ b/arch/i386/kernel/hpet.c | |||
@@ -3,6 +3,8 @@ | |||
3 | #include <linux/errno.h> | 3 | #include <linux/errno.h> |
4 | #include <linux/hpet.h> | 4 | #include <linux/hpet.h> |
5 | #include <linux/init.h> | 5 | #include <linux/init.h> |
6 | #include <linux/sysdev.h> | ||
7 | #include <linux/pm.h> | ||
6 | 8 | ||
7 | #include <asm/hpet.h> | 9 | #include <asm/hpet.h> |
8 | #include <asm/io.h> | 10 | #include <asm/io.h> |
@@ -197,7 +199,7 @@ static int hpet_next_event(unsigned long delta, | |||
197 | cnt += delta; | 199 | cnt += delta; |
198 | hpet_writel(cnt, HPET_T0_CMP); | 200 | hpet_writel(cnt, HPET_T0_CMP); |
199 | 201 | ||
200 | return ((long)(hpet_readl(HPET_COUNTER) - cnt ) > 0); | 202 | return ((long)(hpet_readl(HPET_COUNTER) - cnt ) > 0) ? -ETIME : 0; |
201 | } | 203 | } |
202 | 204 | ||
203 | /* | 205 | /* |
@@ -307,6 +309,7 @@ int __init hpet_enable(void) | |||
307 | out_nohpet: | 309 | out_nohpet: |
308 | iounmap(hpet_virt_address); | 310 | iounmap(hpet_virt_address); |
309 | hpet_virt_address = NULL; | 311 | hpet_virt_address = NULL; |
312 | boot_hpet_disable = 1; | ||
310 | return 0; | 313 | return 0; |
311 | } | 314 | } |
312 | 315 | ||
@@ -521,3 +524,68 @@ irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) | |||
521 | return IRQ_HANDLED; | 524 | return IRQ_HANDLED; |
522 | } | 525 | } |
523 | #endif | 526 | #endif |
527 | |||
528 | |||
529 | /* | ||
530 | * Suspend/resume part | ||
531 | */ | ||
532 | |||
533 | #ifdef CONFIG_PM | ||
534 | |||
535 | static int hpet_suspend(struct sys_device *sys_device, pm_message_t state) | ||
536 | { | ||
537 | unsigned long cfg = hpet_readl(HPET_CFG); | ||
538 | |||
539 | cfg &= ~(HPET_CFG_ENABLE|HPET_CFG_LEGACY); | ||
540 | hpet_writel(cfg, HPET_CFG); | ||
541 | |||
542 | return 0; | ||
543 | } | ||
544 | |||
545 | static int hpet_resume(struct sys_device *sys_device) | ||
546 | { | ||
547 | unsigned int id; | ||
548 | |||
549 | hpet_start_counter(); | ||
550 | |||
551 | id = hpet_readl(HPET_ID); | ||
552 | |||
553 | if (id & HPET_ID_LEGSUP) | ||
554 | hpet_enable_int(); | ||
555 | |||
556 | return 0; | ||
557 | } | ||
558 | |||
559 | static struct sysdev_class hpet_class = { | ||
560 | set_kset_name("hpet"), | ||
561 | .suspend = hpet_suspend, | ||
562 | .resume = hpet_resume, | ||
563 | }; | ||
564 | |||
565 | static struct sys_device hpet_device = { | ||
566 | .id = 0, | ||
567 | .cls = &hpet_class, | ||
568 | }; | ||
569 | |||
570 | |||
571 | static __init int hpet_register_sysfs(void) | ||
572 | { | ||
573 | int err; | ||
574 | |||
575 | if (!is_hpet_capable()) | ||
576 | return 0; | ||
577 | |||
578 | err = sysdev_class_register(&hpet_class); | ||
579 | |||
580 | if (!err) { | ||
581 | err = sysdev_register(&hpet_device); | ||
582 | if (err) | ||
583 | sysdev_class_unregister(&hpet_class); | ||
584 | } | ||
585 | |||
586 | return err; | ||
587 | } | ||
588 | |||
589 | device_initcall(hpet_register_sysfs); | ||
590 | |||
591 | #endif | ||
diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c index e3d4b73bfdb0..4afe26e86260 100644 --- a/arch/i386/kernel/i386_ksyms.c +++ b/arch/i386/kernel/i386_ksyms.c | |||
@@ -28,3 +28,5 @@ EXPORT_SYMBOL(__read_lock_failed); | |||
28 | #endif | 28 | #endif |
29 | 29 | ||
30 | EXPORT_SYMBOL(csum_partial); | 30 | EXPORT_SYMBOL(csum_partial); |
31 | |||
32 | EXPORT_SYMBOL(_proxy_pda); | ||
diff --git a/arch/i386/kernel/i8253.c b/arch/i386/kernel/i8253.c index 5cbb776b3089..10cef5ca8a5b 100644 --- a/arch/i386/kernel/i8253.c +++ b/arch/i386/kernel/i8253.c | |||
@@ -47,9 +47,17 @@ static void init_pit_timer(enum clock_event_mode mode, | |||
47 | outb(LATCH >> 8 , PIT_CH0); /* MSB */ | 47 | outb(LATCH >> 8 , PIT_CH0); /* MSB */ |
48 | break; | 48 | break; |
49 | 49 | ||
50 | case CLOCK_EVT_MODE_ONESHOT: | 50 | /* |
51 | * Avoid unnecessary state transitions, as it confuses | ||
52 | * Geode / Cyrix based boxen. | ||
53 | */ | ||
51 | case CLOCK_EVT_MODE_SHUTDOWN: | 54 | case CLOCK_EVT_MODE_SHUTDOWN: |
55 | if (evt->mode == CLOCK_EVT_MODE_UNUSED) | ||
56 | break; | ||
52 | case CLOCK_EVT_MODE_UNUSED: | 57 | case CLOCK_EVT_MODE_UNUSED: |
58 | if (evt->mode == CLOCK_EVT_MODE_SHUTDOWN) | ||
59 | break; | ||
60 | case CLOCK_EVT_MODE_ONESHOT: | ||
53 | /* One shot setup */ | 61 | /* One shot setup */ |
54 | outb_p(0x38, PIT_MODE); | 62 | outb_p(0x38, PIT_MODE); |
55 | udelay(10); | 63 | udelay(10); |
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index e4408ff4e674..b3ab8ffebd27 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c | |||
@@ -736,7 +736,7 @@ failed: | |||
736 | return 0; | 736 | return 0; |
737 | } | 737 | } |
738 | 738 | ||
739 | int __init irqbalance_disable(char *str) | 739 | int __devinit irqbalance_disable(char *str) |
740 | { | 740 | { |
741 | irqbalance_disabled = 1; | 741 | irqbalance_disabled = 1; |
742 | return 1; | 742 | return 1; |
diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c index b8f16633a6ec..cbe7ec8dbb9f 100644 --- a/arch/i386/kernel/microcode.c +++ b/arch/i386/kernel/microcode.c | |||
@@ -567,6 +567,53 @@ static int cpu_request_microcode(int cpu) | |||
567 | return error; | 567 | return error; |
568 | } | 568 | } |
569 | 569 | ||
570 | static int apply_microcode_on_cpu(int cpu) | ||
571 | { | ||
572 | struct cpuinfo_x86 *c = cpu_data + cpu; | ||
573 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | ||
574 | cpumask_t old; | ||
575 | unsigned int val[2]; | ||
576 | int err = 0; | ||
577 | |||
578 | if (!uci->mc) | ||
579 | return -EINVAL; | ||
580 | |||
581 | old = current->cpus_allowed; | ||
582 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | ||
583 | |||
584 | /* Check if the microcode we have in memory matches the CPU */ | ||
585 | if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || | ||
586 | cpu_has(c, X86_FEATURE_IA64) || uci->sig != cpuid_eax(0x00000001)) | ||
587 | err = -EINVAL; | ||
588 | |||
589 | if (!err && ((c->x86_model >= 5) || (c->x86 > 6))) { | ||
590 | /* get processor flags from MSR 0x17 */ | ||
591 | rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); | ||
592 | if (uci->pf != (1 << ((val[1] >> 18) & 7))) | ||
593 | err = -EINVAL; | ||
594 | } | ||
595 | |||
596 | if (!err) { | ||
597 | wrmsr(MSR_IA32_UCODE_REV, 0, 0); | ||
598 | /* see notes above for revision 1.07. Apparent chip bug */ | ||
599 | sync_core(); | ||
600 | /* get the current revision from MSR 0x8B */ | ||
601 | rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); | ||
602 | if (uci->rev != val[1]) | ||
603 | err = -EINVAL; | ||
604 | } | ||
605 | |||
606 | if (!err) | ||
607 | apply_microcode(cpu); | ||
608 | else | ||
609 | printk(KERN_ERR "microcode: Could not apply microcode to CPU%d:" | ||
610 | " sig=0x%x, pf=0x%x, rev=0x%x\n", | ||
611 | cpu, uci->sig, uci->pf, uci->rev); | ||
612 | |||
613 | set_cpus_allowed(current, old); | ||
614 | return err; | ||
615 | } | ||
616 | |||
570 | static void microcode_init_cpu(int cpu) | 617 | static void microcode_init_cpu(int cpu) |
571 | { | 618 | { |
572 | cpumask_t old; | 619 | cpumask_t old; |
@@ -577,7 +624,8 @@ static void microcode_init_cpu(int cpu) | |||
577 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | 624 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); |
578 | mutex_lock(µcode_mutex); | 625 | mutex_lock(µcode_mutex); |
579 | collect_cpu_info(cpu); | 626 | collect_cpu_info(cpu); |
580 | if (uci->valid && system_state == SYSTEM_RUNNING) | 627 | if (uci->valid && system_state == SYSTEM_RUNNING && |
628 | !suspend_cpu_hotplug) | ||
581 | cpu_request_microcode(cpu); | 629 | cpu_request_microcode(cpu); |
582 | mutex_unlock(µcode_mutex); | 630 | mutex_unlock(µcode_mutex); |
583 | set_cpus_allowed(current, old); | 631 | set_cpus_allowed(current, old); |
@@ -663,13 +711,24 @@ static int mc_sysdev_add(struct sys_device *sys_dev) | |||
663 | return 0; | 711 | return 0; |
664 | 712 | ||
665 | pr_debug("Microcode:CPU %d added\n", cpu); | 713 | pr_debug("Microcode:CPU %d added\n", cpu); |
666 | memset(uci, 0, sizeof(*uci)); | 714 | /* If suspend_cpu_hotplug is set, the system is resuming and we should |
715 | * use the data from before the suspend. | ||
716 | */ | ||
717 | if (suspend_cpu_hotplug) { | ||
718 | err = apply_microcode_on_cpu(cpu); | ||
719 | if (err) | ||
720 | microcode_fini_cpu(cpu); | ||
721 | } | ||
722 | if (!uci->valid) | ||
723 | memset(uci, 0, sizeof(*uci)); | ||
667 | 724 | ||
668 | err = sysfs_create_group(&sys_dev->kobj, &mc_attr_group); | 725 | err = sysfs_create_group(&sys_dev->kobj, &mc_attr_group); |
669 | if (err) | 726 | if (err) |
670 | return err; | 727 | return err; |
671 | 728 | ||
672 | microcode_init_cpu(cpu); | 729 | if (!uci->valid) |
730 | microcode_init_cpu(cpu); | ||
731 | |||
673 | return 0; | 732 | return 0; |
674 | } | 733 | } |
675 | 734 | ||
@@ -680,7 +739,11 @@ static int mc_sysdev_remove(struct sys_device *sys_dev) | |||
680 | if (!cpu_online(cpu)) | 739 | if (!cpu_online(cpu)) |
681 | return 0; | 740 | return 0; |
682 | pr_debug("Microcode:CPU %d removed\n", cpu); | 741 | pr_debug("Microcode:CPU %d removed\n", cpu); |
683 | microcode_fini_cpu(cpu); | 742 | /* If suspend_cpu_hotplug is set, the system is suspending and we should |
743 | * keep the microcode in memory for the resume. | ||
744 | */ | ||
745 | if (!suspend_cpu_hotplug) | ||
746 | microcode_fini_cpu(cpu); | ||
684 | sysfs_remove_group(&sys_dev->kobj, &mc_attr_group); | 747 | sysfs_remove_group(&sys_dev->kobj, &mc_attr_group); |
685 | return 0; | 748 | return 0; |
686 | } | 749 | } |
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index 821df34d2b3a..a98ba88a8c0c 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c | |||
@@ -122,64 +122,129 @@ static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr) | |||
122 | /* checks for a bit availability (hack for oprofile) */ | 122 | /* checks for a bit availability (hack for oprofile) */ |
123 | int avail_to_resrv_perfctr_nmi_bit(unsigned int counter) | 123 | int avail_to_resrv_perfctr_nmi_bit(unsigned int counter) |
124 | { | 124 | { |
125 | int cpu; | ||
125 | BUG_ON(counter > NMI_MAX_COUNTER_BITS); | 126 | BUG_ON(counter > NMI_MAX_COUNTER_BITS); |
126 | 127 | for_each_possible_cpu (cpu) { | |
127 | return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner))); | 128 | if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu))) |
129 | return 0; | ||
130 | } | ||
131 | return 1; | ||
128 | } | 132 | } |
129 | 133 | ||
130 | /* checks the an msr for availability */ | 134 | /* checks the an msr for availability */ |
131 | int avail_to_resrv_perfctr_nmi(unsigned int msr) | 135 | int avail_to_resrv_perfctr_nmi(unsigned int msr) |
132 | { | 136 | { |
133 | unsigned int counter; | 137 | unsigned int counter; |
138 | int cpu; | ||
134 | 139 | ||
135 | counter = nmi_perfctr_msr_to_bit(msr); | 140 | counter = nmi_perfctr_msr_to_bit(msr); |
136 | BUG_ON(counter > NMI_MAX_COUNTER_BITS); | 141 | BUG_ON(counter > NMI_MAX_COUNTER_BITS); |
137 | 142 | ||
138 | return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner))); | 143 | for_each_possible_cpu (cpu) { |
144 | if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu))) | ||
145 | return 0; | ||
146 | } | ||
147 | return 1; | ||
139 | } | 148 | } |
140 | 149 | ||
141 | int reserve_perfctr_nmi(unsigned int msr) | 150 | static int __reserve_perfctr_nmi(int cpu, unsigned int msr) |
142 | { | 151 | { |
143 | unsigned int counter; | 152 | unsigned int counter; |
153 | if (cpu < 0) | ||
154 | cpu = smp_processor_id(); | ||
144 | 155 | ||
145 | counter = nmi_perfctr_msr_to_bit(msr); | 156 | counter = nmi_perfctr_msr_to_bit(msr); |
146 | BUG_ON(counter > NMI_MAX_COUNTER_BITS); | 157 | BUG_ON(counter > NMI_MAX_COUNTER_BITS); |
147 | 158 | ||
148 | if (!test_and_set_bit(counter, &__get_cpu_var(perfctr_nmi_owner))) | 159 | if (!test_and_set_bit(counter, &per_cpu(perfctr_nmi_owner, cpu))) |
149 | return 1; | 160 | return 1; |
150 | return 0; | 161 | return 0; |
151 | } | 162 | } |
152 | 163 | ||
153 | void release_perfctr_nmi(unsigned int msr) | 164 | static void __release_perfctr_nmi(int cpu, unsigned int msr) |
154 | { | 165 | { |
155 | unsigned int counter; | 166 | unsigned int counter; |
167 | if (cpu < 0) | ||
168 | cpu = smp_processor_id(); | ||
156 | 169 | ||
157 | counter = nmi_perfctr_msr_to_bit(msr); | 170 | counter = nmi_perfctr_msr_to_bit(msr); |
158 | BUG_ON(counter > NMI_MAX_COUNTER_BITS); | 171 | BUG_ON(counter > NMI_MAX_COUNTER_BITS); |
159 | 172 | ||
160 | clear_bit(counter, &__get_cpu_var(perfctr_nmi_owner)); | 173 | clear_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)); |
161 | } | 174 | } |
162 | 175 | ||
163 | int reserve_evntsel_nmi(unsigned int msr) | 176 | int reserve_perfctr_nmi(unsigned int msr) |
177 | { | ||
178 | int cpu, i; | ||
179 | for_each_possible_cpu (cpu) { | ||
180 | if (!__reserve_perfctr_nmi(cpu, msr)) { | ||
181 | for_each_possible_cpu (i) { | ||
182 | if (i >= cpu) | ||
183 | break; | ||
184 | __release_perfctr_nmi(i, msr); | ||
185 | } | ||
186 | return 0; | ||
187 | } | ||
188 | } | ||
189 | return 1; | ||
190 | } | ||
191 | |||
192 | void release_perfctr_nmi(unsigned int msr) | ||
193 | { | ||
194 | int cpu; | ||
195 | for_each_possible_cpu (cpu) { | ||
196 | __release_perfctr_nmi(cpu, msr); | ||
197 | } | ||
198 | } | ||
199 | |||
200 | int __reserve_evntsel_nmi(int cpu, unsigned int msr) | ||
164 | { | 201 | { |
165 | unsigned int counter; | 202 | unsigned int counter; |
203 | if (cpu < 0) | ||
204 | cpu = smp_processor_id(); | ||
166 | 205 | ||
167 | counter = nmi_evntsel_msr_to_bit(msr); | 206 | counter = nmi_evntsel_msr_to_bit(msr); |
168 | BUG_ON(counter > NMI_MAX_COUNTER_BITS); | 207 | BUG_ON(counter > NMI_MAX_COUNTER_BITS); |
169 | 208 | ||
170 | if (!test_and_set_bit(counter, &__get_cpu_var(evntsel_nmi_owner)[0])) | 209 | if (!test_and_set_bit(counter, &per_cpu(evntsel_nmi_owner, cpu)[0])) |
171 | return 1; | 210 | return 1; |
172 | return 0; | 211 | return 0; |
173 | } | 212 | } |
174 | 213 | ||
175 | void release_evntsel_nmi(unsigned int msr) | 214 | static void __release_evntsel_nmi(int cpu, unsigned int msr) |
176 | { | 215 | { |
177 | unsigned int counter; | 216 | unsigned int counter; |
217 | if (cpu < 0) | ||
218 | cpu = smp_processor_id(); | ||
178 | 219 | ||
179 | counter = nmi_evntsel_msr_to_bit(msr); | 220 | counter = nmi_evntsel_msr_to_bit(msr); |
180 | BUG_ON(counter > NMI_MAX_COUNTER_BITS); | 221 | BUG_ON(counter > NMI_MAX_COUNTER_BITS); |
181 | 222 | ||
182 | clear_bit(counter, &__get_cpu_var(evntsel_nmi_owner)[0]); | 223 | clear_bit(counter, &per_cpu(evntsel_nmi_owner, cpu)[0]); |
224 | } | ||
225 | |||
226 | int reserve_evntsel_nmi(unsigned int msr) | ||
227 | { | ||
228 | int cpu, i; | ||
229 | for_each_possible_cpu (cpu) { | ||
230 | if (!__reserve_evntsel_nmi(cpu, msr)) { | ||
231 | for_each_possible_cpu (i) { | ||
232 | if (i >= cpu) | ||
233 | break; | ||
234 | __release_evntsel_nmi(i, msr); | ||
235 | } | ||
236 | return 0; | ||
237 | } | ||
238 | } | ||
239 | return 1; | ||
240 | } | ||
241 | |||
242 | void release_evntsel_nmi(unsigned int msr) | ||
243 | { | ||
244 | int cpu; | ||
245 | for_each_possible_cpu (cpu) { | ||
246 | __release_evntsel_nmi(cpu, msr); | ||
247 | } | ||
183 | } | 248 | } |
184 | 249 | ||
185 | static __cpuinit inline int nmi_known_cpu(void) | 250 | static __cpuinit inline int nmi_known_cpu(void) |
@@ -245,14 +310,6 @@ static int __init check_nmi_watchdog(void) | |||
245 | unsigned int *prev_nmi_count; | 310 | unsigned int *prev_nmi_count; |
246 | int cpu; | 311 | int cpu; |
247 | 312 | ||
248 | /* Enable NMI watchdog for newer systems. | ||
249 | Probably safe on most older systems too, but let's be careful. | ||
250 | IBM ThinkPads use INT10 inside SMM and that allows early NMI inside SMM | ||
251 | which hangs the system. Disable watchdog for all thinkpads */ | ||
252 | if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004 && | ||
253 | !dmi_name_in_vendors("ThinkPad")) | ||
254 | nmi_watchdog = NMI_LOCAL_APIC; | ||
255 | |||
256 | if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT)) | 313 | if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT)) |
257 | return 0; | 314 | return 0; |
258 | 315 | ||
@@ -271,7 +328,7 @@ static int __init check_nmi_watchdog(void) | |||
271 | for_each_possible_cpu(cpu) | 328 | for_each_possible_cpu(cpu) |
272 | prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count; | 329 | prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count; |
273 | local_irq_enable(); | 330 | local_irq_enable(); |
274 | mdelay((10*1000)/nmi_hz); // wait 10 ticks | 331 | mdelay((20*1000)/nmi_hz); // wait 20 ticks |
275 | 332 | ||
276 | for_each_possible_cpu(cpu) { | 333 | for_each_possible_cpu(cpu) { |
277 | #ifdef CONFIG_SMP | 334 | #ifdef CONFIG_SMP |
@@ -515,10 +572,10 @@ static int setup_k7_watchdog(void) | |||
515 | 572 | ||
516 | perfctr_msr = MSR_K7_PERFCTR0; | 573 | perfctr_msr = MSR_K7_PERFCTR0; |
517 | evntsel_msr = MSR_K7_EVNTSEL0; | 574 | evntsel_msr = MSR_K7_EVNTSEL0; |
518 | if (!reserve_perfctr_nmi(perfctr_msr)) | 575 | if (!__reserve_perfctr_nmi(-1, perfctr_msr)) |
519 | goto fail; | 576 | goto fail; |
520 | 577 | ||
521 | if (!reserve_evntsel_nmi(evntsel_msr)) | 578 | if (!__reserve_evntsel_nmi(-1, evntsel_msr)) |
522 | goto fail1; | 579 | goto fail1; |
523 | 580 | ||
524 | wrmsrl(perfctr_msr, 0UL); | 581 | wrmsrl(perfctr_msr, 0UL); |
@@ -541,7 +598,7 @@ static int setup_k7_watchdog(void) | |||
541 | wd->check_bit = 1ULL<<63; | 598 | wd->check_bit = 1ULL<<63; |
542 | return 1; | 599 | return 1; |
543 | fail1: | 600 | fail1: |
544 | release_perfctr_nmi(perfctr_msr); | 601 | __release_perfctr_nmi(-1, perfctr_msr); |
545 | fail: | 602 | fail: |
546 | return 0; | 603 | return 0; |
547 | } | 604 | } |
@@ -552,8 +609,8 @@ static void stop_k7_watchdog(void) | |||
552 | 609 | ||
553 | wrmsr(wd->evntsel_msr, 0, 0); | 610 | wrmsr(wd->evntsel_msr, 0, 0); |
554 | 611 | ||
555 | release_evntsel_nmi(wd->evntsel_msr); | 612 | __release_evntsel_nmi(-1, wd->evntsel_msr); |
556 | release_perfctr_nmi(wd->perfctr_msr); | 613 | __release_perfctr_nmi(-1, wd->perfctr_msr); |
557 | } | 614 | } |
558 | 615 | ||
559 | #define P6_EVNTSEL0_ENABLE (1 << 22) | 616 | #define P6_EVNTSEL0_ENABLE (1 << 22) |
@@ -571,10 +628,10 @@ static int setup_p6_watchdog(void) | |||
571 | 628 | ||
572 | perfctr_msr = MSR_P6_PERFCTR0; | 629 | perfctr_msr = MSR_P6_PERFCTR0; |
573 | evntsel_msr = MSR_P6_EVNTSEL0; | 630 | evntsel_msr = MSR_P6_EVNTSEL0; |
574 | if (!reserve_perfctr_nmi(perfctr_msr)) | 631 | if (!__reserve_perfctr_nmi(-1, perfctr_msr)) |
575 | goto fail; | 632 | goto fail; |
576 | 633 | ||
577 | if (!reserve_evntsel_nmi(evntsel_msr)) | 634 | if (!__reserve_evntsel_nmi(-1, evntsel_msr)) |
578 | goto fail1; | 635 | goto fail1; |
579 | 636 | ||
580 | wrmsrl(perfctr_msr, 0UL); | 637 | wrmsrl(perfctr_msr, 0UL); |
@@ -598,7 +655,7 @@ static int setup_p6_watchdog(void) | |||
598 | wd->check_bit = 1ULL<<39; | 655 | wd->check_bit = 1ULL<<39; |
599 | return 1; | 656 | return 1; |
600 | fail1: | 657 | fail1: |
601 | release_perfctr_nmi(perfctr_msr); | 658 | __release_perfctr_nmi(-1, perfctr_msr); |
602 | fail: | 659 | fail: |
603 | return 0; | 660 | return 0; |
604 | } | 661 | } |
@@ -609,8 +666,8 @@ static void stop_p6_watchdog(void) | |||
609 | 666 | ||
610 | wrmsr(wd->evntsel_msr, 0, 0); | 667 | wrmsr(wd->evntsel_msr, 0, 0); |
611 | 668 | ||
612 | release_evntsel_nmi(wd->evntsel_msr); | 669 | __release_evntsel_nmi(-1, wd->evntsel_msr); |
613 | release_perfctr_nmi(wd->perfctr_msr); | 670 | __release_perfctr_nmi(-1, wd->perfctr_msr); |
614 | } | 671 | } |
615 | 672 | ||
616 | /* Note that these events don't tick when the CPU idles. This means | 673 | /* Note that these events don't tick when the CPU idles. This means |
@@ -676,10 +733,10 @@ static int setup_p4_watchdog(void) | |||
676 | cccr_val = P4_CCCR_OVF_PMI1 | P4_CCCR_ESCR_SELECT(4); | 733 | cccr_val = P4_CCCR_OVF_PMI1 | P4_CCCR_ESCR_SELECT(4); |
677 | } | 734 | } |
678 | 735 | ||
679 | if (!reserve_perfctr_nmi(perfctr_msr)) | 736 | if (!__reserve_perfctr_nmi(-1, perfctr_msr)) |
680 | goto fail; | 737 | goto fail; |
681 | 738 | ||
682 | if (!reserve_evntsel_nmi(evntsel_msr)) | 739 | if (!__reserve_evntsel_nmi(-1, evntsel_msr)) |
683 | goto fail1; | 740 | goto fail1; |
684 | 741 | ||
685 | evntsel = P4_ESCR_EVENT_SELECT(0x3F) | 742 | evntsel = P4_ESCR_EVENT_SELECT(0x3F) |
@@ -703,7 +760,7 @@ static int setup_p4_watchdog(void) | |||
703 | wd->check_bit = 1ULL<<39; | 760 | wd->check_bit = 1ULL<<39; |
704 | return 1; | 761 | return 1; |
705 | fail1: | 762 | fail1: |
706 | release_perfctr_nmi(perfctr_msr); | 763 | __release_perfctr_nmi(-1, perfctr_msr); |
707 | fail: | 764 | fail: |
708 | return 0; | 765 | return 0; |
709 | } | 766 | } |
@@ -715,8 +772,8 @@ static void stop_p4_watchdog(void) | |||
715 | wrmsr(wd->cccr_msr, 0, 0); | 772 | wrmsr(wd->cccr_msr, 0, 0); |
716 | wrmsr(wd->evntsel_msr, 0, 0); | 773 | wrmsr(wd->evntsel_msr, 0, 0); |
717 | 774 | ||
718 | release_evntsel_nmi(wd->evntsel_msr); | 775 | __release_evntsel_nmi(-1, wd->evntsel_msr); |
719 | release_perfctr_nmi(wd->perfctr_msr); | 776 | __release_perfctr_nmi(-1, wd->perfctr_msr); |
720 | } | 777 | } |
721 | 778 | ||
722 | #define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL | 779 | #define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL |
@@ -744,10 +801,10 @@ static int setup_intel_arch_watchdog(void) | |||
744 | perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0; | 801 | perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0; |
745 | evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL0; | 802 | evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL0; |
746 | 803 | ||
747 | if (!reserve_perfctr_nmi(perfctr_msr)) | 804 | if (!__reserve_perfctr_nmi(-1, perfctr_msr)) |
748 | goto fail; | 805 | goto fail; |
749 | 806 | ||
750 | if (!reserve_evntsel_nmi(evntsel_msr)) | 807 | if (!__reserve_evntsel_nmi(-1, evntsel_msr)) |
751 | goto fail1; | 808 | goto fail1; |
752 | 809 | ||
753 | wrmsrl(perfctr_msr, 0UL); | 810 | wrmsrl(perfctr_msr, 0UL); |
@@ -772,7 +829,7 @@ static int setup_intel_arch_watchdog(void) | |||
772 | wd->check_bit = 1ULL << (eax.split.bit_width - 1); | 829 | wd->check_bit = 1ULL << (eax.split.bit_width - 1); |
773 | return 1; | 830 | return 1; |
774 | fail1: | 831 | fail1: |
775 | release_perfctr_nmi(perfctr_msr); | 832 | __release_perfctr_nmi(-1, perfctr_msr); |
776 | fail: | 833 | fail: |
777 | return 0; | 834 | return 0; |
778 | } | 835 | } |
@@ -795,8 +852,8 @@ static void stop_intel_arch_watchdog(void) | |||
795 | return; | 852 | return; |
796 | 853 | ||
797 | wrmsr(wd->evntsel_msr, 0, 0); | 854 | wrmsr(wd->evntsel_msr, 0, 0); |
798 | release_evntsel_nmi(wd->evntsel_msr); | 855 | __release_evntsel_nmi(-1, wd->evntsel_msr); |
799 | release_perfctr_nmi(wd->perfctr_msr); | 856 | __release_perfctr_nmi(-1, wd->perfctr_msr); |
800 | } | 857 | } |
801 | 858 | ||
802 | void setup_apic_nmi_watchdog (void *unused) | 859 | void setup_apic_nmi_watchdog (void *unused) |
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 9b0dd2744c82..4ff55e675576 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <linux/notifier.h> | 45 | #include <linux/notifier.h> |
46 | #include <linux/cpu.h> | 46 | #include <linux/cpu.h> |
47 | #include <linux/percpu.h> | 47 | #include <linux/percpu.h> |
48 | #include <linux/nmi.h> | ||
48 | 49 | ||
49 | #include <linux/delay.h> | 50 | #include <linux/delay.h> |
50 | #include <linux/mc146818rtc.h> | 51 | #include <linux/mc146818rtc.h> |
@@ -1278,8 +1279,9 @@ void __cpu_die(unsigned int cpu) | |||
1278 | 1279 | ||
1279 | int __cpuinit __cpu_up(unsigned int cpu) | 1280 | int __cpuinit __cpu_up(unsigned int cpu) |
1280 | { | 1281 | { |
1282 | unsigned long flags; | ||
1281 | #ifdef CONFIG_HOTPLUG_CPU | 1283 | #ifdef CONFIG_HOTPLUG_CPU |
1282 | int ret=0; | 1284 | int ret = 0; |
1283 | 1285 | ||
1284 | /* | 1286 | /* |
1285 | * We do warm boot only on cpus that had booted earlier | 1287 | * We do warm boot only on cpus that had booted earlier |
@@ -1297,23 +1299,25 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
1297 | /* In case one didn't come up */ | 1299 | /* In case one didn't come up */ |
1298 | if (!cpu_isset(cpu, cpu_callin_map)) { | 1300 | if (!cpu_isset(cpu, cpu_callin_map)) { |
1299 | printk(KERN_DEBUG "skipping cpu%d, didn't come online\n", cpu); | 1301 | printk(KERN_DEBUG "skipping cpu%d, didn't come online\n", cpu); |
1300 | local_irq_enable(); | ||
1301 | return -EIO; | 1302 | return -EIO; |
1302 | } | 1303 | } |
1303 | 1304 | ||
1304 | local_irq_enable(); | ||
1305 | |||
1306 | per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; | 1305 | per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; |
1307 | /* Unleash the CPU! */ | 1306 | /* Unleash the CPU! */ |
1308 | cpu_set(cpu, smp_commenced_mask); | 1307 | cpu_set(cpu, smp_commenced_mask); |
1309 | 1308 | ||
1310 | /* | 1309 | /* |
1311 | * Check TSC synchronization with the AP: | 1310 | * Check TSC synchronization with the AP (keep irqs disabled |
1311 | * while doing so): | ||
1312 | */ | 1312 | */ |
1313 | local_irq_save(flags); | ||
1313 | check_tsc_sync_source(cpu); | 1314 | check_tsc_sync_source(cpu); |
1315 | local_irq_restore(flags); | ||
1314 | 1316 | ||
1315 | while (!cpu_isset(cpu, cpu_online_map)) | 1317 | while (!cpu_isset(cpu, cpu_online_map)) { |
1316 | cpu_relax(); | 1318 | cpu_relax(); |
1319 | touch_nmi_watchdog(); | ||
1320 | } | ||
1317 | 1321 | ||
1318 | #ifdef CONFIG_X86_GENERICARCH | 1322 | #ifdef CONFIG_X86_GENERICARCH |
1319 | if (num_online_cpus() > 8 && genapic == &apic_default) | 1323 | if (num_online_cpus() > 8 && genapic == &apic_default) |
diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c index 602660df455c..6cb8f5336732 100644 --- a/arch/i386/kernel/tsc.c +++ b/arch/i386/kernel/tsc.c | |||
@@ -18,6 +18,8 @@ | |||
18 | 18 | ||
19 | #include "mach_timer.h" | 19 | #include "mach_timer.h" |
20 | 20 | ||
21 | static int tsc_enabled; | ||
22 | |||
21 | /* | 23 | /* |
22 | * On some systems the TSC frequency does not | 24 | * On some systems the TSC frequency does not |
23 | * change with the cpu frequency. So we need | 25 | * change with the cpu frequency. So we need |
@@ -105,7 +107,7 @@ unsigned long long sched_clock(void) | |||
105 | /* | 107 | /* |
106 | * Fall back to jiffies if there's no TSC available: | 108 | * Fall back to jiffies if there's no TSC available: |
107 | */ | 109 | */ |
108 | if (unlikely(tsc_disable)) | 110 | if (unlikely(!tsc_enabled)) |
109 | /* No locking but a rare wrong value is not a big deal: */ | 111 | /* No locking but a rare wrong value is not a big deal: */ |
110 | return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ); | 112 | return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ); |
111 | 113 | ||
@@ -283,6 +285,7 @@ void mark_tsc_unstable(void) | |||
283 | { | 285 | { |
284 | if (!tsc_unstable) { | 286 | if (!tsc_unstable) { |
285 | tsc_unstable = 1; | 287 | tsc_unstable = 1; |
288 | tsc_enabled = 0; | ||
286 | /* Can be called before registration */ | 289 | /* Can be called before registration */ |
287 | if (clocksource_tsc.mult) | 290 | if (clocksource_tsc.mult) |
288 | clocksource_change_rating(&clocksource_tsc, 0); | 291 | clocksource_change_rating(&clocksource_tsc, 0); |
@@ -383,7 +386,9 @@ void __init tsc_init(void) | |||
383 | if (check_tsc_unstable()) { | 386 | if (check_tsc_unstable()) { |
384 | clocksource_tsc.rating = 0; | 387 | clocksource_tsc.rating = 0; |
385 | clocksource_tsc.flags &= ~CLOCK_SOURCE_IS_CONTINUOUS; | 388 | clocksource_tsc.flags &= ~CLOCK_SOURCE_IS_CONTINUOUS; |
386 | } | 389 | } else |
390 | tsc_enabled = 1; | ||
391 | |||
387 | clocksource_register(&clocksource_tsc); | 392 | clocksource_register(&clocksource_tsc); |
388 | 393 | ||
389 | return; | 394 | return; |
diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c index fbf45fa08320..edc339fa5038 100644 --- a/arch/i386/kernel/vmi.c +++ b/arch/i386/kernel/vmi.c | |||
@@ -23,7 +23,6 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/license.h> | ||
27 | #include <linux/cpu.h> | 26 | #include <linux/cpu.h> |
28 | #include <linux/bootmem.h> | 27 | #include <linux/bootmem.h> |
29 | #include <linux/mm.h> | 28 | #include <linux/mm.h> |
@@ -48,7 +47,6 @@ typedef u64 __attribute__((regparm(2))) (VROMLONGFUNC)(int); | |||
48 | (((VROMLONGFUNC *)(rom->func)) (arg)) | 47 | (((VROMLONGFUNC *)(rom->func)) (arg)) |
49 | 48 | ||
50 | static struct vrom_header *vmi_rom; | 49 | static struct vrom_header *vmi_rom; |
51 | static int license_gplok; | ||
52 | static int disable_pge; | 50 | static int disable_pge; |
53 | static int disable_pse; | 51 | static int disable_pse; |
54 | static int disable_sep; | 52 | static int disable_sep; |
@@ -71,6 +69,7 @@ struct { | |||
71 | void (*flush_tlb)(int); | 69 | void (*flush_tlb)(int); |
72 | void (*set_initial_ap_state)(int, int); | 70 | void (*set_initial_ap_state)(int, int); |
73 | void (*halt)(void); | 71 | void (*halt)(void); |
72 | void (*set_lazy_mode)(int mode); | ||
74 | } vmi_ops; | 73 | } vmi_ops; |
75 | 74 | ||
76 | /* XXX move this to alternative.h */ | 75 | /* XXX move this to alternative.h */ |
@@ -576,6 +575,26 @@ vmi_startup_ipi_hook(int phys_apicid, unsigned long start_eip, | |||
576 | } | 575 | } |
577 | #endif | 576 | #endif |
578 | 577 | ||
578 | static void vmi_set_lazy_mode(int mode) | ||
579 | { | ||
580 | static DEFINE_PER_CPU(int, lazy_mode); | ||
581 | |||
582 | if (!vmi_ops.set_lazy_mode) | ||
583 | return; | ||
584 | |||
585 | /* Modes should never nest or overlap */ | ||
586 | BUG_ON(__get_cpu_var(lazy_mode) && !(mode == PARAVIRT_LAZY_NONE || | ||
587 | mode == PARAVIRT_LAZY_FLUSH)); | ||
588 | |||
589 | if (mode == PARAVIRT_LAZY_FLUSH) { | ||
590 | vmi_ops.set_lazy_mode(0); | ||
591 | vmi_ops.set_lazy_mode(__get_cpu_var(lazy_mode)); | ||
592 | } else { | ||
593 | vmi_ops.set_lazy_mode(mode); | ||
594 | __get_cpu_var(lazy_mode) = mode; | ||
595 | } | ||
596 | } | ||
597 | |||
579 | static inline int __init check_vmi_rom(struct vrom_header *rom) | 598 | static inline int __init check_vmi_rom(struct vrom_header *rom) |
580 | { | 599 | { |
581 | struct pci_header *pci; | 600 | struct pci_header *pci; |
@@ -629,13 +648,14 @@ static inline int __init check_vmi_rom(struct vrom_header *rom) | |||
629 | rom->api_version_maj, rom->api_version_min, | 648 | rom->api_version_maj, rom->api_version_min, |
630 | pci->rom_version_maj, pci->rom_version_min); | 649 | pci->rom_version_maj, pci->rom_version_min); |
631 | 650 | ||
632 | license_gplok = license_is_gpl_compatible(license); | 651 | /* Don't allow BSD/MIT here for now because we don't want to end up |
633 | if (!license_gplok) { | 652 | with any binary only shim layers */ |
634 | printk(KERN_WARNING "VMI: ROM license '%s' taints kernel... " | 653 | if (strcmp(license, "GPL") && strcmp(license, "GPL v2")) { |
635 | "inlining disabled\n", | 654 | printk(KERN_WARNING "VMI: Non GPL license `%s' found for ROM. Not used.\n", |
636 | license); | 655 | license); |
637 | add_taint(TAINT_PROPRIETARY_MODULE); | 656 | return 0; |
638 | } | 657 | } |
658 | |||
639 | return 1; | 659 | return 1; |
640 | } | 660 | } |
641 | 661 | ||
@@ -805,7 +825,7 @@ static inline int __init activate_vmi(void) | |||
805 | para_wrap(load_esp0, vmi_load_esp0, set_kernel_stack, UpdateKernelStack); | 825 | para_wrap(load_esp0, vmi_load_esp0, set_kernel_stack, UpdateKernelStack); |
806 | para_fill(set_iopl_mask, SetIOPLMask); | 826 | para_fill(set_iopl_mask, SetIOPLMask); |
807 | para_fill(io_delay, IODelay); | 827 | para_fill(io_delay, IODelay); |
808 | para_fill(set_lazy_mode, SetLazyMode); | 828 | para_wrap(set_lazy_mode, vmi_set_lazy_mode, set_lazy_mode, SetLazyMode); |
809 | 829 | ||
810 | /* user and kernel flush are just handled with different flags to FlushTLB */ | 830 | /* user and kernel flush are just handled with different flags to FlushTLB */ |
811 | para_wrap(flush_tlb_user, vmi_flush_tlb_user, flush_tlb, FlushTLB); | 831 | para_wrap(flush_tlb_user, vmi_flush_tlb_user, flush_tlb, FlushTLB); |
diff --git a/arch/i386/lib/usercopy.c b/arch/i386/lib/usercopy.c index d22cfc9d656c..086b3726862a 100644 --- a/arch/i386/lib/usercopy.c +++ b/arch/i386/lib/usercopy.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/blkdev.h> | 10 | #include <linux/blkdev.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/backing-dev.h> | 12 | #include <linux/backing-dev.h> |
13 | #include <linux/interrupt.h> | ||
13 | #include <asm/uaccess.h> | 14 | #include <asm/uaccess.h> |
14 | #include <asm/mmx.h> | 15 | #include <asm/mmx.h> |
15 | 16 | ||
@@ -719,6 +720,14 @@ unsigned long __copy_to_user_ll(void __user *to, const void *from, | |||
719 | #ifndef CONFIG_X86_WP_WORKS_OK | 720 | #ifndef CONFIG_X86_WP_WORKS_OK |
720 | if (unlikely(boot_cpu_data.wp_works_ok == 0) && | 721 | if (unlikely(boot_cpu_data.wp_works_ok == 0) && |
721 | ((unsigned long )to) < TASK_SIZE) { | 722 | ((unsigned long )to) < TASK_SIZE) { |
723 | /* | ||
724 | * When we are in an atomic section (see | ||
725 | * mm/filemap.c:file_read_actor), return the full | ||
726 | * length to take the slow path. | ||
727 | */ | ||
728 | if (in_atomic()) | ||
729 | return n; | ||
730 | |||
722 | /* | 731 | /* |
723 | * CPU does not honor the WP bit when writing | 732 | * CPU does not honor the WP bit when writing |
724 | * from supervisory mode, and due to preemption or SMP, | 733 | * from supervisory mode, and due to preemption or SMP, |
diff --git a/arch/i386/mm/highmem.c b/arch/i386/mm/highmem.c index bb2de1089add..ac70d09df7ee 100644 --- a/arch/i386/mm/highmem.c +++ b/arch/i386/mm/highmem.c | |||
@@ -42,6 +42,7 @@ void *kmap_atomic(struct page *page, enum km_type type) | |||
42 | 42 | ||
43 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | 43 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); |
44 | set_pte(kmap_pte-idx, mk_pte(page, kmap_prot)); | 44 | set_pte(kmap_pte-idx, mk_pte(page, kmap_prot)); |
45 | arch_flush_lazy_mmu_mode(); | ||
45 | 46 | ||
46 | return (void*) vaddr; | 47 | return (void*) vaddr; |
47 | } | 48 | } |
@@ -82,6 +83,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) | |||
82 | idx = type + KM_TYPE_NR*smp_processor_id(); | 83 | idx = type + KM_TYPE_NR*smp_processor_id(); |
83 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | 84 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); |
84 | set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot)); | 85 | set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot)); |
86 | arch_flush_lazy_mmu_mode(); | ||
85 | 87 | ||
86 | return (void*) vaddr; | 88 | return (void*) vaddr; |
87 | } | 89 | } |
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 1bb069372143..3f78d4d8ecf3 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c | |||
@@ -193,6 +193,14 @@ static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { | |||
193 | }, | 193 | }, |
194 | { | 194 | { |
195 | .callback = set_bf_sort, | 195 | .callback = set_bf_sort, |
196 | .ident = "Dell PowerEdge R900", | ||
197 | .matches = { | ||
198 | DMI_MATCH(DMI_SYS_VENDOR, "Dell"), | ||
199 | DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R900"), | ||
200 | }, | ||
201 | }, | ||
202 | { | ||
203 | .callback = set_bf_sort, | ||
196 | .ident = "HP ProLiant BL20p G3", | 204 | .ident = "HP ProLiant BL20p G3", |
197 | .matches = { | 205 | .matches = { |
198 | DMI_MATCH(DMI_SYS_VENDOR, "HP"), | 206 | DMI_MATCH(DMI_SYS_VENDOR, "HP"), |
@@ -426,11 +434,13 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) | |||
426 | if ((err = pcibios_enable_resources(dev, mask)) < 0) | 434 | if ((err = pcibios_enable_resources(dev, mask)) < 0) |
427 | return err; | 435 | return err; |
428 | 436 | ||
429 | return pcibios_enable_irq(dev); | 437 | if (!dev->msi_enabled) |
438 | return pcibios_enable_irq(dev); | ||
439 | return 0; | ||
430 | } | 440 | } |
431 | 441 | ||
432 | void pcibios_disable_device (struct pci_dev *dev) | 442 | void pcibios_disable_device (struct pci_dev *dev) |
433 | { | 443 | { |
434 | if (pcibios_disable_irq) | 444 | if (!dev->msi_enabled && pcibios_disable_irq) |
435 | pcibios_disable_irq(dev); | 445 | pcibios_disable_irq(dev); |
436 | } | 446 | } |