diff options
Diffstat (limited to 'arch')
205 files changed, 5926 insertions, 1795 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 07ba77c19f6c..c8d94dcd8ef7 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -157,7 +157,7 @@ config ARCH_RPC | |||
157 | config ARCH_SA1100 | 157 | config ARCH_SA1100 |
158 | bool "SA1100-based" | 158 | bool "SA1100-based" |
159 | select ISA | 159 | select ISA |
160 | select DISCONTIGMEM | 160 | select ARCH_DISCONTIGMEM_ENABLE |
161 | 161 | ||
162 | config ARCH_S3C2410 | 162 | config ARCH_S3C2410 |
163 | bool "Samsung S3C2410" | 163 | bool "Samsung S3C2410" |
@@ -346,6 +346,21 @@ config PREEMPT | |||
346 | Say Y here if you are building a kernel for a desktop, embedded | 346 | Say Y here if you are building a kernel for a desktop, embedded |
347 | or real-time system. Say N if you are unsure. | 347 | or real-time system. Say N if you are unsure. |
348 | 348 | ||
349 | config NO_IDLE_HZ | ||
350 | bool "Dynamic tick timer" | ||
351 | help | ||
352 | Select this option if you want to disable continuous timer ticks | ||
353 | and have them programmed to occur as required. This option saves | ||
354 | power as the system can remain in idle state for longer. | ||
355 | |||
356 | By default dynamic tick is disabled during the boot, and can be | ||
357 | manually enabled with: | ||
358 | |||
359 | echo 1 > /sys/devices/system/timer/timer0/dyn_tick | ||
360 | |||
361 | Alternatively, if you want dynamic tick automatically enabled | ||
362 | during boot, pass "dyntick=enable" via the kernel command string. | ||
363 | |||
349 | config ARCH_DISCONTIGMEM_ENABLE | 364 | config ARCH_DISCONTIGMEM_ENABLE |
350 | bool | 365 | bool |
351 | default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) | 366 | default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) |
diff --git a/arch/arm/configs/enp2611_defconfig b/arch/arm/configs/enp2611_defconfig index 06fae4b62774..b8c51ee7f1bb 100644 --- a/arch/arm/configs/enp2611_defconfig +++ b/arch/arm/configs/enp2611_defconfig | |||
@@ -1,14 +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.12-rc1-bk2 | 3 | # Linux kernel version: 2.6.12-git6 |
4 | # Sun Mar 27 22:08:24 2005 | 4 | # Sat Jun 25 00:57:29 2005 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
8 | CONFIG_UID16=y | 8 | CONFIG_UID16=y |
9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
10 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 10 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
11 | CONFIG_GENERIC_IOMAP=y | ||
12 | 11 | ||
13 | # | 12 | # |
14 | # Code maturity level options | 13 | # Code maturity level options |
@@ -16,6 +15,7 @@ CONFIG_GENERIC_IOMAP=y | |||
16 | CONFIG_EXPERIMENTAL=y | 15 | CONFIG_EXPERIMENTAL=y |
17 | CONFIG_CLEAN_COMPILE=y | 16 | CONFIG_CLEAN_COMPILE=y |
18 | CONFIG_BROKEN_ON_SMP=y | 17 | CONFIG_BROKEN_ON_SMP=y |
18 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
19 | 19 | ||
20 | # | 20 | # |
21 | # General setup | 21 | # General setup |
@@ -35,6 +35,8 @@ CONFIG_EMBEDDED=y | |||
35 | CONFIG_KALLSYMS=y | 35 | CONFIG_KALLSYMS=y |
36 | # CONFIG_KALLSYMS_ALL is not set | 36 | # CONFIG_KALLSYMS_ALL is not set |
37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
38 | CONFIG_PRINTK=y | ||
39 | CONFIG_BUG=y | ||
38 | CONFIG_BASE_FULL=y | 40 | CONFIG_BASE_FULL=y |
39 | CONFIG_FUTEX=y | 41 | CONFIG_FUTEX=y |
40 | CONFIG_EPOLL=y | 42 | CONFIG_EPOLL=y |
@@ -82,6 +84,7 @@ CONFIG_ARCH_IXP2000=y | |||
82 | # CONFIG_ARCH_VERSATILE is not set | 84 | # CONFIG_ARCH_VERSATILE is not set |
83 | # CONFIG_ARCH_IMX is not set | 85 | # CONFIG_ARCH_IMX is not set |
84 | # CONFIG_ARCH_H720X is not set | 86 | # CONFIG_ARCH_H720X is not set |
87 | # CONFIG_ARCH_AAEC2000 is not set | ||
85 | CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y | 88 | CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y |
86 | 89 | ||
87 | # | 90 | # |
@@ -96,6 +99,7 @@ CONFIG_ARCH_ENP2611=y | |||
96 | # CONFIG_ARCH_IXDP2800 is not set | 99 | # CONFIG_ARCH_IXDP2800 is not set |
97 | # CONFIG_ARCH_IXDP2401 is not set | 100 | # CONFIG_ARCH_IXDP2401 is not set |
98 | # CONFIG_ARCH_IXDP2801 is not set | 101 | # CONFIG_ARCH_IXDP2801 is not set |
102 | # CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set | ||
99 | 103 | ||
100 | # | 104 | # |
101 | # Processor Type | 105 | # Processor Type |
@@ -106,7 +110,6 @@ CONFIG_CPU_32v5=y | |||
106 | CONFIG_CPU_ABRT_EV5T=y | 110 | CONFIG_CPU_ABRT_EV5T=y |
107 | CONFIG_CPU_CACHE_VIVT=y | 111 | CONFIG_CPU_CACHE_VIVT=y |
108 | CONFIG_CPU_TLB_V4WBI=y | 112 | CONFIG_CPU_TLB_V4WBI=y |
109 | CONFIG_CPU_MINICACHE=y | ||
110 | 113 | ||
111 | # | 114 | # |
112 | # Processor Features | 115 | # Processor Features |
@@ -118,9 +121,11 @@ CONFIG_XSCALE_PMU=y | |||
118 | # | 121 | # |
119 | # Bus support | 122 | # Bus support |
120 | # | 123 | # |
124 | CONFIG_ISA_DMA_API=y | ||
121 | CONFIG_PCI=y | 125 | CONFIG_PCI=y |
122 | CONFIG_PCI_LEGACY_PROC=y | 126 | CONFIG_PCI_LEGACY_PROC=y |
123 | CONFIG_PCI_NAMES=y | 127 | CONFIG_PCI_NAMES=y |
128 | # CONFIG_PCI_DEBUG is not set | ||
124 | 129 | ||
125 | # | 130 | # |
126 | # PCCARD (PCMCIA/CardBus) support | 131 | # PCCARD (PCMCIA/CardBus) support |
@@ -130,7 +135,15 @@ CONFIG_PCI_NAMES=y | |||
130 | # | 135 | # |
131 | # Kernel Features | 136 | # Kernel Features |
132 | # | 137 | # |
138 | # CONFIG_SMP is not set | ||
133 | # CONFIG_PREEMPT is not set | 139 | # CONFIG_PREEMPT is not set |
140 | # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set | ||
141 | CONFIG_SELECT_MEMORY_MODEL=y | ||
142 | CONFIG_FLATMEM_MANUAL=y | ||
143 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
144 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
145 | CONFIG_FLATMEM=y | ||
146 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
134 | CONFIG_ALIGNMENT_TRAP=y | 147 | CONFIG_ALIGNMENT_TRAP=y |
135 | 148 | ||
136 | # | 149 | # |
@@ -269,7 +282,6 @@ CONFIG_MTD_IXP2000=y | |||
269 | # | 282 | # |
270 | # Block devices | 283 | # Block devices |
271 | # | 284 | # |
272 | # CONFIG_BLK_DEV_FD is not set | ||
273 | # CONFIG_BLK_CPQ_DA is not set | 285 | # CONFIG_BLK_CPQ_DA is not set |
274 | # CONFIG_BLK_CPQ_CISS_DA is not set | 286 | # CONFIG_BLK_CPQ_CISS_DA is not set |
275 | # CONFIG_BLK_DEV_DAC960 is not set | 287 | # CONFIG_BLK_DEV_DAC960 is not set |
@@ -308,6 +320,7 @@ CONFIG_IOSCHED_CFQ=y | |||
308 | # | 320 | # |
309 | # Fusion MPT device support | 321 | # Fusion MPT device support |
310 | # | 322 | # |
323 | # CONFIG_FUSION is not set | ||
311 | 324 | ||
312 | # | 325 | # |
313 | # IEEE 1394 (FireWire) support | 326 | # IEEE 1394 (FireWire) support |
@@ -329,10 +342,11 @@ CONFIG_NET=y | |||
329 | # | 342 | # |
330 | CONFIG_PACKET=y | 343 | CONFIG_PACKET=y |
331 | CONFIG_PACKET_MMAP=y | 344 | CONFIG_PACKET_MMAP=y |
332 | # CONFIG_NETLINK_DEV is not set | ||
333 | CONFIG_UNIX=y | 345 | CONFIG_UNIX=y |
334 | # CONFIG_NET_KEY is not set | 346 | # CONFIG_NET_KEY is not set |
335 | CONFIG_INET=y | 347 | CONFIG_INET=y |
348 | CONFIG_IP_FIB_HASH=y | ||
349 | # CONFIG_IP_FIB_TRIE is not set | ||
336 | # CONFIG_IP_MULTICAST is not set | 350 | # CONFIG_IP_MULTICAST is not set |
337 | # CONFIG_IP_ADVANCED_ROUTER is not set | 351 | # CONFIG_IP_ADVANCED_ROUTER is not set |
338 | CONFIG_IP_PNP=y | 352 | CONFIG_IP_PNP=y |
@@ -349,6 +363,17 @@ CONFIG_SYN_COOKIES=y | |||
349 | # CONFIG_INET_TUNNEL is not set | 363 | # CONFIG_INET_TUNNEL is not set |
350 | # CONFIG_IP_TCPDIAG is not set | 364 | # CONFIG_IP_TCPDIAG is not set |
351 | # CONFIG_IP_TCPDIAG_IPV6 is not set | 365 | # CONFIG_IP_TCPDIAG_IPV6 is not set |
366 | |||
367 | # | ||
368 | # TCP congestion control | ||
369 | # | ||
370 | CONFIG_TCP_CONG_BIC=y | ||
371 | CONFIG_TCP_CONG_WESTWOOD=m | ||
372 | CONFIG_TCP_CONG_HTCP=m | ||
373 | # CONFIG_TCP_CONG_HSTCP is not set | ||
374 | # CONFIG_TCP_CONG_HYBLA is not set | ||
375 | # CONFIG_TCP_CONG_VEGAS is not set | ||
376 | # CONFIG_TCP_CONG_SCALABLE is not set | ||
352 | # CONFIG_IPV6 is not set | 377 | # CONFIG_IPV6 is not set |
353 | # CONFIG_NETFILTER is not set | 378 | # CONFIG_NETFILTER is not set |
354 | 379 | ||
@@ -404,6 +429,7 @@ CONFIG_MII=y | |||
404 | # CONFIG_SUNGEM is not set | 429 | # CONFIG_SUNGEM is not set |
405 | # CONFIG_NET_VENDOR_3COM is not set | 430 | # CONFIG_NET_VENDOR_3COM is not set |
406 | # CONFIG_SMC91X is not set | 431 | # CONFIG_SMC91X is not set |
432 | # CONFIG_DM9000 is not set | ||
407 | 433 | ||
408 | # | 434 | # |
409 | # Tulip family network device support | 435 | # Tulip family network device support |
@@ -440,9 +466,11 @@ CONFIG_EEPRO100=y | |||
440 | # CONFIG_HAMACHI is not set | 466 | # CONFIG_HAMACHI is not set |
441 | # CONFIG_YELLOWFIN is not set | 467 | # CONFIG_YELLOWFIN is not set |
442 | # CONFIG_R8169 is not set | 468 | # CONFIG_R8169 is not set |
469 | # CONFIG_SKGE is not set | ||
443 | # CONFIG_SK98LIN is not set | 470 | # CONFIG_SK98LIN is not set |
444 | # CONFIG_VIA_VELOCITY is not set | 471 | # CONFIG_VIA_VELOCITY is not set |
445 | # CONFIG_TIGON3 is not set | 472 | # CONFIG_TIGON3 is not set |
473 | # CONFIG_BNX2 is not set | ||
446 | 474 | ||
447 | # | 475 | # |
448 | # Ethernet (10000 Mbit) | 476 | # Ethernet (10000 Mbit) |
@@ -464,6 +492,7 @@ CONFIG_EEPRO100=y | |||
464 | # Wan interfaces | 492 | # Wan interfaces |
465 | # | 493 | # |
466 | CONFIG_WAN=y | 494 | CONFIG_WAN=y |
495 | # CONFIG_DSCC4 is not set | ||
467 | # CONFIG_LANMEDIA is not set | 496 | # CONFIG_LANMEDIA is not set |
468 | # CONFIG_SYNCLINK_SYNCPPP is not set | 497 | # CONFIG_SYNCLINK_SYNCPPP is not set |
469 | CONFIG_HDLC=y | 498 | CONFIG_HDLC=y |
@@ -526,7 +555,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | |||
526 | # | 555 | # |
527 | # CONFIG_SERIO is not set | 556 | # CONFIG_SERIO is not set |
528 | # CONFIG_GAMEPORT is not set | 557 | # CONFIG_GAMEPORT is not set |
529 | CONFIG_SOUND_GAMEPORT=y | ||
530 | 558 | ||
531 | # | 559 | # |
532 | # Character devices | 560 | # Character devices |
@@ -547,6 +575,7 @@ CONFIG_SERIAL_8250_NR_UARTS=2 | |||
547 | # | 575 | # |
548 | CONFIG_SERIAL_CORE=y | 576 | CONFIG_SERIAL_CORE=y |
549 | CONFIG_SERIAL_CORE_CONSOLE=y | 577 | CONFIG_SERIAL_CORE_CONSOLE=y |
578 | # CONFIG_SERIAL_JSM is not set | ||
550 | CONFIG_UNIX98_PTYS=y | 579 | CONFIG_UNIX98_PTYS=y |
551 | CONFIG_LEGACY_PTYS=y | 580 | CONFIG_LEGACY_PTYS=y |
552 | CONFIG_LEGACY_PTY_COUNT=256 | 581 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -613,17 +642,18 @@ CONFIG_I2C_ALGOBIT=y | |||
613 | # CONFIG_I2C_AMD8111 is not set | 642 | # CONFIG_I2C_AMD8111 is not set |
614 | # CONFIG_I2C_I801 is not set | 643 | # CONFIG_I2C_I801 is not set |
615 | # CONFIG_I2C_I810 is not set | 644 | # CONFIG_I2C_I810 is not set |
645 | # CONFIG_I2C_PIIX4 is not set | ||
616 | # CONFIG_I2C_ISA is not set | 646 | # CONFIG_I2C_ISA is not set |
617 | # CONFIG_I2C_IXP2000 is not set | 647 | # CONFIG_I2C_IXP2000 is not set |
618 | # CONFIG_I2C_NFORCE2 is not set | 648 | # CONFIG_I2C_NFORCE2 is not set |
619 | # CONFIG_I2C_PARPORT_LIGHT is not set | 649 | # CONFIG_I2C_PARPORT_LIGHT is not set |
620 | # CONFIG_I2C_PIIX4 is not set | ||
621 | # CONFIG_I2C_PROSAVAGE is not set | 650 | # CONFIG_I2C_PROSAVAGE is not set |
622 | # CONFIG_I2C_SAVAGE4 is not set | 651 | # CONFIG_I2C_SAVAGE4 is not set |
623 | # CONFIG_SCx200_ACB is not set | 652 | # CONFIG_SCx200_ACB is not set |
624 | # CONFIG_I2C_SIS5595 is not set | 653 | # CONFIG_I2C_SIS5595 is not set |
625 | # CONFIG_I2C_SIS630 is not set | 654 | # CONFIG_I2C_SIS630 is not set |
626 | # CONFIG_I2C_SIS96X is not set | 655 | # CONFIG_I2C_SIS96X is not set |
656 | # CONFIG_I2C_STUB is not set | ||
627 | # CONFIG_I2C_VIA is not set | 657 | # CONFIG_I2C_VIA is not set |
628 | # CONFIG_I2C_VIAPRO is not set | 658 | # CONFIG_I2C_VIAPRO is not set |
629 | # CONFIG_I2C_VOODOO3 is not set | 659 | # CONFIG_I2C_VOODOO3 is not set |
@@ -637,7 +667,9 @@ CONFIG_I2C_SENSOR=y | |||
637 | # CONFIG_SENSORS_ADM1025 is not set | 667 | # CONFIG_SENSORS_ADM1025 is not set |
638 | # CONFIG_SENSORS_ADM1026 is not set | 668 | # CONFIG_SENSORS_ADM1026 is not set |
639 | # CONFIG_SENSORS_ADM1031 is not set | 669 | # CONFIG_SENSORS_ADM1031 is not set |
670 | # CONFIG_SENSORS_ADM9240 is not set | ||
640 | # CONFIG_SENSORS_ASB100 is not set | 671 | # CONFIG_SENSORS_ASB100 is not set |
672 | # CONFIG_SENSORS_ATXP1 is not set | ||
641 | # CONFIG_SENSORS_DS1621 is not set | 673 | # CONFIG_SENSORS_DS1621 is not set |
642 | # CONFIG_SENSORS_FSCHER is not set | 674 | # CONFIG_SENSORS_FSCHER is not set |
643 | # CONFIG_SENSORS_FSCPOS is not set | 675 | # CONFIG_SENSORS_FSCPOS is not set |
@@ -653,6 +685,7 @@ CONFIG_I2C_SENSOR=y | |||
653 | # CONFIG_SENSORS_LM85 is not set | 685 | # CONFIG_SENSORS_LM85 is not set |
654 | # CONFIG_SENSORS_LM87 is not set | 686 | # CONFIG_SENSORS_LM87 is not set |
655 | # CONFIG_SENSORS_LM90 is not set | 687 | # CONFIG_SENSORS_LM90 is not set |
688 | # CONFIG_SENSORS_LM92 is not set | ||
656 | # CONFIG_SENSORS_MAX1619 is not set | 689 | # CONFIG_SENSORS_MAX1619 is not set |
657 | # CONFIG_SENSORS_PC87360 is not set | 690 | # CONFIG_SENSORS_PC87360 is not set |
658 | # CONFIG_SENSORS_SMSC47B397 is not set | 691 | # CONFIG_SENSORS_SMSC47B397 is not set |
@@ -662,14 +695,19 @@ CONFIG_I2C_SENSOR=y | |||
662 | # CONFIG_SENSORS_W83781D is not set | 695 | # CONFIG_SENSORS_W83781D is not set |
663 | # CONFIG_SENSORS_W83L785TS is not set | 696 | # CONFIG_SENSORS_W83L785TS is not set |
664 | # CONFIG_SENSORS_W83627HF is not set | 697 | # CONFIG_SENSORS_W83627HF is not set |
698 | # CONFIG_SENSORS_W83627EHF is not set | ||
665 | 699 | ||
666 | # | 700 | # |
667 | # Other I2C Chip support | 701 | # Other I2C Chip support |
668 | # | 702 | # |
703 | # CONFIG_SENSORS_DS1337 is not set | ||
704 | # CONFIG_SENSORS_DS1374 is not set | ||
669 | CONFIG_SENSORS_EEPROM=y | 705 | CONFIG_SENSORS_EEPROM=y |
670 | # CONFIG_SENSORS_PCF8574 is not set | 706 | # CONFIG_SENSORS_PCF8574 is not set |
707 | # CONFIG_SENSORS_PCA9539 is not set | ||
671 | # CONFIG_SENSORS_PCF8591 is not set | 708 | # CONFIG_SENSORS_PCF8591 is not set |
672 | # CONFIG_SENSORS_RTC8564 is not set | 709 | # CONFIG_SENSORS_RTC8564 is not set |
710 | # CONFIG_SENSORS_MAX6875 is not set | ||
673 | # CONFIG_I2C_DEBUG_CORE is not set | 711 | # CONFIG_I2C_DEBUG_CORE is not set |
674 | # CONFIG_I2C_DEBUG_ALGO is not set | 712 | # CONFIG_I2C_DEBUG_ALGO is not set |
675 | # CONFIG_I2C_DEBUG_BUS is not set | 713 | # CONFIG_I2C_DEBUG_BUS is not set |
@@ -723,6 +761,7 @@ CONFIG_EXT2_FS=y | |||
723 | CONFIG_EXT2_FS_XATTR=y | 761 | CONFIG_EXT2_FS_XATTR=y |
724 | CONFIG_EXT2_FS_POSIX_ACL=y | 762 | CONFIG_EXT2_FS_POSIX_ACL=y |
725 | # CONFIG_EXT2_FS_SECURITY is not set | 763 | # CONFIG_EXT2_FS_SECURITY is not set |
764 | # CONFIG_EXT2_FS_XIP is not set | ||
726 | CONFIG_EXT3_FS=y | 765 | CONFIG_EXT3_FS=y |
727 | CONFIG_EXT3_FS_XATTR=y | 766 | CONFIG_EXT3_FS_XATTR=y |
728 | CONFIG_EXT3_FS_POSIX_ACL=y | 767 | CONFIG_EXT3_FS_POSIX_ACL=y |
@@ -763,7 +802,6 @@ CONFIG_DNOTIFY=y | |||
763 | # | 802 | # |
764 | CONFIG_PROC_FS=y | 803 | CONFIG_PROC_FS=y |
765 | CONFIG_SYSFS=y | 804 | CONFIG_SYSFS=y |
766 | # CONFIG_DEVFS_FS is not set | ||
767 | # CONFIG_DEVPTS_FS_XATTR is not set | 805 | # CONFIG_DEVPTS_FS_XATTR is not set |
768 | CONFIG_TMPFS=y | 806 | CONFIG_TMPFS=y |
769 | # CONFIG_TMPFS_XATTR is not set | 807 | # CONFIG_TMPFS_XATTR is not set |
@@ -801,12 +839,14 @@ CONFIG_JFFS2_RTIME=y | |||
801 | # | 839 | # |
802 | CONFIG_NFS_FS=y | 840 | CONFIG_NFS_FS=y |
803 | CONFIG_NFS_V3=y | 841 | CONFIG_NFS_V3=y |
842 | # CONFIG_NFS_V3_ACL is not set | ||
804 | # CONFIG_NFS_V4 is not set | 843 | # CONFIG_NFS_V4 is not set |
805 | # CONFIG_NFS_DIRECTIO is not set | 844 | # CONFIG_NFS_DIRECTIO is not set |
806 | # CONFIG_NFSD is not set | 845 | # CONFIG_NFSD is not set |
807 | CONFIG_ROOT_NFS=y | 846 | CONFIG_ROOT_NFS=y |
808 | CONFIG_LOCKD=y | 847 | CONFIG_LOCKD=y |
809 | CONFIG_LOCKD_V4=y | 848 | CONFIG_LOCKD_V4=y |
849 | CONFIG_NFS_COMMON=y | ||
810 | CONFIG_SUNRPC=y | 850 | CONFIG_SUNRPC=y |
811 | # CONFIG_RPCSEC_GSS_KRB5 is not set | 851 | # CONFIG_RPCSEC_GSS_KRB5 is not set |
812 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | 852 | # CONFIG_RPCSEC_GSS_SPKM3 is not set |
@@ -891,3 +931,4 @@ CONFIG_CRC32=y | |||
891 | # CONFIG_LIBCRC32C is not set | 931 | # CONFIG_LIBCRC32C is not set |
892 | CONFIG_ZLIB_INFLATE=y | 932 | CONFIG_ZLIB_INFLATE=y |
893 | CONFIG_ZLIB_DEFLATE=y | 933 | CONFIG_ZLIB_DEFLATE=y |
934 | # CONFIG_TEXTSEARCH is not set | ||
diff --git a/arch/arm/configs/ixdp2400_defconfig b/arch/arm/configs/ixdp2400_defconfig index 810a450a55d2..3cfbe2ec29ca 100644 --- a/arch/arm/configs/ixdp2400_defconfig +++ b/arch/arm/configs/ixdp2400_defconfig | |||
@@ -1,14 +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.12-rc1-bk2 | 3 | # Linux kernel version: 2.6.12-git6 |
4 | # Sun Mar 27 21:13:38 2005 | 4 | # Sat Jun 25 00:58:38 2005 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
8 | CONFIG_UID16=y | 8 | CONFIG_UID16=y |
9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
10 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 10 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
11 | CONFIG_GENERIC_IOMAP=y | ||
12 | 11 | ||
13 | # | 12 | # |
14 | # Code maturity level options | 13 | # Code maturity level options |
@@ -16,6 +15,7 @@ CONFIG_GENERIC_IOMAP=y | |||
16 | CONFIG_EXPERIMENTAL=y | 15 | CONFIG_EXPERIMENTAL=y |
17 | CONFIG_CLEAN_COMPILE=y | 16 | CONFIG_CLEAN_COMPILE=y |
18 | CONFIG_BROKEN_ON_SMP=y | 17 | CONFIG_BROKEN_ON_SMP=y |
18 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
19 | 19 | ||
20 | # | 20 | # |
21 | # General setup | 21 | # General setup |
@@ -35,6 +35,8 @@ CONFIG_EMBEDDED=y | |||
35 | CONFIG_KALLSYMS=y | 35 | CONFIG_KALLSYMS=y |
36 | # CONFIG_KALLSYMS_ALL is not set | 36 | # CONFIG_KALLSYMS_ALL is not set |
37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
38 | CONFIG_PRINTK=y | ||
39 | CONFIG_BUG=y | ||
38 | CONFIG_BASE_FULL=y | 40 | CONFIG_BASE_FULL=y |
39 | CONFIG_FUTEX=y | 41 | CONFIG_FUTEX=y |
40 | CONFIG_EPOLL=y | 42 | CONFIG_EPOLL=y |
@@ -82,6 +84,7 @@ CONFIG_ARCH_IXP2000=y | |||
82 | # CONFIG_ARCH_VERSATILE is not set | 84 | # CONFIG_ARCH_VERSATILE is not set |
83 | # CONFIG_ARCH_IMX is not set | 85 | # CONFIG_ARCH_IMX is not set |
84 | # CONFIG_ARCH_H720X is not set | 86 | # CONFIG_ARCH_H720X is not set |
87 | # CONFIG_ARCH_AAEC2000 is not set | ||
85 | CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y | 88 | CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y |
86 | 89 | ||
87 | # | 90 | # |
@@ -97,6 +100,7 @@ CONFIG_ARCH_IXDP2400=y | |||
97 | CONFIG_ARCH_IXDP2X00=y | 100 | CONFIG_ARCH_IXDP2X00=y |
98 | # CONFIG_ARCH_IXDP2401 is not set | 101 | # CONFIG_ARCH_IXDP2401 is not set |
99 | # CONFIG_ARCH_IXDP2801 is not set | 102 | # CONFIG_ARCH_IXDP2801 is not set |
103 | # CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set | ||
100 | 104 | ||
101 | # | 105 | # |
102 | # Processor Type | 106 | # Processor Type |
@@ -107,7 +111,6 @@ CONFIG_CPU_32v5=y | |||
107 | CONFIG_CPU_ABRT_EV5T=y | 111 | CONFIG_CPU_ABRT_EV5T=y |
108 | CONFIG_CPU_CACHE_VIVT=y | 112 | CONFIG_CPU_CACHE_VIVT=y |
109 | CONFIG_CPU_TLB_V4WBI=y | 113 | CONFIG_CPU_TLB_V4WBI=y |
110 | CONFIG_CPU_MINICACHE=y | ||
111 | 114 | ||
112 | # | 115 | # |
113 | # Processor Features | 116 | # Processor Features |
@@ -119,9 +122,11 @@ CONFIG_XSCALE_PMU=y | |||
119 | # | 122 | # |
120 | # Bus support | 123 | # Bus support |
121 | # | 124 | # |
125 | CONFIG_ISA_DMA_API=y | ||
122 | CONFIG_PCI=y | 126 | CONFIG_PCI=y |
123 | CONFIG_PCI_LEGACY_PROC=y | 127 | CONFIG_PCI_LEGACY_PROC=y |
124 | CONFIG_PCI_NAMES=y | 128 | CONFIG_PCI_NAMES=y |
129 | # CONFIG_PCI_DEBUG is not set | ||
125 | 130 | ||
126 | # | 131 | # |
127 | # PCCARD (PCMCIA/CardBus) support | 132 | # PCCARD (PCMCIA/CardBus) support |
@@ -131,7 +136,15 @@ CONFIG_PCI_NAMES=y | |||
131 | # | 136 | # |
132 | # Kernel Features | 137 | # Kernel Features |
133 | # | 138 | # |
139 | # CONFIG_SMP is not set | ||
134 | # CONFIG_PREEMPT is not set | 140 | # CONFIG_PREEMPT is not set |
141 | # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set | ||
142 | CONFIG_SELECT_MEMORY_MODEL=y | ||
143 | CONFIG_FLATMEM_MANUAL=y | ||
144 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
145 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
146 | CONFIG_FLATMEM=y | ||
147 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
135 | CONFIG_ALIGNMENT_TRAP=y | 148 | CONFIG_ALIGNMENT_TRAP=y |
136 | 149 | ||
137 | # | 150 | # |
@@ -270,7 +283,6 @@ CONFIG_MTD_IXP2000=y | |||
270 | # | 283 | # |
271 | # Block devices | 284 | # Block devices |
272 | # | 285 | # |
273 | # CONFIG_BLK_DEV_FD is not set | ||
274 | # CONFIG_BLK_CPQ_DA is not set | 286 | # CONFIG_BLK_CPQ_DA is not set |
275 | # CONFIG_BLK_CPQ_CISS_DA is not set | 287 | # CONFIG_BLK_CPQ_CISS_DA is not set |
276 | # CONFIG_BLK_DEV_DAC960 is not set | 288 | # CONFIG_BLK_DEV_DAC960 is not set |
@@ -309,6 +321,7 @@ CONFIG_IOSCHED_CFQ=y | |||
309 | # | 321 | # |
310 | # Fusion MPT device support | 322 | # Fusion MPT device support |
311 | # | 323 | # |
324 | # CONFIG_FUSION is not set | ||
312 | 325 | ||
313 | # | 326 | # |
314 | # IEEE 1394 (FireWire) support | 327 | # IEEE 1394 (FireWire) support |
@@ -330,10 +343,11 @@ CONFIG_NET=y | |||
330 | # | 343 | # |
331 | CONFIG_PACKET=y | 344 | CONFIG_PACKET=y |
332 | CONFIG_PACKET_MMAP=y | 345 | CONFIG_PACKET_MMAP=y |
333 | # CONFIG_NETLINK_DEV is not set | ||
334 | CONFIG_UNIX=y | 346 | CONFIG_UNIX=y |
335 | # CONFIG_NET_KEY is not set | 347 | # CONFIG_NET_KEY is not set |
336 | CONFIG_INET=y | 348 | CONFIG_INET=y |
349 | CONFIG_IP_FIB_HASH=y | ||
350 | # CONFIG_IP_FIB_TRIE is not set | ||
337 | # CONFIG_IP_MULTICAST is not set | 351 | # CONFIG_IP_MULTICAST is not set |
338 | # CONFIG_IP_ADVANCED_ROUTER is not set | 352 | # CONFIG_IP_ADVANCED_ROUTER is not set |
339 | CONFIG_IP_PNP=y | 353 | CONFIG_IP_PNP=y |
@@ -350,6 +364,17 @@ CONFIG_SYN_COOKIES=y | |||
350 | # CONFIG_INET_TUNNEL is not set | 364 | # CONFIG_INET_TUNNEL is not set |
351 | # CONFIG_IP_TCPDIAG is not set | 365 | # CONFIG_IP_TCPDIAG is not set |
352 | # CONFIG_IP_TCPDIAG_IPV6 is not set | 366 | # CONFIG_IP_TCPDIAG_IPV6 is not set |
367 | |||
368 | # | ||
369 | # TCP congestion control | ||
370 | # | ||
371 | CONFIG_TCP_CONG_BIC=y | ||
372 | CONFIG_TCP_CONG_WESTWOOD=m | ||
373 | CONFIG_TCP_CONG_HTCP=m | ||
374 | # CONFIG_TCP_CONG_HSTCP is not set | ||
375 | # CONFIG_TCP_CONG_HYBLA is not set | ||
376 | # CONFIG_TCP_CONG_VEGAS is not set | ||
377 | # CONFIG_TCP_CONG_SCALABLE is not set | ||
353 | # CONFIG_IPV6 is not set | 378 | # CONFIG_IPV6 is not set |
354 | # CONFIG_NETFILTER is not set | 379 | # CONFIG_NETFILTER is not set |
355 | 380 | ||
@@ -405,6 +430,7 @@ CONFIG_MII=y | |||
405 | # CONFIG_SUNGEM is not set | 430 | # CONFIG_SUNGEM is not set |
406 | # CONFIG_NET_VENDOR_3COM is not set | 431 | # CONFIG_NET_VENDOR_3COM is not set |
407 | # CONFIG_SMC91X is not set | 432 | # CONFIG_SMC91X is not set |
433 | # CONFIG_DM9000 is not set | ||
408 | 434 | ||
409 | # | 435 | # |
410 | # Tulip family network device support | 436 | # Tulip family network device support |
@@ -441,9 +467,11 @@ CONFIG_EEPRO100=y | |||
441 | # CONFIG_HAMACHI is not set | 467 | # CONFIG_HAMACHI is not set |
442 | # CONFIG_YELLOWFIN is not set | 468 | # CONFIG_YELLOWFIN is not set |
443 | # CONFIG_R8169 is not set | 469 | # CONFIG_R8169 is not set |
470 | # CONFIG_SKGE is not set | ||
444 | # CONFIG_SK98LIN is not set | 471 | # CONFIG_SK98LIN is not set |
445 | # CONFIG_VIA_VELOCITY is not set | 472 | # CONFIG_VIA_VELOCITY is not set |
446 | # CONFIG_TIGON3 is not set | 473 | # CONFIG_TIGON3 is not set |
474 | # CONFIG_BNX2 is not set | ||
447 | 475 | ||
448 | # | 476 | # |
449 | # Ethernet (10000 Mbit) | 477 | # Ethernet (10000 Mbit) |
@@ -465,6 +493,7 @@ CONFIG_EEPRO100=y | |||
465 | # Wan interfaces | 493 | # Wan interfaces |
466 | # | 494 | # |
467 | CONFIG_WAN=y | 495 | CONFIG_WAN=y |
496 | # CONFIG_DSCC4 is not set | ||
468 | # CONFIG_LANMEDIA is not set | 497 | # CONFIG_LANMEDIA is not set |
469 | # CONFIG_SYNCLINK_SYNCPPP is not set | 498 | # CONFIG_SYNCLINK_SYNCPPP is not set |
470 | CONFIG_HDLC=y | 499 | CONFIG_HDLC=y |
@@ -527,7 +556,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | |||
527 | # | 556 | # |
528 | # CONFIG_SERIO is not set | 557 | # CONFIG_SERIO is not set |
529 | # CONFIG_GAMEPORT is not set | 558 | # CONFIG_GAMEPORT is not set |
530 | CONFIG_SOUND_GAMEPORT=y | ||
531 | 559 | ||
532 | # | 560 | # |
533 | # Character devices | 561 | # Character devices |
@@ -548,6 +576,7 @@ CONFIG_SERIAL_8250_NR_UARTS=2 | |||
548 | # | 576 | # |
549 | CONFIG_SERIAL_CORE=y | 577 | CONFIG_SERIAL_CORE=y |
550 | CONFIG_SERIAL_CORE_CONSOLE=y | 578 | CONFIG_SERIAL_CORE_CONSOLE=y |
579 | # CONFIG_SERIAL_JSM is not set | ||
551 | CONFIG_UNIX98_PTYS=y | 580 | CONFIG_UNIX98_PTYS=y |
552 | CONFIG_LEGACY_PTYS=y | 581 | CONFIG_LEGACY_PTYS=y |
553 | CONFIG_LEGACY_PTY_COUNT=256 | 582 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -614,17 +643,18 @@ CONFIG_I2C_ALGOBIT=y | |||
614 | # CONFIG_I2C_AMD8111 is not set | 643 | # CONFIG_I2C_AMD8111 is not set |
615 | # CONFIG_I2C_I801 is not set | 644 | # CONFIG_I2C_I801 is not set |
616 | # CONFIG_I2C_I810 is not set | 645 | # CONFIG_I2C_I810 is not set |
646 | # CONFIG_I2C_PIIX4 is not set | ||
617 | # CONFIG_I2C_ISA is not set | 647 | # CONFIG_I2C_ISA is not set |
618 | # CONFIG_I2C_IXP2000 is not set | 648 | # CONFIG_I2C_IXP2000 is not set |
619 | # CONFIG_I2C_NFORCE2 is not set | 649 | # CONFIG_I2C_NFORCE2 is not set |
620 | # CONFIG_I2C_PARPORT_LIGHT is not set | 650 | # CONFIG_I2C_PARPORT_LIGHT is not set |
621 | # CONFIG_I2C_PIIX4 is not set | ||
622 | # CONFIG_I2C_PROSAVAGE is not set | 651 | # CONFIG_I2C_PROSAVAGE is not set |
623 | # CONFIG_I2C_SAVAGE4 is not set | 652 | # CONFIG_I2C_SAVAGE4 is not set |
624 | # CONFIG_SCx200_ACB is not set | 653 | # CONFIG_SCx200_ACB is not set |
625 | # CONFIG_I2C_SIS5595 is not set | 654 | # CONFIG_I2C_SIS5595 is not set |
626 | # CONFIG_I2C_SIS630 is not set | 655 | # CONFIG_I2C_SIS630 is not set |
627 | # CONFIG_I2C_SIS96X is not set | 656 | # CONFIG_I2C_SIS96X is not set |
657 | # CONFIG_I2C_STUB is not set | ||
628 | # CONFIG_I2C_VIA is not set | 658 | # CONFIG_I2C_VIA is not set |
629 | # CONFIG_I2C_VIAPRO is not set | 659 | # CONFIG_I2C_VIAPRO is not set |
630 | # CONFIG_I2C_VOODOO3 is not set | 660 | # CONFIG_I2C_VOODOO3 is not set |
@@ -638,7 +668,9 @@ CONFIG_I2C_SENSOR=y | |||
638 | # CONFIG_SENSORS_ADM1025 is not set | 668 | # CONFIG_SENSORS_ADM1025 is not set |
639 | # CONFIG_SENSORS_ADM1026 is not set | 669 | # CONFIG_SENSORS_ADM1026 is not set |
640 | # CONFIG_SENSORS_ADM1031 is not set | 670 | # CONFIG_SENSORS_ADM1031 is not set |
671 | # CONFIG_SENSORS_ADM9240 is not set | ||
641 | # CONFIG_SENSORS_ASB100 is not set | 672 | # CONFIG_SENSORS_ASB100 is not set |
673 | # CONFIG_SENSORS_ATXP1 is not set | ||
642 | # CONFIG_SENSORS_DS1621 is not set | 674 | # CONFIG_SENSORS_DS1621 is not set |
643 | # CONFIG_SENSORS_FSCHER is not set | 675 | # CONFIG_SENSORS_FSCHER is not set |
644 | # CONFIG_SENSORS_FSCPOS is not set | 676 | # CONFIG_SENSORS_FSCPOS is not set |
@@ -654,6 +686,7 @@ CONFIG_I2C_SENSOR=y | |||
654 | # CONFIG_SENSORS_LM85 is not set | 686 | # CONFIG_SENSORS_LM85 is not set |
655 | # CONFIG_SENSORS_LM87 is not set | 687 | # CONFIG_SENSORS_LM87 is not set |
656 | # CONFIG_SENSORS_LM90 is not set | 688 | # CONFIG_SENSORS_LM90 is not set |
689 | # CONFIG_SENSORS_LM92 is not set | ||
657 | # CONFIG_SENSORS_MAX1619 is not set | 690 | # CONFIG_SENSORS_MAX1619 is not set |
658 | # CONFIG_SENSORS_PC87360 is not set | 691 | # CONFIG_SENSORS_PC87360 is not set |
659 | # CONFIG_SENSORS_SMSC47B397 is not set | 692 | # CONFIG_SENSORS_SMSC47B397 is not set |
@@ -663,14 +696,19 @@ CONFIG_I2C_SENSOR=y | |||
663 | # CONFIG_SENSORS_W83781D is not set | 696 | # CONFIG_SENSORS_W83781D is not set |
664 | # CONFIG_SENSORS_W83L785TS is not set | 697 | # CONFIG_SENSORS_W83L785TS is not set |
665 | # CONFIG_SENSORS_W83627HF is not set | 698 | # CONFIG_SENSORS_W83627HF is not set |
699 | # CONFIG_SENSORS_W83627EHF is not set | ||
666 | 700 | ||
667 | # | 701 | # |
668 | # Other I2C Chip support | 702 | # Other I2C Chip support |
669 | # | 703 | # |
704 | # CONFIG_SENSORS_DS1337 is not set | ||
705 | # CONFIG_SENSORS_DS1374 is not set | ||
670 | CONFIG_SENSORS_EEPROM=y | 706 | CONFIG_SENSORS_EEPROM=y |
671 | # CONFIG_SENSORS_PCF8574 is not set | 707 | # CONFIG_SENSORS_PCF8574 is not set |
708 | # CONFIG_SENSORS_PCA9539 is not set | ||
672 | # CONFIG_SENSORS_PCF8591 is not set | 709 | # CONFIG_SENSORS_PCF8591 is not set |
673 | # CONFIG_SENSORS_RTC8564 is not set | 710 | # CONFIG_SENSORS_RTC8564 is not set |
711 | # CONFIG_SENSORS_MAX6875 is not set | ||
674 | # CONFIG_I2C_DEBUG_CORE is not set | 712 | # CONFIG_I2C_DEBUG_CORE is not set |
675 | # CONFIG_I2C_DEBUG_ALGO is not set | 713 | # CONFIG_I2C_DEBUG_ALGO is not set |
676 | # CONFIG_I2C_DEBUG_BUS is not set | 714 | # CONFIG_I2C_DEBUG_BUS is not set |
@@ -724,6 +762,7 @@ CONFIG_EXT2_FS=y | |||
724 | CONFIG_EXT2_FS_XATTR=y | 762 | CONFIG_EXT2_FS_XATTR=y |
725 | CONFIG_EXT2_FS_POSIX_ACL=y | 763 | CONFIG_EXT2_FS_POSIX_ACL=y |
726 | # CONFIG_EXT2_FS_SECURITY is not set | 764 | # CONFIG_EXT2_FS_SECURITY is not set |
765 | # CONFIG_EXT2_FS_XIP is not set | ||
727 | CONFIG_EXT3_FS=y | 766 | CONFIG_EXT3_FS=y |
728 | CONFIG_EXT3_FS_XATTR=y | 767 | CONFIG_EXT3_FS_XATTR=y |
729 | CONFIG_EXT3_FS_POSIX_ACL=y | 768 | CONFIG_EXT3_FS_POSIX_ACL=y |
@@ -764,7 +803,6 @@ CONFIG_DNOTIFY=y | |||
764 | # | 803 | # |
765 | CONFIG_PROC_FS=y | 804 | CONFIG_PROC_FS=y |
766 | CONFIG_SYSFS=y | 805 | CONFIG_SYSFS=y |
767 | # CONFIG_DEVFS_FS is not set | ||
768 | # CONFIG_DEVPTS_FS_XATTR is not set | 806 | # CONFIG_DEVPTS_FS_XATTR is not set |
769 | CONFIG_TMPFS=y | 807 | CONFIG_TMPFS=y |
770 | # CONFIG_TMPFS_XATTR is not set | 808 | # CONFIG_TMPFS_XATTR is not set |
@@ -802,12 +840,14 @@ CONFIG_JFFS2_RTIME=y | |||
802 | # | 840 | # |
803 | CONFIG_NFS_FS=y | 841 | CONFIG_NFS_FS=y |
804 | CONFIG_NFS_V3=y | 842 | CONFIG_NFS_V3=y |
843 | # CONFIG_NFS_V3_ACL is not set | ||
805 | # CONFIG_NFS_V4 is not set | 844 | # CONFIG_NFS_V4 is not set |
806 | # CONFIG_NFS_DIRECTIO is not set | 845 | # CONFIG_NFS_DIRECTIO is not set |
807 | # CONFIG_NFSD is not set | 846 | # CONFIG_NFSD is not set |
808 | CONFIG_ROOT_NFS=y | 847 | CONFIG_ROOT_NFS=y |
809 | CONFIG_LOCKD=y | 848 | CONFIG_LOCKD=y |
810 | CONFIG_LOCKD_V4=y | 849 | CONFIG_LOCKD_V4=y |
850 | CONFIG_NFS_COMMON=y | ||
811 | CONFIG_SUNRPC=y | 851 | CONFIG_SUNRPC=y |
812 | # CONFIG_RPCSEC_GSS_KRB5 is not set | 852 | # CONFIG_RPCSEC_GSS_KRB5 is not set |
813 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | 853 | # CONFIG_RPCSEC_GSS_SPKM3 is not set |
@@ -892,3 +932,4 @@ CONFIG_CRC32=y | |||
892 | # CONFIG_LIBCRC32C is not set | 932 | # CONFIG_LIBCRC32C is not set |
893 | CONFIG_ZLIB_INFLATE=y | 933 | CONFIG_ZLIB_INFLATE=y |
894 | CONFIG_ZLIB_DEFLATE=y | 934 | CONFIG_ZLIB_DEFLATE=y |
935 | # CONFIG_TEXTSEARCH is not set | ||
diff --git a/arch/arm/configs/ixdp2401_defconfig b/arch/arm/configs/ixdp2401_defconfig index 72e1b940e975..5c87e8e6969b 100644 --- a/arch/arm/configs/ixdp2401_defconfig +++ b/arch/arm/configs/ixdp2401_defconfig | |||
@@ -1,14 +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.12-rc1-bk2 | 3 | # Linux kernel version: 2.6.12-git6 |
4 | # Sun Mar 27 21:53:55 2005 | 4 | # Sat Jun 25 00:59:35 2005 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
8 | CONFIG_UID16=y | 8 | CONFIG_UID16=y |
9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
10 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 10 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
11 | CONFIG_GENERIC_IOMAP=y | ||
12 | 11 | ||
13 | # | 12 | # |
14 | # Code maturity level options | 13 | # Code maturity level options |
@@ -16,6 +15,7 @@ CONFIG_GENERIC_IOMAP=y | |||
16 | CONFIG_EXPERIMENTAL=y | 15 | CONFIG_EXPERIMENTAL=y |
17 | CONFIG_CLEAN_COMPILE=y | 16 | CONFIG_CLEAN_COMPILE=y |
18 | CONFIG_BROKEN_ON_SMP=y | 17 | CONFIG_BROKEN_ON_SMP=y |
18 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
19 | 19 | ||
20 | # | 20 | # |
21 | # General setup | 21 | # General setup |
@@ -35,6 +35,8 @@ CONFIG_EMBEDDED=y | |||
35 | CONFIG_KALLSYMS=y | 35 | CONFIG_KALLSYMS=y |
36 | # CONFIG_KALLSYMS_ALL is not set | 36 | # CONFIG_KALLSYMS_ALL is not set |
37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
38 | CONFIG_PRINTK=y | ||
39 | CONFIG_BUG=y | ||
38 | CONFIG_BASE_FULL=y | 40 | CONFIG_BASE_FULL=y |
39 | CONFIG_FUTEX=y | 41 | CONFIG_FUTEX=y |
40 | CONFIG_EPOLL=y | 42 | CONFIG_EPOLL=y |
@@ -82,6 +84,7 @@ CONFIG_ARCH_IXP2000=y | |||
82 | # CONFIG_ARCH_VERSATILE is not set | 84 | # CONFIG_ARCH_VERSATILE is not set |
83 | # CONFIG_ARCH_IMX is not set | 85 | # CONFIG_ARCH_IMX is not set |
84 | # CONFIG_ARCH_H720X is not set | 86 | # CONFIG_ARCH_H720X is not set |
87 | # CONFIG_ARCH_AAEC2000 is not set | ||
85 | CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y | 88 | CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y |
86 | 89 | ||
87 | # | 90 | # |
@@ -97,6 +100,7 @@ CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y | |||
97 | CONFIG_ARCH_IXDP2401=y | 100 | CONFIG_ARCH_IXDP2401=y |
98 | # CONFIG_ARCH_IXDP2801 is not set | 101 | # CONFIG_ARCH_IXDP2801 is not set |
99 | CONFIG_ARCH_IXDP2X01=y | 102 | CONFIG_ARCH_IXDP2X01=y |
103 | # CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set | ||
100 | 104 | ||
101 | # | 105 | # |
102 | # Processor Type | 106 | # Processor Type |
@@ -107,7 +111,6 @@ CONFIG_CPU_32v5=y | |||
107 | CONFIG_CPU_ABRT_EV5T=y | 111 | CONFIG_CPU_ABRT_EV5T=y |
108 | CONFIG_CPU_CACHE_VIVT=y | 112 | CONFIG_CPU_CACHE_VIVT=y |
109 | CONFIG_CPU_TLB_V4WBI=y | 113 | CONFIG_CPU_TLB_V4WBI=y |
110 | CONFIG_CPU_MINICACHE=y | ||
111 | 114 | ||
112 | # | 115 | # |
113 | # Processor Features | 116 | # Processor Features |
@@ -119,9 +122,11 @@ CONFIG_XSCALE_PMU=y | |||
119 | # | 122 | # |
120 | # Bus support | 123 | # Bus support |
121 | # | 124 | # |
125 | CONFIG_ISA_DMA_API=y | ||
122 | CONFIG_PCI=y | 126 | CONFIG_PCI=y |
123 | CONFIG_PCI_LEGACY_PROC=y | 127 | CONFIG_PCI_LEGACY_PROC=y |
124 | CONFIG_PCI_NAMES=y | 128 | CONFIG_PCI_NAMES=y |
129 | # CONFIG_PCI_DEBUG is not set | ||
125 | 130 | ||
126 | # | 131 | # |
127 | # PCCARD (PCMCIA/CardBus) support | 132 | # PCCARD (PCMCIA/CardBus) support |
@@ -131,7 +136,15 @@ CONFIG_PCI_NAMES=y | |||
131 | # | 136 | # |
132 | # Kernel Features | 137 | # Kernel Features |
133 | # | 138 | # |
139 | # CONFIG_SMP is not set | ||
134 | # CONFIG_PREEMPT is not set | 140 | # CONFIG_PREEMPT is not set |
141 | # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set | ||
142 | CONFIG_SELECT_MEMORY_MODEL=y | ||
143 | CONFIG_FLATMEM_MANUAL=y | ||
144 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
145 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
146 | CONFIG_FLATMEM=y | ||
147 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
135 | CONFIG_ALIGNMENT_TRAP=y | 148 | CONFIG_ALIGNMENT_TRAP=y |
136 | 149 | ||
137 | # | 150 | # |
@@ -270,7 +283,6 @@ CONFIG_MTD_IXP2000=y | |||
270 | # | 283 | # |
271 | # Block devices | 284 | # Block devices |
272 | # | 285 | # |
273 | # CONFIG_BLK_DEV_FD is not set | ||
274 | # CONFIG_BLK_CPQ_DA is not set | 286 | # CONFIG_BLK_CPQ_DA is not set |
275 | # CONFIG_BLK_CPQ_CISS_DA is not set | 287 | # CONFIG_BLK_CPQ_CISS_DA is not set |
276 | # CONFIG_BLK_DEV_DAC960 is not set | 288 | # CONFIG_BLK_DEV_DAC960 is not set |
@@ -309,6 +321,7 @@ CONFIG_IOSCHED_CFQ=y | |||
309 | # | 321 | # |
310 | # Fusion MPT device support | 322 | # Fusion MPT device support |
311 | # | 323 | # |
324 | # CONFIG_FUSION is not set | ||
312 | 325 | ||
313 | # | 326 | # |
314 | # IEEE 1394 (FireWire) support | 327 | # IEEE 1394 (FireWire) support |
@@ -330,10 +343,11 @@ CONFIG_NET=y | |||
330 | # | 343 | # |
331 | CONFIG_PACKET=y | 344 | CONFIG_PACKET=y |
332 | CONFIG_PACKET_MMAP=y | 345 | CONFIG_PACKET_MMAP=y |
333 | # CONFIG_NETLINK_DEV is not set | ||
334 | CONFIG_UNIX=y | 346 | CONFIG_UNIX=y |
335 | # CONFIG_NET_KEY is not set | 347 | # CONFIG_NET_KEY is not set |
336 | CONFIG_INET=y | 348 | CONFIG_INET=y |
349 | CONFIG_IP_FIB_HASH=y | ||
350 | # CONFIG_IP_FIB_TRIE is not set | ||
337 | # CONFIG_IP_MULTICAST is not set | 351 | # CONFIG_IP_MULTICAST is not set |
338 | # CONFIG_IP_ADVANCED_ROUTER is not set | 352 | # CONFIG_IP_ADVANCED_ROUTER is not set |
339 | CONFIG_IP_PNP=y | 353 | CONFIG_IP_PNP=y |
@@ -350,6 +364,17 @@ CONFIG_SYN_COOKIES=y | |||
350 | # CONFIG_INET_TUNNEL is not set | 364 | # CONFIG_INET_TUNNEL is not set |
351 | CONFIG_IP_TCPDIAG=y | 365 | CONFIG_IP_TCPDIAG=y |
352 | # CONFIG_IP_TCPDIAG_IPV6 is not set | 366 | # CONFIG_IP_TCPDIAG_IPV6 is not set |
367 | |||
368 | # | ||
369 | # TCP congestion control | ||
370 | # | ||
371 | CONFIG_TCP_CONG_BIC=y | ||
372 | CONFIG_TCP_CONG_WESTWOOD=m | ||
373 | CONFIG_TCP_CONG_HTCP=m | ||
374 | # CONFIG_TCP_CONG_HSTCP is not set | ||
375 | # CONFIG_TCP_CONG_HYBLA is not set | ||
376 | # CONFIG_TCP_CONG_VEGAS is not set | ||
377 | # CONFIG_TCP_CONG_SCALABLE is not set | ||
353 | # CONFIG_IPV6 is not set | 378 | # CONFIG_IPV6 is not set |
354 | # CONFIG_NETFILTER is not set | 379 | # CONFIG_NETFILTER is not set |
355 | 380 | ||
@@ -405,6 +430,7 @@ CONFIG_MII=y | |||
405 | # CONFIG_SUNGEM is not set | 430 | # CONFIG_SUNGEM is not set |
406 | # CONFIG_NET_VENDOR_3COM is not set | 431 | # CONFIG_NET_VENDOR_3COM is not set |
407 | # CONFIG_SMC91X is not set | 432 | # CONFIG_SMC91X is not set |
433 | # CONFIG_DM9000 is not set | ||
408 | 434 | ||
409 | # | 435 | # |
410 | # Tulip family network device support | 436 | # Tulip family network device support |
@@ -442,9 +468,11 @@ CONFIG_EEPRO100=y | |||
442 | # CONFIG_HAMACHI is not set | 468 | # CONFIG_HAMACHI is not set |
443 | # CONFIG_YELLOWFIN is not set | 469 | # CONFIG_YELLOWFIN is not set |
444 | # CONFIG_R8169 is not set | 470 | # CONFIG_R8169 is not set |
471 | # CONFIG_SKGE is not set | ||
445 | # CONFIG_SK98LIN is not set | 472 | # CONFIG_SK98LIN is not set |
446 | # CONFIG_VIA_VELOCITY is not set | 473 | # CONFIG_VIA_VELOCITY is not set |
447 | # CONFIG_TIGON3 is not set | 474 | # CONFIG_TIGON3 is not set |
475 | # CONFIG_BNX2 is not set | ||
448 | 476 | ||
449 | # | 477 | # |
450 | # Ethernet (10000 Mbit) | 478 | # Ethernet (10000 Mbit) |
@@ -466,6 +494,7 @@ CONFIG_EEPRO100=y | |||
466 | # Wan interfaces | 494 | # Wan interfaces |
467 | # | 495 | # |
468 | CONFIG_WAN=y | 496 | CONFIG_WAN=y |
497 | # CONFIG_DSCC4 is not set | ||
469 | # CONFIG_LANMEDIA is not set | 498 | # CONFIG_LANMEDIA is not set |
470 | # CONFIG_SYNCLINK_SYNCPPP is not set | 499 | # CONFIG_SYNCLINK_SYNCPPP is not set |
471 | CONFIG_HDLC=y | 500 | CONFIG_HDLC=y |
@@ -528,7 +557,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | |||
528 | # | 557 | # |
529 | # CONFIG_SERIO is not set | 558 | # CONFIG_SERIO is not set |
530 | # CONFIG_GAMEPORT is not set | 559 | # CONFIG_GAMEPORT is not set |
531 | CONFIG_SOUND_GAMEPORT=y | ||
532 | 560 | ||
533 | # | 561 | # |
534 | # Character devices | 562 | # Character devices |
@@ -549,6 +577,7 @@ CONFIG_SERIAL_8250_NR_UARTS=2 | |||
549 | # | 577 | # |
550 | CONFIG_SERIAL_CORE=y | 578 | CONFIG_SERIAL_CORE=y |
551 | CONFIG_SERIAL_CORE_CONSOLE=y | 579 | CONFIG_SERIAL_CORE_CONSOLE=y |
580 | # CONFIG_SERIAL_JSM is not set | ||
552 | CONFIG_UNIX98_PTYS=y | 581 | CONFIG_UNIX98_PTYS=y |
553 | CONFIG_LEGACY_PTYS=y | 582 | CONFIG_LEGACY_PTYS=y |
554 | CONFIG_LEGACY_PTY_COUNT=256 | 583 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -615,17 +644,18 @@ CONFIG_I2C_ALGOBIT=y | |||
615 | # CONFIG_I2C_AMD8111 is not set | 644 | # CONFIG_I2C_AMD8111 is not set |
616 | # CONFIG_I2C_I801 is not set | 645 | # CONFIG_I2C_I801 is not set |
617 | # CONFIG_I2C_I810 is not set | 646 | # CONFIG_I2C_I810 is not set |
647 | # CONFIG_I2C_PIIX4 is not set | ||
618 | # CONFIG_I2C_ISA is not set | 648 | # CONFIG_I2C_ISA is not set |
619 | # CONFIG_I2C_IXP2000 is not set | 649 | # CONFIG_I2C_IXP2000 is not set |
620 | # CONFIG_I2C_NFORCE2 is not set | 650 | # CONFIG_I2C_NFORCE2 is not set |
621 | # CONFIG_I2C_PARPORT_LIGHT is not set | 651 | # CONFIG_I2C_PARPORT_LIGHT is not set |
622 | # CONFIG_I2C_PIIX4 is not set | ||
623 | # CONFIG_I2C_PROSAVAGE is not set | 652 | # CONFIG_I2C_PROSAVAGE is not set |
624 | # CONFIG_I2C_SAVAGE4 is not set | 653 | # CONFIG_I2C_SAVAGE4 is not set |
625 | # CONFIG_SCx200_ACB is not set | 654 | # CONFIG_SCx200_ACB is not set |
626 | # CONFIG_I2C_SIS5595 is not set | 655 | # CONFIG_I2C_SIS5595 is not set |
627 | # CONFIG_I2C_SIS630 is not set | 656 | # CONFIG_I2C_SIS630 is not set |
628 | # CONFIG_I2C_SIS96X is not set | 657 | # CONFIG_I2C_SIS96X is not set |
658 | # CONFIG_I2C_STUB is not set | ||
629 | # CONFIG_I2C_VIA is not set | 659 | # CONFIG_I2C_VIA is not set |
630 | # CONFIG_I2C_VIAPRO is not set | 660 | # CONFIG_I2C_VIAPRO is not set |
631 | # CONFIG_I2C_VOODOO3 is not set | 661 | # CONFIG_I2C_VOODOO3 is not set |
@@ -639,7 +669,9 @@ CONFIG_I2C_SENSOR=y | |||
639 | # CONFIG_SENSORS_ADM1025 is not set | 669 | # CONFIG_SENSORS_ADM1025 is not set |
640 | # CONFIG_SENSORS_ADM1026 is not set | 670 | # CONFIG_SENSORS_ADM1026 is not set |
641 | # CONFIG_SENSORS_ADM1031 is not set | 671 | # CONFIG_SENSORS_ADM1031 is not set |
672 | # CONFIG_SENSORS_ADM9240 is not set | ||
642 | # CONFIG_SENSORS_ASB100 is not set | 673 | # CONFIG_SENSORS_ASB100 is not set |
674 | # CONFIG_SENSORS_ATXP1 is not set | ||
643 | # CONFIG_SENSORS_DS1621 is not set | 675 | # CONFIG_SENSORS_DS1621 is not set |
644 | # CONFIG_SENSORS_FSCHER is not set | 676 | # CONFIG_SENSORS_FSCHER is not set |
645 | # CONFIG_SENSORS_FSCPOS is not set | 677 | # CONFIG_SENSORS_FSCPOS is not set |
@@ -655,6 +687,7 @@ CONFIG_I2C_SENSOR=y | |||
655 | # CONFIG_SENSORS_LM85 is not set | 687 | # CONFIG_SENSORS_LM85 is not set |
656 | # CONFIG_SENSORS_LM87 is not set | 688 | # CONFIG_SENSORS_LM87 is not set |
657 | # CONFIG_SENSORS_LM90 is not set | 689 | # CONFIG_SENSORS_LM90 is not set |
690 | # CONFIG_SENSORS_LM92 is not set | ||
658 | # CONFIG_SENSORS_MAX1619 is not set | 691 | # CONFIG_SENSORS_MAX1619 is not set |
659 | # CONFIG_SENSORS_PC87360 is not set | 692 | # CONFIG_SENSORS_PC87360 is not set |
660 | # CONFIG_SENSORS_SMSC47B397 is not set | 693 | # CONFIG_SENSORS_SMSC47B397 is not set |
@@ -664,14 +697,19 @@ CONFIG_I2C_SENSOR=y | |||
664 | # CONFIG_SENSORS_W83781D is not set | 697 | # CONFIG_SENSORS_W83781D is not set |
665 | # CONFIG_SENSORS_W83L785TS is not set | 698 | # CONFIG_SENSORS_W83L785TS is not set |
666 | # CONFIG_SENSORS_W83627HF is not set | 699 | # CONFIG_SENSORS_W83627HF is not set |
700 | # CONFIG_SENSORS_W83627EHF is not set | ||
667 | 701 | ||
668 | # | 702 | # |
669 | # Other I2C Chip support | 703 | # Other I2C Chip support |
670 | # | 704 | # |
705 | # CONFIG_SENSORS_DS1337 is not set | ||
706 | # CONFIG_SENSORS_DS1374 is not set | ||
671 | CONFIG_SENSORS_EEPROM=y | 707 | CONFIG_SENSORS_EEPROM=y |
672 | # CONFIG_SENSORS_PCF8574 is not set | 708 | # CONFIG_SENSORS_PCF8574 is not set |
709 | # CONFIG_SENSORS_PCA9539 is not set | ||
673 | # CONFIG_SENSORS_PCF8591 is not set | 710 | # CONFIG_SENSORS_PCF8591 is not set |
674 | # CONFIG_SENSORS_RTC8564 is not set | 711 | # CONFIG_SENSORS_RTC8564 is not set |
712 | # CONFIG_SENSORS_MAX6875 is not set | ||
675 | # CONFIG_I2C_DEBUG_CORE is not set | 713 | # CONFIG_I2C_DEBUG_CORE is not set |
676 | # CONFIG_I2C_DEBUG_ALGO is not set | 714 | # CONFIG_I2C_DEBUG_ALGO is not set |
677 | # CONFIG_I2C_DEBUG_BUS is not set | 715 | # CONFIG_I2C_DEBUG_BUS is not set |
@@ -725,6 +763,7 @@ CONFIG_EXT2_FS=y | |||
725 | CONFIG_EXT2_FS_XATTR=y | 763 | CONFIG_EXT2_FS_XATTR=y |
726 | CONFIG_EXT2_FS_POSIX_ACL=y | 764 | CONFIG_EXT2_FS_POSIX_ACL=y |
727 | # CONFIG_EXT2_FS_SECURITY is not set | 765 | # CONFIG_EXT2_FS_SECURITY is not set |
766 | # CONFIG_EXT2_FS_XIP is not set | ||
728 | CONFIG_EXT3_FS=y | 767 | CONFIG_EXT3_FS=y |
729 | CONFIG_EXT3_FS_XATTR=y | 768 | CONFIG_EXT3_FS_XATTR=y |
730 | CONFIG_EXT3_FS_POSIX_ACL=y | 769 | CONFIG_EXT3_FS_POSIX_ACL=y |
@@ -765,7 +804,6 @@ CONFIG_DNOTIFY=y | |||
765 | # | 804 | # |
766 | CONFIG_PROC_FS=y | 805 | CONFIG_PROC_FS=y |
767 | CONFIG_SYSFS=y | 806 | CONFIG_SYSFS=y |
768 | # CONFIG_DEVFS_FS is not set | ||
769 | # CONFIG_DEVPTS_FS_XATTR is not set | 807 | # CONFIG_DEVPTS_FS_XATTR is not set |
770 | CONFIG_TMPFS=y | 808 | CONFIG_TMPFS=y |
771 | # CONFIG_TMPFS_XATTR is not set | 809 | # CONFIG_TMPFS_XATTR is not set |
@@ -803,12 +841,14 @@ CONFIG_JFFS2_RTIME=y | |||
803 | # | 841 | # |
804 | CONFIG_NFS_FS=y | 842 | CONFIG_NFS_FS=y |
805 | CONFIG_NFS_V3=y | 843 | CONFIG_NFS_V3=y |
844 | # CONFIG_NFS_V3_ACL is not set | ||
806 | # CONFIG_NFS_V4 is not set | 845 | # CONFIG_NFS_V4 is not set |
807 | # CONFIG_NFS_DIRECTIO is not set | 846 | # CONFIG_NFS_DIRECTIO is not set |
808 | # CONFIG_NFSD is not set | 847 | # CONFIG_NFSD is not set |
809 | CONFIG_ROOT_NFS=y | 848 | CONFIG_ROOT_NFS=y |
810 | CONFIG_LOCKD=y | 849 | CONFIG_LOCKD=y |
811 | CONFIG_LOCKD_V4=y | 850 | CONFIG_LOCKD_V4=y |
851 | CONFIG_NFS_COMMON=y | ||
812 | CONFIG_SUNRPC=y | 852 | CONFIG_SUNRPC=y |
813 | # CONFIG_RPCSEC_GSS_KRB5 is not set | 853 | # CONFIG_RPCSEC_GSS_KRB5 is not set |
814 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | 854 | # CONFIG_RPCSEC_GSS_SPKM3 is not set |
@@ -893,3 +933,4 @@ CONFIG_CRC32=y | |||
893 | # CONFIG_LIBCRC32C is not set | 933 | # CONFIG_LIBCRC32C is not set |
894 | CONFIG_ZLIB_INFLATE=y | 934 | CONFIG_ZLIB_INFLATE=y |
895 | CONFIG_ZLIB_DEFLATE=y | 935 | CONFIG_ZLIB_DEFLATE=y |
936 | # CONFIG_TEXTSEARCH is not set | ||
diff --git a/arch/arm/configs/ixdp2800_defconfig b/arch/arm/configs/ixdp2800_defconfig index 1592e45f0278..3cb561a551cb 100644 --- a/arch/arm/configs/ixdp2800_defconfig +++ b/arch/arm/configs/ixdp2800_defconfig | |||
@@ -1,14 +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.12-rc1-bk2 | 3 | # Linux kernel version: 2.6.12-git6 |
4 | # Sun Mar 27 22:15:23 2005 | 4 | # Sat Jun 25 01:00:27 2005 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
8 | CONFIG_UID16=y | 8 | CONFIG_UID16=y |
9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
10 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 10 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
11 | CONFIG_GENERIC_IOMAP=y | ||
12 | 11 | ||
13 | # | 12 | # |
14 | # Code maturity level options | 13 | # Code maturity level options |
@@ -16,6 +15,7 @@ CONFIG_GENERIC_IOMAP=y | |||
16 | CONFIG_EXPERIMENTAL=y | 15 | CONFIG_EXPERIMENTAL=y |
17 | CONFIG_CLEAN_COMPILE=y | 16 | CONFIG_CLEAN_COMPILE=y |
18 | CONFIG_BROKEN_ON_SMP=y | 17 | CONFIG_BROKEN_ON_SMP=y |
18 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
19 | 19 | ||
20 | # | 20 | # |
21 | # General setup | 21 | # General setup |
@@ -35,6 +35,8 @@ CONFIG_EMBEDDED=y | |||
35 | CONFIG_KALLSYMS=y | 35 | CONFIG_KALLSYMS=y |
36 | # CONFIG_KALLSYMS_ALL is not set | 36 | # CONFIG_KALLSYMS_ALL is not set |
37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
38 | CONFIG_PRINTK=y | ||
39 | CONFIG_BUG=y | ||
38 | CONFIG_BASE_FULL=y | 40 | CONFIG_BASE_FULL=y |
39 | CONFIG_FUTEX=y | 41 | CONFIG_FUTEX=y |
40 | CONFIG_EPOLL=y | 42 | CONFIG_EPOLL=y |
@@ -82,6 +84,7 @@ CONFIG_ARCH_IXP2000=y | |||
82 | # CONFIG_ARCH_VERSATILE is not set | 84 | # CONFIG_ARCH_VERSATILE is not set |
83 | # CONFIG_ARCH_IMX is not set | 85 | # CONFIG_ARCH_IMX is not set |
84 | # CONFIG_ARCH_H720X is not set | 86 | # CONFIG_ARCH_H720X is not set |
87 | # CONFIG_ARCH_AAEC2000 is not set | ||
85 | CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y | 88 | CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y |
86 | 89 | ||
87 | # | 90 | # |
@@ -97,6 +100,7 @@ CONFIG_ARCH_IXDP2800=y | |||
97 | CONFIG_ARCH_IXDP2X00=y | 100 | CONFIG_ARCH_IXDP2X00=y |
98 | # CONFIG_ARCH_IXDP2401 is not set | 101 | # CONFIG_ARCH_IXDP2401 is not set |
99 | # CONFIG_ARCH_IXDP2801 is not set | 102 | # CONFIG_ARCH_IXDP2801 is not set |
103 | # CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set | ||
100 | 104 | ||
101 | # | 105 | # |
102 | # Processor Type | 106 | # Processor Type |
@@ -107,7 +111,6 @@ CONFIG_CPU_32v5=y | |||
107 | CONFIG_CPU_ABRT_EV5T=y | 111 | CONFIG_CPU_ABRT_EV5T=y |
108 | CONFIG_CPU_CACHE_VIVT=y | 112 | CONFIG_CPU_CACHE_VIVT=y |
109 | CONFIG_CPU_TLB_V4WBI=y | 113 | CONFIG_CPU_TLB_V4WBI=y |
110 | CONFIG_CPU_MINICACHE=y | ||
111 | 114 | ||
112 | # | 115 | # |
113 | # Processor Features | 116 | # Processor Features |
@@ -119,9 +122,11 @@ CONFIG_XSCALE_PMU=y | |||
119 | # | 122 | # |
120 | # Bus support | 123 | # Bus support |
121 | # | 124 | # |
125 | CONFIG_ISA_DMA_API=y | ||
122 | CONFIG_PCI=y | 126 | CONFIG_PCI=y |
123 | CONFIG_PCI_LEGACY_PROC=y | 127 | CONFIG_PCI_LEGACY_PROC=y |
124 | CONFIG_PCI_NAMES=y | 128 | CONFIG_PCI_NAMES=y |
129 | # CONFIG_PCI_DEBUG is not set | ||
125 | 130 | ||
126 | # | 131 | # |
127 | # PCCARD (PCMCIA/CardBus) support | 132 | # PCCARD (PCMCIA/CardBus) support |
@@ -131,7 +136,15 @@ CONFIG_PCI_NAMES=y | |||
131 | # | 136 | # |
132 | # Kernel Features | 137 | # Kernel Features |
133 | # | 138 | # |
139 | # CONFIG_SMP is not set | ||
134 | # CONFIG_PREEMPT is not set | 140 | # CONFIG_PREEMPT is not set |
141 | # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set | ||
142 | CONFIG_SELECT_MEMORY_MODEL=y | ||
143 | CONFIG_FLATMEM_MANUAL=y | ||
144 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
145 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
146 | CONFIG_FLATMEM=y | ||
147 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
135 | CONFIG_ALIGNMENT_TRAP=y | 148 | CONFIG_ALIGNMENT_TRAP=y |
136 | 149 | ||
137 | # | 150 | # |
@@ -270,7 +283,6 @@ CONFIG_MTD_IXP2000=y | |||
270 | # | 283 | # |
271 | # Block devices | 284 | # Block devices |
272 | # | 285 | # |
273 | # CONFIG_BLK_DEV_FD is not set | ||
274 | # CONFIG_BLK_CPQ_DA is not set | 286 | # CONFIG_BLK_CPQ_DA is not set |
275 | # CONFIG_BLK_CPQ_CISS_DA is not set | 287 | # CONFIG_BLK_CPQ_CISS_DA is not set |
276 | # CONFIG_BLK_DEV_DAC960 is not set | 288 | # CONFIG_BLK_DEV_DAC960 is not set |
@@ -309,6 +321,7 @@ CONFIG_IOSCHED_CFQ=y | |||
309 | # | 321 | # |
310 | # Fusion MPT device support | 322 | # Fusion MPT device support |
311 | # | 323 | # |
324 | # CONFIG_FUSION is not set | ||
312 | 325 | ||
313 | # | 326 | # |
314 | # IEEE 1394 (FireWire) support | 327 | # IEEE 1394 (FireWire) support |
@@ -330,10 +343,11 @@ CONFIG_NET=y | |||
330 | # | 343 | # |
331 | CONFIG_PACKET=y | 344 | CONFIG_PACKET=y |
332 | CONFIG_PACKET_MMAP=y | 345 | CONFIG_PACKET_MMAP=y |
333 | # CONFIG_NETLINK_DEV is not set | ||
334 | CONFIG_UNIX=y | 346 | CONFIG_UNIX=y |
335 | # CONFIG_NET_KEY is not set | 347 | # CONFIG_NET_KEY is not set |
336 | CONFIG_INET=y | 348 | CONFIG_INET=y |
349 | CONFIG_IP_FIB_HASH=y | ||
350 | # CONFIG_IP_FIB_TRIE is not set | ||
337 | # CONFIG_IP_MULTICAST is not set | 351 | # CONFIG_IP_MULTICAST is not set |
338 | # CONFIG_IP_ADVANCED_ROUTER is not set | 352 | # CONFIG_IP_ADVANCED_ROUTER is not set |
339 | CONFIG_IP_PNP=y | 353 | CONFIG_IP_PNP=y |
@@ -350,6 +364,17 @@ CONFIG_SYN_COOKIES=y | |||
350 | # CONFIG_INET_TUNNEL is not set | 364 | # CONFIG_INET_TUNNEL is not set |
351 | # CONFIG_IP_TCPDIAG is not set | 365 | # CONFIG_IP_TCPDIAG is not set |
352 | # CONFIG_IP_TCPDIAG_IPV6 is not set | 366 | # CONFIG_IP_TCPDIAG_IPV6 is not set |
367 | |||
368 | # | ||
369 | # TCP congestion control | ||
370 | # | ||
371 | CONFIG_TCP_CONG_BIC=y | ||
372 | CONFIG_TCP_CONG_WESTWOOD=m | ||
373 | CONFIG_TCP_CONG_HTCP=m | ||
374 | # CONFIG_TCP_CONG_HSTCP is not set | ||
375 | # CONFIG_TCP_CONG_HYBLA is not set | ||
376 | # CONFIG_TCP_CONG_VEGAS is not set | ||
377 | # CONFIG_TCP_CONG_SCALABLE is not set | ||
353 | # CONFIG_IPV6 is not set | 378 | # CONFIG_IPV6 is not set |
354 | # CONFIG_NETFILTER is not set | 379 | # CONFIG_NETFILTER is not set |
355 | 380 | ||
@@ -405,6 +430,7 @@ CONFIG_MII=y | |||
405 | # CONFIG_SUNGEM is not set | 430 | # CONFIG_SUNGEM is not set |
406 | # CONFIG_NET_VENDOR_3COM is not set | 431 | # CONFIG_NET_VENDOR_3COM is not set |
407 | # CONFIG_SMC91X is not set | 432 | # CONFIG_SMC91X is not set |
433 | # CONFIG_DM9000 is not set | ||
408 | 434 | ||
409 | # | 435 | # |
410 | # Tulip family network device support | 436 | # Tulip family network device support |
@@ -441,9 +467,11 @@ CONFIG_EEPRO100=y | |||
441 | # CONFIG_HAMACHI is not set | 467 | # CONFIG_HAMACHI is not set |
442 | # CONFIG_YELLOWFIN is not set | 468 | # CONFIG_YELLOWFIN is not set |
443 | # CONFIG_R8169 is not set | 469 | # CONFIG_R8169 is not set |
470 | # CONFIG_SKGE is not set | ||
444 | # CONFIG_SK98LIN is not set | 471 | # CONFIG_SK98LIN is not set |
445 | # CONFIG_VIA_VELOCITY is not set | 472 | # CONFIG_VIA_VELOCITY is not set |
446 | # CONFIG_TIGON3 is not set | 473 | # CONFIG_TIGON3 is not set |
474 | # CONFIG_BNX2 is not set | ||
447 | 475 | ||
448 | # | 476 | # |
449 | # Ethernet (10000 Mbit) | 477 | # Ethernet (10000 Mbit) |
@@ -465,6 +493,7 @@ CONFIG_EEPRO100=y | |||
465 | # Wan interfaces | 493 | # Wan interfaces |
466 | # | 494 | # |
467 | CONFIG_WAN=y | 495 | CONFIG_WAN=y |
496 | # CONFIG_DSCC4 is not set | ||
468 | # CONFIG_LANMEDIA is not set | 497 | # CONFIG_LANMEDIA is not set |
469 | # CONFIG_SYNCLINK_SYNCPPP is not set | 498 | # CONFIG_SYNCLINK_SYNCPPP is not set |
470 | CONFIG_HDLC=y | 499 | CONFIG_HDLC=y |
@@ -527,7 +556,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | |||
527 | # | 556 | # |
528 | # CONFIG_SERIO is not set | 557 | # CONFIG_SERIO is not set |
529 | # CONFIG_GAMEPORT is not set | 558 | # CONFIG_GAMEPORT is not set |
530 | CONFIG_SOUND_GAMEPORT=y | ||
531 | 559 | ||
532 | # | 560 | # |
533 | # Character devices | 561 | # Character devices |
@@ -548,6 +576,7 @@ CONFIG_SERIAL_8250_NR_UARTS=2 | |||
548 | # | 576 | # |
549 | CONFIG_SERIAL_CORE=y | 577 | CONFIG_SERIAL_CORE=y |
550 | CONFIG_SERIAL_CORE_CONSOLE=y | 578 | CONFIG_SERIAL_CORE_CONSOLE=y |
579 | # CONFIG_SERIAL_JSM is not set | ||
551 | CONFIG_UNIX98_PTYS=y | 580 | CONFIG_UNIX98_PTYS=y |
552 | CONFIG_LEGACY_PTYS=y | 581 | CONFIG_LEGACY_PTYS=y |
553 | CONFIG_LEGACY_PTY_COUNT=256 | 582 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -614,17 +643,18 @@ CONFIG_I2C_ALGOBIT=y | |||
614 | # CONFIG_I2C_AMD8111 is not set | 643 | # CONFIG_I2C_AMD8111 is not set |
615 | # CONFIG_I2C_I801 is not set | 644 | # CONFIG_I2C_I801 is not set |
616 | # CONFIG_I2C_I810 is not set | 645 | # CONFIG_I2C_I810 is not set |
646 | # CONFIG_I2C_PIIX4 is not set | ||
617 | # CONFIG_I2C_ISA is not set | 647 | # CONFIG_I2C_ISA is not set |
618 | # CONFIG_I2C_IXP2000 is not set | 648 | # CONFIG_I2C_IXP2000 is not set |
619 | # CONFIG_I2C_NFORCE2 is not set | 649 | # CONFIG_I2C_NFORCE2 is not set |
620 | # CONFIG_I2C_PARPORT_LIGHT is not set | 650 | # CONFIG_I2C_PARPORT_LIGHT is not set |
621 | # CONFIG_I2C_PIIX4 is not set | ||
622 | # CONFIG_I2C_PROSAVAGE is not set | 651 | # CONFIG_I2C_PROSAVAGE is not set |
623 | # CONFIG_I2C_SAVAGE4 is not set | 652 | # CONFIG_I2C_SAVAGE4 is not set |
624 | # CONFIG_SCx200_ACB is not set | 653 | # CONFIG_SCx200_ACB is not set |
625 | # CONFIG_I2C_SIS5595 is not set | 654 | # CONFIG_I2C_SIS5595 is not set |
626 | # CONFIG_I2C_SIS630 is not set | 655 | # CONFIG_I2C_SIS630 is not set |
627 | # CONFIG_I2C_SIS96X is not set | 656 | # CONFIG_I2C_SIS96X is not set |
657 | # CONFIG_I2C_STUB is not set | ||
628 | # CONFIG_I2C_VIA is not set | 658 | # CONFIG_I2C_VIA is not set |
629 | # CONFIG_I2C_VIAPRO is not set | 659 | # CONFIG_I2C_VIAPRO is not set |
630 | # CONFIG_I2C_VOODOO3 is not set | 660 | # CONFIG_I2C_VOODOO3 is not set |
@@ -638,7 +668,9 @@ CONFIG_I2C_SENSOR=y | |||
638 | # CONFIG_SENSORS_ADM1025 is not set | 668 | # CONFIG_SENSORS_ADM1025 is not set |
639 | # CONFIG_SENSORS_ADM1026 is not set | 669 | # CONFIG_SENSORS_ADM1026 is not set |
640 | # CONFIG_SENSORS_ADM1031 is not set | 670 | # CONFIG_SENSORS_ADM1031 is not set |
671 | # CONFIG_SENSORS_ADM9240 is not set | ||
641 | # CONFIG_SENSORS_ASB100 is not set | 672 | # CONFIG_SENSORS_ASB100 is not set |
673 | # CONFIG_SENSORS_ATXP1 is not set | ||
642 | # CONFIG_SENSORS_DS1621 is not set | 674 | # CONFIG_SENSORS_DS1621 is not set |
643 | # CONFIG_SENSORS_FSCHER is not set | 675 | # CONFIG_SENSORS_FSCHER is not set |
644 | # CONFIG_SENSORS_FSCPOS is not set | 676 | # CONFIG_SENSORS_FSCPOS is not set |
@@ -654,6 +686,7 @@ CONFIG_I2C_SENSOR=y | |||
654 | # CONFIG_SENSORS_LM85 is not set | 686 | # CONFIG_SENSORS_LM85 is not set |
655 | # CONFIG_SENSORS_LM87 is not set | 687 | # CONFIG_SENSORS_LM87 is not set |
656 | # CONFIG_SENSORS_LM90 is not set | 688 | # CONFIG_SENSORS_LM90 is not set |
689 | # CONFIG_SENSORS_LM92 is not set | ||
657 | # CONFIG_SENSORS_MAX1619 is not set | 690 | # CONFIG_SENSORS_MAX1619 is not set |
658 | # CONFIG_SENSORS_PC87360 is not set | 691 | # CONFIG_SENSORS_PC87360 is not set |
659 | # CONFIG_SENSORS_SMSC47B397 is not set | 692 | # CONFIG_SENSORS_SMSC47B397 is not set |
@@ -663,14 +696,19 @@ CONFIG_I2C_SENSOR=y | |||
663 | # CONFIG_SENSORS_W83781D is not set | 696 | # CONFIG_SENSORS_W83781D is not set |
664 | # CONFIG_SENSORS_W83L785TS is not set | 697 | # CONFIG_SENSORS_W83L785TS is not set |
665 | # CONFIG_SENSORS_W83627HF is not set | 698 | # CONFIG_SENSORS_W83627HF is not set |
699 | # CONFIG_SENSORS_W83627EHF is not set | ||
666 | 700 | ||
667 | # | 701 | # |
668 | # Other I2C Chip support | 702 | # Other I2C Chip support |
669 | # | 703 | # |
704 | # CONFIG_SENSORS_DS1337 is not set | ||
705 | # CONFIG_SENSORS_DS1374 is not set | ||
670 | CONFIG_SENSORS_EEPROM=y | 706 | CONFIG_SENSORS_EEPROM=y |
671 | # CONFIG_SENSORS_PCF8574 is not set | 707 | # CONFIG_SENSORS_PCF8574 is not set |
708 | # CONFIG_SENSORS_PCA9539 is not set | ||
672 | # CONFIG_SENSORS_PCF8591 is not set | 709 | # CONFIG_SENSORS_PCF8591 is not set |
673 | # CONFIG_SENSORS_RTC8564 is not set | 710 | # CONFIG_SENSORS_RTC8564 is not set |
711 | # CONFIG_SENSORS_MAX6875 is not set | ||
674 | # CONFIG_I2C_DEBUG_CORE is not set | 712 | # CONFIG_I2C_DEBUG_CORE is not set |
675 | # CONFIG_I2C_DEBUG_ALGO is not set | 713 | # CONFIG_I2C_DEBUG_ALGO is not set |
676 | # CONFIG_I2C_DEBUG_BUS is not set | 714 | # CONFIG_I2C_DEBUG_BUS is not set |
@@ -724,6 +762,7 @@ CONFIG_EXT2_FS=y | |||
724 | CONFIG_EXT2_FS_XATTR=y | 762 | CONFIG_EXT2_FS_XATTR=y |
725 | CONFIG_EXT2_FS_POSIX_ACL=y | 763 | CONFIG_EXT2_FS_POSIX_ACL=y |
726 | # CONFIG_EXT2_FS_SECURITY is not set | 764 | # CONFIG_EXT2_FS_SECURITY is not set |
765 | # CONFIG_EXT2_FS_XIP is not set | ||
727 | CONFIG_EXT3_FS=y | 766 | CONFIG_EXT3_FS=y |
728 | CONFIG_EXT3_FS_XATTR=y | 767 | CONFIG_EXT3_FS_XATTR=y |
729 | CONFIG_EXT3_FS_POSIX_ACL=y | 768 | CONFIG_EXT3_FS_POSIX_ACL=y |
@@ -764,7 +803,6 @@ CONFIG_DNOTIFY=y | |||
764 | # | 803 | # |
765 | CONFIG_PROC_FS=y | 804 | CONFIG_PROC_FS=y |
766 | CONFIG_SYSFS=y | 805 | CONFIG_SYSFS=y |
767 | # CONFIG_DEVFS_FS is not set | ||
768 | # CONFIG_DEVPTS_FS_XATTR is not set | 806 | # CONFIG_DEVPTS_FS_XATTR is not set |
769 | CONFIG_TMPFS=y | 807 | CONFIG_TMPFS=y |
770 | # CONFIG_TMPFS_XATTR is not set | 808 | # CONFIG_TMPFS_XATTR is not set |
@@ -802,12 +840,14 @@ CONFIG_JFFS2_RTIME=y | |||
802 | # | 840 | # |
803 | CONFIG_NFS_FS=y | 841 | CONFIG_NFS_FS=y |
804 | CONFIG_NFS_V3=y | 842 | CONFIG_NFS_V3=y |
843 | # CONFIG_NFS_V3_ACL is not set | ||
805 | # CONFIG_NFS_V4 is not set | 844 | # CONFIG_NFS_V4 is not set |
806 | # CONFIG_NFS_DIRECTIO is not set | 845 | # CONFIG_NFS_DIRECTIO is not set |
807 | # CONFIG_NFSD is not set | 846 | # CONFIG_NFSD is not set |
808 | CONFIG_ROOT_NFS=y | 847 | CONFIG_ROOT_NFS=y |
809 | CONFIG_LOCKD=y | 848 | CONFIG_LOCKD=y |
810 | CONFIG_LOCKD_V4=y | 849 | CONFIG_LOCKD_V4=y |
850 | CONFIG_NFS_COMMON=y | ||
811 | CONFIG_SUNRPC=y | 851 | CONFIG_SUNRPC=y |
812 | # CONFIG_RPCSEC_GSS_KRB5 is not set | 852 | # CONFIG_RPCSEC_GSS_KRB5 is not set |
813 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | 853 | # CONFIG_RPCSEC_GSS_SPKM3 is not set |
@@ -892,3 +932,4 @@ CONFIG_CRC32=y | |||
892 | # CONFIG_LIBCRC32C is not set | 932 | # CONFIG_LIBCRC32C is not set |
893 | CONFIG_ZLIB_INFLATE=y | 933 | CONFIG_ZLIB_INFLATE=y |
894 | CONFIG_ZLIB_DEFLATE=y | 934 | CONFIG_ZLIB_DEFLATE=y |
935 | # CONFIG_TEXTSEARCH is not set | ||
diff --git a/arch/arm/configs/ixdp2801_defconfig b/arch/arm/configs/ixdp2801_defconfig index f1afe3d09ec6..b1e162f29cb9 100644 --- a/arch/arm/configs/ixdp2801_defconfig +++ b/arch/arm/configs/ixdp2801_defconfig | |||
@@ -1,14 +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.12-rc1-bk2 | 3 | # Linux kernel version: 2.6.12-git6 |
4 | # Sun Mar 27 22:39:19 2005 | 4 | # Sat Jun 25 01:01:18 2005 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
8 | CONFIG_UID16=y | 8 | CONFIG_UID16=y |
9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
10 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 10 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
11 | CONFIG_GENERIC_IOMAP=y | ||
12 | 11 | ||
13 | # | 12 | # |
14 | # Code maturity level options | 13 | # Code maturity level options |
@@ -16,6 +15,7 @@ CONFIG_GENERIC_IOMAP=y | |||
16 | CONFIG_EXPERIMENTAL=y | 15 | CONFIG_EXPERIMENTAL=y |
17 | CONFIG_CLEAN_COMPILE=y | 16 | CONFIG_CLEAN_COMPILE=y |
18 | CONFIG_BROKEN_ON_SMP=y | 17 | CONFIG_BROKEN_ON_SMP=y |
18 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
19 | 19 | ||
20 | # | 20 | # |
21 | # General setup | 21 | # General setup |
@@ -35,6 +35,8 @@ CONFIG_EMBEDDED=y | |||
35 | CONFIG_KALLSYMS=y | 35 | CONFIG_KALLSYMS=y |
36 | # CONFIG_KALLSYMS_ALL is not set | 36 | # CONFIG_KALLSYMS_ALL is not set |
37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
38 | CONFIG_PRINTK=y | ||
39 | CONFIG_BUG=y | ||
38 | CONFIG_BASE_FULL=y | 40 | CONFIG_BASE_FULL=y |
39 | CONFIG_FUTEX=y | 41 | CONFIG_FUTEX=y |
40 | CONFIG_EPOLL=y | 42 | CONFIG_EPOLL=y |
@@ -82,6 +84,7 @@ CONFIG_ARCH_IXP2000=y | |||
82 | # CONFIG_ARCH_VERSATILE is not set | 84 | # CONFIG_ARCH_VERSATILE is not set |
83 | # CONFIG_ARCH_IMX is not set | 85 | # CONFIG_ARCH_IMX is not set |
84 | # CONFIG_ARCH_H720X is not set | 86 | # CONFIG_ARCH_H720X is not set |
87 | # CONFIG_ARCH_AAEC2000 is not set | ||
85 | CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y | 88 | CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y |
86 | 89 | ||
87 | # | 90 | # |
@@ -97,6 +100,7 @@ CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y | |||
97 | # CONFIG_ARCH_IXDP2401 is not set | 100 | # CONFIG_ARCH_IXDP2401 is not set |
98 | CONFIG_ARCH_IXDP2801=y | 101 | CONFIG_ARCH_IXDP2801=y |
99 | CONFIG_ARCH_IXDP2X01=y | 102 | CONFIG_ARCH_IXDP2X01=y |
103 | # CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set | ||
100 | 104 | ||
101 | # | 105 | # |
102 | # Processor Type | 106 | # Processor Type |
@@ -107,7 +111,6 @@ CONFIG_CPU_32v5=y | |||
107 | CONFIG_CPU_ABRT_EV5T=y | 111 | CONFIG_CPU_ABRT_EV5T=y |
108 | CONFIG_CPU_CACHE_VIVT=y | 112 | CONFIG_CPU_CACHE_VIVT=y |
109 | CONFIG_CPU_TLB_V4WBI=y | 113 | CONFIG_CPU_TLB_V4WBI=y |
110 | CONFIG_CPU_MINICACHE=y | ||
111 | 114 | ||
112 | # | 115 | # |
113 | # Processor Features | 116 | # Processor Features |
@@ -119,9 +122,11 @@ CONFIG_XSCALE_PMU=y | |||
119 | # | 122 | # |
120 | # Bus support | 123 | # Bus support |
121 | # | 124 | # |
125 | CONFIG_ISA_DMA_API=y | ||
122 | CONFIG_PCI=y | 126 | CONFIG_PCI=y |
123 | CONFIG_PCI_LEGACY_PROC=y | 127 | CONFIG_PCI_LEGACY_PROC=y |
124 | CONFIG_PCI_NAMES=y | 128 | CONFIG_PCI_NAMES=y |
129 | # CONFIG_PCI_DEBUG is not set | ||
125 | 130 | ||
126 | # | 131 | # |
127 | # PCCARD (PCMCIA/CardBus) support | 132 | # PCCARD (PCMCIA/CardBus) support |
@@ -131,7 +136,15 @@ CONFIG_PCI_NAMES=y | |||
131 | # | 136 | # |
132 | # Kernel Features | 137 | # Kernel Features |
133 | # | 138 | # |
139 | # CONFIG_SMP is not set | ||
134 | # CONFIG_PREEMPT is not set | 140 | # CONFIG_PREEMPT is not set |
141 | # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set | ||
142 | CONFIG_SELECT_MEMORY_MODEL=y | ||
143 | CONFIG_FLATMEM_MANUAL=y | ||
144 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
145 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
146 | CONFIG_FLATMEM=y | ||
147 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
135 | CONFIG_ALIGNMENT_TRAP=y | 148 | CONFIG_ALIGNMENT_TRAP=y |
136 | 149 | ||
137 | # | 150 | # |
@@ -270,7 +283,6 @@ CONFIG_MTD_IXP2000=y | |||
270 | # | 283 | # |
271 | # Block devices | 284 | # Block devices |
272 | # | 285 | # |
273 | # CONFIG_BLK_DEV_FD is not set | ||
274 | # CONFIG_BLK_CPQ_DA is not set | 286 | # CONFIG_BLK_CPQ_DA is not set |
275 | # CONFIG_BLK_CPQ_CISS_DA is not set | 287 | # CONFIG_BLK_CPQ_CISS_DA is not set |
276 | # CONFIG_BLK_DEV_DAC960 is not set | 288 | # CONFIG_BLK_DEV_DAC960 is not set |
@@ -309,6 +321,7 @@ CONFIG_IOSCHED_CFQ=y | |||
309 | # | 321 | # |
310 | # Fusion MPT device support | 322 | # Fusion MPT device support |
311 | # | 323 | # |
324 | # CONFIG_FUSION is not set | ||
312 | 325 | ||
313 | # | 326 | # |
314 | # IEEE 1394 (FireWire) support | 327 | # IEEE 1394 (FireWire) support |
@@ -330,10 +343,11 @@ CONFIG_NET=y | |||
330 | # | 343 | # |
331 | CONFIG_PACKET=y | 344 | CONFIG_PACKET=y |
332 | CONFIG_PACKET_MMAP=y | 345 | CONFIG_PACKET_MMAP=y |
333 | # CONFIG_NETLINK_DEV is not set | ||
334 | CONFIG_UNIX=y | 346 | CONFIG_UNIX=y |
335 | # CONFIG_NET_KEY is not set | 347 | # CONFIG_NET_KEY is not set |
336 | CONFIG_INET=y | 348 | CONFIG_INET=y |
349 | CONFIG_IP_FIB_HASH=y | ||
350 | # CONFIG_IP_FIB_TRIE is not set | ||
337 | # CONFIG_IP_MULTICAST is not set | 351 | # CONFIG_IP_MULTICAST is not set |
338 | # CONFIG_IP_ADVANCED_ROUTER is not set | 352 | # CONFIG_IP_ADVANCED_ROUTER is not set |
339 | CONFIG_IP_PNP=y | 353 | CONFIG_IP_PNP=y |
@@ -350,6 +364,17 @@ CONFIG_SYN_COOKIES=y | |||
350 | # CONFIG_INET_TUNNEL is not set | 364 | # CONFIG_INET_TUNNEL is not set |
351 | # CONFIG_IP_TCPDIAG is not set | 365 | # CONFIG_IP_TCPDIAG is not set |
352 | # CONFIG_IP_TCPDIAG_IPV6 is not set | 366 | # CONFIG_IP_TCPDIAG_IPV6 is not set |
367 | |||
368 | # | ||
369 | # TCP congestion control | ||
370 | # | ||
371 | CONFIG_TCP_CONG_BIC=y | ||
372 | CONFIG_TCP_CONG_WESTWOOD=m | ||
373 | CONFIG_TCP_CONG_HTCP=m | ||
374 | # CONFIG_TCP_CONG_HSTCP is not set | ||
375 | # CONFIG_TCP_CONG_HYBLA is not set | ||
376 | # CONFIG_TCP_CONG_VEGAS is not set | ||
377 | # CONFIG_TCP_CONG_SCALABLE is not set | ||
353 | # CONFIG_IPV6 is not set | 378 | # CONFIG_IPV6 is not set |
354 | # CONFIG_NETFILTER is not set | 379 | # CONFIG_NETFILTER is not set |
355 | 380 | ||
@@ -405,6 +430,7 @@ CONFIG_MII=y | |||
405 | # CONFIG_SUNGEM is not set | 430 | # CONFIG_SUNGEM is not set |
406 | # CONFIG_NET_VENDOR_3COM is not set | 431 | # CONFIG_NET_VENDOR_3COM is not set |
407 | # CONFIG_SMC91X is not set | 432 | # CONFIG_SMC91X is not set |
433 | # CONFIG_DM9000 is not set | ||
408 | 434 | ||
409 | # | 435 | # |
410 | # Tulip family network device support | 436 | # Tulip family network device support |
@@ -442,9 +468,11 @@ CONFIG_EEPRO100=y | |||
442 | # CONFIG_HAMACHI is not set | 468 | # CONFIG_HAMACHI is not set |
443 | # CONFIG_YELLOWFIN is not set | 469 | # CONFIG_YELLOWFIN is not set |
444 | # CONFIG_R8169 is not set | 470 | # CONFIG_R8169 is not set |
471 | # CONFIG_SKGE is not set | ||
445 | # CONFIG_SK98LIN is not set | 472 | # CONFIG_SK98LIN is not set |
446 | # CONFIG_VIA_VELOCITY is not set | 473 | # CONFIG_VIA_VELOCITY is not set |
447 | # CONFIG_TIGON3 is not set | 474 | # CONFIG_TIGON3 is not set |
475 | # CONFIG_BNX2 is not set | ||
448 | 476 | ||
449 | # | 477 | # |
450 | # Ethernet (10000 Mbit) | 478 | # Ethernet (10000 Mbit) |
@@ -466,6 +494,7 @@ CONFIG_EEPRO100=y | |||
466 | # Wan interfaces | 494 | # Wan interfaces |
467 | # | 495 | # |
468 | CONFIG_WAN=y | 496 | CONFIG_WAN=y |
497 | # CONFIG_DSCC4 is not set | ||
469 | # CONFIG_LANMEDIA is not set | 498 | # CONFIG_LANMEDIA is not set |
470 | # CONFIG_SYNCLINK_SYNCPPP is not set | 499 | # CONFIG_SYNCLINK_SYNCPPP is not set |
471 | CONFIG_HDLC=y | 500 | CONFIG_HDLC=y |
@@ -528,7 +557,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | |||
528 | # | 557 | # |
529 | # CONFIG_SERIO is not set | 558 | # CONFIG_SERIO is not set |
530 | # CONFIG_GAMEPORT is not set | 559 | # CONFIG_GAMEPORT is not set |
531 | CONFIG_SOUND_GAMEPORT=y | ||
532 | 560 | ||
533 | # | 561 | # |
534 | # Character devices | 562 | # Character devices |
@@ -549,6 +577,7 @@ CONFIG_SERIAL_8250_NR_UARTS=2 | |||
549 | # | 577 | # |
550 | CONFIG_SERIAL_CORE=y | 578 | CONFIG_SERIAL_CORE=y |
551 | CONFIG_SERIAL_CORE_CONSOLE=y | 579 | CONFIG_SERIAL_CORE_CONSOLE=y |
580 | # CONFIG_SERIAL_JSM is not set | ||
552 | CONFIG_UNIX98_PTYS=y | 581 | CONFIG_UNIX98_PTYS=y |
553 | CONFIG_LEGACY_PTYS=y | 582 | CONFIG_LEGACY_PTYS=y |
554 | CONFIG_LEGACY_PTY_COUNT=256 | 583 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -615,17 +644,18 @@ CONFIG_I2C_ALGOBIT=y | |||
615 | # CONFIG_I2C_AMD8111 is not set | 644 | # CONFIG_I2C_AMD8111 is not set |
616 | # CONFIG_I2C_I801 is not set | 645 | # CONFIG_I2C_I801 is not set |
617 | # CONFIG_I2C_I810 is not set | 646 | # CONFIG_I2C_I810 is not set |
647 | # CONFIG_I2C_PIIX4 is not set | ||
618 | # CONFIG_I2C_ISA is not set | 648 | # CONFIG_I2C_ISA is not set |
619 | # CONFIG_I2C_IXP2000 is not set | 649 | # CONFIG_I2C_IXP2000 is not set |
620 | # CONFIG_I2C_NFORCE2 is not set | 650 | # CONFIG_I2C_NFORCE2 is not set |
621 | # CONFIG_I2C_PARPORT_LIGHT is not set | 651 | # CONFIG_I2C_PARPORT_LIGHT is not set |
622 | # CONFIG_I2C_PIIX4 is not set | ||
623 | # CONFIG_I2C_PROSAVAGE is not set | 652 | # CONFIG_I2C_PROSAVAGE is not set |
624 | # CONFIG_I2C_SAVAGE4 is not set | 653 | # CONFIG_I2C_SAVAGE4 is not set |
625 | # CONFIG_SCx200_ACB is not set | 654 | # CONFIG_SCx200_ACB is not set |
626 | # CONFIG_I2C_SIS5595 is not set | 655 | # CONFIG_I2C_SIS5595 is not set |
627 | # CONFIG_I2C_SIS630 is not set | 656 | # CONFIG_I2C_SIS630 is not set |
628 | # CONFIG_I2C_SIS96X is not set | 657 | # CONFIG_I2C_SIS96X is not set |
658 | # CONFIG_I2C_STUB is not set | ||
629 | # CONFIG_I2C_VIA is not set | 659 | # CONFIG_I2C_VIA is not set |
630 | # CONFIG_I2C_VIAPRO is not set | 660 | # CONFIG_I2C_VIAPRO is not set |
631 | # CONFIG_I2C_VOODOO3 is not set | 661 | # CONFIG_I2C_VOODOO3 is not set |
@@ -639,7 +669,9 @@ CONFIG_I2C_SENSOR=y | |||
639 | # CONFIG_SENSORS_ADM1025 is not set | 669 | # CONFIG_SENSORS_ADM1025 is not set |
640 | # CONFIG_SENSORS_ADM1026 is not set | 670 | # CONFIG_SENSORS_ADM1026 is not set |
641 | # CONFIG_SENSORS_ADM1031 is not set | 671 | # CONFIG_SENSORS_ADM1031 is not set |
672 | # CONFIG_SENSORS_ADM9240 is not set | ||
642 | # CONFIG_SENSORS_ASB100 is not set | 673 | # CONFIG_SENSORS_ASB100 is not set |
674 | # CONFIG_SENSORS_ATXP1 is not set | ||
643 | # CONFIG_SENSORS_DS1621 is not set | 675 | # CONFIG_SENSORS_DS1621 is not set |
644 | # CONFIG_SENSORS_FSCHER is not set | 676 | # CONFIG_SENSORS_FSCHER is not set |
645 | # CONFIG_SENSORS_FSCPOS is not set | 677 | # CONFIG_SENSORS_FSCPOS is not set |
@@ -655,6 +687,7 @@ CONFIG_I2C_SENSOR=y | |||
655 | # CONFIG_SENSORS_LM85 is not set | 687 | # CONFIG_SENSORS_LM85 is not set |
656 | # CONFIG_SENSORS_LM87 is not set | 688 | # CONFIG_SENSORS_LM87 is not set |
657 | # CONFIG_SENSORS_LM90 is not set | 689 | # CONFIG_SENSORS_LM90 is not set |
690 | # CONFIG_SENSORS_LM92 is not set | ||
658 | # CONFIG_SENSORS_MAX1619 is not set | 691 | # CONFIG_SENSORS_MAX1619 is not set |
659 | # CONFIG_SENSORS_PC87360 is not set | 692 | # CONFIG_SENSORS_PC87360 is not set |
660 | # CONFIG_SENSORS_SMSC47B397 is not set | 693 | # CONFIG_SENSORS_SMSC47B397 is not set |
@@ -664,14 +697,19 @@ CONFIG_I2C_SENSOR=y | |||
664 | # CONFIG_SENSORS_W83781D is not set | 697 | # CONFIG_SENSORS_W83781D is not set |
665 | # CONFIG_SENSORS_W83L785TS is not set | 698 | # CONFIG_SENSORS_W83L785TS is not set |
666 | # CONFIG_SENSORS_W83627HF is not set | 699 | # CONFIG_SENSORS_W83627HF is not set |
700 | # CONFIG_SENSORS_W83627EHF is not set | ||
667 | 701 | ||
668 | # | 702 | # |
669 | # Other I2C Chip support | 703 | # Other I2C Chip support |
670 | # | 704 | # |
705 | # CONFIG_SENSORS_DS1337 is not set | ||
706 | # CONFIG_SENSORS_DS1374 is not set | ||
671 | CONFIG_SENSORS_EEPROM=y | 707 | CONFIG_SENSORS_EEPROM=y |
672 | # CONFIG_SENSORS_PCF8574 is not set | 708 | # CONFIG_SENSORS_PCF8574 is not set |
709 | # CONFIG_SENSORS_PCA9539 is not set | ||
673 | # CONFIG_SENSORS_PCF8591 is not set | 710 | # CONFIG_SENSORS_PCF8591 is not set |
674 | # CONFIG_SENSORS_RTC8564 is not set | 711 | # CONFIG_SENSORS_RTC8564 is not set |
712 | # CONFIG_SENSORS_MAX6875 is not set | ||
675 | # CONFIG_I2C_DEBUG_CORE is not set | 713 | # CONFIG_I2C_DEBUG_CORE is not set |
676 | # CONFIG_I2C_DEBUG_ALGO is not set | 714 | # CONFIG_I2C_DEBUG_ALGO is not set |
677 | # CONFIG_I2C_DEBUG_BUS is not set | 715 | # CONFIG_I2C_DEBUG_BUS is not set |
@@ -725,6 +763,7 @@ CONFIG_EXT2_FS=y | |||
725 | CONFIG_EXT2_FS_XATTR=y | 763 | CONFIG_EXT2_FS_XATTR=y |
726 | CONFIG_EXT2_FS_POSIX_ACL=y | 764 | CONFIG_EXT2_FS_POSIX_ACL=y |
727 | # CONFIG_EXT2_FS_SECURITY is not set | 765 | # CONFIG_EXT2_FS_SECURITY is not set |
766 | # CONFIG_EXT2_FS_XIP is not set | ||
728 | CONFIG_EXT3_FS=y | 767 | CONFIG_EXT3_FS=y |
729 | CONFIG_EXT3_FS_XATTR=y | 768 | CONFIG_EXT3_FS_XATTR=y |
730 | CONFIG_EXT3_FS_POSIX_ACL=y | 769 | CONFIG_EXT3_FS_POSIX_ACL=y |
@@ -765,7 +804,6 @@ CONFIG_DNOTIFY=y | |||
765 | # | 804 | # |
766 | CONFIG_PROC_FS=y | 805 | CONFIG_PROC_FS=y |
767 | CONFIG_SYSFS=y | 806 | CONFIG_SYSFS=y |
768 | # CONFIG_DEVFS_FS is not set | ||
769 | # CONFIG_DEVPTS_FS_XATTR is not set | 807 | # CONFIG_DEVPTS_FS_XATTR is not set |
770 | CONFIG_TMPFS=y | 808 | CONFIG_TMPFS=y |
771 | # CONFIG_TMPFS_XATTR is not set | 809 | # CONFIG_TMPFS_XATTR is not set |
@@ -803,12 +841,14 @@ CONFIG_JFFS2_RTIME=y | |||
803 | # | 841 | # |
804 | CONFIG_NFS_FS=y | 842 | CONFIG_NFS_FS=y |
805 | CONFIG_NFS_V3=y | 843 | CONFIG_NFS_V3=y |
844 | # CONFIG_NFS_V3_ACL is not set | ||
806 | # CONFIG_NFS_V4 is not set | 845 | # CONFIG_NFS_V4 is not set |
807 | # CONFIG_NFS_DIRECTIO is not set | 846 | # CONFIG_NFS_DIRECTIO is not set |
808 | # CONFIG_NFSD is not set | 847 | # CONFIG_NFSD is not set |
809 | CONFIG_ROOT_NFS=y | 848 | CONFIG_ROOT_NFS=y |
810 | CONFIG_LOCKD=y | 849 | CONFIG_LOCKD=y |
811 | CONFIG_LOCKD_V4=y | 850 | CONFIG_LOCKD_V4=y |
851 | CONFIG_NFS_COMMON=y | ||
812 | CONFIG_SUNRPC=y | 852 | CONFIG_SUNRPC=y |
813 | # CONFIG_RPCSEC_GSS_KRB5 is not set | 853 | # CONFIG_RPCSEC_GSS_KRB5 is not set |
814 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | 854 | # CONFIG_RPCSEC_GSS_SPKM3 is not set |
@@ -893,3 +933,4 @@ CONFIG_CRC32=y | |||
893 | # CONFIG_LIBCRC32C is not set | 933 | # CONFIG_LIBCRC32C is not set |
894 | CONFIG_ZLIB_INFLATE=y | 934 | CONFIG_ZLIB_INFLATE=y |
895 | CONFIG_ZLIB_DEFLATE=y | 935 | CONFIG_ZLIB_DEFLATE=y |
936 | # CONFIG_TEXTSEARCH is not set | ||
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index ff187f4308f0..395137a8fad2 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c | |||
@@ -4,6 +4,10 @@ | |||
4 | * Copyright (C) 1992 Linus Torvalds | 4 | * Copyright (C) 1992 Linus Torvalds |
5 | * Modifications for ARM processor Copyright (C) 1995-2000 Russell King. | 5 | * Modifications for ARM processor Copyright (C) 1995-2000 Russell King. |
6 | * | 6 | * |
7 | * Support for Dynamic Tick Timer Copyright (C) 2004-2005 Nokia Corporation. | ||
8 | * Dynamic Tick Timer written by Tony Lindgren <tony@atomide.com> and | ||
9 | * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>. | ||
10 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 12 | * it under the terms of the GNU General Public License version 2 as |
9 | * published by the Free Software Foundation. | 13 | * published by the Free Software Foundation. |
@@ -37,6 +41,7 @@ | |||
37 | #include <asm/irq.h> | 41 | #include <asm/irq.h> |
38 | #include <asm/system.h> | 42 | #include <asm/system.h> |
39 | #include <asm/mach/irq.h> | 43 | #include <asm/mach/irq.h> |
44 | #include <asm/mach/time.h> | ||
40 | 45 | ||
41 | /* | 46 | /* |
42 | * Maximum IRQ count. Currently, this is arbitary. However, it should | 47 | * Maximum IRQ count. Currently, this is arbitary. However, it should |
@@ -329,6 +334,15 @@ __do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs) | |||
329 | 334 | ||
330 | spin_unlock(&irq_controller_lock); | 335 | spin_unlock(&irq_controller_lock); |
331 | 336 | ||
337 | #ifdef CONFIG_NO_IDLE_HZ | ||
338 | if (!(action->flags & SA_TIMER) && system_timer->dyn_tick != NULL) { | ||
339 | write_seqlock(&xtime_lock); | ||
340 | if (system_timer->dyn_tick->state & DYN_TICK_ENABLED) | ||
341 | system_timer->dyn_tick->handler(irq, 0, regs); | ||
342 | write_sequnlock(&xtime_lock); | ||
343 | } | ||
344 | #endif | ||
345 | |||
332 | if (!(action->flags & SA_INTERRUPT)) | 346 | if (!(action->flags & SA_INTERRUPT)) |
333 | local_irq_enable(); | 347 | local_irq_enable(); |
334 | 348 | ||
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index c232f24f4a60..06054c9ba074 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c | |||
@@ -381,6 +381,95 @@ static struct sysdev_class timer_sysclass = { | |||
381 | .resume = timer_resume, | 381 | .resume = timer_resume, |
382 | }; | 382 | }; |
383 | 383 | ||
384 | #ifdef CONFIG_NO_IDLE_HZ | ||
385 | static int timer_dyn_tick_enable(void) | ||
386 | { | ||
387 | struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; | ||
388 | unsigned long flags; | ||
389 | int ret = -ENODEV; | ||
390 | |||
391 | if (dyn_tick) { | ||
392 | write_seqlock_irqsave(&xtime_lock, flags); | ||
393 | ret = 0; | ||
394 | if (!(dyn_tick->state & DYN_TICK_ENABLED)) { | ||
395 | ret = dyn_tick->enable(); | ||
396 | |||
397 | if (ret == 0) | ||
398 | dyn_tick->state |= DYN_TICK_ENABLED; | ||
399 | } | ||
400 | write_sequnlock_irqrestore(&xtime_lock, flags); | ||
401 | } | ||
402 | |||
403 | return ret; | ||
404 | } | ||
405 | |||
406 | static int timer_dyn_tick_disable(void) | ||
407 | { | ||
408 | struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; | ||
409 | unsigned long flags; | ||
410 | int ret = -ENODEV; | ||
411 | |||
412 | if (dyn_tick) { | ||
413 | write_seqlock_irqsave(&xtime_lock, flags); | ||
414 | ret = 0; | ||
415 | if (dyn_tick->state & DYN_TICK_ENABLED) { | ||
416 | ret = dyn_tick->disable(); | ||
417 | |||
418 | if (ret == 0) | ||
419 | dyn_tick->state &= ~DYN_TICK_ENABLED; | ||
420 | } | ||
421 | write_sequnlock_irqrestore(&xtime_lock, flags); | ||
422 | } | ||
423 | |||
424 | return ret; | ||
425 | } | ||
426 | |||
427 | void timer_dyn_reprogram(void) | ||
428 | { | ||
429 | struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; | ||
430 | unsigned long flags; | ||
431 | |||
432 | write_seqlock_irqsave(&xtime_lock, flags); | ||
433 | if (dyn_tick->state & DYN_TICK_ENABLED) | ||
434 | dyn_tick->reprogram(next_timer_interrupt() - jiffies); | ||
435 | write_sequnlock_irqrestore(&xtime_lock, flags); | ||
436 | } | ||
437 | |||
438 | static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf) | ||
439 | { | ||
440 | return sprintf(buf, "%i\n", | ||
441 | (system_timer->dyn_tick->state & DYN_TICK_ENABLED) >> 1); | ||
442 | } | ||
443 | |||
444 | static ssize_t timer_set_dyn_tick(struct sys_device *dev, const char *buf, | ||
445 | size_t count) | ||
446 | { | ||
447 | unsigned int enable = simple_strtoul(buf, NULL, 2); | ||
448 | |||
449 | if (enable) | ||
450 | timer_dyn_tick_enable(); | ||
451 | else | ||
452 | timer_dyn_tick_disable(); | ||
453 | |||
454 | return count; | ||
455 | } | ||
456 | static SYSDEV_ATTR(dyn_tick, 0644, timer_show_dyn_tick, timer_set_dyn_tick); | ||
457 | |||
458 | /* | ||
459 | * dyntick=enable|disable | ||
460 | */ | ||
461 | static char dyntick_str[4] __initdata = ""; | ||
462 | |||
463 | static int __init dyntick_setup(char *str) | ||
464 | { | ||
465 | if (str) | ||
466 | strlcpy(dyntick_str, str, sizeof(dyntick_str)); | ||
467 | return 1; | ||
468 | } | ||
469 | |||
470 | __setup("dyntick=", dyntick_setup); | ||
471 | #endif | ||
472 | |||
384 | static int __init timer_init_sysfs(void) | 473 | static int __init timer_init_sysfs(void) |
385 | { | 474 | { |
386 | int ret = sysdev_class_register(&timer_sysclass); | 475 | int ret = sysdev_class_register(&timer_sysclass); |
@@ -388,6 +477,20 @@ static int __init timer_init_sysfs(void) | |||
388 | system_timer->dev.cls = &timer_sysclass; | 477 | system_timer->dev.cls = &timer_sysclass; |
389 | ret = sysdev_register(&system_timer->dev); | 478 | ret = sysdev_register(&system_timer->dev); |
390 | } | 479 | } |
480 | |||
481 | #ifdef CONFIG_NO_IDLE_HZ | ||
482 | if (ret == 0 && system_timer->dyn_tick) { | ||
483 | ret = sysdev_create_file(&system_timer->dev, &attr_dyn_tick); | ||
484 | |||
485 | /* | ||
486 | * Turn on dynamic tick after calibrate delay | ||
487 | * for correct bogomips | ||
488 | */ | ||
489 | if (ret == 0 && dyntick_str[0] == 'e') | ||
490 | ret = timer_dyn_tick_enable(); | ||
491 | } | ||
492 | #endif | ||
493 | |||
391 | return ret; | 494 | return ret; |
392 | } | 495 | } |
393 | 496 | ||
diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig index 45c930ccd064..0793dcf54f2e 100644 --- a/arch/arm/mach-clps711x/Kconfig +++ b/arch/arm/mach-clps711x/Kconfig | |||
@@ -28,7 +28,7 @@ config ARCH_CLEP7312 | |||
28 | config ARCH_EDB7211 | 28 | config ARCH_EDB7211 |
29 | bool "EDB7211" | 29 | bool "EDB7211" |
30 | select ISA | 30 | select ISA |
31 | select DISCONTIGMEM | 31 | select ARCH_DISCONTIGMEM_ENABLE |
32 | help | 32 | help |
33 | Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211 | 33 | Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211 |
34 | evaluation board. | 34 | evaluation board. |
diff --git a/arch/arm/mach-ixp2000/Kconfig b/arch/arm/mach-ixp2000/Kconfig index 9361e05f6fa3..ecb58d83478e 100644 --- a/arch/arm/mach-ixp2000/Kconfig +++ b/arch/arm/mach-ixp2000/Kconfig | |||
@@ -54,6 +54,14 @@ config ARCH_IXDP2X01 | |||
54 | depends on ARCH_IXDP2401 || ARCH_IXDP2801 | 54 | depends on ARCH_IXDP2401 || ARCH_IXDP2801 |
55 | default y | 55 | default y |
56 | 56 | ||
57 | config IXP2000_SUPPORT_BROKEN_PCI_IO | ||
58 | bool "Support broken PCI I/O on older IXP2000s" | ||
59 | default y | ||
60 | help | ||
61 | Say 'N' here if you only intend to run your kernel on an | ||
62 | IXP2000 B0 or later model and do not need the PCI I/O | ||
63 | byteswap workaround. Say 'Y' otherwise. | ||
64 | |||
57 | endmenu | 65 | endmenu |
58 | 66 | ||
59 | endif | 67 | endif |
diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c index 04b38bcf9aac..f3a291b6a9fb 100644 --- a/arch/arm/mach-ixp2000/enp2611.c +++ b/arch/arm/mach-ixp2000/enp2611.c | |||
@@ -197,8 +197,23 @@ static struct platform_device enp2611_flash = { | |||
197 | .resource = &enp2611_flash_resource, | 197 | .resource = &enp2611_flash_resource, |
198 | }; | 198 | }; |
199 | 199 | ||
200 | static struct ixp2000_i2c_pins enp2611_i2c_gpio_pins = { | ||
201 | .sda_pin = ENP2611_GPIO_SDA, | ||
202 | .scl_pin = ENP2611_GPIO_SCL, | ||
203 | }; | ||
204 | |||
205 | static struct platform_device enp2611_i2c_controller = { | ||
206 | .name = "IXP2000-I2C", | ||
207 | .id = 0, | ||
208 | .dev = { | ||
209 | .platform_data = &enp2611_i2c_gpio_pins | ||
210 | }, | ||
211 | .num_resources = 0 | ||
212 | }; | ||
213 | |||
200 | static struct platform_device *enp2611_devices[] __initdata = { | 214 | static struct platform_device *enp2611_devices[] __initdata = { |
201 | &enp2611_flash | 215 | &enp2611_flash, |
216 | &enp2611_i2c_controller | ||
202 | }; | 217 | }; |
203 | 218 | ||
204 | static void __init enp2611_init_machine(void) | 219 | static void __init enp2611_init_machine(void) |
diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c index 21c41fe15b99..5e4380747b53 100644 --- a/arch/arm/mach-ixp2000/ixdp2x00.c +++ b/arch/arm/mach-ixp2000/ixdp2x00.c | |||
@@ -42,6 +42,9 @@ | |||
42 | #include <asm/mach/flash.h> | 42 | #include <asm/mach/flash.h> |
43 | #include <asm/mach/arch.h> | 43 | #include <asm/mach/arch.h> |
44 | 44 | ||
45 | #include <asm/arch/gpio.h> | ||
46 | |||
47 | |||
45 | /************************************************************************* | 48 | /************************************************************************* |
46 | * IXDP2x00 IRQ Initialization | 49 | * IXDP2x00 IRQ Initialization |
47 | *************************************************************************/ | 50 | *************************************************************************/ |
diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c index 5ff2f2718c58..0788fb2b5c10 100644 --- a/arch/arm/mach-ixp2000/pci.c +++ b/arch/arm/mach-ixp2000/pci.c | |||
@@ -198,6 +198,19 @@ clear_master_aborts(void) | |||
198 | void __init | 198 | void __init |
199 | ixp2000_pci_preinit(void) | 199 | ixp2000_pci_preinit(void) |
200 | { | 200 | { |
201 | #ifndef CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO | ||
202 | /* | ||
203 | * Configure the PCI unit to properly byteswap I/O transactions, | ||
204 | * and verify that it worked. | ||
205 | */ | ||
206 | ixp2000_reg_write(IXP2000_PCI_CONTROL, | ||
207 | (*IXP2000_PCI_CONTROL | PCI_CONTROL_IEE)); | ||
208 | |||
209 | if ((*IXP2000_PCI_CONTROL & PCI_CONTROL_IEE) == 0) | ||
210 | panic("IXP2000: PCI I/O is broken on this ixp model, and " | ||
211 | "the needed workaround has not been configured in"); | ||
212 | #endif | ||
213 | |||
201 | hook_fault_code(16+6, ixp2000_pci_abort_handler, SIGBUS, | 214 | hook_fault_code(16+6, ixp2000_pci_abort_handler, SIGBUS, |
202 | "PCI config cycle to non-existent device"); | 215 | "PCI config cycle to non-existent device"); |
203 | } | 216 | } |
diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c index ef6865f0b979..767ebb55bd83 100644 --- a/arch/frv/kernel/setup.c +++ b/arch/frv/kernel/setup.c | |||
@@ -790,12 +790,10 @@ void __init setup_arch(char **cmdline_p) | |||
790 | #ifndef CONFIG_GDBSTUB_UART0 | 790 | #ifndef CONFIG_GDBSTUB_UART0 |
791 | __reg(UART0_BASE + UART_IER * 8) = 0; | 791 | __reg(UART0_BASE + UART_IER * 8) = 0; |
792 | early_serial_setup(&__frv_uart0); | 792 | early_serial_setup(&__frv_uart0); |
793 | // register_serial(&__frv_uart0); | ||
794 | #endif | 793 | #endif |
795 | #ifndef CONFIG_GDBSTUB_UART1 | 794 | #ifndef CONFIG_GDBSTUB_UART1 |
796 | __reg(UART1_BASE + UART_IER * 8) = 0; | 795 | __reg(UART1_BASE + UART_IER * 8) = 0; |
797 | early_serial_setup(&__frv_uart1); | 796 | early_serial_setup(&__frv_uart1); |
798 | // register_serial(&__frv_uart1); | ||
799 | #endif | 797 | #endif |
800 | 798 | ||
801 | #if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH) | 799 | #if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH) |
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index d4ae5f9ceae6..6c02336fe2e4 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig | |||
@@ -510,28 +510,7 @@ config SCHED_SMT | |||
510 | cost of slightly increased overhead in some places. If unsure say | 510 | cost of slightly increased overhead in some places. If unsure say |
511 | N here. | 511 | N here. |
512 | 512 | ||
513 | config PREEMPT | 513 | source "kernel/Kconfig.preempt" |
514 | bool "Preemptible Kernel" | ||
515 | help | ||
516 | This option reduces the latency of the kernel when reacting to | ||
517 | real-time or interactive events by allowing a low priority process to | ||
518 | be preempted even if it is in kernel mode executing a system call. | ||
519 | This allows applications to run more reliably even when the system is | ||
520 | under load. | ||
521 | |||
522 | Say Y here if you are building a kernel for a desktop, embedded | ||
523 | or real-time system. Say N if you are unsure. | ||
524 | |||
525 | config PREEMPT_BKL | ||
526 | bool "Preempt The Big Kernel Lock" | ||
527 | depends on PREEMPT | ||
528 | default y | ||
529 | help | ||
530 | This option reduces the latency of the kernel by making the | ||
531 | big kernel lock preemptible. | ||
532 | |||
533 | Say Y here if you are building a kernel for a desktop system. | ||
534 | Say N if you are unsure. | ||
535 | 514 | ||
536 | config X86_UP_APIC | 515 | config X86_UP_APIC |
537 | bool "Local APIC support on uniprocessors" | 516 | bool "Local APIC support on uniprocessors" |
@@ -963,6 +942,41 @@ config SECCOMP | |||
963 | 942 | ||
964 | source kernel/Kconfig.hz | 943 | source kernel/Kconfig.hz |
965 | 944 | ||
945 | config PHYSICAL_START | ||
946 | hex "Physical address where the kernel is loaded" if EMBEDDED | ||
947 | default "0x100000" | ||
948 | help | ||
949 | This gives the physical address where the kernel is loaded. | ||
950 | Primarily used in the case of kexec on panic where the | ||
951 | fail safe kernel needs to run at a different address than | ||
952 | the panic-ed kernel. | ||
953 | |||
954 | Don't change this unless you know what you are doing. | ||
955 | |||
956 | config KEXEC | ||
957 | bool "kexec system call (EXPERIMENTAL)" | ||
958 | depends on EXPERIMENTAL | ||
959 | help | ||
960 | kexec is a system call that implements the ability to shutdown your | ||
961 | current kernel, and to start another kernel. It is like a reboot | ||
962 | but it is indepedent of the system firmware. And like a reboot | ||
963 | you can start any kernel with it, not just Linux. | ||
964 | |||
965 | The name comes from the similiarity to the exec system call. | ||
966 | |||
967 | It is an ongoing process to be certain the hardware in a machine | ||
968 | is properly shutdown, so do not be surprised if this code does not | ||
969 | initially work for you. It may help to enable device hotplugging | ||
970 | support. As of this writing the exact hardware interface is | ||
971 | strongly in flux, so no good recommendation can be made. | ||
972 | |||
973 | config CRASH_DUMP | ||
974 | bool "kernel crash dumps (EXPERIMENTAL)" | ||
975 | depends on EMBEDDED | ||
976 | depends on EXPERIMENTAL | ||
977 | depends on HIGHMEM | ||
978 | help | ||
979 | Generate crash dump after being started by kexec. | ||
966 | endmenu | 980 | endmenu |
967 | 981 | ||
968 | 982 | ||
@@ -1250,6 +1264,15 @@ config SCx200 | |||
1250 | This support is also available as a module. If compiled as a | 1264 | This support is also available as a module. If compiled as a |
1251 | module, it will be called scx200. | 1265 | module, it will be called scx200. |
1252 | 1266 | ||
1267 | config HOTPLUG_CPU | ||
1268 | bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" | ||
1269 | depends on SMP && HOTPLUG && EXPERIMENTAL | ||
1270 | ---help--- | ||
1271 | Say Y here to experiment with turning CPUs off and on. CPUs | ||
1272 | can be controlled through /sys/devices/system/cpu. | ||
1273 | |||
1274 | Say N. | ||
1275 | |||
1253 | source "drivers/pcmcia/Kconfig" | 1276 | source "drivers/pcmcia/Kconfig" |
1254 | 1277 | ||
1255 | source "drivers/pci/hotplug/Kconfig" | 1278 | source "drivers/pci/hotplug/Kconfig" |
diff --git a/arch/i386/boot/Makefile b/arch/i386/boot/Makefile index 43cd6220ee49..1e71382d413a 100644 --- a/arch/i386/boot/Makefile +++ b/arch/i386/boot/Makefile | |||
@@ -25,8 +25,8 @@ SVGA_MODE := -DSVGA_MODE=NORMAL_VGA | |||
25 | 25 | ||
26 | #RAMDISK := -DRAMDISK=512 | 26 | #RAMDISK := -DRAMDISK=512 |
27 | 27 | ||
28 | targets := vmlinux.bin bootsect bootsect.o setup setup.o \ | 28 | targets := vmlinux.bin bootsect bootsect.o \ |
29 | zImage bzImage | 29 | setup setup.o zImage bzImage |
30 | subdir- := compressed | 30 | subdir- := compressed |
31 | 31 | ||
32 | hostprogs-y := tools/build | 32 | hostprogs-y := tools/build |
diff --git a/arch/i386/boot/compressed/head.S b/arch/i386/boot/compressed/head.S index c5e80b69e7d4..b5893e4ecd37 100644 --- a/arch/i386/boot/compressed/head.S +++ b/arch/i386/boot/compressed/head.S | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include <linux/linkage.h> | 26 | #include <linux/linkage.h> |
27 | #include <asm/segment.h> | 27 | #include <asm/segment.h> |
28 | #include <asm/page.h> | ||
28 | 29 | ||
29 | .globl startup_32 | 30 | .globl startup_32 |
30 | 31 | ||
@@ -74,7 +75,7 @@ startup_32: | |||
74 | popl %esi # discard address | 75 | popl %esi # discard address |
75 | popl %esi # real mode pointer | 76 | popl %esi # real mode pointer |
76 | xorl %ebx,%ebx | 77 | xorl %ebx,%ebx |
77 | ljmp $(__BOOT_CS), $0x100000 | 78 | ljmp $(__BOOT_CS), $__PHYSICAL_START |
78 | 79 | ||
79 | /* | 80 | /* |
80 | * We come here, if we were loaded high. | 81 | * We come here, if we were loaded high. |
@@ -99,7 +100,7 @@ startup_32: | |||
99 | popl %ecx # lcount | 100 | popl %ecx # lcount |
100 | popl %edx # high_buffer_start | 101 | popl %edx # high_buffer_start |
101 | popl %eax # hcount | 102 | popl %eax # hcount |
102 | movl $0x100000,%edi | 103 | movl $__PHYSICAL_START,%edi |
103 | cli # make sure we don't get interrupted | 104 | cli # make sure we don't get interrupted |
104 | ljmp $(__BOOT_CS), $0x1000 # and jump to the move routine | 105 | ljmp $(__BOOT_CS), $0x1000 # and jump to the move routine |
105 | 106 | ||
@@ -124,5 +125,5 @@ move_routine_start: | |||
124 | movsl | 125 | movsl |
125 | movl %ebx,%esi # Restore setup pointer | 126 | movl %ebx,%esi # Restore setup pointer |
126 | xorl %ebx,%ebx | 127 | xorl %ebx,%ebx |
127 | ljmp $(__BOOT_CS), $0x100000 | 128 | ljmp $(__BOOT_CS), $__PHYSICAL_START |
128 | move_routine_end: | 129 | move_routine_end: |
diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c index cedc55cc47de..82a807f9f5e6 100644 --- a/arch/i386/boot/compressed/misc.c +++ b/arch/i386/boot/compressed/misc.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/vmalloc.h> | 13 | #include <linux/vmalloc.h> |
14 | #include <linux/tty.h> | 14 | #include <linux/tty.h> |
15 | #include <asm/io.h> | 15 | #include <asm/io.h> |
16 | #include <asm/page.h> | ||
16 | 17 | ||
17 | /* | 18 | /* |
18 | * gzip declarations | 19 | * gzip declarations |
@@ -308,7 +309,7 @@ static void setup_normal_output_buffer(void) | |||
308 | #else | 309 | #else |
309 | if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < 1024) error("Less than 2MB of memory"); | 310 | if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < 1024) error("Less than 2MB of memory"); |
310 | #endif | 311 | #endif |
311 | output_data = (char *)0x100000; /* Points to 1M */ | 312 | output_data = (char *)__PHYSICAL_START; /* Normally Points to 1M */ |
312 | free_mem_end_ptr = (long)real_mode; | 313 | free_mem_end_ptr = (long)real_mode; |
313 | } | 314 | } |
314 | 315 | ||
@@ -333,8 +334,8 @@ static void setup_output_buffer_if_we_run_high(struct moveparams *mv) | |||
333 | low_buffer_size = low_buffer_end - LOW_BUFFER_START; | 334 | low_buffer_size = low_buffer_end - LOW_BUFFER_START; |
334 | high_loaded = 1; | 335 | high_loaded = 1; |
335 | free_mem_end_ptr = (long)high_buffer_start; | 336 | free_mem_end_ptr = (long)high_buffer_start; |
336 | if ( (0x100000 + low_buffer_size) > ((ulg)high_buffer_start)) { | 337 | if ( (__PHYSICAL_START + low_buffer_size) > ((ulg)high_buffer_start)) { |
337 | high_buffer_start = (uch *)(0x100000 + low_buffer_size); | 338 | high_buffer_start = (uch *)(__PHYSICAL_START + low_buffer_size); |
338 | mv->hcount = 0; /* say: we need not to move high_buffer */ | 339 | mv->hcount = 0; /* say: we need not to move high_buffer */ |
339 | } | 340 | } |
340 | else mv->hcount = -1; | 341 | else mv->hcount = -1; |
@@ -353,7 +354,6 @@ static void close_output_buffer_if_we_run_high(struct moveparams *mv) | |||
353 | } | 354 | } |
354 | } | 355 | } |
355 | 356 | ||
356 | |||
357 | asmlinkage int decompress_kernel(struct moveparams *mv, void *rmode) | 357 | asmlinkage int decompress_kernel(struct moveparams *mv, void *rmode) |
358 | { | 358 | { |
359 | real_mode = rmode; | 359 | real_mode = rmode; |
diff --git a/arch/i386/boot/edd.S b/arch/i386/boot/edd.S index 027d6b354ffb..d8d69f2b911d 100644 --- a/arch/i386/boot/edd.S +++ b/arch/i386/boot/edd.S | |||
@@ -6,7 +6,7 @@ | |||
6 | * projects 1572D, 1484D, 1386D, 1226DT | 6 | * projects 1572D, 1484D, 1386D, 1226DT |
7 | * disk signature read by Matt Domsch <Matt_Domsch@dell.com> | 7 | * disk signature read by Matt Domsch <Matt_Domsch@dell.com> |
8 | * and Andrew Wilks <Andrew_Wilks@dell.com> September 2003, June 2004 | 8 | * and Andrew Wilks <Andrew_Wilks@dell.com> September 2003, June 2004 |
9 | * legacy CHS retreival by Patrick J. LoPresti <patl@users.sourceforge.net> | 9 | * legacy CHS retrieval by Patrick J. LoPresti <patl@users.sourceforge.net> |
10 | * March 2004 | 10 | * March 2004 |
11 | * Command line option parsing, Matt Domsch, November 2004 | 11 | * Command line option parsing, Matt Domsch, November 2004 |
12 | */ | 12 | */ |
diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S index caa1fde6904e..8cb420f40c58 100644 --- a/arch/i386/boot/setup.S +++ b/arch/i386/boot/setup.S | |||
@@ -33,7 +33,7 @@ | |||
33 | * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999. | 33 | * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999. |
34 | * <stiker@northlink.com> | 34 | * <stiker@northlink.com> |
35 | * | 35 | * |
36 | * Fix to work around buggy BIOSes which dont use carry bit correctly | 36 | * Fix to work around buggy BIOSes which don't use carry bit correctly |
37 | * and/or report extended memory in CX/DX for e801h memory size detection | 37 | * and/or report extended memory in CX/DX for e801h memory size detection |
38 | * call. As a result the kernel got wrong figures. The int15/e801h docs | 38 | * call. As a result the kernel got wrong figures. The int15/e801h docs |
39 | * from Ralf Brown interrupt list seem to indicate AX/BX should be used | 39 | * from Ralf Brown interrupt list seem to indicate AX/BX should be used |
@@ -357,7 +357,7 @@ bail820: | |||
357 | 357 | ||
358 | meme801: | 358 | meme801: |
359 | stc # fix to work around buggy | 359 | stc # fix to work around buggy |
360 | xorw %cx,%cx # BIOSes which dont clear/set | 360 | xorw %cx,%cx # BIOSes which don't clear/set |
361 | xorw %dx,%dx # carry on pass/error of | 361 | xorw %dx,%dx # carry on pass/error of |
362 | # e801h memory size call | 362 | # e801h memory size call |
363 | # or merely pass cx,dx though | 363 | # or merely pass cx,dx though |
@@ -847,7 +847,7 @@ flush_instr: | |||
847 | # | 847 | # |
848 | # but we yet haven't reloaded the CS register, so the default size | 848 | # but we yet haven't reloaded the CS register, so the default size |
849 | # of the target offset still is 16 bit. | 849 | # of the target offset still is 16 bit. |
850 | # However, using an operand prefix (0x66), the CPU will properly | 850 | # However, using an operand prefix (0x66), the CPU will properly |
851 | # take our 48 bit far pointer. (INTeL 80386 Programmer's Reference | 851 | # take our 48 bit far pointer. (INTeL 80386 Programmer's Reference |
852 | # Manual, Mixing 16-bit and 32-bit code, page 16-6) | 852 | # Manual, Mixing 16-bit and 32-bit code, page 16-6) |
853 | 853 | ||
diff --git a/arch/i386/boot/tools/build.c b/arch/i386/boot/tools/build.c index 26509b826aed..4a17956512e1 100644 --- a/arch/i386/boot/tools/build.c +++ b/arch/i386/boot/tools/build.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: build.c,v 1.5 1997/05/19 12:29:58 mj Exp $ | ||
3 | * | ||
4 | * Copyright (C) 1991, 1992 Linus Torvalds | 2 | * Copyright (C) 1991, 1992 Linus Torvalds |
5 | * Copyright (C) 1997 Martin Mares | 3 | * Copyright (C) 1997 Martin Mares |
6 | */ | 4 | */ |
@@ -8,7 +6,8 @@ | |||
8 | /* | 6 | /* |
9 | * This file builds a disk-image from three different files: | 7 | * This file builds a disk-image from three different files: |
10 | * | 8 | * |
11 | * - bootsect: exactly 512 bytes of 8086 machine code, loads the rest | 9 | * - bootsect: compatibility mbr which prints an error message if |
10 | * someone tries to boot the kernel directly. | ||
12 | * - setup: 8086 machine code, sets up system parm | 11 | * - setup: 8086 machine code, sets up system parm |
13 | * - system: 80386 code for actual system | 12 | * - system: 80386 code for actual system |
14 | * | 13 | * |
diff --git a/arch/i386/crypto/aes.c b/arch/i386/crypto/aes.c index 1019430fc1f1..88ee85c3b43b 100644 --- a/arch/i386/crypto/aes.c +++ b/arch/i386/crypto/aes.c | |||
@@ -59,7 +59,7 @@ struct aes_ctx { | |||
59 | }; | 59 | }; |
60 | 60 | ||
61 | #define WPOLY 0x011b | 61 | #define WPOLY 0x011b |
62 | #define u32_in(x) le32_to_cpu(*(const u32 *)(x)) | 62 | #define u32_in(x) le32_to_cpup((const __le32 *)(x)) |
63 | #define bytes2word(b0, b1, b2, b3) \ | 63 | #define bytes2word(b0, b1, b2, b3) \ |
64 | (((u32)(b3) << 24) | ((u32)(b2) << 16) | ((u32)(b1) << 8) | (b0)) | 64 | (((u32)(b3) << 24) | ((u32)(b2) << 16) | ((u32)(b1) << 8) | (b0)) |
65 | 65 | ||
diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 28e620383799..ca07b95c06b8 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig | |||
@@ -126,7 +126,6 @@ CONFIG_HAVE_DEC_LOCK=y | |||
126 | # | 126 | # |
127 | CONFIG_PM=y | 127 | CONFIG_PM=y |
128 | CONFIG_SOFTWARE_SUSPEND=y | 128 | CONFIG_SOFTWARE_SUSPEND=y |
129 | # CONFIG_PM_DISK is not set | ||
130 | 129 | ||
131 | # | 130 | # |
132 | # ACPI (Advanced Configuration and Power Interface) Support | 131 | # ACPI (Advanced Configuration and Power Interface) Support |
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 | |||
24 | obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o | 24 | obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o |
25 | obj-$(CONFIG_X86_IO_APIC) += io_apic.o | 25 | obj-$(CONFIG_X86_IO_APIC) += io_apic.o |
26 | obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups.o | 26 | obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups.o |
27 | obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o | ||
27 | obj-$(CONFIG_X86_NUMAQ) += numaq.o | 28 | obj-$(CONFIG_X86_NUMAQ) += numaq.o |
28 | obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o | 29 | obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o |
29 | obj-$(CONFIG_KPROBES) += kprobes.o | 30 | obj-$(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 | ||
819 | extern int acpi_force; | ||
820 | |||
821 | #ifdef __i386__ | ||
822 | |||
823 | #ifdef CONFIG_ACPI_PCI | ||
824 | static 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 | |||
834 | static 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 | |||
845 | static 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 | */ | ||
860 | static 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 | */ | ||
877 | static 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 | |||
97 | static __init int reset_videomode_after_s3(struct dmi_system_id *d) | ||
98 | { | ||
99 | acpi_video_flags |= 2; | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static __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 | |||
114 | static int __init acpisleep_dmi_init(void) | ||
115 | { | ||
116 | dmi_check_system(acpisleep_dmi_table); | ||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | core_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 | */ | ||
46 | int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */ | ||
47 | |||
48 | /* | ||
43 | * Debug level | 49 | * Debug level |
44 | */ | 50 | */ |
45 | int apic_verbosity; | 51 | int apic_verbosity; |
@@ -205,7 +211,7 @@ void __init connect_bsp_APIC(void) | |||
205 | enable_apic_mode(); | 211 | enable_apic_mode(); |
206 | } | 212 | } |
207 | 213 | ||
208 | void disconnect_bsp_APIC(void) | 214 | void 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 | ||
224 | void disable_local_APIC(void) | 266 | void 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 | ||
366 | void __init setup_local_APIC (void) | 408 | void __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 | ||
637 | static void __init apic_pm_activate(void) | 679 | static 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 | */ | ||
671 | int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */ | ||
672 | |||
673 | static 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 | |||
681 | static int __init lapic_enable(char *str) | ||
682 | { | ||
683 | enable_local_apic = 1; | ||
684 | return 0; | ||
685 | } | ||
686 | __setup("lapic", lapic_enable); | ||
687 | |||
688 | static int __init apic_set_verbosity(char *str) | 710 | static 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 | */ |
858 | static unsigned int __init get_8254_timer_count(void) | 880 | static 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 */ |
877 | static void __init wait_8254_wraparound(void) | 899 | static 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 | */ |
897 | void (*wait_timer_tick)(void) __initdata = wait_8254_wraparound; | 919 | void (*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 | ||
933 | static void __init setup_APIC_timer(unsigned int clocks) | 955 | static 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 | ||
1046 | void __init setup_secondary_APIC_clock(void) | 1068 | void __devinit setup_secondary_APIC_clock(void) |
1047 | { | 1069 | { |
1048 | setup_APIC_timer(calibration_result); | 1070 | setup_APIC_timer(calibration_result); |
1049 | } | 1071 | } |
1050 | 1072 | ||
1051 | void __init disable_APIC_timer(void) | 1073 | void __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); | |||
346 | struct apm_user { | 346 | struct 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); | |||
24 | DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); | 24 | DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); |
25 | EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack); | 25 | EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack); |
26 | 26 | ||
27 | static int cachesize_override __initdata = -1; | 27 | static int cachesize_override __devinitdata = -1; |
28 | static int disable_x86_fxsr __initdata = 0; | 28 | static int disable_x86_fxsr __devinitdata = 0; |
29 | static int disable_x86_serial_nr __initdata = 1; | 29 | static int disable_x86_serial_nr __devinitdata = 1; |
30 | 30 | ||
31 | struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {}; | 31 | struct 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 | ||
62 | int __init get_model_name(struct cpuinfo_x86 *c) | 62 | int __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 | ||
92 | void __init display_cacheinfo(struct cpuinfo_x86 *c) | 92 | void __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. */ |
133 | static char __init *table_lookup_model(struct cpuinfo_x86 *c) | 133 | static 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 | ||
154 | void __init get_cpu_vendor(struct cpuinfo_x86 *c, int early) | 154 | void __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 */ |
205 | static int __init have_cpuid_p(void) | 205 | static 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 | ||
252 | void __init generic_identify(struct cpuinfo_x86 * c) | 252 | void __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 | ||
299 | static void __init squash_the_stupid_serial_number(struct cpuinfo_x86 *c) | 299 | static 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 | */ |
327 | void __init identify_cpu(struct cpuinfo_x86 *c) | 327 | void __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 |
438 | void __init detect_ht(struct cpuinfo_x86 *c) | 441 | void __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 | ||
493 | void __init print_cpu_info(struct cpuinfo_x86 *c) | 496 | void __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 | ||
516 | cpumask_t cpu_initialized __initdata = CPU_MASK_NONE; | 519 | cpumask_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 | */ |
563 | void __init cpu_init (void) | 566 | void __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 | ||
656 | void __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); | |||
28 | struct movsl_mask movsl_mask; | 28 | struct movsl_mask movsl_mask; |
29 | #endif | 29 | #endif |
30 | 30 | ||
31 | void __init early_intel_workaround(struct cpuinfo_x86 *c) | 31 | void __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 | ||
46 | int __init ppro_with_ram_bug(void) | 46 | int __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 | */ |
64 | static void __init Intel_errata_workarounds(struct cpuinfo_x86 *c) | 64 | static 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 | */ |
83 | static int __init num_cpu_cores(struct cpuinfo_x86 *c) | 83 | static 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 | ||
101 | static void __init init_intel(struct cpuinfo_x86 *c) | 101 | static 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 | ||
207 | static struct cpu_dev intel_cpu_dev __initdata = { | 207 | static 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) */ |
31 | static struct _cache_table cache_table[] __initdata = | 31 | static 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 | ||
163 | unsigned int __init init_intel_cacheinfo(struct cpuinfo_x86 *c) | 163 | unsigned 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 */ |
72 | void __init amd_mcheck_init(struct cpuinfo_x86 *c) | 72 | void __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 | ||
19 | int mce_disabled __initdata = 0; | 19 | int mce_disabled __devinitdata = 0; |
20 | int nr_mce_banks; | 20 | int nr_mce_banks; |
21 | 21 | ||
22 | EXPORT_SYMBOL_GPL(nr_mce_banks); /* non-fatal.o */ | 22 | EXPORT_SYMBOL_GPL(nr_mce_banks); /* non-fatal.o */ |
@@ -31,7 +31,7 @@ static fastcall void unexpected_machine_check(struct pt_regs * regs, long error_ | |||
31 | void fastcall (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check; | 31 | void 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 */ |
34 | void __init mcheck_init(struct cpuinfo_x86 *c) | 34 | void __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 */ |
81 | static void __init intel_init_thermal(struct cpuinfo_x86 *c) | 81 | static 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 | ||
235 | void __init intel_p4_mcheck_init(struct cpuinfo_x86 *c) | 235 | void __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 */ |
32 | void __init intel_p5_mcheck_init(struct cpuinfo_x86 *c) | 32 | void __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 */ |
83 | void __init intel_p6_mcheck_init(struct cpuinfo_x86 *c) | 83 | void __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 */ |
26 | void __init winchip_mcheck_init(struct cpuinfo_x86 *c) | 26 | void __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 */ |
71 | void __init finalize_mtrr_state(void) | 71 | void __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 | |||
30 | note_buf_t crash_notes[NR_CPUS]; | ||
31 | /* This keeps a track of which one is crashing cpu. */ | ||
32 | static int crashing_cpu; | ||
33 | |||
34 | static 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, ¬e, 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 | |||
52 | static 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, ¬e, sizeof(note)); | ||
60 | } | ||
61 | |||
62 | static 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 | |||
86 | static 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 | */ | ||
109 | static 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 | */ | ||
120 | static 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(®s, saved_regs); | ||
128 | else | ||
129 | crash_get_current_regs(®s); | ||
130 | crash_save_this_cpu(®s, cpu); | ||
131 | } | ||
132 | |||
133 | #ifdef CONFIG_SMP | ||
134 | static atomic_t waiting_for_crash_ipi; | ||
135 | |||
136 | static 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 | */ | ||
167 | static void smp_send_nmi_allbutself(void) | ||
168 | { | ||
169 | send_IPI_allbutself(APIC_DM_NMI); | ||
170 | } | ||
171 | |||
172 | static 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 | ||
196 | static void nmi_shootdown_cpus(void) | ||
197 | { | ||
198 | /* There are no cpus to shootdown */ | ||
199 | } | ||
200 | #endif | ||
201 | |||
202 | void 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 | ||
15 | struct dmi_header | 9 | struct 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 | ||
30 | static char * __init dmi_string(struct dmi_header *dm, u8 s) | 23 | static 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 | 41 | static int __init dmi_table(u32 base, int len, int num, | |
51 | static 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 | 76 | static int __init dmi_checksum(u8 *buf) | |
90 | inline 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 | ||
100 | static int __init dmi_iterate(void (*decode)(struct dmi_header *)) | 87 | static 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 | |||
147 | static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string) | 135 | static 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 | |||
173 | static __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 | ||
181 | static __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 | ||
192 | extern int acpi_force; | ||
193 | |||
194 | static __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 | */ | ||
209 | static __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 | ||
224 | static __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 | } | ||
233 | static __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 | |||
254 | static __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 | |||
386 | static void __init dmi_decode(struct dmi_header *dm) | 157 | static 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 | ||
432 | void __init dmi_scan_machine(void) | 191 | void __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 | |||
474 | EXPORT_SYMBOL(dmi_check_system); | 229 | EXPORT_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 | */ |
483 | char * dmi_get_system_info(int field) | 238 | char *dmi_get_system_info(int field) |
484 | { | 239 | { |
485 | return dmi_ident[field]; | 240 | return dmi_ident[field]; |
486 | } | 241 | } |
487 | 242 | EXPORT_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 | ||
271 | static 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 | |||
271 | static struct sysdev_class i8259_sysdev_class = { | 282 | static 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 | ||
277 | static struct sys_device device_i8259A = { | 289 | static struct sys_device device_i8259A = { |
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 2451a3a99440..35eb8e29c485 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c | |||
@@ -576,9 +576,11 @@ static int balanced_irq(void *unused) | |||
576 | try_to_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"); |
631 | failed: | 633 | failed: |
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 | */ |
1635 | void disable_IO_APIC(void) | 1635 | void 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 | ||
19 | DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_maxaligned_in_smp; | 22 | DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_maxaligned_in_smp; |
20 | EXPORT_PER_CPU_SYMBOL(irq_stat); | 23 | EXPORT_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 | ||
159 | void irq_ctx_exit(int cpu) | ||
160 | { | ||
161 | hardirq_ctx[cpu] = NULL; | ||
162 | } | ||
163 | |||
156 | extern asmlinkage void __do_softirq(void); | 164 | extern asmlinkage void __do_softirq(void); |
157 | 165 | ||
158 | asmlinkage void do_softirq(void) | 166 | asmlinkage 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 | |||
270 | void 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 | |||
20 | static 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) | ||
37 | static u32 pgtable_level1[1024] PAGE_ALIGNED; | ||
38 | |||
39 | static 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) | ||
64 | static u64 pgtable_level1[512] PAGE_ALIGNED; | ||
65 | static u64 pgtable_level2[512] PAGE_ALIGNED; | ||
66 | |||
67 | static 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 | |||
94 | static 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 | |||
109 | static 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 | |||
123 | static 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 | |||
142 | typedef 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 | |||
148 | const extern unsigned char relocate_new_kernel[]; | ||
149 | extern void relocate_new_kernel_end(void); | ||
150 | const 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 | */ | ||
165 | int 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 | */ | ||
174 | void 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 | */ | ||
182 | NORET_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 */ |
69 | unsigned int boot_cpu_physical_apicid = -1U; | 69 | unsigned int boot_cpu_physical_apicid = -1U; |
70 | unsigned int boot_cpu_logical_apicid = -1U; | ||
71 | /* Internal processor count */ | 70 | /* Internal processor count */ |
72 | static unsigned int __initdata num_processors; | 71 | static 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 | |||
58 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); | 62 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); |
59 | 63 | ||
60 | static int hlt_counter; | 64 | static 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. */ | ||
153 | static 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 | ||
170 | static 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 | */ |
152 | void cpu_idle (void) | 182 | void 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 | ||
226 | void __init select_idle_routine(const struct cpuinfo_x86 *c) | 261 | void __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; | |||
26 | static int reboot_thru_bios; | 26 | static int reboot_thru_bios; |
27 | 27 | ||
28 | #ifdef CONFIG_SMP | 28 | #ifdef CONFIG_SMP |
29 | int reboot_smp = 0; | ||
30 | static int reboot_cpu = -1; | 29 | static 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 | */ | ||
94 | static 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 | */ | ||
108 | static 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 | |||
115 | static struct dmi_system_id __initdata reboot_dmi_table[] = { | 89 | static 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) | |||
301 | EXPORT_SYMBOL(machine_real_restart); | 275 | EXPORT_SYMBOL(machine_real_restart); |
302 | #endif | 276 | #endif |
303 | 277 | ||
304 | void machine_restart(char * __unused) | 278 | void 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 | |||
314 | void 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 | ||
16 | relocate_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 | ||
57 | 1: | ||
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 | |||
67 | 0: /* top, read another word from the indirection page */ | ||
68 | movl (%ebx), %ecx | ||
69 | addl $4, %ebx | ||
70 | 1: | ||
71 | testl $0x1, %ecx /* is it a destination page */ | ||
72 | jz 2f | ||
73 | movl %ecx, %edi | ||
74 | andl $0xfffff000, %edi | ||
75 | jmp 0b | ||
76 | 2: | ||
77 | testl $0x2, %ecx /* is it an indirection page */ | ||
78 | jz 2f | ||
79 | movl %ecx, %ebx | ||
80 | andl $0xfffff000, %ebx | ||
81 | jmp 0b | ||
82 | 2: | ||
83 | testl $0x4, %ecx /* is it the done indicator */ | ||
84 | jz 2f | ||
85 | jmp 3f | ||
86 | 2: | ||
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 | |||
96 | 3: | ||
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 | ||
116 | relocate_new_kernel_end: | ||
117 | |||
118 | .globl relocate_new_kernel_size | ||
119 | relocate_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. */ | ||
64 | void __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! */ |
61 | unsigned long init_pg_tables_end __initdata = ~0UL; | 69 | unsigned long init_pg_tables_end __initdata = ~0UL; |
62 | 70 | ||
63 | int disable_pse __initdata = 0; | 71 | int 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/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: | |||
346 | static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm, | 347 | static 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 | */ |
477 | void smp_send_reschedule(int cpu) | 478 | void 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 | ||
498 | void lock_ipi_call_lock(void) | ||
499 | { | ||
500 | spin_lock_irq(&call_lock); | ||
501 | } | ||
502 | |||
503 | void unlock_ipi_call_lock(void) | ||
504 | { | ||
505 | spin_unlock_irq(&call_lock); | ||
506 | } | ||
507 | |||
496 | static struct call_data_struct * call_data; | 508 | static 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 */ |
59 | static int __initdata smp_b_stepping; | 62 | static int __devinitdata smp_b_stepping; |
60 | 63 | ||
61 | /* Number of siblings per CPU package */ | 64 | /* Number of siblings per CPU package */ |
62 | int smp_num_siblings = 1; | 65 | int smp_num_siblings = 1; |
63 | #ifdef CONFIG_X86_HT | 66 | #ifdef CONFIG_X86_HT |
64 | EXPORT_SYMBOL(smp_num_siblings); | 67 | EXPORT_SYMBOL(smp_num_siblings); |
65 | #endif | 68 | #endif |
66 | int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */ | 69 | |
70 | /* Package ID of each logical CPU */ | ||
71 | int phys_proc_id[NR_CPUS] = {[0 ... NR_CPUS-1] = BAD_APICID}; | ||
67 | EXPORT_SYMBOL(phys_proc_id); | 72 | EXPORT_SYMBOL(phys_proc_id); |
68 | int cpu_core_id[NR_CPUS]; /* Core ID of each logical CPU */ | 73 | |
74 | /* Core ID of each logical CPU */ | ||
75 | int cpu_core_id[NR_CPUS] = {[0 ... NR_CPUS-1] = BAD_APICID}; | ||
69 | EXPORT_SYMBOL(cpu_core_id); | 76 | EXPORT_SYMBOL(cpu_core_id); |
70 | 77 | ||
78 | cpumask_t cpu_sibling_map[NR_CPUS]; | ||
79 | EXPORT_SYMBOL(cpu_sibling_map); | ||
80 | |||
81 | cpumask_t cpu_core_map[NR_CPUS]; | ||
82 | EXPORT_SYMBOL(cpu_core_map); | ||
83 | |||
71 | /* bitmap of online cpus */ | 84 | /* bitmap of online cpus */ |
72 | cpumask_t cpu_online_map; | 85 | cpumask_t cpu_online_map; |
73 | EXPORT_SYMBOL(cpu_online_map); | 86 | EXPORT_SYMBOL(cpu_online_map); |
@@ -77,6 +90,12 @@ cpumask_t cpu_callout_map; | |||
77 | EXPORT_SYMBOL(cpu_callout_map); | 90 | EXPORT_SYMBOL(cpu_callout_map); |
78 | static cpumask_t smp_commenced_mask; | 91 | static 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 | */ | ||
97 | static int __devinitdata tsc_sync_disabled; | ||
98 | |||
80 | /* Per CPU bogomips and other parameters */ | 99 | /* Per CPU bogomips and other parameters */ |
81 | struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; | 100 | struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; |
82 | EXPORT_SYMBOL(cpu_data); | 101 | EXPORT_SYMBOL(cpu_data); |
@@ -96,13 +115,16 @@ static int trampoline_exec; | |||
96 | 115 | ||
97 | static void map_cpu_to_logical_apicid(void); | 116 | static void map_cpu_to_logical_apicid(void); |
98 | 117 | ||
118 | /* State of each CPU. */ | ||
119 | DEFINE_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 | ||
105 | static unsigned long __init setup_trampoline(void) | 127 | static 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 | ||
135 | static void __init smp_store_cpu_info(int id) | 157 | static 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 | ||
327 | static atomic_t init_deasserted; | 349 | static atomic_t init_deasserted; |
328 | 350 | ||
329 | static void __init smp_callin(void) | 351 | static 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 | ||
418 | static int cpucount; | 440 | static int cpucount; |
419 | 441 | ||
442 | static inline void | ||
443 | set_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 | */ |
423 | static void __init start_secondary(void *unused) | 477 | static 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 | */ |
461 | void __init initialize_secondary(void) | 531 | void __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 | */ |
575 | static int __init | 645 | static int __devinit |
576 | wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip) | 646 | wakeup_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 |
621 | static int __init | 691 | static int __devinit |
622 | wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) | 692 | wakeup_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 | ||
755 | extern cpumask_t cpu_initialized; | 825 | extern cpumask_t cpu_initialized; |
826 | static 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 | ||
838 | static struct task_struct * __devinitdata cpu_idle_tasks[NR_CPUS]; | ||
839 | static 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 | ||
757 | static int __init do_boot_cpu(int apicid) | 862 | static 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 | ||
967 | void 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 | |||
985 | struct warm_boot_cpu_info { | ||
986 | struct completion *complete; | ||
987 | int apicid; | ||
988 | int cpu; | ||
989 | }; | ||
990 | |||
991 | static 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 | |||
998 | int __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; | ||
1029 | exit: | ||
1030 | unlock_cpu_hotplug(); | ||
1031 | return ret; | ||
1032 | } | ||
1033 | #endif | ||
1034 | |||
857 | static void smp_tune_scheduling (void) | 1035 | static void smp_tune_scheduling (void) |
858 | { | 1036 | { |
859 | unsigned long cachesize; /* kB */ | 1037 | unsigned long cachesize; /* kB */ |
@@ -895,13 +1073,6 @@ void *xquad_portio; | |||
895 | EXPORT_SYMBOL(xquad_portio); | 1073 | EXPORT_SYMBOL(xquad_portio); |
896 | #endif | 1074 | #endif |
897 | 1075 | ||
898 | cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; | ||
899 | #ifdef CONFIG_X86_HT | ||
900 | EXPORT_SYMBOL(cpu_sibling_map); | ||
901 | #endif | ||
902 | cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; | ||
903 | EXPORT_SYMBOL(cpu_core_map); | ||
904 | |||
905 | static void __init smp_boot_cpus(unsigned int max_cpus) | 1076 | static 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 */ |
1120 | void __init smp_prepare_cpus(unsigned int max_cpus) | 1255 | void __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 | ||
1131 | int __devinit __cpu_up(unsigned int cpu) | 1271 | #ifdef CONFIG_HOTPLUG_CPU |
1272 | static void | ||
1273 | remove_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 | |||
1287 | int __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 | |||
1319 | void __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 */ | ||
1336 | int __cpu_disable(void) | ||
1337 | { | ||
1338 | return -ENOSYS; | ||
1339 | } | ||
1340 | |||
1341 | void __cpu_die(unsigned int cpu) | ||
1342 | { | ||
1343 | /* We said "no" in __cpu_disable */ | ||
1344 | BUG(); | ||
1345 | } | ||
1346 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
1138 | 1347 | ||
1348 | int __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 | ||
1165 | void __init smp_intr_init(void) | 1380 | void __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 | ||
22 | extern asmlinkage void sysenter_entry(void); | 22 | extern asmlinkage void sysenter_entry(void); |
23 | 23 | ||
24 | void enable_sep_cpu(void *info) | 24 | void 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) | |||
41 | extern const char vsyscall_int80_start, vsyscall_int80_end; | 46 | extern const char vsyscall_int80_start, vsyscall_int80_end; |
42 | extern const char vsyscall_sysenter_start, vsyscall_sysenter_end; | 47 | extern const char vsyscall_sysenter_start, vsyscall_sysenter_end; |
43 | 48 | ||
44 | static int __init sysenter_setup(void) | 49 | int __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 | */ |
53 | static void __init wait_hpet_tick(void) | 53 | static 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 | ||
89 | unsigned long __init calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr) | 89 | unsigned 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 | ||
34 | static inline void cpufreq_delayed_get(void); | 34 | static inline void cpufreq_delayed_get(void); |
35 | 35 | ||
36 | int tsc_disable __initdata = 0; | 36 | int tsc_disable __devinitdata = 0; |
37 | 37 | ||
38 | extern spinlock_t i8253_lock; | 38 | extern 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 | */ | ||
297 | void die(const char * str, struct pt_regs * regs, long err) | 301 | void 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 | |||
361 | static void do_trap(int trapnr, int signr, char *str, int vm86, | 369 | static 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 | ||
9 | OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") | 11 | OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") |
10 | OUTPUT_ARCH(i386) | 12 | OUTPUT_ARCH(i386) |
11 | ENTRY(startup_32) | 13 | ENTRY(phys_startup_32) |
12 | jiffies = jiffies_64; | 14 | jiffies = jiffies_64; |
13 | SECTIONS | 15 | SECTIONS |
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); |
diff --git a/arch/i386/mach-default/setup.c b/arch/i386/mach-default/setup.c index 0aa08eaa8932..e5a1a83d09ef 100644 --- a/arch/i386/mach-default/setup.c +++ b/arch/i386/mach-default/setup.c | |||
@@ -10,6 +10,14 @@ | |||
10 | #include <asm/acpi.h> | 10 | #include <asm/acpi.h> |
11 | #include <asm/arch_hooks.h> | 11 | #include <asm/arch_hooks.h> |
12 | 12 | ||
13 | #ifdef CONFIG_HOTPLUG_CPU | ||
14 | #define DEFAULT_SEND_IPI (1) | ||
15 | #else | ||
16 | #define DEFAULT_SEND_IPI (0) | ||
17 | #endif | ||
18 | |||
19 | int no_broadcast=DEFAULT_SEND_IPI; | ||
20 | |||
13 | /** | 21 | /** |
14 | * pre_intr_init_hook - initialisation prior to setting up interrupt vectors | 22 | * pre_intr_init_hook - initialisation prior to setting up interrupt vectors |
15 | * | 23 | * |
@@ -104,3 +112,22 @@ void __init mca_nmi_hook(void) | |||
104 | printk("NMI generated from unknown source!\n"); | 112 | printk("NMI generated from unknown source!\n"); |
105 | } | 113 | } |
106 | #endif | 114 | #endif |
115 | |||
116 | static __init int no_ipi_broadcast(char *str) | ||
117 | { | ||
118 | get_option(&str, &no_broadcast); | ||
119 | printk ("Using %s mode\n", no_broadcast ? "No IPI Broadcast" : | ||
120 | "IPI Broadcast"); | ||
121 | return 1; | ||
122 | } | ||
123 | |||
124 | __setup("no_ipi_broadcast", no_ipi_broadcast); | ||
125 | |||
126 | static int __init print_ipi_mode(void) | ||
127 | { | ||
128 | printk ("Using IPI %s mode\n", no_broadcast ? "No-Shortcut" : | ||
129 | "Shortcut"); | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | late_initcall(print_ipi_mode); | ||
diff --git a/arch/i386/mach-default/topology.c b/arch/i386/mach-default/topology.c index 5b3e8817dae8..23395fff35d1 100644 --- a/arch/i386/mach-default/topology.c +++ b/arch/i386/mach-default/topology.c | |||
@@ -73,12 +73,11 @@ static int __init topology_init(void) | |||
73 | { | 73 | { |
74 | int i; | 74 | int i; |
75 | 75 | ||
76 | for (i = 0; i < MAX_NUMNODES; i++) { | 76 | for_each_online_node(i) |
77 | if (node_online(i)) | 77 | arch_register_node(i); |
78 | arch_register_node(i); | 78 | |
79 | } | 79 | for_each_cpu(i) |
80 | for (i = 0; i < NR_CPUS; i++) | 80 | arch_register_cpu(i); |
81 | if (cpu_possible(i)) arch_register_cpu(i); | ||
82 | return 0; | 81 | return 0; |
83 | } | 82 | } |
84 | 83 | ||
@@ -88,8 +87,8 @@ static int __init topology_init(void) | |||
88 | { | 87 | { |
89 | int i; | 88 | int i; |
90 | 89 | ||
91 | for (i = 0; i < NR_CPUS; i++) | 90 | for_each_cpu(i) |
92 | if (cpu_possible(i)) arch_register_cpu(i); | 91 | arch_register_cpu(i); |
93 | return 0; | 92 | return 0; |
94 | } | 93 | } |
95 | 94 | ||
diff --git a/arch/i386/mach-visws/mpparse.c b/arch/i386/mach-visws/mpparse.c index 5a22082147f4..5f3d7e6de37b 100644 --- a/arch/i386/mach-visws/mpparse.c +++ b/arch/i386/mach-visws/mpparse.c | |||
@@ -23,7 +23,6 @@ unsigned long mp_lapic_addr; | |||
23 | 23 | ||
24 | /* Processor that is doing the boot up */ | 24 | /* Processor that is doing the boot up */ |
25 | unsigned int boot_cpu_physical_apicid = -1U; | 25 | unsigned int boot_cpu_physical_apicid = -1U; |
26 | unsigned int boot_cpu_logical_apicid = -1U; | ||
27 | 26 | ||
28 | /* Bitmask of physically existing CPUs */ | 27 | /* Bitmask of physically existing CPUs */ |
29 | physid_mask_t phys_cpu_present_map; | 28 | physid_mask_t phys_cpu_present_map; |
@@ -52,10 +51,8 @@ static void __init MP_processor_info (struct mpc_config_processor *m) | |||
52 | (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, | 51 | (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, |
53 | m->mpc_apicver); | 52 | m->mpc_apicver); |
54 | 53 | ||
55 | if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { | 54 | if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) |
56 | boot_cpu_physical_apicid = m->mpc_apicid; | 55 | boot_cpu_physical_apicid = m->mpc_apicid; |
57 | boot_cpu_logical_apicid = logical_apicid; | ||
58 | } | ||
59 | 56 | ||
60 | ver = m->mpc_apicver; | 57 | ver = m->mpc_apicver; |
61 | if ((ver >= 0x14 && m->mpc_apicid >= 0xff) || m->mpc_apicid >= 0xf) { | 58 | if ((ver >= 0x14 && m->mpc_apicid >= 0xff) || m->mpc_apicid >= 0xf) { |
diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c index f429c871e845..b358f0702a44 100644 --- a/arch/i386/mm/discontig.c +++ b/arch/i386/mm/discontig.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include <linux/initrd.h> | 30 | #include <linux/initrd.h> |
31 | #include <linux/nodemask.h> | 31 | #include <linux/nodemask.h> |
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/kexec.h> | ||
34 | |||
33 | #include <asm/e820.h> | 35 | #include <asm/e820.h> |
34 | #include <asm/setup.h> | 36 | #include <asm/setup.h> |
35 | #include <asm/mmzone.h> | 37 | #include <asm/mmzone.h> |
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c index a509237c4815..8e90339d6eaa 100644 --- a/arch/i386/mm/fault.c +++ b/arch/i386/mm/fault.c | |||
@@ -146,7 +146,7 @@ static int __is_prefetch(struct pt_regs *regs, unsigned long addr) | |||
146 | 146 | ||
147 | if (instr > limit) | 147 | if (instr > limit) |
148 | break; | 148 | break; |
149 | if (__get_user(opcode, (unsigned char *) instr)) | 149 | if (__get_user(opcode, (unsigned char __user *) instr)) |
150 | break; | 150 | break; |
151 | 151 | ||
152 | instr_hi = opcode & 0xf0; | 152 | instr_hi = opcode & 0xf0; |
@@ -173,7 +173,7 @@ static int __is_prefetch(struct pt_regs *regs, unsigned long addr) | |||
173 | scan_more = 0; | 173 | scan_more = 0; |
174 | if (instr > limit) | 174 | if (instr > limit) |
175 | break; | 175 | break; |
176 | if (__get_user(opcode, (unsigned char *) instr)) | 176 | if (__get_user(opcode, (unsigned char __user *) instr)) |
177 | break; | 177 | break; |
178 | prefetch = (instr_lo == 0xF) && | 178 | prefetch = (instr_lo == 0xF) && |
179 | (opcode == 0x0D || opcode == 0x18); | 179 | (opcode == 0x0D || opcode == 0x18); |
@@ -463,6 +463,9 @@ no_context: | |||
463 | printk(KERN_ALERT "*pte = %08lx\n", page); | 463 | printk(KERN_ALERT "*pte = %08lx\n", page); |
464 | } | 464 | } |
465 | #endif | 465 | #endif |
466 | tsk->thread.cr2 = address; | ||
467 | tsk->thread.trap_no = 14; | ||
468 | tsk->thread.error_code = error_code; | ||
466 | die("Oops", regs, error_code); | 469 | die("Oops", regs, error_code); |
467 | bust_spinlocks(0); | 470 | bust_spinlocks(0); |
468 | do_exit(SIGKILL); | 471 | do_exit(SIGKILL); |
diff --git a/arch/i386/mm/highmem.c b/arch/i386/mm/highmem.c index 4b7aaf99d7ea..b6eb4dcb8777 100644 --- a/arch/i386/mm/highmem.c +++ b/arch/i386/mm/highmem.c | |||
@@ -75,6 +75,24 @@ void kunmap_atomic(void *kvaddr, enum km_type type) | |||
75 | preempt_check_resched(); | 75 | preempt_check_resched(); |
76 | } | 76 | } |
77 | 77 | ||
78 | /* This is the same as kmap_atomic() but can map memory that doesn't | ||
79 | * have a struct page associated with it. | ||
80 | */ | ||
81 | void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) | ||
82 | { | ||
83 | enum fixed_addresses idx; | ||
84 | unsigned long vaddr; | ||
85 | |||
86 | inc_preempt_count(); | ||
87 | |||
88 | idx = type + KM_TYPE_NR*smp_processor_id(); | ||
89 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | ||
90 | set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot)); | ||
91 | __flush_tlb_one(vaddr); | ||
92 | |||
93 | return (void*) vaddr; | ||
94 | } | ||
95 | |||
78 | struct page *kmap_atomic_to_page(void *ptr) | 96 | struct page *kmap_atomic_to_page(void *ptr) |
79 | { | 97 | { |
80 | unsigned long idx, vaddr = (unsigned long)ptr; | 98 | unsigned long idx, vaddr = (unsigned long)ptr; |
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 3672e2ef51ae..12216b52e28b 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c | |||
@@ -352,7 +352,7 @@ static void __init pagetable_init (void) | |||
352 | #endif | 352 | #endif |
353 | } | 353 | } |
354 | 354 | ||
355 | #if defined(CONFIG_PM_DISK) || defined(CONFIG_SOFTWARE_SUSPEND) | 355 | #ifdef CONFIG_SOFTWARE_SUSPEND |
356 | /* | 356 | /* |
357 | * Swap suspend & friends need this for resume because things like the intel-agp | 357 | * Swap suspend & friends need this for resume because things like the intel-agp |
358 | * driver might have split up a kernel 4MB mapping. | 358 | * driver might have split up a kernel 4MB mapping. |
diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c index d393eefc7052..6b25afc933b6 100644 --- a/arch/i386/mm/ioremap.c +++ b/arch/i386/mm/ioremap.c | |||
@@ -243,7 +243,7 @@ void iounmap(volatile void __iomem *addr) | |||
243 | write_lock(&vmlist_lock); | 243 | write_lock(&vmlist_lock); |
244 | p = __remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr)); | 244 | p = __remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr)); |
245 | if (!p) { | 245 | if (!p) { |
246 | printk("iounmap: bad address %p\n", addr); | 246 | printk(KERN_WARNING "iounmap: bad address %p\n", addr); |
247 | goto out_unlock; | 247 | goto out_unlock; |
248 | } | 248 | } |
249 | 249 | ||
diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c index 270c59f099a4..bd2f7afc7a2a 100644 --- a/arch/i386/mm/pgtable.c +++ b/arch/i386/mm/pgtable.c | |||
@@ -32,9 +32,9 @@ void show_mem(void) | |||
32 | unsigned long i; | 32 | unsigned long i; |
33 | struct page_state ps; | 33 | struct page_state ps; |
34 | 34 | ||
35 | printk("Mem-info:\n"); | 35 | printk(KERN_INFO "Mem-info:\n"); |
36 | show_free_areas(); | 36 | show_free_areas(); |
37 | printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); | 37 | printk(KERN_INFO "Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); |
38 | for_each_pgdat(pgdat) { | 38 | for_each_pgdat(pgdat) { |
39 | for (i = 0; i < pgdat->node_spanned_pages; ++i) { | 39 | for (i = 0; i < pgdat->node_spanned_pages; ++i) { |
40 | page = pgdat_page_nr(pgdat, i); | 40 | page = pgdat_page_nr(pgdat, i); |
@@ -49,18 +49,18 @@ void show_mem(void) | |||
49 | shared += page_count(page) - 1; | 49 | shared += page_count(page) - 1; |
50 | } | 50 | } |
51 | } | 51 | } |
52 | printk("%d pages of RAM\n", total); | 52 | printk(KERN_INFO "%d pages of RAM\n", total); |
53 | printk("%d pages of HIGHMEM\n",highmem); | 53 | printk(KERN_INFO "%d pages of HIGHMEM\n", highmem); |
54 | printk("%d reserved pages\n",reserved); | 54 | printk(KERN_INFO "%d reserved pages\n", reserved); |
55 | printk("%d pages shared\n",shared); | 55 | printk(KERN_INFO "%d pages shared\n", shared); |
56 | printk("%d pages swap cached\n",cached); | 56 | printk(KERN_INFO "%d pages swap cached\n", cached); |
57 | 57 | ||
58 | get_page_state(&ps); | 58 | get_page_state(&ps); |
59 | printk("%lu pages dirty\n", ps.nr_dirty); | 59 | printk(KERN_INFO "%lu pages dirty\n", ps.nr_dirty); |
60 | printk("%lu pages writeback\n", ps.nr_writeback); | 60 | printk(KERN_INFO "%lu pages writeback\n", ps.nr_writeback); |
61 | printk("%lu pages mapped\n", ps.nr_mapped); | 61 | printk(KERN_INFO "%lu pages mapped\n", ps.nr_mapped); |
62 | printk("%lu pages slab\n", ps.nr_slab); | 62 | printk(KERN_INFO "%lu pages slab\n", ps.nr_slab); |
63 | printk("%lu pages pagetables\n", ps.nr_page_table_pages); | 63 | printk(KERN_INFO "%lu pages pagetables\n", ps.nr_page_table_pages); |
64 | } | 64 | } |
65 | 65 | ||
66 | /* | 66 | /* |
@@ -113,16 +113,16 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags) | |||
113 | pmd_t *pmd; | 113 | pmd_t *pmd; |
114 | 114 | ||
115 | if (vaddr & (PMD_SIZE-1)) { /* vaddr is misaligned */ | 115 | if (vaddr & (PMD_SIZE-1)) { /* vaddr is misaligned */ |
116 | printk ("set_pmd_pfn: vaddr misaligned\n"); | 116 | printk(KERN_WARNING "set_pmd_pfn: vaddr misaligned\n"); |
117 | return; /* BUG(); */ | 117 | return; /* BUG(); */ |
118 | } | 118 | } |
119 | if (pfn & (PTRS_PER_PTE-1)) { /* pfn is misaligned */ | 119 | if (pfn & (PTRS_PER_PTE-1)) { /* pfn is misaligned */ |
120 | printk ("set_pmd_pfn: pfn misaligned\n"); | 120 | printk(KERN_WARNING "set_pmd_pfn: pfn misaligned\n"); |
121 | return; /* BUG(); */ | 121 | return; /* BUG(); */ |
122 | } | 122 | } |
123 | pgd = swapper_pg_dir + pgd_index(vaddr); | 123 | pgd = swapper_pg_dir + pgd_index(vaddr); |
124 | if (pgd_none(*pgd)) { | 124 | if (pgd_none(*pgd)) { |
125 | printk ("set_pmd_pfn: pgd_none\n"); | 125 | printk(KERN_WARNING "set_pmd_pfn: pgd_none\n"); |
126 | return; /* BUG(); */ | 126 | return; /* BUG(); */ |
127 | } | 127 | } |
128 | pud = pud_offset(pgd, vaddr); | 128 | pud = pud_offset(pgd, vaddr); |
diff --git a/arch/i386/power/cpu.c b/arch/i386/power/cpu.c index 6f521cf19a13..0e6b45b61251 100644 --- a/arch/i386/power/cpu.c +++ b/arch/i386/power/cpu.c | |||
@@ -22,9 +22,11 @@ | |||
22 | #include <linux/device.h> | 22 | #include <linux/device.h> |
23 | #include <linux/suspend.h> | 23 | #include <linux/suspend.h> |
24 | #include <linux/acpi.h> | 24 | #include <linux/acpi.h> |
25 | |||
25 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
26 | #include <asm/acpi.h> | 27 | #include <asm/acpi.h> |
27 | #include <asm/tlbflush.h> | 28 | #include <asm/tlbflush.h> |
29 | #include <asm/processor.h> | ||
28 | 30 | ||
29 | static struct saved_context saved_context; | 31 | static struct saved_context saved_context; |
30 | 32 | ||
@@ -33,8 +35,6 @@ unsigned long saved_context_esp, saved_context_ebp; | |||
33 | unsigned long saved_context_esi, saved_context_edi; | 35 | unsigned long saved_context_esi, saved_context_edi; |
34 | unsigned long saved_context_eflags; | 36 | unsigned long saved_context_eflags; |
35 | 37 | ||
36 | extern void enable_sep_cpu(void *); | ||
37 | |||
38 | void __save_processor_state(struct saved_context *ctxt) | 38 | void __save_processor_state(struct saved_context *ctxt) |
39 | { | 39 | { |
40 | kernel_fpu_begin(); | 40 | kernel_fpu_begin(); |
@@ -44,7 +44,6 @@ void __save_processor_state(struct saved_context *ctxt) | |||
44 | */ | 44 | */ |
45 | asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit)); | 45 | asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit)); |
46 | asm volatile ("sidt %0" : "=m" (ctxt->idt_limit)); | 46 | asm volatile ("sidt %0" : "=m" (ctxt->idt_limit)); |
47 | asm volatile ("sldt %0" : "=m" (ctxt->ldt)); | ||
48 | asm volatile ("str %0" : "=m" (ctxt->tr)); | 47 | asm volatile ("str %0" : "=m" (ctxt->tr)); |
49 | 48 | ||
50 | /* | 49 | /* |
@@ -107,7 +106,6 @@ static void fix_processor_context(void) | |||
107 | 106 | ||
108 | void __restore_processor_state(struct saved_context *ctxt) | 107 | void __restore_processor_state(struct saved_context *ctxt) |
109 | { | 108 | { |
110 | |||
111 | /* | 109 | /* |
112 | * control registers | 110 | * control registers |
113 | */ | 111 | */ |
@@ -117,6 +115,13 @@ void __restore_processor_state(struct saved_context *ctxt) | |||
117 | asm volatile ("movl %0, %%cr0" :: "r" (ctxt->cr0)); | 115 | asm volatile ("movl %0, %%cr0" :: "r" (ctxt->cr0)); |
118 | 116 | ||
119 | /* | 117 | /* |
118 | * now restore the descriptor tables to their proper values | ||
119 | * ltr is done i fix_processor_context(). | ||
120 | */ | ||
121 | asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit)); | ||
122 | asm volatile ("lidt %0" :: "m" (ctxt->idt_limit)); | ||
123 | |||
124 | /* | ||
120 | * segment registers | 125 | * segment registers |
121 | */ | 126 | */ |
122 | asm volatile ("movw %0, %%es" :: "r" (ctxt->es)); | 127 | asm volatile ("movw %0, %%es" :: "r" (ctxt->es)); |
@@ -125,18 +130,10 @@ void __restore_processor_state(struct saved_context *ctxt) | |||
125 | asm volatile ("movw %0, %%ss" :: "r" (ctxt->ss)); | 130 | asm volatile ("movw %0, %%ss" :: "r" (ctxt->ss)); |
126 | 131 | ||
127 | /* | 132 | /* |
128 | * now restore the descriptor tables to their proper values | ||
129 | * ltr is done i fix_processor_context(). | ||
130 | */ | ||
131 | asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit)); | ||
132 | asm volatile ("lidt %0" :: "m" (ctxt->idt_limit)); | ||
133 | asm volatile ("lldt %0" :: "m" (ctxt->ldt)); | ||
134 | |||
135 | /* | ||
136 | * sysenter MSRs | 133 | * sysenter MSRs |
137 | */ | 134 | */ |
138 | if (boot_cpu_has(X86_FEATURE_SEP)) | 135 | if (boot_cpu_has(X86_FEATURE_SEP)) |
139 | enable_sep_cpu(NULL); | 136 | enable_sep_cpu(); |
140 | 137 | ||
141 | fix_processor_context(); | 138 | fix_processor_context(); |
142 | do_fpu_end(); | 139 | do_fpu_end(); |
diff --git a/arch/ia64/kernel/domain.c b/arch/ia64/kernel/domain.c index fe532c970438..d65e87b6394f 100644 --- a/arch/ia64/kernel/domain.c +++ b/arch/ia64/kernel/domain.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/topology.h> | 14 | #include <linux/topology.h> |
15 | #include <linux/nodemask.h> | 15 | #include <linux/nodemask.h> |
16 | 16 | ||
17 | #define SD_NODES_PER_DOMAIN 6 | 17 | #define SD_NODES_PER_DOMAIN 16 |
18 | 18 | ||
19 | #ifdef CONFIG_NUMA | 19 | #ifdef CONFIG_NUMA |
20 | /** | 20 | /** |
@@ -27,7 +27,7 @@ | |||
27 | * | 27 | * |
28 | * Should use nodemask_t. | 28 | * Should use nodemask_t. |
29 | */ | 29 | */ |
30 | static int __devinit find_next_best_node(int node, unsigned long *used_nodes) | 30 | static int find_next_best_node(int node, unsigned long *used_nodes) |
31 | { | 31 | { |
32 | int i, n, val, min_val, best_node = 0; | 32 | int i, n, val, min_val, best_node = 0; |
33 | 33 | ||
@@ -66,7 +66,7 @@ static int __devinit find_next_best_node(int node, unsigned long *used_nodes) | |||
66 | * should be one that prevents unnecessary balancing, but also spreads tasks | 66 | * should be one that prevents unnecessary balancing, but also spreads tasks |
67 | * out optimally. | 67 | * out optimally. |
68 | */ | 68 | */ |
69 | static cpumask_t __devinit sched_domain_node_span(int node) | 69 | static cpumask_t sched_domain_node_span(int node) |
70 | { | 70 | { |
71 | int i; | 71 | int i; |
72 | cpumask_t span, nodemask; | 72 | cpumask_t span, nodemask; |
@@ -96,7 +96,7 @@ static cpumask_t __devinit sched_domain_node_span(int node) | |||
96 | #ifdef CONFIG_SCHED_SMT | 96 | #ifdef CONFIG_SCHED_SMT |
97 | static DEFINE_PER_CPU(struct sched_domain, cpu_domains); | 97 | static DEFINE_PER_CPU(struct sched_domain, cpu_domains); |
98 | static struct sched_group sched_group_cpus[NR_CPUS]; | 98 | static struct sched_group sched_group_cpus[NR_CPUS]; |
99 | static int __devinit cpu_to_cpu_group(int cpu) | 99 | static int cpu_to_cpu_group(int cpu) |
100 | { | 100 | { |
101 | return cpu; | 101 | return cpu; |
102 | } | 102 | } |
@@ -104,7 +104,7 @@ static int __devinit cpu_to_cpu_group(int cpu) | |||
104 | 104 | ||
105 | static DEFINE_PER_CPU(struct sched_domain, phys_domains); | 105 | static DEFINE_PER_CPU(struct sched_domain, phys_domains); |
106 | static struct sched_group sched_group_phys[NR_CPUS]; | 106 | static struct sched_group sched_group_phys[NR_CPUS]; |
107 | static int __devinit cpu_to_phys_group(int cpu) | 107 | static int cpu_to_phys_group(int cpu) |
108 | { | 108 | { |
109 | #ifdef CONFIG_SCHED_SMT | 109 | #ifdef CONFIG_SCHED_SMT |
110 | return first_cpu(cpu_sibling_map[cpu]); | 110 | return first_cpu(cpu_sibling_map[cpu]); |
@@ -125,44 +125,36 @@ static struct sched_group *sched_group_nodes[MAX_NUMNODES]; | |||
125 | static DEFINE_PER_CPU(struct sched_domain, allnodes_domains); | 125 | static DEFINE_PER_CPU(struct sched_domain, allnodes_domains); |
126 | static struct sched_group sched_group_allnodes[MAX_NUMNODES]; | 126 | static struct sched_group sched_group_allnodes[MAX_NUMNODES]; |
127 | 127 | ||
128 | static int __devinit cpu_to_allnodes_group(int cpu) | 128 | static int cpu_to_allnodes_group(int cpu) |
129 | { | 129 | { |
130 | return cpu_to_node(cpu); | 130 | return cpu_to_node(cpu); |
131 | } | 131 | } |
132 | #endif | 132 | #endif |
133 | 133 | ||
134 | /* | 134 | /* |
135 | * Set up scheduler domains and groups. Callers must hold the hotplug lock. | 135 | * Build sched domains for a given set of cpus and attach the sched domains |
136 | * to the individual cpus | ||
136 | */ | 137 | */ |
137 | void __devinit arch_init_sched_domains(void) | 138 | void build_sched_domains(const cpumask_t *cpu_map) |
138 | { | 139 | { |
139 | int i; | 140 | int i; |
140 | cpumask_t cpu_default_map; | ||
141 | 141 | ||
142 | /* | 142 | /* |
143 | * Setup mask for cpus without special case scheduling requirements. | 143 | * Set up domains for cpus specified by the cpu_map. |
144 | * For now this just excludes isolated cpus, but could be used to | ||
145 | * exclude other special cases in the future. | ||
146 | */ | 144 | */ |
147 | cpus_complement(cpu_default_map, cpu_isolated_map); | 145 | for_each_cpu_mask(i, *cpu_map) { |
148 | cpus_and(cpu_default_map, cpu_default_map, cpu_online_map); | ||
149 | |||
150 | /* | ||
151 | * Set up domains. Isolated domains just stay on the dummy domain. | ||
152 | */ | ||
153 | for_each_cpu_mask(i, cpu_default_map) { | ||
154 | int group; | 146 | int group; |
155 | struct sched_domain *sd = NULL, *p; | 147 | struct sched_domain *sd = NULL, *p; |
156 | cpumask_t nodemask = node_to_cpumask(cpu_to_node(i)); | 148 | cpumask_t nodemask = node_to_cpumask(cpu_to_node(i)); |
157 | 149 | ||
158 | cpus_and(nodemask, nodemask, cpu_default_map); | 150 | cpus_and(nodemask, nodemask, *cpu_map); |
159 | 151 | ||
160 | #ifdef CONFIG_NUMA | 152 | #ifdef CONFIG_NUMA |
161 | if (num_online_cpus() | 153 | if (num_online_cpus() |
162 | > SD_NODES_PER_DOMAIN*cpus_weight(nodemask)) { | 154 | > SD_NODES_PER_DOMAIN*cpus_weight(nodemask)) { |
163 | sd = &per_cpu(allnodes_domains, i); | 155 | sd = &per_cpu(allnodes_domains, i); |
164 | *sd = SD_ALLNODES_INIT; | 156 | *sd = SD_ALLNODES_INIT; |
165 | sd->span = cpu_default_map; | 157 | sd->span = *cpu_map; |
166 | group = cpu_to_allnodes_group(i); | 158 | group = cpu_to_allnodes_group(i); |
167 | sd->groups = &sched_group_allnodes[group]; | 159 | sd->groups = &sched_group_allnodes[group]; |
168 | p = sd; | 160 | p = sd; |
@@ -173,7 +165,7 @@ void __devinit arch_init_sched_domains(void) | |||
173 | *sd = SD_NODE_INIT; | 165 | *sd = SD_NODE_INIT; |
174 | sd->span = sched_domain_node_span(cpu_to_node(i)); | 166 | sd->span = sched_domain_node_span(cpu_to_node(i)); |
175 | sd->parent = p; | 167 | sd->parent = p; |
176 | cpus_and(sd->span, sd->span, cpu_default_map); | 168 | cpus_and(sd->span, sd->span, *cpu_map); |
177 | #endif | 169 | #endif |
178 | 170 | ||
179 | p = sd; | 171 | p = sd; |
@@ -190,7 +182,7 @@ void __devinit arch_init_sched_domains(void) | |||
190 | group = cpu_to_cpu_group(i); | 182 | group = cpu_to_cpu_group(i); |
191 | *sd = SD_SIBLING_INIT; | 183 | *sd = SD_SIBLING_INIT; |
192 | sd->span = cpu_sibling_map[i]; | 184 | sd->span = cpu_sibling_map[i]; |
193 | cpus_and(sd->span, sd->span, cpu_default_map); | 185 | cpus_and(sd->span, sd->span, *cpu_map); |
194 | sd->parent = p; | 186 | sd->parent = p; |
195 | sd->groups = &sched_group_cpus[group]; | 187 | sd->groups = &sched_group_cpus[group]; |
196 | #endif | 188 | #endif |
@@ -198,9 +190,9 @@ void __devinit arch_init_sched_domains(void) | |||
198 | 190 | ||
199 | #ifdef CONFIG_SCHED_SMT | 191 | #ifdef CONFIG_SCHED_SMT |
200 | /* Set up CPU (sibling) groups */ | 192 | /* Set up CPU (sibling) groups */ |
201 | for_each_cpu_mask(i, cpu_default_map) { | 193 | for_each_cpu_mask(i, *cpu_map) { |
202 | cpumask_t this_sibling_map = cpu_sibling_map[i]; | 194 | cpumask_t this_sibling_map = cpu_sibling_map[i]; |
203 | cpus_and(this_sibling_map, this_sibling_map, cpu_default_map); | 195 | cpus_and(this_sibling_map, this_sibling_map, *cpu_map); |
204 | if (i != first_cpu(this_sibling_map)) | 196 | if (i != first_cpu(this_sibling_map)) |
205 | continue; | 197 | continue; |
206 | 198 | ||
@@ -213,7 +205,7 @@ void __devinit arch_init_sched_domains(void) | |||
213 | for (i = 0; i < MAX_NUMNODES; i++) { | 205 | for (i = 0; i < MAX_NUMNODES; i++) { |
214 | cpumask_t nodemask = node_to_cpumask(i); | 206 | cpumask_t nodemask = node_to_cpumask(i); |
215 | 207 | ||
216 | cpus_and(nodemask, nodemask, cpu_default_map); | 208 | cpus_and(nodemask, nodemask, *cpu_map); |
217 | if (cpus_empty(nodemask)) | 209 | if (cpus_empty(nodemask)) |
218 | continue; | 210 | continue; |
219 | 211 | ||
@@ -222,7 +214,7 @@ void __devinit arch_init_sched_domains(void) | |||
222 | } | 214 | } |
223 | 215 | ||
224 | #ifdef CONFIG_NUMA | 216 | #ifdef CONFIG_NUMA |
225 | init_sched_build_groups(sched_group_allnodes, cpu_default_map, | 217 | init_sched_build_groups(sched_group_allnodes, *cpu_map, |
226 | &cpu_to_allnodes_group); | 218 | &cpu_to_allnodes_group); |
227 | 219 | ||
228 | for (i = 0; i < MAX_NUMNODES; i++) { | 220 | for (i = 0; i < MAX_NUMNODES; i++) { |
@@ -233,12 +225,12 @@ void __devinit arch_init_sched_domains(void) | |||
233 | cpumask_t covered = CPU_MASK_NONE; | 225 | cpumask_t covered = CPU_MASK_NONE; |
234 | int j; | 226 | int j; |
235 | 227 | ||
236 | cpus_and(nodemask, nodemask, cpu_default_map); | 228 | cpus_and(nodemask, nodemask, *cpu_map); |
237 | if (cpus_empty(nodemask)) | 229 | if (cpus_empty(nodemask)) |
238 | continue; | 230 | continue; |
239 | 231 | ||
240 | domainspan = sched_domain_node_span(i); | 232 | domainspan = sched_domain_node_span(i); |
241 | cpus_and(domainspan, domainspan, cpu_default_map); | 233 | cpus_and(domainspan, domainspan, *cpu_map); |
242 | 234 | ||
243 | sg = kmalloc(sizeof(struct sched_group), GFP_KERNEL); | 235 | sg = kmalloc(sizeof(struct sched_group), GFP_KERNEL); |
244 | sched_group_nodes[i] = sg; | 236 | sched_group_nodes[i] = sg; |
@@ -266,7 +258,7 @@ void __devinit arch_init_sched_domains(void) | |||
266 | int n = (i + j) % MAX_NUMNODES; | 258 | int n = (i + j) % MAX_NUMNODES; |
267 | 259 | ||
268 | cpus_complement(notcovered, covered); | 260 | cpus_complement(notcovered, covered); |
269 | cpus_and(tmp, notcovered, cpu_default_map); | 261 | cpus_and(tmp, notcovered, *cpu_map); |
270 | cpus_and(tmp, tmp, domainspan); | 262 | cpus_and(tmp, tmp, domainspan); |
271 | if (cpus_empty(tmp)) | 263 | if (cpus_empty(tmp)) |
272 | break; | 264 | break; |
@@ -293,7 +285,7 @@ void __devinit arch_init_sched_domains(void) | |||
293 | #endif | 285 | #endif |
294 | 286 | ||
295 | /* Calculate CPU power for physical packages and nodes */ | 287 | /* Calculate CPU power for physical packages and nodes */ |
296 | for_each_cpu_mask(i, cpu_default_map) { | 288 | for_each_cpu_mask(i, *cpu_map) { |
297 | int power; | 289 | int power; |
298 | struct sched_domain *sd; | 290 | struct sched_domain *sd; |
299 | #ifdef CONFIG_SCHED_SMT | 291 | #ifdef CONFIG_SCHED_SMT |
@@ -359,13 +351,35 @@ next_sg: | |||
359 | cpu_attach_domain(sd, i); | 351 | cpu_attach_domain(sd, i); |
360 | } | 352 | } |
361 | } | 353 | } |
354 | /* | ||
355 | * Set up scheduler domains and groups. Callers must hold the hotplug lock. | ||
356 | */ | ||
357 | void arch_init_sched_domains(const cpumask_t *cpu_map) | ||
358 | { | ||
359 | cpumask_t cpu_default_map; | ||
360 | |||
361 | /* | ||
362 | * Setup mask for cpus without special case scheduling requirements. | ||
363 | * For now this just excludes isolated cpus, but could be used to | ||
364 | * exclude other special cases in the future. | ||
365 | */ | ||
366 | cpus_andnot(cpu_default_map, *cpu_map, cpu_isolated_map); | ||
367 | |||
368 | build_sched_domains(&cpu_default_map); | ||
369 | } | ||
362 | 370 | ||
363 | void __devinit arch_destroy_sched_domains(void) | 371 | void arch_destroy_sched_domains(const cpumask_t *cpu_map) |
364 | { | 372 | { |
365 | #ifdef CONFIG_NUMA | 373 | #ifdef CONFIG_NUMA |
366 | int i; | 374 | int i; |
367 | for (i = 0; i < MAX_NUMNODES; i++) { | 375 | for (i = 0; i < MAX_NUMNODES; i++) { |
376 | cpumask_t nodemask = node_to_cpumask(i); | ||
368 | struct sched_group *oldsg, *sg = sched_group_nodes[i]; | 377 | struct sched_group *oldsg, *sg = sched_group_nodes[i]; |
378 | |||
379 | cpus_and(nodemask, nodemask, *cpu_map); | ||
380 | if (cpus_empty(nodemask)) | ||
381 | continue; | ||
382 | |||
369 | if (sg == NULL) | 383 | if (sg == NULL) |
370 | continue; | 384 | continue; |
371 | sg = sg->next; | 385 | sg = sg->next; |
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 3865f088ffa2..623b0a546709 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c | |||
@@ -346,6 +346,7 @@ smp_callin (void) | |||
346 | lock_ipi_calllock(); | 346 | lock_ipi_calllock(); |
347 | cpu_set(cpuid, cpu_online_map); | 347 | cpu_set(cpuid, cpu_online_map); |
348 | unlock_ipi_calllock(); | 348 | unlock_ipi_calllock(); |
349 | per_cpu(cpu_state, cpuid) = CPU_ONLINE; | ||
349 | 350 | ||
350 | smp_setup_percpu_timer(); | 351 | smp_setup_percpu_timer(); |
351 | 352 | ||
@@ -611,6 +612,7 @@ void __devinit smp_prepare_boot_cpu(void) | |||
611 | { | 612 | { |
612 | cpu_set(smp_processor_id(), cpu_online_map); | 613 | cpu_set(smp_processor_id(), cpu_online_map); |
613 | cpu_set(smp_processor_id(), cpu_callin_map); | 614 | cpu_set(smp_processor_id(), cpu_callin_map); |
615 | per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; | ||
614 | } | 616 | } |
615 | 617 | ||
616 | /* | 618 | /* |
@@ -688,6 +690,7 @@ int __cpu_disable(void) | |||
688 | return -EBUSY; | 690 | return -EBUSY; |
689 | 691 | ||
690 | remove_siblinginfo(cpu); | 692 | remove_siblinginfo(cpu); |
693 | cpu_clear(cpu, cpu_online_map); | ||
691 | fixup_irqs(); | 694 | fixup_irqs(); |
692 | local_flush_tlb_all(); | 695 | local_flush_tlb_all(); |
693 | cpu_clear(cpu, cpu_callin_map); | 696 | cpu_clear(cpu, cpu_callin_map); |
@@ -774,6 +777,7 @@ __cpu_up (unsigned int cpu) | |||
774 | if (cpu_isset(cpu, cpu_callin_map)) | 777 | if (cpu_isset(cpu, cpu_callin_map)) |
775 | return -EINVAL; | 778 | return -EINVAL; |
776 | 779 | ||
780 | per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; | ||
777 | /* Processor goes to start_secondary(), sets online flag */ | 781 | /* Processor goes to start_secondary(), sets online flag */ |
778 | ret = do_boot_cpu(sapicid, cpu); | 782 | ret = do_boot_cpu(sapicid, cpu); |
779 | if (ret < 0) | 783 | if (ret < 0) |
diff --git a/arch/ia64/sn/kernel/xpc.h b/arch/ia64/sn/kernel/xpc.h index 1a0aed8490d1..d0ee635daf2e 100644 --- a/arch/ia64/sn/kernel/xpc.h +++ b/arch/ia64/sn/kernel/xpc.h | |||
@@ -87,7 +87,7 @@ struct xpc_rsvd_page { | |||
87 | u8 partid; /* partition ID from SAL */ | 87 | u8 partid; /* partition ID from SAL */ |
88 | u8 version; | 88 | u8 version; |
89 | u8 pad[6]; /* pad to u64 align */ | 89 | u8 pad[6]; /* pad to u64 align */ |
90 | u64 vars_pa; | 90 | volatile u64 vars_pa; |
91 | u64 part_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned; | 91 | u64 part_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned; |
92 | u64 mach_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned; | 92 | u64 mach_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned; |
93 | }; | 93 | }; |
@@ -138,7 +138,7 @@ struct xpc_vars { | |||
138 | * occupies half a cacheline. | 138 | * occupies half a cacheline. |
139 | */ | 139 | */ |
140 | struct xpc_vars_part { | 140 | struct xpc_vars_part { |
141 | u64 magic; | 141 | volatile u64 magic; |
142 | 142 | ||
143 | u64 openclose_args_pa; /* physical address of open and close args */ | 143 | u64 openclose_args_pa; /* physical address of open and close args */ |
144 | u64 GPs_pa; /* physical address of Get/Put values */ | 144 | u64 GPs_pa; /* physical address of Get/Put values */ |
@@ -185,8 +185,8 @@ struct xpc_vars_part { | |||
185 | * Define a Get/Put value pair (pointers) used with a message queue. | 185 | * Define a Get/Put value pair (pointers) used with a message queue. |
186 | */ | 186 | */ |
187 | struct xpc_gp { | 187 | struct xpc_gp { |
188 | s64 get; /* Get value */ | 188 | volatile s64 get; /* Get value */ |
189 | s64 put; /* Put value */ | 189 | volatile s64 put; /* Put value */ |
190 | }; | 190 | }; |
191 | 191 | ||
192 | #define XPC_GP_SIZE \ | 192 | #define XPC_GP_SIZE \ |
@@ -231,7 +231,7 @@ struct xpc_openclose_args { | |||
231 | */ | 231 | */ |
232 | struct xpc_notify { | 232 | struct xpc_notify { |
233 | struct semaphore sema; /* notify semaphore */ | 233 | struct semaphore sema; /* notify semaphore */ |
234 | u8 type; /* type of notification */ | 234 | volatile u8 type; /* type of notification */ |
235 | 235 | ||
236 | /* the following two fields are only used if type == XPC_N_CALL */ | 236 | /* the following two fields are only used if type == XPC_N_CALL */ |
237 | xpc_notify_func func; /* user's notify function */ | 237 | xpc_notify_func func; /* user's notify function */ |
@@ -439,7 +439,7 @@ struct xpc_partition { | |||
439 | 439 | ||
440 | /* XPC infrastructure referencing and teardown control */ | 440 | /* XPC infrastructure referencing and teardown control */ |
441 | 441 | ||
442 | u8 setup_state; /* infrastructure setup state */ | 442 | volatile u8 setup_state; /* infrastructure setup state */ |
443 | wait_queue_head_t teardown_wq; /* kthread waiting to teardown infra */ | 443 | wait_queue_head_t teardown_wq; /* kthread waiting to teardown infra */ |
444 | atomic_t references; /* #of references to infrastructure */ | 444 | atomic_t references; /* #of references to infrastructure */ |
445 | 445 | ||
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c index 0bf6fbcc46d2..6d02dac8056f 100644 --- a/arch/ia64/sn/kernel/xpc_channel.c +++ b/arch/ia64/sn/kernel/xpc_channel.c | |||
@@ -209,7 +209,7 @@ xpc_setup_infrastructure(struct xpc_partition *part) | |||
209 | * With the setting of the partition setup_state to XPC_P_SETUP, we're | 209 | * With the setting of the partition setup_state to XPC_P_SETUP, we're |
210 | * declaring that this partition is ready to go. | 210 | * declaring that this partition is ready to go. |
211 | */ | 211 | */ |
212 | (volatile u8) part->setup_state = XPC_P_SETUP; | 212 | part->setup_state = XPC_P_SETUP; |
213 | 213 | ||
214 | 214 | ||
215 | /* | 215 | /* |
@@ -227,7 +227,7 @@ xpc_setup_infrastructure(struct xpc_partition *part) | |||
227 | xpc_vars_part[partid].IPI_phys_cpuid = | 227 | xpc_vars_part[partid].IPI_phys_cpuid = |
228 | cpu_physical_id(smp_processor_id()); | 228 | cpu_physical_id(smp_processor_id()); |
229 | xpc_vars_part[partid].nchannels = part->nchannels; | 229 | xpc_vars_part[partid].nchannels = part->nchannels; |
230 | (volatile u64) xpc_vars_part[partid].magic = XPC_VP_MAGIC1; | 230 | xpc_vars_part[partid].magic = XPC_VP_MAGIC1; |
231 | 231 | ||
232 | return xpcSuccess; | 232 | return xpcSuccess; |
233 | } | 233 | } |
@@ -355,7 +355,7 @@ xpc_pull_remote_vars_part(struct xpc_partition *part) | |||
355 | 355 | ||
356 | /* let the other side know that we've pulled their variables */ | 356 | /* let the other side know that we've pulled their variables */ |
357 | 357 | ||
358 | (volatile u64) xpc_vars_part[partid].magic = XPC_VP_MAGIC2; | 358 | xpc_vars_part[partid].magic = XPC_VP_MAGIC2; |
359 | } | 359 | } |
360 | 360 | ||
361 | if (pulled_entry->magic == XPC_VP_MAGIC1) { | 361 | if (pulled_entry->magic == XPC_VP_MAGIC1) { |
@@ -1183,7 +1183,7 @@ xpc_process_msg_IPI(struct xpc_partition *part, int ch_number) | |||
1183 | */ | 1183 | */ |
1184 | xpc_clear_local_msgqueue_flags(ch); | 1184 | xpc_clear_local_msgqueue_flags(ch); |
1185 | 1185 | ||
1186 | (volatile s64) ch->w_remote_GP.get = ch->remote_GP.get; | 1186 | ch->w_remote_GP.get = ch->remote_GP.get; |
1187 | 1187 | ||
1188 | dev_dbg(xpc_chan, "w_remote_GP.get changed to %ld, partid=%d, " | 1188 | dev_dbg(xpc_chan, "w_remote_GP.get changed to %ld, partid=%d, " |
1189 | "channel=%d\n", ch->w_remote_GP.get, ch->partid, | 1189 | "channel=%d\n", ch->w_remote_GP.get, ch->partid, |
@@ -1211,7 +1211,7 @@ xpc_process_msg_IPI(struct xpc_partition *part, int ch_number) | |||
1211 | */ | 1211 | */ |
1212 | xpc_clear_remote_msgqueue_flags(ch); | 1212 | xpc_clear_remote_msgqueue_flags(ch); |
1213 | 1213 | ||
1214 | (volatile s64) ch->w_remote_GP.put = ch->remote_GP.put; | 1214 | ch->w_remote_GP.put = ch->remote_GP.put; |
1215 | 1215 | ||
1216 | dev_dbg(xpc_chan, "w_remote_GP.put changed to %ld, partid=%d, " | 1216 | dev_dbg(xpc_chan, "w_remote_GP.put changed to %ld, partid=%d, " |
1217 | "channel=%d\n", ch->w_remote_GP.put, ch->partid, | 1217 | "channel=%d\n", ch->w_remote_GP.put, ch->partid, |
@@ -1875,7 +1875,7 @@ xpc_send_msg(struct xpc_channel *ch, struct xpc_msg *msg, u8 notify_type, | |||
1875 | notify = &ch->notify_queue[msg_number % ch->local_nentries]; | 1875 | notify = &ch->notify_queue[msg_number % ch->local_nentries]; |
1876 | notify->func = func; | 1876 | notify->func = func; |
1877 | notify->key = key; | 1877 | notify->key = key; |
1878 | (volatile u8) notify->type = notify_type; | 1878 | notify->type = notify_type; |
1879 | 1879 | ||
1880 | // >>> is a mb() needed here? | 1880 | // >>> is a mb() needed here? |
1881 | 1881 | ||
diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c index cd7ed73f0e7a..578265ea9e67 100644 --- a/arch/ia64/sn/kernel/xpc_partition.c +++ b/arch/ia64/sn/kernel/xpc_partition.c | |||
@@ -253,7 +253,7 @@ xpc_rsvd_page_init(void) | |||
253 | * This signifies to the remote partition that our reserved | 253 | * This signifies to the remote partition that our reserved |
254 | * page is initialized. | 254 | * page is initialized. |
255 | */ | 255 | */ |
256 | (volatile u64) rp->vars_pa = __pa(xpc_vars); | 256 | rp->vars_pa = __pa(xpc_vars); |
257 | 257 | ||
258 | return rp; | 258 | return rp; |
259 | } | 259 | } |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 94f5a8eb2c22..bd9de7b00c0a 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -1416,6 +1416,12 @@ config HIGHMEM | |||
1416 | bool "High Memory Support" | 1416 | bool "High Memory Support" |
1417 | depends on MIPS32 && (CPU_R3000 || CPU_SB1 || CPU_R7000 || CPU_RM9000 || CPU_R10000) && !(MACH_DECSTATION || MOMENCO_JAGUAR_ATX) | 1417 | depends on MIPS32 && (CPU_R3000 || CPU_SB1 || CPU_R7000 || CPU_RM9000 || CPU_R10000) && !(MACH_DECSTATION || MOMENCO_JAGUAR_ATX) |
1418 | 1418 | ||
1419 | config ARCH_FLATMEM_ENABLE | ||
1420 | def_bool y | ||
1421 | depends on !NUMA | ||
1422 | |||
1423 | source "mm/Kconfig" | ||
1424 | |||
1419 | config SMP | 1425 | config SMP |
1420 | bool "Multi-Processing support" | 1426 | bool "Multi-Processing support" |
1421 | depends on CPU_RM9000 || (SIBYTE_SB1250 && !SIBYTE_STANDALONE) || SGI_IP27 | 1427 | depends on CPU_RM9000 || (SIBYTE_SB1250 && !SIBYTE_STANDALONE) || SGI_IP27 |
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 6018ca25aceb..3a240e3e004c 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/root_dev.h> | 33 | #include <linux/root_dev.h> |
34 | #include <linux/highmem.h> | 34 | #include <linux/highmem.h> |
35 | #include <linux/console.h> | 35 | #include <linux/console.h> |
36 | #include <linux/mmzone.h> | ||
36 | 37 | ||
37 | #include <asm/addrspace.h> | 38 | #include <asm/addrspace.h> |
38 | #include <asm/bootinfo.h> | 39 | #include <asm/bootinfo.h> |
@@ -356,6 +357,8 @@ static inline void bootmem_init(void) | |||
356 | } | 357 | } |
357 | #endif | 358 | #endif |
358 | 359 | ||
360 | memory_present(0, first_usable_pfn, max_low_pfn); | ||
361 | |||
359 | /* Initialize the boot-time allocator with low memory only. */ | 362 | /* Initialize the boot-time allocator with low memory only. */ |
360 | bootmap_size = init_bootmem(first_usable_pfn, max_low_pfn); | 363 | bootmap_size = init_bootmem(first_usable_pfn, max_low_pfn); |
361 | 364 | ||
@@ -557,6 +560,7 @@ void __init setup_arch(char **cmdline_p) | |||
557 | 560 | ||
558 | parse_cmdline_early(); | 561 | parse_cmdline_early(); |
559 | bootmem_init(); | 562 | bootmem_init(); |
563 | sparse_init(); | ||
560 | paging_init(); | 564 | paging_init(); |
561 | resource_init(); | 565 | resource_init(); |
562 | } | 566 | } |
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 73843c528778..9c9a271c8a3a 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c | |||
@@ -128,7 +128,7 @@ static void __init fixrange_init(unsigned long start, unsigned long end, | |||
128 | #endif /* CONFIG_MIPS64 */ | 128 | #endif /* CONFIG_MIPS64 */ |
129 | #endif /* CONFIG_HIGHMEM */ | 129 | #endif /* CONFIG_HIGHMEM */ |
130 | 130 | ||
131 | #ifndef CONFIG_DISCONTIGMEM | 131 | #ifndef CONFIG_NEED_MULTIPLE_NODES |
132 | extern void pagetable_init(void); | 132 | extern void pagetable_init(void); |
133 | 133 | ||
134 | void __init paging_init(void) | 134 | void __init paging_init(void) |
@@ -253,7 +253,7 @@ void __init mem_init(void) | |||
253 | initsize >> 10, | 253 | initsize >> 10, |
254 | (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))); | 254 | (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))); |
255 | } | 255 | } |
256 | #endif /* !CONFIG_DISCONTIGMEM */ | 256 | #endif /* !CONFIG_NEED_MULTIPLE_NODES */ |
257 | 257 | ||
258 | #ifdef CONFIG_BLK_DEV_INITRD | 258 | #ifdef CONFIG_BLK_DEV_INITRD |
259 | void free_initrd_mem(unsigned long start, unsigned long end) | 259 | void free_initrd_mem(unsigned long start, unsigned long end) |
diff --git a/arch/mips/mm/pgtable.c b/arch/mips/mm/pgtable.c index 3b88fdeef329..3fe94202da8c 100644 --- a/arch/mips/mm/pgtable.c +++ b/arch/mips/mm/pgtable.c | |||
@@ -5,7 +5,7 @@ | |||
5 | 5 | ||
6 | void show_mem(void) | 6 | void show_mem(void) |
7 | { | 7 | { |
8 | #ifndef CONFIG_DISCONTIGMEM /* XXX(hch): later.. */ | 8 | #ifndef CONFIG_NEED_MULTIPLE_NODES /* XXX(hch): later.. */ |
9 | int pfn, total = 0, reserved = 0; | 9 | int pfn, total = 0, reserved = 0; |
10 | int shared = 0, cached = 0; | 10 | int shared = 0, cached = 0; |
11 | int highmem = 0; | 11 | int highmem = 0; |
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index 848f43970a4b..a7835cd3f51f 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig | |||
@@ -88,6 +88,9 @@ config 8xx | |||
88 | depends on BROKEN | 88 | depends on BROKEN |
89 | bool "8xx" | 89 | bool "8xx" |
90 | 90 | ||
91 | config E200 | ||
92 | bool "e200" | ||
93 | |||
91 | config E500 | 94 | config E500 |
92 | bool "e500" | 95 | bool "e500" |
93 | 96 | ||
@@ -98,12 +101,12 @@ config PPC_FPU | |||
98 | 101 | ||
99 | config BOOKE | 102 | config BOOKE |
100 | bool | 103 | bool |
101 | depends on E500 | 104 | depends on E200 || E500 |
102 | default y | 105 | default y |
103 | 106 | ||
104 | config FSL_BOOKE | 107 | config FSL_BOOKE |
105 | bool | 108 | bool |
106 | depends on E500 | 109 | depends on E200 || E500 |
107 | default y | 110 | default y |
108 | 111 | ||
109 | config PTE_64BIT | 112 | config PTE_64BIT |
@@ -141,16 +144,16 @@ config ALTIVEC | |||
141 | 144 | ||
142 | config SPE | 145 | config SPE |
143 | bool "SPE Support" | 146 | bool "SPE Support" |
144 | depends on E500 | 147 | depends on E200 || E500 |
145 | ---help--- | 148 | ---help--- |
146 | This option enables kernel support for the Signal Processing | 149 | This option enables kernel support for the Signal Processing |
147 | Extensions (SPE) to the PowerPC processor. The kernel currently | 150 | Extensions (SPE) to the PowerPC processor. The kernel currently |
148 | supports saving and restoring SPE registers, and turning on the | 151 | supports saving and restoring SPE registers, and turning on the |
149 | 'spe enable' bit so user processes can execute SPE instructions. | 152 | 'spe enable' bit so user processes can execute SPE instructions. |
150 | 153 | ||
151 | This option is only usefully if you have a processor that supports | 154 | This option is only useful if you have a processor that supports |
152 | SPE (e500, otherwise known as 85xx series), but does not have any | 155 | SPE (e500, otherwise known as 85xx series), but does not have any |
153 | affect on a non-spe cpu (it does, however add code to the kernel). | 156 | effect on a non-spe cpu (it does, however add code to the kernel). |
154 | 157 | ||
155 | If in doubt, say Y here. | 158 | If in doubt, say Y here. |
156 | 159 | ||
@@ -200,7 +203,7 @@ config TAU_AVERAGE | |||
200 | 203 | ||
201 | config MATH_EMULATION | 204 | config MATH_EMULATION |
202 | bool "Math emulation" | 205 | bool "Math emulation" |
203 | depends on 4xx || 8xx || E500 | 206 | depends on 4xx || 8xx || E200 || E500 |
204 | ---help--- | 207 | ---help--- |
205 | Some PowerPC chips designed for embedded applications do not have | 208 | Some PowerPC chips designed for embedded applications do not have |
206 | a floating-point unit and therefore do not implement the | 209 | a floating-point unit and therefore do not implement the |
@@ -214,6 +217,26 @@ config MATH_EMULATION | |||
214 | here. Saying Y here will not hurt performance (on any machine) but | 217 | here. Saying Y here will not hurt performance (on any machine) but |
215 | will increase the size of the kernel. | 218 | will increase the size of the kernel. |
216 | 219 | ||
220 | config KEXEC | ||
221 | bool "kexec system call (EXPERIMENTAL)" | ||
222 | depends on EXPERIMENTAL | ||
223 | help | ||
224 | kexec is a system call that implements the ability to shutdown your | ||
225 | current kernel, and to start another kernel. It is like a reboot | ||
226 | but it is indepedent of the system firmware. And like a reboot | ||
227 | you can start any kernel with it, not just Linux. | ||
228 | |||
229 | The name comes from the similiarity to the exec system call. | ||
230 | |||
231 | It is an ongoing process to be certain the hardware in a machine | ||
232 | is properly shutdown, so do not be surprised if this code does not | ||
233 | initially work for you. It may help to enable device hotplugging | ||
234 | support. As of this writing the exact hardware interface is | ||
235 | strongly in flux, so no good recommendation can be made. | ||
236 | |||
237 | In the GameCube implementation, kexec allows you to load and | ||
238 | run DOL files, including kernel and homebrew DOLs. | ||
239 | |||
217 | source "drivers/cpufreq/Kconfig" | 240 | source "drivers/cpufreq/Kconfig" |
218 | 241 | ||
219 | config CPU_FREQ_PMAC | 242 | config CPU_FREQ_PMAC |
@@ -254,7 +277,7 @@ config PPC_STD_MMU | |||
254 | 277 | ||
255 | config NOT_COHERENT_CACHE | 278 | config NOT_COHERENT_CACHE |
256 | bool | 279 | bool |
257 | depends on 4xx || 8xx | 280 | depends on 4xx || 8xx || E200 |
258 | default y | 281 | default y |
259 | 282 | ||
260 | endmenu | 283 | endmenu |
diff --git a/arch/ppc/Kconfig.debug b/arch/ppc/Kconfig.debug index d2e1eea8e8e4..e16c7710d4be 100644 --- a/arch/ppc/Kconfig.debug +++ b/arch/ppc/Kconfig.debug | |||
@@ -66,7 +66,7 @@ config SERIAL_TEXT_DEBUG | |||
66 | 66 | ||
67 | config PPC_OCP | 67 | config PPC_OCP |
68 | bool | 68 | bool |
69 | depends on IBM_OCP || FSL_OCP || XILINX_OCP | 69 | depends on IBM_OCP || XILINX_OCP |
70 | default y | 70 | default y |
71 | 71 | ||
72 | endmenu | 72 | endmenu |
diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index 0432a25b4735..f9b0d778dd82 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile | |||
@@ -29,7 +29,7 @@ CPP = $(CC) -E $(CFLAGS) | |||
29 | 29 | ||
30 | CHECKFLAGS += -D__powerpc__ | 30 | CHECKFLAGS += -D__powerpc__ |
31 | 31 | ||
32 | ifndef CONFIG_E500 | 32 | ifndef CONFIG_FSL_BOOKE |
33 | CFLAGS += -mstring | 33 | CFLAGS += -mstring |
34 | endif | 34 | endif |
35 | 35 | ||
@@ -38,6 +38,7 @@ cpu-as-$(CONFIG_4xx) += -Wa,-m405 | |||
38 | cpu-as-$(CONFIG_6xx) += -Wa,-maltivec | 38 | cpu-as-$(CONFIG_6xx) += -Wa,-maltivec |
39 | cpu-as-$(CONFIG_POWER4) += -Wa,-maltivec | 39 | cpu-as-$(CONFIG_POWER4) += -Wa,-maltivec |
40 | cpu-as-$(CONFIG_E500) += -Wa,-me500 | 40 | cpu-as-$(CONFIG_E500) += -Wa,-me500 |
41 | cpu-as-$(CONFIG_E200) += -Wa,-me200 | ||
41 | 42 | ||
42 | AFLAGS += $(cpu-as-y) | 43 | AFLAGS += $(cpu-as-y) |
43 | CFLAGS += $(cpu-as-y) | 44 | CFLAGS += $(cpu-as-y) |
diff --git a/arch/ppc/boot/openfirmware/chrpmain.c b/arch/ppc/boot/openfirmware/chrpmain.c index 6fb4f738728c..effe4a0624b0 100644 --- a/arch/ppc/boot/openfirmware/chrpmain.c +++ b/arch/ppc/boot/openfirmware/chrpmain.c | |||
@@ -39,7 +39,7 @@ char *avail_high; | |||
39 | 39 | ||
40 | #define SCRATCH_SIZE (128 << 10) | 40 | #define SCRATCH_SIZE (128 << 10) |
41 | 41 | ||
42 | static char scratch[SCRATCH_SIZE]; /* 1MB of scratch space for gunzip */ | 42 | static char scratch[SCRATCH_SIZE]; /* 128k of scratch space for gunzip */ |
43 | 43 | ||
44 | typedef void (*kernel_start_t)(int, int, void *, unsigned int, unsigned int); | 44 | typedef void (*kernel_start_t)(int, int, void *, unsigned int, unsigned int); |
45 | 45 | ||
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index b284451802c9..b1457a8a9c0f 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile | |||
@@ -26,7 +26,10 @@ obj-$(CONFIG_KGDB) += ppc-stub.o | |||
26 | obj-$(CONFIG_SMP) += smp.o smp-tbsync.o | 26 | obj-$(CONFIG_SMP) += smp.o smp-tbsync.o |
27 | obj-$(CONFIG_TAU) += temp.o | 27 | obj-$(CONFIG_TAU) += temp.o |
28 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o | 28 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o |
29 | ifndef CONFIG_E200 | ||
29 | obj-$(CONFIG_FSL_BOOKE) += perfmon_fsl_booke.o | 30 | obj-$(CONFIG_FSL_BOOKE) += perfmon_fsl_booke.o |
31 | endif | ||
32 | obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o | ||
30 | 33 | ||
31 | ifndef CONFIG_MATH_EMULATION | 34 | ifndef CONFIG_MATH_EMULATION |
32 | obj-$(CONFIG_8xx) += softemu8xx.o | 35 | obj-$(CONFIG_8xx) += softemu8xx.o |
diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c index 01c226008dbf..50936cda0af9 100644 --- a/arch/ppc/kernel/cputable.c +++ b/arch/ppc/kernel/cputable.c | |||
@@ -903,7 +903,30 @@ struct cpu_spec cpu_specs[] = { | |||
903 | .dcache_bsize = 32, | 903 | .dcache_bsize = 32, |
904 | }, | 904 | }, |
905 | #endif /* CONFIG_44x */ | 905 | #endif /* CONFIG_44x */ |
906 | #ifdef CONFIG_E500 | 906 | #ifdef CONFIG_FSL_BOOKE |
907 | { /* e200z5 */ | ||
908 | .pvr_mask = 0xfff00000, | ||
909 | .pvr_value = 0x81000000, | ||
910 | .cpu_name = "e200z5", | ||
911 | /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ | ||
912 | .cpu_features = CPU_FTR_USE_TB, | ||
913 | .cpu_user_features = PPC_FEATURE_32 | | ||
914 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_EFP_SINGLE | | ||
915 | PPC_FEATURE_UNIFIED_CACHE, | ||
916 | .dcache_bsize = 32, | ||
917 | }, | ||
918 | { /* e200z6 */ | ||
919 | .pvr_mask = 0xfff00000, | ||
920 | .pvr_value = 0x81100000, | ||
921 | .cpu_name = "e200z6", | ||
922 | /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ | ||
923 | .cpu_features = CPU_FTR_USE_TB, | ||
924 | .cpu_user_features = PPC_FEATURE_32 | | ||
925 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP | | ||
926 | PPC_FEATURE_HAS_EFP_SINGLE | | ||
927 | PPC_FEATURE_UNIFIED_CACHE, | ||
928 | .dcache_bsize = 32, | ||
929 | }, | ||
907 | { /* e500 */ | 930 | { /* e500 */ |
908 | .pvr_mask = 0xffff0000, | 931 | .pvr_mask = 0xffff0000, |
909 | .pvr_value = 0x80200000, | 932 | .pvr_value = 0x80200000, |
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S index 8377b6ca26da..d4df68629cc6 100644 --- a/arch/ppc/kernel/entry.S +++ b/arch/ppc/kernel/entry.S | |||
@@ -60,6 +60,11 @@ mcheck_transfer_to_handler: | |||
60 | TRANSFER_TO_HANDLER_EXC_LEVEL(MCHECK) | 60 | TRANSFER_TO_HANDLER_EXC_LEVEL(MCHECK) |
61 | b transfer_to_handler_full | 61 | b transfer_to_handler_full |
62 | 62 | ||
63 | .globl debug_transfer_to_handler | ||
64 | debug_transfer_to_handler: | ||
65 | TRANSFER_TO_HANDLER_EXC_LEVEL(DEBUG) | ||
66 | b transfer_to_handler_full | ||
67 | |||
63 | .globl crit_transfer_to_handler | 68 | .globl crit_transfer_to_handler |
64 | crit_transfer_to_handler: | 69 | crit_transfer_to_handler: |
65 | TRANSFER_TO_HANDLER_EXC_LEVEL(CRIT) | 70 | TRANSFER_TO_HANDLER_EXC_LEVEL(CRIT) |
@@ -835,6 +840,10 @@ ret_from_crit_exc: | |||
835 | RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI) | 840 | RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI) |
836 | 841 | ||
837 | #ifdef CONFIG_BOOKE | 842 | #ifdef CONFIG_BOOKE |
843 | .globl ret_from_debug_exc | ||
844 | ret_from_debug_exc: | ||
845 | RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, RFDI) | ||
846 | |||
838 | .globl ret_from_mcheck_exc | 847 | .globl ret_from_mcheck_exc |
839 | ret_from_mcheck_exc: | 848 | ret_from_mcheck_exc: |
840 | RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, RFMCI) | 849 | RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, RFMCI) |
diff --git a/arch/ppc/kernel/head_booke.h b/arch/ppc/kernel/head_booke.h index 9c50f9d2657c..9342acf12e72 100644 --- a/arch/ppc/kernel/head_booke.h +++ b/arch/ppc/kernel/head_booke.h | |||
@@ -49,6 +49,7 @@ | |||
49 | * | 49 | * |
50 | * On 40x critical is the only additional level | 50 | * On 40x critical is the only additional level |
51 | * On 44x/e500 we have critical and machine check | 51 | * On 44x/e500 we have critical and machine check |
52 | * On e200 we have critical and debug (machine check occurs via critical) | ||
52 | * | 53 | * |
53 | * Additionally we reserve a SPRG for each priority level so we can free up a | 54 | * Additionally we reserve a SPRG for each priority level so we can free up a |
54 | * GPR to use as the base for indirect access to the exception stacks. This | 55 | * GPR to use as the base for indirect access to the exception stacks. This |
@@ -60,12 +61,16 @@ | |||
60 | 61 | ||
61 | /* CRIT_SPRG only used in critical exception handling */ | 62 | /* CRIT_SPRG only used in critical exception handling */ |
62 | #define CRIT_SPRG SPRN_SPRG2 | 63 | #define CRIT_SPRG SPRN_SPRG2 |
63 | /* MCHECK_SPRG only used in critical exception handling */ | 64 | /* MCHECK_SPRG only used in machine check exception handling */ |
64 | #define MCHECK_SPRG SPRN_SPRG6W | 65 | #define MCHECK_SPRG SPRN_SPRG6W |
65 | 66 | ||
66 | #define MCHECK_STACK_TOP (exception_stack_top - 4096) | 67 | #define MCHECK_STACK_TOP (exception_stack_top - 4096) |
67 | #define CRIT_STACK_TOP (exception_stack_top) | 68 | #define CRIT_STACK_TOP (exception_stack_top) |
68 | 69 | ||
70 | /* only on e200 for now */ | ||
71 | #define DEBUG_STACK_TOP (exception_stack_top - 4096) | ||
72 | #define DEBUG_SPRG SPRN_SPRG6W | ||
73 | |||
69 | #ifdef CONFIG_SMP | 74 | #ifdef CONFIG_SMP |
70 | #define BOOKE_LOAD_EXC_LEVEL_STACK(level) \ | 75 | #define BOOKE_LOAD_EXC_LEVEL_STACK(level) \ |
71 | mfspr r8,SPRN_PIR; \ | 76 | mfspr r8,SPRN_PIR; \ |
@@ -124,6 +129,8 @@ | |||
124 | 129 | ||
125 | #define CRITICAL_EXCEPTION_PROLOG \ | 130 | #define CRITICAL_EXCEPTION_PROLOG \ |
126 | EXC_LEVEL_EXCEPTION_PROLOG(CRIT, SPRN_CSRR0, SPRN_CSRR1) | 131 | EXC_LEVEL_EXCEPTION_PROLOG(CRIT, SPRN_CSRR0, SPRN_CSRR1) |
132 | #define DEBUG_EXCEPTION_PROLOG \ | ||
133 | EXC_LEVEL_EXCEPTION_PROLOG(DEBUG, SPRN_DSRR0, SPRN_DSRR1) | ||
127 | #define MCHECK_EXCEPTION_PROLOG \ | 134 | #define MCHECK_EXCEPTION_PROLOG \ |
128 | EXC_LEVEL_EXCEPTION_PROLOG(MCHECK, SPRN_MCSRR0, SPRN_MCSRR1) | 135 | EXC_LEVEL_EXCEPTION_PROLOG(MCHECK, SPRN_MCSRR0, SPRN_MCSRR1) |
129 | 136 | ||
@@ -205,6 +212,60 @@ label: | |||
205 | * save (and later restore) the MSR via SPRN_CSRR1, which will still have | 212 | * save (and later restore) the MSR via SPRN_CSRR1, which will still have |
206 | * the MSR_DE bit set. | 213 | * the MSR_DE bit set. |
207 | */ | 214 | */ |
215 | #ifdef CONFIG_E200 | ||
216 | #define DEBUG_EXCEPTION \ | ||
217 | START_EXCEPTION(Debug); \ | ||
218 | DEBUG_EXCEPTION_PROLOG; \ | ||
219 | \ | ||
220 | /* \ | ||
221 | * If there is a single step or branch-taken exception in an \ | ||
222 | * exception entry sequence, it was probably meant to apply to \ | ||
223 | * the code where the exception occurred (since exception entry \ | ||
224 | * doesn't turn off DE automatically). We simulate the effect \ | ||
225 | * of turning off DE on entry to an exception handler by turning \ | ||
226 | * off DE in the CSRR1 value and clearing the debug status. \ | ||
227 | */ \ | ||
228 | mfspr r10,SPRN_DBSR; /* check single-step/branch taken */ \ | ||
229 | andis. r10,r10,DBSR_IC@h; \ | ||
230 | beq+ 2f; \ | ||
231 | \ | ||
232 | lis r10,KERNELBASE@h; /* check if exception in vectors */ \ | ||
233 | ori r10,r10,KERNELBASE@l; \ | ||
234 | cmplw r12,r10; \ | ||
235 | blt+ 2f; /* addr below exception vectors */ \ | ||
236 | \ | ||
237 | lis r10,Debug@h; \ | ||
238 | ori r10,r10,Debug@l; \ | ||
239 | cmplw r12,r10; \ | ||
240 | bgt+ 2f; /* addr above exception vectors */ \ | ||
241 | \ | ||
242 | /* here it looks like we got an inappropriate debug exception. */ \ | ||
243 | 1: rlwinm r9,r9,0,~MSR_DE; /* clear DE in the CDRR1 value */ \ | ||
244 | lis r10,DBSR_IC@h; /* clear the IC event */ \ | ||
245 | mtspr SPRN_DBSR,r10; \ | ||
246 | /* restore state and get out */ \ | ||
247 | lwz r10,_CCR(r11); \ | ||
248 | lwz r0,GPR0(r11); \ | ||
249 | lwz r1,GPR1(r11); \ | ||
250 | mtcrf 0x80,r10; \ | ||
251 | mtspr SPRN_DSRR0,r12; \ | ||
252 | mtspr SPRN_DSRR1,r9; \ | ||
253 | lwz r9,GPR9(r11); \ | ||
254 | lwz r12,GPR12(r11); \ | ||
255 | mtspr DEBUG_SPRG,r8; \ | ||
256 | BOOKE_LOAD_EXC_LEVEL_STACK(DEBUG); /* r8 points to the debug stack */ \ | ||
257 | lwz r10,GPR10-INT_FRAME_SIZE(r8); \ | ||
258 | lwz r11,GPR11-INT_FRAME_SIZE(r8); \ | ||
259 | mfspr r8,DEBUG_SPRG; \ | ||
260 | \ | ||
261 | RFDI; \ | ||
262 | b .; \ | ||
263 | \ | ||
264 | /* continue normal handling for a critical exception... */ \ | ||
265 | 2: mfspr r4,SPRN_DBSR; \ | ||
266 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | ||
267 | EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, debug_transfer_to_handler, ret_from_debug_exc) | ||
268 | #else | ||
208 | #define DEBUG_EXCEPTION \ | 269 | #define DEBUG_EXCEPTION \ |
209 | START_EXCEPTION(Debug); \ | 270 | START_EXCEPTION(Debug); \ |
210 | CRITICAL_EXCEPTION_PROLOG; \ | 271 | CRITICAL_EXCEPTION_PROLOG; \ |
@@ -257,6 +318,7 @@ label: | |||
257 | 2: mfspr r4,SPRN_DBSR; \ | 318 | 2: mfspr r4,SPRN_DBSR; \ |
258 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | 319 | addi r3,r1,STACK_FRAME_OVERHEAD; \ |
259 | EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, crit_transfer_to_handler, ret_from_crit_exc) | 320 | EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, crit_transfer_to_handler, ret_from_crit_exc) |
321 | #endif | ||
260 | 322 | ||
261 | #define INSTRUCTION_STORAGE_EXCEPTION \ | 323 | #define INSTRUCTION_STORAGE_EXCEPTION \ |
262 | START_EXCEPTION(InstructionStorage) \ | 324 | START_EXCEPTION(InstructionStorage) \ |
diff --git a/arch/ppc/kernel/head_fsl_booke.S b/arch/ppc/kernel/head_fsl_booke.S index ce36e88ba627..eb804b7a3cb2 100644 --- a/arch/ppc/kernel/head_fsl_booke.S +++ b/arch/ppc/kernel/head_fsl_booke.S | |||
@@ -102,6 +102,7 @@ invstr: mflr r6 /* Make it accessible */ | |||
102 | or r7,r7,r4 | 102 | or r7,r7,r4 |
103 | mtspr SPRN_MAS6,r7 | 103 | mtspr SPRN_MAS6,r7 |
104 | tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */ | 104 | tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */ |
105 | #ifndef CONFIG_E200 | ||
105 | mfspr r7,SPRN_MAS1 | 106 | mfspr r7,SPRN_MAS1 |
106 | andis. r7,r7,MAS1_VALID@h | 107 | andis. r7,r7,MAS1_VALID@h |
107 | bne match_TLB | 108 | bne match_TLB |
@@ -118,6 +119,7 @@ invstr: mflr r6 /* Make it accessible */ | |||
118 | or r7,r7,r4 | 119 | or r7,r7,r4 |
119 | mtspr SPRN_MAS6,r7 | 120 | mtspr SPRN_MAS6,r7 |
120 | tlbsx 0,r6 /* Fall through, we had to match */ | 121 | tlbsx 0,r6 /* Fall through, we had to match */ |
122 | #endif | ||
121 | match_TLB: | 123 | match_TLB: |
122 | mfspr r7,SPRN_MAS0 | 124 | mfspr r7,SPRN_MAS0 |
123 | rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */ | 125 | rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */ |
@@ -196,8 +198,10 @@ skpinv: addi r6,r6,1 /* Increment */ | |||
196 | /* 4. Clear out PIDs & Search info */ | 198 | /* 4. Clear out PIDs & Search info */ |
197 | li r6,0 | 199 | li r6,0 |
198 | mtspr SPRN_PID0,r6 | 200 | mtspr SPRN_PID0,r6 |
201 | #ifndef CONFIG_E200 | ||
199 | mtspr SPRN_PID1,r6 | 202 | mtspr SPRN_PID1,r6 |
200 | mtspr SPRN_PID2,r6 | 203 | mtspr SPRN_PID2,r6 |
204 | #endif | ||
201 | mtspr SPRN_MAS6,r6 | 205 | mtspr SPRN_MAS6,r6 |
202 | 206 | ||
203 | /* 5. Invalidate mapping we started in */ | 207 | /* 5. Invalidate mapping we started in */ |
@@ -277,7 +281,9 @@ skpinv: addi r6,r6,1 /* Increment */ | |||
277 | SET_IVOR(32, SPEUnavailable); | 281 | SET_IVOR(32, SPEUnavailable); |
278 | SET_IVOR(33, SPEFloatingPointData); | 282 | SET_IVOR(33, SPEFloatingPointData); |
279 | SET_IVOR(34, SPEFloatingPointRound); | 283 | SET_IVOR(34, SPEFloatingPointRound); |
284 | #ifndef CONFIG_E200 | ||
280 | SET_IVOR(35, PerformanceMonitor); | 285 | SET_IVOR(35, PerformanceMonitor); |
286 | #endif | ||
281 | 287 | ||
282 | /* Establish the interrupt vector base */ | 288 | /* Establish the interrupt vector base */ |
283 | lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */ | 289 | lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */ |
@@ -285,6 +291,9 @@ skpinv: addi r6,r6,1 /* Increment */ | |||
285 | 291 | ||
286 | /* Setup the defaults for TLB entries */ | 292 | /* Setup the defaults for TLB entries */ |
287 | li r2,(MAS4_TSIZED(BOOKE_PAGESZ_4K))@l | 293 | li r2,(MAS4_TSIZED(BOOKE_PAGESZ_4K))@l |
294 | #ifdef CONFIG_E200 | ||
295 | oris r2,r2,MAS4_TLBSELD(1)@h | ||
296 | #endif | ||
288 | mtspr SPRN_MAS4, r2 | 297 | mtspr SPRN_MAS4, r2 |
289 | 298 | ||
290 | #if 0 | 299 | #if 0 |
@@ -293,6 +302,12 @@ skpinv: addi r6,r6,1 /* Increment */ | |||
293 | oris r2,r2,HID0_DOZE@h | 302 | oris r2,r2,HID0_DOZE@h |
294 | mtspr SPRN_HID0, r2 | 303 | mtspr SPRN_HID0, r2 |
295 | #endif | 304 | #endif |
305 | #ifdef CONFIG_E200 | ||
306 | /* enable dedicated debug exception handling resources (Debug APU) */ | ||
307 | mfspr r2,SPRN_HID0 | ||
308 | ori r2,r2,HID0_DAPUEN@l | ||
309 | mtspr SPRN_HID0,r2 | ||
310 | #endif | ||
296 | 311 | ||
297 | #if !defined(CONFIG_BDI_SWITCH) | 312 | #if !defined(CONFIG_BDI_SWITCH) |
298 | /* | 313 | /* |
@@ -414,7 +429,12 @@ interrupt_base: | |||
414 | CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException) | 429 | CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException) |
415 | 430 | ||
416 | /* Machine Check Interrupt */ | 431 | /* Machine Check Interrupt */ |
432 | #ifdef CONFIG_E200 | ||
433 | /* no RFMCI, MCSRRs on E200 */ | ||
434 | CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException) | ||
435 | #else | ||
417 | MCHECK_EXCEPTION(0x0200, MachineCheck, MachineCheckException) | 436 | MCHECK_EXCEPTION(0x0200, MachineCheck, MachineCheckException) |
437 | #endif | ||
418 | 438 | ||
419 | /* Data Storage Interrupt */ | 439 | /* Data Storage Interrupt */ |
420 | START_EXCEPTION(DataStorage) | 440 | START_EXCEPTION(DataStorage) |
@@ -520,8 +540,13 @@ interrupt_base: | |||
520 | #ifdef CONFIG_PPC_FPU | 540 | #ifdef CONFIG_PPC_FPU |
521 | FP_UNAVAILABLE_EXCEPTION | 541 | FP_UNAVAILABLE_EXCEPTION |
522 | #else | 542 | #else |
543 | #ifdef CONFIG_E200 | ||
544 | /* E200 treats 'normal' floating point instructions as FP Unavail exception */ | ||
545 | EXCEPTION(0x0800, FloatingPointUnavailable, ProgramCheckException, EXC_XFER_EE) | ||
546 | #else | ||
523 | EXCEPTION(0x0800, FloatingPointUnavailable, UnknownException, EXC_XFER_EE) | 547 | EXCEPTION(0x0800, FloatingPointUnavailable, UnknownException, EXC_XFER_EE) |
524 | #endif | 548 | #endif |
549 | #endif | ||
525 | 550 | ||
526 | /* System Call Interrupt */ | 551 | /* System Call Interrupt */ |
527 | START_EXCEPTION(SystemCall) | 552 | START_EXCEPTION(SystemCall) |
@@ -691,6 +716,7 @@ interrupt_base: | |||
691 | /* | 716 | /* |
692 | * Local functions | 717 | * Local functions |
693 | */ | 718 | */ |
719 | |||
694 | /* | 720 | /* |
695 | * Data TLB exceptions will bail out to this point | 721 | * Data TLB exceptions will bail out to this point |
696 | * if they can't resolve the lightweight TLB fault. | 722 | * if they can't resolve the lightweight TLB fault. |
@@ -761,6 +787,31 @@ END_FTR_SECTION_IFSET(CPU_FTR_BIG_PHYS) | |||
761 | 2: rlwimi r11, r12, 0, 20, 31 /* Extract RPN from PTE and merge with perms */ | 787 | 2: rlwimi r11, r12, 0, 20, 31 /* Extract RPN from PTE and merge with perms */ |
762 | mtspr SPRN_MAS3, r11 | 788 | mtspr SPRN_MAS3, r11 |
763 | #endif | 789 | #endif |
790 | #ifdef CONFIG_E200 | ||
791 | /* Round robin TLB1 entries assignment */ | ||
792 | mfspr r12, SPRN_MAS0 | ||
793 | |||
794 | /* Extract TLB1CFG(NENTRY) */ | ||
795 | mfspr r11, SPRN_TLB1CFG | ||
796 | andi. r11, r11, 0xfff | ||
797 | |||
798 | /* Extract MAS0(NV) */ | ||
799 | andi. r13, r12, 0xfff | ||
800 | addi r13, r13, 1 | ||
801 | cmpw 0, r13, r11 | ||
802 | addi r12, r12, 1 | ||
803 | |||
804 | /* check if we need to wrap */ | ||
805 | blt 7f | ||
806 | |||
807 | /* wrap back to first free tlbcam entry */ | ||
808 | lis r13, tlbcam_index@ha | ||
809 | lwz r13, tlbcam_index@l(r13) | ||
810 | rlwimi r12, r13, 0, 20, 31 | ||
811 | 7: | ||
812 | mtspr SPRN_MAS0,r12 | ||
813 | #endif /* CONFIG_E200 */ | ||
814 | |||
764 | tlbwe | 815 | tlbwe |
765 | 816 | ||
766 | /* Done...restore registers and get out of here. */ | 817 | /* Done...restore registers and get out of here. */ |
diff --git a/arch/ppc/kernel/machine_kexec.c b/arch/ppc/kernel/machine_kexec.c new file mode 100644 index 000000000000..84d65a87191e --- /dev/null +++ b/arch/ppc/kernel/machine_kexec.c | |||
@@ -0,0 +1,118 @@ | |||
1 | /* | ||
2 | * machine_kexec.c - handle transition of Linux booting another kernel | ||
3 | * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com> | ||
4 | * | ||
5 | * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz | ||
6 | * | ||
7 | * This source code is licensed under the GNU General Public License, | ||
8 | * Version 2. See the file COPYING for more details. | ||
9 | */ | ||
10 | |||
11 | #include <linux/mm.h> | ||
12 | #include <linux/kexec.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/reboot.h> | ||
15 | #include <asm/pgtable.h> | ||
16 | #include <asm/pgalloc.h> | ||
17 | #include <asm/mmu_context.h> | ||
18 | #include <asm/io.h> | ||
19 | #include <asm/hw_irq.h> | ||
20 | #include <asm/cacheflush.h> | ||
21 | #include <asm/machdep.h> | ||
22 | |||
23 | typedef NORET_TYPE void (*relocate_new_kernel_t)( | ||
24 | unsigned long indirection_page, | ||
25 | unsigned long reboot_code_buffer, | ||
26 | unsigned long start_address) ATTRIB_NORET; | ||
27 | |||
28 | const extern unsigned char relocate_new_kernel[]; | ||
29 | const extern unsigned int relocate_new_kernel_size; | ||
30 | |||
31 | void machine_shutdown(void) | ||
32 | { | ||
33 | if (ppc_md.machine_shutdown) | ||
34 | ppc_md.machine_shutdown(); | ||
35 | } | ||
36 | |||
37 | void machine_crash_shutdown(struct pt_regs *regs) | ||
38 | { | ||
39 | if (ppc_md.machine_crash_shutdown) | ||
40 | ppc_md.machine_crash_shutdown(); | ||
41 | } | ||
42 | |||
43 | /* | ||
44 | * Do what every setup is needed on image and the | ||
45 | * reboot code buffer to allow us to avoid allocations | ||
46 | * later. | ||
47 | */ | ||
48 | int machine_kexec_prepare(struct kimage *image) | ||
49 | { | ||
50 | if (ppc_md.machine_kexec_prepare) | ||
51 | return ppc_md.machine_kexec_prepare(image); | ||
52 | /* | ||
53 | * Fail if platform doesn't provide its own machine_kexec_prepare | ||
54 | * implementation. | ||
55 | */ | ||
56 | return -ENOSYS; | ||
57 | } | ||
58 | |||
59 | void machine_kexec_cleanup(struct kimage *image) | ||
60 | { | ||
61 | if (ppc_md.machine_kexec_cleanup) | ||
62 | ppc_md.machine_kexec_cleanup(image); | ||
63 | } | ||
64 | |||
65 | /* | ||
66 | * Do not allocate memory (or fail in any way) in machine_kexec(). | ||
67 | * We are past the point of no return, committed to rebooting now. | ||
68 | */ | ||
69 | NORET_TYPE void machine_kexec(struct kimage *image) | ||
70 | { | ||
71 | if (ppc_md.machine_kexec) | ||
72 | ppc_md.machine_kexec(image); | ||
73 | else { | ||
74 | /* | ||
75 | * Fall back to normal restart if platform doesn't provide | ||
76 | * its own kexec function, and user insist to kexec... | ||
77 | */ | ||
78 | machine_restart(NULL); | ||
79 | } | ||
80 | for(;;); | ||
81 | } | ||
82 | |||
83 | /* | ||
84 | * This is a generic machine_kexec function suitable at least for | ||
85 | * non-OpenFirmware embedded platforms. | ||
86 | * It merely copies the image relocation code to the control page and | ||
87 | * jumps to it. | ||
88 | * A platform specific function may just call this one. | ||
89 | */ | ||
90 | void machine_kexec_simple(struct kimage *image) | ||
91 | { | ||
92 | unsigned long page_list; | ||
93 | unsigned long reboot_code_buffer, reboot_code_buffer_phys; | ||
94 | relocate_new_kernel_t rnk; | ||
95 | |||
96 | /* Interrupts aren't acceptable while we reboot */ | ||
97 | local_irq_disable(); | ||
98 | |||
99 | page_list = image->head; | ||
100 | |||
101 | /* we need both effective and real address here */ | ||
102 | reboot_code_buffer = | ||
103 | (unsigned long)page_address(image->control_code_page); | ||
104 | reboot_code_buffer_phys = virt_to_phys((void *)reboot_code_buffer); | ||
105 | |||
106 | /* copy our kernel relocation code to the control code page */ | ||
107 | memcpy((void *)reboot_code_buffer, relocate_new_kernel, | ||
108 | relocate_new_kernel_size); | ||
109 | |||
110 | flush_icache_range(reboot_code_buffer, | ||
111 | reboot_code_buffer + KEXEC_CONTROL_CODE_SIZE); | ||
112 | printk(KERN_INFO "Bye!\n"); | ||
113 | |||
114 | /* now call it */ | ||
115 | rnk = (relocate_new_kernel_t) reboot_code_buffer; | ||
116 | (*rnk)(page_list, reboot_code_buffer_phys, image->start); | ||
117 | } | ||
118 | |||
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 7329ef177a18..b6a63a49a232 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S | |||
@@ -593,6 +593,14 @@ _GLOBAL(flush_instruction_cache) | |||
593 | iccci 0,r3 | 593 | iccci 0,r3 |
594 | #endif | 594 | #endif |
595 | #elif CONFIG_FSL_BOOKE | 595 | #elif CONFIG_FSL_BOOKE |
596 | BEGIN_FTR_SECTION | ||
597 | mfspr r3,SPRN_L1CSR0 | ||
598 | ori r3,r3,L1CSR0_CFI|L1CSR0_CLFC | ||
599 | /* msync; isync recommended here */ | ||
600 | mtspr SPRN_L1CSR0,r3 | ||
601 | isync | ||
602 | blr | ||
603 | END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) | ||
596 | mfspr r3,SPRN_L1CSR1 | 604 | mfspr r3,SPRN_L1CSR1 |
597 | ori r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR | 605 | ori r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR |
598 | mtspr SPRN_L1CSR1,r3 | 606 | mtspr SPRN_L1CSR1,r3 |
@@ -1436,7 +1444,7 @@ _GLOBAL(sys_call_table) | |||
1436 | .long sys_mq_timedreceive /* 265 */ | 1444 | .long sys_mq_timedreceive /* 265 */ |
1437 | .long sys_mq_notify | 1445 | .long sys_mq_notify |
1438 | .long sys_mq_getsetattr | 1446 | .long sys_mq_getsetattr |
1439 | .long sys_ni_syscall /* 268 reserved for sys_kexec_load */ | 1447 | .long sys_kexec_load |
1440 | .long sys_add_key | 1448 | .long sys_add_key |
1441 | .long sys_request_key /* 270 */ | 1449 | .long sys_request_key /* 270 */ |
1442 | .long sys_keyctl | 1450 | .long sys_keyctl |
diff --git a/arch/ppc/kernel/perfmon.c b/arch/ppc/kernel/perfmon.c index 918f6b252e45..fa1dad96b830 100644 --- a/arch/ppc/kernel/perfmon.c +++ b/arch/ppc/kernel/perfmon.c | |||
@@ -36,7 +36,7 @@ | |||
36 | /* A lock to regulate grabbing the interrupt */ | 36 | /* A lock to regulate grabbing the interrupt */ |
37 | DEFINE_SPINLOCK(perfmon_lock); | 37 | DEFINE_SPINLOCK(perfmon_lock); |
38 | 38 | ||
39 | #ifdef CONFIG_FSL_BOOKE | 39 | #if defined (CONFIG_FSL_BOOKE) && !defined (CONFIG_E200) |
40 | static void dummy_perf(struct pt_regs *regs) | 40 | static void dummy_perf(struct pt_regs *regs) |
41 | { | 41 | { |
42 | unsigned int pmgc0 = mfpmr(PMRN_PMGC0); | 42 | unsigned int pmgc0 = mfpmr(PMRN_PMGC0); |
diff --git a/arch/ppc/kernel/relocate_kernel.S b/arch/ppc/kernel/relocate_kernel.S new file mode 100644 index 000000000000..7ff69c4af920 --- /dev/null +++ b/arch/ppc/kernel/relocate_kernel.S | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * relocate_kernel.S - put the kernel image in place to boot | ||
3 | * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com> | ||
4 | * | ||
5 | * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz | ||
6 | * | ||
7 | * This source code is licensed under the GNU General Public License, | ||
8 | * Version 2. See the file COPYING for more details. | ||
9 | */ | ||
10 | |||
11 | #include <asm/reg.h> | ||
12 | #include <asm/ppc_asm.h> | ||
13 | #include <asm/processor.h> | ||
14 | |||
15 | #include <asm/kexec.h> | ||
16 | |||
17 | #define PAGE_SIZE 4096 /* must be same value as in <asm/page.h> */ | ||
18 | |||
19 | /* | ||
20 | * Must be relocatable PIC code callable as a C function. | ||
21 | */ | ||
22 | .globl relocate_new_kernel | ||
23 | relocate_new_kernel: | ||
24 | /* r3 = page_list */ | ||
25 | /* r4 = reboot_code_buffer */ | ||
26 | /* r5 = start_address */ | ||
27 | |||
28 | li r0, 0 | ||
29 | |||
30 | /* | ||
31 | * Set Machine Status Register to a known status, | ||
32 | * switch the MMU off and jump to 1: in a single step. | ||
33 | */ | ||
34 | |||
35 | mr r8, r0 | ||
36 | ori r8, r8, MSR_RI|MSR_ME | ||
37 | mtspr SRR1, r8 | ||
38 | addi r8, r4, 1f - relocate_new_kernel | ||
39 | mtspr SRR0, r8 | ||
40 | sync | ||
41 | rfi | ||
42 | |||
43 | 1: | ||
44 | /* from this point address translation is turned off */ | ||
45 | /* and interrupts are disabled */ | ||
46 | |||
47 | /* set a new stack at the bottom of our page... */ | ||
48 | /* (not really needed now) */ | ||
49 | addi r1, r4, KEXEC_CONTROL_CODE_SIZE - 8 /* for LR Save+Back Chain */ | ||
50 | stw r0, 0(r1) | ||
51 | |||
52 | /* Do the copies */ | ||
53 | li r6, 0 /* checksum */ | ||
54 | mr r0, r3 | ||
55 | b 1f | ||
56 | |||
57 | 0: /* top, read another word for the indirection page */ | ||
58 | lwzu r0, 4(r3) | ||
59 | |||
60 | 1: | ||
61 | /* is it a destination page? (r8) */ | ||
62 | rlwinm. r7, r0, 0, 31, 31 /* IND_DESTINATION (1<<0) */ | ||
63 | beq 2f | ||
64 | |||
65 | rlwinm r8, r0, 0, 0, 19 /* clear kexec flags, page align */ | ||
66 | b 0b | ||
67 | |||
68 | 2: /* is it an indirection page? (r3) */ | ||
69 | rlwinm. r7, r0, 0, 30, 30 /* IND_INDIRECTION (1<<1) */ | ||
70 | beq 2f | ||
71 | |||
72 | rlwinm r3, r0, 0, 0, 19 /* clear kexec flags, page align */ | ||
73 | subi r3, r3, 4 | ||
74 | b 0b | ||
75 | |||
76 | 2: /* are we done? */ | ||
77 | rlwinm. r7, r0, 0, 29, 29 /* IND_DONE (1<<2) */ | ||
78 | beq 2f | ||
79 | b 3f | ||
80 | |||
81 | 2: /* is it a source page? (r9) */ | ||
82 | rlwinm. r7, r0, 0, 28, 28 /* IND_SOURCE (1<<3) */ | ||
83 | beq 0b | ||
84 | |||
85 | rlwinm r9, r0, 0, 0, 19 /* clear kexec flags, page align */ | ||
86 | |||
87 | li r7, PAGE_SIZE / 4 | ||
88 | mtctr r7 | ||
89 | subi r9, r9, 4 | ||
90 | subi r8, r8, 4 | ||
91 | 9: | ||
92 | lwzu r0, 4(r9) /* do the copy */ | ||
93 | xor r6, r6, r0 | ||
94 | stwu r0, 4(r8) | ||
95 | dcbst 0, r8 | ||
96 | sync | ||
97 | icbi 0, r8 | ||
98 | bdnz 9b | ||
99 | |||
100 | addi r9, r9, 4 | ||
101 | addi r8, r8, 4 | ||
102 | b 0b | ||
103 | |||
104 | 3: | ||
105 | |||
106 | /* To be certain of avoiding problems with self-modifying code | ||
107 | * execute a serializing instruction here. | ||
108 | */ | ||
109 | isync | ||
110 | sync | ||
111 | |||
112 | /* jump to the entry point, usually the setup routine */ | ||
113 | mtlr r5 | ||
114 | blrl | ||
115 | |||
116 | 1: b 1b | ||
117 | |||
118 | relocate_new_kernel_end: | ||
119 | |||
120 | .globl relocate_new_kernel_size | ||
121 | relocate_new_kernel_size: | ||
122 | .long relocate_new_kernel_end - relocate_new_kernel | ||
123 | |||
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 2ca8ecfeefd9..9e6ae5696650 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c | |||
@@ -173,13 +173,13 @@ static inline int check_io_access(struct pt_regs *regs) | |||
173 | /* On 4xx, the reason for the machine check or program exception | 173 | /* On 4xx, the reason for the machine check or program exception |
174 | is in the ESR. */ | 174 | is in the ESR. */ |
175 | #define get_reason(regs) ((regs)->dsisr) | 175 | #define get_reason(regs) ((regs)->dsisr) |
176 | #ifndef CONFIG_E500 | 176 | #ifndef CONFIG_FSL_BOOKE |
177 | #define get_mc_reason(regs) ((regs)->dsisr) | 177 | #define get_mc_reason(regs) ((regs)->dsisr) |
178 | #else | 178 | #else |
179 | #define get_mc_reason(regs) (mfspr(SPRN_MCSR)) | 179 | #define get_mc_reason(regs) (mfspr(SPRN_MCSR)) |
180 | #endif | 180 | #endif |
181 | #define REASON_FP ESR_FP | 181 | #define REASON_FP ESR_FP |
182 | #define REASON_ILLEGAL ESR_PIL | 182 | #define REASON_ILLEGAL (ESR_PIL | ESR_PUO) |
183 | #define REASON_PRIVILEGED ESR_PPR | 183 | #define REASON_PRIVILEGED ESR_PPR |
184 | #define REASON_TRAP ESR_PTR | 184 | #define REASON_TRAP ESR_PTR |
185 | 185 | ||
@@ -302,7 +302,25 @@ void MachineCheckException(struct pt_regs *regs) | |||
302 | printk("Bus - Instruction Parity Error\n"); | 302 | printk("Bus - Instruction Parity Error\n"); |
303 | if (reason & MCSR_BUS_RPERR) | 303 | if (reason & MCSR_BUS_RPERR) |
304 | printk("Bus - Read Parity Error\n"); | 304 | printk("Bus - Read Parity Error\n"); |
305 | #else /* !CONFIG_4xx && !CONFIG_E500 */ | 305 | #elif defined (CONFIG_E200) |
306 | printk("Machine check in kernel mode.\n"); | ||
307 | printk("Caused by (from MCSR=%lx): ", reason); | ||
308 | |||
309 | if (reason & MCSR_MCP) | ||
310 | printk("Machine Check Signal\n"); | ||
311 | if (reason & MCSR_CP_PERR) | ||
312 | printk("Cache Push Parity Error\n"); | ||
313 | if (reason & MCSR_CPERR) | ||
314 | printk("Cache Parity Error\n"); | ||
315 | if (reason & MCSR_EXCP_ERR) | ||
316 | printk("ISI, ITLB, or Bus Error on first instruction fetch for an exception handler\n"); | ||
317 | if (reason & MCSR_BUS_IRERR) | ||
318 | printk("Bus - Read Bus Error on instruction fetch\n"); | ||
319 | if (reason & MCSR_BUS_DRERR) | ||
320 | printk("Bus - Read Bus Error on data load\n"); | ||
321 | if (reason & MCSR_BUS_WRERR) | ||
322 | printk("Bus - Write Bus Error on buffered store or cache line push\n"); | ||
323 | #else /* !CONFIG_4xx && !CONFIG_E500 && !CONFIG_E200 */ | ||
306 | printk("Machine check in kernel mode.\n"); | 324 | printk("Machine check in kernel mode.\n"); |
307 | printk("Caused by (from SRR1=%lx): ", reason); | 325 | printk("Caused by (from SRR1=%lx): ", reason); |
308 | switch (reason & 0x601F0000) { | 326 | switch (reason & 0x601F0000) { |
diff --git a/arch/ppc/mm/44x_mmu.c b/arch/ppc/mm/44x_mmu.c index 72f7c0d1c0ed..3d79ce281b67 100644 --- a/arch/ppc/mm/44x_mmu.c +++ b/arch/ppc/mm/44x_mmu.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <linux/vmalloc.h> | 39 | #include <linux/vmalloc.h> |
40 | #include <linux/init.h> | 40 | #include <linux/init.h> |
41 | #include <linux/delay.h> | 41 | #include <linux/delay.h> |
42 | #include <linux/bootmem.h> | ||
43 | #include <linux/highmem.h> | 42 | #include <linux/highmem.h> |
44 | 43 | ||
45 | #include <asm/pgalloc.h> | 44 | #include <asm/pgalloc.h> |
diff --git a/arch/ppc/mm/4xx_mmu.c b/arch/ppc/mm/4xx_mmu.c index a7f616140381..b7bcbc232f39 100644 --- a/arch/ppc/mm/4xx_mmu.c +++ b/arch/ppc/mm/4xx_mmu.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/vmalloc.h> | 36 | #include <linux/vmalloc.h> |
37 | #include <linux/init.h> | 37 | #include <linux/init.h> |
38 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
39 | #include <linux/bootmem.h> | ||
40 | #include <linux/highmem.h> | 39 | #include <linux/highmem.h> |
41 | 40 | ||
42 | #include <asm/pgalloc.h> | 41 | #include <asm/pgalloc.h> |
diff --git a/arch/ppc/mm/fsl_booke_mmu.c b/arch/ppc/mm/fsl_booke_mmu.c index e07990efa046..af9ca0eb6d55 100644 --- a/arch/ppc/mm/fsl_booke_mmu.c +++ b/arch/ppc/mm/fsl_booke_mmu.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include <linux/vmalloc.h> | 41 | #include <linux/vmalloc.h> |
42 | #include <linux/init.h> | 42 | #include <linux/init.h> |
43 | #include <linux/delay.h> | 43 | #include <linux/delay.h> |
44 | #include <linux/bootmem.h> | ||
45 | #include <linux/highmem.h> | 44 | #include <linux/highmem.h> |
46 | 45 | ||
47 | #include <asm/pgalloc.h> | 46 | #include <asm/pgalloc.h> |
@@ -126,7 +125,7 @@ void settlbcam(int index, unsigned long virt, phys_addr_t phys, | |||
126 | flags |= _PAGE_COHERENT; | 125 | flags |= _PAGE_COHERENT; |
127 | #endif | 126 | #endif |
128 | 127 | ||
129 | TLBCAM[index].MAS0 = MAS0_TLBSEL(1) | MAS0_ESEL(index); | 128 | TLBCAM[index].MAS0 = MAS0_TLBSEL(1) | MAS0_ESEL(index) | MAS0_NV(index+1); |
130 | TLBCAM[index].MAS1 = MAS1_VALID | MAS1_IPROT | MAS1_TSIZE(tsize) | MAS1_TID(pid); | 129 | TLBCAM[index].MAS1 = MAS1_VALID | MAS1_IPROT | MAS1_TSIZE(tsize) | MAS1_TID(pid); |
131 | TLBCAM[index].MAS2 = virt & PAGE_MASK; | 130 | TLBCAM[index].MAS2 = virt & PAGE_MASK; |
132 | 131 | ||
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c index 37ece1542799..ddd04d4c1ea9 100644 --- a/arch/ppc/platforms/83xx/mpc834x_sys.c +++ b/arch/ppc/platforms/83xx/mpc834x_sys.c | |||
@@ -94,20 +94,24 @@ mpc834x_sys_setup_arch(void) | |||
94 | 94 | ||
95 | /* setup the board related information for the enet controllers */ | 95 | /* setup the board related information for the enet controllers */ |
96 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC1); | 96 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC1); |
97 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 97 | if (pdata) { |
98 | pdata->interruptPHY = MPC83xx_IRQ_EXT1; | 98 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
99 | pdata->phyid = 0; | 99 | pdata->interruptPHY = MPC83xx_IRQ_EXT1; |
100 | /* fixup phy address */ | 100 | pdata->phyid = 0; |
101 | pdata->phy_reg_addr += binfo->bi_immr_base; | 101 | /* fixup phy address */ |
102 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | 102 | pdata->phy_reg_addr += binfo->bi_immr_base; |
103 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | ||
104 | } | ||
103 | 105 | ||
104 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC2); | 106 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC2); |
105 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 107 | if (pdata) { |
106 | pdata->interruptPHY = MPC83xx_IRQ_EXT2; | 108 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
107 | pdata->phyid = 1; | 109 | pdata->interruptPHY = MPC83xx_IRQ_EXT2; |
108 | /* fixup phy address */ | 110 | pdata->phyid = 1; |
109 | pdata->phy_reg_addr += binfo->bi_immr_base; | 111 | /* fixup phy address */ |
110 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | 112 | pdata->phy_reg_addr += binfo->bi_immr_base; |
113 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | ||
114 | } | ||
111 | 115 | ||
112 | #ifdef CONFIG_BLK_DEV_INITRD | 116 | #ifdef CONFIG_BLK_DEV_INITRD |
113 | if (initrd_start) | 117 | if (initrd_start) |
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c index a2ed611cd936..ddd2e9a5bb12 100644 --- a/arch/ppc/platforms/85xx/mpc8540_ads.c +++ b/arch/ppc/platforms/85xx/mpc8540_ads.c | |||
@@ -92,28 +92,34 @@ mpc8540ads_setup_arch(void) | |||
92 | 92 | ||
93 | /* setup the board related information for the enet controllers */ | 93 | /* setup the board related information for the enet controllers */ |
94 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); | 94 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); |
95 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 95 | if (pdata) { |
96 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; | 96 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
97 | pdata->phyid = 0; | 97 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; |
98 | /* fixup phy address */ | 98 | pdata->phyid = 0; |
99 | pdata->phy_reg_addr += binfo->bi_immr_base; | 99 | /* fixup phy address */ |
100 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | 100 | pdata->phy_reg_addr += binfo->bi_immr_base; |
101 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | ||
102 | } | ||
101 | 103 | ||
102 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); | 104 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); |
103 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 105 | if (pdata) { |
104 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; | 106 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
105 | pdata->phyid = 1; | 107 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; |
106 | /* fixup phy address */ | 108 | pdata->phyid = 1; |
107 | pdata->phy_reg_addr += binfo->bi_immr_base; | 109 | /* fixup phy address */ |
108 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | 110 | pdata->phy_reg_addr += binfo->bi_immr_base; |
109 | 111 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | |
110 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC); | 112 | } |
111 | pdata->board_flags = 0; | 113 | |
112 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; | 114 | if (pdata) { |
113 | pdata->phyid = 3; | 115 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC); |
114 | /* fixup phy address */ | 116 | pdata->board_flags = 0; |
115 | pdata->phy_reg_addr += binfo->bi_immr_base; | 117 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; |
116 | memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6); | 118 | pdata->phyid = 3; |
119 | /* fixup phy address */ | ||
120 | pdata->phy_reg_addr += binfo->bi_immr_base; | ||
121 | memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6); | ||
122 | } | ||
117 | 123 | ||
118 | #ifdef CONFIG_BLK_DEV_INITRD | 124 | #ifdef CONFIG_BLK_DEV_INITRD |
119 | if (initrd_start) | 125 | if (initrd_start) |
diff --git a/arch/ppc/platforms/85xx/mpc8560_ads.c b/arch/ppc/platforms/85xx/mpc8560_ads.c index d87dfd5ce0a2..e18380258b68 100644 --- a/arch/ppc/platforms/85xx/mpc8560_ads.c +++ b/arch/ppc/platforms/85xx/mpc8560_ads.c | |||
@@ -90,20 +90,24 @@ mpc8560ads_setup_arch(void) | |||
90 | 90 | ||
91 | /* setup the board related information for the enet controllers */ | 91 | /* setup the board related information for the enet controllers */ |
92 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); | 92 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); |
93 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 93 | if (pdata) { |
94 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; | 94 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
95 | pdata->phyid = 0; | 95 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; |
96 | /* fixup phy address */ | 96 | pdata->phyid = 0; |
97 | pdata->phy_reg_addr += binfo->bi_immr_base; | 97 | /* fixup phy address */ |
98 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | 98 | pdata->phy_reg_addr += binfo->bi_immr_base; |
99 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | ||
100 | } | ||
99 | 101 | ||
100 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); | 102 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); |
101 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 103 | if (pdata) { |
102 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; | 104 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
103 | pdata->phyid = 1; | 105 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; |
104 | /* fixup phy address */ | 106 | pdata->phyid = 1; |
105 | pdata->phy_reg_addr += binfo->bi_immr_base; | 107 | /* fixup phy address */ |
106 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | 108 | pdata->phy_reg_addr += binfo->bi_immr_base; |
109 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | ||
110 | } | ||
107 | 111 | ||
108 | #ifdef CONFIG_BLK_DEV_INITRD | 112 | #ifdef CONFIG_BLK_DEV_INITRD |
109 | if (initrd_start) | 113 | if (initrd_start) |
diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c index 3dbdd73618eb..165df94d4aa6 100644 --- a/arch/ppc/platforms/85xx/sbc8560.c +++ b/arch/ppc/platforms/85xx/sbc8560.c | |||
@@ -129,20 +129,24 @@ sbc8560_setup_arch(void) | |||
129 | 129 | ||
130 | /* setup the board related information for the enet controllers */ | 130 | /* setup the board related information for the enet controllers */ |
131 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); | 131 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); |
132 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 132 | if (pdata) { |
133 | pdata->interruptPHY = MPC85xx_IRQ_EXT6; | 133 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
134 | pdata->phyid = 25; | 134 | pdata->interruptPHY = MPC85xx_IRQ_EXT6; |
135 | /* fixup phy address */ | 135 | pdata->phyid = 25; |
136 | pdata->phy_reg_addr += binfo->bi_immr_base; | 136 | /* fixup phy address */ |
137 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | 137 | pdata->phy_reg_addr += binfo->bi_immr_base; |
138 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | ||
139 | } | ||
138 | 140 | ||
139 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); | 141 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); |
140 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; | 142 | if (pdata) { |
141 | pdata->interruptPHY = MPC85xx_IRQ_EXT7; | 143 | pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; |
142 | pdata->phyid = 26; | 144 | pdata->interruptPHY = MPC85xx_IRQ_EXT7; |
143 | /* fixup phy address */ | 145 | pdata->phyid = 26; |
144 | pdata->phy_reg_addr += binfo->bi_immr_base; | 146 | /* fixup phy address */ |
145 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | 147 | pdata->phy_reg_addr += binfo->bi_immr_base; |
148 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | ||
149 | } | ||
146 | 150 | ||
147 | #ifdef CONFIG_BLK_DEV_INITRD | 151 | #ifdef CONFIG_BLK_DEV_INITRD |
148 | if (initrd_start) | 152 | if (initrd_start) |
diff --git a/arch/ppc/platforms/85xx/stx_gp3.c b/arch/ppc/platforms/85xx/stx_gp3.c index 9455bb6b45e9..bb41265cfc85 100644 --- a/arch/ppc/platforms/85xx/stx_gp3.c +++ b/arch/ppc/platforms/85xx/stx_gp3.c | |||
@@ -122,19 +122,23 @@ gp3_setup_arch(void) | |||
122 | 122 | ||
123 | /* setup the board related information for the enet controllers */ | 123 | /* setup the board related information for the enet controllers */ |
124 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); | 124 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); |
125 | /* pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */ | 125 | if (pdata) { |
126 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; | 126 | /* pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */ |
127 | pdata->phyid = 2; | 127 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; |
128 | pdata->phy_reg_addr += binfo->bi_immr_base; | 128 | pdata->phyid = 2; |
129 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | 129 | pdata->phy_reg_addr += binfo->bi_immr_base; |
130 | memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); | ||
131 | } | ||
130 | 132 | ||
131 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); | 133 | pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); |
132 | /* pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */ | 134 | if (pdata) { |
133 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; | 135 | /* pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */ |
134 | pdata->phyid = 4; | 136 | pdata->interruptPHY = MPC85xx_IRQ_EXT5; |
135 | /* fixup phy address */ | 137 | pdata->phyid = 4; |
136 | pdata->phy_reg_addr += binfo->bi_immr_base; | 138 | /* fixup phy address */ |
137 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | 139 | pdata->phy_reg_addr += binfo->bi_immr_base; |
140 | memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); | ||
141 | } | ||
138 | 142 | ||
139 | #ifdef CONFIG_BLK_DEV_INITRD | 143 | #ifdef CONFIG_BLK_DEV_INITRD |
140 | if (initrd_start) | 144 | if (initrd_start) |
diff --git a/arch/ppc/platforms/chrp_pci.c b/arch/ppc/platforms/chrp_pci.c index 7d0ee308f662..7d3fbb5c5db2 100644 --- a/arch/ppc/platforms/chrp_pci.c +++ b/arch/ppc/platforms/chrp_pci.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/string.h> | 9 | #include <linux/string.h> |
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/ide.h> | 11 | #include <linux/ide.h> |
12 | #include <linux/bootmem.h> | ||
13 | 12 | ||
14 | #include <asm/io.h> | 13 | #include <asm/io.h> |
15 | #include <asm/pgtable.h> | 14 | #include <asm/pgtable.h> |
diff --git a/arch/ppc/platforms/katana.c b/arch/ppc/platforms/katana.c index eda922ac3167..169dbf6534b9 100644 --- a/arch/ppc/platforms/katana.c +++ b/arch/ppc/platforms/katana.c | |||
@@ -27,12 +27,12 @@ | |||
27 | #include <linux/root_dev.h> | 27 | #include <linux/root_dev.h> |
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | #include <linux/seq_file.h> | 29 | #include <linux/seq_file.h> |
30 | #include <linux/bootmem.h> | ||
31 | #include <linux/mtd/physmap.h> | 30 | #include <linux/mtd/physmap.h> |
32 | #include <linux/mv643xx.h> | 31 | #include <linux/mv643xx.h> |
33 | #ifdef CONFIG_BOOTIMG | 32 | #ifdef CONFIG_BOOTIMG |
34 | #include <linux/bootimg.h> | 33 | #include <linux/bootimg.h> |
35 | #endif | 34 | #endif |
35 | #include <asm/io.h> | ||
36 | #include <asm/page.h> | 36 | #include <asm/page.h> |
37 | #include <asm/time.h> | 37 | #include <asm/time.h> |
38 | #include <asm/smp.h> | 38 | #include <asm/smp.h> |
diff --git a/arch/ppc/platforms/pmac_pci.c b/arch/ppc/platforms/pmac_pci.c index f6ff51924061..719fb49fe2bc 100644 --- a/arch/ppc/platforms/pmac_pci.c +++ b/arch/ppc/platforms/pmac_pci.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/string.h> | 18 | #include <linux/string.h> |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/bootmem.h> | ||
21 | 20 | ||
22 | #include <asm/sections.h> | 21 | #include <asm/sections.h> |
23 | #include <asm/io.h> | 22 | #include <asm/io.h> |
diff --git a/arch/ppc/syslib/cpm2_common.c b/arch/ppc/syslib/cpm2_common.c index ea5e77080e8d..4c19a4ac7163 100644 --- a/arch/ppc/syslib/cpm2_common.c +++ b/arch/ppc/syslib/cpm2_common.c | |||
@@ -21,8 +21,8 @@ | |||
21 | #include <linux/string.h> | 21 | #include <linux/string.h> |
22 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | #include <linux/bootmem.h> | ||
25 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <asm/io.h> | ||
26 | #include <asm/irq.h> | 26 | #include <asm/irq.h> |
27 | #include <asm/mpc8260.h> | 27 | #include <asm/mpc8260.h> |
28 | #include <asm/page.h> | 28 | #include <asm/page.h> |
diff --git a/arch/ppc/syslib/indirect_pci.c b/arch/ppc/syslib/indirect_pci.c index a5a752609e2c..e71488469704 100644 --- a/arch/ppc/syslib/indirect_pci.c +++ b/arch/ppc/syslib/indirect_pci.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | #include <linux/string.h> | 15 | #include <linux/string.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/bootmem.h> | ||
18 | 17 | ||
19 | #include <asm/io.h> | 18 | #include <asm/io.h> |
20 | #include <asm/prom.h> | 19 | #include <asm/prom.h> |
diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c index 7b241e7876bd..cc77177fa1c6 100644 --- a/arch/ppc/syslib/mv64x60.c +++ b/arch/ppc/syslib/mv64x60.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/string.h> | 19 | #include <linux/string.h> |
20 | #include <linux/bootmem.h> | ||
21 | #include <linux/spinlock.h> | 20 | #include <linux/spinlock.h> |
22 | #include <linux/mv643xx.h> | 21 | #include <linux/mv643xx.h> |
23 | 22 | ||
diff --git a/arch/ppc/syslib/mv64x60_win.c b/arch/ppc/syslib/mv64x60_win.c index b6f0f5dcf6ee..5b827e2bbe22 100644 --- a/arch/ppc/syslib/mv64x60_win.c +++ b/arch/ppc/syslib/mv64x60_win.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/string.h> | 19 | #include <linux/string.h> |
20 | #include <linux/bootmem.h> | ||
21 | #include <linux/mv643xx.h> | 20 | #include <linux/mv643xx.h> |
22 | 21 | ||
23 | #include <asm/byteorder.h> | 22 | #include <asm/byteorder.h> |
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index cb27068bfcd4..f804f25232ac 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig | |||
@@ -142,6 +142,23 @@ config PPC_SPLPAR | |||
142 | processors, that is, which share physical processors between | 142 | processors, that is, which share physical processors between |
143 | two or more partitions. | 143 | two or more partitions. |
144 | 144 | ||
145 | config KEXEC | ||
146 | bool "kexec system call (EXPERIMENTAL)" | ||
147 | depends on PPC_MULTIPLATFORM && EXPERIMENTAL | ||
148 | help | ||
149 | kexec is a system call that implements the ability to shutdown your | ||
150 | current kernel, and to start another kernel. It is like a reboot | ||
151 | but it is indepedent of the system firmware. And like a reboot | ||
152 | you can start any kernel with it, not just Linux. | ||
153 | |||
154 | The name comes from the similiarity to the exec system call. | ||
155 | |||
156 | It is an ongoing process to be certain the hardware in a machine | ||
157 | is properly shutdown, so do not be surprised if this code does not | ||
158 | initially work for you. It may help to enable device hotplugging | ||
159 | support. As of this writing the exact hardware interface is | ||
160 | strongly in flux, so no good recommendation can be made. | ||
161 | |||
145 | config IBMVIO | 162 | config IBMVIO |
146 | depends on PPC_PSERIES || PPC_ISERIES | 163 | depends on PPC_PSERIES || PPC_ISERIES |
147 | bool | 164 | bool |
@@ -270,26 +287,7 @@ config SCHED_SMT | |||
270 | when dealing with POWER5 cpus at a cost of slightly increased | 287 | when dealing with POWER5 cpus at a cost of slightly increased |
271 | overhead in some places. If unsure say N here. | 288 | overhead in some places. If unsure say N here. |
272 | 289 | ||
273 | config PREEMPT | 290 | source "kernel/Kconfig.preempt" |
274 | bool "Preemptible Kernel" | ||
275 | help | ||
276 | This option reduces the latency of the kernel when reacting to | ||
277 | real-time or interactive events by allowing a low priority process to | ||
278 | be preempted even if it is in kernel mode executing a system call. | ||
279 | |||
280 | Say Y here if you are building a kernel for a desktop, embedded | ||
281 | or real-time system. Say N if you are unsure. | ||
282 | |||
283 | config PREEMPT_BKL | ||
284 | bool "Preempt The Big Kernel Lock" | ||
285 | depends on PREEMPT | ||
286 | default y | ||
287 | help | ||
288 | This option reduces the latency of the kernel by making the | ||
289 | big kernel lock preemptible. | ||
290 | |||
291 | Say Y here if you are building a kernel for a desktop system. | ||
292 | Say N if you are unsure. | ||
293 | 291 | ||
294 | config EEH | 292 | config EEH |
295 | bool "PCI Extended Error Handling (EEH)" if EMBEDDED | 293 | bool "PCI Extended Error Handling (EEH)" if EMBEDDED |
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index dffbfb7ac8d5..d9b2660ef221 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile | |||
@@ -36,6 +36,7 @@ obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \ | |||
36 | obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o \ | 36 | obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o \ |
37 | bpa_iic.o spider-pic.o | 37 | bpa_iic.o spider-pic.o |
38 | 38 | ||
39 | obj-$(CONFIG_KEXEC) += machine_kexec.o | ||
39 | obj-$(CONFIG_EEH) += eeh.o | 40 | obj-$(CONFIG_EEH) += eeh.o |
40 | obj-$(CONFIG_PROC_FS) += proc_ppc64.o | 41 | obj-$(CONFIG_PROC_FS) += proc_ppc64.o |
41 | obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o | 42 | obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o |
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index 02c8f4e3e4bc..675c2708588f 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S | |||
@@ -1194,7 +1194,7 @@ _GLOBAL(pSeries_secondary_smp_init) | |||
1194 | bl .__restore_cpu_setup | 1194 | bl .__restore_cpu_setup |
1195 | 1195 | ||
1196 | /* Set up a paca value for this processor. Since we have the | 1196 | /* Set up a paca value for this processor. Since we have the |
1197 | * physical cpu id in r3, we need to search the pacas to find | 1197 | * physical cpu id in r24, we need to search the pacas to find |
1198 | * which logical id maps to our physical one. | 1198 | * which logical id maps to our physical one. |
1199 | */ | 1199 | */ |
1200 | LOADADDR(r13, paca) /* Get base vaddr of paca array */ | 1200 | LOADADDR(r13, paca) /* Get base vaddr of paca array */ |
@@ -1207,8 +1207,8 @@ _GLOBAL(pSeries_secondary_smp_init) | |||
1207 | cmpwi r5,NR_CPUS | 1207 | cmpwi r5,NR_CPUS |
1208 | blt 1b | 1208 | blt 1b |
1209 | 1209 | ||
1210 | 99: HMT_LOW /* Couldn't find our CPU id */ | 1210 | mr r3,r24 /* not found, copy phys to r3 */ |
1211 | b 99b | 1211 | b .kexec_wait /* next kernel might do better */ |
1212 | 1212 | ||
1213 | 2: mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */ | 1213 | 2: mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */ |
1214 | /* From now on, r24 is expected to be logica cpuid */ | 1214 | /* From now on, r24 is expected to be logica cpuid */ |
diff --git a/arch/ppc64/kernel/lparcfg.c b/arch/ppc64/kernel/lparcfg.c index 387923fcf9b0..02e96627fa66 100644 --- a/arch/ppc64/kernel/lparcfg.c +++ b/arch/ppc64/kernel/lparcfg.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <asm/system.h> | 34 | #include <asm/system.h> |
35 | #include <asm/time.h> | 35 | #include <asm/time.h> |
36 | #include <asm/iSeries/ItExtVpdPanel.h> | 36 | #include <asm/iSeries/ItExtVpdPanel.h> |
37 | #include <asm/prom.h> | ||
37 | 38 | ||
38 | #define MODULE_VERS "1.6" | 39 | #define MODULE_VERS "1.6" |
39 | #define MODULE_NAME "lparcfg" | 40 | #define MODULE_NAME "lparcfg" |
diff --git a/arch/ppc64/kernel/machine_kexec.c b/arch/ppc64/kernel/machine_kexec.c new file mode 100644 index 000000000000..fdb2fc649d72 --- /dev/null +++ b/arch/ppc64/kernel/machine_kexec.c | |||
@@ -0,0 +1,302 @@ | |||
1 | /* | ||
2 | * machine_kexec.c - handle transition of Linux booting another kernel | ||
3 | * | ||
4 | * Copyright (C) 2004-2005, IBM Corp. | ||
5 | * | ||
6 | * Created by: Milton D Miller II | ||
7 | * | ||
8 | * This source code is licensed under the GNU General Public License, | ||
9 | * Version 2. See the file COPYING for more details. | ||
10 | */ | ||
11 | |||
12 | |||
13 | #include <linux/cpumask.h> | ||
14 | #include <linux/kexec.h> | ||
15 | #include <linux/smp.h> | ||
16 | #include <linux/thread_info.h> | ||
17 | #include <linux/errno.h> | ||
18 | |||
19 | #include <asm/page.h> | ||
20 | #include <asm/current.h> | ||
21 | #include <asm/machdep.h> | ||
22 | #include <asm/cacheflush.h> | ||
23 | #include <asm/paca.h> | ||
24 | #include <asm/mmu.h> | ||
25 | #include <asm/sections.h> /* _end */ | ||
26 | #include <asm/prom.h> | ||
27 | |||
28 | #define HASH_GROUP_SIZE 0x80 /* size of each hash group, asm/mmu.h */ | ||
29 | |||
30 | /* Have this around till we move it into crash specific file */ | ||
31 | note_buf_t crash_notes[NR_CPUS]; | ||
32 | |||
33 | /* Dummy for now. Not sure if we need to have a crash shutdown in here | ||
34 | * and if what it will achieve. Letting it be now to compile the code | ||
35 | * in generic kexec environment | ||
36 | */ | ||
37 | void machine_crash_shutdown(struct pt_regs *regs) | ||
38 | { | ||
39 | /* do nothing right now */ | ||
40 | /* smp_relase_cpus() if we want smp on panic kernel */ | ||
41 | /* cpu_irq_down to isolate us until we are ready */ | ||
42 | } | ||
43 | |||
44 | int machine_kexec_prepare(struct kimage *image) | ||
45 | { | ||
46 | int i; | ||
47 | unsigned long begin, end; /* limits of segment */ | ||
48 | unsigned long low, high; /* limits of blocked memory range */ | ||
49 | struct device_node *node; | ||
50 | unsigned long *basep; | ||
51 | unsigned int *sizep; | ||
52 | |||
53 | if (!ppc_md.hpte_clear_all) | ||
54 | return -ENOENT; | ||
55 | |||
56 | /* | ||
57 | * Since we use the kernel fault handlers and paging code to | ||
58 | * handle the virtual mode, we must make sure no destination | ||
59 | * overlaps kernel static data or bss. | ||
60 | */ | ||
61 | for (i = 0; i < image->nr_segments; i++) | ||
62 | if (image->segment[i].mem < __pa(_end)) | ||
63 | return -ETXTBSY; | ||
64 | |||
65 | /* | ||
66 | * For non-LPAR, we absolutely can not overwrite the mmu hash | ||
67 | * table, since we are still using the bolted entries in it to | ||
68 | * do the copy. Check that here. | ||
69 | * | ||
70 | * It is safe if the end is below the start of the blocked | ||
71 | * region (end <= low), or if the beginning is after the | ||
72 | * end of the blocked region (begin >= high). Use the | ||
73 | * boolean identity !(a || b) === (!a && !b). | ||
74 | */ | ||
75 | if (htab_address) { | ||
76 | low = __pa(htab_address); | ||
77 | high = low + (htab_hash_mask + 1) * HASH_GROUP_SIZE; | ||
78 | |||
79 | for (i = 0; i < image->nr_segments; i++) { | ||
80 | begin = image->segment[i].mem; | ||
81 | end = begin + image->segment[i].memsz; | ||
82 | |||
83 | if ((begin < high) && (end > low)) | ||
84 | return -ETXTBSY; | ||
85 | } | ||
86 | } | ||
87 | |||
88 | /* We also should not overwrite the tce tables */ | ||
89 | for (node = of_find_node_by_type(NULL, "pci"); node != NULL; | ||
90 | node = of_find_node_by_type(node, "pci")) { | ||
91 | basep = (unsigned long *)get_property(node, "linux,tce-base", | ||
92 | NULL); | ||
93 | sizep = (unsigned int *)get_property(node, "linux,tce-size", | ||
94 | NULL); | ||
95 | if (basep == NULL || sizep == NULL) | ||
96 | continue; | ||
97 | |||
98 | low = *basep; | ||
99 | high = low + (*sizep); | ||
100 | |||
101 | for (i = 0; i < image->nr_segments; i++) { | ||
102 | begin = image->segment[i].mem; | ||
103 | end = begin + image->segment[i].memsz; | ||
104 | |||
105 | if ((begin < high) && (end > low)) | ||
106 | return -ETXTBSY; | ||
107 | } | ||
108 | } | ||
109 | |||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | void machine_kexec_cleanup(struct kimage *image) | ||
114 | { | ||
115 | /* we do nothing in prepare that needs to be undone */ | ||
116 | } | ||
117 | |||
118 | #define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE) | ||
119 | |||
120 | static void copy_segments(unsigned long ind) | ||
121 | { | ||
122 | unsigned long entry; | ||
123 | unsigned long *ptr; | ||
124 | void *dest; | ||
125 | void *addr; | ||
126 | |||
127 | /* | ||
128 | * We rely on kexec_load to create a lists that properly | ||
129 | * initializes these pointers before they are used. | ||
130 | * We will still crash if the list is wrong, but at least | ||
131 | * the compiler will be quiet. | ||
132 | */ | ||
133 | ptr = NULL; | ||
134 | dest = NULL; | ||
135 | |||
136 | for (entry = ind; !(entry & IND_DONE); entry = *ptr++) { | ||
137 | addr = __va(entry & PAGE_MASK); | ||
138 | |||
139 | switch (entry & IND_FLAGS) { | ||
140 | case IND_DESTINATION: | ||
141 | dest = addr; | ||
142 | break; | ||
143 | case IND_INDIRECTION: | ||
144 | ptr = addr; | ||
145 | break; | ||
146 | case IND_SOURCE: | ||
147 | copy_page(dest, addr); | ||
148 | dest += PAGE_SIZE; | ||
149 | } | ||
150 | } | ||
151 | } | ||
152 | |||
153 | void kexec_copy_flush(struct kimage *image) | ||
154 | { | ||
155 | long i, nr_segments = image->nr_segments; | ||
156 | struct kexec_segment ranges[KEXEC_SEGMENT_MAX]; | ||
157 | |||
158 | /* save the ranges on the stack to efficiently flush the icache */ | ||
159 | memcpy(ranges, image->segment, sizeof(ranges)); | ||
160 | |||
161 | /* | ||
162 | * After this call we may not use anything allocated in dynamic | ||
163 | * memory, including *image. | ||
164 | * | ||
165 | * Only globals and the stack are allowed. | ||
166 | */ | ||
167 | copy_segments(image->head); | ||
168 | |||
169 | /* | ||
170 | * we need to clear the icache for all dest pages sometime, | ||
171 | * including ones that were in place on the original copy | ||
172 | */ | ||
173 | for (i = 0; i < nr_segments; i++) | ||
174 | flush_icache_range(ranges[i].mem + KERNELBASE, | ||
175 | ranges[i].mem + KERNELBASE + | ||
176 | ranges[i].memsz); | ||
177 | } | ||
178 | |||
179 | #ifdef CONFIG_SMP | ||
180 | |||
181 | /* FIXME: we should schedule this function to be called on all cpus based | ||
182 | * on calling the interrupts, but we would like to call it off irq level | ||
183 | * so that the interrupt controller is clean. | ||
184 | */ | ||
185 | void kexec_smp_down(void *arg) | ||
186 | { | ||
187 | if (ppc_md.cpu_irq_down) | ||
188 | ppc_md.cpu_irq_down(); | ||
189 | |||
190 | local_irq_disable(); | ||
191 | kexec_smp_wait(); | ||
192 | /* NOTREACHED */ | ||
193 | } | ||
194 | |||
195 | static void kexec_prepare_cpus(void) | ||
196 | { | ||
197 | int my_cpu, i, notified=-1; | ||
198 | |||
199 | smp_call_function(kexec_smp_down, NULL, 0, /* wait */0); | ||
200 | my_cpu = get_cpu(); | ||
201 | |||
202 | /* check the others cpus are now down (via paca hw cpu id == -1) */ | ||
203 | for (i=0; i < NR_CPUS; i++) { | ||
204 | if (i == my_cpu) | ||
205 | continue; | ||
206 | |||
207 | while (paca[i].hw_cpu_id != -1) { | ||
208 | if (!cpu_possible(i)) { | ||
209 | printk("kexec: cpu %d hw_cpu_id %d is not" | ||
210 | " possible, ignoring\n", | ||
211 | i, paca[i].hw_cpu_id); | ||
212 | break; | ||
213 | } | ||
214 | if (!cpu_online(i)) { | ||
215 | /* Fixme: this can be spinning in | ||
216 | * pSeries_secondary_wait with a paca | ||
217 | * waiting for it to go online. | ||
218 | */ | ||
219 | printk("kexec: cpu %d hw_cpu_id %d is not" | ||
220 | " online, ignoring\n", | ||
221 | i, paca[i].hw_cpu_id); | ||
222 | break; | ||
223 | } | ||
224 | if (i != notified) { | ||
225 | printk( "kexec: waiting for cpu %d (physical" | ||
226 | " %d) to go down\n", | ||
227 | i, paca[i].hw_cpu_id); | ||
228 | notified = i; | ||
229 | } | ||
230 | } | ||
231 | } | ||
232 | |||
233 | /* after we tell the others to go down */ | ||
234 | if (ppc_md.cpu_irq_down) | ||
235 | ppc_md.cpu_irq_down(); | ||
236 | |||
237 | put_cpu(); | ||
238 | |||
239 | local_irq_disable(); | ||
240 | } | ||
241 | |||
242 | #else /* ! SMP */ | ||
243 | |||
244 | static void kexec_prepare_cpus(void) | ||
245 | { | ||
246 | /* | ||
247 | * move the secondarys to us so that we can copy | ||
248 | * the new kernel 0-0x100 safely | ||
249 | * | ||
250 | * do this if kexec in setup.c ? | ||
251 | */ | ||
252 | smp_relase_cpus(); | ||
253 | if (ppc_md.cpu_irq_down) | ||
254 | ppc_md.cpu_irq_down(); | ||
255 | local_irq_disable(); | ||
256 | } | ||
257 | |||
258 | #endif /* SMP */ | ||
259 | |||
260 | /* | ||
261 | * kexec thread structure and stack. | ||
262 | * | ||
263 | * We need to make sure that this is 16384-byte aligned due to the | ||
264 | * way process stacks are handled. It also must be statically allocated | ||
265 | * or allocated as part of the kimage, because everything else may be | ||
266 | * overwritten when we copy the kexec image. We piggyback on the | ||
267 | * "init_task" linker section here to statically allocate a stack. | ||
268 | * | ||
269 | * We could use a smaller stack if we don't care about anything using | ||
270 | * current, but that audit has not been performed. | ||
271 | */ | ||
272 | union thread_union kexec_stack | ||
273 | __attribute__((__section__(".data.init_task"))) = { }; | ||
274 | |||
275 | /* Our assembly helper, in kexec_stub.S */ | ||
276 | extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start, | ||
277 | void *image, void *control, | ||
278 | void (*clear_all)(void)) ATTRIB_NORET; | ||
279 | |||
280 | /* too late to fail here */ | ||
281 | void machine_kexec(struct kimage *image) | ||
282 | { | ||
283 | |||
284 | /* prepare control code if any */ | ||
285 | |||
286 | /* shutdown other cpus into our wait loop and quiesce interrupts */ | ||
287 | kexec_prepare_cpus(); | ||
288 | |||
289 | /* switch to a staticly allocated stack. Based on irq stack code. | ||
290 | * XXX: the task struct will likely be invalid once we do the copy! | ||
291 | */ | ||
292 | kexec_stack.thread_info.task = current_thread_info()->task; | ||
293 | kexec_stack.thread_info.flags = 0; | ||
294 | |||
295 | /* Some things are best done in assembly. Finding globals with | ||
296 | * a toc is easier in C, so pass in what we can. | ||
297 | */ | ||
298 | kexec_sequence(&kexec_stack, image->start, image, | ||
299 | page_address(image->control_code_page), | ||
300 | ppc_md.hpte_clear_all); | ||
301 | /* NOTREACHED */ | ||
302 | } | ||
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index e3c73b3425dc..f3dea0c5a88c 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S | |||
@@ -680,6 +680,177 @@ _GLOBAL(kernel_thread) | |||
680 | ld r30,-16(r1) | 680 | ld r30,-16(r1) |
681 | blr | 681 | blr |
682 | 682 | ||
683 | /* kexec_wait(phys_cpu) | ||
684 | * | ||
685 | * wait for the flag to change, indicating this kernel is going away but | ||
686 | * the slave code for the next one is at addresses 0 to 100. | ||
687 | * | ||
688 | * This is used by all slaves. | ||
689 | * | ||
690 | * Physical (hardware) cpu id should be in r3. | ||
691 | */ | ||
692 | _GLOBAL(kexec_wait) | ||
693 | bl 1f | ||
694 | 1: mflr r5 | ||
695 | addi r5,r5,kexec_flag-1b | ||
696 | |||
697 | 99: HMT_LOW | ||
698 | #ifdef CONFIG_KEXEC /* use no memory without kexec */ | ||
699 | lwz r4,0(r5) | ||
700 | cmpwi 0,r4,0 | ||
701 | bnea 0x60 | ||
702 | #endif | ||
703 | b 99b | ||
704 | |||
705 | /* this can be in text because we won't change it until we are | ||
706 | * running in real anyways | ||
707 | */ | ||
708 | kexec_flag: | ||
709 | .long 0 | ||
710 | |||
711 | |||
712 | #ifdef CONFIG_KEXEC | ||
713 | |||
714 | /* kexec_smp_wait(void) | ||
715 | * | ||
716 | * call with interrupts off | ||
717 | * note: this is a terminal routine, it does not save lr | ||
718 | * | ||
719 | * get phys id from paca | ||
720 | * set paca id to -1 to say we got here | ||
721 | * switch to real mode | ||
722 | * join other cpus in kexec_wait(phys_id) | ||
723 | */ | ||
724 | _GLOBAL(kexec_smp_wait) | ||
725 | lhz r3,PACAHWCPUID(r13) | ||
726 | li r4,-1 | ||
727 | sth r4,PACAHWCPUID(r13) /* let others know we left */ | ||
728 | bl real_mode | ||
729 | b .kexec_wait | ||
730 | |||
731 | /* | ||
732 | * switch to real mode (turn mmu off) | ||
733 | * we use the early kernel trick that the hardware ignores bits | ||
734 | * 0 and 1 (big endian) of the effective address in real mode | ||
735 | * | ||
736 | * don't overwrite r3 here, it is live for kexec_wait above. | ||
737 | */ | ||
738 | real_mode: /* assume normal blr return */ | ||
739 | 1: li r9,MSR_RI | ||
740 | li r10,MSR_DR|MSR_IR | ||
741 | mflr r11 /* return address to SRR0 */ | ||
742 | mfmsr r12 | ||
743 | andc r9,r12,r9 | ||
744 | andc r10,r12,r10 | ||
745 | |||
746 | mtmsrd r9,1 | ||
747 | mtspr SPRN_SRR1,r10 | ||
748 | mtspr SPRN_SRR0,r11 | ||
749 | rfid | ||
750 | |||
751 | |||
752 | /* | ||
753 | * kexec_sequence(newstack, start, image, control, clear_all()) | ||
754 | * | ||
755 | * does the grungy work with stack switching and real mode switches | ||
756 | * also does simple calls to other code | ||
757 | */ | ||
758 | |||
759 | _GLOBAL(kexec_sequence) | ||
760 | mflr r0 | ||
761 | std r0,16(r1) | ||
762 | |||
763 | /* switch stacks to newstack -- &kexec_stack.stack */ | ||
764 | stdu r1,THREAD_SIZE-112(r3) | ||
765 | mr r1,r3 | ||
766 | |||
767 | li r0,0 | ||
768 | std r0,16(r1) | ||
769 | |||
770 | /* save regs for local vars on new stack. | ||
771 | * yes, we won't go back, but ... | ||
772 | */ | ||
773 | std r31,-8(r1) | ||
774 | std r30,-16(r1) | ||
775 | std r29,-24(r1) | ||
776 | std r28,-32(r1) | ||
777 | std r27,-40(r1) | ||
778 | std r26,-48(r1) | ||
779 | std r25,-56(r1) | ||
780 | |||
781 | stdu r1,-112-64(r1) | ||
782 | |||
783 | /* save args into preserved regs */ | ||
784 | mr r31,r3 /* newstack (both) */ | ||
785 | mr r30,r4 /* start (real) */ | ||
786 | mr r29,r5 /* image (virt) */ | ||
787 | mr r28,r6 /* control, unused */ | ||
788 | mr r27,r7 /* clear_all() fn desc */ | ||
789 | mr r26,r8 /* spare */ | ||
790 | lhz r25,PACAHWCPUID(r13) /* get our phys cpu from paca */ | ||
791 | |||
792 | /* disable interrupts, we are overwriting kernel data next */ | ||
793 | mfmsr r3 | ||
794 | rlwinm r3,r3,0,17,15 | ||
795 | mtmsrd r3,1 | ||
796 | |||
797 | /* copy dest pages, flush whole dest image */ | ||
798 | mr r3,r29 | ||
799 | bl .kexec_copy_flush /* (image) */ | ||
800 | |||
801 | /* turn off mmu */ | ||
802 | bl real_mode | ||
803 | |||
804 | /* clear out hardware hash page table and tlb */ | ||
805 | ld r5,0(r27) /* deref function descriptor */ | ||
806 | mtctr r5 | ||
807 | bctrl /* ppc_md.hash_clear_all(void); */ | ||
808 | |||
809 | /* | ||
810 | * kexec image calling is: | ||
811 | * the first 0x100 bytes of the entry point are copied to 0 | ||
812 | * | ||
813 | * all slaves branch to slave = 0x60 (absolute) | ||
814 | * slave(phys_cpu_id); | ||
815 | * | ||
816 | * master goes to start = entry point | ||
817 | * start(phys_cpu_id, start, 0); | ||
818 | * | ||
819 | * | ||
820 | * a wrapper is needed to call existing kernels, here is an approximate | ||
821 | * description of one method: | ||
822 | * | ||
823 | * v2: (2.6.10) | ||
824 | * start will be near the boot_block (maybe 0x100 bytes before it?) | ||
825 | * it will have a 0x60, which will b to boot_block, where it will wait | ||
826 | * and 0 will store phys into struct boot-block and load r3 from there, | ||
827 | * copy kernel 0-0x100 and tell slaves to back down to 0x60 again | ||
828 | * | ||
829 | * v1: (2.6.9) | ||
830 | * boot block will have all cpus scanning device tree to see if they | ||
831 | * are the boot cpu ????? | ||
832 | * other device tree differences (prop sizes, va vs pa, etc)... | ||
833 | */ | ||
834 | |||
835 | /* copy 0x100 bytes starting at start to 0 */ | ||
836 | li r3,0 | ||
837 | mr r4,r30 | ||
838 | li r5,0x100 | ||
839 | li r6,0 | ||
840 | bl .copy_and_flush /* (dest, src, copy limit, start offset) */ | ||
841 | 1: /* assume normal blr return */ | ||
842 | |||
843 | /* release other cpus to the new kernel secondary start at 0x60 */ | ||
844 | mflr r5 | ||
845 | li r6,1 | ||
846 | stw r6,kexec_flag-1b(5) | ||
847 | mr r3,r25 # my phys cpu | ||
848 | mr r4,r30 # start, aka phys mem offset | ||
849 | mtlr 4 | ||
850 | li r5,0 | ||
851 | blr /* image->start(physid, image->start, 0); */ | ||
852 | #endif /* CONFIG_KEXEC */ | ||
853 | |||
683 | /* Why isn't this a) automatic, b) written in 'C'? */ | 854 | /* Why isn't this a) automatic, b) written in 'C'? */ |
684 | .balign 8 | 855 | .balign 8 |
685 | _GLOBAL(sys_call_table32) | 856 | _GLOBAL(sys_call_table32) |
@@ -951,7 +1122,7 @@ _GLOBAL(sys_call_table32) | |||
951 | .llong .compat_sys_mq_timedreceive /* 265 */ | 1122 | .llong .compat_sys_mq_timedreceive /* 265 */ |
952 | .llong .compat_sys_mq_notify | 1123 | .llong .compat_sys_mq_notify |
953 | .llong .compat_sys_mq_getsetattr | 1124 | .llong .compat_sys_mq_getsetattr |
954 | .llong .sys_ni_syscall /* 268 reserved for sys_kexec_load */ | 1125 | .llong .compat_sys_kexec_load |
955 | .llong .sys32_add_key | 1126 | .llong .sys32_add_key |
956 | .llong .sys32_request_key | 1127 | .llong .sys32_request_key |
957 | .llong .compat_sys_keyctl | 1128 | .llong .compat_sys_keyctl |
@@ -1227,7 +1398,7 @@ _GLOBAL(sys_call_table) | |||
1227 | .llong .sys_mq_timedreceive /* 265 */ | 1398 | .llong .sys_mq_timedreceive /* 265 */ |
1228 | .llong .sys_mq_notify | 1399 | .llong .sys_mq_notify |
1229 | .llong .sys_mq_getsetattr | 1400 | .llong .sys_mq_getsetattr |
1230 | .llong .sys_ni_syscall /* 268 reserved for sys_kexec_load */ | 1401 | .llong .sys_kexec_load |
1231 | .llong .sys_add_key | 1402 | .llong .sys_add_key |
1232 | .llong .sys_request_key /* 270 */ | 1403 | .llong .sys_request_key /* 270 */ |
1233 | .llong .sys_keyctl | 1404 | .llong .sys_keyctl |
diff --git a/arch/ppc64/kernel/mpic.c b/arch/ppc64/kernel/mpic.c index 593ea5b82afa..e8fbab1df37f 100644 --- a/arch/ppc64/kernel/mpic.c +++ b/arch/ppc64/kernel/mpic.c | |||
@@ -792,6 +792,35 @@ void mpic_setup_this_cpu(void) | |||
792 | #endif /* CONFIG_SMP */ | 792 | #endif /* CONFIG_SMP */ |
793 | } | 793 | } |
794 | 794 | ||
795 | /* | ||
796 | * XXX: someone who knows mpic should check this. | ||
797 | * do we need to eoi the ipi here (see xics comments)? | ||
798 | * or can we reset the mpic in the new kernel? | ||
799 | */ | ||
800 | void mpic_teardown_this_cpu(void) | ||
801 | { | ||
802 | struct mpic *mpic = mpic_primary; | ||
803 | unsigned long flags; | ||
804 | u32 msk = 1 << hard_smp_processor_id(); | ||
805 | unsigned int i; | ||
806 | |||
807 | BUG_ON(mpic == NULL); | ||
808 | |||
809 | DBG("%s: teardown_this_cpu(%d)\n", mpic->name, hard_smp_processor_id()); | ||
810 | spin_lock_irqsave(&mpic_lock, flags); | ||
811 | |||
812 | /* let the mpic know we don't want intrs. */ | ||
813 | for (i = 0; i < mpic->num_sources ; i++) | ||
814 | mpic_irq_write(i, MPIC_IRQ_DESTINATION, | ||
815 | mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk); | ||
816 | |||
817 | /* Set current processor priority to max */ | ||
818 | mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf); | ||
819 | |||
820 | spin_unlock_irqrestore(&mpic_lock, flags); | ||
821 | } | ||
822 | |||
823 | |||
795 | void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask) | 824 | void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask) |
796 | { | 825 | { |
797 | struct mpic *mpic = mpic_primary; | 826 | struct mpic *mpic = mpic_primary; |
diff --git a/arch/ppc64/kernel/mpic.h b/arch/ppc64/kernel/mpic.h index 63e177143eac..99fbbc9a084c 100644 --- a/arch/ppc64/kernel/mpic.h +++ b/arch/ppc64/kernel/mpic.h | |||
@@ -255,6 +255,9 @@ extern unsigned int mpic_irq_get_priority(unsigned int irq); | |||
255 | /* Setup a non-boot CPU */ | 255 | /* Setup a non-boot CPU */ |
256 | extern void mpic_setup_this_cpu(void); | 256 | extern void mpic_setup_this_cpu(void); |
257 | 257 | ||
258 | /* Clean up for kexec (or cpu offline or ...) */ | ||
259 | extern void mpic_teardown_this_cpu(void); | ||
260 | |||
258 | /* Request IPIs on primary mpic */ | 261 | /* Request IPIs on primary mpic */ |
259 | extern void mpic_request_ipis(void); | 262 | extern void mpic_request_ipis(void); |
260 | 263 | ||
diff --git a/arch/ppc64/kernel/pSeries_setup.c b/arch/ppc64/kernel/pSeries_setup.c index f2b41243342c..44d9af72d225 100644 --- a/arch/ppc64/kernel/pSeries_setup.c +++ b/arch/ppc64/kernel/pSeries_setup.c | |||
@@ -187,14 +187,16 @@ static void __init pSeries_setup_arch(void) | |||
187 | { | 187 | { |
188 | /* Fixup ppc_md depending on the type of interrupt controller */ | 188 | /* Fixup ppc_md depending on the type of interrupt controller */ |
189 | if (ppc64_interrupt_controller == IC_OPEN_PIC) { | 189 | if (ppc64_interrupt_controller == IC_OPEN_PIC) { |
190 | ppc_md.init_IRQ = pSeries_init_mpic; | 190 | ppc_md.init_IRQ = pSeries_init_mpic; |
191 | ppc_md.get_irq = mpic_get_irq; | 191 | ppc_md.get_irq = mpic_get_irq; |
192 | ppc_md.cpu_irq_down = mpic_teardown_this_cpu; | ||
192 | /* Allocate the mpic now, so that find_and_init_phbs() can | 193 | /* Allocate the mpic now, so that find_and_init_phbs() can |
193 | * fill the ISUs */ | 194 | * fill the ISUs */ |
194 | pSeries_setup_mpic(); | 195 | pSeries_setup_mpic(); |
195 | } else { | 196 | } else { |
196 | ppc_md.init_IRQ = xics_init_IRQ; | 197 | ppc_md.init_IRQ = xics_init_IRQ; |
197 | ppc_md.get_irq = xics_get_irq; | 198 | ppc_md.get_irq = xics_get_irq; |
199 | ppc_md.cpu_irq_down = xics_teardown_cpu; | ||
198 | } | 200 | } |
199 | 201 | ||
200 | #ifdef CONFIG_SMP | 202 | #ifdef CONFIG_SMP |
diff --git a/arch/ppc64/kernel/pSeries_smp.c b/arch/ppc64/kernel/pSeries_smp.c index 30154140f7e2..62c55a123560 100644 --- a/arch/ppc64/kernel/pSeries_smp.c +++ b/arch/ppc64/kernel/pSeries_smp.c | |||
@@ -93,10 +93,13 @@ static int query_cpu_stopped(unsigned int pcpu) | |||
93 | 93 | ||
94 | int pSeries_cpu_disable(void) | 94 | int pSeries_cpu_disable(void) |
95 | { | 95 | { |
96 | int cpu = smp_processor_id(); | ||
97 | |||
98 | cpu_clear(cpu, cpu_online_map); | ||
96 | systemcfg->processorCount--; | 99 | systemcfg->processorCount--; |
97 | 100 | ||
98 | /*fix boot_cpuid here*/ | 101 | /*fix boot_cpuid here*/ |
99 | if (smp_processor_id() == boot_cpuid) | 102 | if (cpu == boot_cpuid) |
100 | boot_cpuid = any_online_cpu(cpu_online_map); | 103 | boot_cpuid = any_online_cpu(cpu_online_map); |
101 | 104 | ||
102 | /* FIXME: abstract this to not be platform specific later on */ | 105 | /* FIXME: abstract this to not be platform specific later on */ |
diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index 0a47a5ef428d..d5e4866e9ac2 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c | |||
@@ -677,11 +677,16 @@ void __init setup_system(void) | |||
677 | DBG(" <- setup_system()\n"); | 677 | DBG(" <- setup_system()\n"); |
678 | } | 678 | } |
679 | 679 | ||
680 | 680 | /* also used by kexec */ | |
681 | void machine_restart(char *cmd) | 681 | void machine_shutdown(void) |
682 | { | 682 | { |
683 | if (ppc_md.nvram_sync) | 683 | if (ppc_md.nvram_sync) |
684 | ppc_md.nvram_sync(); | 684 | ppc_md.nvram_sync(); |
685 | } | ||
686 | |||
687 | void machine_restart(char *cmd) | ||
688 | { | ||
689 | machine_shutdown(); | ||
685 | ppc_md.restart(cmd); | 690 | ppc_md.restart(cmd); |
686 | #ifdef CONFIG_SMP | 691 | #ifdef CONFIG_SMP |
687 | smp_send_stop(); | 692 | smp_send_stop(); |
@@ -690,13 +695,11 @@ void machine_restart(char *cmd) | |||
690 | local_irq_disable(); | 695 | local_irq_disable(); |
691 | while (1) ; | 696 | while (1) ; |
692 | } | 697 | } |
693 | |||
694 | EXPORT_SYMBOL(machine_restart); | 698 | EXPORT_SYMBOL(machine_restart); |
695 | 699 | ||
696 | void machine_power_off(void) | 700 | void machine_power_off(void) |
697 | { | 701 | { |
698 | if (ppc_md.nvram_sync) | 702 | machine_shutdown(); |
699 | ppc_md.nvram_sync(); | ||
700 | ppc_md.power_off(); | 703 | ppc_md.power_off(); |
701 | #ifdef CONFIG_SMP | 704 | #ifdef CONFIG_SMP |
702 | smp_send_stop(); | 705 | smp_send_stop(); |
@@ -705,13 +708,11 @@ void machine_power_off(void) | |||
705 | local_irq_disable(); | 708 | local_irq_disable(); |
706 | while (1) ; | 709 | while (1) ; |
707 | } | 710 | } |
708 | |||
709 | EXPORT_SYMBOL(machine_power_off); | 711 | EXPORT_SYMBOL(machine_power_off); |
710 | 712 | ||
711 | void machine_halt(void) | 713 | void machine_halt(void) |
712 | { | 714 | { |
713 | if (ppc_md.nvram_sync) | 715 | machine_shutdown(); |
714 | ppc_md.nvram_sync(); | ||
715 | ppc_md.halt(); | 716 | ppc_md.halt(); |
716 | #ifdef CONFIG_SMP | 717 | #ifdef CONFIG_SMP |
717 | smp_send_stop(); | 718 | smp_send_stop(); |
@@ -720,7 +721,6 @@ void machine_halt(void) | |||
720 | local_irq_disable(); | 721 | local_irq_disable(); |
721 | while (1) ; | 722 | while (1) ; |
722 | } | 723 | } |
723 | |||
724 | EXPORT_SYMBOL(machine_halt); | 724 | EXPORT_SYMBOL(machine_halt); |
725 | 725 | ||
726 | static int ppc64_panic_event(struct notifier_block *this, | 726 | static int ppc64_panic_event(struct notifier_block *this, |
diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c index 879f39b90a33..677c4450984a 100644 --- a/arch/ppc64/kernel/xics.c +++ b/arch/ppc64/kernel/xics.c | |||
@@ -647,6 +647,31 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) | |||
647 | } | 647 | } |
648 | } | 648 | } |
649 | 649 | ||
650 | void xics_teardown_cpu(void) | ||
651 | { | ||
652 | int cpu = smp_processor_id(); | ||
653 | int status; | ||
654 | |||
655 | ops->cppr_info(cpu, 0x00); | ||
656 | iosync(); | ||
657 | |||
658 | /* | ||
659 | * we need to EOI the IPI if we got here from kexec down IPI | ||
660 | * | ||
661 | * xics doesn't care if we duplicate an EOI as long as we | ||
662 | * don't EOI and raise priority. | ||
663 | * | ||
664 | * probably need to check all the other interrupts too | ||
665 | * should we be flagging idle loop instead? | ||
666 | * or creating some task to be scheduled? | ||
667 | */ | ||
668 | ops->xirr_info_set(cpu, XICS_IPI); | ||
669 | |||
670 | status = rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, | ||
671 | (1UL << interrupt_server_size) - 1 - default_distrib_server, 0); | ||
672 | WARN_ON(status != 0); | ||
673 | } | ||
674 | |||
650 | #ifdef CONFIG_HOTPLUG_CPU | 675 | #ifdef CONFIG_HOTPLUG_CPU |
651 | 676 | ||
652 | /* Interrupts are disabled. */ | 677 | /* Interrupts are disabled. */ |
diff --git a/arch/ppc64/mm/hash_native.c b/arch/ppc64/mm/hash_native.c index 52b6b9305341..4fec05817d66 100644 --- a/arch/ppc64/mm/hash_native.c +++ b/arch/ppc64/mm/hash_native.c | |||
@@ -304,6 +304,50 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long va, | |||
304 | local_irq_restore(flags); | 304 | local_irq_restore(flags); |
305 | } | 305 | } |
306 | 306 | ||
307 | /* | ||
308 | * clear all mappings on kexec. All cpus are in real mode (or they will | ||
309 | * be when they isi), and we are the only one left. We rely on our kernel | ||
310 | * mapping being 0xC0's and the hardware ignoring those two real bits. | ||
311 | * | ||
312 | * TODO: add batching support when enabled. remember, no dynamic memory here, | ||
313 | * athough there is the control page available... | ||
314 | */ | ||
315 | static void native_hpte_clear(void) | ||
316 | { | ||
317 | unsigned long slot, slots, flags; | ||
318 | HPTE *hptep = htab_address; | ||
319 | Hpte_dword0 dw0; | ||
320 | unsigned long pteg_count; | ||
321 | |||
322 | pteg_count = htab_hash_mask + 1; | ||
323 | |||
324 | local_irq_save(flags); | ||
325 | |||
326 | /* we take the tlbie lock and hold it. Some hardware will | ||
327 | * deadlock if we try to tlbie from two processors at once. | ||
328 | */ | ||
329 | spin_lock(&native_tlbie_lock); | ||
330 | |||
331 | slots = pteg_count * HPTES_PER_GROUP; | ||
332 | |||
333 | for (slot = 0; slot < slots; slot++, hptep++) { | ||
334 | /* | ||
335 | * we could lock the pte here, but we are the only cpu | ||
336 | * running, right? and for crash dump, we probably | ||
337 | * don't want to wait for a maybe bad cpu. | ||
338 | */ | ||
339 | dw0 = hptep->dw0.dw0; | ||
340 | |||
341 | if (dw0.v) { | ||
342 | hptep->dw0.dword0 = 0; | ||
343 | tlbie(slot2va(dw0.avpn, dw0.l, dw0.h, slot), dw0.l); | ||
344 | } | ||
345 | } | ||
346 | |||
347 | spin_unlock(&native_tlbie_lock); | ||
348 | local_irq_restore(flags); | ||
349 | } | ||
350 | |||
307 | static void native_flush_hash_range(unsigned long context, | 351 | static void native_flush_hash_range(unsigned long context, |
308 | unsigned long number, int local) | 352 | unsigned long number, int local) |
309 | { | 353 | { |
@@ -415,7 +459,8 @@ void hpte_init_native(void) | |||
415 | ppc_md.hpte_updatepp = native_hpte_updatepp; | 459 | ppc_md.hpte_updatepp = native_hpte_updatepp; |
416 | ppc_md.hpte_updateboltedpp = native_hpte_updateboltedpp; | 460 | ppc_md.hpte_updateboltedpp = native_hpte_updateboltedpp; |
417 | ppc_md.hpte_insert = native_hpte_insert; | 461 | ppc_md.hpte_insert = native_hpte_insert; |
418 | ppc_md.hpte_remove = native_hpte_remove; | 462 | ppc_md.hpte_remove = native_hpte_remove; |
463 | ppc_md.hpte_clear_all = native_hpte_clear; | ||
419 | if (tlb_batching_enabled()) | 464 | if (tlb_batching_enabled()) |
420 | ppc_md.flush_hash_range = native_flush_hash_range; | 465 | ppc_md.flush_hash_range = native_flush_hash_range; |
421 | htab_finish_init(); | 466 | htab_finish_init(); |
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 32696c1d9280..6600ee87f896 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
@@ -455,6 +455,14 @@ config NO_IDLE_HZ_INIT | |||
455 | The HZ timer is switched off in idle by default. That means the | 455 | The HZ timer is switched off in idle by default. That means the |
456 | HZ timer is already disabled at boot time. | 456 | HZ timer is already disabled at boot time. |
457 | 457 | ||
458 | config KEXEC | ||
459 | bool "kexec system call (EXPERIMENTAL)" | ||
460 | depends on EXPERIMENTAL | ||
461 | help | ||
462 | kexec is a system call that implements the ability to shutdown your | ||
463 | current kernel, and to start another kernel. It is like a reboot | ||
464 | but is independent of hardware/microcode support. | ||
465 | |||
458 | endmenu | 466 | endmenu |
459 | 467 | ||
460 | config PCMCIA | 468 | config PCMCIA |
diff --git a/arch/s390/defconfig b/arch/s390/defconfig index 07fd0414a4bf..89850b2c27ea 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig | |||
@@ -245,6 +245,7 @@ CONFIG_S390_TAPE_BLOCK=y | |||
245 | # | 245 | # |
246 | CONFIG_S390_TAPE_34XX=m | 246 | CONFIG_S390_TAPE_34XX=m |
247 | # CONFIG_VMLOGRDR is not set | 247 | # CONFIG_VMLOGRDR is not set |
248 | # CONFIG_VMCP is not set | ||
248 | # CONFIG_MONREADER is not set | 249 | # CONFIG_MONREADER is not set |
249 | # CONFIG_DCSS_SHM is not set | 250 | # CONFIG_DCSS_SHM is not set |
250 | 251 | ||
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index b41e0e199a7c..ab1e49d2e518 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile | |||
@@ -25,6 +25,16 @@ obj-$(CONFIG_ARCH_S390X) += entry64.o reipl64.o | |||
25 | 25 | ||
26 | obj-$(CONFIG_VIRT_TIMER) += vtime.o | 26 | obj-$(CONFIG_VIRT_TIMER) += vtime.o |
27 | 27 | ||
28 | # Kexec part | ||
29 | S390_KEXEC_OBJS := machine_kexec.o crash.o | ||
30 | ifeq ($(CONFIG_ARCH_S390X),y) | ||
31 | S390_KEXEC_OBJS += relocate_kernel64.o | ||
32 | else | ||
33 | S390_KEXEC_OBJS += relocate_kernel.o | ||
34 | endif | ||
35 | obj-$(CONFIG_KEXEC) += $(S390_KEXEC_OBJS) | ||
36 | |||
37 | |||
28 | # | 38 | # |
29 | # This is just to get the dependencies... | 39 | # This is just to get the dependencies... |
30 | # | 40 | # |
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 7a607b1d0380..bf529739c8ab 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S | |||
@@ -1441,3 +1441,11 @@ compat_sys_waitid_wrapper: | |||
1441 | lgfr %r5,%r5 # int | 1441 | lgfr %r5,%r5 # int |
1442 | llgtr %r6,%r6 # struct rusage_emu31 * | 1442 | llgtr %r6,%r6 # struct rusage_emu31 * |
1443 | jg compat_sys_waitid | 1443 | jg compat_sys_waitid |
1444 | |||
1445 | .globl compat_sys_kexec_load_wrapper | ||
1446 | compat_sys_kexec_load_wrapper: | ||
1447 | llgfr %r2,%r2 # unsigned long | ||
1448 | llgfr %r3,%r3 # unsigned long | ||
1449 | llgtr %r4,%r4 # struct kexec_segment * | ||
1450 | llgfr %r5,%r5 # unsigned long | ||
1451 | jg compat_sys_kexec_load | ||
diff --git a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c index 44df8dc07c59..20062145e84e 100644 --- a/arch/s390/kernel/cpcmd.c +++ b/arch/s390/kernel/cpcmd.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * arch/s390/kernel/cpcmd.c | 2 | * arch/s390/kernel/cpcmd.c |
3 | * | 3 | * |
4 | * S390 version | 4 | * S390 version |
5 | * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation | 5 | * Copyright (C) 1999,2005 IBM Deutschland Entwicklung GmbH, IBM Corporation |
6 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), | 6 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), |
7 | * Christian Borntraeger (cborntra@de.ibm.com), | 7 | * Christian Borntraeger (cborntra@de.ibm.com), |
8 | */ | 8 | */ |
@@ -18,93 +18,114 @@ | |||
18 | #include <asm/system.h> | 18 | #include <asm/system.h> |
19 | 19 | ||
20 | static DEFINE_SPINLOCK(cpcmd_lock); | 20 | static DEFINE_SPINLOCK(cpcmd_lock); |
21 | static char cpcmd_buf[240]; | 21 | static char cpcmd_buf[241]; |
22 | 22 | ||
23 | /* | 23 | /* |
24 | * the caller of __cpcmd has to ensure that the response buffer is below 2 GB | 24 | * the caller of __cpcmd has to ensure that the response buffer is below 2 GB |
25 | */ | 25 | */ |
26 | void __cpcmd(char *cmd, char *response, int rlen) | 26 | int __cpcmd(const char *cmd, char *response, int rlen, int *response_code) |
27 | { | 27 | { |
28 | const int mask = 0x40000000L; | 28 | const int mask = 0x40000000L; |
29 | unsigned long flags; | 29 | unsigned long flags; |
30 | int return_code; | ||
31 | int return_len; | ||
30 | int cmdlen; | 32 | int cmdlen; |
31 | 33 | ||
32 | spin_lock_irqsave(&cpcmd_lock, flags); | 34 | spin_lock_irqsave(&cpcmd_lock, flags); |
33 | cmdlen = strlen(cmd); | 35 | cmdlen = strlen(cmd); |
34 | BUG_ON(cmdlen > 240); | 36 | BUG_ON(cmdlen > 240); |
35 | strcpy(cpcmd_buf, cmd); | 37 | memcpy(cpcmd_buf, cmd, cmdlen); |
36 | ASCEBC(cpcmd_buf, cmdlen); | 38 | ASCEBC(cpcmd_buf, cmdlen); |
37 | 39 | ||
38 | if (response != NULL && rlen > 0) { | 40 | if (response != NULL && rlen > 0) { |
39 | memset(response, 0, rlen); | 41 | memset(response, 0, rlen); |
40 | #ifndef CONFIG_ARCH_S390X | 42 | #ifndef CONFIG_ARCH_S390X |
41 | asm volatile ("LRA 2,0(%0)\n\t" | 43 | asm volatile ( "lra 2,0(%2)\n" |
42 | "LR 4,%1\n\t" | 44 | "lr 4,%3\n" |
43 | "O 4,%4\n\t" | 45 | "o 4,%6\n" |
44 | "LRA 3,0(%2)\n\t" | 46 | "lra 3,0(%4)\n" |
45 | "LR 5,%3\n\t" | 47 | "lr 5,%5\n" |
46 | ".long 0x83240008 # Diagnose X'08'\n\t" | 48 | "diag 2,4,0x8\n" |
47 | : /* no output */ | 49 | "brc 8, .Litfits\n" |
48 | : "a" (cpcmd_buf), "d" (cmdlen), | 50 | "ar 5, %5\n" |
49 | "a" (response), "d" (rlen), "m" (mask) | 51 | ".Litfits: \n" |
50 | : "cc", "2", "3", "4", "5" ); | 52 | "lr %0,4\n" |
53 | "lr %1,5\n" | ||
54 | : "=d" (return_code), "=d" (return_len) | ||
55 | : "a" (cpcmd_buf), "d" (cmdlen), | ||
56 | "a" (response), "d" (rlen), "m" (mask) | ||
57 | : "cc", "2", "3", "4", "5" ); | ||
51 | #else /* CONFIG_ARCH_S390X */ | 58 | #else /* CONFIG_ARCH_S390X */ |
52 | asm volatile (" lrag 2,0(%0)\n" | 59 | asm volatile ( "lrag 2,0(%2)\n" |
53 | " lgr 4,%1\n" | 60 | "lgr 4,%3\n" |
54 | " o 4,%4\n" | 61 | "o 4,%6\n" |
55 | " lrag 3,0(%2)\n" | 62 | "lrag 3,0(%4)\n" |
56 | " lgr 5,%3\n" | 63 | "lgr 5,%5\n" |
57 | " sam31\n" | 64 | "sam31\n" |
58 | " .long 0x83240008 # Diagnose X'08'\n" | 65 | "diag 2,4,0x8\n" |
59 | " sam64" | 66 | "sam64\n" |
60 | : /* no output */ | 67 | "brc 8, .Litfits\n" |
61 | : "a" (cpcmd_buf), "d" (cmdlen), | 68 | "agr 5, %5\n" |
62 | "a" (response), "d" (rlen), "m" (mask) | 69 | ".Litfits: \n" |
63 | : "cc", "2", "3", "4", "5" ); | 70 | "lgr %0,4\n" |
71 | "lgr %1,5\n" | ||
72 | : "=d" (return_code), "=d" (return_len) | ||
73 | : "a" (cpcmd_buf), "d" (cmdlen), | ||
74 | "a" (response), "d" (rlen), "m" (mask) | ||
75 | : "cc", "2", "3", "4", "5" ); | ||
64 | #endif /* CONFIG_ARCH_S390X */ | 76 | #endif /* CONFIG_ARCH_S390X */ |
65 | EBCASC(response, rlen); | 77 | EBCASC(response, rlen); |
66 | } else { | 78 | } else { |
79 | return_len = 0; | ||
67 | #ifndef CONFIG_ARCH_S390X | 80 | #ifndef CONFIG_ARCH_S390X |
68 | asm volatile ("LRA 2,0(%0)\n\t" | 81 | asm volatile ( "lra 2,0(%1)\n" |
69 | "LR 3,%1\n\t" | 82 | "lr 3,%2\n" |
70 | ".long 0x83230008 # Diagnose X'08'\n\t" | 83 | "diag 2,3,0x8\n" |
71 | : /* no output */ | 84 | "lr %0,3\n" |
72 | : "a" (cpcmd_buf), "d" (cmdlen) | 85 | : "=d" (return_code) |
73 | : "2", "3" ); | 86 | : "a" (cpcmd_buf), "d" (cmdlen) |
87 | : "2", "3" ); | ||
74 | #else /* CONFIG_ARCH_S390X */ | 88 | #else /* CONFIG_ARCH_S390X */ |
75 | asm volatile (" lrag 2,0(%0)\n" | 89 | asm volatile ( "lrag 2,0(%1)\n" |
76 | " lgr 3,%1\n" | 90 | "lgr 3,%2\n" |
77 | " sam31\n" | 91 | "sam31\n" |
78 | " .long 0x83230008 # Diagnose X'08'\n" | 92 | "diag 2,3,0x8\n" |
79 | " sam64" | 93 | "sam64\n" |
80 | : /* no output */ | 94 | "lgr %0,3\n" |
81 | : "a" (cpcmd_buf), "d" (cmdlen) | 95 | : "=d" (return_code) |
82 | : "2", "3" ); | 96 | : "a" (cpcmd_buf), "d" (cmdlen) |
97 | : "2", "3" ); | ||
83 | #endif /* CONFIG_ARCH_S390X */ | 98 | #endif /* CONFIG_ARCH_S390X */ |
84 | } | 99 | } |
85 | spin_unlock_irqrestore(&cpcmd_lock, flags); | 100 | spin_unlock_irqrestore(&cpcmd_lock, flags); |
101 | if (response_code != NULL) | ||
102 | *response_code = return_code; | ||
103 | return return_len; | ||
86 | } | 104 | } |
87 | 105 | ||
88 | EXPORT_SYMBOL(__cpcmd); | 106 | EXPORT_SYMBOL(__cpcmd); |
89 | 107 | ||
90 | #ifdef CONFIG_ARCH_S390X | 108 | #ifdef CONFIG_ARCH_S390X |
91 | void cpcmd(char *cmd, char *response, int rlen) | 109 | int cpcmd(const char *cmd, char *response, int rlen, int *response_code) |
92 | { | 110 | { |
93 | char *lowbuf; | 111 | char *lowbuf; |
112 | int len; | ||
113 | |||
94 | if ((rlen == 0) || (response == NULL) | 114 | if ((rlen == 0) || (response == NULL) |
95 | || !((unsigned long)response >> 31)) | 115 | || !((unsigned long)response >> 31)) |
96 | __cpcmd(cmd, response, rlen); | 116 | len = __cpcmd(cmd, response, rlen, response_code); |
97 | else { | 117 | else { |
98 | lowbuf = kmalloc(rlen, GFP_KERNEL | GFP_DMA); | 118 | lowbuf = kmalloc(rlen, GFP_KERNEL | GFP_DMA); |
99 | if (!lowbuf) { | 119 | if (!lowbuf) { |
100 | printk(KERN_WARNING | 120 | printk(KERN_WARNING |
101 | "cpcmd: could not allocate response buffer\n"); | 121 | "cpcmd: could not allocate response buffer\n"); |
102 | return; | 122 | return -ENOMEM; |
103 | } | 123 | } |
104 | __cpcmd(cmd, lowbuf, rlen); | 124 | len = __cpcmd(cmd, lowbuf, rlen, response_code); |
105 | memcpy(response, lowbuf, rlen); | 125 | memcpy(response, lowbuf, rlen); |
106 | kfree(lowbuf); | 126 | kfree(lowbuf); |
107 | } | 127 | } |
128 | return len; | ||
108 | } | 129 | } |
109 | 130 | ||
110 | EXPORT_SYMBOL(cpcmd); | 131 | EXPORT_SYMBOL(cpcmd); |
diff --git a/arch/s390/kernel/crash.c b/arch/s390/kernel/crash.c new file mode 100644 index 000000000000..7bd169c58b0c --- /dev/null +++ b/arch/s390/kernel/crash.c | |||
@@ -0,0 +1,17 @@ | |||
1 | /* | ||
2 | * arch/s390/kernel/crash.c | ||
3 | * | ||
4 | * (C) Copyright IBM Corp. 2005 | ||
5 | * | ||
6 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #include <linux/threads.h> | ||
11 | #include <linux/kexec.h> | ||
12 | |||
13 | note_buf_t crash_notes[NR_CPUS]; | ||
14 | |||
15 | void machine_crash_shutdown(struct pt_regs *regs) | ||
16 | { | ||
17 | } | ||
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index 91f8ce5543d3..960ba6029c3a 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c | |||
@@ -19,22 +19,27 @@ | |||
19 | #include <linux/sysctl.h> | 19 | #include <linux/sysctl.h> |
20 | #include <asm/uaccess.h> | 20 | #include <asm/uaccess.h> |
21 | #include <asm/semaphore.h> | 21 | #include <asm/semaphore.h> |
22 | |||
23 | #include <linux/module.h> | 22 | #include <linux/module.h> |
24 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/fs.h> | ||
25 | #include <linux/debugfs.h> | ||
25 | 26 | ||
26 | #include <asm/debug.h> | 27 | #include <asm/debug.h> |
27 | 28 | ||
28 | #define DEBUG_PROLOG_ENTRY -1 | 29 | #define DEBUG_PROLOG_ENTRY -1 |
29 | 30 | ||
31 | #define ALL_AREAS 0 /* copy all debug areas */ | ||
32 | #define NO_AREAS 1 /* copy no debug areas */ | ||
33 | |||
30 | /* typedefs */ | 34 | /* typedefs */ |
31 | 35 | ||
32 | typedef struct file_private_info { | 36 | typedef struct file_private_info { |
33 | loff_t offset; /* offset of last read in file */ | 37 | loff_t offset; /* offset of last read in file */ |
34 | int act_area; /* number of last formated area */ | 38 | int act_area; /* number of last formated area */ |
39 | int act_page; /* act page in given area */ | ||
35 | int act_entry; /* last formated entry (offset */ | 40 | int act_entry; /* last formated entry (offset */ |
36 | /* relative to beginning of last */ | 41 | /* relative to beginning of last */ |
37 | /* formated area) */ | 42 | /* formated page) */ |
38 | size_t act_entry_offset; /* up to this offset we copied */ | 43 | size_t act_entry_offset; /* up to this offset we copied */ |
39 | /* in last read the last formated */ | 44 | /* in last read the last formated */ |
40 | /* entry to userland */ | 45 | /* entry to userland */ |
@@ -51,8 +56,8 @@ typedef struct | |||
51 | * This assumes that all args are converted into longs | 56 | * This assumes that all args are converted into longs |
52 | * on L/390 this is the case for all types of parameter | 57 | * on L/390 this is the case for all types of parameter |
53 | * except of floats, and long long (32 bit) | 58 | * except of floats, and long long (32 bit) |
54 | * | 59 | * |
55 | */ | 60 | */ |
56 | long args[0]; | 61 | long args[0]; |
57 | } debug_sprintf_entry_t; | 62 | } debug_sprintf_entry_t; |
58 | 63 | ||
@@ -63,32 +68,38 @@ extern void tod_to_timeval(uint64_t todval, struct timeval *xtime); | |||
63 | 68 | ||
64 | static int debug_init(void); | 69 | static int debug_init(void); |
65 | static ssize_t debug_output(struct file *file, char __user *user_buf, | 70 | static ssize_t debug_output(struct file *file, char __user *user_buf, |
66 | size_t user_len, loff_t * offset); | 71 | size_t user_len, loff_t * offset); |
67 | static ssize_t debug_input(struct file *file, const char __user *user_buf, | 72 | static ssize_t debug_input(struct file *file, const char __user *user_buf, |
68 | size_t user_len, loff_t * offset); | 73 | size_t user_len, loff_t * offset); |
69 | static int debug_open(struct inode *inode, struct file *file); | 74 | static int debug_open(struct inode *inode, struct file *file); |
70 | static int debug_close(struct inode *inode, struct file *file); | 75 | static int debug_close(struct inode *inode, struct file *file); |
71 | static debug_info_t* debug_info_create(char *name, int page_order, int nr_areas, int buf_size); | 76 | static debug_info_t* debug_info_create(char *name, int pages_per_area, |
77 | int nr_areas, int buf_size); | ||
72 | static void debug_info_get(debug_info_t *); | 78 | static void debug_info_get(debug_info_t *); |
73 | static void debug_info_put(debug_info_t *); | 79 | static void debug_info_put(debug_info_t *); |
74 | static int debug_prolog_level_fn(debug_info_t * id, | 80 | static int debug_prolog_level_fn(debug_info_t * id, |
75 | struct debug_view *view, char *out_buf); | 81 | struct debug_view *view, char *out_buf); |
76 | static int debug_input_level_fn(debug_info_t * id, struct debug_view *view, | 82 | static int debug_input_level_fn(debug_info_t * id, struct debug_view *view, |
77 | struct file *file, const char __user *user_buf, | 83 | struct file *file, const char __user *user_buf, |
78 | size_t user_buf_size, loff_t * offset); | 84 | size_t user_buf_size, loff_t * offset); |
85 | static int debug_prolog_pages_fn(debug_info_t * id, | ||
86 | struct debug_view *view, char *out_buf); | ||
87 | static int debug_input_pages_fn(debug_info_t * id, struct debug_view *view, | ||
88 | struct file *file, const char __user *user_buf, | ||
89 | size_t user_buf_size, loff_t * offset); | ||
79 | static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view, | 90 | static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view, |
80 | struct file *file, const char __user *user_buf, | 91 | struct file *file, const char __user *user_buf, |
81 | size_t user_buf_size, loff_t * offset); | 92 | size_t user_buf_size, loff_t * offset); |
82 | static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view, | 93 | static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view, |
83 | char *out_buf, const char *in_buf); | 94 | char *out_buf, const char *in_buf); |
84 | static int debug_raw_format_fn(debug_info_t * id, | 95 | static int debug_raw_format_fn(debug_info_t * id, |
85 | struct debug_view *view, char *out_buf, | 96 | struct debug_view *view, char *out_buf, |
86 | const char *in_buf); | 97 | const char *in_buf); |
87 | static int debug_raw_header_fn(debug_info_t * id, struct debug_view *view, | 98 | static int debug_raw_header_fn(debug_info_t * id, struct debug_view *view, |
88 | int area, debug_entry_t * entry, char *out_buf); | 99 | int area, debug_entry_t * entry, char *out_buf); |
89 | 100 | ||
90 | static int debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view, | 101 | static int debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view, |
91 | char *out_buf, debug_sprintf_entry_t *curr_event); | 102 | char *out_buf, debug_sprintf_entry_t *curr_event); |
92 | 103 | ||
93 | /* globals */ | 104 | /* globals */ |
94 | 105 | ||
@@ -119,6 +130,15 @@ struct debug_view debug_level_view = { | |||
119 | NULL | 130 | NULL |
120 | }; | 131 | }; |
121 | 132 | ||
133 | struct debug_view debug_pages_view = { | ||
134 | "pages", | ||
135 | &debug_prolog_pages_fn, | ||
136 | NULL, | ||
137 | NULL, | ||
138 | &debug_input_pages_fn, | ||
139 | NULL | ||
140 | }; | ||
141 | |||
122 | struct debug_view debug_flush_view = { | 142 | struct debug_view debug_flush_view = { |
123 | "flush", | 143 | "flush", |
124 | NULL, | 144 | NULL, |
@@ -149,98 +169,161 @@ DECLARE_MUTEX(debug_lock); | |||
149 | static int initialized; | 169 | static int initialized; |
150 | 170 | ||
151 | static struct file_operations debug_file_ops = { | 171 | static struct file_operations debug_file_ops = { |
152 | .owner = THIS_MODULE, | 172 | .owner = THIS_MODULE, |
153 | .read = debug_output, | 173 | .read = debug_output, |
154 | .write = debug_input, | 174 | .write = debug_input, |
155 | .open = debug_open, | 175 | .open = debug_open, |
156 | .release = debug_close, | 176 | .release = debug_close, |
157 | }; | 177 | }; |
158 | 178 | ||
159 | static struct proc_dir_entry *debug_proc_root_entry; | 179 | static struct dentry *debug_debugfs_root_entry; |
160 | 180 | ||
161 | /* functions */ | 181 | /* functions */ |
162 | 182 | ||
163 | /* | 183 | /* |
184 | * debug_areas_alloc | ||
185 | * - Debug areas are implemented as a threedimensonal array: | ||
186 | * areas[areanumber][pagenumber][pageoffset] | ||
187 | */ | ||
188 | |||
189 | static debug_entry_t*** | ||
190 | debug_areas_alloc(int pages_per_area, int nr_areas) | ||
191 | { | ||
192 | debug_entry_t*** areas; | ||
193 | int i,j; | ||
194 | |||
195 | areas = (debug_entry_t ***) kmalloc(nr_areas * | ||
196 | sizeof(debug_entry_t**), | ||
197 | GFP_KERNEL); | ||
198 | if (!areas) | ||
199 | goto fail_malloc_areas; | ||
200 | for (i = 0; i < nr_areas; i++) { | ||
201 | areas[i] = (debug_entry_t**) kmalloc(pages_per_area * | ||
202 | sizeof(debug_entry_t*),GFP_KERNEL); | ||
203 | if (!areas[i]) { | ||
204 | goto fail_malloc_areas2; | ||
205 | } | ||
206 | for(j = 0; j < pages_per_area; j++) { | ||
207 | areas[i][j] = (debug_entry_t*)kmalloc(PAGE_SIZE, | ||
208 | GFP_KERNEL); | ||
209 | if(!areas[i][j]) { | ||
210 | for(j--; j >=0 ; j--) { | ||
211 | kfree(areas[i][j]); | ||
212 | } | ||
213 | kfree(areas[i]); | ||
214 | goto fail_malloc_areas2; | ||
215 | } else { | ||
216 | memset(areas[i][j],0,PAGE_SIZE); | ||
217 | } | ||
218 | } | ||
219 | } | ||
220 | return areas; | ||
221 | |||
222 | fail_malloc_areas2: | ||
223 | for(i--; i >= 0; i--){ | ||
224 | for(j=0; j < pages_per_area;j++){ | ||
225 | kfree(areas[i][j]); | ||
226 | } | ||
227 | kfree(areas[i]); | ||
228 | } | ||
229 | kfree(areas); | ||
230 | fail_malloc_areas: | ||
231 | return NULL; | ||
232 | |||
233 | } | ||
234 | |||
235 | |||
236 | /* | ||
164 | * debug_info_alloc | 237 | * debug_info_alloc |
165 | * - alloc new debug-info | 238 | * - alloc new debug-info |
166 | */ | 239 | */ |
167 | 240 | ||
168 | static debug_info_t* debug_info_alloc(char *name, int page_order, | 241 | static debug_info_t* |
169 | int nr_areas, int buf_size) | 242 | debug_info_alloc(char *name, int pages_per_area, int nr_areas, int buf_size, |
243 | int level, int mode) | ||
170 | { | 244 | { |
171 | debug_info_t* rc; | 245 | debug_info_t* rc; |
172 | int i; | ||
173 | 246 | ||
174 | /* alloc everything */ | 247 | /* alloc everything */ |
175 | 248 | ||
176 | rc = (debug_info_t*) kmalloc(sizeof(debug_info_t), GFP_ATOMIC); | 249 | rc = (debug_info_t*) kmalloc(sizeof(debug_info_t), GFP_KERNEL); |
177 | if(!rc) | 250 | if(!rc) |
178 | goto fail_malloc_rc; | 251 | goto fail_malloc_rc; |
179 | rc->active_entry = (int*)kmalloc(nr_areas * sizeof(int), GFP_ATOMIC); | 252 | rc->active_entries = (int*)kmalloc(nr_areas * sizeof(int), GFP_KERNEL); |
180 | if(!rc->active_entry) | 253 | if(!rc->active_entries) |
181 | goto fail_malloc_active_entry; | 254 | goto fail_malloc_active_entries; |
182 | memset(rc->active_entry, 0, nr_areas * sizeof(int)); | 255 | memset(rc->active_entries, 0, nr_areas * sizeof(int)); |
183 | rc->areas = (debug_entry_t **) kmalloc(nr_areas * | 256 | rc->active_pages = (int*)kmalloc(nr_areas * sizeof(int), GFP_KERNEL); |
184 | sizeof(debug_entry_t *), | 257 | if(!rc->active_pages) |
185 | GFP_ATOMIC); | 258 | goto fail_malloc_active_pages; |
186 | if (!rc->areas) | 259 | memset(rc->active_pages, 0, nr_areas * sizeof(int)); |
187 | goto fail_malloc_areas; | 260 | if((mode == ALL_AREAS) && (pages_per_area != 0)){ |
188 | for (i = 0; i < nr_areas; i++) { | 261 | rc->areas = debug_areas_alloc(pages_per_area, nr_areas); |
189 | rc->areas[i] = (debug_entry_t *) __get_free_pages(GFP_ATOMIC, | 262 | if(!rc->areas) |
190 | page_order); | 263 | goto fail_malloc_areas; |
191 | if (!rc->areas[i]) { | 264 | } else { |
192 | for (i--; i >= 0; i--) { | 265 | rc->areas = NULL; |
193 | free_pages((unsigned long) rc->areas[i], | ||
194 | page_order); | ||
195 | } | ||
196 | goto fail_malloc_areas2; | ||
197 | } else { | ||
198 | memset(rc->areas[i], 0, PAGE_SIZE << page_order); | ||
199 | } | ||
200 | } | 266 | } |
201 | 267 | ||
202 | /* initialize members */ | 268 | /* initialize members */ |
203 | 269 | ||
204 | spin_lock_init(&rc->lock); | 270 | spin_lock_init(&rc->lock); |
205 | rc->page_order = page_order; | 271 | rc->pages_per_area = pages_per_area; |
206 | rc->nr_areas = nr_areas; | 272 | rc->nr_areas = nr_areas; |
207 | rc->active_area = 0; | 273 | rc->active_area = 0; |
208 | rc->level = DEBUG_DEFAULT_LEVEL; | 274 | rc->level = level; |
209 | rc->buf_size = buf_size; | 275 | rc->buf_size = buf_size; |
210 | rc->entry_size = sizeof(debug_entry_t) + buf_size; | 276 | rc->entry_size = sizeof(debug_entry_t) + buf_size; |
211 | strlcpy(rc->name, name, sizeof(rc->name)); | 277 | strlcpy(rc->name, name, sizeof(rc->name)-1); |
212 | memset(rc->views, 0, DEBUG_MAX_VIEWS * sizeof(struct debug_view *)); | 278 | memset(rc->views, 0, DEBUG_MAX_VIEWS * sizeof(struct debug_view *)); |
213 | #ifdef CONFIG_PROC_FS | 279 | memset(rc->debugfs_entries, 0 ,DEBUG_MAX_VIEWS * |
214 | memset(rc->proc_entries, 0 ,DEBUG_MAX_VIEWS * | 280 | sizeof(struct dentry*)); |
215 | sizeof(struct proc_dir_entry*)); | ||
216 | #endif /* CONFIG_PROC_FS */ | ||
217 | atomic_set(&(rc->ref_count), 0); | 281 | atomic_set(&(rc->ref_count), 0); |
218 | 282 | ||
219 | return rc; | 283 | return rc; |
220 | 284 | ||
221 | fail_malloc_areas2: | ||
222 | kfree(rc->areas); | ||
223 | fail_malloc_areas: | 285 | fail_malloc_areas: |
224 | kfree(rc->active_entry); | 286 | kfree(rc->active_pages); |
225 | fail_malloc_active_entry: | 287 | fail_malloc_active_pages: |
288 | kfree(rc->active_entries); | ||
289 | fail_malloc_active_entries: | ||
226 | kfree(rc); | 290 | kfree(rc); |
227 | fail_malloc_rc: | 291 | fail_malloc_rc: |
228 | return NULL; | 292 | return NULL; |
229 | } | 293 | } |
230 | 294 | ||
231 | /* | 295 | /* |
232 | * debug_info_free | 296 | * debug_areas_free |
233 | * - free memory debug-info | 297 | * - free all debug areas |
234 | */ | 298 | */ |
235 | 299 | ||
236 | static void debug_info_free(debug_info_t* db_info){ | 300 | static void |
237 | int i; | 301 | debug_areas_free(debug_info_t* db_info) |
302 | { | ||
303 | int i,j; | ||
304 | |||
305 | if(!db_info->areas) | ||
306 | return; | ||
238 | for (i = 0; i < db_info->nr_areas; i++) { | 307 | for (i = 0; i < db_info->nr_areas; i++) { |
239 | free_pages((unsigned long) db_info->areas[i], | 308 | for(j = 0; j < db_info->pages_per_area; j++) { |
240 | db_info->page_order); | 309 | kfree(db_info->areas[i][j]); |
310 | } | ||
311 | kfree(db_info->areas[i]); | ||
241 | } | 312 | } |
242 | kfree(db_info->areas); | 313 | kfree(db_info->areas); |
243 | kfree(db_info->active_entry); | 314 | db_info->areas = NULL; |
315 | } | ||
316 | |||
317 | /* | ||
318 | * debug_info_free | ||
319 | * - free memory debug-info | ||
320 | */ | ||
321 | |||
322 | static void | ||
323 | debug_info_free(debug_info_t* db_info){ | ||
324 | debug_areas_free(db_info); | ||
325 | kfree(db_info->active_entries); | ||
326 | kfree(db_info->active_pages); | ||
244 | kfree(db_info); | 327 | kfree(db_info); |
245 | } | 328 | } |
246 | 329 | ||
@@ -249,21 +332,22 @@ static void debug_info_free(debug_info_t* db_info){ | |||
249 | * - create new debug-info | 332 | * - create new debug-info |
250 | */ | 333 | */ |
251 | 334 | ||
252 | static debug_info_t* debug_info_create(char *name, int page_order, | 335 | static debug_info_t* |
253 | int nr_areas, int buf_size) | 336 | debug_info_create(char *name, int pages_per_area, int nr_areas, int buf_size) |
254 | { | 337 | { |
255 | debug_info_t* rc; | 338 | debug_info_t* rc; |
256 | 339 | ||
257 | rc = debug_info_alloc(name, page_order, nr_areas, buf_size); | 340 | rc = debug_info_alloc(name, pages_per_area, nr_areas, buf_size, |
341 | DEBUG_DEFAULT_LEVEL, ALL_AREAS); | ||
258 | if(!rc) | 342 | if(!rc) |
259 | goto out; | 343 | goto out; |
260 | 344 | ||
261 | 345 | /* create root directory */ | |
262 | /* create proc rood directory */ | 346 | rc->debugfs_root_entry = debugfs_create_dir(rc->name, |
263 | rc->proc_root_entry = proc_mkdir(rc->name, debug_proc_root_entry); | 347 | debug_debugfs_root_entry); |
264 | 348 | ||
265 | /* append new element to linked list */ | 349 | /* append new element to linked list */ |
266 | if (debug_area_first == NULL) { | 350 | if (!debug_area_first) { |
267 | /* first element in list */ | 351 | /* first element in list */ |
268 | debug_area_first = rc; | 352 | debug_area_first = rc; |
269 | rc->prev = NULL; | 353 | rc->prev = NULL; |
@@ -285,17 +369,21 @@ out: | |||
285 | * - copy debug-info | 369 | * - copy debug-info |
286 | */ | 370 | */ |
287 | 371 | ||
288 | static debug_info_t* debug_info_copy(debug_info_t* in) | 372 | static debug_info_t* |
373 | debug_info_copy(debug_info_t* in, int mode) | ||
289 | { | 374 | { |
290 | int i; | 375 | int i,j; |
291 | debug_info_t* rc; | 376 | debug_info_t* rc; |
292 | rc = debug_info_alloc(in->name, in->page_order, | 377 | |
293 | in->nr_areas, in->buf_size); | 378 | rc = debug_info_alloc(in->name, in->pages_per_area, in->nr_areas, |
294 | if(!rc) | 379 | in->buf_size, in->level, mode); |
380 | if(!rc || (mode == NO_AREAS)) | ||
295 | goto out; | 381 | goto out; |
296 | 382 | ||
297 | for(i = 0; i < in->nr_areas; i++){ | 383 | for(i = 0; i < in->nr_areas; i++){ |
298 | memcpy(rc->areas[i],in->areas[i], PAGE_SIZE << in->page_order); | 384 | for(j = 0; j < in->pages_per_area; j++) { |
385 | memcpy(rc->areas[i][j], in->areas[i][j],PAGE_SIZE); | ||
386 | } | ||
299 | } | 387 | } |
300 | out: | 388 | out: |
301 | return rc; | 389 | return rc; |
@@ -306,7 +394,8 @@ out: | |||
306 | * - increments reference count for debug-info | 394 | * - increments reference count for debug-info |
307 | */ | 395 | */ |
308 | 396 | ||
309 | static void debug_info_get(debug_info_t * db_info) | 397 | static void |
398 | debug_info_get(debug_info_t * db_info) | ||
310 | { | 399 | { |
311 | if (db_info) | 400 | if (db_info) |
312 | atomic_inc(&db_info->ref_count); | 401 | atomic_inc(&db_info->ref_count); |
@@ -317,29 +406,20 @@ static void debug_info_get(debug_info_t * db_info) | |||
317 | * - decreases reference count for debug-info and frees it if necessary | 406 | * - decreases reference count for debug-info and frees it if necessary |
318 | */ | 407 | */ |
319 | 408 | ||
320 | static void debug_info_put(debug_info_t *db_info) | 409 | static void |
410 | debug_info_put(debug_info_t *db_info) | ||
321 | { | 411 | { |
322 | int i; | 412 | int i; |
323 | 413 | ||
324 | if (!db_info) | 414 | if (!db_info) |
325 | return; | 415 | return; |
326 | if (atomic_dec_and_test(&db_info->ref_count)) { | 416 | if (atomic_dec_and_test(&db_info->ref_count)) { |
327 | #ifdef DEBUG | ||
328 | printk(KERN_INFO "debug: freeing debug area %p (%s)\n", | ||
329 | db_info, db_info->name); | ||
330 | #endif | ||
331 | for (i = 0; i < DEBUG_MAX_VIEWS; i++) { | 417 | for (i = 0; i < DEBUG_MAX_VIEWS; i++) { |
332 | if (db_info->views[i] == NULL) | 418 | if (!db_info->views[i]) |
333 | continue; | 419 | continue; |
334 | #ifdef CONFIG_PROC_FS | 420 | debugfs_remove(db_info->debugfs_entries[i]); |
335 | remove_proc_entry(db_info->proc_entries[i]->name, | ||
336 | db_info->proc_root_entry); | ||
337 | #endif | ||
338 | } | 421 | } |
339 | #ifdef CONFIG_PROC_FS | 422 | debugfs_remove(db_info->debugfs_root_entry); |
340 | remove_proc_entry(db_info->proc_root_entry->name, | ||
341 | debug_proc_root_entry); | ||
342 | #endif | ||
343 | if(db_info == debug_area_first) | 423 | if(db_info == debug_area_first) |
344 | debug_area_first = db_info->next; | 424 | debug_area_first = db_info->next; |
345 | if(db_info == debug_area_last) | 425 | if(db_info == debug_area_last) |
@@ -355,9 +435,9 @@ static void debug_info_put(debug_info_t *db_info) | |||
355 | * - format one debug entry and return size of formated data | 435 | * - format one debug entry and return size of formated data |
356 | */ | 436 | */ |
357 | 437 | ||
358 | static int debug_format_entry(file_private_info_t *p_info) | 438 | static int |
439 | debug_format_entry(file_private_info_t *p_info) | ||
359 | { | 440 | { |
360 | debug_info_t *id_org = p_info->debug_info_org; | ||
361 | debug_info_t *id_snap = p_info->debug_info_snap; | 441 | debug_info_t *id_snap = p_info->debug_info_snap; |
362 | struct debug_view *view = p_info->view; | 442 | struct debug_view *view = p_info->view; |
363 | debug_entry_t *act_entry; | 443 | debug_entry_t *act_entry; |
@@ -365,22 +445,23 @@ static int debug_format_entry(file_private_info_t *p_info) | |||
365 | if(p_info->act_entry == DEBUG_PROLOG_ENTRY){ | 445 | if(p_info->act_entry == DEBUG_PROLOG_ENTRY){ |
366 | /* print prolog */ | 446 | /* print prolog */ |
367 | if (view->prolog_proc) | 447 | if (view->prolog_proc) |
368 | len += view->prolog_proc(id_org, view,p_info->temp_buf); | 448 | len += view->prolog_proc(id_snap,view,p_info->temp_buf); |
369 | goto out; | 449 | goto out; |
370 | } | 450 | } |
371 | 451 | if (!id_snap->areas) /* this is true, if we have a prolog only view */ | |
372 | act_entry = (debug_entry_t *) ((char*)id_snap->areas[p_info->act_area] + | 452 | goto out; /* or if 'pages_per_area' is 0 */ |
373 | p_info->act_entry); | 453 | act_entry = (debug_entry_t *) ((char*)id_snap->areas[p_info->act_area] |
454 | [p_info->act_page] + p_info->act_entry); | ||
374 | 455 | ||
375 | if (act_entry->id.stck == 0LL) | 456 | if (act_entry->id.stck == 0LL) |
376 | goto out; /* empty entry */ | 457 | goto out; /* empty entry */ |
377 | if (view->header_proc) | 458 | if (view->header_proc) |
378 | len += view->header_proc(id_org, view, p_info->act_area, | 459 | len += view->header_proc(id_snap, view, p_info->act_area, |
379 | act_entry, p_info->temp_buf + len); | 460 | act_entry, p_info->temp_buf + len); |
380 | if (view->format_proc) | 461 | if (view->format_proc) |
381 | len += view->format_proc(id_org, view, p_info->temp_buf + len, | 462 | len += view->format_proc(id_snap, view, p_info->temp_buf + len, |
382 | DEBUG_DATA(act_entry)); | 463 | DEBUG_DATA(act_entry)); |
383 | out: | 464 | out: |
384 | return len; | 465 | return len; |
385 | } | 466 | } |
386 | 467 | ||
@@ -389,20 +470,30 @@ static int debug_format_entry(file_private_info_t *p_info) | |||
389 | * - goto next entry in p_info | 470 | * - goto next entry in p_info |
390 | */ | 471 | */ |
391 | 472 | ||
392 | extern inline int debug_next_entry(file_private_info_t *p_info) | 473 | extern inline int |
474 | debug_next_entry(file_private_info_t *p_info) | ||
393 | { | 475 | { |
394 | debug_info_t *id = p_info->debug_info_snap; | 476 | debug_info_t *id; |
477 | |||
478 | id = p_info->debug_info_snap; | ||
395 | if(p_info->act_entry == DEBUG_PROLOG_ENTRY){ | 479 | if(p_info->act_entry == DEBUG_PROLOG_ENTRY){ |
396 | p_info->act_entry = 0; | 480 | p_info->act_entry = 0; |
481 | p_info->act_page = 0; | ||
397 | goto out; | 482 | goto out; |
398 | } | 483 | } |
399 | if ((p_info->act_entry += id->entry_size) | 484 | if(!id->areas) |
400 | > ((PAGE_SIZE << (id->page_order)) | 485 | return 1; |
401 | - id->entry_size)){ | 486 | p_info->act_entry += id->entry_size; |
402 | 487 | /* switch to next page, if we reached the end of the page */ | |
403 | /* next area */ | 488 | if (p_info->act_entry > (PAGE_SIZE - id->entry_size)){ |
489 | /* next page */ | ||
404 | p_info->act_entry = 0; | 490 | p_info->act_entry = 0; |
405 | p_info->act_area++; | 491 | p_info->act_page += 1; |
492 | if((p_info->act_page % id->pages_per_area) == 0) { | ||
493 | /* next area */ | ||
494 | p_info->act_area++; | ||
495 | p_info->act_page=0; | ||
496 | } | ||
406 | if(p_info->act_area >= id->nr_areas) | 497 | if(p_info->act_area >= id->nr_areas) |
407 | return 1; | 498 | return 1; |
408 | } | 499 | } |
@@ -416,13 +507,14 @@ out: | |||
416 | * - copies formated debug entries to the user buffer | 507 | * - copies formated debug entries to the user buffer |
417 | */ | 508 | */ |
418 | 509 | ||
419 | static ssize_t debug_output(struct file *file, /* file descriptor */ | 510 | static ssize_t |
420 | char __user *user_buf, /* user buffer */ | 511 | debug_output(struct file *file, /* file descriptor */ |
421 | size_t len, /* length of buffer */ | 512 | char __user *user_buf, /* user buffer */ |
422 | loff_t *offset) /* offset in the file */ | 513 | size_t len, /* length of buffer */ |
514 | loff_t *offset) /* offset in the file */ | ||
423 | { | 515 | { |
424 | size_t count = 0; | 516 | size_t count = 0; |
425 | size_t entry_offset, size = 0; | 517 | size_t entry_offset; |
426 | file_private_info_t *p_info; | 518 | file_private_info_t *p_info; |
427 | 519 | ||
428 | p_info = ((file_private_info_t *) file->private_data); | 520 | p_info = ((file_private_info_t *) file->private_data); |
@@ -430,27 +522,33 @@ static ssize_t debug_output(struct file *file, /* file descriptor */ | |||
430 | return -EPIPE; | 522 | return -EPIPE; |
431 | if(p_info->act_area >= p_info->debug_info_snap->nr_areas) | 523 | if(p_info->act_area >= p_info->debug_info_snap->nr_areas) |
432 | return 0; | 524 | return 0; |
433 | |||
434 | entry_offset = p_info->act_entry_offset; | 525 | entry_offset = p_info->act_entry_offset; |
435 | |||
436 | while(count < len){ | 526 | while(count < len){ |
437 | size = debug_format_entry(p_info); | 527 | int formatted_line_size; |
438 | size = min((len - count), (size - entry_offset)); | 528 | int formatted_line_residue; |
439 | 529 | int user_buf_residue; | |
440 | if(size){ | 530 | size_t copy_size; |
441 | if (copy_to_user(user_buf + count, | 531 | |
442 | p_info->temp_buf + entry_offset, size)) | 532 | formatted_line_size = debug_format_entry(p_info); |
443 | return -EFAULT; | 533 | formatted_line_residue = formatted_line_size - entry_offset; |
534 | user_buf_residue = len-count; | ||
535 | copy_size = min(user_buf_residue, formatted_line_residue); | ||
536 | if(copy_size){ | ||
537 | if (copy_to_user(user_buf + count, p_info->temp_buf | ||
538 | + entry_offset, copy_size)) | ||
539 | return -EFAULT; | ||
540 | count += copy_size; | ||
541 | entry_offset += copy_size; | ||
444 | } | 542 | } |
445 | count += size; | 543 | if(copy_size == formatted_line_residue){ |
446 | entry_offset = 0; | 544 | entry_offset = 0; |
447 | if(count != len) | 545 | if(debug_next_entry(p_info)) |
448 | if(debug_next_entry(p_info)) | ||
449 | goto out; | 546 | goto out; |
547 | } | ||
450 | } | 548 | } |
451 | out: | 549 | out: |
452 | p_info->offset = *offset + count; | 550 | p_info->offset = *offset + count; |
453 | p_info->act_entry_offset = size; | 551 | p_info->act_entry_offset = entry_offset; |
454 | *offset = p_info->offset; | 552 | *offset = p_info->offset; |
455 | return count; | 553 | return count; |
456 | } | 554 | } |
@@ -461,9 +559,9 @@ out: | |||
461 | * - calls input function of view | 559 | * - calls input function of view |
462 | */ | 560 | */ |
463 | 561 | ||
464 | static ssize_t debug_input(struct file *file, | 562 | static ssize_t |
465 | const char __user *user_buf, size_t length, | 563 | debug_input(struct file *file, const char __user *user_buf, size_t length, |
466 | loff_t *offset) | 564 | loff_t *offset) |
467 | { | 565 | { |
468 | int rc = 0; | 566 | int rc = 0; |
469 | file_private_info_t *p_info; | 567 | file_private_info_t *p_info; |
@@ -487,26 +585,23 @@ static ssize_t debug_input(struct file *file, | |||
487 | * handle | 585 | * handle |
488 | */ | 586 | */ |
489 | 587 | ||
490 | static int debug_open(struct inode *inode, struct file *file) | 588 | static int |
589 | debug_open(struct inode *inode, struct file *file) | ||
491 | { | 590 | { |
492 | int i = 0, rc = 0; | 591 | int i = 0, rc = 0; |
493 | file_private_info_t *p_info; | 592 | file_private_info_t *p_info; |
494 | debug_info_t *debug_info, *debug_info_snapshot; | 593 | debug_info_t *debug_info, *debug_info_snapshot; |
495 | 594 | ||
496 | #ifdef DEBUG | ||
497 | printk("debug_open\n"); | ||
498 | #endif | ||
499 | down(&debug_lock); | 595 | down(&debug_lock); |
500 | 596 | ||
501 | /* find debug log and view */ | 597 | /* find debug log and view */ |
502 | |||
503 | debug_info = debug_area_first; | 598 | debug_info = debug_area_first; |
504 | while(debug_info != NULL){ | 599 | while(debug_info != NULL){ |
505 | for (i = 0; i < DEBUG_MAX_VIEWS; i++) { | 600 | for (i = 0; i < DEBUG_MAX_VIEWS; i++) { |
506 | if (debug_info->views[i] == NULL) | 601 | if (!debug_info->views[i]) |
507 | continue; | 602 | continue; |
508 | else if (debug_info->proc_entries[i] == | 603 | else if (debug_info->debugfs_entries[i] == |
509 | PDE(file->f_dentry->d_inode)) { | 604 | file->f_dentry) { |
510 | goto found; /* found view ! */ | 605 | goto found; /* found view ! */ |
511 | } | 606 | } |
512 | } | 607 | } |
@@ -516,41 +611,42 @@ static int debug_open(struct inode *inode, struct file *file) | |||
516 | rc = -EINVAL; | 611 | rc = -EINVAL; |
517 | goto out; | 612 | goto out; |
518 | 613 | ||
519 | found: | 614 | found: |
520 | 615 | ||
521 | /* make snapshot of current debug areas to get it consistent */ | 616 | /* Make snapshot of current debug areas to get it consistent. */ |
617 | /* To copy all the areas is only needed, if we have a view which */ | ||
618 | /* formats the debug areas. */ | ||
522 | 619 | ||
523 | debug_info_snapshot = debug_info_copy(debug_info); | 620 | if(!debug_info->views[i]->format_proc && |
621 | !debug_info->views[i]->header_proc){ | ||
622 | debug_info_snapshot = debug_info_copy(debug_info, NO_AREAS); | ||
623 | } else { | ||
624 | debug_info_snapshot = debug_info_copy(debug_info, ALL_AREAS); | ||
625 | } | ||
524 | 626 | ||
525 | if(!debug_info_snapshot){ | 627 | if(!debug_info_snapshot){ |
526 | #ifdef DEBUG | ||
527 | printk(KERN_ERR "debug_open: debug_info_copy failed (out of mem)\n"); | ||
528 | #endif | ||
529 | rc = -ENOMEM; | 628 | rc = -ENOMEM; |
530 | goto out; | 629 | goto out; |
531 | } | 630 | } |
532 | 631 | p_info = (file_private_info_t *) kmalloc(sizeof(file_private_info_t), | |
533 | if ((file->private_data = | 632 | GFP_KERNEL); |
534 | kmalloc(sizeof(file_private_info_t), GFP_ATOMIC)) == 0) { | 633 | if(!p_info){ |
535 | #ifdef DEBUG | 634 | if(debug_info_snapshot) |
536 | printk(KERN_ERR "debug_open: kmalloc failed\n"); | 635 | debug_info_free(debug_info_snapshot); |
537 | #endif | ||
538 | debug_info_free(debug_info_snapshot); | ||
539 | rc = -ENOMEM; | 636 | rc = -ENOMEM; |
540 | goto out; | 637 | goto out; |
541 | } | 638 | } |
542 | p_info = (file_private_info_t *) file->private_data; | ||
543 | p_info->offset = 0; | 639 | p_info->offset = 0; |
544 | p_info->debug_info_snap = debug_info_snapshot; | 640 | p_info->debug_info_snap = debug_info_snapshot; |
545 | p_info->debug_info_org = debug_info; | 641 | p_info->debug_info_org = debug_info; |
546 | p_info->view = debug_info->views[i]; | 642 | p_info->view = debug_info->views[i]; |
547 | p_info->act_area = 0; | 643 | p_info->act_area = 0; |
644 | p_info->act_page = 0; | ||
548 | p_info->act_entry = DEBUG_PROLOG_ENTRY; | 645 | p_info->act_entry = DEBUG_PROLOG_ENTRY; |
549 | p_info->act_entry_offset = 0; | 646 | p_info->act_entry_offset = 0; |
550 | 647 | file->private_data = p_info; | |
551 | debug_info_get(debug_info); | 648 | debug_info_get(debug_info); |
552 | 649 | out: | |
553 | out: | ||
554 | up(&debug_lock); | 650 | up(&debug_lock); |
555 | return rc; | 651 | return rc; |
556 | } | 652 | } |
@@ -561,14 +657,13 @@ static int debug_open(struct inode *inode, struct file *file) | |||
561 | * - deletes private_data area of the file handle | 657 | * - deletes private_data area of the file handle |
562 | */ | 658 | */ |
563 | 659 | ||
564 | static int debug_close(struct inode *inode, struct file *file) | 660 | static int |
661 | debug_close(struct inode *inode, struct file *file) | ||
565 | { | 662 | { |
566 | file_private_info_t *p_info; | 663 | file_private_info_t *p_info; |
567 | #ifdef DEBUG | ||
568 | printk("debug_close\n"); | ||
569 | #endif | ||
570 | p_info = (file_private_info_t *) file->private_data; | 664 | p_info = (file_private_info_t *) file->private_data; |
571 | debug_info_free(p_info->debug_info_snap); | 665 | if(p_info->debug_info_snap) |
666 | debug_info_free(p_info->debug_info_snap); | ||
572 | debug_info_put(p_info->debug_info_org); | 667 | debug_info_put(p_info->debug_info_org); |
573 | kfree(file->private_data); | 668 | kfree(file->private_data); |
574 | return 0; /* success */ | 669 | return 0; /* success */ |
@@ -580,8 +675,8 @@ static int debug_close(struct inode *inode, struct file *file) | |||
580 | * - returns handle for debug area | 675 | * - returns handle for debug area |
581 | */ | 676 | */ |
582 | 677 | ||
583 | debug_info_t *debug_register | 678 | debug_info_t* |
584 | (char *name, int page_order, int nr_areas, int buf_size) | 679 | debug_register (char *name, int pages_per_area, int nr_areas, int buf_size) |
585 | { | 680 | { |
586 | debug_info_t *rc = NULL; | 681 | debug_info_t *rc = NULL; |
587 | 682 | ||
@@ -591,18 +686,14 @@ debug_info_t *debug_register | |||
591 | 686 | ||
592 | /* create new debug_info */ | 687 | /* create new debug_info */ |
593 | 688 | ||
594 | rc = debug_info_create(name, page_order, nr_areas, buf_size); | 689 | rc = debug_info_create(name, pages_per_area, nr_areas, buf_size); |
595 | if(!rc) | 690 | if(!rc) |
596 | goto out; | 691 | goto out; |
597 | debug_register_view(rc, &debug_level_view); | 692 | debug_register_view(rc, &debug_level_view); |
598 | debug_register_view(rc, &debug_flush_view); | 693 | debug_register_view(rc, &debug_flush_view); |
599 | #ifdef DEBUG | 694 | debug_register_view(rc, &debug_pages_view); |
600 | printk(KERN_INFO | 695 | out: |
601 | "debug: reserved %d areas of %d pages for debugging %s\n", | 696 | if (!rc){ |
602 | nr_areas, 1 << page_order, rc->name); | ||
603 | #endif | ||
604 | out: | ||
605 | if (rc == NULL){ | ||
606 | printk(KERN_ERR "debug: debug_register failed for %s\n",name); | 697 | printk(KERN_ERR "debug: debug_register failed for %s\n",name); |
607 | } | 698 | } |
608 | up(&debug_lock); | 699 | up(&debug_lock); |
@@ -614,27 +705,65 @@ debug_info_t *debug_register | |||
614 | * - give back debug area | 705 | * - give back debug area |
615 | */ | 706 | */ |
616 | 707 | ||
617 | void debug_unregister(debug_info_t * id) | 708 | void |
709 | debug_unregister(debug_info_t * id) | ||
618 | { | 710 | { |
619 | if (!id) | 711 | if (!id) |
620 | goto out; | 712 | goto out; |
621 | down(&debug_lock); | 713 | down(&debug_lock); |
622 | #ifdef DEBUG | ||
623 | printk(KERN_INFO "debug: unregistering %s\n", id->name); | ||
624 | #endif | ||
625 | debug_info_put(id); | 714 | debug_info_put(id); |
626 | up(&debug_lock); | 715 | up(&debug_lock); |
627 | 716 | ||
628 | out: | 717 | out: |
629 | return; | 718 | return; |
630 | } | 719 | } |
631 | 720 | ||
632 | /* | 721 | /* |
722 | * debug_set_size: | ||
723 | * - set area size (number of pages) and number of areas | ||
724 | */ | ||
725 | static int | ||
726 | debug_set_size(debug_info_t* id, int nr_areas, int pages_per_area) | ||
727 | { | ||
728 | unsigned long flags; | ||
729 | debug_entry_t *** new_areas; | ||
730 | int rc=0; | ||
731 | |||
732 | if(!id || (nr_areas <= 0) || (pages_per_area < 0)) | ||
733 | return -EINVAL; | ||
734 | if(pages_per_area > 0){ | ||
735 | new_areas = debug_areas_alloc(pages_per_area, nr_areas); | ||
736 | if(!new_areas) { | ||
737 | printk(KERN_WARNING "debug: could not allocate memory "\ | ||
738 | "for pagenumber: %i\n",pages_per_area); | ||
739 | rc = -ENOMEM; | ||
740 | goto out; | ||
741 | } | ||
742 | } else { | ||
743 | new_areas = NULL; | ||
744 | } | ||
745 | spin_lock_irqsave(&id->lock,flags); | ||
746 | debug_areas_free(id); | ||
747 | id->areas = new_areas; | ||
748 | id->nr_areas = nr_areas; | ||
749 | id->pages_per_area = pages_per_area; | ||
750 | id->active_area = 0; | ||
751 | memset(id->active_entries,0,sizeof(int)*id->nr_areas); | ||
752 | memset(id->active_pages, 0, sizeof(int)*id->nr_areas); | ||
753 | spin_unlock_irqrestore(&id->lock,flags); | ||
754 | printk(KERN_INFO "debug: %s: set new size (%i pages)\n"\ | ||
755 | ,id->name, pages_per_area); | ||
756 | out: | ||
757 | return rc; | ||
758 | } | ||
759 | |||
760 | /* | ||
633 | * debug_set_level: | 761 | * debug_set_level: |
634 | * - set actual debug level | 762 | * - set actual debug level |
635 | */ | 763 | */ |
636 | 764 | ||
637 | void debug_set_level(debug_info_t* id, int new_level) | 765 | void |
766 | debug_set_level(debug_info_t* id, int new_level) | ||
638 | { | 767 | { |
639 | unsigned long flags; | 768 | unsigned long flags; |
640 | if(!id) | 769 | if(!id) |
@@ -649,10 +778,6 @@ void debug_set_level(debug_info_t* id, int new_level) | |||
649 | id->name, new_level, 0, DEBUG_MAX_LEVEL); | 778 | id->name, new_level, 0, DEBUG_MAX_LEVEL); |
650 | } else { | 779 | } else { |
651 | id->level = new_level; | 780 | id->level = new_level; |
652 | #ifdef DEBUG | ||
653 | printk(KERN_INFO | ||
654 | "debug: %s: new level %i\n",id->name,id->level); | ||
655 | #endif | ||
656 | } | 781 | } |
657 | spin_unlock_irqrestore(&id->lock,flags); | 782 | spin_unlock_irqrestore(&id->lock,flags); |
658 | } | 783 | } |
@@ -663,11 +788,16 @@ void debug_set_level(debug_info_t* id, int new_level) | |||
663 | * - set active entry to next in the ring buffer | 788 | * - set active entry to next in the ring buffer |
664 | */ | 789 | */ |
665 | 790 | ||
666 | extern inline void proceed_active_entry(debug_info_t * id) | 791 | extern inline void |
792 | proceed_active_entry(debug_info_t * id) | ||
667 | { | 793 | { |
668 | if ((id->active_entry[id->active_area] += id->entry_size) | 794 | if ((id->active_entries[id->active_area] += id->entry_size) |
669 | > ((PAGE_SIZE << (id->page_order)) - id->entry_size)) | 795 | > (PAGE_SIZE - id->entry_size)){ |
670 | id->active_entry[id->active_area] = 0; | 796 | id->active_entries[id->active_area] = 0; |
797 | id->active_pages[id->active_area] = | ||
798 | (id->active_pages[id->active_area] + 1) % | ||
799 | id->pages_per_area; | ||
800 | } | ||
671 | } | 801 | } |
672 | 802 | ||
673 | /* | 803 | /* |
@@ -675,7 +805,8 @@ extern inline void proceed_active_entry(debug_info_t * id) | |||
675 | * - set active area to next in the ring buffer | 805 | * - set active area to next in the ring buffer |
676 | */ | 806 | */ |
677 | 807 | ||
678 | extern inline void proceed_active_area(debug_info_t * id) | 808 | extern inline void |
809 | proceed_active_area(debug_info_t * id) | ||
679 | { | 810 | { |
680 | id->active_area++; | 811 | id->active_area++; |
681 | id->active_area = id->active_area % id->nr_areas; | 812 | id->active_area = id->active_area % id->nr_areas; |
@@ -685,10 +816,12 @@ extern inline void proceed_active_area(debug_info_t * id) | |||
685 | * get_active_entry: | 816 | * get_active_entry: |
686 | */ | 817 | */ |
687 | 818 | ||
688 | extern inline debug_entry_t *get_active_entry(debug_info_t * id) | 819 | extern inline debug_entry_t* |
820 | get_active_entry(debug_info_t * id) | ||
689 | { | 821 | { |
690 | return (debug_entry_t *) ((char *) id->areas[id->active_area] + | 822 | return (debug_entry_t *) (((char *) id->areas[id->active_area] |
691 | id->active_entry[id->active_area]); | 823 | [id->active_pages[id->active_area]]) + |
824 | id->active_entries[id->active_area]); | ||
692 | } | 825 | } |
693 | 826 | ||
694 | /* | 827 | /* |
@@ -696,8 +829,9 @@ extern inline debug_entry_t *get_active_entry(debug_info_t * id) | |||
696 | * - set timestamp, caller address, cpu number etc. | 829 | * - set timestamp, caller address, cpu number etc. |
697 | */ | 830 | */ |
698 | 831 | ||
699 | extern inline void debug_finish_entry(debug_info_t * id, debug_entry_t* active, | 832 | extern inline void |
700 | int level, int exception) | 833 | debug_finish_entry(debug_info_t * id, debug_entry_t* active, int level, |
834 | int exception) | ||
701 | { | 835 | { |
702 | STCK(active->id.stck); | 836 | STCK(active->id.stck); |
703 | active->id.fields.cpuid = smp_processor_id(); | 837 | active->id.fields.cpuid = smp_processor_id(); |
@@ -721,7 +855,8 @@ static int debug_active=1; | |||
721 | * always allow read, allow write only if debug_stoppable is set or | 855 | * always allow read, allow write only if debug_stoppable is set or |
722 | * if debug_active is already off | 856 | * if debug_active is already off |
723 | */ | 857 | */ |
724 | static int s390dbf_procactive(ctl_table *table, int write, struct file *filp, | 858 | static int |
859 | s390dbf_procactive(ctl_table *table, int write, struct file *filp, | ||
725 | void __user *buffer, size_t *lenp, loff_t *ppos) | 860 | void __user *buffer, size_t *lenp, loff_t *ppos) |
726 | { | 861 | { |
727 | if (!write || debug_stoppable || !debug_active) | 862 | if (!write || debug_stoppable || !debug_active) |
@@ -766,7 +901,8 @@ static struct ctl_table s390dbf_dir_table[] = { | |||
766 | 901 | ||
767 | struct ctl_table_header *s390dbf_sysctl_header; | 902 | struct ctl_table_header *s390dbf_sysctl_header; |
768 | 903 | ||
769 | void debug_stop_all(void) | 904 | void |
905 | debug_stop_all(void) | ||
770 | { | 906 | { |
771 | if (debug_stoppable) | 907 | if (debug_stoppable) |
772 | debug_active = 0; | 908 | debug_active = 0; |
@@ -778,13 +914,13 @@ void debug_stop_all(void) | |||
778 | * - write debug entry with given size | 914 | * - write debug entry with given size |
779 | */ | 915 | */ |
780 | 916 | ||
781 | debug_entry_t *debug_event_common(debug_info_t * id, int level, const void *buf, | 917 | debug_entry_t* |
782 | int len) | 918 | debug_event_common(debug_info_t * id, int level, const void *buf, int len) |
783 | { | 919 | { |
784 | unsigned long flags; | 920 | unsigned long flags; |
785 | debug_entry_t *active; | 921 | debug_entry_t *active; |
786 | 922 | ||
787 | if (!debug_active) | 923 | if (!debug_active || !id->areas) |
788 | return NULL; | 924 | return NULL; |
789 | spin_lock_irqsave(&id->lock, flags); | 925 | spin_lock_irqsave(&id->lock, flags); |
790 | active = get_active_entry(id); | 926 | active = get_active_entry(id); |
@@ -801,13 +937,13 @@ debug_entry_t *debug_event_common(debug_info_t * id, int level, const void *buf, | |||
801 | * - write debug entry with given size and switch to next debug area | 937 | * - write debug entry with given size and switch to next debug area |
802 | */ | 938 | */ |
803 | 939 | ||
804 | debug_entry_t *debug_exception_common(debug_info_t * id, int level, | 940 | debug_entry_t |
805 | const void *buf, int len) | 941 | *debug_exception_common(debug_info_t * id, int level, const void *buf, int len) |
806 | { | 942 | { |
807 | unsigned long flags; | 943 | unsigned long flags; |
808 | debug_entry_t *active; | 944 | debug_entry_t *active; |
809 | 945 | ||
810 | if (!debug_active) | 946 | if (!debug_active || !id->areas) |
811 | return NULL; | 947 | return NULL; |
812 | spin_lock_irqsave(&id->lock, flags); | 948 | spin_lock_irqsave(&id->lock, flags); |
813 | active = get_active_entry(id); | 949 | active = get_active_entry(id); |
@@ -823,7 +959,8 @@ debug_entry_t *debug_exception_common(debug_info_t * id, int level, | |||
823 | * counts arguments in format string for sprintf view | 959 | * counts arguments in format string for sprintf view |
824 | */ | 960 | */ |
825 | 961 | ||
826 | extern inline int debug_count_numargs(char *string) | 962 | extern inline int |
963 | debug_count_numargs(char *string) | ||
827 | { | 964 | { |
828 | int numargs=0; | 965 | int numargs=0; |
829 | 966 | ||
@@ -838,8 +975,8 @@ extern inline int debug_count_numargs(char *string) | |||
838 | * debug_sprintf_event: | 975 | * debug_sprintf_event: |
839 | */ | 976 | */ |
840 | 977 | ||
841 | debug_entry_t *debug_sprintf_event(debug_info_t* id, | 978 | debug_entry_t* |
842 | int level,char *string,...) | 979 | debug_sprintf_event(debug_info_t* id, int level,char *string,...) |
843 | { | 980 | { |
844 | va_list ap; | 981 | va_list ap; |
845 | int numargs,idx; | 982 | int numargs,idx; |
@@ -849,7 +986,7 @@ debug_entry_t *debug_sprintf_event(debug_info_t* id, | |||
849 | 986 | ||
850 | if((!id) || (level > id->level)) | 987 | if((!id) || (level > id->level)) |
851 | return NULL; | 988 | return NULL; |
852 | if (!debug_active) | 989 | if (!debug_active || !id->areas) |
853 | return NULL; | 990 | return NULL; |
854 | numargs=debug_count_numargs(string); | 991 | numargs=debug_count_numargs(string); |
855 | 992 | ||
@@ -871,8 +1008,8 @@ debug_entry_t *debug_sprintf_event(debug_info_t* id, | |||
871 | * debug_sprintf_exception: | 1008 | * debug_sprintf_exception: |
872 | */ | 1009 | */ |
873 | 1010 | ||
874 | debug_entry_t *debug_sprintf_exception(debug_info_t* id, | 1011 | debug_entry_t* |
875 | int level,char *string,...) | 1012 | debug_sprintf_exception(debug_info_t* id, int level,char *string,...) |
876 | { | 1013 | { |
877 | va_list ap; | 1014 | va_list ap; |
878 | int numargs,idx; | 1015 | int numargs,idx; |
@@ -882,7 +1019,7 @@ debug_entry_t *debug_sprintf_exception(debug_info_t* id, | |||
882 | 1019 | ||
883 | if((!id) || (level > id->level)) | 1020 | if((!id) || (level > id->level)) |
884 | return NULL; | 1021 | return NULL; |
885 | if (!debug_active) | 1022 | if (!debug_active || !id->areas) |
886 | return NULL; | 1023 | return NULL; |
887 | 1024 | ||
888 | numargs=debug_count_numargs(string); | 1025 | numargs=debug_count_numargs(string); |
@@ -906,15 +1043,14 @@ debug_entry_t *debug_sprintf_exception(debug_info_t* id, | |||
906 | * - is called exactly once to initialize the debug feature | 1043 | * - is called exactly once to initialize the debug feature |
907 | */ | 1044 | */ |
908 | 1045 | ||
909 | static int __init debug_init(void) | 1046 | static int |
1047 | __init debug_init(void) | ||
910 | { | 1048 | { |
911 | int rc = 0; | 1049 | int rc = 0; |
912 | 1050 | ||
913 | s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table, 1); | 1051 | s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table, 1); |
914 | down(&debug_lock); | 1052 | down(&debug_lock); |
915 | #ifdef CONFIG_PROC_FS | 1053 | debug_debugfs_root_entry = debugfs_create_dir(DEBUG_DIR_ROOT,NULL); |
916 | debug_proc_root_entry = proc_mkdir(DEBUG_DIR_ROOT, NULL); | ||
917 | #endif /* CONFIG_PROC_FS */ | ||
918 | printk(KERN_INFO "debug: Initialization complete\n"); | 1054 | printk(KERN_INFO "debug: Initialization complete\n"); |
919 | initialized = 1; | 1055 | initialized = 1; |
920 | up(&debug_lock); | 1056 | up(&debug_lock); |
@@ -926,13 +1062,14 @@ static int __init debug_init(void) | |||
926 | * debug_register_view: | 1062 | * debug_register_view: |
927 | */ | 1063 | */ |
928 | 1064 | ||
929 | int debug_register_view(debug_info_t * id, struct debug_view *view) | 1065 | int |
1066 | debug_register_view(debug_info_t * id, struct debug_view *view) | ||
930 | { | 1067 | { |
931 | int rc = 0; | 1068 | int rc = 0; |
932 | int i; | 1069 | int i; |
933 | unsigned long flags; | 1070 | unsigned long flags; |
934 | mode_t mode = S_IFREG; | 1071 | mode_t mode = S_IFREG; |
935 | struct proc_dir_entry *pde; | 1072 | struct dentry *pde; |
936 | 1073 | ||
937 | if (!id) | 1074 | if (!id) |
938 | goto out; | 1075 | goto out; |
@@ -940,16 +1077,17 @@ int debug_register_view(debug_info_t * id, struct debug_view *view) | |||
940 | mode |= S_IRUSR; | 1077 | mode |= S_IRUSR; |
941 | if (view->input_proc) | 1078 | if (view->input_proc) |
942 | mode |= S_IWUSR; | 1079 | mode |= S_IWUSR; |
943 | pde = create_proc_entry(view->name, mode, id->proc_root_entry); | 1080 | pde = debugfs_create_file(view->name, mode, id->debugfs_root_entry, |
1081 | NULL, &debug_file_ops); | ||
944 | if (!pde){ | 1082 | if (!pde){ |
945 | printk(KERN_WARNING "debug: create_proc_entry() failed! Cannot register view %s/%s\n", id->name,view->name); | 1083 | printk(KERN_WARNING "debug: debugfs_create_file() failed!"\ |
1084 | " Cannot register view %s/%s\n", id->name,view->name); | ||
946 | rc = -1; | 1085 | rc = -1; |
947 | goto out; | 1086 | goto out; |
948 | } | 1087 | } |
949 | |||
950 | spin_lock_irqsave(&id->lock, flags); | 1088 | spin_lock_irqsave(&id->lock, flags); |
951 | for (i = 0; i < DEBUG_MAX_VIEWS; i++) { | 1089 | for (i = 0; i < DEBUG_MAX_VIEWS; i++) { |
952 | if (id->views[i] == NULL) | 1090 | if (!id->views[i]) |
953 | break; | 1091 | break; |
954 | } | 1092 | } |
955 | if (i == DEBUG_MAX_VIEWS) { | 1093 | if (i == DEBUG_MAX_VIEWS) { |
@@ -957,16 +1095,14 @@ int debug_register_view(debug_info_t * id, struct debug_view *view) | |||
957 | id->name,view->name); | 1095 | id->name,view->name); |
958 | printk(KERN_WARNING | 1096 | printk(KERN_WARNING |
959 | "debug: maximum number of views reached (%i)!\n", i); | 1097 | "debug: maximum number of views reached (%i)!\n", i); |
960 | remove_proc_entry(pde->name, id->proc_root_entry); | 1098 | debugfs_remove(pde); |
961 | rc = -1; | 1099 | rc = -1; |
962 | } | 1100 | } else { |
963 | else { | ||
964 | id->views[i] = view; | 1101 | id->views[i] = view; |
965 | pde->proc_fops = &debug_file_ops; | 1102 | id->debugfs_entries[i] = pde; |
966 | id->proc_entries[i] = pde; | ||
967 | } | 1103 | } |
968 | spin_unlock_irqrestore(&id->lock, flags); | 1104 | spin_unlock_irqrestore(&id->lock, flags); |
969 | out: | 1105 | out: |
970 | return rc; | 1106 | return rc; |
971 | } | 1107 | } |
972 | 1108 | ||
@@ -974,7 +1110,8 @@ int debug_register_view(debug_info_t * id, struct debug_view *view) | |||
974 | * debug_unregister_view: | 1110 | * debug_unregister_view: |
975 | */ | 1111 | */ |
976 | 1112 | ||
977 | int debug_unregister_view(debug_info_t * id, struct debug_view *view) | 1113 | int |
1114 | debug_unregister_view(debug_info_t * id, struct debug_view *view) | ||
978 | { | 1115 | { |
979 | int rc = 0; | 1116 | int rc = 0; |
980 | int i; | 1117 | int i; |
@@ -990,15 +1127,46 @@ int debug_unregister_view(debug_info_t * id, struct debug_view *view) | |||
990 | if (i == DEBUG_MAX_VIEWS) | 1127 | if (i == DEBUG_MAX_VIEWS) |
991 | rc = -1; | 1128 | rc = -1; |
992 | else { | 1129 | else { |
993 | #ifdef CONFIG_PROC_FS | 1130 | debugfs_remove(id->debugfs_entries[i]); |
994 | remove_proc_entry(id->proc_entries[i]->name, | ||
995 | id->proc_root_entry); | ||
996 | #endif | ||
997 | id->views[i] = NULL; | 1131 | id->views[i] = NULL; |
998 | rc = 0; | 1132 | rc = 0; |
999 | } | 1133 | } |
1000 | spin_unlock_irqrestore(&id->lock, flags); | 1134 | spin_unlock_irqrestore(&id->lock, flags); |
1001 | out: | 1135 | out: |
1136 | return rc; | ||
1137 | } | ||
1138 | |||
1139 | static inline char * | ||
1140 | debug_get_user_string(const char __user *user_buf, size_t user_len) | ||
1141 | { | ||
1142 | char* buffer; | ||
1143 | |||
1144 | buffer = kmalloc(user_len + 1, GFP_KERNEL); | ||
1145 | if (!buffer) | ||
1146 | return ERR_PTR(-ENOMEM); | ||
1147 | if (copy_from_user(buffer, user_buf, user_len) != 0) { | ||
1148 | kfree(buffer); | ||
1149 | return ERR_PTR(-EFAULT); | ||
1150 | } | ||
1151 | /* got the string, now strip linefeed. */ | ||
1152 | if (buffer[user_len - 1] == '\n') | ||
1153 | buffer[user_len - 1] = 0; | ||
1154 | else | ||
1155 | buffer[user_len] = 0; | ||
1156 | return buffer; | ||
1157 | } | ||
1158 | |||
1159 | static inline int | ||
1160 | debug_get_uint(char *buf) | ||
1161 | { | ||
1162 | int rc; | ||
1163 | |||
1164 | for(; isspace(*buf); buf++); | ||
1165 | rc = simple_strtoul(buf, &buf, 10); | ||
1166 | if(*buf){ | ||
1167 | printk("debug: no integer specified!\n"); | ||
1168 | rc = -EINVAL; | ||
1169 | } | ||
1002 | return rc; | 1170 | return rc; |
1003 | } | 1171 | } |
1004 | 1172 | ||
@@ -1011,13 +1179,69 @@ int debug_unregister_view(debug_info_t * id, struct debug_view *view) | |||
1011 | * prints out actual debug level | 1179 | * prints out actual debug level |
1012 | */ | 1180 | */ |
1013 | 1181 | ||
1014 | static int debug_prolog_level_fn(debug_info_t * id, | 1182 | static int |
1183 | debug_prolog_pages_fn(debug_info_t * id, | ||
1015 | struct debug_view *view, char *out_buf) | 1184 | struct debug_view *view, char *out_buf) |
1016 | { | 1185 | { |
1186 | return sprintf(out_buf, "%i\n", id->pages_per_area); | ||
1187 | } | ||
1188 | |||
1189 | /* | ||
1190 | * reads new size (number of pages per debug area) | ||
1191 | */ | ||
1192 | |||
1193 | static int | ||
1194 | debug_input_pages_fn(debug_info_t * id, struct debug_view *view, | ||
1195 | struct file *file, const char __user *user_buf, | ||
1196 | size_t user_len, loff_t * offset) | ||
1197 | { | ||
1198 | char *str; | ||
1199 | int rc,new_pages; | ||
1200 | |||
1201 | if (user_len > 0x10000) | ||
1202 | user_len = 0x10000; | ||
1203 | if (*offset != 0){ | ||
1204 | rc = -EPIPE; | ||
1205 | goto out; | ||
1206 | } | ||
1207 | str = debug_get_user_string(user_buf,user_len); | ||
1208 | if(IS_ERR(str)){ | ||
1209 | rc = PTR_ERR(str); | ||
1210 | goto out; | ||
1211 | } | ||
1212 | new_pages = debug_get_uint(str); | ||
1213 | if(new_pages < 0){ | ||
1214 | rc = -EINVAL; | ||
1215 | goto free_str; | ||
1216 | } | ||
1217 | rc = debug_set_size(id,id->nr_areas, new_pages); | ||
1218 | if(rc != 0){ | ||
1219 | rc = -EINVAL; | ||
1220 | goto free_str; | ||
1221 | } | ||
1222 | rc = user_len; | ||
1223 | free_str: | ||
1224 | kfree(str); | ||
1225 | out: | ||
1226 | *offset += user_len; | ||
1227 | return rc; /* number of input characters */ | ||
1228 | } | ||
1229 | |||
1230 | /* | ||
1231 | * prints out actual debug level | ||
1232 | */ | ||
1233 | |||
1234 | static int | ||
1235 | debug_prolog_level_fn(debug_info_t * id, struct debug_view *view, char *out_buf) | ||
1236 | { | ||
1017 | int rc = 0; | 1237 | int rc = 0; |
1018 | 1238 | ||
1019 | if(id->level == -1) rc = sprintf(out_buf,"-\n"); | 1239 | if(id->level == DEBUG_OFF_LEVEL) { |
1020 | else rc = sprintf(out_buf, "%i\n", id->level); | 1240 | rc = sprintf(out_buf,"-\n"); |
1241 | } | ||
1242 | else { | ||
1243 | rc = sprintf(out_buf, "%i\n", id->level); | ||
1244 | } | ||
1021 | return rc; | 1245 | return rc; |
1022 | } | 1246 | } |
1023 | 1247 | ||
@@ -1025,30 +1249,43 @@ static int debug_prolog_level_fn(debug_info_t * id, | |||
1025 | * reads new debug level | 1249 | * reads new debug level |
1026 | */ | 1250 | */ |
1027 | 1251 | ||
1028 | static int debug_input_level_fn(debug_info_t * id, struct debug_view *view, | 1252 | static int |
1029 | struct file *file, const char __user *user_buf, | 1253 | debug_input_level_fn(debug_info_t * id, struct debug_view *view, |
1030 | size_t in_buf_size, loff_t * offset) | 1254 | struct file *file, const char __user *user_buf, |
1255 | size_t user_len, loff_t * offset) | ||
1031 | { | 1256 | { |
1032 | char input_buf[1]; | 1257 | char *str; |
1033 | int rc = in_buf_size; | 1258 | int rc,new_level; |
1034 | 1259 | ||
1035 | if (*offset != 0) | 1260 | if (user_len > 0x10000) |
1261 | user_len = 0x10000; | ||
1262 | if (*offset != 0){ | ||
1263 | rc = -EPIPE; | ||
1036 | goto out; | 1264 | goto out; |
1037 | if (copy_from_user(input_buf, user_buf, 1)){ | 1265 | } |
1038 | rc = -EFAULT; | 1266 | str = debug_get_user_string(user_buf,user_len); |
1267 | if(IS_ERR(str)){ | ||
1268 | rc = PTR_ERR(str); | ||
1039 | goto out; | 1269 | goto out; |
1040 | } | 1270 | } |
1041 | if (isdigit(input_buf[0])) { | 1271 | if(str[0] == '-'){ |
1042 | int new_level = ((int) input_buf[0] - (int) '0'); | ||
1043 | debug_set_level(id, new_level); | ||
1044 | } else if(input_buf[0] == '-') { | ||
1045 | debug_set_level(id, DEBUG_OFF_LEVEL); | 1272 | debug_set_level(id, DEBUG_OFF_LEVEL); |
1273 | rc = user_len; | ||
1274 | goto free_str; | ||
1046 | } else { | 1275 | } else { |
1047 | printk(KERN_INFO "debug: level `%c` is not valid\n", | 1276 | new_level = debug_get_uint(str); |
1048 | input_buf[0]); | ||
1049 | } | 1277 | } |
1050 | out: | 1278 | if(new_level < 0) { |
1051 | *offset += in_buf_size; | 1279 | printk(KERN_INFO "debug: level `%s` is not valid\n", str); |
1280 | rc = -EINVAL; | ||
1281 | } else { | ||
1282 | debug_set_level(id, new_level); | ||
1283 | rc = user_len; | ||
1284 | } | ||
1285 | free_str: | ||
1286 | kfree(str); | ||
1287 | out: | ||
1288 | *offset += user_len; | ||
1052 | return rc; /* number of input characters */ | 1289 | return rc; /* number of input characters */ |
1053 | } | 1290 | } |
1054 | 1291 | ||
@@ -1057,29 +1294,36 @@ static int debug_input_level_fn(debug_info_t * id, struct debug_view *view, | |||
1057 | * flushes debug areas | 1294 | * flushes debug areas |
1058 | */ | 1295 | */ |
1059 | 1296 | ||
1060 | void debug_flush(debug_info_t* id, int area) | 1297 | void |
1298 | debug_flush(debug_info_t* id, int area) | ||
1061 | { | 1299 | { |
1062 | unsigned long flags; | 1300 | unsigned long flags; |
1063 | int i; | 1301 | int i,j; |
1064 | 1302 | ||
1065 | if(!id) | 1303 | if(!id || !id->areas) |
1066 | return; | 1304 | return; |
1067 | spin_lock_irqsave(&id->lock,flags); | 1305 | spin_lock_irqsave(&id->lock,flags); |
1068 | if(area == DEBUG_FLUSH_ALL){ | 1306 | if(area == DEBUG_FLUSH_ALL){ |
1069 | id->active_area = 0; | 1307 | id->active_area = 0; |
1070 | memset(id->active_entry, 0, id->nr_areas * sizeof(int)); | 1308 | memset(id->active_entries, 0, id->nr_areas * sizeof(int)); |
1071 | for (i = 0; i < id->nr_areas; i++) | 1309 | for (i = 0; i < id->nr_areas; i++) { |
1072 | memset(id->areas[i], 0, PAGE_SIZE << id->page_order); | 1310 | id->active_pages[i] = 0; |
1311 | for(j = 0; j < id->pages_per_area; j++) { | ||
1312 | memset(id->areas[i][j], 0, PAGE_SIZE); | ||
1313 | } | ||
1314 | } | ||
1073 | printk(KERN_INFO "debug: %s: all areas flushed\n",id->name); | 1315 | printk(KERN_INFO "debug: %s: all areas flushed\n",id->name); |
1074 | } else if(area >= 0 && area < id->nr_areas) { | 1316 | } else if(area >= 0 && area < id->nr_areas) { |
1075 | id->active_entry[area] = 0; | 1317 | id->active_entries[area] = 0; |
1076 | memset(id->areas[area], 0, PAGE_SIZE << id->page_order); | 1318 | id->active_pages[area] = 0; |
1077 | printk(KERN_INFO | 1319 | for(i = 0; i < id->pages_per_area; i++) { |
1078 | "debug: %s: area %i has been flushed\n", | 1320 | memset(id->areas[area][i],0,PAGE_SIZE); |
1321 | } | ||
1322 | printk(KERN_INFO "debug: %s: area %i has been flushed\n", | ||
1079 | id->name, area); | 1323 | id->name, area); |
1080 | } else { | 1324 | } else { |
1081 | printk(KERN_INFO | 1325 | printk(KERN_INFO |
1082 | "debug: %s: area %i cannot be flushed (range: %i - %i)\n", | 1326 | "debug: %s: area %i cannot be flushed (range: %i - %i)\n", |
1083 | id->name, area, 0, id->nr_areas-1); | 1327 | id->name, area, 0, id->nr_areas-1); |
1084 | } | 1328 | } |
1085 | spin_unlock_irqrestore(&id->lock,flags); | 1329 | spin_unlock_irqrestore(&id->lock,flags); |
@@ -1089,15 +1333,20 @@ void debug_flush(debug_info_t* id, int area) | |||
1089 | * view function: flushes debug areas | 1333 | * view function: flushes debug areas |
1090 | */ | 1334 | */ |
1091 | 1335 | ||
1092 | static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view, | 1336 | static int |
1093 | struct file *file, const char __user *user_buf, | 1337 | debug_input_flush_fn(debug_info_t * id, struct debug_view *view, |
1094 | size_t in_buf_size, loff_t * offset) | 1338 | struct file *file, const char __user *user_buf, |
1339 | size_t user_len, loff_t * offset) | ||
1095 | { | 1340 | { |
1096 | char input_buf[1]; | 1341 | char input_buf[1]; |
1097 | int rc = in_buf_size; | 1342 | int rc = user_len; |
1098 | 1343 | ||
1099 | if (*offset != 0) | 1344 | if (user_len > 0x10000) |
1345 | user_len = 0x10000; | ||
1346 | if (*offset != 0){ | ||
1347 | rc = -EPIPE; | ||
1100 | goto out; | 1348 | goto out; |
1349 | } | ||
1101 | if (copy_from_user(input_buf, user_buf, 1)){ | 1350 | if (copy_from_user(input_buf, user_buf, 1)){ |
1102 | rc = -EFAULT; | 1351 | rc = -EFAULT; |
1103 | goto out; | 1352 | goto out; |
@@ -1114,8 +1363,8 @@ static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view, | |||
1114 | 1363 | ||
1115 | printk(KERN_INFO "debug: area `%c` is not valid\n", input_buf[0]); | 1364 | printk(KERN_INFO "debug: area `%c` is not valid\n", input_buf[0]); |
1116 | 1365 | ||
1117 | out: | 1366 | out: |
1118 | *offset += in_buf_size; | 1367 | *offset += user_len; |
1119 | return rc; /* number of input characters */ | 1368 | return rc; /* number of input characters */ |
1120 | } | 1369 | } |
1121 | 1370 | ||
@@ -1123,8 +1372,9 @@ static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view, | |||
1123 | * prints debug header in raw format | 1372 | * prints debug header in raw format |
1124 | */ | 1373 | */ |
1125 | 1374 | ||
1126 | int debug_raw_header_fn(debug_info_t * id, struct debug_view *view, | 1375 | static int |
1127 | int area, debug_entry_t * entry, char *out_buf) | 1376 | debug_raw_header_fn(debug_info_t * id, struct debug_view *view, |
1377 | int area, debug_entry_t * entry, char *out_buf) | ||
1128 | { | 1378 | { |
1129 | int rc; | 1379 | int rc; |
1130 | 1380 | ||
@@ -1137,7 +1387,8 @@ int debug_raw_header_fn(debug_info_t * id, struct debug_view *view, | |||
1137 | * prints debug data in raw format | 1387 | * prints debug data in raw format |
1138 | */ | 1388 | */ |
1139 | 1389 | ||
1140 | static int debug_raw_format_fn(debug_info_t * id, struct debug_view *view, | 1390 | static int |
1391 | debug_raw_format_fn(debug_info_t * id, struct debug_view *view, | ||
1141 | char *out_buf, const char *in_buf) | 1392 | char *out_buf, const char *in_buf) |
1142 | { | 1393 | { |
1143 | int rc; | 1394 | int rc; |
@@ -1151,8 +1402,9 @@ static int debug_raw_format_fn(debug_info_t * id, struct debug_view *view, | |||
1151 | * prints debug data in hex/ascii format | 1402 | * prints debug data in hex/ascii format |
1152 | */ | 1403 | */ |
1153 | 1404 | ||
1154 | static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view, | 1405 | static int |
1155 | char *out_buf, const char *in_buf) | 1406 | debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view, |
1407 | char *out_buf, const char *in_buf) | ||
1156 | { | 1408 | { |
1157 | int i, rc = 0; | 1409 | int i, rc = 0; |
1158 | 1410 | ||
@@ -1176,7 +1428,8 @@ static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view, | |||
1176 | * prints header for debug entry | 1428 | * prints header for debug entry |
1177 | */ | 1429 | */ |
1178 | 1430 | ||
1179 | int debug_dflt_header_fn(debug_info_t * id, struct debug_view *view, | 1431 | int |
1432 | debug_dflt_header_fn(debug_info_t * id, struct debug_view *view, | ||
1180 | int area, debug_entry_t * entry, char *out_buf) | 1433 | int area, debug_entry_t * entry, char *out_buf) |
1181 | { | 1434 | { |
1182 | struct timeval time_val; | 1435 | struct timeval time_val; |
@@ -1210,8 +1463,9 @@ int debug_dflt_header_fn(debug_info_t * id, struct debug_view *view, | |||
1210 | 1463 | ||
1211 | #define DEBUG_SPRINTF_MAX_ARGS 10 | 1464 | #define DEBUG_SPRINTF_MAX_ARGS 10 |
1212 | 1465 | ||
1213 | int debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view, | 1466 | static int |
1214 | char *out_buf, debug_sprintf_entry_t *curr_event) | 1467 | debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view, |
1468 | char *out_buf, debug_sprintf_entry_t *curr_event) | ||
1215 | { | 1469 | { |
1216 | int num_longs, num_used_args = 0,i, rc = 0; | 1470 | int num_longs, num_used_args = 0,i, rc = 0; |
1217 | int index[DEBUG_SPRINTF_MAX_ARGS]; | 1471 | int index[DEBUG_SPRINTF_MAX_ARGS]; |
@@ -1251,14 +1505,10 @@ out: | |||
1251 | /* | 1505 | /* |
1252 | * clean up module | 1506 | * clean up module |
1253 | */ | 1507 | */ |
1254 | void __exit debug_exit(void) | 1508 | void |
1509 | __exit debug_exit(void) | ||
1255 | { | 1510 | { |
1256 | #ifdef DEBUG | 1511 | debugfs_remove(debug_debugfs_root_entry); |
1257 | printk("debug_cleanup_module: \n"); | ||
1258 | #endif | ||
1259 | #ifdef CONFIG_PROC_FS | ||
1260 | remove_proc_entry(debug_proc_root_entry->name, NULL); | ||
1261 | #endif /* CONFIG_PROC_FS */ | ||
1262 | unregister_sysctl_table(s390dbf_sysctl_header); | 1512 | unregister_sysctl_table(s390dbf_sysctl_header); |
1263 | return; | 1513 | return; |
1264 | } | 1514 | } |
@@ -1266,7 +1516,7 @@ void __exit debug_exit(void) | |||
1266 | /* | 1516 | /* |
1267 | * module definitions | 1517 | * module definitions |
1268 | */ | 1518 | */ |
1269 | core_initcall(debug_init); | 1519 | postcore_initcall(debug_init); |
1270 | module_exit(debug_exit); | 1520 | module_exit(debug_exit); |
1271 | MODULE_LICENSE("GPL"); | 1521 | MODULE_LICENSE("GPL"); |
1272 | 1522 | ||
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index c0e09b33febe..5b262b5d869f 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -7,6 +7,7 @@ | |||
7 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), | 7 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), |
8 | * Hartmut Penner (hp@de.ibm.com), | 8 | * Hartmut Penner (hp@de.ibm.com), |
9 | * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), | 9 | * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), |
10 | * Heiko Carstens <heiko.carstens@de.ibm.com> | ||
10 | */ | 11 | */ |
11 | 12 | ||
12 | #include <linux/sys.h> | 13 | #include <linux/sys.h> |
@@ -49,9 +50,9 @@ SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC | |||
49 | SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP | 50 | SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP |
50 | SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE | 51 | SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE |
51 | 52 | ||
52 | _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ | 53 | _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING | \ |
53 | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) | 54 | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) |
54 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED) | 55 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING) |
55 | 56 | ||
56 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER | 57 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER |
57 | STACK_SIZE = 1 << STACK_SHIFT | 58 | STACK_SIZE = 1 << STACK_SHIFT |
@@ -121,7 +122,11 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
121 | bz BASED(stack_overflow) | 122 | bz BASED(stack_overflow) |
122 | 3: | 123 | 3: |
123 | #endif | 124 | #endif |
124 | 2: s %r15,BASED(.Lc_spsize) # make room for registers & psw | 125 | 2: |
126 | .endm | ||
127 | |||
128 | .macro CREATE_STACK_FRAME psworg,savearea | ||
129 | s %r15,BASED(.Lc_spsize) # make room for registers & psw | ||
125 | mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack | 130 | mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack |
126 | la %r12,\psworg | 131 | la %r12,\psworg |
127 | st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 | 132 | st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 |
@@ -161,6 +166,13 @@ __switch_to_base: | |||
161 | be __switch_to_noper-__switch_to_base(%r1) # we got away w/o bashing TLB's | 166 | be __switch_to_noper-__switch_to_base(%r1) # we got away w/o bashing TLB's |
162 | lctl %c9,%c11,__THREAD_per(%r3) # Nope we didn't | 167 | lctl %c9,%c11,__THREAD_per(%r3) # Nope we didn't |
163 | __switch_to_noper: | 168 | __switch_to_noper: |
169 | l %r4,__THREAD_info(%r2) # get thread_info of prev | ||
170 | tm __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending? | ||
171 | bz __switch_to_no_mcck-__switch_to_base(%r1) | ||
172 | ni __TI_flags+3(%r4),255-_TIF_MCCK_PENDING # clear flag in prev | ||
173 | l %r4,__THREAD_info(%r3) # get thread_info of next | ||
174 | oi __TI_flags+3(%r4),_TIF_MCCK_PENDING # set it in next | ||
175 | __switch_to_no_mcck: | ||
164 | stm %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task | 176 | stm %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task |
165 | st %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp | 177 | st %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp |
166 | l %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp | 178 | l %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp |
@@ -185,6 +197,7 @@ system_call: | |||
185 | sysc_saveall: | 197 | sysc_saveall: |
186 | SAVE_ALL_BASE __LC_SAVE_AREA | 198 | SAVE_ALL_BASE __LC_SAVE_AREA |
187 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 | 199 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 |
200 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | ||
188 | lh %r7,0x8a # get svc number from lowcore | 201 | lh %r7,0x8a # get svc number from lowcore |
189 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 202 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
190 | sysc_vtime: | 203 | sysc_vtime: |
@@ -234,6 +247,8 @@ sysc_work_loop: | |||
234 | # One of the work bits is on. Find out which one. | 247 | # One of the work bits is on. Find out which one. |
235 | # | 248 | # |
236 | sysc_work: | 249 | sysc_work: |
250 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING | ||
251 | bo BASED(sysc_mcck_pending) | ||
237 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | 252 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED |
238 | bo BASED(sysc_reschedule) | 253 | bo BASED(sysc_reschedule) |
239 | tm __TI_flags+3(%r9),_TIF_SIGPENDING | 254 | tm __TI_flags+3(%r9),_TIF_SIGPENDING |
@@ -253,6 +268,14 @@ sysc_reschedule: | |||
253 | br %r1 # call scheduler | 268 | br %r1 # call scheduler |
254 | 269 | ||
255 | # | 270 | # |
271 | # _TIF_MCCK_PENDING is set, call handler | ||
272 | # | ||
273 | sysc_mcck_pending: | ||
274 | l %r1,BASED(.Ls390_handle_mcck) | ||
275 | la %r14,BASED(sysc_work_loop) | ||
276 | br %r1 # TIF bit will be cleared by handler | ||
277 | |||
278 | # | ||
256 | # _TIF_SIGPENDING is set, call do_signal | 279 | # _TIF_SIGPENDING is set, call do_signal |
257 | # | 280 | # |
258 | sysc_sigpending: | 281 | sysc_sigpending: |
@@ -430,6 +453,7 @@ pgm_check_handler: | |||
430 | tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception | 453 | tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception |
431 | bnz BASED(pgm_per) # got per exception -> special case | 454 | bnz BASED(pgm_per) # got per exception -> special case |
432 | SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 | 455 | SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 |
456 | CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA | ||
433 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 457 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
434 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 458 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
435 | bz BASED(pgm_no_vtime) | 459 | bz BASED(pgm_no_vtime) |
@@ -468,6 +492,7 @@ pgm_per: | |||
468 | # | 492 | # |
469 | pgm_per_std: | 493 | pgm_per_std: |
470 | SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 | 494 | SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 |
495 | CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA | ||
471 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 496 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
472 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 497 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
473 | bz BASED(pgm_no_vtime2) | 498 | bz BASED(pgm_no_vtime2) |
@@ -493,6 +518,7 @@ pgm_no_vtime2: | |||
493 | # | 518 | # |
494 | pgm_svcper: | 519 | pgm_svcper: |
495 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 | 520 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 |
521 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | ||
496 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 522 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
497 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 523 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
498 | bz BASED(pgm_no_vtime3) | 524 | bz BASED(pgm_no_vtime3) |
@@ -521,6 +547,7 @@ io_int_handler: | |||
521 | stck __LC_INT_CLOCK | 547 | stck __LC_INT_CLOCK |
522 | SAVE_ALL_BASE __LC_SAVE_AREA+16 | 548 | SAVE_ALL_BASE __LC_SAVE_AREA+16 |
523 | SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+16,0 | 549 | SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+16,0 |
550 | CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 | ||
524 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 551 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
525 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 552 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
526 | bz BASED(io_no_vtime) | 553 | bz BASED(io_no_vtime) |
@@ -578,9 +605,11 @@ io_work: | |||
578 | lr %r15,%r1 | 605 | lr %r15,%r1 |
579 | # | 606 | # |
580 | # One of the work bits is on. Find out which one. | 607 | # One of the work bits is on. Find out which one. |
581 | # Checked are: _TIF_SIGPENDING and _TIF_NEED_RESCHED | 608 | # Checked are: _TIF_SIGPENDING, _TIF_NEED_RESCHED and _TIF_MCCK_PENDING |
582 | # | 609 | # |
583 | io_work_loop: | 610 | io_work_loop: |
611 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING | ||
612 | bo BASED(io_mcck_pending) | ||
584 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | 613 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED |
585 | bo BASED(io_reschedule) | 614 | bo BASED(io_reschedule) |
586 | tm __TI_flags+3(%r9),_TIF_SIGPENDING | 615 | tm __TI_flags+3(%r9),_TIF_SIGPENDING |
@@ -588,6 +617,14 @@ io_work_loop: | |||
588 | b BASED(io_leave) | 617 | b BASED(io_leave) |
589 | 618 | ||
590 | # | 619 | # |
620 | # _TIF_MCCK_PENDING is set, call handler | ||
621 | # | ||
622 | io_mcck_pending: | ||
623 | l %r1,BASED(.Ls390_handle_mcck) | ||
624 | l %r14,BASED(io_work_loop) | ||
625 | br %r1 # TIF bit will be cleared by handler | ||
626 | |||
627 | # | ||
591 | # _TIF_NEED_RESCHED is set, call schedule | 628 | # _TIF_NEED_RESCHED is set, call schedule |
592 | # | 629 | # |
593 | io_reschedule: | 630 | io_reschedule: |
@@ -621,6 +658,7 @@ ext_int_handler: | |||
621 | stck __LC_INT_CLOCK | 658 | stck __LC_INT_CLOCK |
622 | SAVE_ALL_BASE __LC_SAVE_AREA+16 | 659 | SAVE_ALL_BASE __LC_SAVE_AREA+16 |
623 | SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16,0 | 660 | SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16,0 |
661 | CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 | ||
624 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 662 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
625 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 663 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
626 | bz BASED(ext_no_vtime) | 664 | bz BASED(ext_no_vtime) |
@@ -642,19 +680,62 @@ ext_no_vtime: | |||
642 | 680 | ||
643 | .globl mcck_int_handler | 681 | .globl mcck_int_handler |
644 | mcck_int_handler: | 682 | mcck_int_handler: |
645 | STORE_TIMER __LC_ASYNC_ENTER_TIMER | 683 | spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer |
684 | lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs | ||
646 | SAVE_ALL_BASE __LC_SAVE_AREA+32 | 685 | SAVE_ALL_BASE __LC_SAVE_AREA+32 |
647 | SAVE_ALL __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32,0 | 686 | la %r12,__LC_MCK_OLD_PSW |
687 | tm __LC_MCCK_CODE,0x80 # system damage? | ||
688 | bo BASED(mcck_int_main) # yes -> rest of mcck code invalid | ||
689 | tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? | ||
690 | bo BASED(0f) | ||
691 | spt __LC_LAST_UPDATE_TIMER # revalidate cpu timer | ||
648 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 692 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
649 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 693 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER |
694 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | ||
695 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_EXIT_TIMER | ||
696 | 0: tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? | ||
697 | bno BASED(mcck_no_vtime) # no -> skip cleanup critical | ||
698 | tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ? | ||
650 | bz BASED(mcck_no_vtime) | 699 | bz BASED(mcck_no_vtime) |
651 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER | 700 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER |
652 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 701 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
653 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER | 702 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER |
654 | mcck_no_vtime: | 703 | mcck_no_vtime: |
655 | #endif | 704 | #endif |
705 | 0: | ||
706 | tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? | ||
707 | bno BASED(mcck_int_main) # no -> skip cleanup critical | ||
708 | tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit | ||
709 | bnz BASED(mcck_int_main) # from user -> load async stack | ||
710 | clc __LC_MCK_OLD_PSW+4(4),BASED(.Lcritical_end) | ||
711 | bhe BASED(mcck_int_main) | ||
712 | clc __LC_MCK_OLD_PSW+4(4),BASED(.Lcritical_start) | ||
713 | bl BASED(mcck_int_main) | ||
714 | l %r14,BASED(.Lcleanup_critical) | ||
715 | basr %r14,%r14 | ||
716 | mcck_int_main: | ||
717 | l %r14,__LC_PANIC_STACK # are we already on the panic stack? | ||
718 | slr %r14,%r15 | ||
719 | sra %r14,PAGE_SHIFT | ||
720 | be BASED(0f) | ||
721 | l %r15,__LC_PANIC_STACK # load panic stack | ||
722 | 0: CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32 | ||
723 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | ||
724 | la %r2,SP_PTREGS(%r15) # load pt_regs | ||
656 | l %r1,BASED(.Ls390_mcck) | 725 | l %r1,BASED(.Ls390_mcck) |
657 | basr %r14,%r1 # call machine check handler | 726 | basr %r14,%r1 # call machine check handler |
727 | tm SP_PSW+1(%r15),0x01 # returning to user ? | ||
728 | bno BASED(mcck_return) | ||
729 | l %r1,__LC_KERNEL_STACK # switch to kernel stack | ||
730 | s %r1,BASED(.Lc_spsize) | ||
731 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) | ||
732 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain | ||
733 | lr %r15,%r1 | ||
734 | stosm __SF_EMPTY(%r15),0x04 # turn dat on | ||
735 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING | ||
736 | bno BASED(mcck_return) | ||
737 | l %r1,BASED(.Ls390_handle_mcck) | ||
738 | basr %r14,%r1 # call machine check handler | ||
658 | mcck_return: | 739 | mcck_return: |
659 | RESTORE_ALL 0 | 740 | RESTORE_ALL 0 |
660 | 741 | ||
@@ -742,7 +823,7 @@ cleanup_critical: | |||
742 | clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop) | 823 | clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop) |
743 | bl BASED(0f) | 824 | bl BASED(0f) |
744 | clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop+4) | 825 | clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop+4) |
745 | bl BASED(cleanup_sysc_leave) | 826 | bl BASED(cleanup_sysc_return) |
746 | 0: | 827 | 0: |
747 | br %r14 | 828 | br %r14 |
748 | 829 | ||
@@ -760,6 +841,7 @@ cleanup_system_call: | |||
760 | mvc __LC_SAVE_AREA(16),__LC_SAVE_AREA+16 | 841 | mvc __LC_SAVE_AREA(16),__LC_SAVE_AREA+16 |
761 | 0: st %r13,__LC_SAVE_AREA+20 | 842 | 0: st %r13,__LC_SAVE_AREA+20 |
762 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 | 843 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 |
844 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | ||
763 | st %r15,__LC_SAVE_AREA+28 | 845 | st %r15,__LC_SAVE_AREA+28 |
764 | lh %r7,0x8a | 846 | lh %r7,0x8a |
765 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 847 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
@@ -834,6 +916,8 @@ cleanup_sysc_leave_insn: | |||
834 | * Symbol constants | 916 | * Symbol constants |
835 | */ | 917 | */ |
836 | .Ls390_mcck: .long s390_do_machine_check | 918 | .Ls390_mcck: .long s390_do_machine_check |
919 | .Ls390_handle_mcck: | ||
920 | .long s390_handle_mcck | ||
837 | .Ldo_IRQ: .long do_IRQ | 921 | .Ldo_IRQ: .long do_IRQ |
838 | .Ldo_extint: .long do_extint | 922 | .Ldo_extint: .long do_extint |
839 | .Ldo_signal: .long do_signal | 923 | .Ldo_signal: .long do_signal |
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 51527ab8c8f9..57ca75d0ad7f 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
@@ -7,6 +7,7 @@ | |||
7 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), | 7 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), |
8 | * Hartmut Penner (hp@de.ibm.com), | 8 | * Hartmut Penner (hp@de.ibm.com), |
9 | * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), | 9 | * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), |
10 | * Heiko Carstens <heiko.carstens@de.ibm.com> | ||
10 | */ | 11 | */ |
11 | 12 | ||
12 | #include <linux/sys.h> | 13 | #include <linux/sys.h> |
@@ -52,9 +53,9 @@ SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE | |||
52 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER | 53 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER |
53 | STACK_SIZE = 1 << STACK_SHIFT | 54 | STACK_SIZE = 1 << STACK_SHIFT |
54 | 55 | ||
55 | _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ | 56 | _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING | \ |
56 | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) | 57 | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) |
57 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED) | 58 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING) |
58 | 59 | ||
59 | #define BASED(name) name-system_call(%r13) | 60 | #define BASED(name) name-system_call(%r13) |
60 | 61 | ||
@@ -114,7 +115,11 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED) | |||
114 | jz stack_overflow | 115 | jz stack_overflow |
115 | 3: | 116 | 3: |
116 | #endif | 117 | #endif |
117 | 2: aghi %r15,-SP_SIZE # make room for registers & psw | 118 | 2: |
119 | .endm | ||
120 | |||
121 | .macro CREATE_STACK_FRAME psworg,savearea | ||
122 | aghi %r15,-SP_SIZE # make room for registers & psw | ||
118 | mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack | 123 | mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack |
119 | la %r12,\psworg | 124 | la %r12,\psworg |
120 | stg %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 | 125 | stg %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 |
@@ -152,6 +157,13 @@ __switch_to: | |||
152 | je __switch_to_noper # we got away without bashing TLB's | 157 | je __switch_to_noper # we got away without bashing TLB's |
153 | lctlg %c9,%c11,__THREAD_per(%r3) # Nope we didn't | 158 | lctlg %c9,%c11,__THREAD_per(%r3) # Nope we didn't |
154 | __switch_to_noper: | 159 | __switch_to_noper: |
160 | lg %r4,__THREAD_info(%r2) # get thread_info of prev | ||
161 | tm __TI_flags+7(%r4),_TIF_MCCK_PENDING # machine check pending? | ||
162 | jz __switch_to_no_mcck | ||
163 | ni __TI_flags+7(%r4),255-_TIF_MCCK_PENDING # clear flag in prev | ||
164 | lg %r4,__THREAD_info(%r3) # get thread_info of next | ||
165 | oi __TI_flags+7(%r4),_TIF_MCCK_PENDING # set it in next | ||
166 | __switch_to_no_mcck: | ||
155 | stmg %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task | 167 | stmg %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task |
156 | stg %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp | 168 | stg %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp |
157 | lg %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp | 169 | lg %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp |
@@ -176,6 +188,7 @@ system_call: | |||
176 | sysc_saveall: | 188 | sysc_saveall: |
177 | SAVE_ALL_BASE __LC_SAVE_AREA | 189 | SAVE_ALL_BASE __LC_SAVE_AREA |
178 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 | 190 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 |
191 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | ||
179 | llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore | 192 | llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore |
180 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 193 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
181 | sysc_vtime: | 194 | sysc_vtime: |
@@ -232,6 +245,8 @@ sysc_work_loop: | |||
232 | # One of the work bits is on. Find out which one. | 245 | # One of the work bits is on. Find out which one. |
233 | # | 246 | # |
234 | sysc_work: | 247 | sysc_work: |
248 | tm __TI_flags+7(%r9),_TIF_MCCK_PENDING | ||
249 | jo sysc_mcck_pending | ||
235 | tm __TI_flags+7(%r9),_TIF_NEED_RESCHED | 250 | tm __TI_flags+7(%r9),_TIF_NEED_RESCHED |
236 | jo sysc_reschedule | 251 | jo sysc_reschedule |
237 | tm __TI_flags+7(%r9),_TIF_SIGPENDING | 252 | tm __TI_flags+7(%r9),_TIF_SIGPENDING |
@@ -250,6 +265,13 @@ sysc_reschedule: | |||
250 | jg schedule # return point is sysc_return | 265 | jg schedule # return point is sysc_return |
251 | 266 | ||
252 | # | 267 | # |
268 | # _TIF_MCCK_PENDING is set, call handler | ||
269 | # | ||
270 | sysc_mcck_pending: | ||
271 | larl %r14,sysc_work_loop | ||
272 | jg s390_handle_mcck # TIF bit will be cleared by handler | ||
273 | |||
274 | # | ||
253 | # _TIF_SIGPENDING is set, call do_signal | 275 | # _TIF_SIGPENDING is set, call do_signal |
254 | # | 276 | # |
255 | sysc_sigpending: | 277 | sysc_sigpending: |
@@ -474,6 +496,7 @@ pgm_check_handler: | |||
474 | tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception | 496 | tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception |
475 | jnz pgm_per # got per exception -> special case | 497 | jnz pgm_per # got per exception -> special case |
476 | SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 | 498 | SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 |
499 | CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA | ||
477 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 500 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
478 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 501 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
479 | jz pgm_no_vtime | 502 | jz pgm_no_vtime |
@@ -512,6 +535,7 @@ pgm_per: | |||
512 | # | 535 | # |
513 | pgm_per_std: | 536 | pgm_per_std: |
514 | SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 | 537 | SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 |
538 | CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA | ||
515 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 539 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
516 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 540 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
517 | jz pgm_no_vtime2 | 541 | jz pgm_no_vtime2 |
@@ -537,6 +561,7 @@ pgm_no_vtime2: | |||
537 | # | 561 | # |
538 | pgm_svcper: | 562 | pgm_svcper: |
539 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 | 563 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 |
564 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | ||
540 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 565 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
541 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 566 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
542 | jz pgm_no_vtime3 | 567 | jz pgm_no_vtime3 |
@@ -564,6 +589,7 @@ io_int_handler: | |||
564 | stck __LC_INT_CLOCK | 589 | stck __LC_INT_CLOCK |
565 | SAVE_ALL_BASE __LC_SAVE_AREA+32 | 590 | SAVE_ALL_BASE __LC_SAVE_AREA+32 |
566 | SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+32,0 | 591 | SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+32,0 |
592 | CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+32 | ||
567 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 593 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
568 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 594 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
569 | jz io_no_vtime | 595 | jz io_no_vtime |
@@ -621,9 +647,11 @@ io_work: | |||
621 | lgr %r15,%r1 | 647 | lgr %r15,%r1 |
622 | # | 648 | # |
623 | # One of the work bits is on. Find out which one. | 649 | # One of the work bits is on. Find out which one. |
624 | # Checked are: _TIF_SIGPENDING and _TIF_NEED_RESCHED | 650 | # Checked are: _TIF_SIGPENDING, _TIF_NEED_RESCHED and _TIF_MCCK_PENDING |
625 | # | 651 | # |
626 | io_work_loop: | 652 | io_work_loop: |
653 | tm __TI_flags+7(%r9),_TIF_MCCK_PENDING | ||
654 | jo io_mcck_pending | ||
627 | tm __TI_flags+7(%r9),_TIF_NEED_RESCHED | 655 | tm __TI_flags+7(%r9),_TIF_NEED_RESCHED |
628 | jo io_reschedule | 656 | jo io_reschedule |
629 | tm __TI_flags+7(%r9),_TIF_SIGPENDING | 657 | tm __TI_flags+7(%r9),_TIF_SIGPENDING |
@@ -631,6 +659,13 @@ io_work_loop: | |||
631 | j io_leave | 659 | j io_leave |
632 | 660 | ||
633 | # | 661 | # |
662 | # _TIF_MCCK_PENDING is set, call handler | ||
663 | # | ||
664 | io_mcck_pending: | ||
665 | larl %r14,io_work_loop | ||
666 | jg s390_handle_mcck # TIF bit will be cleared by handler | ||
667 | |||
668 | # | ||
634 | # _TIF_NEED_RESCHED is set, call schedule | 669 | # _TIF_NEED_RESCHED is set, call schedule |
635 | # | 670 | # |
636 | io_reschedule: | 671 | io_reschedule: |
@@ -661,6 +696,7 @@ ext_int_handler: | |||
661 | stck __LC_INT_CLOCK | 696 | stck __LC_INT_CLOCK |
662 | SAVE_ALL_BASE __LC_SAVE_AREA+32 | 697 | SAVE_ALL_BASE __LC_SAVE_AREA+32 |
663 | SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32,0 | 698 | SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32,0 |
699 | CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32 | ||
664 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 700 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
665 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 701 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
666 | jz ext_no_vtime | 702 | jz ext_no_vtime |
@@ -680,18 +716,60 @@ ext_no_vtime: | |||
680 | */ | 716 | */ |
681 | .globl mcck_int_handler | 717 | .globl mcck_int_handler |
682 | mcck_int_handler: | 718 | mcck_int_handler: |
683 | STORE_TIMER __LC_ASYNC_ENTER_TIMER | 719 | la %r1,4095 # revalidate r1 |
720 | spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer | ||
721 | lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs | ||
684 | SAVE_ALL_BASE __LC_SAVE_AREA+64 | 722 | SAVE_ALL_BASE __LC_SAVE_AREA+64 |
685 | SAVE_ALL __LC_MCK_OLD_PSW,__LC_SAVE_AREA+64,0 | 723 | la %r12,__LC_MCK_OLD_PSW |
724 | tm __LC_MCCK_CODE,0x80 # system damage? | ||
725 | jo mcck_int_main # yes -> rest of mcck code invalid | ||
726 | tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? | ||
727 | jo 0f | ||
728 | spt __LC_LAST_UPDATE_TIMER | ||
686 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 729 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
687 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 730 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER |
731 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | ||
732 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_EXIT_TIMER | ||
733 | 0: tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? | ||
734 | jno mcck_no_vtime # no -> no timer update | ||
735 | tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ? | ||
688 | jz mcck_no_vtime | 736 | jz mcck_no_vtime |
689 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER | 737 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER |
690 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 738 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
691 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER | 739 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER |
692 | mcck_no_vtime: | 740 | mcck_no_vtime: |
693 | #endif | 741 | #endif |
694 | brasl %r14,s390_do_machine_check | 742 | 0: |
743 | tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? | ||
744 | jno mcck_int_main # no -> skip cleanup critical | ||
745 | tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit | ||
746 | jnz mcck_int_main # from user -> load kernel stack | ||
747 | clc __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_end) | ||
748 | jhe mcck_int_main | ||
749 | clc __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_start) | ||
750 | jl mcck_int_main | ||
751 | brasl %r14,cleanup_critical | ||
752 | mcck_int_main: | ||
753 | lg %r14,__LC_PANIC_STACK # are we already on the panic stack? | ||
754 | slgr %r14,%r15 | ||
755 | srag %r14,%r14,PAGE_SHIFT | ||
756 | jz 0f | ||
757 | lg %r15,__LC_PANIC_STACK # load panic stack | ||
758 | 0: CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+64 | ||
759 | lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct | ||
760 | la %r2,SP_PTREGS(%r15) # load pt_regs | ||
761 | brasl %r14,s390_do_machine_check | ||
762 | tm SP_PSW+1(%r15),0x01 # returning to user ? | ||
763 | jno mcck_return | ||
764 | lg %r1,__LC_KERNEL_STACK # switch to kernel stack | ||
765 | aghi %r1,-SP_SIZE | ||
766 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) | ||
767 | xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain | ||
768 | lgr %r15,%r1 | ||
769 | stosm __SF_EMPTY(%r15),0x04 # turn dat on | ||
770 | tm __TI_flags+7(%r9),_TIF_MCCK_PENDING | ||
771 | jno mcck_return | ||
772 | brasl %r14,s390_handle_mcck | ||
695 | mcck_return: | 773 | mcck_return: |
696 | RESTORE_ALL 0 | 774 | RESTORE_ALL 0 |
697 | 775 | ||
@@ -775,7 +853,7 @@ cleanup_critical: | |||
775 | clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop) | 853 | clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop) |
776 | jl 0f | 854 | jl 0f |
777 | clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop+8) | 855 | clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop+8) |
778 | jl cleanup_sysc_leave | 856 | jl cleanup_sysc_return |
779 | 0: | 857 | 0: |
780 | br %r14 | 858 | br %r14 |
781 | 859 | ||
@@ -793,6 +871,7 @@ cleanup_system_call: | |||
793 | mvc __LC_SAVE_AREA(32),__LC_SAVE_AREA+32 | 871 | mvc __LC_SAVE_AREA(32),__LC_SAVE_AREA+32 |
794 | 0: stg %r13,__LC_SAVE_AREA+40 | 872 | 0: stg %r13,__LC_SAVE_AREA+40 |
795 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 | 873 | SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 |
874 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | ||
796 | stg %r15,__LC_SAVE_AREA+56 | 875 | stg %r15,__LC_SAVE_AREA+56 |
797 | llgh %r7,__LC_SVC_INT_CODE | 876 | llgh %r7,__LC_SVC_INT_CODE |
798 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 877 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c new file mode 100644 index 000000000000..2721c3a32b84 --- /dev/null +++ b/arch/s390/kernel/machine_kexec.c | |||
@@ -0,0 +1,98 @@ | |||
1 | /* | ||
2 | * arch/s390/kernel/machine_kexec.c | ||
3 | * | ||
4 | * (C) Copyright IBM Corp. 2005 | ||
5 | * | ||
6 | * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com> | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * s390_machine_kexec.c - handle the transition of Linux booting another kernel | ||
12 | * on the S390 architecture. | ||
13 | */ | ||
14 | |||
15 | #include <asm/cio.h> | ||
16 | #include <asm/setup.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/mm.h> | ||
19 | #include <linux/kexec.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <asm/pgtable.h> | ||
22 | #include <asm/pgalloc.h> | ||
23 | #include <asm/system.h> | ||
24 | |||
25 | static void kexec_halt_all_cpus(void *); | ||
26 | |||
27 | typedef void (*relocate_kernel_t) (kimage_entry_t *, unsigned long); | ||
28 | |||
29 | const extern unsigned char relocate_kernel[]; | ||
30 | const extern unsigned long long relocate_kernel_len; | ||
31 | |||
32 | int | ||
33 | machine_kexec_prepare(struct kimage *image) | ||
34 | { | ||
35 | unsigned long reboot_code_buffer; | ||
36 | |||
37 | /* We don't support anything but the default image type for now. */ | ||
38 | if (image->type != KEXEC_TYPE_DEFAULT) | ||
39 | return -EINVAL; | ||
40 | |||
41 | /* Get the destination where the assembler code should be copied to.*/ | ||
42 | reboot_code_buffer = page_to_pfn(image->control_code_page)<<PAGE_SHIFT; | ||
43 | |||
44 | /* Then copy it */ | ||
45 | memcpy((void *) reboot_code_buffer, relocate_kernel, | ||
46 | relocate_kernel_len); | ||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | void | ||
51 | machine_kexec_cleanup(struct kimage *image) | ||
52 | { | ||
53 | } | ||
54 | |||
55 | void | ||
56 | machine_shutdown(void) | ||
57 | { | ||
58 | printk(KERN_INFO "kexec: machine_shutdown called\n"); | ||
59 | } | ||
60 | |||
61 | NORET_TYPE void | ||
62 | machine_kexec(struct kimage *image) | ||
63 | { | ||
64 | clear_all_subchannels(); | ||
65 | |||
66 | /* Disable lowcore protection */ | ||
67 | ctl_clear_bit(0,28); | ||
68 | |||
69 | on_each_cpu(kexec_halt_all_cpus, image, 0, 0); | ||
70 | for (;;); | ||
71 | } | ||
72 | |||
73 | static void | ||
74 | kexec_halt_all_cpus(void *kernel_image) | ||
75 | { | ||
76 | static atomic_t cpuid = ATOMIC_INIT(-1); | ||
77 | int cpu; | ||
78 | struct kimage *image; | ||
79 | relocate_kernel_t data_mover; | ||
80 | |||
81 | if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid)) | ||
82 | signal_processor(smp_processor_id(), sigp_stop); | ||
83 | |||
84 | /* Wait for all other cpus to enter stopped state */ | ||
85 | for_each_online_cpu(cpu) { | ||
86 | if (cpu == smp_processor_id()) | ||
87 | continue; | ||
88 | while (!smp_cpu_not_running(cpu)) | ||
89 | cpu_relax(); | ||
90 | } | ||
91 | |||
92 | image = (struct kimage *) kernel_image; | ||
93 | data_mover = (relocate_kernel_t) | ||
94 | (page_to_pfn(image->control_code_page) << PAGE_SHIFT); | ||
95 | |||
96 | /* Call the moving routine */ | ||
97 | (*data_mover) (&image->head, image->start); | ||
98 | } | ||
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 7aea25d6e300..9f3dff6c0b72 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
@@ -91,13 +91,12 @@ void do_monitor_call(struct pt_regs *regs, long interruption_code) | |||
91 | (void *)(long) smp_processor_id()); | 91 | (void *)(long) smp_processor_id()); |
92 | } | 92 | } |
93 | 93 | ||
94 | extern void s390_handle_mcck(void); | ||
94 | /* | 95 | /* |
95 | * The idle loop on a S390... | 96 | * The idle loop on a S390... |
96 | */ | 97 | */ |
97 | void default_idle(void) | 98 | void default_idle(void) |
98 | { | 99 | { |
99 | psw_t wait_psw; | ||
100 | unsigned long reg; | ||
101 | int cpu, rc; | 100 | int cpu, rc; |
102 | 101 | ||
103 | local_irq_disable(); | 102 | local_irq_disable(); |
@@ -125,38 +124,17 @@ void default_idle(void) | |||
125 | cpu_die(); | 124 | cpu_die(); |
126 | #endif | 125 | #endif |
127 | 126 | ||
128 | /* | 127 | local_mcck_disable(); |
129 | * Wait for external, I/O or machine check interrupt and | 128 | if (test_thread_flag(TIF_MCCK_PENDING)) { |
130 | * switch off machine check bit after the wait has ended. | 129 | local_mcck_enable(); |
131 | */ | 130 | local_irq_enable(); |
132 | wait_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK | PSW_MASK_WAIT | | 131 | s390_handle_mcck(); |
133 | PSW_MASK_IO | PSW_MASK_EXT; | 132 | return; |
134 | #ifndef CONFIG_ARCH_S390X | 133 | } |
135 | asm volatile ( | 134 | |
136 | " basr %0,0\n" | 135 | /* Wait for external, I/O or machine check interrupt. */ |
137 | "0: la %0,1f-0b(%0)\n" | 136 | __load_psw_mask(PSW_KERNEL_BITS | PSW_MASK_WAIT | |
138 | " st %0,4(%1)\n" | 137 | PSW_MASK_IO | PSW_MASK_EXT); |
139 | " oi 4(%1),0x80\n" | ||
140 | " lpsw 0(%1)\n" | ||
141 | "1: la %0,2f-1b(%0)\n" | ||
142 | " st %0,4(%1)\n" | ||
143 | " oi 4(%1),0x80\n" | ||
144 | " ni 1(%1),0xf9\n" | ||
145 | " lpsw 0(%1)\n" | ||
146 | "2:" | ||
147 | : "=&a" (reg) : "a" (&wait_psw) : "memory", "cc" ); | ||
148 | #else /* CONFIG_ARCH_S390X */ | ||
149 | asm volatile ( | ||
150 | " larl %0,0f\n" | ||
151 | " stg %0,8(%1)\n" | ||
152 | " lpswe 0(%1)\n" | ||
153 | "0: larl %0,1f\n" | ||
154 | " stg %0,8(%1)\n" | ||
155 | " ni 1(%1),0xf9\n" | ||
156 | " lpswe 0(%1)\n" | ||
157 | "1:" | ||
158 | : "=&a" (reg) : "a" (&wait_psw) : "memory", "cc" ); | ||
159 | #endif /* CONFIG_ARCH_S390X */ | ||
160 | } | 138 | } |
161 | 139 | ||
162 | void cpu_idle(void) | 140 | void cpu_idle(void) |
diff --git a/arch/s390/kernel/relocate_kernel.S b/arch/s390/kernel/relocate_kernel.S new file mode 100644 index 000000000000..d5e4a62fbb79 --- /dev/null +++ b/arch/s390/kernel/relocate_kernel.S | |||
@@ -0,0 +1,81 @@ | |||
1 | /* | ||
2 | * arch/s390/kernel/relocate_kernel.S | ||
3 | * | ||
4 | * (C) Copyright IBM Corp. 2005 | ||
5 | * | ||
6 | * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com> | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * moves the new kernel to its destination... | ||
12 | * %r2 = pointer to first kimage_entry_t | ||
13 | * %r3 = start address - where to jump to after the job is done... | ||
14 | * | ||
15 | * %r5 will be used as temp. storage | ||
16 | * %r6 holds the destination address | ||
17 | * %r7 = PAGE_SIZE | ||
18 | * %r8 holds the source address | ||
19 | * %r9 = PAGE_SIZE | ||
20 | * %r10 is a page mask | ||
21 | */ | ||
22 | |||
23 | .text | ||
24 | .globl relocate_kernel | ||
25 | relocate_kernel: | ||
26 | basr %r13,0 #base address | ||
27 | .base: | ||
28 | spx zero64-.base(%r13) #absolute addressing mode | ||
29 | stnsm sys_msk-.base(%r13),0xf8 #disable DAT and IRQ (external) | ||
30 | lhi %r10,-1 #preparing the mask | ||
31 | sll %r10,12 #shift it such that it becomes 0xf000 | ||
32 | .top: | ||
33 | lhi %r7,4096 #load PAGE_SIZE in r7 | ||
34 | lhi %r9,4096 #load PAGE_SIZE in r9 | ||
35 | l %r5,0(%r2) #read another word for indirection page | ||
36 | ahi %r2,4 #increment pointer | ||
37 | tml %r5,0x1 #is it a destination page? | ||
38 | je .indir_check #NO, goto "indir_check" | ||
39 | lr %r6,%r5 #r6 = r5 | ||
40 | nr %r6,%r10 #mask it out and... | ||
41 | j .top #...next iteration | ||
42 | .indir_check: | ||
43 | tml %r5,0x2 #is it a indirection page? | ||
44 | je .done_test #NO, goto "done_test" | ||
45 | nr %r5,%r10 #YES, mask out, | ||
46 | lr %r2,%r5 #move it into the right register, | ||
47 | j .top #and read next... | ||
48 | .done_test: | ||
49 | tml %r5,0x4 #is it the done indicator? | ||
50 | je .source_test #NO! Well, then it should be the source indicator... | ||
51 | j .done #ok, lets finish it here... | ||
52 | .source_test: | ||
53 | tml %r5,0x8 #it should be a source indicator... | ||
54 | je .top #NO, ignore it... | ||
55 | lr %r8,%r5 #r8 = r5 | ||
56 | nr %r8,%r10 #masking | ||
57 | 0: mvcle %r6,%r8,0x0 #copy PAGE_SIZE bytes from r8 to r6 - pad with 0 | ||
58 | jo 0b | ||
59 | j .top | ||
60 | .done: | ||
61 | sr %r0,%r0 #clear register r0 | ||
62 | la %r4,load_psw-.base(%r13) #load psw-address into the register | ||
63 | o %r3,4(%r4) #or load address into psw | ||
64 | st %r3,4(%r4) | ||
65 | mvc 0(8,%r0),0(%r4) #copy psw to absolute address 0 | ||
66 | sr %r1,%r1 #clear %r1 | ||
67 | sr %r2,%r2 #clear %r2 | ||
68 | sigp %r1,%r2,0x12 #set cpuid to zero | ||
69 | lpsw 0 #hopefully start new kernel... | ||
70 | |||
71 | .align 8 | ||
72 | zero64: | ||
73 | .quad 0 | ||
74 | load_psw: | ||
75 | .long 0x00080000,0x80000000 | ||
76 | sys_msk: | ||
77 | .quad 0 | ||
78 | relocate_kernel_end: | ||
79 | .globl relocate_kernel_len | ||
80 | relocate_kernel_len: | ||
81 | .quad relocate_kernel_end - relocate_kernel | ||
diff --git a/arch/s390/kernel/relocate_kernel64.S b/arch/s390/kernel/relocate_kernel64.S new file mode 100644 index 000000000000..96290cc4eb3c --- /dev/null +++ b/arch/s390/kernel/relocate_kernel64.S | |||
@@ -0,0 +1,82 @@ | |||
1 | /* | ||
2 | * arch/s390/kernel/relocate_kernel64.S | ||
3 | * | ||
4 | * (C) Copyright IBM Corp. 2005 | ||
5 | * | ||
6 | * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com> | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * moves the new kernel to its destination... | ||
12 | * %r2 = pointer to first kimage_entry_t | ||
13 | * %r3 = start address - where to jump to after the job is done... | ||
14 | * | ||
15 | * %r5 will be used as temp. storage | ||
16 | * %r6 holds the destination address | ||
17 | * %r7 = PAGE_SIZE | ||
18 | * %r8 holds the source address | ||
19 | * %r9 = PAGE_SIZE | ||
20 | * | ||
21 | * 0xf000 is a page_mask | ||
22 | */ | ||
23 | |||
24 | .text | ||
25 | .globl relocate_kernel | ||
26 | relocate_kernel: | ||
27 | basr %r13,0 #base address | ||
28 | .base: | ||
29 | spx zero64-.base(%r13) #absolute addressing mode | ||
30 | stnsm sys_msk-.base(%r13),0xf8 #disable DAT and IRQ (external) | ||
31 | .top: | ||
32 | lghi %r7,4096 #load PAGE_SIZE in r7 | ||
33 | lghi %r9,4096 #load PAGE_SIZE in r9 | ||
34 | lg %r5,0(%r2) #read another word for indirection page | ||
35 | aghi %r2,8 #increment pointer | ||
36 | tml %r5,0x1 #is it a destination page? | ||
37 | je .indir_check #NO, goto "indir_check" | ||
38 | lgr %r6,%r5 #r6 = r5 | ||
39 | nill %r6,0xf000 #mask it out and... | ||
40 | j .top #...next iteration | ||
41 | .indir_check: | ||
42 | tml %r5,0x2 #is it a indirection page? | ||
43 | je .done_test #NO, goto "done_test" | ||
44 | nill %r5,0xf000 #YES, mask out, | ||
45 | lgr %r2,%r5 #move it into the right register, | ||
46 | j .top #and read next... | ||
47 | .done_test: | ||
48 | tml %r5,0x4 #is it the done indicator? | ||
49 | je .source_test #NO! Well, then it should be the source indicator... | ||
50 | j .done #ok, lets finish it here... | ||
51 | .source_test: | ||
52 | tml %r5,0x8 #it should be a source indicator... | ||
53 | je .top #NO, ignore it... | ||
54 | lgr %r8,%r5 #r8 = r5 | ||
55 | nill %r8,0xf000 #masking | ||
56 | 0: mvcle %r6,%r8,0x0 #copy PAGE_SIZE bytes from r8 to r6 - pad with 0 | ||
57 | jo 0b | ||
58 | j .top | ||
59 | .done: | ||
60 | sgr %r0,%r0 #clear register r0 | ||
61 | la %r4,load_psw-.base(%r13) #load psw-address into the register | ||
62 | o %r3,4(%r4) #or load address into psw | ||
63 | st %r3,4(%r4) | ||
64 | mvc 0(8,%r0),0(%r4) #copy psw to absolute address 0 | ||
65 | sam31 #31 bit mode | ||
66 | sr %r1,%r1 #erase register r1 | ||
67 | sr %r2,%r2 #erase register r2 | ||
68 | sigp %r1,%r2,0x12 #set cpuid to zero | ||
69 | lpsw 0 #hopefully start new kernel... | ||
70 | |||
71 | .align 8 | ||
72 | zero64: | ||
73 | .quad 0 | ||
74 | load_psw: | ||
75 | .long 0x00080000,0x80000000 | ||
76 | sys_msk: | ||
77 | .quad 0 | ||
78 | relocate_kernel_end: | ||
79 | .globl relocate_kernel_len | ||
80 | relocate_kernel_len: | ||
81 | .quad relocate_kernel_end - relocate_kernel | ||
82 | |||
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index df83215beac3..b6d740ac0e6e 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -198,11 +198,11 @@ static void __init conmode_default(void) | |||
198 | char *ptr; | 198 | char *ptr; |
199 | 199 | ||
200 | if (MACHINE_IS_VM) { | 200 | if (MACHINE_IS_VM) { |
201 | __cpcmd("QUERY CONSOLE", query_buffer, 1024); | 201 | __cpcmd("QUERY CONSOLE", query_buffer, 1024, NULL); |
202 | console_devno = simple_strtoul(query_buffer + 5, NULL, 16); | 202 | console_devno = simple_strtoul(query_buffer + 5, NULL, 16); |
203 | ptr = strstr(query_buffer, "SUBCHANNEL ="); | 203 | ptr = strstr(query_buffer, "SUBCHANNEL ="); |
204 | console_irq = simple_strtoul(ptr + 13, NULL, 16); | 204 | console_irq = simple_strtoul(ptr + 13, NULL, 16); |
205 | __cpcmd("QUERY TERM", query_buffer, 1024); | 205 | __cpcmd("QUERY TERM", query_buffer, 1024, NULL); |
206 | ptr = strstr(query_buffer, "CONMODE"); | 206 | ptr = strstr(query_buffer, "CONMODE"); |
207 | /* | 207 | /* |
208 | * Set the conmode to 3215 so that the device recognition | 208 | * Set the conmode to 3215 so that the device recognition |
@@ -211,7 +211,7 @@ static void __init conmode_default(void) | |||
211 | * 3215 and the 3270 driver will try to access the console | 211 | * 3215 and the 3270 driver will try to access the console |
212 | * device (3215 as console and 3270 as normal tty). | 212 | * device (3215 as console and 3270 as normal tty). |
213 | */ | 213 | */ |
214 | __cpcmd("TERM CONMODE 3215", NULL, 0); | 214 | __cpcmd("TERM CONMODE 3215", NULL, 0, NULL); |
215 | if (ptr == NULL) { | 215 | if (ptr == NULL) { |
216 | #if defined(CONFIG_SCLP_CONSOLE) | 216 | #if defined(CONFIG_SCLP_CONSOLE) |
217 | SET_CONSOLE_SCLP; | 217 | SET_CONSOLE_SCLP; |
@@ -414,7 +414,8 @@ setup_lowcore(void) | |||
414 | lc->program_new_psw.mask = PSW_KERNEL_BITS; | 414 | lc->program_new_psw.mask = PSW_KERNEL_BITS; |
415 | lc->program_new_psw.addr = | 415 | lc->program_new_psw.addr = |
416 | PSW_ADDR_AMODE | (unsigned long)pgm_check_handler; | 416 | PSW_ADDR_AMODE | (unsigned long)pgm_check_handler; |
417 | lc->mcck_new_psw.mask = PSW_KERNEL_BITS; | 417 | lc->mcck_new_psw.mask = |
418 | PSW_KERNEL_BITS & ~PSW_MASK_MCHECK & ~PSW_MASK_DAT; | ||
418 | lc->mcck_new_psw.addr = | 419 | lc->mcck_new_psw.addr = |
419 | PSW_ADDR_AMODE | (unsigned long) mcck_int_handler; | 420 | PSW_ADDR_AMODE | (unsigned long) mcck_int_handler; |
420 | lc->io_new_psw.mask = PSW_KERNEL_BITS; | 421 | lc->io_new_psw.mask = PSW_KERNEL_BITS; |
@@ -424,12 +425,18 @@ setup_lowcore(void) | |||
424 | lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE; | 425 | lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE; |
425 | lc->async_stack = (unsigned long) | 426 | lc->async_stack = (unsigned long) |
426 | __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE; | 427 | __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE; |
427 | #ifdef CONFIG_CHECK_STACK | ||
428 | lc->panic_stack = (unsigned long) | 428 | lc->panic_stack = (unsigned long) |
429 | __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) + PAGE_SIZE; | 429 | __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) + PAGE_SIZE; |
430 | #endif | ||
431 | lc->current_task = (unsigned long) init_thread_union.thread_info.task; | 430 | lc->current_task = (unsigned long) init_thread_union.thread_info.task; |
432 | lc->thread_info = (unsigned long) &init_thread_union; | 431 | lc->thread_info = (unsigned long) &init_thread_union; |
432 | #ifndef CONFIG_ARCH_S390X | ||
433 | if (MACHINE_HAS_IEEE) { | ||
434 | lc->extended_save_area_addr = (__u32) | ||
435 | __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0); | ||
436 | /* enable extended save area */ | ||
437 | ctl_set_bit(14, 29); | ||
438 | } | ||
439 | #endif | ||
433 | #ifdef CONFIG_ARCH_S390X | 440 | #ifdef CONFIG_ARCH_S390X |
434 | if (MACHINE_HAS_DIAG44) | 441 | if (MACHINE_HAS_DIAG44) |
435 | lc->diag44_opcode = 0x83000044; | 442 | lc->diag44_opcode = 0x83000044; |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index fdfcf0488b49..642572a8e334 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -284,7 +284,7 @@ static void do_machine_restart(void * __unused) | |||
284 | * locks are always held disabled). | 284 | * locks are always held disabled). |
285 | */ | 285 | */ |
286 | if (MACHINE_IS_VM) | 286 | if (MACHINE_IS_VM) |
287 | cpcmd ("IPL", NULL, 0); | 287 | cpcmd ("IPL", NULL, 0, NULL); |
288 | else | 288 | else |
289 | reipl (0x10000 | S390_lowcore.ipl_device); | 289 | reipl (0x10000 | S390_lowcore.ipl_device); |
290 | } | 290 | } |
@@ -313,7 +313,7 @@ static void do_machine_halt(void * __unused) | |||
313 | if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid) == 0) { | 313 | if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid) == 0) { |
314 | smp_send_stop(); | 314 | smp_send_stop(); |
315 | if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0) | 315 | if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0) |
316 | cpcmd(vmhalt_cmd, NULL, 0); | 316 | cpcmd(vmhalt_cmd, NULL, 0, NULL); |
317 | signal_processor(smp_processor_id(), | 317 | signal_processor(smp_processor_id(), |
318 | sigp_stop_and_store_status); | 318 | sigp_stop_and_store_status); |
319 | } | 319 | } |
@@ -332,7 +332,7 @@ static void do_machine_power_off(void * __unused) | |||
332 | if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid) == 0) { | 332 | if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid) == 0) { |
333 | smp_send_stop(); | 333 | smp_send_stop(); |
334 | if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0) | 334 | if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0) |
335 | cpcmd(vmpoff_cmd, NULL, 0); | 335 | cpcmd(vmpoff_cmd, NULL, 0, NULL); |
336 | signal_processor(smp_processor_id(), | 336 | signal_processor(smp_processor_id(), |
337 | sigp_stop_and_store_status); | 337 | sigp_stop_and_store_status); |
338 | } | 338 | } |
@@ -679,12 +679,14 @@ __cpu_disable(void) | |||
679 | { | 679 | { |
680 | unsigned long flags; | 680 | unsigned long flags; |
681 | ec_creg_mask_parms cr_parms; | 681 | ec_creg_mask_parms cr_parms; |
682 | int cpu = smp_processor_id(); | ||
682 | 683 | ||
683 | spin_lock_irqsave(&smp_reserve_lock, flags); | 684 | spin_lock_irqsave(&smp_reserve_lock, flags); |
684 | if (smp_cpu_reserved[smp_processor_id()] != 0) { | 685 | if (smp_cpu_reserved[cpu] != 0) { |
685 | spin_unlock_irqrestore(&smp_reserve_lock, flags); | 686 | spin_unlock_irqrestore(&smp_reserve_lock, flags); |
686 | return -EBUSY; | 687 | return -EBUSY; |
687 | } | 688 | } |
689 | cpu_clear(cpu, cpu_online_map); | ||
688 | 690 | ||
689 | #ifdef CONFIG_PFAULT | 691 | #ifdef CONFIG_PFAULT |
690 | /* Disable pfault pseudo page faults on this cpu. */ | 692 | /* Disable pfault pseudo page faults on this cpu. */ |
@@ -771,13 +773,24 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
771 | 773 | ||
772 | *(lowcore_ptr[i]) = S390_lowcore; | 774 | *(lowcore_ptr[i]) = S390_lowcore; |
773 | lowcore_ptr[i]->async_stack = stack + (ASYNC_SIZE); | 775 | lowcore_ptr[i]->async_stack = stack + (ASYNC_SIZE); |
774 | #ifdef CONFIG_CHECK_STACK | ||
775 | stack = __get_free_pages(GFP_KERNEL,0); | 776 | stack = __get_free_pages(GFP_KERNEL,0); |
776 | if (stack == 0ULL) | 777 | if (stack == 0ULL) |
777 | panic("smp_boot_cpus failed to allocate memory\n"); | 778 | panic("smp_boot_cpus failed to allocate memory\n"); |
778 | lowcore_ptr[i]->panic_stack = stack + (PAGE_SIZE); | 779 | lowcore_ptr[i]->panic_stack = stack + (PAGE_SIZE); |
780 | #ifndef __s390x__ | ||
781 | if (MACHINE_HAS_IEEE) { | ||
782 | lowcore_ptr[i]->extended_save_area_addr = | ||
783 | (__u32) __get_free_pages(GFP_KERNEL,0); | ||
784 | if (lowcore_ptr[i]->extended_save_area_addr == 0) | ||
785 | panic("smp_boot_cpus failed to " | ||
786 | "allocate memory\n"); | ||
787 | } | ||
779 | #endif | 788 | #endif |
780 | } | 789 | } |
790 | #ifndef __s390x__ | ||
791 | if (MACHINE_HAS_IEEE) | ||
792 | ctl_set_bit(14, 29); /* enable extended save area */ | ||
793 | #endif | ||
781 | set_prefix((u32)(unsigned long) lowcore_ptr[smp_processor_id()]); | 794 | set_prefix((u32)(unsigned long) lowcore_ptr[smp_processor_id()]); |
782 | 795 | ||
783 | for_each_cpu(cpu) | 796 | for_each_cpu(cpu) |
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 515938628f82..a8668afb5f87 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S | |||
@@ -285,7 +285,7 @@ SYSCALL(sys_mq_timedsend,sys_mq_timedsend,compat_sys_mq_timedsend_wrapper) | |||
285 | SYSCALL(sys_mq_timedreceive,sys_mq_timedreceive,compat_sys_mq_timedreceive_wrapper) | 285 | SYSCALL(sys_mq_timedreceive,sys_mq_timedreceive,compat_sys_mq_timedreceive_wrapper) |
286 | SYSCALL(sys_mq_notify,sys_mq_notify,compat_sys_mq_notify_wrapper) /* 275 */ | 286 | SYSCALL(sys_mq_notify,sys_mq_notify,compat_sys_mq_notify_wrapper) /* 275 */ |
287 | SYSCALL(sys_mq_getsetattr,sys_mq_getsetattr,compat_sys_mq_getsetattr_wrapper) | 287 | SYSCALL(sys_mq_getsetattr,sys_mq_getsetattr,compat_sys_mq_getsetattr_wrapper) |
288 | NI_SYSCALL /* reserved for kexec */ | 288 | SYSCALL(sys_kexec_load,sys_kexec_load,compat_sys_kexec_load_wrapper) |
289 | SYSCALL(sys_add_key,sys_add_key,compat_sys_add_key_wrapper) | 289 | SYSCALL(sys_add_key,sys_add_key,compat_sys_add_key_wrapper) |
290 | SYSCALL(sys_request_key,sys_request_key,compat_sys_request_key_wrapper) | 290 | SYSCALL(sys_request_key,sys_request_key,compat_sys_request_key_wrapper) |
291 | SYSCALL(sys_keyctl,sys_keyctl,compat_sys_keyctl) /* 280 */ | 291 | SYSCALL(sys_keyctl,sys_keyctl,compat_sys_keyctl) /* 280 */ |
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index ca34b6f34b38..bc7b7be7acbe 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c | |||
@@ -735,7 +735,7 @@ void __init trap_init(void) | |||
735 | &ext_int_pfault); | 735 | &ext_int_pfault); |
736 | #endif | 736 | #endif |
737 | #ifndef CONFIG_ARCH_S390X | 737 | #ifndef CONFIG_ARCH_S390X |
738 | cpcmd("SET PAGEX ON", NULL, 0); | 738 | cpcmd("SET PAGEX ON", NULL, 0, NULL); |
739 | #endif | 739 | #endif |
740 | } | 740 | } |
741 | } | 741 | } |
diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index 648deed17e25..c5348108ca3c 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c | |||
@@ -576,8 +576,8 @@ segment_save(char *name) | |||
576 | segtype_string[seg->range[i].start & 0xff]); | 576 | segtype_string[seg->range[i].start & 0xff]); |
577 | } | 577 | } |
578 | sprintf(cmd2, "SAVESEG %s", name); | 578 | sprintf(cmd2, "SAVESEG %s", name); |
579 | cpcmd(cmd1, NULL, 0); | 579 | cpcmd(cmd1, NULL, 0, NULL); |
580 | cpcmd(cmd2, NULL, 0); | 580 | cpcmd(cmd2, NULL, 0, NULL); |
581 | spin_unlock(&dcss_lock); | 581 | spin_unlock(&dcss_lock); |
582 | } | 582 | } |
583 | 583 | ||
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c index cf15b4a8b517..c1b03f7c1daa 100644 --- a/arch/um/drivers/daemon_user.c +++ b/arch/um/drivers/daemon_user.c | |||
@@ -157,9 +157,9 @@ static void daemon_remove(void *data) | |||
157 | 157 | ||
158 | os_close_file(pri->fd); | 158 | os_close_file(pri->fd); |
159 | os_close_file(pri->control); | 159 | os_close_file(pri->control); |
160 | if(pri->data_addr != NULL) kfree(pri->data_addr); | 160 | kfree(pri->data_addr); |
161 | if(pri->ctl_addr != NULL) kfree(pri->ctl_addr); | 161 | kfree(pri->ctl_addr); |
162 | if(pri->local_addr != NULL) kfree(pri->local_addr); | 162 | kfree(pri->local_addr); |
163 | } | 163 | } |
164 | 164 | ||
165 | int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri) | 165 | int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri) |
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 0f59736db329..2bb4c4f5dec4 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
@@ -602,11 +602,26 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str, | |||
602 | return n; | 602 | return n; |
603 | } | 603 | } |
604 | 604 | ||
605 | int line_remove(struct line *lines, unsigned int num, char *str) | 605 | int line_id(char **str, int *start_out, int *end_out) |
606 | { | ||
607 | char *end; | ||
608 | int n; | ||
609 | |||
610 | n = simple_strtoul(*str, &end, 0); | ||
611 | if((*end != '\0') || (end == *str)) | ||
612 | return -1; | ||
613 | |||
614 | *str = end; | ||
615 | *start_out = n; | ||
616 | *end_out = n; | ||
617 | return n; | ||
618 | } | ||
619 | |||
620 | int line_remove(struct line *lines, unsigned int num, int n) | ||
606 | { | 621 | { |
607 | char config[sizeof("conxxxx=none\0")]; | 622 | char config[sizeof("conxxxx=none\0")]; |
608 | 623 | ||
609 | sprintf(config, "%s=none", str); | 624 | sprintf(config, "%d=none", n); |
610 | return !line_setup(lines, num, config, 0); | 625 | return !line_setup(lines, num, config, 0); |
611 | } | 626 | } |
612 | 627 | ||
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index d7c7adcc0a67..404de41a4f67 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c | |||
@@ -419,8 +419,9 @@ void mconsole_config(struct mc_request *req) | |||
419 | void mconsole_remove(struct mc_request *req) | 419 | void mconsole_remove(struct mc_request *req) |
420 | { | 420 | { |
421 | struct mc_device *dev; | 421 | struct mc_device *dev; |
422 | char *ptr = req->request.data; | 422 | char *ptr = req->request.data, *err_msg = ""; |
423 | int err; | 423 | char error[256]; |
424 | int err, start, end, n; | ||
424 | 425 | ||
425 | ptr += strlen("remove"); | 426 | ptr += strlen("remove"); |
426 | while(isspace(*ptr)) ptr++; | 427 | while(isspace(*ptr)) ptr++; |
@@ -429,8 +430,35 @@ void mconsole_remove(struct mc_request *req) | |||
429 | mconsole_reply(req, "Bad remove option", 1, 0); | 430 | mconsole_reply(req, "Bad remove option", 1, 0); |
430 | return; | 431 | return; |
431 | } | 432 | } |
432 | err = (*dev->remove)(&ptr[strlen(dev->name)]); | 433 | |
433 | mconsole_reply(req, "", err, 0); | 434 | ptr = &ptr[strlen(dev->name)]; |
435 | |||
436 | err = 1; | ||
437 | n = (*dev->id)(&ptr, &start, &end); | ||
438 | if(n < 0){ | ||
439 | err_msg = "Couldn't parse device number"; | ||
440 | goto out; | ||
441 | } | ||
442 | else if((n < start) || (n > end)){ | ||
443 | sprintf(error, "Invalid device number - must be between " | ||
444 | "%d and %d", start, end); | ||
445 | err_msg = error; | ||
446 | goto out; | ||
447 | } | ||
448 | |||
449 | err = (*dev->remove)(n); | ||
450 | switch(err){ | ||
451 | case -ENODEV: | ||
452 | err_msg = "Device doesn't exist"; | ||
453 | break; | ||
454 | case -EBUSY: | ||
455 | err_msg = "Device is currently open"; | ||
456 | break; | ||
457 | default: | ||
458 | break; | ||
459 | } | ||
460 | out: | ||
461 | mconsole_reply(req, err_msg, err, 0); | ||
434 | } | 462 | } |
435 | 463 | ||
436 | #ifdef CONFIG_MAGIC_SYSRQ | 464 | #ifdef CONFIG_MAGIC_SYSRQ |
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 5388a7428691..1495007bf6c0 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c | |||
@@ -612,25 +612,35 @@ static int net_config(char *str) | |||
612 | return(err); | 612 | return(err); |
613 | } | 613 | } |
614 | 614 | ||
615 | static int net_remove(char *str) | 615 | static int net_id(char **str, int *start_out, int *end_out) |
616 | { | ||
617 | char *end; | ||
618 | int n; | ||
619 | |||
620 | n = simple_strtoul(*str, &end, 0); | ||
621 | if((*end != '\0') || (end == *str)) | ||
622 | return -1; | ||
623 | |||
624 | *start_out = n; | ||
625 | *end_out = n; | ||
626 | *str = end; | ||
627 | return n; | ||
628 | } | ||
629 | |||
630 | static int net_remove(int n) | ||
616 | { | 631 | { |
617 | struct uml_net *device; | 632 | struct uml_net *device; |
618 | struct net_device *dev; | 633 | struct net_device *dev; |
619 | struct uml_net_private *lp; | 634 | struct uml_net_private *lp; |
620 | char *end; | ||
621 | int n; | ||
622 | |||
623 | n = simple_strtoul(str, &end, 0); | ||
624 | if((*end != '\0') || (end == str)) | ||
625 | return(-1); | ||
626 | 635 | ||
627 | device = find_device(n); | 636 | device = find_device(n); |
628 | if(device == NULL) | 637 | if(device == NULL) |
629 | return(0); | 638 | return -ENODEV; |
630 | 639 | ||
631 | dev = device->dev; | 640 | dev = device->dev; |
632 | lp = dev->priv; | 641 | lp = dev->priv; |
633 | if(lp->fd > 0) return(-1); | 642 | if(lp->fd > 0) |
643 | return -EBUSY; | ||
634 | if(lp->remove != NULL) (*lp->remove)(&lp->user); | 644 | if(lp->remove != NULL) (*lp->remove)(&lp->user); |
635 | unregister_netdev(dev); | 645 | unregister_netdev(dev); |
636 | platform_device_unregister(&device->pdev); | 646 | platform_device_unregister(&device->pdev); |
@@ -638,13 +648,14 @@ static int net_remove(char *str) | |||
638 | list_del(&device->list); | 648 | list_del(&device->list); |
639 | kfree(device); | 649 | kfree(device); |
640 | free_netdev(dev); | 650 | free_netdev(dev); |
641 | return(0); | 651 | return 0; |
642 | } | 652 | } |
643 | 653 | ||
644 | static struct mc_device net_mc = { | 654 | static struct mc_device net_mc = { |
645 | .name = "eth", | 655 | .name = "eth", |
646 | .config = net_config, | 656 | .config = net_config, |
647 | .get_config = NULL, | 657 | .get_config = NULL, |
658 | .id = net_id, | ||
648 | .remove = net_remove, | 659 | .remove = net_remove, |
649 | }; | 660 | }; |
650 | 661 | ||
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index b32a77010fbe..62e04ecfada8 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c | |||
@@ -49,7 +49,7 @@ static struct chan_opts opts = { | |||
49 | 49 | ||
50 | static int ssl_config(char *str); | 50 | static int ssl_config(char *str); |
51 | static int ssl_get_config(char *dev, char *str, int size, char **error_out); | 51 | static int ssl_get_config(char *dev, char *str, int size, char **error_out); |
52 | static int ssl_remove(char *str); | 52 | static int ssl_remove(int n); |
53 | 53 | ||
54 | static struct line_driver driver = { | 54 | static struct line_driver driver = { |
55 | .name = "UML serial line", | 55 | .name = "UML serial line", |
@@ -69,6 +69,7 @@ static struct line_driver driver = { | |||
69 | .name = "ssl", | 69 | .name = "ssl", |
70 | .config = ssl_config, | 70 | .config = ssl_config, |
71 | .get_config = ssl_get_config, | 71 | .get_config = ssl_get_config, |
72 | .id = line_id, | ||
72 | .remove = ssl_remove, | 73 | .remove = ssl_remove, |
73 | }, | 74 | }, |
74 | }; | 75 | }; |
@@ -94,10 +95,10 @@ static int ssl_get_config(char *dev, char *str, int size, char **error_out) | |||
94 | str, size, error_out)); | 95 | str, size, error_out)); |
95 | } | 96 | } |
96 | 97 | ||
97 | static int ssl_remove(char *str) | 98 | static int ssl_remove(int n) |
98 | { | 99 | { |
99 | return(line_remove(serial_lines, | 100 | return line_remove(serial_lines, |
100 | sizeof(serial_lines)/sizeof(serial_lines[0]), str)); | 101 | sizeof(serial_lines)/sizeof(serial_lines[0]), n); |
101 | } | 102 | } |
102 | 103 | ||
103 | int ssl_open(struct tty_struct *tty, struct file *filp) | 104 | int ssl_open(struct tty_struct *tty, struct file *filp) |
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index afbe1e71ed83..005aa6333b6e 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c | |||
@@ -55,7 +55,7 @@ static struct chan_opts opts = { | |||
55 | 55 | ||
56 | static int con_config(char *str); | 56 | static int con_config(char *str); |
57 | static int con_get_config(char *dev, char *str, int size, char **error_out); | 57 | static int con_get_config(char *dev, char *str, int size, char **error_out); |
58 | static int con_remove(char *str); | 58 | static int con_remove(int n); |
59 | 59 | ||
60 | static struct line_driver driver = { | 60 | static struct line_driver driver = { |
61 | .name = "UML console", | 61 | .name = "UML console", |
@@ -75,6 +75,7 @@ static struct line_driver driver = { | |||
75 | .name = "con", | 75 | .name = "con", |
76 | .config = con_config, | 76 | .config = con_config, |
77 | .get_config = con_get_config, | 77 | .get_config = con_get_config, |
78 | .id = line_id, | ||
78 | .remove = con_remove, | 79 | .remove = con_remove, |
79 | }, | 80 | }, |
80 | }; | 81 | }; |
@@ -99,9 +100,9 @@ static int con_get_config(char *dev, char *str, int size, char **error_out) | |||
99 | size, error_out)); | 100 | size, error_out)); |
100 | } | 101 | } |
101 | 102 | ||
102 | static int con_remove(char *str) | 103 | static int con_remove(int n) |
103 | { | 104 | { |
104 | return(line_remove(vts, sizeof(vts)/sizeof(vts[0]), str)); | 105 | return line_remove(vts, sizeof(vts)/sizeof(vts[0]), n); |
105 | } | 106 | } |
106 | 107 | ||
107 | static int con_open(struct tty_struct *tty, struct file *filp) | 108 | static int con_open(struct tty_struct *tty, struct file *filp) |
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 2a7f6892c55c..344b24d09a7c 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c | |||
@@ -754,24 +754,34 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out) | |||
754 | return(len); | 754 | return(len); |
755 | } | 755 | } |
756 | 756 | ||
757 | static int ubd_remove(char *str) | 757 | static int ubd_id(char **str, int *start_out, int *end_out) |
758 | { | ||
759 | int n; | ||
760 | |||
761 | n = parse_unit(str); | ||
762 | *start_out = 0; | ||
763 | *end_out = MAX_DEV - 1; | ||
764 | return n; | ||
765 | } | ||
766 | |||
767 | static int ubd_remove(int n) | ||
758 | { | 768 | { |
759 | struct ubd *dev; | 769 | struct ubd *dev; |
760 | int n, err = -ENODEV; | 770 | int err = -ENODEV; |
761 | 771 | ||
762 | n = parse_unit(&str); | 772 | spin_lock(&ubd_lock); |
763 | 773 | ||
764 | if((n < 0) || (n >= MAX_DEV)) | 774 | if(ubd_gendisk[n] == NULL) |
765 | return(err); | 775 | goto out; |
766 | 776 | ||
767 | dev = &ubd_dev[n]; | 777 | dev = &ubd_dev[n]; |
768 | if(dev->count > 0) | ||
769 | return(-EBUSY); /* you cannot remove a open disk */ | ||
770 | 778 | ||
771 | err = 0; | 779 | if(dev->file == NULL) |
772 | spin_lock(&ubd_lock); | 780 | goto out; |
773 | 781 | ||
774 | if(ubd_gendisk[n] == NULL) | 782 | /* you cannot remove a open disk */ |
783 | err = -EBUSY; | ||
784 | if(dev->count > 0) | ||
775 | goto out; | 785 | goto out; |
776 | 786 | ||
777 | del_gendisk(ubd_gendisk[n]); | 787 | del_gendisk(ubd_gendisk[n]); |
@@ -787,15 +797,16 @@ static int ubd_remove(char *str) | |||
787 | platform_device_unregister(&dev->pdev); | 797 | platform_device_unregister(&dev->pdev); |
788 | *dev = ((struct ubd) DEFAULT_UBD); | 798 | *dev = ((struct ubd) DEFAULT_UBD); |
789 | err = 0; | 799 | err = 0; |
790 | out: | 800 | out: |
791 | spin_unlock(&ubd_lock); | 801 | spin_unlock(&ubd_lock); |
792 | return(err); | 802 | return err; |
793 | } | 803 | } |
794 | 804 | ||
795 | static struct mc_device ubd_mc = { | 805 | static struct mc_device ubd_mc = { |
796 | .name = "ubd", | 806 | .name = "ubd", |
797 | .config = ubd_config, | 807 | .config = ubd_config, |
798 | .get_config = ubd_get_config, | 808 | .get_config = ubd_get_config, |
809 | .id = ubd_id, | ||
799 | .remove = ubd_remove, | 810 | .remove = ubd_remove, |
800 | }; | 811 | }; |
801 | 812 | ||
diff --git a/arch/um/include/line.h b/arch/um/include/line.h index 4c5e92c04ccb..5323d22a6ca7 100644 --- a/arch/um/include/line.h +++ b/arch/um/include/line.h | |||
@@ -101,7 +101,8 @@ extern void lines_init(struct line *lines, int nlines); | |||
101 | extern void close_lines(struct line *lines, int nlines); | 101 | extern void close_lines(struct line *lines, int nlines); |
102 | 102 | ||
103 | extern int line_config(struct line *lines, unsigned int sizeof_lines, char *str); | 103 | extern int line_config(struct line *lines, unsigned int sizeof_lines, char *str); |
104 | extern int line_remove(struct line *lines, unsigned int sizeof_lines, char *str); | 104 | extern int line_id(char **str, int *start_out, int *end_out); |
105 | extern int line_remove(struct line *lines, unsigned int sizeof_lines, int n); | ||
105 | extern int line_get_config(char *dev, struct line *lines, unsigned int sizeof_lines, char *str, | 106 | extern int line_get_config(char *dev, struct line *lines, unsigned int sizeof_lines, char *str, |
106 | int size, char **error_out); | 107 | int size, char **error_out); |
107 | 108 | ||
diff --git a/arch/um/include/mconsole_kern.h b/arch/um/include/mconsole_kern.h index 61c274fcee5d..d86ee14260ce 100644 --- a/arch/um/include/mconsole_kern.h +++ b/arch/um/include/mconsole_kern.h | |||
@@ -20,7 +20,8 @@ struct mc_device { | |||
20 | char *name; | 20 | char *name; |
21 | int (*config)(char *); | 21 | int (*config)(char *); |
22 | int (*get_config)(char *, char *, int, char **); | 22 | int (*get_config)(char *, char *, int, char **); |
23 | int (*remove)(char *); | 23 | int (*id)(char **, int *, int *); |
24 | int (*remove)(int); | ||
24 | }; | 25 | }; |
25 | 26 | ||
26 | #define CONFIG_CHUNK(str, size, current, chunk, end) \ | 27 | #define CONFIG_CHUNK(str, size, current, chunk, end) \ |
diff --git a/arch/um/include/time_user.h b/arch/um/include/time_user.h index 6793a2fcd0ae..f64ef77019a3 100644 --- a/arch/um/include/time_user.h +++ b/arch/um/include/time_user.h | |||
@@ -8,11 +8,11 @@ | |||
8 | 8 | ||
9 | extern void timer(void); | 9 | extern void timer(void); |
10 | extern void switch_timers(int to_real); | 10 | extern void switch_timers(int to_real); |
11 | extern void set_interval(int timer_type); | ||
12 | extern void idle_sleep(int secs); | 11 | extern void idle_sleep(int secs); |
13 | extern void enable_timer(void); | 12 | extern void enable_timer(void); |
14 | extern void disable_timer(void); | 13 | extern void disable_timer(void); |
15 | extern unsigned long time_lock(void); | 14 | extern unsigned long time_lock(void); |
16 | extern void time_unlock(unsigned long); | 15 | extern void time_unlock(unsigned long); |
16 | extern void user_time_init(void); | ||
17 | 17 | ||
18 | #endif | 18 | #endif |
diff --git a/arch/um/kernel/main.c b/arch/um/kernel/main.c index e59f58152678..1e1a87f1c510 100644 --- a/arch/um/kernel/main.c +++ b/arch/um/kernel/main.c | |||
@@ -69,7 +69,6 @@ static __init void do_uml_initcalls(void) | |||
69 | 69 | ||
70 | static void last_ditch_exit(int sig) | 70 | static void last_ditch_exit(int sig) |
71 | { | 71 | { |
72 | kmalloc_ok = 0; | ||
73 | signal(SIGINT, SIG_DFL); | 72 | signal(SIGINT, SIG_DFL); |
74 | signal(SIGTERM, SIG_DFL); | 73 | signal(SIGTERM, SIG_DFL); |
75 | signal(SIGHUP, SIG_DFL); | 74 | signal(SIGHUP, SIG_DFL); |
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c index 157584ae4792..d4036ed680bc 100644 --- a/arch/um/kernel/process_kern.c +++ b/arch/um/kernel/process_kern.c | |||
@@ -96,8 +96,8 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | |||
96 | 96 | ||
97 | current->thread.request.u.thread.proc = fn; | 97 | current->thread.request.u.thread.proc = fn; |
98 | current->thread.request.u.thread.arg = arg; | 98 | current->thread.request.u.thread.arg = arg; |
99 | pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, NULL, 0, NULL, | 99 | pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, |
100 | NULL); | 100 | ¤t->thread.regs, 0, NULL, NULL); |
101 | if(pid < 0) | 101 | if(pid < 0) |
102 | panic("do_fork failed in kernel_thread, errno = %d", pid); | 102 | panic("do_fork failed in kernel_thread, errno = %d", pid); |
103 | return(pid); | 103 | return(pid); |
@@ -169,7 +169,7 @@ int current_pid(void) | |||
169 | 169 | ||
170 | void default_idle(void) | 170 | void default_idle(void) |
171 | { | 171 | { |
172 | uml_idle_timer(); | 172 | CHOOSE_MODE(uml_idle_timer(), (void) 0); |
173 | 173 | ||
174 | atomic_inc(&init_mm.mm_count); | 174 | atomic_inc(&init_mm.mm_count); |
175 | current->mm = &init_mm; | 175 | current->mm = &init_mm; |
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c index 207f89d74908..fcec51da1d37 100644 --- a/arch/um/kernel/reboot.c +++ b/arch/um/kernel/reboot.c | |||
@@ -38,14 +38,14 @@ static void kill_off_processes(void) | |||
38 | 38 | ||
39 | void uml_cleanup(void) | 39 | void uml_cleanup(void) |
40 | { | 40 | { |
41 | kill_off_processes(); | 41 | kmalloc_ok = 0; |
42 | do_uml_exitcalls(); | 42 | do_uml_exitcalls(); |
43 | kill_off_processes(); | ||
43 | } | 44 | } |
44 | 45 | ||
45 | void machine_restart(char * __unused) | 46 | void machine_restart(char * __unused) |
46 | { | 47 | { |
47 | do_uml_exitcalls(); | 48 | uml_cleanup(); |
48 | kill_off_processes(); | ||
49 | CHOOSE_MODE(reboot_tt(), reboot_skas()); | 49 | CHOOSE_MODE(reboot_tt(), reboot_skas()); |
50 | } | 50 | } |
51 | 51 | ||
@@ -53,8 +53,7 @@ EXPORT_SYMBOL(machine_restart); | |||
53 | 53 | ||
54 | void machine_power_off(void) | 54 | void machine_power_off(void) |
55 | { | 55 | { |
56 | do_uml_exitcalls(); | 56 | uml_cleanup(); |
57 | kill_off_processes(); | ||
58 | CHOOSE_MODE(halt_tt(), halt_skas()); | 57 | CHOOSE_MODE(halt_tt(), halt_skas()); |
59 | } | 58 | } |
60 | 59 | ||
diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile index d37d1bfcd6f7..ff69c4b312c0 100644 --- a/arch/um/kernel/skas/Makefile +++ b/arch/um/kernel/skas/Makefile | |||
@@ -4,10 +4,10 @@ | |||
4 | # | 4 | # |
5 | 5 | ||
6 | obj-y := exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \ | 6 | obj-y := exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \ |
7 | syscall_kern.o syscall_user.o time.o tlb.o trap_user.o uaccess.o \ | 7 | syscall_kern.o syscall_user.o tlb.o trap_user.o uaccess.o \ |
8 | 8 | ||
9 | subdir- := util | 9 | subdir- := util |
10 | 10 | ||
11 | USER_OBJS := process.o time.o | 11 | USER_OBJS := process.o |
12 | 12 | ||
13 | include arch/um/scripts/Makefile.rules | 13 | include arch/um/scripts/Makefile.rules |
diff --git a/arch/um/kernel/skas/include/mode-skas.h b/arch/um/kernel/skas/include/mode-skas.h index c1e33bd788db..bcd26a6a3888 100644 --- a/arch/um/kernel/skas/include/mode-skas.h +++ b/arch/um/kernel/skas/include/mode-skas.h | |||
@@ -13,7 +13,6 @@ extern unsigned long exec_fp_regs[]; | |||
13 | extern unsigned long exec_fpx_regs[]; | 13 | extern unsigned long exec_fpx_regs[]; |
14 | extern int have_fpx_regs; | 14 | extern int have_fpx_regs; |
15 | 15 | ||
16 | extern void user_time_init_skas(void); | ||
17 | extern void sig_handler_common_skas(int sig, void *sc_ptr); | 16 | extern void sig_handler_common_skas(int sig, void *sc_ptr); |
18 | extern void halt_skas(void); | 17 | extern void halt_skas(void); |
19 | extern void reboot_skas(void); | 18 | extern void reboot_skas(void); |
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c index fc71ef295782..0a7b8aa55db8 100644 --- a/arch/um/kernel/skas/process_kern.c +++ b/arch/um/kernel/skas/process_kern.c | |||
@@ -111,8 +111,7 @@ int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp, | |||
111 | void (*handler)(int); | 111 | void (*handler)(int); |
112 | 112 | ||
113 | if(current->thread.forking){ | 113 | if(current->thread.forking){ |
114 | memcpy(&p->thread.regs.regs.skas, | 114 | memcpy(&p->thread.regs.regs.skas, ®s->regs.skas, |
115 | ¤t->thread.regs.regs.skas, | ||
116 | sizeof(p->thread.regs.regs.skas)); | 115 | sizeof(p->thread.regs.regs.skas)); |
117 | REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.skas.regs, 0); | 116 | REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.skas.regs, 0); |
118 | if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp; | 117 | if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp; |
@@ -181,7 +180,6 @@ int start_uml_skas(void) | |||
181 | start_userspace(0); | 180 | start_userspace(0); |
182 | 181 | ||
183 | init_new_thread_signals(1); | 182 | init_new_thread_signals(1); |
184 | uml_idle_timer(); | ||
185 | 183 | ||
186 | init_task.thread.request.u.thread.proc = start_kernel_proc; | 184 | init_task.thread.request.u.thread.proc = start_kernel_proc; |
187 | init_task.thread.request.u.thread.arg = NULL; | 185 | init_task.thread.request.u.thread.arg = NULL; |
@@ -201,14 +199,3 @@ int thread_pid_skas(struct task_struct *task) | |||
201 | #warning Need to look up userspace_pid by cpu | 199 | #warning Need to look up userspace_pid by cpu |
202 | return(userspace_pid[0]); | 200 | return(userspace_pid[0]); |
203 | } | 201 | } |
204 | |||
205 | /* | ||
206 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
207 | * Emacs will notice this stuff at the end of the file and automatically | ||
208 | * adjust the settings for this buffer only. This must remain at the end | ||
209 | * of the file. | ||
210 | * --------------------------------------------------------------------------- | ||
211 | * Local variables: | ||
212 | * c-file-style: "linux" | ||
213 | * End: | ||
214 | */ | ||
diff --git a/arch/um/kernel/skas/time.c b/arch/um/kernel/skas/time.c deleted file mode 100644 index 98091494b897..000000000000 --- a/arch/um/kernel/skas/time.c +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #include <sys/signal.h> | ||
7 | #include <sys/time.h> | ||
8 | #include "time_user.h" | ||
9 | #include "process.h" | ||
10 | #include "user.h" | ||
11 | |||
12 | void user_time_init_skas(void) | ||
13 | { | ||
14 | if(signal(SIGALRM, (__sighandler_t) alarm_handler) == SIG_ERR) | ||
15 | panic("Couldn't set SIGALRM handler"); | ||
16 | if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR) | ||
17 | panic("Couldn't set SIGVTALRM handler"); | ||
18 | set_interval(ITIMER_VIRTUAL); | ||
19 | } | ||
20 | |||
21 | /* | ||
22 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
23 | * Emacs will notice this stuff at the end of the file and automatically | ||
24 | * adjust the settings for this buffer only. This must remain at the end | ||
25 | * of the file. | ||
26 | * --------------------------------------------------------------------------- | ||
27 | * Local variables: | ||
28 | * c-file-style: "linux" | ||
29 | * End: | ||
30 | */ | ||
diff --git a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c index b7a55251e897..8e1a3501ff46 100644 --- a/arch/um/kernel/syscall_kern.c +++ b/arch/um/kernel/syscall_kern.c | |||
@@ -31,7 +31,8 @@ long sys_fork(void) | |||
31 | long ret; | 31 | long ret; |
32 | 32 | ||
33 | current->thread.forking = 1; | 33 | current->thread.forking = 1; |
34 | ret = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL); | 34 | ret = do_fork(SIGCHLD, UPT_SP(¤t->thread.regs.regs), |
35 | ¤t->thread.regs, 0, NULL, NULL); | ||
35 | current->thread.forking = 0; | 36 | current->thread.forking = 0; |
36 | return(ret); | 37 | return(ret); |
37 | } | 38 | } |
@@ -41,8 +42,9 @@ long sys_vfork(void) | |||
41 | long ret; | 42 | long ret; |
42 | 43 | ||
43 | current->thread.forking = 1; | 44 | current->thread.forking = 1; |
44 | ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL, | 45 | ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, |
45 | NULL); | 46 | UPT_SP(¤t->thread.regs.regs), |
47 | ¤t->thread.regs, 0, NULL, NULL); | ||
46 | current->thread.forking = 0; | 48 | current->thread.forking = 0; |
47 | return(ret); | 49 | return(ret); |
48 | } | 50 | } |
@@ -162,14 +164,3 @@ int next_syscall_index(int limit) | |||
162 | spin_unlock(&syscall_lock); | 164 | spin_unlock(&syscall_lock); |
163 | return(ret); | 165 | return(ret); |
164 | } | 166 | } |
165 | |||
166 | /* | ||
167 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
168 | * Emacs will notice this stuff at the end of the file and automatically | ||
169 | * adjust the settings for this buffer only. This must remain at the end | ||
170 | * of the file. | ||
171 | * --------------------------------------------------------------------------- | ||
172 | * Local variables: | ||
173 | * c-file-style: "linux" | ||
174 | * End: | ||
175 | */ | ||
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index c40c86a3f918..f829b309b63c 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c | |||
@@ -33,7 +33,7 @@ void timer(void) | |||
33 | timeradd(&xtime, &local_offset, &xtime); | 33 | timeradd(&xtime, &local_offset, &xtime); |
34 | } | 34 | } |
35 | 35 | ||
36 | void set_interval(int timer_type) | 36 | static void set_interval(int timer_type) |
37 | { | 37 | { |
38 | int usec = 1000000/hz(); | 38 | int usec = 1000000/hz(); |
39 | struct itimerval interval = ((struct itimerval) { { 0, usec }, | 39 | struct itimerval interval = ((struct itimerval) { { 0, usec }, |
@@ -45,12 +45,7 @@ void set_interval(int timer_type) | |||
45 | 45 | ||
46 | void enable_timer(void) | 46 | void enable_timer(void) |
47 | { | 47 | { |
48 | int usec = 1000000/hz(); | 48 | set_interval(ITIMER_VIRTUAL); |
49 | struct itimerval enable = ((struct itimerval) { { 0, usec }, | ||
50 | { 0, usec }}); | ||
51 | if(setitimer(ITIMER_VIRTUAL, &enable, NULL)) | ||
52 | printk("enable_timer - setitimer failed, errno = %d\n", | ||
53 | errno); | ||
54 | } | 49 | } |
55 | 50 | ||
56 | void disable_timer(void) | 51 | void disable_timer(void) |
@@ -155,13 +150,15 @@ void idle_sleep(int secs) | |||
155 | nanosleep(&ts, NULL); | 150 | nanosleep(&ts, NULL); |
156 | } | 151 | } |
157 | 152 | ||
158 | /* | 153 | /* XXX This partly duplicates init_irq_signals */ |
159 | * Overrides for Emacs so that we follow Linus's tabbing style. | 154 | |
160 | * Emacs will notice this stuff at the end of the file and automatically | 155 | void user_time_init(void) |
161 | * adjust the settings for this buffer only. This must remain at the end | 156 | { |
162 | * of the file. | 157 | set_handler(SIGVTALRM, (__sighandler_t) alarm_handler, |
163 | * --------------------------------------------------------------------------- | 158 | SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, |
164 | * Local variables: | 159 | SIGALRM, SIGUSR2, -1); |
165 | * c-file-style: "linux" | 160 | set_handler(SIGALRM, (__sighandler_t) alarm_handler, |
166 | * End: | 161 | SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, |
167 | */ | 162 | SIGVTALRM, SIGUSR2, -1); |
163 | set_interval(ITIMER_VIRTUAL); | ||
164 | } | ||
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c index 6516fc52afe0..a8b4ef601f59 100644 --- a/arch/um/kernel/time_kern.c +++ b/arch/um/kernel/time_kern.c | |||
@@ -162,7 +162,7 @@ int __init timer_init(void) | |||
162 | { | 162 | { |
163 | int err; | 163 | int err; |
164 | 164 | ||
165 | CHOOSE_MODE(user_time_init_tt(), user_time_init_skas()); | 165 | user_time_init(); |
166 | err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL); | 166 | err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL); |
167 | if(err != 0) | 167 | if(err != 0) |
168 | printk(KERN_ERR "timer_init : request_irq failed - " | 168 | printk(KERN_ERR "timer_init : request_irq failed - " |
diff --git a/arch/um/kernel/tt/Makefile b/arch/um/kernel/tt/Makefile index 3fd2554e60b6..6939e5af8472 100644 --- a/arch/um/kernel/tt/Makefile +++ b/arch/um/kernel/tt/Makefile | |||
@@ -4,11 +4,11 @@ | |||
4 | # | 4 | # |
5 | 5 | ||
6 | obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \ | 6 | obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \ |
7 | syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \ | 7 | syscall_kern.o syscall_user.o tlb.o tracer.o trap_user.o \ |
8 | uaccess.o uaccess_user.o | 8 | uaccess.o uaccess_user.o |
9 | 9 | ||
10 | obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/ | 10 | obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/ |
11 | 11 | ||
12 | USER_OBJS := gdb.o time.o tracer.o | 12 | USER_OBJS := gdb.o tracer.o |
13 | 13 | ||
14 | include arch/um/scripts/Makefile.rules | 14 | include arch/um/scripts/Makefile.rules |
diff --git a/arch/um/kernel/tt/gdb.c b/arch/um/kernel/tt/gdb.c index 19a0ad7b35b3..37e22d71a0d9 100644 --- a/arch/um/kernel/tt/gdb.c +++ b/arch/um/kernel/tt/gdb.c | |||
@@ -153,10 +153,10 @@ void remove_gdb_cb(void *unused) | |||
153 | exit_debugger_cb(NULL); | 153 | exit_debugger_cb(NULL); |
154 | } | 154 | } |
155 | 155 | ||
156 | int gdb_remove(char *unused) | 156 | int gdb_remove(int unused) |
157 | { | 157 | { |
158 | initial_thread_cb(remove_gdb_cb, NULL); | 158 | initial_thread_cb(remove_gdb_cb, NULL); |
159 | return(0); | 159 | return 0; |
160 | } | 160 | } |
161 | 161 | ||
162 | void signal_usr1(int sig) | 162 | void signal_usr1(int sig) |
diff --git a/arch/um/kernel/tt/gdb_kern.c b/arch/um/kernel/tt/gdb_kern.c index 93fb121f86af..26506388a6aa 100644 --- a/arch/um/kernel/tt/gdb_kern.c +++ b/arch/um/kernel/tt/gdb_kern.c | |||
@@ -10,7 +10,7 @@ | |||
10 | #ifdef CONFIG_MCONSOLE | 10 | #ifdef CONFIG_MCONSOLE |
11 | 11 | ||
12 | extern int gdb_config(char *str); | 12 | extern int gdb_config(char *str); |
13 | extern int gdb_remove(char *unused); | 13 | extern int gdb_remove(int n); |
14 | 14 | ||
15 | static struct mc_device gdb_mc = { | 15 | static struct mc_device gdb_mc = { |
16 | .name = "gdb", | 16 | .name = "gdb", |
diff --git a/arch/um/kernel/tt/include/debug.h b/arch/um/kernel/tt/include/debug.h index 8eff674107ca..738435461e13 100644 --- a/arch/um/kernel/tt/include/debug.h +++ b/arch/um/kernel/tt/include/debug.h | |||
@@ -4,8 +4,8 @@ | |||
4 | * Licensed under the GPL | 4 | * Licensed under the GPL |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #ifndef __DEBUG_H | 7 | #ifndef __UML_TT_DEBUG_H |
8 | #define __DEBUG_H | 8 | #define __UML_TT_DEBUG_H |
9 | 9 | ||
10 | extern int debugger_proxy(int status, pid_t pid); | 10 | extern int debugger_proxy(int status, pid_t pid); |
11 | extern void child_proxy(pid_t pid, int status); | 11 | extern void child_proxy(pid_t pid, int status); |
@@ -13,17 +13,6 @@ extern void init_proxy (pid_t pid, int waiting, int status); | |||
13 | extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd); | 13 | extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd); |
14 | extern void fake_child_exit(void); | 14 | extern void fake_child_exit(void); |
15 | extern int gdb_config(char *str); | 15 | extern int gdb_config(char *str); |
16 | extern int gdb_remove(char *unused); | 16 | extern int gdb_remove(int unused); |
17 | 17 | ||
18 | #endif | 18 | #endif |
19 | |||
20 | /* | ||
21 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
22 | * Emacs will notice this stuff at the end of the file and automatically | ||
23 | * adjust the settings for this buffer only. This must remain at the end | ||
24 | * of the file. | ||
25 | * --------------------------------------------------------------------------- | ||
26 | * Local variables: | ||
27 | * c-file-style: "linux" | ||
28 | * End: | ||
29 | */ | ||
diff --git a/arch/um/kernel/tt/include/mode-tt.h b/arch/um/kernel/tt/include/mode-tt.h index efe462019069..e171e15fead5 100644 --- a/arch/um/kernel/tt/include/mode-tt.h +++ b/arch/um/kernel/tt/include/mode-tt.h | |||
@@ -13,7 +13,6 @@ enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB }; | |||
13 | extern int tracing_pid; | 13 | extern int tracing_pid; |
14 | 14 | ||
15 | extern int tracer(int (*init_proc)(void *), void *sp); | 15 | extern int tracer(int (*init_proc)(void *), void *sp); |
16 | extern void user_time_init_tt(void); | ||
17 | extern void sig_handler_common_tt(int sig, void *sc); | 16 | extern void sig_handler_common_tt(int sig, void *sc); |
18 | extern void syscall_handler_tt(int sig, union uml_pt_regs *regs); | 17 | extern void syscall_handler_tt(int sig, union uml_pt_regs *regs); |
19 | extern void reboot_tt(void); | 18 | extern void reboot_tt(void); |
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c index 776310fd5b8b..a189a2b92935 100644 --- a/arch/um/kernel/tt/process_kern.c +++ b/arch/um/kernel/tt/process_kern.c | |||
@@ -266,10 +266,10 @@ int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp, | |||
266 | } | 266 | } |
267 | 267 | ||
268 | if(current->thread.forking){ | 268 | if(current->thread.forking){ |
269 | sc_to_sc(UPT_SC(&p->thread.regs.regs), | 269 | sc_to_sc(UPT_SC(&p->thread.regs.regs), UPT_SC(®s->regs)); |
270 | UPT_SC(¤t->thread.regs.regs)); | ||
271 | SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0); | 270 | SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0); |
272 | if(sp != 0) SC_SP(UPT_SC(&p->thread.regs.regs)) = sp; | 271 | if(sp != 0) |
272 | SC_SP(UPT_SC(&p->thread.regs.regs)) = sp; | ||
273 | } | 273 | } |
274 | p->thread.mode.tt.extern_pid = new_pid; | 274 | p->thread.mode.tt.extern_pid = new_pid; |
275 | 275 | ||
@@ -459,14 +459,3 @@ int is_valid_pid(int pid) | |||
459 | read_unlock(&tasklist_lock); | 459 | read_unlock(&tasklist_lock); |
460 | return(0); | 460 | return(0); |
461 | } | 461 | } |
462 | |||
463 | /* | ||
464 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
465 | * Emacs will notice this stuff at the end of the file and automatically | ||
466 | * adjust the settings for this buffer only. This must remain at the end | ||
467 | * of the file. | ||
468 | * --------------------------------------------------------------------------- | ||
469 | * Local variables: | ||
470 | * c-file-style: "linux" | ||
471 | * End: | ||
472 | */ | ||
diff --git a/arch/um/kernel/tt/time.c b/arch/um/kernel/tt/time.c deleted file mode 100644 index 8565b71b07cd..000000000000 --- a/arch/um/kernel/tt/time.c +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #include <signal.h> | ||
7 | #include <sys/time.h> | ||
8 | #include <time_user.h> | ||
9 | #include "process.h" | ||
10 | #include "user.h" | ||
11 | |||
12 | void user_time_init_tt(void) | ||
13 | { | ||
14 | if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR) | ||
15 | panic("Couldn't set SIGVTALRM handler"); | ||
16 | set_interval(ITIMER_VIRTUAL); | ||
17 | } | ||
18 | |||
19 | /* | ||
20 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
21 | * Emacs will notice this stuff at the end of the file and automatically | ||
22 | * adjust the settings for this buffer only. This must remain at the end | ||
23 | * of the file. | ||
24 | * --------------------------------------------------------------------------- | ||
25 | * Local variables: | ||
26 | * c-file-style: "linux" | ||
27 | * End: | ||
28 | */ | ||
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c index 03913ca5d256..4efc69a039d7 100644 --- a/arch/um/sys-i386/signal.c +++ b/arch/um/sys-i386/signal.c | |||
@@ -312,7 +312,7 @@ long sys_sigreturn(struct pt_regs regs) | |||
312 | unsigned long __user *extramask = frame->extramask; | 312 | unsigned long __user *extramask = frame->extramask; |
313 | int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long); | 313 | int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long); |
314 | 314 | ||
315 | if(copy_from_user(&set.sig[0], oldmask, sizeof(&set.sig[0])) || | 315 | if(copy_from_user(&set.sig[0], oldmask, sizeof(set.sig[0])) || |
316 | copy_from_user(&set.sig[1], extramask, sig_size)) | 316 | copy_from_user(&set.sig[1], extramask, sig_size)) |
317 | goto segfault; | 317 | goto segfault; |
318 | 318 | ||
diff --git a/arch/um/sys-i386/syscalls.c b/arch/um/sys-i386/syscalls.c index 335e2d89504d..83e9be820a86 100644 --- a/arch/um/sys-i386/syscalls.c +++ b/arch/um/sys-i386/syscalls.c | |||
@@ -69,15 +69,11 @@ long sys_clone(unsigned long clone_flags, unsigned long newsp, | |||
69 | { | 69 | { |
70 | long ret; | 70 | long ret; |
71 | 71 | ||
72 | /* XXX: normal arch do here this pass, and also pass the regs to | 72 | if (!newsp) |
73 | * do_fork, instead of NULL. Currently the arch-independent code | 73 | newsp = UPT_SP(¤t->thread.regs.regs); |
74 | * ignores these values, while the UML code (actually it's | ||
75 | * copy_thread) does the right thing. But this should change, | ||
76 | probably. */ | ||
77 | /*if (!newsp) | ||
78 | newsp = UPT_SP(current->thread.regs);*/ | ||
79 | current->thread.forking = 1; | 74 | current->thread.forking = 1; |
80 | ret = do_fork(clone_flags, newsp, NULL, 0, parent_tid, child_tid); | 75 | ret = do_fork(clone_flags, newsp, ¤t->thread.regs, 0, parent_tid, |
76 | child_tid); | ||
81 | current->thread.forking = 0; | 77 | current->thread.forking = 0; |
82 | return(ret); | 78 | return(ret); |
83 | } | 79 | } |
@@ -197,14 +193,3 @@ long sys_sigaction(int sig, const struct old_sigaction __user *act, | |||
197 | 193 | ||
198 | return ret; | 194 | return ret; |
199 | } | 195 | } |
200 | |||
201 | /* | ||
202 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
203 | * Emacs will notice this stuff at the end of the file and automatically | ||
204 | * adjust the settings for this buffer only. This must remain at the end | ||
205 | * of the file. | ||
206 | * --------------------------------------------------------------------------- | ||
207 | * Local variables: | ||
208 | * c-file-style: "linux" | ||
209 | * End: | ||
210 | */ | ||
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c index 6f44f40204ed..3259a4db4534 100644 --- a/arch/um/sys-x86_64/syscalls.c +++ b/arch/um/sys-x86_64/syscalls.c | |||
@@ -174,26 +174,11 @@ long sys_clone(unsigned long clone_flags, unsigned long newsp, | |||
174 | { | 174 | { |
175 | long ret; | 175 | long ret; |
176 | 176 | ||
177 | /* XXX: normal arch do here this pass, and also pass the regs to | 177 | if (!newsp) |
178 | * do_fork, instead of NULL. Currently the arch-independent code | 178 | newsp = UPT_SP(¤t->thread.regs.regs); |
179 | * ignores these values, while the UML code (actually it's | ||
180 | * copy_thread) does the right thing. But this should change, | ||
181 | probably. */ | ||
182 | /*if (!newsp) | ||
183 | newsp = UPT_SP(current->thread.regs);*/ | ||
184 | current->thread.forking = 1; | 179 | current->thread.forking = 1; |
185 | ret = do_fork(clone_flags, newsp, NULL, 0, parent_tid, child_tid); | 180 | ret = do_fork(clone_flags, newsp, ¤t->thread.regs, 0, parent_tid, |
181 | child_tid); | ||
186 | current->thread.forking = 0; | 182 | current->thread.forking = 0; |
187 | return(ret); | 183 | return(ret); |
188 | } | 184 | } |
189 | |||
190 | /* | ||
191 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
192 | * Emacs will notice this stuff at the end of the file and automatically | ||
193 | * adjust the settings for this buffer only. This must remain at the end | ||
194 | * of the file. | ||
195 | * --------------------------------------------------------------------------- | ||
196 | * Local variables: | ||
197 | * c-file-style: "linux" | ||
198 | * End: | ||
199 | */ | ||
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index db259757dc8a..d09437b5c48f 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig | |||
@@ -207,33 +207,6 @@ config SMP | |||
207 | 207 | ||
208 | If you don't know what to do here, say N. | 208 | If you don't know what to do here, say N. |
209 | 209 | ||
210 | config PREEMPT | ||
211 | bool "Preemptible Kernel" | ||
212 | ---help--- | ||
213 | This option reduces the latency of the kernel when reacting to | ||
214 | real-time or interactive events by allowing a low priority process to | ||
215 | be preempted even if it is in kernel mode executing a system call. | ||
216 | This allows applications to run more reliably even when the system is | ||
217 | under load. On contrary it may also break your drivers and add | ||
218 | priority inheritance problems to your system. Don't select it if | ||
219 | you rely on a stable system or have slightly obscure hardware. | ||
220 | It's also not very well tested on x86-64 currently. | ||
221 | You have been warned. | ||
222 | |||
223 | Say Y here if you are feeling brave and building a kernel for a | ||
224 | desktop, embedded or real-time system. Say N if you are unsure. | ||
225 | |||
226 | config PREEMPT_BKL | ||
227 | bool "Preempt The Big Kernel Lock" | ||
228 | depends on PREEMPT | ||
229 | default y | ||
230 | help | ||
231 | This option reduces the latency of the kernel by making the | ||
232 | big kernel lock preemptible. | ||
233 | |||
234 | Say Y here if you are building a kernel for a desktop system. | ||
235 | Say N if you are unsure. | ||
236 | |||
237 | config SCHED_SMT | 210 | config SCHED_SMT |
238 | bool "SMT (Hyperthreading) scheduler support" | 211 | bool "SMT (Hyperthreading) scheduler support" |
239 | depends on SMP | 212 | depends on SMP |
@@ -244,6 +217,8 @@ config SCHED_SMT | |||
244 | cost of slightly increased overhead in some places. If unsure say | 217 | cost of slightly increased overhead in some places. If unsure say |
245 | N here. | 218 | N here. |
246 | 219 | ||
220 | source "kernel/Kconfig.preempt" | ||
221 | |||
247 | config K8_NUMA | 222 | config K8_NUMA |
248 | bool "K8 NUMA support" | 223 | bool "K8 NUMA support" |
249 | select NUMA | 224 | select NUMA |
@@ -313,6 +288,15 @@ config NR_CPUS | |||
313 | This is purely to save memory - each supported CPU requires | 288 | This is purely to save memory - each supported CPU requires |
314 | memory in the static kernel configuration. | 289 | memory in the static kernel configuration. |
315 | 290 | ||
291 | config HOTPLUG_CPU | ||
292 | bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" | ||
293 | depends on SMP && HOTPLUG && EXPERIMENTAL | ||
294 | help | ||
295 | Say Y here to experiment with turning CPUs off and on. CPUs | ||
296 | can be controlled through /sys/devices/system/cpu/cpu#. | ||
297 | Say N if you want to disable CPU hotplug. | ||
298 | |||
299 | |||
316 | config HPET_TIMER | 300 | config HPET_TIMER |
317 | bool | 301 | bool |
318 | default y | 302 | default y |
@@ -385,6 +369,34 @@ config X86_MCE_INTEL | |||
385 | Additional support for intel specific MCE features such as | 369 | Additional support for intel specific MCE features such as |
386 | the thermal monitor. | 370 | the thermal monitor. |
387 | 371 | ||
372 | config PHYSICAL_START | ||
373 | hex "Physical address where the kernel is loaded" if EMBEDDED | ||
374 | default "0x100000" | ||
375 | help | ||
376 | This gives the physical address where the kernel is loaded. | ||
377 | Primarily used in the case of kexec on panic where the | ||
378 | fail safe kernel needs to run at a different address than | ||
379 | the panic-ed kernel. | ||
380 | |||
381 | Don't change this unless you know what you are doing. | ||
382 | |||
383 | config KEXEC | ||
384 | bool "kexec system call (EXPERIMENTAL)" | ||
385 | depends on EXPERIMENTAL | ||
386 | help | ||
387 | kexec is a system call that implements the ability to shutdown your | ||
388 | current kernel, and to start another kernel. It is like a reboot | ||
389 | but it is indepedent of the system firmware. And like a reboot | ||
390 | you can start any kernel with it, not just Linux. | ||
391 | |||
392 | The name comes from the similiarity to the exec system call. | ||
393 | |||
394 | It is an ongoing process to be certain the hardware in a machine | ||
395 | is properly shutdown, so do not be surprised if this code does not | ||
396 | initially work for you. It may help to enable device hotplugging | ||
397 | support. As of this writing the exact hardware interface is | ||
398 | strongly in flux, so no good recommendation can be made. | ||
399 | |||
388 | config SECCOMP | 400 | config SECCOMP |
389 | bool "Enable seccomp to safely compute untrusted bytecode" | 401 | bool "Enable seccomp to safely compute untrusted bytecode" |
390 | depends on PROC_FS | 402 | depends on PROC_FS |
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile index 6f90c246c418..8a73794f9b90 100644 --- a/arch/x86_64/Makefile +++ b/arch/x86_64/Makefile | |||
@@ -35,7 +35,7 @@ export IA32_CC IA32_LD IA32_AS IA32_OBJCOPY IA32_CPP | |||
35 | 35 | ||
36 | LDFLAGS := -m elf_x86_64 | 36 | LDFLAGS := -m elf_x86_64 |
37 | OBJCOPYFLAGS := -O binary -R .note -R .comment -S | 37 | OBJCOPYFLAGS := -O binary -R .note -R .comment -S |
38 | LDFLAGS_vmlinux := -e stext | 38 | LDFLAGS_vmlinux := |
39 | 39 | ||
40 | CHECKFLAGS += -D__x86_64__ -m64 | 40 | CHECKFLAGS += -D__x86_64__ -m64 |
41 | 41 | ||
diff --git a/arch/x86_64/boot/compressed/head.S b/arch/x86_64/boot/compressed/head.S index 27264dbd575c..6f55565e4d42 100644 --- a/arch/x86_64/boot/compressed/head.S +++ b/arch/x86_64/boot/compressed/head.S | |||
@@ -2,8 +2,6 @@ | |||
2 | * linux/boot/head.S | 2 | * linux/boot/head.S |
3 | * | 3 | * |
4 | * Copyright (C) 1991, 1992, 1993 Linus Torvalds | 4 | * Copyright (C) 1991, 1992, 1993 Linus Torvalds |
5 | * | ||
6 | * $Id: head.S,v 1.3 2001/04/20 00:59:28 ak Exp $ | ||
7 | */ | 5 | */ |
8 | 6 | ||
9 | /* | 7 | /* |
@@ -21,13 +19,14 @@ | |||
21 | */ | 19 | */ |
22 | 20 | ||
23 | /* | 21 | /* |
24 | * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 | 22 | * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 |
25 | */ | 23 | */ |
26 | .code32 | 24 | .code32 |
27 | .text | 25 | .text |
28 | 26 | ||
29 | #include <linux/linkage.h> | 27 | #include <linux/linkage.h> |
30 | #include <asm/segment.h> | 28 | #include <asm/segment.h> |
29 | #include <asm/page.h> | ||
31 | 30 | ||
32 | .code32 | 31 | .code32 |
33 | .globl startup_32 | 32 | .globl startup_32 |
@@ -77,7 +76,7 @@ startup_32: | |||
77 | jnz 3f | 76 | jnz 3f |
78 | addl $8,%esp | 77 | addl $8,%esp |
79 | xorl %ebx,%ebx | 78 | xorl %ebx,%ebx |
80 | ljmp $(__KERNEL_CS), $0x100000 | 79 | ljmp $(__KERNEL_CS), $__PHYSICAL_START |
81 | 80 | ||
82 | /* | 81 | /* |
83 | * We come here, if we were loaded high. | 82 | * We come here, if we were loaded high. |
@@ -103,7 +102,7 @@ startup_32: | |||
103 | popl %ecx # lcount | 102 | popl %ecx # lcount |
104 | popl %edx # high_buffer_start | 103 | popl %edx # high_buffer_start |
105 | popl %eax # hcount | 104 | popl %eax # hcount |
106 | movl $0x100000,%edi | 105 | movl $__PHYSICAL_START,%edi |
107 | cli # make sure we don't get interrupted | 106 | cli # make sure we don't get interrupted |
108 | ljmp $(__KERNEL_CS), $0x1000 # and jump to the move routine | 107 | ljmp $(__KERNEL_CS), $0x1000 # and jump to the move routine |
109 | 108 | ||
@@ -128,7 +127,7 @@ move_routine_start: | |||
128 | movsl | 127 | movsl |
129 | movl %ebx,%esi # Restore setup pointer | 128 | movl %ebx,%esi # Restore setup pointer |
130 | xorl %ebx,%ebx | 129 | xorl %ebx,%ebx |
131 | ljmp $(__KERNEL_CS), $0x100000 | 130 | ljmp $(__KERNEL_CS), $__PHYSICAL_START |
132 | move_routine_end: | 131 | move_routine_end: |
133 | 132 | ||
134 | 133 | ||
diff --git a/arch/x86_64/boot/compressed/misc.c b/arch/x86_64/boot/compressed/misc.c index c8b9216f9e63..b38d5b8b5fb8 100644 --- a/arch/x86_64/boot/compressed/misc.c +++ b/arch/x86_64/boot/compressed/misc.c | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include "miscsetup.h" | 12 | #include "miscsetup.h" |
13 | #include <asm/io.h> | 13 | #include <asm/io.h> |
14 | #include <asm/page.h> | ||
14 | 15 | ||
15 | /* | 16 | /* |
16 | * gzip declarations | 17 | * gzip declarations |
@@ -92,8 +93,11 @@ static unsigned long output_ptr = 0; | |||
92 | static void *malloc(int size); | 93 | static void *malloc(int size); |
93 | static void free(void *where); | 94 | static void free(void *where); |
94 | 95 | ||
96 | void* memset(void* s, int c, unsigned n); | ||
97 | void* memcpy(void* dest, const void* src, unsigned n); | ||
98 | |||
95 | static void putstr(const char *); | 99 | static void putstr(const char *); |
96 | 100 | ||
97 | extern int end; | 101 | extern int end; |
98 | static long free_mem_ptr = (long)&end; | 102 | static long free_mem_ptr = (long)&end; |
99 | static long free_mem_end_ptr; | 103 | static long free_mem_end_ptr; |
@@ -284,7 +288,7 @@ void setup_normal_output_buffer(void) | |||
284 | #else | 288 | #else |
285 | if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory"); | 289 | if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory"); |
286 | #endif | 290 | #endif |
287 | output_data = (char *)0x100000; /* Points to 1M */ | 291 | output_data = (char *)__PHYSICAL_START; /* Normally Points to 1M */ |
288 | free_mem_end_ptr = (long)real_mode; | 292 | free_mem_end_ptr = (long)real_mode; |
289 | } | 293 | } |
290 | 294 | ||
@@ -307,8 +311,8 @@ void setup_output_buffer_if_we_run_high(struct moveparams *mv) | |||
307 | low_buffer_size = low_buffer_end - LOW_BUFFER_START; | 311 | low_buffer_size = low_buffer_end - LOW_BUFFER_START; |
308 | high_loaded = 1; | 312 | high_loaded = 1; |
309 | free_mem_end_ptr = (long)high_buffer_start; | 313 | free_mem_end_ptr = (long)high_buffer_start; |
310 | if ( (0x100000 + low_buffer_size) > ((ulg)high_buffer_start)) { | 314 | if ( (__PHYSICAL_START + low_buffer_size) > ((ulg)high_buffer_start)) { |
311 | high_buffer_start = (uch *)(0x100000 + low_buffer_size); | 315 | high_buffer_start = (uch *)(__PHYSICAL_START + low_buffer_size); |
312 | mv->hcount = 0; /* say: we need not to move high_buffer */ | 316 | mv->hcount = 0; /* say: we need not to move high_buffer */ |
313 | } | 317 | } |
314 | else mv->hcount = -1; | 318 | else mv->hcount = -1; |
diff --git a/arch/x86_64/boot/install.sh b/arch/x86_64/boot/install.sh index f17b40dfc0f4..198af15a7758 100644 --- a/arch/x86_64/boot/install.sh +++ b/arch/x86_64/boot/install.sh | |||
@@ -1,6 +1,6 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | # | 2 | # |
3 | # arch/i386/boot/install.sh | 3 | # arch/x86_64/boot/install.sh |
4 | # | 4 | # |
5 | # This file is subject to the terms and conditions of the GNU General Public | 5 | # This file is subject to the terms and conditions of the GNU General Public |
6 | # License. See the file "COPYING" in the main directory of this archive | 6 | # License. See the file "COPYING" in the main directory of this archive |
diff --git a/arch/x86_64/boot/setup.S b/arch/x86_64/boot/setup.S index 75d4d2ad93b3..ff58b2832b75 100644 --- a/arch/x86_64/boot/setup.S +++ b/arch/x86_64/boot/setup.S | |||
@@ -33,7 +33,7 @@ | |||
33 | * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999. | 33 | * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999. |
34 | * <stiker@northlink.com> | 34 | * <stiker@northlink.com> |
35 | * | 35 | * |
36 | * Fix to work around buggy BIOSes which dont use carry bit correctly | 36 | * Fix to work around buggy BIOSes which don't use carry bit correctly |
37 | * and/or report extended memory in CX/DX for e801h memory size detection | 37 | * and/or report extended memory in CX/DX for e801h memory size detection |
38 | * call. As a result the kernel got wrong figures. The int15/e801h docs | 38 | * call. As a result the kernel got wrong figures. The int15/e801h docs |
39 | * from Ralf Brown interrupt list seem to indicate AX/BX should be used | 39 | * from Ralf Brown interrupt list seem to indicate AX/BX should be used |
@@ -383,7 +383,7 @@ sse_ok: | |||
383 | # a whole bunch of different types, and allows memory holes and | 383 | # a whole bunch of different types, and allows memory holes and |
384 | # everything. We scan through this memory map and build a list | 384 | # everything. We scan through this memory map and build a list |
385 | # of the first 32 memory areas, which we return at [E820MAP]. | 385 | # of the first 32 memory areas, which we return at [E820MAP]. |
386 | # This is documented at http://www.teleport.com/~acpi/acpihtml/topic245.htm | 386 | # This is documented at http://www.acpi.info/, in the ACPI 2.0 specification. |
387 | 387 | ||
388 | #define SMAP 0x534d4150 | 388 | #define SMAP 0x534d4150 |
389 | 389 | ||
@@ -436,7 +436,7 @@ bail820: | |||
436 | 436 | ||
437 | meme801: | 437 | meme801: |
438 | stc # fix to work around buggy | 438 | stc # fix to work around buggy |
439 | xorw %cx,%cx # BIOSes which dont clear/set | 439 | xorw %cx,%cx # BIOSes which don't clear/set |
440 | xorw %dx,%dx # carry on pass/error of | 440 | xorw %dx,%dx # carry on pass/error of |
441 | # e801h memory size call | 441 | # e801h memory size call |
442 | # or merely pass cx,dx though | 442 | # or merely pass cx,dx though |
@@ -733,7 +733,7 @@ flush_instr: | |||
733 | # | 733 | # |
734 | # but we yet haven't reloaded the CS register, so the default size | 734 | # but we yet haven't reloaded the CS register, so the default size |
735 | # of the target offset still is 16 bit. | 735 | # of the target offset still is 16 bit. |
736 | # However, using an operant prefix (0x66), the CPU will properly | 736 | # However, using an operand prefix (0x66), the CPU will properly |
737 | # take our 48 bit far pointer. (INTeL 80386 Programmer's Reference | 737 | # take our 48 bit far pointer. (INTeL 80386 Programmer's Reference |
738 | # Manual, Mixing 16-bit and 32-bit code, page 16-6) | 738 | # Manual, Mixing 16-bit and 32-bit code, page 16-6) |
739 | 739 | ||
diff --git a/arch/x86_64/boot/tools/build.c b/arch/x86_64/boot/tools/build.c index c2fa66313170..18b5bac1c428 100644 --- a/arch/x86_64/boot/tools/build.c +++ b/arch/x86_64/boot/tools/build.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: build.c,v 1.3 2001/06/26 15:14:50 pavel Exp $ | ||
3 | * | ||
4 | * Copyright (C) 1991, 1992 Linus Torvalds | 2 | * Copyright (C) 1991, 1992 Linus Torvalds |
5 | * Copyright (C) 1997 Martin Mares | 3 | * Copyright (C) 1997 Martin Mares |
6 | */ | 4 | */ |
@@ -8,7 +6,8 @@ | |||
8 | /* | 6 | /* |
9 | * This file builds a disk-image from three different files: | 7 | * This file builds a disk-image from three different files: |
10 | * | 8 | * |
11 | * - bootsect: exactly 512 bytes of 8086 machine code, loads the rest | 9 | * - bootsect: compatibility mbr which prints an error message if |
10 | * someone tries to boot the kernel directly. | ||
12 | * - setup: 8086 machine code, sets up system parm | 11 | * - setup: 8086 machine code, sets up system parm |
13 | * - system: 80386 code for actual system | 12 | * - system: 80386 code for actual system |
14 | * | 13 | * |
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S index f3ca0db85b5b..cc935427d532 100644 --- a/arch/x86_64/ia32/ia32entry.S +++ b/arch/x86_64/ia32/ia32entry.S | |||
@@ -589,7 +589,7 @@ ia32_sys_call_table: | |||
589 | .quad compat_sys_mq_timedreceive /* 280 */ | 589 | .quad compat_sys_mq_timedreceive /* 280 */ |
590 | .quad compat_sys_mq_notify | 590 | .quad compat_sys_mq_notify |
591 | .quad compat_sys_mq_getsetattr | 591 | .quad compat_sys_mq_getsetattr |
592 | .quad quiet_ni_syscall /* reserved for kexec */ | 592 | .quad compat_sys_kexec_load /* reserved for kexec */ |
593 | .quad compat_sys_waitid | 593 | .quad compat_sys_waitid |
594 | .quad quiet_ni_syscall /* sys_altroot */ | 594 | .quad quiet_ni_syscall /* sys_altroot */ |
595 | .quad sys_add_key | 595 | .quad sys_add_key |
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile index 5ca4a4598fda..48f9e2c19cd6 100644 --- a/arch/x86_64/kernel/Makefile +++ b/arch/x86_64/kernel/Makefile | |||
@@ -20,6 +20,7 @@ obj-$(CONFIG_SMP) += smp.o smpboot.o trampoline.o | |||
20 | obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o | 20 | obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o |
21 | obj-$(CONFIG_X86_IO_APIC) += io_apic.o mpparse.o \ | 21 | obj-$(CONFIG_X86_IO_APIC) += io_apic.o mpparse.o \ |
22 | genapic.o genapic_cluster.o genapic_flat.o | 22 | genapic.o genapic_cluster.o genapic_flat.o |
23 | obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o | ||
23 | obj-$(CONFIG_PM) += suspend.o | 24 | obj-$(CONFIG_PM) += suspend.o |
24 | obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend_asm.o | 25 | obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend_asm.o |
25 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ | 26 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ |
diff --git a/arch/x86_64/kernel/acpi/wakeup.S b/arch/x86_64/kernel/acpi/wakeup.S index a4c630034cd4..185faa911db5 100644 --- a/arch/x86_64/kernel/acpi/wakeup.S +++ b/arch/x86_64/kernel/acpi/wakeup.S | |||
@@ -67,7 +67,7 @@ wakeup_code: | |||
67 | shll $4, %eax | 67 | shll $4, %eax |
68 | addl $(gdta - wakeup_code), %eax | 68 | addl $(gdta - wakeup_code), %eax |
69 | movl %eax, gdt_48a +2 - wakeup_code | 69 | movl %eax, gdt_48a +2 - wakeup_code |
70 | lgdt %ds:gdt_48a - wakeup_code # load gdt with whatever is | 70 | lgdtl %ds:gdt_48a - wakeup_code # load gdt with whatever is |
71 | # appropriate | 71 | # appropriate |
72 | 72 | ||
73 | movl $1, %eax # protected mode (PE) bit | 73 | movl $1, %eax # protected mode (PE) bit |
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c index f8e6cc4fecd4..375d369570ca 100644 --- a/arch/x86_64/kernel/apic.c +++ b/arch/x86_64/kernel/apic.c | |||
@@ -133,7 +133,7 @@ void __init connect_bsp_APIC(void) | |||
133 | } | 133 | } |
134 | } | 134 | } |
135 | 135 | ||
136 | void disconnect_bsp_APIC(void) | 136 | void disconnect_bsp_APIC(int virt_wire_setup) |
137 | { | 137 | { |
138 | if (pic_mode) { | 138 | if (pic_mode) { |
139 | /* | 139 | /* |
@@ -146,6 +146,42 @@ void disconnect_bsp_APIC(void) | |||
146 | outb(0x70, 0x22); | 146 | outb(0x70, 0x22); |
147 | outb(0x00, 0x23); | 147 | outb(0x00, 0x23); |
148 | } | 148 | } |
149 | else { | ||
150 | /* Go back to Virtual Wire compatibility mode */ | ||
151 | unsigned long value; | ||
152 | |||
153 | /* For the spurious interrupt use vector F, and enable it */ | ||
154 | value = apic_read(APIC_SPIV); | ||
155 | value &= ~APIC_VECTOR_MASK; | ||
156 | value |= APIC_SPIV_APIC_ENABLED; | ||
157 | value |= 0xf; | ||
158 | apic_write_around(APIC_SPIV, value); | ||
159 | |||
160 | if (!virt_wire_setup) { | ||
161 | /* For LVT0 make it edge triggered, active high, external and enabled */ | ||
162 | value = apic_read(APIC_LVT0); | ||
163 | value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | | ||
164 | APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | | ||
165 | APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED ); | ||
166 | value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; | ||
167 | value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT); | ||
168 | apic_write_around(APIC_LVT0, value); | ||
169 | } | ||
170 | else { | ||
171 | /* Disable LVT0 */ | ||
172 | apic_write_around(APIC_LVT0, APIC_LVT_MASKED); | ||
173 | } | ||
174 | |||
175 | /* For LVT1 make it edge triggered, active high, nmi and enabled */ | ||
176 | value = apic_read(APIC_LVT1); | ||
177 | value &= ~( | ||
178 | APIC_MODE_MASK | APIC_SEND_PENDING | | ||
179 | APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | | ||
180 | APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED); | ||
181 | value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; | ||
182 | value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI); | ||
183 | apic_write_around(APIC_LVT1, value); | ||
184 | } | ||
149 | } | 185 | } |
150 | 186 | ||
151 | void disable_local_APIC(void) | 187 | void disable_local_APIC(void) |
@@ -285,7 +321,7 @@ void __init init_bsp_APIC(void) | |||
285 | apic_write_around(APIC_LVT1, value); | 321 | apic_write_around(APIC_LVT1, value); |
286 | } | 322 | } |
287 | 323 | ||
288 | void __init setup_local_APIC (void) | 324 | void __cpuinit setup_local_APIC (void) |
289 | { | 325 | { |
290 | unsigned int value, ver, maxlvt; | 326 | unsigned int value, ver, maxlvt; |
291 | 327 | ||
@@ -534,7 +570,7 @@ static struct sys_device device_lapic = { | |||
534 | .cls = &lapic_sysclass, | 570 | .cls = &lapic_sysclass, |
535 | }; | 571 | }; |
536 | 572 | ||
537 | static void __init apic_pm_activate(void) | 573 | static void __cpuinit apic_pm_activate(void) |
538 | { | 574 | { |
539 | apic_pm_state.active = 1; | 575 | apic_pm_state.active = 1; |
540 | } | 576 | } |
@@ -774,14 +810,14 @@ void __init setup_boot_APIC_clock (void) | |||
774 | local_irq_enable(); | 810 | local_irq_enable(); |
775 | } | 811 | } |
776 | 812 | ||
777 | void __init setup_secondary_APIC_clock(void) | 813 | void __cpuinit setup_secondary_APIC_clock(void) |
778 | { | 814 | { |
779 | local_irq_disable(); /* FIXME: Do we need this? --RR */ | 815 | local_irq_disable(); /* FIXME: Do we need this? --RR */ |
780 | setup_APIC_timer(calibration_result); | 816 | setup_APIC_timer(calibration_result); |
781 | local_irq_enable(); | 817 | local_irq_enable(); |
782 | } | 818 | } |
783 | 819 | ||
784 | void __init disable_APIC_timer(void) | 820 | void __cpuinit disable_APIC_timer(void) |
785 | { | 821 | { |
786 | if (using_apic_timer) { | 822 | if (using_apic_timer) { |
787 | unsigned long v; | 823 | unsigned long v; |
diff --git a/arch/x86_64/kernel/crash.c b/arch/x86_64/kernel/crash.c new file mode 100644 index 000000000000..d7fa4248501c --- /dev/null +++ b/arch/x86_64/kernel/crash.c | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * Architecture specific (x86_64) 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 | |||
18 | #include <asm/processor.h> | ||
19 | #include <asm/hardirq.h> | ||
20 | #include <asm/nmi.h> | ||
21 | #include <asm/hw_irq.h> | ||
22 | |||
23 | note_buf_t crash_notes[NR_CPUS]; | ||
24 | |||
25 | void machine_crash_shutdown(struct pt_regs *regs) | ||
26 | { | ||
27 | /* This function is only called after the system | ||
28 | * has paniced or is otherwise in a critical state. | ||
29 | * The minimum amount of code to allow a kexec'd kernel | ||
30 | * to run successfully needs to happen here. | ||
31 | * | ||
32 | * In practice this means shooting down the other cpus in | ||
33 | * an SMP system. | ||
34 | */ | ||
35 | } | ||
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c index 7c154dfff64a..6ded3a50dfe6 100644 --- a/arch/x86_64/kernel/e820.c +++ b/arch/x86_64/kernel/e820.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/bootmem.h> | 16 | #include <linux/bootmem.h> |
17 | #include <linux/ioport.h> | 17 | #include <linux/ioport.h> |
18 | #include <linux/string.h> | 18 | #include <linux/string.h> |
19 | #include <linux/kexec.h> | ||
19 | #include <asm/page.h> | 20 | #include <asm/page.h> |
20 | #include <asm/e820.h> | 21 | #include <asm/e820.h> |
21 | #include <asm/proto.h> | 22 | #include <asm/proto.h> |
@@ -191,8 +192,6 @@ void __init e820_reserve_resources(void) | |||
191 | int i; | 192 | int i; |
192 | for (i = 0; i < e820.nr_map; i++) { | 193 | for (i = 0; i < e820.nr_map; i++) { |
193 | struct resource *res; | 194 | struct resource *res; |
194 | if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL) | ||
195 | continue; | ||
196 | res = alloc_bootmem_low(sizeof(struct resource)); | 195 | res = alloc_bootmem_low(sizeof(struct resource)); |
197 | switch (e820.map[i].type) { | 196 | switch (e820.map[i].type) { |
198 | case E820_RAM: res->name = "System RAM"; break; | 197 | case E820_RAM: res->name = "System RAM"; break; |
@@ -212,6 +211,9 @@ void __init e820_reserve_resources(void) | |||
212 | */ | 211 | */ |
213 | request_resource(res, &code_resource); | 212 | request_resource(res, &code_resource); |
214 | request_resource(res, &data_resource); | 213 | request_resource(res, &data_resource); |
214 | #ifdef CONFIG_KEXEC | ||
215 | request_resource(res, &crashk_res); | ||
216 | #endif | ||
215 | } | 217 | } |
216 | } | 218 | } |
217 | } | 219 | } |
diff --git a/arch/x86_64/kernel/genapic_flat.c b/arch/x86_64/kernel/genapic_flat.c index b4cbbad04226..282846965080 100644 --- a/arch/x86_64/kernel/genapic_flat.c +++ b/arch/x86_64/kernel/genapic_flat.c | |||
@@ -7,6 +7,8 @@ | |||
7 | * Hacked for x86-64 by James Cleverdon from i386 architecture code by | 7 | * Hacked for x86-64 by James Cleverdon from i386 architecture code by |
8 | * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and | 8 | * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and |
9 | * James Cleverdon. | 9 | * James Cleverdon. |
10 | * Ashok Raj <ashok.raj@intel.com> | ||
11 | * Removed IPI broadcast shortcut to support CPU hotplug | ||
10 | */ | 12 | */ |
11 | #include <linux/config.h> | 13 | #include <linux/config.h> |
12 | #include <linux/threads.h> | 14 | #include <linux/threads.h> |
@@ -18,6 +20,46 @@ | |||
18 | #include <asm/smp.h> | 20 | #include <asm/smp.h> |
19 | #include <asm/ipi.h> | 21 | #include <asm/ipi.h> |
20 | 22 | ||
23 | /* | ||
24 | * The following permit choosing broadcast IPI shortcut v.s sending IPI only | ||
25 | * to online cpus via the send_IPI_mask varient. | ||
26 | * The mask version is my preferred option, since it eliminates a lot of | ||
27 | * other extra code that would need to be written to cleanup intrs sent | ||
28 | * to a CPU while offline. | ||
29 | * | ||
30 | * Sending broadcast introduces lots of trouble in CPU hotplug situations. | ||
31 | * These IPI's are delivered to cpu's irrespective of their offline status | ||
32 | * and could pickup stale intr data when these CPUS are turned online. | ||
33 | * | ||
34 | * Not using broadcast is a cleaner approach IMO, but Andi Kleen disagrees with | ||
35 | * the idea of not using broadcast IPI's anymore. Hence the run time check | ||
36 | * is introduced, on his request so we can choose an alternate mechanism. | ||
37 | * | ||
38 | * Initial wacky performance tests that collect cycle counts show | ||
39 | * no increase in using mask v.s broadcast version. In fact they seem | ||
40 | * identical in terms of cycle counts. | ||
41 | * | ||
42 | * if we need to use broadcast, we need to do the following. | ||
43 | * | ||
44 | * cli; | ||
45 | * hold call_lock; | ||
46 | * clear any pending IPI, just ack and clear all pending intr | ||
47 | * set cpu_online_map; | ||
48 | * release call_lock; | ||
49 | * sti; | ||
50 | * | ||
51 | * The complicated dummy irq processing shown above is not required if | ||
52 | * we didnt sent IPI's to wrong CPU's in the first place. | ||
53 | * | ||
54 | * - Ashok Raj <ashok.raj@intel.com> | ||
55 | */ | ||
56 | #ifdef CONFIG_HOTPLUG_CPU | ||
57 | #define DEFAULT_SEND_IPI (1) | ||
58 | #else | ||
59 | #define DEFAULT_SEND_IPI (0) | ||
60 | #endif | ||
61 | |||
62 | static int no_broadcast=DEFAULT_SEND_IPI; | ||
21 | 63 | ||
22 | static cpumask_t flat_target_cpus(void) | 64 | static cpumask_t flat_target_cpus(void) |
23 | { | 65 | { |
@@ -45,22 +87,6 @@ static void flat_init_apic_ldr(void) | |||
45 | apic_write_around(APIC_LDR, val); | 87 | apic_write_around(APIC_LDR, val); |
46 | } | 88 | } |
47 | 89 | ||
48 | static void flat_send_IPI_allbutself(int vector) | ||
49 | { | ||
50 | /* | ||
51 | * if there are no other CPUs in the system then | ||
52 | * we get an APIC send error if we try to broadcast. | ||
53 | * thus we have to avoid sending IPIs in this case. | ||
54 | */ | ||
55 | if (num_online_cpus() > 1) | ||
56 | __send_IPI_shortcut(APIC_DEST_ALLBUT, vector, APIC_DEST_LOGICAL); | ||
57 | } | ||
58 | |||
59 | static void flat_send_IPI_all(int vector) | ||
60 | { | ||
61 | __send_IPI_shortcut(APIC_DEST_ALLINC, vector, APIC_DEST_LOGICAL); | ||
62 | } | ||
63 | |||
64 | static void flat_send_IPI_mask(cpumask_t cpumask, int vector) | 90 | static void flat_send_IPI_mask(cpumask_t cpumask, int vector) |
65 | { | 91 | { |
66 | unsigned long mask = cpus_addr(cpumask)[0]; | 92 | unsigned long mask = cpus_addr(cpumask)[0]; |
@@ -93,6 +119,39 @@ static void flat_send_IPI_mask(cpumask_t cpumask, int vector) | |||
93 | local_irq_restore(flags); | 119 | local_irq_restore(flags); |
94 | } | 120 | } |
95 | 121 | ||
122 | static inline void __local_flat_send_IPI_allbutself(int vector) | ||
123 | { | ||
124 | if (no_broadcast) { | ||
125 | cpumask_t mask = cpu_online_map; | ||
126 | int this_cpu = get_cpu(); | ||
127 | |||
128 | cpu_clear(this_cpu, mask); | ||
129 | flat_send_IPI_mask(mask, vector); | ||
130 | put_cpu(); | ||
131 | } | ||
132 | else | ||
133 | __send_IPI_shortcut(APIC_DEST_ALLBUT, vector, APIC_DEST_LOGICAL); | ||
134 | } | ||
135 | |||
136 | static inline void __local_flat_send_IPI_all(int vector) | ||
137 | { | ||
138 | if (no_broadcast) | ||
139 | flat_send_IPI_mask(cpu_online_map, vector); | ||
140 | else | ||
141 | __send_IPI_shortcut(APIC_DEST_ALLINC, vector, APIC_DEST_LOGICAL); | ||
142 | } | ||
143 | |||
144 | static void flat_send_IPI_allbutself(int vector) | ||
145 | { | ||
146 | if (((num_online_cpus()) - 1) >= 1) | ||
147 | __local_flat_send_IPI_allbutself(vector); | ||
148 | } | ||
149 | |||
150 | static void flat_send_IPI_all(int vector) | ||
151 | { | ||
152 | __local_flat_send_IPI_all(vector); | ||
153 | } | ||
154 | |||
96 | static int flat_apic_id_registered(void) | 155 | static int flat_apic_id_registered(void) |
97 | { | 156 | { |
98 | return physid_isset(GET_APIC_ID(apic_read(APIC_ID)), phys_cpu_present_map); | 157 | return physid_isset(GET_APIC_ID(apic_read(APIC_ID)), phys_cpu_present_map); |
@@ -111,6 +170,16 @@ static unsigned int phys_pkg_id(int index_msb) | |||
111 | return ((ebx >> 24) & 0xFF) >> index_msb; | 170 | return ((ebx >> 24) & 0xFF) >> index_msb; |
112 | } | 171 | } |
113 | 172 | ||
173 | static __init int no_ipi_broadcast(char *str) | ||
174 | { | ||
175 | get_option(&str, &no_broadcast); | ||
176 | printk ("Using %s mode\n", no_broadcast ? "No IPI Broadcast" : | ||
177 | "IPI Broadcast"); | ||
178 | return 1; | ||
179 | } | ||
180 | |||
181 | __setup("no_ipi_broadcast", no_ipi_broadcast); | ||
182 | |||
114 | struct genapic apic_flat = { | 183 | struct genapic apic_flat = { |
115 | .name = "flat", | 184 | .name = "flat", |
116 | .int_delivery_mode = dest_LowestPrio, | 185 | .int_delivery_mode = dest_LowestPrio, |
@@ -125,3 +194,12 @@ struct genapic apic_flat = { | |||
125 | .cpu_mask_to_apicid = flat_cpu_mask_to_apicid, | 194 | .cpu_mask_to_apicid = flat_cpu_mask_to_apicid, |
126 | .phys_pkg_id = phys_pkg_id, | 195 | .phys_pkg_id = phys_pkg_id, |
127 | }; | 196 | }; |
197 | |||
198 | static int __init print_ipi_mode(void) | ||
199 | { | ||
200 | printk ("Using IPI %s mode\n", no_broadcast ? "No-Shortcut" : | ||
201 | "Shortcut"); | ||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | late_initcall(print_ipi_mode); | ||
diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S index 9bd2e7a4b81e..8d765aa77a26 100644 --- a/arch/x86_64/kernel/head.S +++ b/arch/x86_64/kernel/head.S | |||
@@ -248,23 +248,23 @@ ENTRY(_stext) | |||
248 | */ | 248 | */ |
249 | .org 0x1000 | 249 | .org 0x1000 |
250 | ENTRY(init_level4_pgt) | 250 | ENTRY(init_level4_pgt) |
251 | .quad 0x0000000000102007 /* -> level3_ident_pgt */ | 251 | .quad 0x0000000000002007 + __PHYSICAL_START /* -> level3_ident_pgt */ |
252 | .fill 255,8,0 | 252 | .fill 255,8,0 |
253 | .quad 0x000000000010a007 | 253 | .quad 0x000000000000a007 + __PHYSICAL_START |
254 | .fill 254,8,0 | 254 | .fill 254,8,0 |
255 | /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ | 255 | /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ |
256 | .quad 0x0000000000103007 /* -> level3_kernel_pgt */ | 256 | .quad 0x0000000000003007 + __PHYSICAL_START /* -> level3_kernel_pgt */ |
257 | 257 | ||
258 | .org 0x2000 | 258 | .org 0x2000 |
259 | ENTRY(level3_ident_pgt) | 259 | ENTRY(level3_ident_pgt) |
260 | .quad 0x0000000000104007 | 260 | .quad 0x0000000000004007 + __PHYSICAL_START |
261 | .fill 511,8,0 | 261 | .fill 511,8,0 |
262 | 262 | ||
263 | .org 0x3000 | 263 | .org 0x3000 |
264 | ENTRY(level3_kernel_pgt) | 264 | ENTRY(level3_kernel_pgt) |
265 | .fill 510,8,0 | 265 | .fill 510,8,0 |
266 | /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */ | 266 | /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */ |
267 | .quad 0x0000000000105007 /* -> level2_kernel_pgt */ | 267 | .quad 0x0000000000005007 + __PHYSICAL_START /* -> level2_kernel_pgt */ |
268 | .fill 1,8,0 | 268 | .fill 1,8,0 |
269 | 269 | ||
270 | .org 0x4000 | 270 | .org 0x4000 |
@@ -337,17 +337,17 @@ ENTRY(empty_bad_pmd_table) | |||
337 | 337 | ||
338 | .org 0xa000 | 338 | .org 0xa000 |
339 | ENTRY(level3_physmem_pgt) | 339 | ENTRY(level3_physmem_pgt) |
340 | .quad 0x0000000000105007 /* -> level2_kernel_pgt (so that __va works even before pagetable_init) */ | 340 | .quad 0x0000000000005007 + __PHYSICAL_START /* -> level2_kernel_pgt (so that __va works even before pagetable_init) */ |
341 | 341 | ||
342 | .org 0xb000 | 342 | .org 0xb000 |
343 | #ifdef CONFIG_ACPI_SLEEP | 343 | #ifdef CONFIG_ACPI_SLEEP |
344 | ENTRY(wakeup_level4_pgt) | 344 | ENTRY(wakeup_level4_pgt) |
345 | .quad 0x0000000000102007 /* -> level3_ident_pgt */ | 345 | .quad 0x0000000000002007 + __PHYSICAL_START /* -> level3_ident_pgt */ |
346 | .fill 255,8,0 | 346 | .fill 255,8,0 |
347 | .quad 0x000000000010a007 | 347 | .quad 0x000000000000a007 + __PHYSICAL_START |
348 | .fill 254,8,0 | 348 | .fill 254,8,0 |
349 | /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ | 349 | /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ |
350 | .quad 0x0000000000103007 /* -> level3_kernel_pgt */ | 350 | .quad 0x0000000000003007 + __PHYSICAL_START /* -> level3_kernel_pgt */ |
351 | #endif | 351 | #endif |
352 | 352 | ||
353 | .data | 353 | .data |
diff --git a/arch/x86_64/kernel/i387.c b/arch/x86_64/kernel/i387.c index ba139cac57ce..d9b22b633e39 100644 --- a/arch/x86_64/kernel/i387.c +++ b/arch/x86_64/kernel/i387.c | |||
@@ -42,7 +42,7 @@ void mxcsr_feature_mask_init(void) | |||
42 | * Called at bootup to set up the initial FPU state that is later cloned | 42 | * Called at bootup to set up the initial FPU state that is later cloned |
43 | * into all processes. | 43 | * into all processes. |
44 | */ | 44 | */ |
45 | void __init fpu_init(void) | 45 | void __cpuinit fpu_init(void) |
46 | { | 46 | { |
47 | unsigned long oldcr0 = read_cr0(); | 47 | unsigned long oldcr0 = read_cr0(); |
48 | extern void __bad_fxsave_alignment(void); | 48 | extern void __bad_fxsave_alignment(void); |
diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c index 19eafa0aa95c..a89169095129 100644 --- a/arch/x86_64/kernel/i8259.c +++ b/arch/x86_64/kernel/i8259.c | |||
@@ -414,10 +414,22 @@ static int i8259A_suspend(struct sys_device *dev, pm_message_t state) | |||
414 | return 0; | 414 | return 0; |
415 | } | 415 | } |
416 | 416 | ||
417 | static int i8259A_shutdown(struct sys_device *dev) | ||
418 | { | ||
419 | /* Put the i8259A into a quiescent state that | ||
420 | * the kernel initialization code can get it | ||
421 | * out of. | ||
422 | */ | ||
423 | outb(0xff, 0x21); /* mask all of 8259A-1 */ | ||
424 | outb(0xff, 0xA1); /* mask all of 8259A-1 */ | ||
425 | return 0; | ||
426 | } | ||
427 | |||
417 | static struct sysdev_class i8259_sysdev_class = { | 428 | static struct sysdev_class i8259_sysdev_class = { |
418 | set_kset_name("i8259"), | 429 | set_kset_name("i8259"), |
419 | .suspend = i8259A_suspend, | 430 | .suspend = i8259A_suspend, |
420 | .resume = i8259A_resume, | 431 | .resume = i8259A_resume, |
432 | .shutdown = i8259A_shutdown, | ||
421 | }; | 433 | }; |
422 | 434 | ||
423 | static struct sys_device device_i8259A = { | 435 | static struct sys_device device_i8259A = { |
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index afd87e64d0a8..157190d986bb 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c | |||
@@ -330,7 +330,7 @@ static int find_irq_entry(int apic, int pin, int type) | |||
330 | /* | 330 | /* |
331 | * Find the pin to which IRQ[irq] (ISA) is connected | 331 | * Find the pin to which IRQ[irq] (ISA) is connected |
332 | */ | 332 | */ |
333 | static int __init find_isa_irq_pin(int irq, int type) | 333 | static int find_isa_irq_pin(int irq, int type) |
334 | { | 334 | { |
335 | int i; | 335 | int i; |
336 | 336 | ||
@@ -1132,12 +1132,44 @@ static void __init enable_IO_APIC(void) | |||
1132 | */ | 1132 | */ |
1133 | void disable_IO_APIC(void) | 1133 | void disable_IO_APIC(void) |
1134 | { | 1134 | { |
1135 | int pin; | ||
1135 | /* | 1136 | /* |
1136 | * Clear the IO-APIC before rebooting: | 1137 | * Clear the IO-APIC before rebooting: |
1137 | */ | 1138 | */ |
1138 | clear_IO_APIC(); | 1139 | clear_IO_APIC(); |
1139 | 1140 | ||
1140 | disconnect_bsp_APIC(); | 1141 | /* |
1142 | * If the i82559 is routed through an IOAPIC | ||
1143 | * Put that IOAPIC in virtual wire mode | ||
1144 | * so legacy interrups can be delivered. | ||
1145 | */ | ||
1146 | pin = find_isa_irq_pin(0, mp_ExtINT); | ||
1147 | if (pin != -1) { | ||
1148 | struct IO_APIC_route_entry entry; | ||
1149 | unsigned long flags; | ||
1150 | |||
1151 | memset(&entry, 0, sizeof(entry)); | ||
1152 | entry.mask = 0; /* Enabled */ | ||
1153 | entry.trigger = 0; /* Edge */ | ||
1154 | entry.irr = 0; | ||
1155 | entry.polarity = 0; /* High */ | ||
1156 | entry.delivery_status = 0; | ||
1157 | entry.dest_mode = 0; /* Physical */ | ||
1158 | entry.delivery_mode = 7; /* ExtInt */ | ||
1159 | entry.vector = 0; | ||
1160 | entry.dest.physical.physical_dest = 0; | ||
1161 | |||
1162 | |||
1163 | /* | ||
1164 | * Add it to the IO-APIC irq-routing table: | ||
1165 | */ | ||
1166 | spin_lock_irqsave(&ioapic_lock, flags); | ||
1167 | io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1)); | ||
1168 | io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0)); | ||
1169 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
1170 | } | ||
1171 | |||
1172 | disconnect_bsp_APIC(pin != -1); | ||
1141 | } | 1173 | } |
1142 | 1174 | ||
1143 | /* | 1175 | /* |
diff --git a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c index 62b112e4deb4..cc3fb85f5145 100644 --- a/arch/x86_64/kernel/irq.c +++ b/arch/x86_64/kernel/irq.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
15 | #include <linux/seq_file.h> | 15 | #include <linux/seq_file.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/delay.h> | ||
17 | #include <asm/uaccess.h> | 18 | #include <asm/uaccess.h> |
18 | #include <asm/io_apic.h> | 19 | #include <asm/io_apic.h> |
19 | 20 | ||
@@ -106,3 +107,31 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs) | |||
106 | return 1; | 107 | return 1; |
107 | } | 108 | } |
108 | 109 | ||
110 | #ifdef CONFIG_HOTPLUG_CPU | ||
111 | void fixup_irqs(cpumask_t map) | ||
112 | { | ||
113 | unsigned int irq; | ||
114 | static int warned; | ||
115 | |||
116 | for (irq = 0; irq < NR_IRQS; irq++) { | ||
117 | cpumask_t mask; | ||
118 | if (irq == 2) | ||
119 | continue; | ||
120 | |||
121 | cpus_and(mask, irq_affinity[irq], map); | ||
122 | if (any_online_cpu(mask) == NR_CPUS) { | ||
123 | printk("Breaking affinity for irq %i\n", irq); | ||
124 | mask = map; | ||
125 | } | ||
126 | if (irq_desc[irq].handler->set_affinity) | ||
127 | irq_desc[irq].handler->set_affinity(irq, mask); | ||
128 | else if (irq_desc[irq].action && !(warned++)) | ||
129 | printk("Cannot set affinity for irq %i\n", irq); | ||
130 | } | ||
131 | |||
132 | /* That doesn't seem sufficient. Give it 1ms. */ | ||
133 | local_irq_enable(); | ||
134 | mdelay(1); | ||
135 | local_irq_disable(); | ||
136 | } | ||
137 | #endif | ||
diff --git a/arch/x86_64/kernel/machine_kexec.c b/arch/x86_64/kernel/machine_kexec.c new file mode 100644 index 000000000000..60d1eff41567 --- /dev/null +++ b/arch/x86_64/kernel/machine_kexec.c | |||
@@ -0,0 +1,250 @@ | |||
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 <linux/string.h> | ||
13 | #include <linux/reboot.h> | ||
14 | #include <asm/pda.h> | ||
15 | #include <asm/pgtable.h> | ||
16 | #include <asm/pgalloc.h> | ||
17 | #include <asm/tlbflush.h> | ||
18 | #include <asm/mmu_context.h> | ||
19 | #include <asm/io.h> | ||
20 | #include <asm/apic.h> | ||
21 | #include <asm/cpufeature.h> | ||
22 | #include <asm/hw_irq.h> | ||
23 | |||
24 | #define LEVEL0_SIZE (1UL << 12UL) | ||
25 | #define LEVEL1_SIZE (1UL << 21UL) | ||
26 | #define LEVEL2_SIZE (1UL << 30UL) | ||
27 | #define LEVEL3_SIZE (1UL << 39UL) | ||
28 | #define LEVEL4_SIZE (1UL << 48UL) | ||
29 | |||
30 | #define L0_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) | ||
31 | #define L1_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_PSE) | ||
32 | #define L2_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) | ||
33 | #define L3_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) | ||
34 | |||
35 | static void init_level2_page(u64 *level2p, unsigned long addr) | ||
36 | { | ||
37 | unsigned long end_addr; | ||
38 | |||
39 | addr &= PAGE_MASK; | ||
40 | end_addr = addr + LEVEL2_SIZE; | ||
41 | while (addr < end_addr) { | ||
42 | *(level2p++) = addr | L1_ATTR; | ||
43 | addr += LEVEL1_SIZE; | ||
44 | } | ||
45 | } | ||
46 | |||
47 | static int init_level3_page(struct kimage *image, u64 *level3p, | ||
48 | unsigned long addr, unsigned long last_addr) | ||
49 | { | ||
50 | unsigned long end_addr; | ||
51 | int result; | ||
52 | |||
53 | result = 0; | ||
54 | addr &= PAGE_MASK; | ||
55 | end_addr = addr + LEVEL3_SIZE; | ||
56 | while ((addr < last_addr) && (addr < end_addr)) { | ||
57 | struct page *page; | ||
58 | u64 *level2p; | ||
59 | |||
60 | page = kimage_alloc_control_pages(image, 0); | ||
61 | if (!page) { | ||
62 | result = -ENOMEM; | ||
63 | goto out; | ||
64 | } | ||
65 | level2p = (u64 *)page_address(page); | ||
66 | init_level2_page(level2p, addr); | ||
67 | *(level3p++) = __pa(level2p) | L2_ATTR; | ||
68 | addr += LEVEL2_SIZE; | ||
69 | } | ||
70 | /* clear the unused entries */ | ||
71 | while (addr < end_addr) { | ||
72 | *(level3p++) = 0; | ||
73 | addr += LEVEL2_SIZE; | ||
74 | } | ||
75 | out: | ||
76 | return result; | ||
77 | } | ||
78 | |||
79 | |||
80 | static int init_level4_page(struct kimage *image, u64 *level4p, | ||
81 | unsigned long addr, unsigned long last_addr) | ||
82 | { | ||
83 | unsigned long end_addr; | ||
84 | int result; | ||
85 | |||
86 | result = 0; | ||
87 | addr &= PAGE_MASK; | ||
88 | end_addr = addr + LEVEL4_SIZE; | ||
89 | while ((addr < last_addr) && (addr < end_addr)) { | ||
90 | struct page *page; | ||
91 | u64 *level3p; | ||
92 | |||
93 | page = kimage_alloc_control_pages(image, 0); | ||
94 | if (!page) { | ||
95 | result = -ENOMEM; | ||
96 | goto out; | ||
97 | } | ||
98 | level3p = (u64 *)page_address(page); | ||
99 | result = init_level3_page(image, level3p, addr, last_addr); | ||
100 | if (result) { | ||
101 | goto out; | ||
102 | } | ||
103 | *(level4p++) = __pa(level3p) | L3_ATTR; | ||
104 | addr += LEVEL3_SIZE; | ||
105 | } | ||
106 | /* clear the unused entries */ | ||
107 | while (addr < end_addr) { | ||
108 | *(level4p++) = 0; | ||
109 | addr += LEVEL3_SIZE; | ||
110 | } | ||
111 | out: | ||
112 | return result; | ||
113 | } | ||
114 | |||
115 | |||
116 | static int init_pgtable(struct kimage *image, unsigned long start_pgtable) | ||
117 | { | ||
118 | u64 *level4p; | ||
119 | level4p = (u64 *)__va(start_pgtable); | ||
120 | return init_level4_page(image, level4p, 0, end_pfn << PAGE_SHIFT); | ||
121 | } | ||
122 | |||
123 | static void set_idt(void *newidt, u16 limit) | ||
124 | { | ||
125 | unsigned char curidt[10]; | ||
126 | |||
127 | /* x86-64 supports unaliged loads & stores */ | ||
128 | (*(u16 *)(curidt)) = limit; | ||
129 | (*(u64 *)(curidt +2)) = (unsigned long)(newidt); | ||
130 | |||
131 | __asm__ __volatile__ ( | ||
132 | "lidt %0\n" | ||
133 | : "=m" (curidt) | ||
134 | ); | ||
135 | }; | ||
136 | |||
137 | |||
138 | static void set_gdt(void *newgdt, u16 limit) | ||
139 | { | ||
140 | unsigned char curgdt[10]; | ||
141 | |||
142 | /* x86-64 supports unaligned loads & stores */ | ||
143 | (*(u16 *)(curgdt)) = limit; | ||
144 | (*(u64 *)(curgdt +2)) = (unsigned long)(newgdt); | ||
145 | |||
146 | __asm__ __volatile__ ( | ||
147 | "lgdt %0\n" | ||
148 | : "=m" (curgdt) | ||
149 | ); | ||
150 | }; | ||
151 | |||
152 | static void load_segments(void) | ||
153 | { | ||
154 | __asm__ __volatile__ ( | ||
155 | "\tmovl $"STR(__KERNEL_DS)",%eax\n" | ||
156 | "\tmovl %eax,%ds\n" | ||
157 | "\tmovl %eax,%es\n" | ||
158 | "\tmovl %eax,%ss\n" | ||
159 | "\tmovl %eax,%fs\n" | ||
160 | "\tmovl %eax,%gs\n" | ||
161 | ); | ||
162 | #undef STR | ||
163 | #undef __STR | ||
164 | } | ||
165 | |||
166 | typedef NORET_TYPE void (*relocate_new_kernel_t)(unsigned long indirection_page, | ||
167 | unsigned long control_code_buffer, | ||
168 | unsigned long start_address, | ||
169 | unsigned long pgtable) ATTRIB_NORET; | ||
170 | |||
171 | const extern unsigned char relocate_new_kernel[]; | ||
172 | const extern unsigned long relocate_new_kernel_size; | ||
173 | |||
174 | int machine_kexec_prepare(struct kimage *image) | ||
175 | { | ||
176 | unsigned long start_pgtable, control_code_buffer; | ||
177 | int result; | ||
178 | |||
179 | /* Calculate the offsets */ | ||
180 | start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT; | ||
181 | control_code_buffer = start_pgtable + 4096UL; | ||
182 | |||
183 | /* Setup the identity mapped 64bit page table */ | ||
184 | result = init_pgtable(image, start_pgtable); | ||
185 | if (result) | ||
186 | return result; | ||
187 | |||
188 | /* Place the code in the reboot code buffer */ | ||
189 | memcpy(__va(control_code_buffer), relocate_new_kernel, | ||
190 | relocate_new_kernel_size); | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | void machine_kexec_cleanup(struct kimage *image) | ||
196 | { | ||
197 | return; | ||
198 | } | ||
199 | |||
200 | /* | ||
201 | * Do not allocate memory (or fail in any way) in machine_kexec(). | ||
202 | * We are past the point of no return, committed to rebooting now. | ||
203 | */ | ||
204 | NORET_TYPE void machine_kexec(struct kimage *image) | ||
205 | { | ||
206 | unsigned long page_list; | ||
207 | unsigned long control_code_buffer; | ||
208 | unsigned long start_pgtable; | ||
209 | relocate_new_kernel_t rnk; | ||
210 | |||
211 | /* Interrupts aren't acceptable while we reboot */ | ||
212 | local_irq_disable(); | ||
213 | |||
214 | /* Calculate the offsets */ | ||
215 | page_list = image->head; | ||
216 | start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT; | ||
217 | control_code_buffer = start_pgtable + 4096UL; | ||
218 | |||
219 | /* Set the low half of the page table to my identity mapped | ||
220 | * page table for kexec. Leave the high half pointing at the | ||
221 | * kernel pages. Don't bother to flush the global pages | ||
222 | * as that will happen when I fully switch to my identity mapped | ||
223 | * page table anyway. | ||
224 | */ | ||
225 | memcpy(__va(read_cr3()), __va(start_pgtable), PAGE_SIZE/2); | ||
226 | __flush_tlb(); | ||
227 | |||
228 | |||
229 | /* The segment registers are funny things, they are | ||
230 | * automatically loaded from a table, in memory wherever you | ||
231 | * set them to a specific selector, but this table is never | ||
232 | * accessed again unless you set the segment to a different selector. | ||
233 | * | ||
234 | * The more common model are caches where the behide | ||
235 | * the scenes work is done, but is also dropped at arbitrary | ||
236 | * times. | ||
237 | * | ||
238 | * I take advantage of this here by force loading the | ||
239 | * segments, before I zap the gdt with an invalid value. | ||
240 | */ | ||
241 | load_segments(); | ||
242 | /* The gdt & idt are now invalid. | ||
243 | * If you want to load them you must set up your own idt & gdt. | ||
244 | */ | ||
245 | set_gdt(phys_to_virt(0),0); | ||
246 | set_idt(phys_to_virt(0),0); | ||
247 | /* now call it */ | ||
248 | rnk = (relocate_new_kernel_t) control_code_buffer; | ||
249 | (*rnk)(page_list, control_code_buffer, image->start, start_pgtable); | ||
250 | } | ||
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index 3a89d735a4f6..21e70625a495 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c | |||
@@ -327,7 +327,7 @@ static void mce_init(void *dummy) | |||
327 | } | 327 | } |
328 | 328 | ||
329 | /* Add per CPU specific workarounds here */ | 329 | /* Add per CPU specific workarounds here */ |
330 | static void __init mce_cpu_quirks(struct cpuinfo_x86 *c) | 330 | static void __cpuinit mce_cpu_quirks(struct cpuinfo_x86 *c) |
331 | { | 331 | { |
332 | /* This should be disabled by the BIOS, but isn't always */ | 332 | /* This should be disabled by the BIOS, but isn't always */ |
333 | if (c->x86_vendor == X86_VENDOR_AMD && c->x86 == 15) { | 333 | if (c->x86_vendor == X86_VENDOR_AMD && c->x86 == 15) { |
@@ -337,7 +337,7 @@ static void __init mce_cpu_quirks(struct cpuinfo_x86 *c) | |||
337 | } | 337 | } |
338 | } | 338 | } |
339 | 339 | ||
340 | static void __init mce_cpu_features(struct cpuinfo_x86 *c) | 340 | static void __cpuinit mce_cpu_features(struct cpuinfo_x86 *c) |
341 | { | 341 | { |
342 | switch (c->x86_vendor) { | 342 | switch (c->x86_vendor) { |
343 | case X86_VENDOR_INTEL: | 343 | case X86_VENDOR_INTEL: |
@@ -352,7 +352,7 @@ static void __init mce_cpu_features(struct cpuinfo_x86 *c) | |||
352 | * Called for each booted CPU to set up machine checks. | 352 | * Called for each booted CPU to set up machine checks. |
353 | * Must be called with preempt off. | 353 | * Must be called with preempt off. |
354 | */ | 354 | */ |
355 | void __init mcheck_init(struct cpuinfo_x86 *c) | 355 | void __cpuinit mcheck_init(struct cpuinfo_x86 *c) |
356 | { | 356 | { |
357 | static cpumask_t mce_cpus __initdata = CPU_MASK_NONE; | 357 | static cpumask_t mce_cpus __initdata = CPU_MASK_NONE; |
358 | 358 | ||
@@ -411,7 +411,7 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, loff | |||
411 | memset(mcelog.entry, 0, next * sizeof(struct mce)); | 411 | memset(mcelog.entry, 0, next * sizeof(struct mce)); |
412 | mcelog.next = 0; | 412 | mcelog.next = 0; |
413 | 413 | ||
414 | synchronize_kernel(); | 414 | synchronize_sched(); |
415 | 415 | ||
416 | /* Collect entries that were still getting written before the synchronize. */ | 416 | /* Collect entries that were still getting written before the synchronize. */ |
417 | 417 | ||
@@ -542,7 +542,7 @@ ACCESSOR(bank4ctl,bank[4],mce_restart()) | |||
542 | ACCESSOR(tolerant,tolerant,) | 542 | ACCESSOR(tolerant,tolerant,) |
543 | ACCESSOR(check_interval,check_interval,mce_restart()) | 543 | ACCESSOR(check_interval,check_interval,mce_restart()) |
544 | 544 | ||
545 | static __init int mce_init_device(void) | 545 | static __cpuinit int mce_init_device(void) |
546 | { | 546 | { |
547 | int err; | 547 | int err; |
548 | if (!mce_available(&boot_cpu_data)) | 548 | if (!mce_available(&boot_cpu_data)) |
diff --git a/arch/x86_64/kernel/mce_intel.c b/arch/x86_64/kernel/mce_intel.c index 4db9a640069f..0be0a7959814 100644 --- a/arch/x86_64/kernel/mce_intel.c +++ b/arch/x86_64/kernel/mce_intel.c | |||
@@ -42,7 +42,7 @@ done: | |||
42 | irq_exit(); | 42 | irq_exit(); |
43 | } | 43 | } |
44 | 44 | ||
45 | static void __init intel_init_thermal(struct cpuinfo_x86 *c) | 45 | static void __cpuinit intel_init_thermal(struct cpuinfo_x86 *c) |
46 | { | 46 | { |
47 | u32 l, h; | 47 | u32 l, h; |
48 | int tm2 = 0; | 48 | int tm2 = 0; |
@@ -93,7 +93,7 @@ static void __init intel_init_thermal(struct cpuinfo_x86 *c) | |||
93 | return; | 93 | return; |
94 | } | 94 | } |
95 | 95 | ||
96 | void __init mce_intel_feature_init(struct cpuinfo_x86 *c) | 96 | void __cpuinit mce_intel_feature_init(struct cpuinfo_x86 *c) |
97 | { | 97 | { |
98 | intel_init_thermal(c); | 98 | intel_init_thermal(c); |
99 | } | 99 | } |
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index 31c0f2e6ac91..4e44d6e6b7e5 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c | |||
@@ -98,7 +98,7 @@ static unsigned int nmi_p4_cccr_val; | |||
98 | (P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \ | 98 | (P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \ |
99 | P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE) | 99 | P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE) |
100 | 100 | ||
101 | static __init inline int nmi_known_cpu(void) | 101 | static __cpuinit inline int nmi_known_cpu(void) |
102 | { | 102 | { |
103 | switch (boot_cpu_data.x86_vendor) { | 103 | switch (boot_cpu_data.x86_vendor) { |
104 | case X86_VENDOR_AMD: | 104 | case X86_VENDOR_AMD: |
@@ -110,7 +110,7 @@ static __init inline int nmi_known_cpu(void) | |||
110 | } | 110 | } |
111 | 111 | ||
112 | /* Run after command line and cpu_init init, but before all other checks */ | 112 | /* Run after command line and cpu_init init, but before all other checks */ |
113 | void __init nmi_watchdog_default(void) | 113 | void __cpuinit nmi_watchdog_default(void) |
114 | { | 114 | { |
115 | if (nmi_watchdog != NMI_DEFAULT) | 115 | if (nmi_watchdog != NMI_DEFAULT) |
116 | return; | 116 | return; |
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index e59d1f9d6163..1d91271796e5 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c | |||
@@ -8,7 +8,8 @@ | |||
8 | * | 8 | * |
9 | * X86-64 port | 9 | * X86-64 port |
10 | * Andi Kleen. | 10 | * Andi Kleen. |
11 | * | 11 | * |
12 | * CPU hotplug support - ashok.raj@intel.com | ||
12 | * $Id: process.c,v 1.38 2002/01/15 10:08:03 ak Exp $ | 13 | * $Id: process.c,v 1.38 2002/01/15 10:08:03 ak Exp $ |
13 | */ | 14 | */ |
14 | 15 | ||
@@ -18,6 +19,7 @@ | |||
18 | 19 | ||
19 | #include <stdarg.h> | 20 | #include <stdarg.h> |
20 | 21 | ||
22 | #include <linux/cpu.h> | ||
21 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
22 | #include <linux/sched.h> | 24 | #include <linux/sched.h> |
23 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
@@ -154,6 +156,29 @@ void cpu_idle_wait(void) | |||
154 | } | 156 | } |
155 | EXPORT_SYMBOL_GPL(cpu_idle_wait); | 157 | EXPORT_SYMBOL_GPL(cpu_idle_wait); |
156 | 158 | ||
159 | #ifdef CONFIG_HOTPLUG_CPU | ||
160 | DECLARE_PER_CPU(int, cpu_state); | ||
161 | |||
162 | #include <asm/nmi.h> | ||
163 | /* We don't actually take CPU down, just spin without interrupts. */ | ||
164 | static inline void play_dead(void) | ||
165 | { | ||
166 | idle_task_exit(); | ||
167 | wbinvd(); | ||
168 | mb(); | ||
169 | /* Ack it */ | ||
170 | __get_cpu_var(cpu_state) = CPU_DEAD; | ||
171 | |||
172 | while (1) | ||
173 | safe_halt(); | ||
174 | } | ||
175 | #else | ||
176 | static inline void play_dead(void) | ||
177 | { | ||
178 | BUG(); | ||
179 | } | ||
180 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
181 | |||
157 | /* | 182 | /* |
158 | * The idle thread. There's no useful work to be | 183 | * The idle thread. There's no useful work to be |
159 | * done, so just try to conserve power and have a | 184 | * done, so just try to conserve power and have a |
@@ -174,6 +199,8 @@ void cpu_idle (void) | |||
174 | idle = pm_idle; | 199 | idle = pm_idle; |
175 | if (!idle) | 200 | if (!idle) |
176 | idle = default_idle; | 201 | idle = default_idle; |
202 | if (cpu_is_offline(smp_processor_id())) | ||
203 | play_dead(); | ||
177 | idle(); | 204 | idle(); |
178 | } | 205 | } |
179 | 206 | ||
@@ -204,7 +231,7 @@ static void mwait_idle(void) | |||
204 | } | 231 | } |
205 | } | 232 | } |
206 | 233 | ||
207 | void __init select_idle_routine(const struct cpuinfo_x86 *c) | 234 | void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) |
208 | { | 235 | { |
209 | static int printed; | 236 | static int printed; |
210 | if (cpu_has(c, X86_FEATURE_MWAIT)) { | 237 | if (cpu_has(c, X86_FEATURE_MWAIT)) { |
diff --git a/arch/x86_64/kernel/reboot.c b/arch/x86_64/kernel/reboot.c index be4b36f762cf..57e71dbdfd69 100644 --- a/arch/x86_64/kernel/reboot.c +++ b/arch/x86_64/kernel/reboot.c | |||
@@ -66,41 +66,47 @@ static int __init reboot_setup(char *str) | |||
66 | 66 | ||
67 | __setup("reboot=", reboot_setup); | 67 | __setup("reboot=", reboot_setup); |
68 | 68 | ||
69 | #ifdef CONFIG_SMP | 69 | static inline void kb_wait(void) |
70 | static void smp_halt(void) | ||
71 | { | 70 | { |
72 | int cpuid = safe_smp_processor_id(); | 71 | int i; |
73 | static int first_entry = 1; | ||
74 | 72 | ||
75 | if (reboot_force) | 73 | for (i=0; i<0x10000; i++) |
76 | return; | 74 | if ((inb_p(0x64) & 0x02) == 0) |
75 | break; | ||
76 | } | ||
77 | 77 | ||
78 | if (first_entry) { | 78 | void machine_shutdown(void) |
79 | first_entry = 0; | 79 | { |
80 | smp_call_function((void *)machine_restart, NULL, 1, 0); | 80 | /* Stop the cpus and apics */ |
81 | } | 81 | #ifdef CONFIG_SMP |
82 | 82 | int reboot_cpu_id; | |
83 | smp_stop_cpu(); | ||
84 | 83 | ||
85 | /* AP calling this. Just halt */ | 84 | /* The boot cpu is always logical cpu 0 */ |
86 | if (cpuid != boot_cpu_id) { | 85 | reboot_cpu_id = 0; |
87 | for (;;) | 86 | |
88 | asm("hlt"); | 87 | /* Make certain the cpu I'm about to reboot on is online */ |
88 | if (!cpu_isset(reboot_cpu_id, cpu_online_map)) { | ||
89 | reboot_cpu_id = smp_processor_id(); | ||
89 | } | 90 | } |
90 | 91 | ||
91 | /* Wait for all other CPUs to have run smp_stop_cpu */ | 92 | /* Make certain I only run on the appropriate processor */ |
92 | while (!cpus_empty(cpu_online_map)) | 93 | set_cpus_allowed(current, cpumask_of_cpu(reboot_cpu_id)); |
93 | rep_nop(); | 94 | |
94 | } | 95 | /* O.K Now that I'm on the appropriate processor, |
96 | * stop all of the others. | ||
97 | */ | ||
98 | smp_send_stop(); | ||
95 | #endif | 99 | #endif |
96 | 100 | ||
97 | static inline void kb_wait(void) | 101 | local_irq_disable(); |
98 | { | ||
99 | int i; | ||
100 | 102 | ||
101 | for (i=0; i<0x10000; i++) | 103 | #ifndef CONFIG_SMP |
102 | if ((inb_p(0x64) & 0x02) == 0) | 104 | disable_local_APIC(); |
103 | break; | 105 | #endif |
106 | |||
107 | disable_IO_APIC(); | ||
108 | |||
109 | local_irq_enable(); | ||
104 | } | 110 | } |
105 | 111 | ||
106 | void machine_restart(char * __unused) | 112 | void machine_restart(char * __unused) |
@@ -109,9 +115,7 @@ void machine_restart(char * __unused) | |||
109 | 115 | ||
110 | printk("machine restart\n"); | 116 | printk("machine restart\n"); |
111 | 117 | ||
112 | #ifdef CONFIG_SMP | 118 | machine_shutdown(); |
113 | smp_halt(); | ||
114 | #endif | ||
115 | 119 | ||
116 | if (!reboot_force) { | 120 | if (!reboot_force) { |
117 | local_irq_disable(); | 121 | local_irq_disable(); |
diff --git a/arch/x86_64/kernel/relocate_kernel.S b/arch/x86_64/kernel/relocate_kernel.S new file mode 100644 index 000000000000..d24fa9b72a2b --- /dev/null +++ b/arch/x86_64/kernel/relocate_kernel.S | |||
@@ -0,0 +1,143 @@ | |||
1 | /* | ||
2 | * relocate_kernel.S - put the kernel image in place to boot | ||
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/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 | ||
16 | .code64 | ||
17 | relocate_new_kernel: | ||
18 | /* %rdi page_list | ||
19 | * %rsi reboot_code_buffer | ||
20 | * %rdx start address | ||
21 | * %rcx page_table | ||
22 | * %r8 arg5 | ||
23 | * %r9 arg6 | ||
24 | */ | ||
25 | |||
26 | /* zero out flags, and disable interrupts */ | ||
27 | pushq $0 | ||
28 | popfq | ||
29 | |||
30 | /* set a new stack at the bottom of our page... */ | ||
31 | lea 4096(%rsi), %rsp | ||
32 | |||
33 | /* store the parameters back on the stack */ | ||
34 | pushq %rdx /* store the start address */ | ||
35 | |||
36 | /* Set cr0 to a known state: | ||
37 | * 31 1 == Paging enabled | ||
38 | * 18 0 == Alignment check disabled | ||
39 | * 16 0 == Write protect disabled | ||
40 | * 3 0 == No task switch | ||
41 | * 2 0 == Don't do FP software emulation. | ||
42 | * 0 1 == Proctected mode enabled | ||
43 | */ | ||
44 | movq %cr0, %rax | ||
45 | andq $~((1<<18)|(1<<16)|(1<<3)|(1<<2)), %rax | ||
46 | orl $((1<<31)|(1<<0)), %eax | ||
47 | movq %rax, %cr0 | ||
48 | |||
49 | /* Set cr4 to a known state: | ||
50 | * 10 0 == xmm exceptions disabled | ||
51 | * 9 0 == xmm registers instructions disabled | ||
52 | * 8 0 == performance monitoring counter disabled | ||
53 | * 7 0 == page global disabled | ||
54 | * 6 0 == machine check exceptions disabled | ||
55 | * 5 1 == physical address extension enabled | ||
56 | * 4 0 == page size extensions disabled | ||
57 | * 3 0 == Debug extensions disabled | ||
58 | * 2 0 == Time stamp disable (disabled) | ||
59 | * 1 0 == Protected mode virtual interrupts disabled | ||
60 | * 0 0 == VME disabled | ||
61 | */ | ||
62 | |||
63 | movq $((1<<5)), %rax | ||
64 | movq %rax, %cr4 | ||
65 | |||
66 | jmp 1f | ||
67 | 1: | ||
68 | |||
69 | /* Switch to the identity mapped page tables, | ||
70 | * and flush the TLB. | ||
71 | */ | ||
72 | movq %rcx, %cr3 | ||
73 | |||
74 | /* Do the copies */ | ||
75 | movq %rdi, %rcx /* Put the page_list in %rcx */ | ||
76 | xorq %rdi, %rdi | ||
77 | xorq %rsi, %rsi | ||
78 | jmp 1f | ||
79 | |||
80 | 0: /* top, read another word for the indirection page */ | ||
81 | |||
82 | movq (%rbx), %rcx | ||
83 | addq $8, %rbx | ||
84 | 1: | ||
85 | testq $0x1, %rcx /* is it a destination page? */ | ||
86 | jz 2f | ||
87 | movq %rcx, %rdi | ||
88 | andq $0xfffffffffffff000, %rdi | ||
89 | jmp 0b | ||
90 | 2: | ||
91 | testq $0x2, %rcx /* is it an indirection page? */ | ||
92 | jz 2f | ||
93 | movq %rcx, %rbx | ||
94 | andq $0xfffffffffffff000, %rbx | ||
95 | jmp 0b | ||
96 | 2: | ||
97 | testq $0x4, %rcx /* is it the done indicator? */ | ||
98 | jz 2f | ||
99 | jmp 3f | ||
100 | 2: | ||
101 | testq $0x8, %rcx /* is it the source indicator? */ | ||
102 | jz 0b /* Ignore it otherwise */ | ||
103 | movq %rcx, %rsi /* For ever source page do a copy */ | ||
104 | andq $0xfffffffffffff000, %rsi | ||
105 | |||
106 | movq $512, %rcx | ||
107 | rep ; movsq | ||
108 | jmp 0b | ||
109 | 3: | ||
110 | |||
111 | /* To be certain of avoiding problems with self-modifying code | ||
112 | * I need to execute a serializing instruction here. | ||
113 | * So I flush the TLB by reloading %cr3 here, it's handy, | ||
114 | * and not processor dependent. | ||
115 | */ | ||
116 | movq %cr3, %rax | ||
117 | movq %rax, %cr3 | ||
118 | |||
119 | /* set all of the registers to known values */ | ||
120 | /* leave %rsp alone */ | ||
121 | |||
122 | xorq %rax, %rax | ||
123 | xorq %rbx, %rbx | ||
124 | xorq %rcx, %rcx | ||
125 | xorq %rdx, %rdx | ||
126 | xorq %rsi, %rsi | ||
127 | xorq %rdi, %rdi | ||
128 | xorq %rbp, %rbp | ||
129 | xorq %r8, %r8 | ||
130 | xorq %r9, %r9 | ||
131 | xorq %r10, %r9 | ||
132 | xorq %r11, %r11 | ||
133 | xorq %r12, %r12 | ||
134 | xorq %r13, %r13 | ||
135 | xorq %r14, %r14 | ||
136 | xorq %r15, %r15 | ||
137 | |||
138 | ret | ||
139 | relocate_new_kernel_end: | ||
140 | |||
141 | .globl relocate_new_kernel_size | ||
142 | relocate_new_kernel_size: | ||
143 | .quad relocate_new_kernel_end - relocate_new_kernel | ||
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 000015dd5a8b..b02d921da4f7 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/kallsyms.h> | 41 | #include <linux/kallsyms.h> |
42 | #include <linux/edd.h> | 42 | #include <linux/edd.h> |
43 | #include <linux/mmzone.h> | 43 | #include <linux/mmzone.h> |
44 | #include <linux/kexec.h> | ||
44 | 45 | ||
45 | #include <asm/mtrr.h> | 46 | #include <asm/mtrr.h> |
46 | #include <asm/uaccess.h> | 47 | #include <asm/uaccess.h> |
@@ -367,6 +368,27 @@ static __init void parse_cmdline_early (char ** cmdline_p) | |||
367 | if (!memcmp(from, "noexec=", 7)) | 368 | if (!memcmp(from, "noexec=", 7)) |
368 | nonx_setup(from + 7); | 369 | nonx_setup(from + 7); |
369 | 370 | ||
371 | #ifdef CONFIG_KEXEC | ||
372 | /* crashkernel=size@addr specifies the location to reserve for | ||
373 | * a crash kernel. By reserving this memory we guarantee | ||
374 | * that linux never set's it up as a DMA target. | ||
375 | * Useful for holding code to do something appropriate | ||
376 | * after a kernel panic. | ||
377 | */ | ||
378 | else if (!memcmp(from, "crashkernel=", 12)) { | ||
379 | unsigned long size, base; | ||
380 | size = memparse(from+12, &from); | ||
381 | if (*from == '@') { | ||
382 | base = memparse(from+1, &from); | ||
383 | /* FIXME: Do I want a sanity check | ||
384 | * to validate the memory range? | ||
385 | */ | ||
386 | crashk_res.start = base; | ||
387 | crashk_res.end = base + size - 1; | ||
388 | } | ||
389 | } | ||
390 | #endif | ||
391 | |||
370 | next_char: | 392 | next_char: |
371 | c = *(from++); | 393 | c = *(from++); |
372 | if (!c) | 394 | if (!c) |
@@ -625,6 +647,13 @@ void __init setup_arch(char **cmdline_p) | |||
625 | #endif | 647 | #endif |
626 | 648 | ||
627 | sparse_init(); | 649 | sparse_init(); |
650 | |||
651 | #ifdef CONFIG_KEXEC | ||
652 | if (crashk_res.start != crashk_res.end) { | ||
653 | reserve_bootmem(crashk_res.start, | ||
654 | crashk_res.end - crashk_res.start + 1); | ||
655 | } | ||
656 | #endif | ||
628 | paging_init(); | 657 | paging_init(); |
629 | 658 | ||
630 | check_ioapic(); | 659 | check_ioapic(); |
@@ -676,7 +705,7 @@ void __init setup_arch(char **cmdline_p) | |||
676 | #endif | 705 | #endif |
677 | } | 706 | } |
678 | 707 | ||
679 | static int __init get_model_name(struct cpuinfo_x86 *c) | 708 | static int __cpuinit get_model_name(struct cpuinfo_x86 *c) |
680 | { | 709 | { |
681 | unsigned int *v; | 710 | unsigned int *v; |
682 | 711 | ||
@@ -692,7 +721,7 @@ static int __init get_model_name(struct cpuinfo_x86 *c) | |||
692 | } | 721 | } |
693 | 722 | ||
694 | 723 | ||
695 | static void __init display_cacheinfo(struct cpuinfo_x86 *c) | 724 | static void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c) |
696 | { | 725 | { |
697 | unsigned int n, dummy, eax, ebx, ecx, edx; | 726 | unsigned int n, dummy, eax, ebx, ecx, edx; |
698 | 727 | ||
@@ -803,7 +832,7 @@ static int __init init_amd(struct cpuinfo_x86 *c) | |||
803 | return r; | 832 | return r; |
804 | } | 833 | } |
805 | 834 | ||
806 | static void __init detect_ht(struct cpuinfo_x86 *c) | 835 | static void __cpuinit detect_ht(struct cpuinfo_x86 *c) |
807 | { | 836 | { |
808 | #ifdef CONFIG_SMP | 837 | #ifdef CONFIG_SMP |
809 | u32 eax, ebx, ecx, edx; | 838 | u32 eax, ebx, ecx, edx; |
@@ -864,7 +893,7 @@ static void __init detect_ht(struct cpuinfo_x86 *c) | |||
864 | /* | 893 | /* |
865 | * find out the number of processor cores on the die | 894 | * find out the number of processor cores on the die |
866 | */ | 895 | */ |
867 | static int __init intel_num_cpu_cores(struct cpuinfo_x86 *c) | 896 | static int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c) |
868 | { | 897 | { |
869 | unsigned int eax; | 898 | unsigned int eax; |
870 | 899 | ||
@@ -882,7 +911,7 @@ static int __init intel_num_cpu_cores(struct cpuinfo_x86 *c) | |||
882 | return 1; | 911 | return 1; |
883 | } | 912 | } |
884 | 913 | ||
885 | static void __init init_intel(struct cpuinfo_x86 *c) | 914 | static void __cpuinit init_intel(struct cpuinfo_x86 *c) |
886 | { | 915 | { |
887 | /* Cache sizes */ | 916 | /* Cache sizes */ |
888 | unsigned n; | 917 | unsigned n; |
@@ -902,7 +931,7 @@ static void __init init_intel(struct cpuinfo_x86 *c) | |||
902 | c->x86_num_cores = intel_num_cpu_cores(c); | 931 | c->x86_num_cores = intel_num_cpu_cores(c); |
903 | } | 932 | } |
904 | 933 | ||
905 | void __init get_cpu_vendor(struct cpuinfo_x86 *c) | 934 | void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c) |
906 | { | 935 | { |
907 | char *v = c->x86_vendor_id; | 936 | char *v = c->x86_vendor_id; |
908 | 937 | ||
@@ -923,7 +952,7 @@ struct cpu_model_info { | |||
923 | /* Do some early cpuid on the boot CPU to get some parameter that are | 952 | /* Do some early cpuid on the boot CPU to get some parameter that are |
924 | needed before check_bugs. Everything advanced is in identify_cpu | 953 | needed before check_bugs. Everything advanced is in identify_cpu |
925 | below. */ | 954 | below. */ |
926 | void __init early_identify_cpu(struct cpuinfo_x86 *c) | 955 | void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c) |
927 | { | 956 | { |
928 | u32 tfms; | 957 | u32 tfms; |
929 | 958 | ||
@@ -977,7 +1006,7 @@ void __init early_identify_cpu(struct cpuinfo_x86 *c) | |||
977 | /* | 1006 | /* |
978 | * This does the hard work of actually picking apart the CPU stuff... | 1007 | * This does the hard work of actually picking apart the CPU stuff... |
979 | */ | 1008 | */ |
980 | void __init identify_cpu(struct cpuinfo_x86 *c) | 1009 | void __cpuinit identify_cpu(struct cpuinfo_x86 *c) |
981 | { | 1010 | { |
982 | int i; | 1011 | int i; |
983 | u32 xlvl; | 1012 | u32 xlvl; |
@@ -1054,7 +1083,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c) | |||
1054 | } | 1083 | } |
1055 | 1084 | ||
1056 | 1085 | ||
1057 | void __init print_cpu_info(struct cpuinfo_x86 *c) | 1086 | void __cpuinit print_cpu_info(struct cpuinfo_x86 *c) |
1058 | { | 1087 | { |
1059 | if (c->x86_model_id[0]) | 1088 | if (c->x86_model_id[0]) |
1060 | printk("%s", c->x86_model_id); | 1089 | printk("%s", c->x86_model_id); |
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c index 678b7ac33b8b..f2b9c6bc999a 100644 --- a/arch/x86_64/kernel/setup64.c +++ b/arch/x86_64/kernel/setup64.c | |||
@@ -29,7 +29,7 @@ | |||
29 | 29 | ||
30 | char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,}; | 30 | char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,}; |
31 | 31 | ||
32 | cpumask_t cpu_initialized __initdata = CPU_MASK_NONE; | 32 | cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE; |
33 | 33 | ||
34 | struct x8664_pda cpu_pda[NR_CPUS] __cacheline_aligned; | 34 | struct x8664_pda cpu_pda[NR_CPUS] __cacheline_aligned; |
35 | 35 | ||
@@ -171,7 +171,7 @@ void syscall_init(void) | |||
171 | wrmsrl(MSR_SYSCALL_MASK, EF_TF|EF_DF|EF_IE|0x3000); | 171 | wrmsrl(MSR_SYSCALL_MASK, EF_TF|EF_DF|EF_IE|0x3000); |
172 | } | 172 | } |
173 | 173 | ||
174 | void __init check_efer(void) | 174 | void __cpuinit check_efer(void) |
175 | { | 175 | { |
176 | unsigned long efer; | 176 | unsigned long efer; |
177 | 177 | ||
@@ -188,7 +188,7 @@ void __init check_efer(void) | |||
188 | * 'CPU state barrier', nothing should get across. | 188 | * 'CPU state barrier', nothing should get across. |
189 | * A lot of state is already set up in PDA init. | 189 | * A lot of state is already set up in PDA init. |
190 | */ | 190 | */ |
191 | void __init cpu_init (void) | 191 | void __cpuinit cpu_init (void) |
192 | { | 192 | { |
193 | #ifdef CONFIG_SMP | 193 | #ifdef CONFIG_SMP |
194 | int cpu = stack_smp_processor_id(); | 194 | int cpu = stack_smp_processor_id(); |
diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c index 1e379ed17b1d..ccae392886af 100644 --- a/arch/x86_64/kernel/smp.c +++ b/arch/x86_64/kernel/smp.c | |||
@@ -283,6 +283,16 @@ struct call_data_struct { | |||
283 | 283 | ||
284 | static struct call_data_struct * call_data; | 284 | static struct call_data_struct * call_data; |
285 | 285 | ||
286 | void lock_ipi_call_lock(void) | ||
287 | { | ||
288 | spin_lock_irq(&call_lock); | ||
289 | } | ||
290 | |||
291 | void unlock_ipi_call_lock(void) | ||
292 | { | ||
293 | spin_unlock_irq(&call_lock); | ||
294 | } | ||
295 | |||
286 | /* | 296 | /* |
287 | * this function sends a 'generic call function' IPI to all other CPUs | 297 | * this function sends a 'generic call function' IPI to all other CPUs |
288 | * in the system. | 298 | * in the system. |
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index f1ec0f345941..b969ee128728 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c | |||
@@ -34,6 +34,7 @@ | |||
34 | * Andi Kleen : Converted to new state machine. | 34 | * Andi Kleen : Converted to new state machine. |
35 | * Various cleanups. | 35 | * Various cleanups. |
36 | * Probably mostly hotplug CPU ready now. | 36 | * Probably mostly hotplug CPU ready now. |
37 | * Ashok Raj : CPU hotplug support | ||
37 | */ | 38 | */ |
38 | 39 | ||
39 | 40 | ||
@@ -58,11 +59,6 @@ | |||
58 | #include <asm/proto.h> | 59 | #include <asm/proto.h> |
59 | #include <asm/nmi.h> | 60 | #include <asm/nmi.h> |
60 | 61 | ||
61 | /* Change for real CPU hotplug. Note other files need to be fixed | ||
62 | first too. */ | ||
63 | #define __cpuinit __init | ||
64 | #define __cpuinitdata __initdata | ||
65 | |||
66 | /* Number of siblings per CPU package */ | 62 | /* Number of siblings per CPU package */ |
67 | int smp_num_siblings = 1; | 63 | int smp_num_siblings = 1; |
68 | /* Package ID of each logical CPU */ | 64 | /* Package ID of each logical CPU */ |
@@ -103,6 +99,37 @@ EXPORT_SYMBOL(cpu_core_map); | |||
103 | extern unsigned char trampoline_data[]; | 99 | extern unsigned char trampoline_data[]; |
104 | extern unsigned char trampoline_end[]; | 100 | extern unsigned char trampoline_end[]; |
105 | 101 | ||
102 | /* State of each CPU */ | ||
103 | DEFINE_PER_CPU(int, cpu_state) = { 0 }; | ||
104 | |||
105 | /* | ||
106 | * Store all idle threads, this can be reused instead of creating | ||
107 | * a new thread. Also avoids complicated thread destroy functionality | ||
108 | * for idle threads. | ||
109 | */ | ||
110 | struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ; | ||
111 | |||
112 | #define get_idle_for_cpu(x) (idle_thread_array[(x)]) | ||
113 | #define set_idle_for_cpu(x,p) (idle_thread_array[(x)] = (p)) | ||
114 | |||
115 | /* | ||
116 | * cpu_possible_map should be static, it cannot change as cpu's | ||
117 | * are onlined, or offlined. The reason is per-cpu data-structures | ||
118 | * are allocated by some modules at init time, and dont expect to | ||
119 | * do this dynamically on cpu arrival/departure. | ||
120 | * cpu_present_map on the other hand can change dynamically. | ||
121 | * In case when cpu_hotplug is not compiled, then we resort to current | ||
122 | * behaviour, which is cpu_possible == cpu_present. | ||
123 | * If cpu-hotplug is supported, then we need to preallocate for all | ||
124 | * those NR_CPUS, hence cpu_possible_map represents entire NR_CPUS range. | ||
125 | * - Ashok Raj | ||
126 | */ | ||
127 | #ifdef CONFIG_HOTPLUG_CPU | ||
128 | #define fixup_cpu_possible_map(x) cpu_set((x), cpu_possible_map) | ||
129 | #else | ||
130 | #define fixup_cpu_possible_map(x) | ||
131 | #endif | ||
132 | |||
106 | /* | 133 | /* |
107 | * Currently trivial. Write the real->protected mode | 134 | * Currently trivial. Write the real->protected mode |
108 | * bootstrap into the page concerned. The caller | 135 | * bootstrap into the page concerned. The caller |
@@ -418,6 +445,33 @@ void __cpuinit smp_callin(void) | |||
418 | cpu_set(cpuid, cpu_callin_map); | 445 | cpu_set(cpuid, cpu_callin_map); |
419 | } | 446 | } |
420 | 447 | ||
448 | static inline void set_cpu_sibling_map(int cpu) | ||
449 | { | ||
450 | int i; | ||
451 | |||
452 | if (smp_num_siblings > 1) { | ||
453 | for_each_cpu(i) { | ||
454 | if (cpu_core_id[cpu] == cpu_core_id[i]) { | ||
455 | cpu_set(i, cpu_sibling_map[cpu]); | ||
456 | cpu_set(cpu, cpu_sibling_map[i]); | ||
457 | } | ||
458 | } | ||
459 | } else { | ||
460 | cpu_set(cpu, cpu_sibling_map[cpu]); | ||
461 | } | ||
462 | |||
463 | if (current_cpu_data.x86_num_cores > 1) { | ||
464 | for_each_cpu(i) { | ||
465 | if (phys_proc_id[cpu] == phys_proc_id[i]) { | ||
466 | cpu_set(i, cpu_core_map[cpu]); | ||
467 | cpu_set(cpu, cpu_core_map[i]); | ||
468 | } | ||
469 | } | ||
470 | } else { | ||
471 | cpu_core_map[cpu] = cpu_sibling_map[cpu]; | ||
472 | } | ||
473 | } | ||
474 | |||
421 | /* | 475 | /* |
422 | * Setup code on secondary processor (after comming out of the trampoline) | 476 | * Setup code on secondary processor (after comming out of the trampoline) |
423 | */ | 477 | */ |
@@ -448,9 +502,28 @@ void __cpuinit start_secondary(void) | |||
448 | enable_APIC_timer(); | 502 | enable_APIC_timer(); |
449 | 503 | ||
450 | /* | 504 | /* |
505 | * The sibling maps must be set before turing the online map on for | ||
506 | * this cpu | ||
507 | */ | ||
508 | set_cpu_sibling_map(smp_processor_id()); | ||
509 | |||
510 | /* | ||
511 | * We need to hold call_lock, so there is no inconsistency | ||
512 | * between the time smp_call_function() determines number of | ||
513 | * IPI receipients, and the time when the determination is made | ||
514 | * for which cpus receive the IPI in genapic_flat.c. Holding this | ||
515 | * lock helps us to not include this cpu in a currently in progress | ||
516 | * smp_call_function(). | ||
517 | */ | ||
518 | lock_ipi_call_lock(); | ||
519 | |||
520 | /* | ||
451 | * Allow the master to continue. | 521 | * Allow the master to continue. |
452 | */ | 522 | */ |
453 | cpu_set(smp_processor_id(), cpu_online_map); | 523 | cpu_set(smp_processor_id(), cpu_online_map); |
524 | per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; | ||
525 | unlock_ipi_call_lock(); | ||
526 | |||
454 | mb(); | 527 | mb(); |
455 | 528 | ||
456 | /* Wait for TSC sync to not schedule things before. | 529 | /* Wait for TSC sync to not schedule things before. |
@@ -628,33 +701,77 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta | |||
628 | return (send_status | accept_status); | 701 | return (send_status | accept_status); |
629 | } | 702 | } |
630 | 703 | ||
704 | struct create_idle { | ||
705 | struct task_struct *idle; | ||
706 | struct completion done; | ||
707 | int cpu; | ||
708 | }; | ||
709 | |||
710 | void do_fork_idle(void *_c_idle) | ||
711 | { | ||
712 | struct create_idle *c_idle = _c_idle; | ||
713 | |||
714 | c_idle->idle = fork_idle(c_idle->cpu); | ||
715 | complete(&c_idle->done); | ||
716 | } | ||
717 | |||
631 | /* | 718 | /* |
632 | * Boot one CPU. | 719 | * Boot one CPU. |
633 | */ | 720 | */ |
634 | static int __cpuinit do_boot_cpu(int cpu, int apicid) | 721 | static int __cpuinit do_boot_cpu(int cpu, int apicid) |
635 | { | 722 | { |
636 | struct task_struct *idle; | ||
637 | unsigned long boot_error; | 723 | unsigned long boot_error; |
638 | int timeout; | 724 | int timeout; |
639 | unsigned long start_rip; | 725 | unsigned long start_rip; |
726 | struct create_idle c_idle = { | ||
727 | .cpu = cpu, | ||
728 | .done = COMPLETION_INITIALIZER(c_idle.done), | ||
729 | }; | ||
730 | DECLARE_WORK(work, do_fork_idle, &c_idle); | ||
731 | |||
732 | c_idle.idle = get_idle_for_cpu(cpu); | ||
733 | |||
734 | if (c_idle.idle) { | ||
735 | c_idle.idle->thread.rsp = (unsigned long) (((struct pt_regs *) | ||
736 | (THREAD_SIZE + (unsigned long) c_idle.idle->thread_info)) - 1); | ||
737 | init_idle(c_idle.idle, cpu); | ||
738 | goto do_rest; | ||
739 | } | ||
740 | |||
640 | /* | 741 | /* |
641 | * We can't use kernel_thread since we must avoid to | 742 | * During cold boot process, keventd thread is not spun up yet. |
642 | * reschedule the child. | 743 | * When we do cpu hot-add, we create idle threads on the fly, we should |
744 | * not acquire any attributes from the calling context. Hence the clean | ||
745 | * way to create kernel_threads() is to do that from keventd(). | ||
746 | * We do the current_is_keventd() due to the fact that ACPI notifier | ||
747 | * was also queuing to keventd() and when the caller is already running | ||
748 | * in context of keventd(), we would end up with locking up the keventd | ||
749 | * thread. | ||
643 | */ | 750 | */ |
644 | idle = fork_idle(cpu); | 751 | if (!keventd_up() || current_is_keventd()) |
645 | if (IS_ERR(idle)) { | 752 | work.func(work.data); |
753 | else { | ||
754 | schedule_work(&work); | ||
755 | wait_for_completion(&c_idle.done); | ||
756 | } | ||
757 | |||
758 | if (IS_ERR(c_idle.idle)) { | ||
646 | printk("failed fork for CPU %d\n", cpu); | 759 | printk("failed fork for CPU %d\n", cpu); |
647 | return PTR_ERR(idle); | 760 | return PTR_ERR(c_idle.idle); |
648 | } | 761 | } |
649 | 762 | ||
650 | cpu_pda[cpu].pcurrent = idle; | 763 | set_idle_for_cpu(cpu, c_idle.idle); |
764 | |||
765 | do_rest: | ||
766 | |||
767 | cpu_pda[cpu].pcurrent = c_idle.idle; | ||
651 | 768 | ||
652 | start_rip = setup_trampoline(); | 769 | start_rip = setup_trampoline(); |
653 | 770 | ||
654 | init_rsp = idle->thread.rsp; | 771 | init_rsp = c_idle.idle->thread.rsp; |
655 | per_cpu(init_tss,cpu).rsp0 = init_rsp; | 772 | per_cpu(init_tss,cpu).rsp0 = init_rsp; |
656 | initial_code = start_secondary; | 773 | initial_code = start_secondary; |
657 | clear_ti_thread_flag(idle->thread_info, TIF_FORK); | 774 | clear_ti_thread_flag(c_idle.idle->thread_info, TIF_FORK); |
658 | 775 | ||
659 | printk(KERN_INFO "Booting processor %d/%d rip %lx rsp %lx\n", cpu, apicid, | 776 | printk(KERN_INFO "Booting processor %d/%d rip %lx rsp %lx\n", cpu, apicid, |
660 | start_rip, init_rsp); | 777 | start_rip, init_rsp); |
@@ -746,51 +863,6 @@ cycles_t cacheflush_time; | |||
746 | unsigned long cache_decay_ticks; | 863 | unsigned long cache_decay_ticks; |
747 | 864 | ||
748 | /* | 865 | /* |
749 | * Construct cpu_sibling_map[], so that we can tell the sibling CPU | ||
750 | * on SMT systems efficiently. | ||
751 | */ | ||
752 | static __cpuinit void detect_siblings(void) | ||
753 | { | ||
754 | int cpu; | ||
755 | |||
756 | for (cpu = 0; cpu < NR_CPUS; cpu++) { | ||
757 | cpus_clear(cpu_sibling_map[cpu]); | ||
758 | cpus_clear(cpu_core_map[cpu]); | ||
759 | } | ||
760 | |||
761 | for_each_online_cpu (cpu) { | ||
762 | struct cpuinfo_x86 *c = cpu_data + cpu; | ||
763 | int siblings = 0; | ||
764 | int i; | ||
765 | if (smp_num_siblings > 1) { | ||
766 | for_each_online_cpu (i) { | ||
767 | if (cpu_core_id[cpu] == cpu_core_id[i]) { | ||
768 | siblings++; | ||
769 | cpu_set(i, cpu_sibling_map[cpu]); | ||
770 | } | ||
771 | } | ||
772 | } else { | ||
773 | siblings++; | ||
774 | cpu_set(cpu, cpu_sibling_map[cpu]); | ||
775 | } | ||
776 | |||
777 | if (siblings != smp_num_siblings) { | ||
778 | printk(KERN_WARNING | ||
779 | "WARNING: %d siblings found for CPU%d, should be %d\n", | ||
780 | siblings, cpu, smp_num_siblings); | ||
781 | smp_num_siblings = siblings; | ||
782 | } | ||
783 | if (c->x86_num_cores > 1) { | ||
784 | for_each_online_cpu(i) { | ||
785 | if (phys_proc_id[cpu] == phys_proc_id[i]) | ||
786 | cpu_set(i, cpu_core_map[cpu]); | ||
787 | } | ||
788 | } else | ||
789 | cpu_core_map[cpu] = cpu_sibling_map[cpu]; | ||
790 | } | ||
791 | } | ||
792 | |||
793 | /* | ||
794 | * Cleanup possible dangling ends... | 866 | * Cleanup possible dangling ends... |
795 | */ | 867 | */ |
796 | static __cpuinit void smp_cleanup_boot(void) | 868 | static __cpuinit void smp_cleanup_boot(void) |
@@ -823,7 +895,7 @@ static __cpuinit void smp_cleanup_boot(void) | |||
823 | * | 895 | * |
824 | * RED-PEN audit/test this more. I bet there is more state messed up here. | 896 | * RED-PEN audit/test this more. I bet there is more state messed up here. |
825 | */ | 897 | */ |
826 | static __cpuinit void disable_smp(void) | 898 | static __init void disable_smp(void) |
827 | { | 899 | { |
828 | cpu_present_map = cpumask_of_cpu(0); | 900 | cpu_present_map = cpumask_of_cpu(0); |
829 | cpu_possible_map = cpumask_of_cpu(0); | 901 | cpu_possible_map = cpumask_of_cpu(0); |
@@ -838,7 +910,7 @@ static __cpuinit void disable_smp(void) | |||
838 | /* | 910 | /* |
839 | * Handle user cpus=... parameter. | 911 | * Handle user cpus=... parameter. |
840 | */ | 912 | */ |
841 | static __cpuinit void enforce_max_cpus(unsigned max_cpus) | 913 | static __init void enforce_max_cpus(unsigned max_cpus) |
842 | { | 914 | { |
843 | int i, k; | 915 | int i, k; |
844 | k = 0; | 916 | k = 0; |
@@ -855,7 +927,7 @@ static __cpuinit void enforce_max_cpus(unsigned max_cpus) | |||
855 | /* | 927 | /* |
856 | * Various sanity checks. | 928 | * Various sanity checks. |
857 | */ | 929 | */ |
858 | static int __cpuinit smp_sanity_check(unsigned max_cpus) | 930 | static int __init smp_sanity_check(unsigned max_cpus) |
859 | { | 931 | { |
860 | if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) { | 932 | if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) { |
861 | printk("weird, boot CPU (#%d) not listed by the BIOS.\n", | 933 | printk("weird, boot CPU (#%d) not listed by the BIOS.\n", |
@@ -913,7 +985,7 @@ static int __cpuinit smp_sanity_check(unsigned max_cpus) | |||
913 | * Prepare for SMP bootup. The MP table or ACPI has been read | 985 | * Prepare for SMP bootup. The MP table or ACPI has been read |
914 | * earlier. Just do some sanity checking here and enable APIC mode. | 986 | * earlier. Just do some sanity checking here and enable APIC mode. |
915 | */ | 987 | */ |
916 | void __cpuinit smp_prepare_cpus(unsigned int max_cpus) | 988 | void __init smp_prepare_cpus(unsigned int max_cpus) |
917 | { | 989 | { |
918 | int i; | 990 | int i; |
919 | 991 | ||
@@ -930,10 +1002,9 @@ void __cpuinit smp_prepare_cpus(unsigned int max_cpus) | |||
930 | int apicid = cpu_present_to_apicid(i); | 1002 | int apicid = cpu_present_to_apicid(i); |
931 | if (physid_isset(apicid, phys_cpu_present_map)) { | 1003 | if (physid_isset(apicid, phys_cpu_present_map)) { |
932 | cpu_set(i, cpu_present_map); | 1004 | cpu_set(i, cpu_present_map); |
933 | /* possible map would be different if we supported real | ||
934 | CPU hotplug. */ | ||
935 | cpu_set(i, cpu_possible_map); | 1005 | cpu_set(i, cpu_possible_map); |
936 | } | 1006 | } |
1007 | fixup_cpu_possible_map(i); | ||
937 | } | 1008 | } |
938 | 1009 | ||
939 | if (smp_sanity_check(max_cpus) < 0) { | 1010 | if (smp_sanity_check(max_cpus) < 0) { |
@@ -978,13 +1049,13 @@ void __init smp_prepare_boot_cpu(void) | |||
978 | int me = smp_processor_id(); | 1049 | int me = smp_processor_id(); |
979 | cpu_set(me, cpu_online_map); | 1050 | cpu_set(me, cpu_online_map); |
980 | cpu_set(me, cpu_callout_map); | 1051 | cpu_set(me, cpu_callout_map); |
1052 | cpu_set(0, cpu_sibling_map[0]); | ||
1053 | cpu_set(0, cpu_core_map[0]); | ||
1054 | per_cpu(cpu_state, me) = CPU_ONLINE; | ||
981 | } | 1055 | } |
982 | 1056 | ||
983 | /* | 1057 | /* |
984 | * Entry point to boot a CPU. | 1058 | * Entry point to boot a CPU. |
985 | * | ||
986 | * This is all __cpuinit, not __devinit for now because we don't support | ||
987 | * CPU hotplug (yet). | ||
988 | */ | 1059 | */ |
989 | int __cpuinit __cpu_up(unsigned int cpu) | 1060 | int __cpuinit __cpu_up(unsigned int cpu) |
990 | { | 1061 | { |
@@ -1001,6 +1072,15 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
1001 | return -EINVAL; | 1072 | return -EINVAL; |
1002 | } | 1073 | } |
1003 | 1074 | ||
1075 | /* | ||
1076 | * Already booted CPU? | ||
1077 | */ | ||
1078 | if (cpu_isset(cpu, cpu_callin_map)) { | ||
1079 | Dprintk("do_boot_cpu %d Already started\n", cpu); | ||
1080 | return -ENOSYS; | ||
1081 | } | ||
1082 | |||
1083 | per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; | ||
1004 | /* Boot it! */ | 1084 | /* Boot it! */ |
1005 | err = do_boot_cpu(cpu, apicid); | 1085 | err = do_boot_cpu(cpu, apicid); |
1006 | if (err < 0) { | 1086 | if (err < 0) { |
@@ -1013,23 +1093,118 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
1013 | 1093 | ||
1014 | while (!cpu_isset(cpu, cpu_online_map)) | 1094 | while (!cpu_isset(cpu, cpu_online_map)) |
1015 | cpu_relax(); | 1095 | cpu_relax(); |
1016 | return 0; | 1096 | err = 0; |
1097 | |||
1098 | return err; | ||
1017 | } | 1099 | } |
1018 | 1100 | ||
1019 | /* | 1101 | /* |
1020 | * Finish the SMP boot. | 1102 | * Finish the SMP boot. |
1021 | */ | 1103 | */ |
1022 | void __cpuinit smp_cpus_done(unsigned int max_cpus) | 1104 | void __init smp_cpus_done(unsigned int max_cpus) |
1023 | { | 1105 | { |
1106 | #ifndef CONFIG_HOTPLUG_CPU | ||
1024 | zap_low_mappings(); | 1107 | zap_low_mappings(); |
1108 | #endif | ||
1025 | smp_cleanup_boot(); | 1109 | smp_cleanup_boot(); |
1026 | 1110 | ||
1027 | #ifdef CONFIG_X86_IO_APIC | 1111 | #ifdef CONFIG_X86_IO_APIC |
1028 | setup_ioapic_dest(); | 1112 | setup_ioapic_dest(); |
1029 | #endif | 1113 | #endif |
1030 | 1114 | ||
1031 | detect_siblings(); | ||
1032 | time_init_gtod(); | 1115 | time_init_gtod(); |
1033 | 1116 | ||
1034 | check_nmi_watchdog(); | 1117 | check_nmi_watchdog(); |
1035 | } | 1118 | } |
1119 | |||
1120 | #ifdef CONFIG_HOTPLUG_CPU | ||
1121 | |||
1122 | static void remove_siblinginfo(int cpu) | ||
1123 | { | ||
1124 | int sibling; | ||
1125 | |||
1126 | for_each_cpu_mask(sibling, cpu_sibling_map[cpu]) | ||
1127 | cpu_clear(cpu, cpu_sibling_map[sibling]); | ||
1128 | for_each_cpu_mask(sibling, cpu_core_map[cpu]) | ||
1129 | cpu_clear(cpu, cpu_core_map[sibling]); | ||
1130 | cpus_clear(cpu_sibling_map[cpu]); | ||
1131 | cpus_clear(cpu_core_map[cpu]); | ||
1132 | phys_proc_id[cpu] = BAD_APICID; | ||
1133 | cpu_core_id[cpu] = BAD_APICID; | ||
1134 | } | ||
1135 | |||
1136 | void remove_cpu_from_maps(void) | ||
1137 | { | ||
1138 | int cpu = smp_processor_id(); | ||
1139 | |||
1140 | cpu_clear(cpu, cpu_callout_map); | ||
1141 | cpu_clear(cpu, cpu_callin_map); | ||
1142 | clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */ | ||
1143 | } | ||
1144 | |||
1145 | int __cpu_disable(void) | ||
1146 | { | ||
1147 | int cpu = smp_processor_id(); | ||
1148 | |||
1149 | /* | ||
1150 | * Perhaps use cpufreq to drop frequency, but that could go | ||
1151 | * into generic code. | ||
1152 | * | ||
1153 | * We won't take down the boot processor on i386 due to some | ||
1154 | * interrupts only being able to be serviced by the BSP. | ||
1155 | * Especially so if we're not using an IOAPIC -zwane | ||
1156 | */ | ||
1157 | if (cpu == 0) | ||
1158 | return -EBUSY; | ||
1159 | |||
1160 | disable_APIC_timer(); | ||
1161 | |||
1162 | /* | ||
1163 | * HACK: | ||
1164 | * Allow any queued timer interrupts to get serviced | ||
1165 | * This is only a temporary solution until we cleanup | ||
1166 | * fixup_irqs as we do for IA64. | ||
1167 | */ | ||
1168 | local_irq_enable(); | ||
1169 | mdelay(1); | ||
1170 | |||
1171 | local_irq_disable(); | ||
1172 | remove_siblinginfo(cpu); | ||
1173 | |||
1174 | /* It's now safe to remove this processor from the online map */ | ||
1175 | cpu_clear(cpu, cpu_online_map); | ||
1176 | remove_cpu_from_maps(); | ||
1177 | fixup_irqs(cpu_online_map); | ||
1178 | return 0; | ||
1179 | } | ||
1180 | |||
1181 | void __cpu_die(unsigned int cpu) | ||
1182 | { | ||
1183 | /* We don't do anything here: idle task is faking death itself. */ | ||
1184 | unsigned int i; | ||
1185 | |||
1186 | for (i = 0; i < 10; i++) { | ||
1187 | /* They ack this in play_dead by setting CPU_DEAD */ | ||
1188 | if (per_cpu(cpu_state, cpu) == CPU_DEAD) { | ||
1189 | printk ("CPU %d is now offline\n", cpu); | ||
1190 | return; | ||
1191 | } | ||
1192 | current->state = TASK_UNINTERRUPTIBLE; | ||
1193 | schedule_timeout(HZ/10); | ||
1194 | } | ||
1195 | printk(KERN_ERR "CPU %u didn't die...\n", cpu); | ||
1196 | } | ||
1197 | |||
1198 | #else /* ... !CONFIG_HOTPLUG_CPU */ | ||
1199 | |||
1200 | int __cpu_disable(void) | ||
1201 | { | ||
1202 | return -ENOSYS; | ||
1203 | } | ||
1204 | |||
1205 | void __cpu_die(unsigned int cpu) | ||
1206 | { | ||
1207 | /* We said "no" in __cpu_disable */ | ||
1208 | BUG(); | ||
1209 | } | ||
1210 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
diff --git a/arch/x86_64/kernel/suspend.c b/arch/x86_64/kernel/suspend.c index ebaa1e37d657..6c0f402e3a88 100644 --- a/arch/x86_64/kernel/suspend.c +++ b/arch/x86_64/kernel/suspend.c | |||
@@ -44,7 +44,6 @@ void __save_processor_state(struct saved_context *ctxt) | |||
44 | */ | 44 | */ |
45 | asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit)); | 45 | asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit)); |
46 | asm volatile ("sidt %0" : "=m" (ctxt->idt_limit)); | 46 | asm volatile ("sidt %0" : "=m" (ctxt->idt_limit)); |
47 | asm volatile ("sldt %0" : "=m" (ctxt->ldt)); | ||
48 | asm volatile ("str %0" : "=m" (ctxt->tr)); | 47 | asm volatile ("str %0" : "=m" (ctxt->tr)); |
49 | 48 | ||
50 | /* XMM0..XMM15 should be handled by kernel_fpu_begin(). */ | 49 | /* XMM0..XMM15 should be handled by kernel_fpu_begin(). */ |
@@ -69,6 +68,7 @@ void __save_processor_state(struct saved_context *ctxt) | |||
69 | asm volatile ("movq %%cr2, %0" : "=r" (ctxt->cr2)); | 68 | asm volatile ("movq %%cr2, %0" : "=r" (ctxt->cr2)); |
70 | asm volatile ("movq %%cr3, %0" : "=r" (ctxt->cr3)); | 69 | asm volatile ("movq %%cr3, %0" : "=r" (ctxt->cr3)); |
71 | asm volatile ("movq %%cr4, %0" : "=r" (ctxt->cr4)); | 70 | asm volatile ("movq %%cr4, %0" : "=r" (ctxt->cr4)); |
71 | asm volatile ("movq %%cr8, %0" : "=r" (ctxt->cr8)); | ||
72 | } | 72 | } |
73 | 73 | ||
74 | void save_processor_state(void) | 74 | void save_processor_state(void) |
@@ -90,12 +90,20 @@ void __restore_processor_state(struct saved_context *ctxt) | |||
90 | /* | 90 | /* |
91 | * control registers | 91 | * control registers |
92 | */ | 92 | */ |
93 | asm volatile ("movq %0, %%cr8" :: "r" (ctxt->cr8)); | ||
93 | asm volatile ("movq %0, %%cr4" :: "r" (ctxt->cr4)); | 94 | asm volatile ("movq %0, %%cr4" :: "r" (ctxt->cr4)); |
94 | asm volatile ("movq %0, %%cr3" :: "r" (ctxt->cr3)); | 95 | asm volatile ("movq %0, %%cr3" :: "r" (ctxt->cr3)); |
95 | asm volatile ("movq %0, %%cr2" :: "r" (ctxt->cr2)); | 96 | asm volatile ("movq %0, %%cr2" :: "r" (ctxt->cr2)); |
96 | asm volatile ("movq %0, %%cr0" :: "r" (ctxt->cr0)); | 97 | asm volatile ("movq %0, %%cr0" :: "r" (ctxt->cr0)); |
97 | 98 | ||
98 | /* | 99 | /* |
100 | * now restore the descriptor tables to their proper values | ||
101 | * ltr is done i fix_processor_context(). | ||
102 | */ | ||
103 | asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit)); | ||
104 | asm volatile ("lidt %0" :: "m" (ctxt->idt_limit)); | ||
105 | |||
106 | /* | ||
99 | * segment registers | 107 | * segment registers |
100 | */ | 108 | */ |
101 | asm volatile ("movw %0, %%ds" :: "r" (ctxt->ds)); | 109 | asm volatile ("movw %0, %%ds" :: "r" (ctxt->ds)); |
@@ -108,14 +116,6 @@ void __restore_processor_state(struct saved_context *ctxt) | |||
108 | wrmsrl(MSR_GS_BASE, ctxt->gs_base); | 116 | wrmsrl(MSR_GS_BASE, ctxt->gs_base); |
109 | wrmsrl(MSR_KERNEL_GS_BASE, ctxt->gs_kernel_base); | 117 | wrmsrl(MSR_KERNEL_GS_BASE, ctxt->gs_kernel_base); |
110 | 118 | ||
111 | /* | ||
112 | * now restore the descriptor tables to their proper values | ||
113 | * ltr is done i fix_processor_context(). | ||
114 | */ | ||
115 | asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit)); | ||
116 | asm volatile ("lidt %0" :: "m" (ctxt->idt_limit)); | ||
117 | asm volatile ("lldt %0" :: "m" (ctxt->ldt)); | ||
118 | |||
119 | fix_processor_context(); | 119 | fix_processor_context(); |
120 | 120 | ||
121 | do_fpu_end(); | 121 | do_fpu_end(); |
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 121646fc43f6..102736630002 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c | |||
@@ -586,11 +586,17 @@ static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs) | |||
586 | asmlinkage void default_do_nmi(struct pt_regs *regs) | 586 | asmlinkage void default_do_nmi(struct pt_regs *regs) |
587 | { | 587 | { |
588 | unsigned char reason = 0; | 588 | unsigned char reason = 0; |
589 | int cpu; | ||
590 | |||
591 | cpu = smp_processor_id(); | ||
589 | 592 | ||
590 | /* Only the BSP gets external NMIs from the system. */ | 593 | /* Only the BSP gets external NMIs from the system. */ |
591 | if (!smp_processor_id()) | 594 | if (!cpu) |
592 | reason = get_nmi_reason(); | 595 | reason = get_nmi_reason(); |
593 | 596 | ||
597 | if (!cpu_online(cpu)) | ||
598 | return; | ||
599 | |||
594 | if (!(reason & 0xc0)) { | 600 | if (!(reason & 0xc0)) { |
595 | if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT) | 601 | if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT) |
596 | == NOTIFY_STOP) | 602 | == NOTIFY_STOP) |
diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index 59ebd5beda87..73389f51c4e5 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S | |||
@@ -2,7 +2,10 @@ | |||
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 __START_KERNEL_map | ||
6 | |||
5 | #include <asm-generic/vmlinux.lds.h> | 7 | #include <asm-generic/vmlinux.lds.h> |
8 | #include <asm/page.h> | ||
6 | #include <linux/config.h> | 9 | #include <linux/config.h> |
7 | 10 | ||
8 | OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") | 11 | OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") |
@@ -11,28 +14,30 @@ ENTRY(phys_startup_64) | |||
11 | jiffies_64 = jiffies; | 14 | jiffies_64 = jiffies; |
12 | SECTIONS | 15 | SECTIONS |
13 | { | 16 | { |
14 | . = 0xffffffff80100000; | 17 | . = __START_KERNEL; |
15 | phys_startup_64 = startup_64 - LOAD_OFFSET; | 18 | phys_startup_64 = startup_64 - LOAD_OFFSET; |
16 | _text = .; /* Text and read-only data */ | 19 | _text = .; /* Text and read-only data */ |
17 | .text : { | 20 | .text : AT(ADDR(.text) - LOAD_OFFSET) { |
18 | *(.text) | 21 | *(.text) |
19 | SCHED_TEXT | 22 | SCHED_TEXT |
20 | LOCK_TEXT | 23 | LOCK_TEXT |
21 | *(.fixup) | 24 | *(.fixup) |
22 | *(.gnu.warning) | 25 | *(.gnu.warning) |
23 | } = 0x9090 | 26 | } = 0x9090 |
24 | .text.lock : { *(.text.lock) } /* out-of-line lock text */ | 27 | /* out-of-line lock text */ |
28 | .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET) { *(.text.lock) } | ||
25 | 29 | ||
26 | _etext = .; /* End of text section */ | 30 | _etext = .; /* End of text section */ |
27 | 31 | ||
28 | . = ALIGN(16); /* Exception table */ | 32 | . = ALIGN(16); /* Exception table */ |
29 | __start___ex_table = .; | 33 | __start___ex_table = .; |
30 | __ex_table : { *(__ex_table) } | 34 | __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) } |
31 | __stop___ex_table = .; | 35 | __stop___ex_table = .; |
32 | 36 | ||
33 | RODATA | 37 | RODATA |
34 | 38 | ||
35 | .data : { /* Data */ | 39 | /* Data */ |
40 | .data : AT(ADDR(.data) - LOAD_OFFSET) { | ||
36 | *(.data) | 41 | *(.data) |
37 | CONSTRUCTORS | 42 | CONSTRUCTORS |
38 | } | 43 | } |
@@ -40,62 +45,95 @@ SECTIONS | |||
40 | _edata = .; /* End of data section */ | 45 | _edata = .; /* End of data section */ |
41 | 46 | ||
42 | __bss_start = .; /* BSS */ | 47 | __bss_start = .; /* BSS */ |
43 | .bss : { | 48 | .bss : AT(ADDR(.bss) - LOAD_OFFSET) { |
44 | *(.bss.page_aligned) | 49 | *(.bss.page_aligned) |
45 | *(.bss) | 50 | *(.bss) |
46 | } | 51 | } |
47 | __bss_end = .; | 52 | __bss_end = .; |
48 | 53 | ||
54 | . = ALIGN(PAGE_SIZE); | ||
49 | . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); | 55 | . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); |
50 | .data.cacheline_aligned : { *(.data.cacheline_aligned) } | 56 | .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { |
57 | *(.data.cacheline_aligned) | ||
58 | } | ||
59 | |||
60 | #define VSYSCALL_ADDR (-10*1024*1024) | ||
61 | #define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.cacheline_aligned) + SIZEOF(.data.cacheline_aligned) + 4095) & ~(4095)) | ||
62 | #define VSYSCALL_VIRT_ADDR ((ADDR(.data.cacheline_aligned) + SIZEOF(.data.cacheline_aligned) + 4095) & ~(4095)) | ||
63 | |||
64 | #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR) | ||
65 | #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET) | ||
66 | |||
67 | #define VVIRT_OFFSET (VSYSCALL_ADDR - VSYSCALL_VIRT_ADDR) | ||
68 | #define VVIRT(x) (ADDR(x) - VVIRT_OFFSET) | ||
51 | 69 | ||
52 | #define AFTER(x) BINALIGN(LOADADDR(x) + SIZEOF(x), 16) | 70 | . = VSYSCALL_ADDR; |
53 | #define BINALIGN(x,y) (((x) + (y) - 1) & ~((y) - 1)) | 71 | .vsyscall_0 : AT(VSYSCALL_PHYS_ADDR) { *(.vsyscall_0) } |
54 | #define CACHE_ALIGN(x) BINALIGN(x, CONFIG_X86_L1_CACHE_BYTES) | 72 | __vsyscall_0 = VSYSCALL_VIRT_ADDR; |
55 | 73 | ||
56 | .vsyscall_0 -10*1024*1024: AT ((LOADADDR(.data.cacheline_aligned) + SIZEOF(.data.cacheline_aligned) + 4095) & ~(4095)) { *(.vsyscall_0) } | ||
57 | __vsyscall_0 = LOADADDR(.vsyscall_0); | ||
58 | . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); | 74 | . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); |
59 | .xtime_lock : AT CACHE_ALIGN(AFTER(.vsyscall_0)) { *(.xtime_lock) } | 75 | .xtime_lock : AT(VLOAD(.xtime_lock)) { *(.xtime_lock) } |
60 | xtime_lock = LOADADDR(.xtime_lock); | 76 | xtime_lock = VVIRT(.xtime_lock); |
61 | .vxtime : AT AFTER(.xtime_lock) { *(.vxtime) } | 77 | |
62 | vxtime = LOADADDR(.vxtime); | 78 | .vxtime : AT(VLOAD(.vxtime)) { *(.vxtime) } |
63 | .wall_jiffies : AT AFTER(.vxtime) { *(.wall_jiffies) } | 79 | vxtime = VVIRT(.vxtime); |
64 | wall_jiffies = LOADADDR(.wall_jiffies); | 80 | |
65 | .sys_tz : AT AFTER(.wall_jiffies) { *(.sys_tz) } | 81 | .wall_jiffies : AT(VLOAD(.wall_jiffies)) { *(.wall_jiffies) } |
66 | sys_tz = LOADADDR(.sys_tz); | 82 | wall_jiffies = VVIRT(.wall_jiffies); |
67 | .sysctl_vsyscall : AT AFTER(.sys_tz) { *(.sysctl_vsyscall) } | 83 | |
68 | sysctl_vsyscall = LOADADDR(.sysctl_vsyscall); | 84 | .sys_tz : AT(VLOAD(.sys_tz)) { *(.sys_tz) } |
69 | .xtime : AT AFTER(.sysctl_vsyscall) { *(.xtime) } | 85 | sys_tz = VVIRT(.sys_tz); |
70 | xtime = LOADADDR(.xtime); | 86 | |
87 | .sysctl_vsyscall : AT(VLOAD(.sysctl_vsyscall)) { *(.sysctl_vsyscall) } | ||
88 | sysctl_vsyscall = VVIRT(.sysctl_vsyscall); | ||
89 | |||
90 | .xtime : AT(VLOAD(.xtime)) { *(.xtime) } | ||
91 | xtime = VVIRT(.xtime); | ||
92 | |||
71 | . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); | 93 | . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); |
72 | .jiffies : AT CACHE_ALIGN(AFTER(.xtime)) { *(.jiffies) } | 94 | .jiffies : AT(VLOAD(.jiffies)) { *(.jiffies) } |
73 | jiffies = LOADADDR(.jiffies); | 95 | jiffies = VVIRT(.jiffies); |
74 | .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT (LOADADDR(.vsyscall_0) + 1024) { *(.vsyscall_1) } | 96 | |
75 | . = LOADADDR(.vsyscall_0) + 4096; | 97 | .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT(VLOAD(.vsyscall_1)) { *(.vsyscall_1) } |
98 | .vsyscall_2 ADDR(.vsyscall_0) + 2048: AT(VLOAD(.vsyscall_2)) { *(.vsyscall_2) } | ||
99 | .vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3)) { *(.vsyscall_3) } | ||
100 | |||
101 | . = VSYSCALL_VIRT_ADDR + 4096; | ||
102 | |||
103 | #undef VSYSCALL_ADDR | ||
104 | #undef VSYSCALL_PHYS_ADDR | ||
105 | #undef VSYSCALL_VIRT_ADDR | ||
106 | #undef VLOAD_OFFSET | ||
107 | #undef VLOAD | ||
108 | #undef VVIRT_OFFSET | ||
109 | #undef VVIRT | ||
76 | 110 | ||
77 | . = ALIGN(8192); /* init_task */ | 111 | . = ALIGN(8192); /* init_task */ |
78 | .data.init_task : { *(.data.init_task) } | 112 | .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { |
113 | *(.data.init_task) | ||
114 | } | ||
79 | 115 | ||
80 | . = ALIGN(4096); | 116 | . = ALIGN(4096); |
81 | .data.page_aligned : { *(.data.page_aligned) } | 117 | .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { |
118 | *(.data.page_aligned) | ||
119 | } | ||
82 | 120 | ||
83 | . = ALIGN(4096); /* Init code and data */ | 121 | . = ALIGN(4096); /* Init code and data */ |
84 | __init_begin = .; | 122 | __init_begin = .; |
85 | .init.text : { | 123 | .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { |
86 | _sinittext = .; | 124 | _sinittext = .; |
87 | *(.init.text) | 125 | *(.init.text) |
88 | _einittext = .; | 126 | _einittext = .; |
89 | } | 127 | } |
90 | __initdata_begin = .; | 128 | __initdata_begin = .; |
91 | .init.data : { *(.init.data) } | 129 | .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) } |
92 | __initdata_end = .; | 130 | __initdata_end = .; |
93 | . = ALIGN(16); | 131 | . = ALIGN(16); |
94 | __setup_start = .; | 132 | __setup_start = .; |
95 | .init.setup : { *(.init.setup) } | 133 | .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) } |
96 | __setup_end = .; | 134 | __setup_end = .; |
97 | __initcall_start = .; | 135 | __initcall_start = .; |
98 | .initcall.init : { | 136 | .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { |
99 | *(.initcall1.init) | 137 | *(.initcall1.init) |
100 | *(.initcall2.init) | 138 | *(.initcall2.init) |
101 | *(.initcall3.init) | 139 | *(.initcall3.init) |
@@ -106,32 +144,38 @@ SECTIONS | |||
106 | } | 144 | } |
107 | __initcall_end = .; | 145 | __initcall_end = .; |
108 | __con_initcall_start = .; | 146 | __con_initcall_start = .; |
109 | .con_initcall.init : { *(.con_initcall.init) } | 147 | .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) { |
148 | *(.con_initcall.init) | ||
149 | } | ||
110 | __con_initcall_end = .; | 150 | __con_initcall_end = .; |
111 | SECURITY_INIT | 151 | SECURITY_INIT |
112 | . = ALIGN(8); | 152 | . = ALIGN(8); |
113 | __alt_instructions = .; | 153 | __alt_instructions = .; |
114 | .altinstructions : { *(.altinstructions) } | 154 | .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) { |
155 | *(.altinstructions) | ||
156 | } | ||
115 | __alt_instructions_end = .; | 157 | __alt_instructions_end = .; |
116 | .altinstr_replacement : { *(.altinstr_replacement) } | 158 | .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) { |
159 | *(.altinstr_replacement) | ||
160 | } | ||
117 | /* .exit.text is discard at runtime, not link time, to deal with references | 161 | /* .exit.text is discard at runtime, not link time, to deal with references |
118 | from .altinstructions and .eh_frame */ | 162 | from .altinstructions and .eh_frame */ |
119 | .exit.text : { *(.exit.text) } | 163 | .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) } |
120 | .exit.data : { *(.exit.data) } | 164 | .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) } |
121 | . = ALIGN(4096); | 165 | . = ALIGN(4096); |
122 | __initramfs_start = .; | 166 | __initramfs_start = .; |
123 | .init.ramfs : { *(.init.ramfs) } | 167 | .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) } |
124 | __initramfs_end = .; | 168 | __initramfs_end = .; |
125 | . = ALIGN(32); | 169 | . = ALIGN(32); |
126 | __per_cpu_start = .; | 170 | __per_cpu_start = .; |
127 | .data.percpu : { *(.data.percpu) } | 171 | .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) } |
128 | __per_cpu_end = .; | 172 | __per_cpu_end = .; |
129 | . = ALIGN(4096); | 173 | . = ALIGN(4096); |
130 | __init_end = .; | 174 | __init_end = .; |
131 | 175 | ||
132 | . = ALIGN(4096); | 176 | . = ALIGN(4096); |
133 | __nosave_begin = .; | 177 | __nosave_begin = .; |
134 | .data_nosave : { *(.data.nosave) } | 178 | .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) } |
135 | . = ALIGN(4096); | 179 | . = ALIGN(4096); |
136 | __nosave_end = .; | 180 | __nosave_end = .; |
137 | 181 | ||
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c index 84cde796ecb1..ac61c186eb02 100644 --- a/arch/x86_64/mm/numa.c +++ b/arch/x86_64/mm/numa.c | |||
@@ -251,7 +251,7 @@ void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn) | |||
251 | setup_node_bootmem(0, start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT); | 251 | setup_node_bootmem(0, start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT); |
252 | } | 252 | } |
253 | 253 | ||
254 | __init void numa_add_cpu(int cpu) | 254 | __cpuinit void numa_add_cpu(int cpu) |
255 | { | 255 | { |
256 | /* BP is initialized elsewhere */ | 256 | /* BP is initialized elsewhere */ |
257 | if (cpu) | 257 | if (cpu) |
diff --git a/arch/xtensa/platform-iss/console.c b/arch/xtensa/platform-iss/console.c index 9e2b53f6a907..4fbddf92a921 100644 --- a/arch/xtensa/platform-iss/console.c +++ b/arch/xtensa/platform-iss/console.c | |||
@@ -198,9 +198,6 @@ static int rs_read_proc(char *page, char **start, off_t off, int count, | |||
198 | } | 198 | } |
199 | 199 | ||
200 | 200 | ||
201 | int register_serial(struct serial_struct*); | ||
202 | void unregister_serial(int); | ||
203 | |||
204 | static struct tty_operations serial_ops = { | 201 | static struct tty_operations serial_ops = { |
205 | .open = rs_open, | 202 | .open = rs_open, |
206 | .close = rs_close, | 203 | .close = rs_close, |