diff options
Diffstat (limited to 'arch')
383 files changed, 12503 insertions, 4643 deletions
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 0c79b9d95f74..f7c96635d3b4 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig | |||
@@ -280,6 +280,10 @@ config ISA | |||
280 | (MCA) or VESA. ISA is an older system, now being displaced by PCI; | 280 | (MCA) or VESA. ISA is an older system, now being displaced by PCI; |
281 | newer boards don't support it. If you have ISA, say Y, otherwise N. | 281 | newer boards don't support it. If you have ISA, say Y, otherwise N. |
282 | 282 | ||
283 | config ISA_DMA_API | ||
284 | bool | ||
285 | default y | ||
286 | |||
283 | config PCI | 287 | config PCI |
284 | bool | 288 | bool |
285 | depends on !ALPHA_JENSEN | 289 | depends on !ALPHA_JENSEN |
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 64e450dddb49..167fd89f8707 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c | |||
@@ -1150,16 +1150,13 @@ osf_usleep_thread(struct timeval32 __user *sleep, struct timeval32 __user *remai | |||
1150 | if (get_tv32(&tmp, sleep)) | 1150 | if (get_tv32(&tmp, sleep)) |
1151 | goto fault; | 1151 | goto fault; |
1152 | 1152 | ||
1153 | ticks = tmp.tv_usec; | 1153 | ticks = timeval_to_jiffies(&tmp); |
1154 | ticks = (ticks + (1000000 / HZ) - 1) / (1000000 / HZ); | ||
1155 | ticks += tmp.tv_sec * HZ; | ||
1156 | 1154 | ||
1157 | current->state = TASK_INTERRUPTIBLE; | 1155 | current->state = TASK_INTERRUPTIBLE; |
1158 | ticks = schedule_timeout(ticks); | 1156 | ticks = schedule_timeout(ticks); |
1159 | 1157 | ||
1160 | if (remain) { | 1158 | if (remain) { |
1161 | tmp.tv_sec = ticks / HZ; | 1159 | jiffies_to_timeval(ticks, &tmp); |
1162 | tmp.tv_usec = ticks % HZ; | ||
1163 | if (put_tv32(remain, &tmp)) | 1160 | if (put_tv32(remain, &tmp)) |
1164 | goto fault; | 1161 | goto fault; |
1165 | } | 1162 | } |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4055115ae0e2..475950c8a831 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -85,6 +85,7 @@ choice | |||
85 | config ARCH_CLPS7500 | 85 | config ARCH_CLPS7500 |
86 | bool "Cirrus-CL-PS7500FE" | 86 | bool "Cirrus-CL-PS7500FE" |
87 | select TIMER_ACORN | 87 | select TIMER_ACORN |
88 | select ISA | ||
88 | 89 | ||
89 | config ARCH_CLPS711X | 90 | config ARCH_CLPS711X |
90 | bool "CLPS711x/EP721x-based" | 91 | bool "CLPS711x/EP721x-based" |
@@ -96,6 +97,7 @@ config ARCH_CO285 | |||
96 | 97 | ||
97 | config ARCH_EBSA110 | 98 | config ARCH_EBSA110 |
98 | bool "EBSA-110" | 99 | bool "EBSA-110" |
100 | select ISA | ||
99 | help | 101 | help |
100 | This is an evaluation board for the StrongARM processor available | 102 | This is an evaluation board for the StrongARM processor available |
101 | from Digital. It has limited hardware on-board, including an onboard | 103 | from Digital. It has limited hardware on-board, including an onboard |
@@ -120,13 +122,16 @@ config ARCH_INTEGRATOR | |||
120 | 122 | ||
121 | config ARCH_IOP3XX | 123 | config ARCH_IOP3XX |
122 | bool "IOP3xx-based" | 124 | bool "IOP3xx-based" |
125 | select PCI | ||
123 | 126 | ||
124 | config ARCH_IXP4XX | 127 | config ARCH_IXP4XX |
125 | bool "IXP4xx-based" | 128 | bool "IXP4xx-based" |
126 | select DMABOUNCE | 129 | select DMABOUNCE |
130 | select PCI | ||
127 | 131 | ||
128 | config ARCH_IXP2000 | 132 | config ARCH_IXP2000 |
129 | bool "IXP2400/2800-based" | 133 | bool "IXP2400/2800-based" |
134 | select PCI | ||
130 | 135 | ||
131 | config ARCH_L7200 | 136 | config ARCH_L7200 |
132 | bool "LinkUp-L7200" | 137 | bool "LinkUp-L7200" |
@@ -155,6 +160,8 @@ config ARCH_RPC | |||
155 | 160 | ||
156 | config ARCH_SA1100 | 161 | config ARCH_SA1100 |
157 | bool "SA1100-based" | 162 | bool "SA1100-based" |
163 | select ISA | ||
164 | select DISCONTIGMEM | ||
158 | 165 | ||
159 | config ARCH_S3C2410 | 166 | config ARCH_S3C2410 |
160 | bool "Samsung S3C2410" | 167 | bool "Samsung S3C2410" |
@@ -165,6 +172,9 @@ config ARCH_S3C2410 | |||
165 | 172 | ||
166 | config ARCH_SHARK | 173 | config ARCH_SHARK |
167 | bool "Shark" | 174 | bool "Shark" |
175 | select ISA | ||
176 | select ISA_DMA | ||
177 | select PCI | ||
168 | 178 | ||
169 | config ARCH_LH7A40X | 179 | config ARCH_LH7A40X |
170 | bool "Sharp LH7A40X" | 180 | bool "Sharp LH7A40X" |
@@ -252,8 +262,6 @@ config ARM_AMBA | |||
252 | 262 | ||
253 | config ISA | 263 | config ISA |
254 | bool | 264 | bool |
255 | depends on FOOTBRIDGE_HOST || ARCH_SHARK || ARCH_CLPS7500 || ARCH_EBSA110 || ARCH_CDB89712 || ARCH_EDB7211 || ARCH_SA1100 || ARCH_MX1ADS | ||
256 | default y | ||
257 | help | 265 | help |
258 | Find out whether you have ISA slots on your motherboard. ISA is the | 266 | Find out whether you have ISA slots on your motherboard. ISA is the |
259 | name of a bus system, i.e. the way the CPU talks to the other stuff | 267 | name of a bus system, i.e. the way the CPU talks to the other stuff |
@@ -263,12 +271,13 @@ config ISA | |||
263 | 271 | ||
264 | config ISA_DMA | 272 | config ISA_DMA |
265 | bool | 273 | bool |
266 | depends on FOOTBRIDGE_HOST || ARCH_SHARK | 274 | |
275 | config ISA_DMA_API | ||
276 | bool | ||
267 | default y | 277 | default y |
268 | 278 | ||
269 | config PCI | 279 | config PCI |
270 | bool "PCI support" if ARCH_INTEGRATOR_AP | 280 | bool "PCI support" if ARCH_INTEGRATOR_AP |
271 | default y if ARCH_SHARK || FOOTBRIDGE_HOST || ARCH_IOP3XX || ARCH_IXP4XX || ARCH_IXP2000 | ||
272 | help | 281 | help |
273 | Find out whether you have a PCI motherboard. PCI is the name of a | 282 | Find out whether you have a PCI motherboard. PCI is the name of a |
274 | bus system, i.e. the way the CPU talks to the other stuff inside | 283 | bus system, i.e. the way the CPU talks to the other stuff inside |
@@ -296,7 +305,7 @@ menu "Kernel Features" | |||
296 | 305 | ||
297 | config SMP | 306 | config SMP |
298 | bool "Symmetric Multi-Processing (EXPERIMENTAL)" | 307 | bool "Symmetric Multi-Processing (EXPERIMENTAL)" |
299 | depends on EXPERIMENTAL && n | 308 | depends on EXPERIMENTAL #&& n |
300 | help | 309 | help |
301 | This enables support for systems with more than one CPU. If you have | 310 | This enables support for systems with more than one CPU. If you have |
302 | a system with only one CPU, like most personal computers, say N. If | 311 | a system with only one CPU, like most personal computers, say N. If |
@@ -336,8 +345,7 @@ config PREEMPT | |||
336 | 345 | ||
337 | config DISCONTIGMEM | 346 | config DISCONTIGMEM |
338 | bool | 347 | bool |
339 | depends on ARCH_EDB7211 || ARCH_SA1100 || (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) | 348 | default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) |
340 | default y | ||
341 | help | 349 | help |
342 | Say Y to support efficient handling of discontiguous physical memory, | 350 | Say Y to support efficient handling of discontiguous physical memory, |
343 | for architectures which are either NUMA (Non-Uniform Memory Access) | 351 | for architectures which are either NUMA (Non-Uniform Memory Access) |
@@ -489,7 +497,7 @@ source "drivers/cpufreq/Kconfig" | |||
489 | 497 | ||
490 | config CPU_FREQ_SA1100 | 498 | config CPU_FREQ_SA1100 |
491 | bool | 499 | bool |
492 | depends on CPU_FREQ && (SA1100_LART || SA1100_PLEB) | 500 | depends on CPU_FREQ && (SA1100_H3100 || SA1100_H3600 || SA1100_H3800 || SA1100_LART || SA1100_PLEB || SA1100_BADGE4 || SA1100_HACKKIT) |
493 | default y | 501 | default y |
494 | 502 | ||
495 | config CPU_FREQ_SA1110 | 503 | config CPU_FREQ_SA1110 |
@@ -681,7 +689,9 @@ source "drivers/block/Kconfig" | |||
681 | 689 | ||
682 | source "drivers/acorn/block/Kconfig" | 690 | source "drivers/acorn/block/Kconfig" |
683 | 691 | ||
684 | if ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE | 692 | if PCMCIA || ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX \ |
693 | || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \ | ||
694 | || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE | ||
685 | source "drivers/ide/Kconfig" | 695 | source "drivers/ide/Kconfig" |
686 | endif | 696 | endif |
687 | 697 | ||
diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S index 665bd2c20743..d3fe2533907e 100644 --- a/arch/arm/boot/compressed/head-xscale.S +++ b/arch/arm/boot/compressed/head-xscale.S | |||
@@ -47,3 +47,10 @@ __XScale_start: | |||
47 | orr r7, r7, #(MACH_TYPE_GTWX5715 & 0xff00) | 47 | orr r7, r7, #(MACH_TYPE_GTWX5715 & 0xff00) |
48 | #endif | 48 | #endif |
49 | 49 | ||
50 | #ifdef CONFIG_ARCH_IXP2000 | ||
51 | mov r1, #-1 | ||
52 | mov r0, #0xd6000000 | ||
53 | str r1, [r0, #0x14] | ||
54 | str r1, [r0, #0x18] | ||
55 | #endif | ||
56 | |||
diff --git a/arch/arm/configs/badge4_defconfig b/arch/arm/configs/badge4_defconfig index 2b4059d2f8e4..5d92af975d87 100644 --- a/arch/arm/configs/badge4_defconfig +++ b/arch/arm/configs/badge4_defconfig | |||
@@ -1,7 +1,7 @@ | |||
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-rc6-git3 |
4 | # Sat Mar 26 21:32:26 2005 | 4 | # Thu Jun 9 19:00:50 2005 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
@@ -16,6 +16,7 @@ CONFIG_GENERIC_IOMAP=y | |||
16 | CONFIG_EXPERIMENTAL=y | 16 | CONFIG_EXPERIMENTAL=y |
17 | CONFIG_CLEAN_COMPILE=y | 17 | CONFIG_CLEAN_COMPILE=y |
18 | CONFIG_BROKEN_ON_SMP=y | 18 | CONFIG_BROKEN_ON_SMP=y |
19 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
19 | 20 | ||
20 | # | 21 | # |
21 | # General setup | 22 | # General setup |
@@ -34,6 +35,8 @@ CONFIG_EMBEDDED=y | |||
34 | CONFIG_KALLSYMS=y | 35 | CONFIG_KALLSYMS=y |
35 | # CONFIG_KALLSYMS_ALL is not set | 36 | # CONFIG_KALLSYMS_ALL is not set |
36 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
38 | CONFIG_PRINTK=y | ||
39 | CONFIG_BUG=y | ||
37 | CONFIG_BASE_FULL=y | 40 | CONFIG_BASE_FULL=y |
38 | CONFIG_FUTEX=y | 41 | CONFIG_FUTEX=y |
39 | CONFIG_EPOLL=y | 42 | CONFIG_EPOLL=y |
@@ -109,7 +112,6 @@ CONFIG_CPU_ABRT_EV4=y | |||
109 | CONFIG_CPU_CACHE_V4WB=y | 112 | CONFIG_CPU_CACHE_V4WB=y |
110 | CONFIG_CPU_CACHE_VIVT=y | 113 | CONFIG_CPU_CACHE_VIVT=y |
111 | CONFIG_CPU_TLB_V4WB=y | 114 | CONFIG_CPU_TLB_V4WB=y |
112 | CONFIG_CPU_MINICACHE=y | ||
113 | 115 | ||
114 | # | 116 | # |
115 | # Processor Features | 117 | # Processor Features |
@@ -122,6 +124,7 @@ CONFIG_FORCE_MAX_ZONEORDER=9 | |||
122 | # Bus support | 124 | # Bus support |
123 | # | 125 | # |
124 | CONFIG_ISA=y | 126 | CONFIG_ISA=y |
127 | CONFIG_ISA_DMA_API=y | ||
125 | 128 | ||
126 | # | 129 | # |
127 | # PCCARD (PCMCIA/CardBus) support | 130 | # PCCARD (PCMCIA/CardBus) support |
@@ -131,6 +134,7 @@ CONFIG_ISA=y | |||
131 | # | 134 | # |
132 | # Kernel Features | 135 | # Kernel Features |
133 | # | 136 | # |
137 | # CONFIG_SMP is not set | ||
134 | # CONFIG_PREEMPT is not set | 138 | # CONFIG_PREEMPT is not set |
135 | CONFIG_DISCONTIGMEM=y | 139 | CONFIG_DISCONTIGMEM=y |
136 | # CONFIG_LEDS is not set | 140 | # CONFIG_LEDS is not set |
@@ -152,12 +156,14 @@ CONFIG_CPU_FREQ_TABLE=y | |||
152 | # CONFIG_CPU_FREQ_DEBUG is not set | 156 | # CONFIG_CPU_FREQ_DEBUG is not set |
153 | CONFIG_CPU_FREQ_STAT=y | 157 | CONFIG_CPU_FREQ_STAT=y |
154 | # CONFIG_CPU_FREQ_STAT_DETAILS is not set | 158 | # CONFIG_CPU_FREQ_STAT_DETAILS is not set |
155 | CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y | 159 | # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set |
156 | # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set | 160 | CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y |
157 | CONFIG_CPU_FREQ_GOV_PERFORMANCE=y | 161 | CONFIG_CPU_FREQ_GOV_PERFORMANCE=y |
158 | # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set | 162 | # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set |
159 | # CONFIG_CPU_FREQ_GOV_USERSPACE is not set | 163 | CONFIG_CPU_FREQ_GOV_USERSPACE=y |
160 | # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set | 164 | # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set |
165 | # CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set | ||
166 | CONFIG_CPU_FREQ_SA1100=y | ||
161 | 167 | ||
162 | # | 168 | # |
163 | # Floating point emulation | 169 | # Floating point emulation |
@@ -294,7 +300,6 @@ CONFIG_PARPORT_NOT_PC=y | |||
294 | # | 300 | # |
295 | # Block devices | 301 | # Block devices |
296 | # | 302 | # |
297 | # CONFIG_BLK_DEV_FD is not set | ||
298 | # CONFIG_BLK_DEV_XD is not set | 303 | # CONFIG_BLK_DEV_XD is not set |
299 | # CONFIG_PARIDE is not set | 304 | # CONFIG_PARIDE is not set |
300 | # CONFIG_BLK_DEV_COW_COMMON is not set | 305 | # CONFIG_BLK_DEV_COW_COMMON is not set |
@@ -428,7 +433,6 @@ CONFIG_NET=y | |||
428 | # | 433 | # |
429 | CONFIG_PACKET=y | 434 | CONFIG_PACKET=y |
430 | # CONFIG_PACKET_MMAP is not set | 435 | # CONFIG_PACKET_MMAP is not set |
431 | # CONFIG_NETLINK_DEV is not set | ||
432 | CONFIG_UNIX=y | 436 | CONFIG_UNIX=y |
433 | # CONFIG_NET_KEY is not set | 437 | # CONFIG_NET_KEY is not set |
434 | CONFIG_INET=y | 438 | CONFIG_INET=y |
@@ -526,6 +530,7 @@ CONFIG_IRDA_ULTRA=y | |||
526 | # CONFIG_SMC_IRCC_FIR is not set | 530 | # CONFIG_SMC_IRCC_FIR is not set |
527 | # CONFIG_ALI_FIR is not set | 531 | # CONFIG_ALI_FIR is not set |
528 | CONFIG_SA1100_FIR=y | 532 | CONFIG_SA1100_FIR=y |
533 | # CONFIG_VIA_FIR is not set | ||
529 | CONFIG_BT=m | 534 | CONFIG_BT=m |
530 | CONFIG_BT_L2CAP=m | 535 | CONFIG_BT_L2CAP=m |
531 | # CONFIG_BT_SCO is not set | 536 | # CONFIG_BT_SCO is not set |
@@ -618,7 +623,6 @@ CONFIG_NET_WIRELESS=y | |||
618 | # | 623 | # |
619 | # CONFIG_SERIO is not set | 624 | # CONFIG_SERIO is not set |
620 | # CONFIG_GAMEPORT is not set | 625 | # CONFIG_GAMEPORT is not set |
621 | CONFIG_SOUND_GAMEPORT=y | ||
622 | 626 | ||
623 | # | 627 | # |
624 | # Character devices | 628 | # Character devices |
@@ -687,7 +691,6 @@ CONFIG_RTC=m | |||
687 | # | 691 | # |
688 | # TPM devices | 692 | # TPM devices |
689 | # | 693 | # |
690 | # CONFIG_TCG_TPM is not set | ||
691 | 694 | ||
692 | # | 695 | # |
693 | # I2C support | 696 | # I2C support |
@@ -736,6 +739,7 @@ CONFIG_I2C_ELEKTOR=m | |||
736 | # CONFIG_SENSORS_LM85 is not set | 739 | # CONFIG_SENSORS_LM85 is not set |
737 | # CONFIG_SENSORS_LM87 is not set | 740 | # CONFIG_SENSORS_LM87 is not set |
738 | # CONFIG_SENSORS_LM90 is not set | 741 | # CONFIG_SENSORS_LM90 is not set |
742 | # CONFIG_SENSORS_LM92 is not set | ||
739 | # CONFIG_SENSORS_MAX1619 is not set | 743 | # CONFIG_SENSORS_MAX1619 is not set |
740 | # CONFIG_SENSORS_PC87360 is not set | 744 | # CONFIG_SENSORS_PC87360 is not set |
741 | # CONFIG_SENSORS_SMSC47B397 is not set | 745 | # CONFIG_SENSORS_SMSC47B397 is not set |
@@ -747,6 +751,7 @@ CONFIG_I2C_ELEKTOR=m | |||
747 | # | 751 | # |
748 | # Other I2C Chip support | 752 | # Other I2C Chip support |
749 | # | 753 | # |
754 | # CONFIG_SENSORS_DS1337 is not set | ||
750 | # CONFIG_SENSORS_EEPROM is not set | 755 | # CONFIG_SENSORS_EEPROM is not set |
751 | # CONFIG_SENSORS_PCF8574 is not set | 756 | # CONFIG_SENSORS_PCF8574 is not set |
752 | # CONFIG_SENSORS_PCF8591 is not set | 757 | # CONFIG_SENSORS_PCF8591 is not set |
@@ -871,7 +876,6 @@ CONFIG_USB_PRINTER=m | |||
871 | # | 876 | # |
872 | CONFIG_USB_STORAGE=y | 877 | CONFIG_USB_STORAGE=y |
873 | CONFIG_USB_STORAGE_DEBUG=y | 878 | CONFIG_USB_STORAGE_DEBUG=y |
874 | # CONFIG_USB_STORAGE_RW_DETECT is not set | ||
875 | # CONFIG_USB_STORAGE_DATAFAB is not set | 879 | # CONFIG_USB_STORAGE_DATAFAB is not set |
876 | # CONFIG_USB_STORAGE_FREECOM is not set | 880 | # CONFIG_USB_STORAGE_FREECOM is not set |
877 | # CONFIG_USB_STORAGE_ISD200 is not set | 881 | # CONFIG_USB_STORAGE_ISD200 is not set |
@@ -954,9 +958,11 @@ CONFIG_USB_USS720=m | |||
954 | # | 958 | # |
955 | CONFIG_USB_SERIAL=m | 959 | CONFIG_USB_SERIAL=m |
956 | CONFIG_USB_SERIAL_GENERIC=y | 960 | CONFIG_USB_SERIAL_GENERIC=y |
961 | # CONFIG_USB_SERIAL_AIRPRIME is not set | ||
957 | CONFIG_USB_SERIAL_BELKIN=m | 962 | CONFIG_USB_SERIAL_BELKIN=m |
958 | CONFIG_USB_SERIAL_WHITEHEAT=m | 963 | CONFIG_USB_SERIAL_WHITEHEAT=m |
959 | CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m | 964 | CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m |
965 | # CONFIG_USB_SERIAL_CP2101 is not set | ||
960 | # CONFIG_USB_SERIAL_CYPRESS_M8 is not set | 966 | # CONFIG_USB_SERIAL_CYPRESS_M8 is not set |
961 | CONFIG_USB_SERIAL_EMPEG=m | 967 | CONFIG_USB_SERIAL_EMPEG=m |
962 | CONFIG_USB_SERIAL_FTDI_SIO=m | 968 | CONFIG_USB_SERIAL_FTDI_SIO=m |
@@ -985,6 +991,7 @@ CONFIG_USB_SERIAL_KEYSPAN=m | |||
985 | # CONFIG_USB_SERIAL_KOBIL_SCT is not set | 991 | # CONFIG_USB_SERIAL_KOBIL_SCT is not set |
986 | CONFIG_USB_SERIAL_MCT_U232=m | 992 | CONFIG_USB_SERIAL_MCT_U232=m |
987 | CONFIG_USB_SERIAL_PL2303=m | 993 | CONFIG_USB_SERIAL_PL2303=m |
994 | # CONFIG_USB_SERIAL_HP4X is not set | ||
988 | # CONFIG_USB_SERIAL_SAFE is not set | 995 | # CONFIG_USB_SERIAL_SAFE is not set |
989 | # CONFIG_USB_SERIAL_TI is not set | 996 | # CONFIG_USB_SERIAL_TI is not set |
990 | CONFIG_USB_SERIAL_CYBERJACK=m | 997 | CONFIG_USB_SERIAL_CYBERJACK=m |
diff --git a/arch/arm/configs/h3600_defconfig b/arch/arm/configs/h3600_defconfig index b4e297dd54b2..b9de07de80fe 100644 --- a/arch/arm/configs/h3600_defconfig +++ b/arch/arm/configs/h3600_defconfig | |||
@@ -1,7 +1,7 @@ | |||
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-rc4 |
4 | # Mon Mar 28 00:02:26 2005 | 4 | # Thu Jun 9 01:59:03 2005 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
@@ -16,6 +16,7 @@ CONFIG_GENERIC_IOMAP=y | |||
16 | CONFIG_EXPERIMENTAL=y | 16 | CONFIG_EXPERIMENTAL=y |
17 | CONFIG_CLEAN_COMPILE=y | 17 | CONFIG_CLEAN_COMPILE=y |
18 | CONFIG_BROKEN_ON_SMP=y | 18 | CONFIG_BROKEN_ON_SMP=y |
19 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
19 | 20 | ||
20 | # | 21 | # |
21 | # General setup | 22 | # General setup |
@@ -33,6 +34,8 @@ CONFIG_KOBJECT_UEVENT=y | |||
33 | # CONFIG_EMBEDDED is not set | 34 | # CONFIG_EMBEDDED is not set |
34 | CONFIG_KALLSYMS=y | 35 | CONFIG_KALLSYMS=y |
35 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 36 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
37 | CONFIG_PRINTK=y | ||
38 | CONFIG_BUG=y | ||
36 | CONFIG_BASE_FULL=y | 39 | CONFIG_BASE_FULL=y |
37 | CONFIG_FUTEX=y | 40 | CONFIG_FUTEX=y |
38 | CONFIG_EPOLL=y | 41 | CONFIG_EPOLL=y |
@@ -120,6 +123,7 @@ CONFIG_CPU_MINICACHE=y | |||
120 | # Bus support | 123 | # Bus support |
121 | # | 124 | # |
122 | CONFIG_ISA=y | 125 | CONFIG_ISA=y |
126 | CONFIG_ISA_DMA_API=y | ||
123 | 127 | ||
124 | # | 128 | # |
125 | # PCCARD (PCMCIA/CardBus) support | 129 | # PCCARD (PCMCIA/CardBus) support |
@@ -138,6 +142,7 @@ CONFIG_PCMCIA_SA1100=y | |||
138 | # | 142 | # |
139 | # Kernel Features | 143 | # Kernel Features |
140 | # | 144 | # |
145 | # CONFIG_SMP is not set | ||
141 | # CONFIG_PREEMPT is not set | 146 | # CONFIG_PREEMPT is not set |
142 | CONFIG_DISCONTIGMEM=y | 147 | CONFIG_DISCONTIGMEM=y |
143 | # CONFIG_LEDS is not set | 148 | # CONFIG_LEDS is not set |
@@ -159,12 +164,13 @@ CONFIG_CPU_FREQ_TABLE=y | |||
159 | # CONFIG_CPU_FREQ_DEBUG is not set | 164 | # CONFIG_CPU_FREQ_DEBUG is not set |
160 | CONFIG_CPU_FREQ_STAT=y | 165 | CONFIG_CPU_FREQ_STAT=y |
161 | # CONFIG_CPU_FREQ_STAT_DETAILS is not set | 166 | # CONFIG_CPU_FREQ_STAT_DETAILS is not set |
162 | CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y | 167 | # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set |
163 | # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set | 168 | CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y |
164 | CONFIG_CPU_FREQ_GOV_PERFORMANCE=y | 169 | # CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set |
165 | # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set | 170 | # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set |
166 | # CONFIG_CPU_FREQ_GOV_USERSPACE is not set | 171 | CONFIG_CPU_FREQ_GOV_USERSPACE=y |
167 | # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set | 172 | # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set |
173 | CONFIG_CPU_FREQ_SA1100=y | ||
168 | 174 | ||
169 | # | 175 | # |
170 | # Floating point emulation | 176 | # Floating point emulation |
@@ -298,7 +304,6 @@ CONFIG_MTD_SA1100=y | |||
298 | # | 304 | # |
299 | # Block devices | 305 | # Block devices |
300 | # | 306 | # |
301 | # CONFIG_BLK_DEV_FD is not set | ||
302 | # CONFIG_BLK_DEV_XD is not set | 307 | # CONFIG_BLK_DEV_XD is not set |
303 | # CONFIG_BLK_DEV_COW_COMMON is not set | 308 | # CONFIG_BLK_DEV_COW_COMMON is not set |
304 | CONFIG_BLK_DEV_LOOP=m | 309 | CONFIG_BLK_DEV_LOOP=m |
@@ -379,7 +384,6 @@ CONFIG_NET=y | |||
379 | # Networking options | 384 | # Networking options |
380 | # | 385 | # |
381 | # CONFIG_PACKET is not set | 386 | # CONFIG_PACKET is not set |
382 | # CONFIG_NETLINK_DEV is not set | ||
383 | CONFIG_UNIX=y | 387 | CONFIG_UNIX=y |
384 | # CONFIG_NET_KEY is not set | 388 | # CONFIG_NET_KEY is not set |
385 | CONFIG_INET=y | 389 | CONFIG_INET=y |
@@ -476,6 +480,7 @@ CONFIG_IRCOMM=m | |||
476 | # CONFIG_SMC_IRCC_FIR is not set | 480 | # CONFIG_SMC_IRCC_FIR is not set |
477 | # CONFIG_ALI_FIR is not set | 481 | # CONFIG_ALI_FIR is not set |
478 | CONFIG_SA1100_FIR=m | 482 | CONFIG_SA1100_FIR=m |
483 | # CONFIG_VIA_FIR is not set | ||
479 | # CONFIG_BT is not set | 484 | # CONFIG_BT is not set |
480 | CONFIG_NETDEVICES=y | 485 | CONFIG_NETDEVICES=y |
481 | # CONFIG_DUMMY is not set | 486 | # CONFIG_DUMMY is not set |
@@ -647,7 +652,6 @@ CONFIG_LEGACY_PTY_COUNT=256 | |||
647 | # | 652 | # |
648 | # TPM devices | 653 | # TPM devices |
649 | # | 654 | # |
650 | # CONFIG_TCG_TPM is not set | ||
651 | 655 | ||
652 | # | 656 | # |
653 | # I2C support | 657 | # I2C support |
@@ -676,9 +680,11 @@ CONFIG_FB_CFB_FILLRECT=y | |||
676 | CONFIG_FB_CFB_COPYAREA=y | 680 | CONFIG_FB_CFB_COPYAREA=y |
677 | CONFIG_FB_CFB_IMAGEBLIT=y | 681 | CONFIG_FB_CFB_IMAGEBLIT=y |
678 | CONFIG_FB_SOFT_CURSOR=y | 682 | CONFIG_FB_SOFT_CURSOR=y |
683 | # CONFIG_FB_MACMODES is not set | ||
679 | # CONFIG_FB_MODE_HELPERS is not set | 684 | # CONFIG_FB_MODE_HELPERS is not set |
680 | # CONFIG_FB_TILEBLITTING is not set | 685 | # CONFIG_FB_TILEBLITTING is not set |
681 | CONFIG_FB_SA1100=y | 686 | CONFIG_FB_SA1100=y |
687 | # CONFIG_FB_S1D13XXX is not set | ||
682 | # CONFIG_FB_VIRTUAL is not set | 688 | # CONFIG_FB_VIRTUAL is not set |
683 | 689 | ||
684 | # | 690 | # |
diff --git a/arch/arm/configs/hackkit_defconfig b/arch/arm/configs/hackkit_defconfig index 6987c8c5ddb4..fb41a36a5a68 100644 --- a/arch/arm/configs/hackkit_defconfig +++ b/arch/arm/configs/hackkit_defconfig | |||
@@ -1,7 +1,7 @@ | |||
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-rc6-git3 |
4 | # Mon Mar 28 00:22:34 2005 | 4 | # Thu Jun 9 20:58:58 2005 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
@@ -16,6 +16,7 @@ CONFIG_GENERIC_IOMAP=y | |||
16 | CONFIG_EXPERIMENTAL=y | 16 | CONFIG_EXPERIMENTAL=y |
17 | CONFIG_CLEAN_COMPILE=y | 17 | CONFIG_CLEAN_COMPILE=y |
18 | CONFIG_BROKEN_ON_SMP=y | 18 | CONFIG_BROKEN_ON_SMP=y |
19 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
19 | 20 | ||
20 | # | 21 | # |
21 | # General setup | 22 | # General setup |
@@ -34,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y | |||
34 | CONFIG_KALLSYMS=y | 35 | CONFIG_KALLSYMS=y |
35 | # CONFIG_KALLSYMS_ALL is not set | 36 | # CONFIG_KALLSYMS_ALL is not set |
36 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
38 | CONFIG_PRINTK=y | ||
39 | CONFIG_BUG=y | ||
37 | CONFIG_BASE_FULL=y | 40 | CONFIG_BASE_FULL=y |
38 | CONFIG_FUTEX=y | 41 | CONFIG_FUTEX=y |
39 | CONFIG_EPOLL=y | 42 | CONFIG_EPOLL=y |
@@ -109,7 +112,6 @@ CONFIG_CPU_ABRT_EV4=y | |||
109 | CONFIG_CPU_CACHE_V4WB=y | 112 | CONFIG_CPU_CACHE_V4WB=y |
110 | CONFIG_CPU_CACHE_VIVT=y | 113 | CONFIG_CPU_CACHE_VIVT=y |
111 | CONFIG_CPU_TLB_V4WB=y | 114 | CONFIG_CPU_TLB_V4WB=y |
112 | CONFIG_CPU_MINICACHE=y | ||
113 | 115 | ||
114 | # | 116 | # |
115 | # Processor Features | 117 | # Processor Features |
@@ -119,6 +121,7 @@ CONFIG_CPU_MINICACHE=y | |||
119 | # Bus support | 121 | # Bus support |
120 | # | 122 | # |
121 | CONFIG_ISA=y | 123 | CONFIG_ISA=y |
124 | CONFIG_ISA_DMA_API=y | ||
122 | 125 | ||
123 | # | 126 | # |
124 | # PCCARD (PCMCIA/CardBus) support | 127 | # PCCARD (PCMCIA/CardBus) support |
@@ -128,6 +131,7 @@ CONFIG_ISA=y | |||
128 | # | 131 | # |
129 | # Kernel Features | 132 | # Kernel Features |
130 | # | 133 | # |
134 | # CONFIG_SMP is not set | ||
131 | # CONFIG_PREEMPT is not set | 135 | # CONFIG_PREEMPT is not set |
132 | CONFIG_DISCONTIGMEM=y | 136 | CONFIG_DISCONTIGMEM=y |
133 | CONFIG_LEDS=y | 137 | CONFIG_LEDS=y |
@@ -151,12 +155,14 @@ CONFIG_CPU_FREQ_TABLE=y | |||
151 | # CONFIG_CPU_FREQ_DEBUG is not set | 155 | # CONFIG_CPU_FREQ_DEBUG is not set |
152 | CONFIG_CPU_FREQ_STAT=y | 156 | CONFIG_CPU_FREQ_STAT=y |
153 | # CONFIG_CPU_FREQ_STAT_DETAILS is not set | 157 | # CONFIG_CPU_FREQ_STAT_DETAILS is not set |
154 | CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y | 158 | # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set |
155 | # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set | 159 | CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y |
156 | CONFIG_CPU_FREQ_GOV_PERFORMANCE=y | 160 | CONFIG_CPU_FREQ_GOV_PERFORMANCE=y |
157 | # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set | 161 | # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set |
158 | # CONFIG_CPU_FREQ_GOV_USERSPACE is not set | 162 | CONFIG_CPU_FREQ_GOV_USERSPACE=y |
159 | # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set | 163 | # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set |
164 | # CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set | ||
165 | CONFIG_CPU_FREQ_SA1100=y | ||
160 | 166 | ||
161 | # | 167 | # |
162 | # Floating point emulation | 168 | # Floating point emulation |
@@ -280,7 +286,6 @@ CONFIG_MTD_CFI_UTIL=y | |||
280 | # | 286 | # |
281 | # Block devices | 287 | # Block devices |
282 | # | 288 | # |
283 | # CONFIG_BLK_DEV_FD is not set | ||
284 | # CONFIG_BLK_DEV_XD is not set | 289 | # CONFIG_BLK_DEV_XD is not set |
285 | # CONFIG_BLK_DEV_COW_COMMON is not set | 290 | # CONFIG_BLK_DEV_COW_COMMON is not set |
286 | # CONFIG_BLK_DEV_LOOP is not set | 291 | # CONFIG_BLK_DEV_LOOP is not set |
@@ -338,7 +343,6 @@ CONFIG_NET=y | |||
338 | # | 343 | # |
339 | CONFIG_PACKET=y | 344 | CONFIG_PACKET=y |
340 | # CONFIG_PACKET_MMAP is not set | 345 | # CONFIG_PACKET_MMAP is not set |
341 | # CONFIG_NETLINK_DEV is not set | ||
342 | CONFIG_UNIX=y | 346 | CONFIG_UNIX=y |
343 | # CONFIG_NET_KEY is not set | 347 | # CONFIG_NET_KEY is not set |
344 | CONFIG_INET=y | 348 | CONFIG_INET=y |
@@ -484,7 +488,6 @@ CONFIG_SERIO=y | |||
484 | CONFIG_SERIO_SERPORT=y | 488 | CONFIG_SERIO_SERPORT=y |
485 | # CONFIG_SERIO_RAW is not set | 489 | # CONFIG_SERIO_RAW is not set |
486 | # CONFIG_GAMEPORT is not set | 490 | # CONFIG_GAMEPORT is not set |
487 | CONFIG_SOUND_GAMEPORT=y | ||
488 | 491 | ||
489 | # | 492 | # |
490 | # Character devices | 493 | # Character devices |
@@ -533,7 +536,6 @@ CONFIG_LEGACY_PTY_COUNT=256 | |||
533 | # | 536 | # |
534 | # TPM devices | 537 | # TPM devices |
535 | # | 538 | # |
536 | # CONFIG_TCG_TPM is not set | ||
537 | 539 | ||
538 | # | 540 | # |
539 | # I2C support | 541 | # I2C support |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 080df907f242..e14278d59882 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -17,8 +17,8 @@ | |||
17 | 17 | ||
18 | #include <asm/glue.h> | 18 | #include <asm/glue.h> |
19 | #include <asm/vfpmacros.h> | 19 | #include <asm/vfpmacros.h> |
20 | #include <asm/hardware.h> @ should be moved into entry-macro.S | 20 | #include <asm/hardware.h> /* should be moved into entry-macro.S */ |
21 | #include <asm/arch/irqs.h> @ should be moved into entry-macro.S | 21 | #include <asm/arch/irqs.h> /* should be moved into entry-macro.S */ |
22 | #include <asm/arch/entry-macro.S> | 22 | #include <asm/arch/entry-macro.S> |
23 | 23 | ||
24 | #include "entry-header.S" | 24 | #include "entry-header.S" |
@@ -269,7 +269,7 @@ __pabt_svc: | |||
269 | add r5, sp, #S_PC | 269 | add r5, sp, #S_PC |
270 | ldmia r7, {r2 - r4} @ Get USR pc, cpsr | 270 | ldmia r7, {r2 - r4} @ Get USR pc, cpsr |
271 | 271 | ||
272 | #if __LINUX_ARM_ARCH__ < 6 | 272 | #if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) |
273 | @ make sure our user space atomic helper is aborted | 273 | @ make sure our user space atomic helper is aborted |
274 | cmp r2, #VIRT_OFFSET | 274 | cmp r2, #VIRT_OFFSET |
275 | bichs r3, r3, #PSR_Z_BIT | 275 | bichs r3, r3, #PSR_Z_BIT |
@@ -505,9 +505,9 @@ ENTRY(__switch_to) | |||
505 | mra r4, r5, acc0 | 505 | mra r4, r5, acc0 |
506 | stmia ip, {r4, r5} | 506 | stmia ip, {r4, r5} |
507 | #endif | 507 | #endif |
508 | #ifdef CONFIG_HAS_TLS_REG | 508 | #if defined(CONFIG_HAS_TLS_REG) |
509 | mcr p15, 0, r3, c13, c0, 3 @ set TLS register | 509 | mcr p15, 0, r3, c13, c0, 3 @ set TLS register |
510 | #else | 510 | #elif !defined(CONFIG_TLS_REG_EMUL) |
511 | mov r4, #0xffff0fff | 511 | mov r4, #0xffff0fff |
512 | str r3, [r4, #-15] @ TLS val at 0xffff0ff0 | 512 | str r3, [r4, #-15] @ TLS val at 0xffff0ff0 |
513 | #endif | 513 | #endif |
@@ -616,11 +616,17 @@ __kuser_helper_start: | |||
616 | 616 | ||
617 | __kuser_cmpxchg: @ 0xffff0fc0 | 617 | __kuser_cmpxchg: @ 0xffff0fc0 |
618 | 618 | ||
619 | #if __LINUX_ARM_ARCH__ < 6 | 619 | #if defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) |
620 | 620 | ||
621 | #ifdef CONFIG_SMP /* sanity check */ | 621 | /* |
622 | #error "CONFIG_SMP on a machine supporting pre-ARMv6 processors?" | 622 | * Poor you. No fast solution possible... |
623 | #endif | 623 | * The kernel itself must perform the operation. |
624 | * A special ghost syscall is used for that (see traps.c). | ||
625 | */ | ||
626 | swi #0x9ffff0 | ||
627 | mov pc, lr | ||
628 | |||
629 | #elif __LINUX_ARM_ARCH__ < 6 | ||
624 | 630 | ||
625 | /* | 631 | /* |
626 | * Theory of operation: | 632 | * Theory of operation: |
@@ -690,11 +696,7 @@ __kuser_cmpxchg: @ 0xffff0fc0 | |||
690 | 696 | ||
691 | __kuser_get_tls: @ 0xffff0fe0 | 697 | __kuser_get_tls: @ 0xffff0fe0 |
692 | 698 | ||
693 | #ifndef CONFIG_HAS_TLS_REG | 699 | #if !defined(CONFIG_HAS_TLS_REG) && !defined(CONFIG_TLS_REG_EMUL) |
694 | |||
695 | #ifdef CONFIG_SMP /* sanity check */ | ||
696 | #error "CONFIG_SMP without CONFIG_HAS_TLS_REG is wrong" | ||
697 | #endif | ||
698 | 700 | ||
699 | ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0 | 701 | ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0 |
700 | mov pc, lr | 702 | mov pc, lr |
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 171b3e811c71..4733877296d4 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <asm/procinfo.h> | 19 | #include <asm/procinfo.h> |
20 | #include <asm/ptrace.h> | 20 | #include <asm/ptrace.h> |
21 | #include <asm/constants.h> | 21 | #include <asm/constants.h> |
22 | #include <asm/thread_info.h> | ||
22 | #include <asm/system.h> | 23 | #include <asm/system.h> |
23 | 24 | ||
24 | #define PROCINFO_MMUFLAGS 8 | 25 | #define PROCINFO_MMUFLAGS 8 |
@@ -131,7 +132,7 @@ __switch_data: | |||
131 | .long processor_id @ r4 | 132 | .long processor_id @ r4 |
132 | .long __machine_arch_type @ r5 | 133 | .long __machine_arch_type @ r5 |
133 | .long cr_alignment @ r6 | 134 | .long cr_alignment @ r6 |
134 | .long init_thread_union+8192 @ sp | 135 | .long init_thread_union + THREAD_START_SP @ sp |
135 | 136 | ||
136 | /* | 137 | /* |
137 | * The following fragment of code is executed with the MMU on, and uses | 138 | * The following fragment of code is executed with the MMU on, and uses |
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 26eacd3e5def..8f146a4b4752 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
@@ -256,8 +256,6 @@ static unsigned long *thread_info_head; | |||
256 | static unsigned int nr_thread_info; | 256 | static unsigned int nr_thread_info; |
257 | 257 | ||
258 | #define EXTRA_TASK_STRUCT 4 | 258 | #define EXTRA_TASK_STRUCT 4 |
259 | #define ll_alloc_task_struct() ((struct thread_info *) __get_free_pages(GFP_KERNEL,1)) | ||
260 | #define ll_free_task_struct(p) free_pages((unsigned long)(p),1) | ||
261 | 259 | ||
262 | struct thread_info *alloc_thread_info(struct task_struct *task) | 260 | struct thread_info *alloc_thread_info(struct task_struct *task) |
263 | { | 261 | { |
@@ -274,17 +272,16 @@ struct thread_info *alloc_thread_info(struct task_struct *task) | |||
274 | } | 272 | } |
275 | 273 | ||
276 | if (!thread) | 274 | if (!thread) |
277 | thread = ll_alloc_task_struct(); | 275 | thread = (struct thread_info *) |
276 | __get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER); | ||
278 | 277 | ||
279 | #ifdef CONFIG_MAGIC_SYSRQ | 278 | #ifdef CONFIG_DEBUG_STACK_USAGE |
280 | /* | 279 | /* |
281 | * The stack must be cleared if you want SYSRQ-T to | 280 | * The stack must be cleared if you want SYSRQ-T to |
282 | * give sensible stack usage information | 281 | * give sensible stack usage information |
283 | */ | 282 | */ |
284 | if (thread) { | 283 | if (thread) |
285 | char *p = (char *)thread; | 284 | memzero(thread, THREAD_SIZE); |
286 | memzero(p+KERNEL_STACK_SIZE, KERNEL_STACK_SIZE); | ||
287 | } | ||
288 | #endif | 285 | #endif |
289 | return thread; | 286 | return thread; |
290 | } | 287 | } |
@@ -297,7 +294,7 @@ void free_thread_info(struct thread_info *thread) | |||
297 | thread_info_head = p; | 294 | thread_info_head = p; |
298 | nr_thread_info += 1; | 295 | nr_thread_info += 1; |
299 | } else | 296 | } else |
300 | ll_free_task_struct(thread); | 297 | free_pages((unsigned long)thread, THREAD_SIZE_ORDER); |
301 | } | 298 | } |
302 | 299 | ||
303 | /* | 300 | /* |
@@ -350,7 +347,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start, | |||
350 | struct thread_info *thread = p->thread_info; | 347 | struct thread_info *thread = p->thread_info; |
351 | struct pt_regs *childregs; | 348 | struct pt_regs *childregs; |
352 | 349 | ||
353 | childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_SIZE - 8)) - 1; | 350 | childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_START_SP)) - 1; |
354 | *childregs = *regs; | 351 | *childregs = *regs; |
355 | childregs->ARM_r0 = 0; | 352 | childregs->ARM_r0 = 0; |
356 | childregs->ARM_sp = stack_start; | 353 | childregs->ARM_sp = stack_start; |
@@ -447,15 +444,17 @@ EXPORT_SYMBOL(kernel_thread); | |||
447 | unsigned long get_wchan(struct task_struct *p) | 444 | unsigned long get_wchan(struct task_struct *p) |
448 | { | 445 | { |
449 | unsigned long fp, lr; | 446 | unsigned long fp, lr; |
450 | unsigned long stack_page; | 447 | unsigned long stack_start, stack_end; |
451 | int count = 0; | 448 | int count = 0; |
452 | if (!p || p == current || p->state == TASK_RUNNING) | 449 | if (!p || p == current || p->state == TASK_RUNNING) |
453 | return 0; | 450 | return 0; |
454 | 451 | ||
455 | stack_page = 4096 + (unsigned long)p->thread_info; | 452 | stack_start = (unsigned long)(p->thread_info + 1); |
453 | stack_end = ((unsigned long)p->thread_info) + THREAD_SIZE; | ||
454 | |||
456 | fp = thread_saved_fp(p); | 455 | fp = thread_saved_fp(p); |
457 | do { | 456 | do { |
458 | if (fp < stack_page || fp > 4092+stack_page) | 457 | if (fp < stack_start || fp > stack_end) |
459 | return 0; | 458 | return 0; |
460 | lr = pc_pointer (((unsigned long *)fp)[-1]); | 459 | lr = pc_pointer (((unsigned long *)fp)[-1]); |
461 | if (!in_sched_functions(lr)) | 460 | if (!in_sched_functions(lr)) |
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index ef32577da304..f897ce2ccf0d 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c | |||
@@ -302,7 +302,7 @@ long execve(const char *filename, char **argv, char **envp) | |||
302 | "b ret_to_user" | 302 | "b ret_to_user" |
303 | : | 303 | : |
304 | : "r" (current_thread_info()), | 304 | : "r" (current_thread_info()), |
305 | "Ir" (THREAD_SIZE - 8 - sizeof(regs)), | 305 | "Ir" (THREAD_START_SP - sizeof(regs)), |
306 | "r" (®s), | 306 | "r" (®s), |
307 | "Ir" (sizeof(regs)) | 307 | "Ir" (sizeof(regs)) |
308 | : "r0", "r1", "r2", "r3", "ip", "memory"); | 308 | : "r0", "r1", "r2", "r3", "ip", "memory"); |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 3a001fe5540b..45d2a032d890 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -218,7 +218,8 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err) | |||
218 | tsk->comm, tsk->pid, tsk->thread_info + 1); | 218 | tsk->comm, tsk->pid, tsk->thread_info + 1); |
219 | 219 | ||
220 | if (!user_mode(regs) || in_interrupt()) { | 220 | if (!user_mode(regs) || in_interrupt()) { |
221 | dump_mem("Stack: ", regs->ARM_sp, 8192+(unsigned long)tsk->thread_info); | 221 | dump_mem("Stack: ", regs->ARM_sp, |
222 | THREAD_SIZE + (unsigned long)tsk->thread_info); | ||
222 | dump_backtrace(regs, tsk); | 223 | dump_backtrace(regs, tsk); |
223 | dump_instr(regs); | 224 | dump_instr(regs); |
224 | } | 225 | } |
@@ -450,9 +451,9 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) | |||
450 | 451 | ||
451 | case NR(set_tls): | 452 | case NR(set_tls): |
452 | thread->tp_value = regs->ARM_r0; | 453 | thread->tp_value = regs->ARM_r0; |
453 | #ifdef CONFIG_HAS_TLS_REG | 454 | #if defined(CONFIG_HAS_TLS_REG) |
454 | asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) ); | 455 | asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) ); |
455 | #else | 456 | #elif !defined(CONFIG_TLS_REG_EMUL) |
456 | /* | 457 | /* |
457 | * User space must never try to access this directly. | 458 | * User space must never try to access this directly. |
458 | * Expect your app to break eventually if you do so. | 459 | * Expect your app to break eventually if you do so. |
@@ -463,6 +464,55 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) | |||
463 | #endif | 464 | #endif |
464 | return 0; | 465 | return 0; |
465 | 466 | ||
467 | #ifdef CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG | ||
468 | /* | ||
469 | * Atomically store r1 in *r2 if *r2 is equal to r0 for user space. | ||
470 | * Return zero in r0 if *MEM was changed or non-zero if no exchange | ||
471 | * happened. Also set the user C flag accordingly. | ||
472 | * If access permissions have to be fixed up then non-zero is | ||
473 | * returned and the operation has to be re-attempted. | ||
474 | * | ||
475 | * *NOTE*: This is a ghost syscall private to the kernel. Only the | ||
476 | * __kuser_cmpxchg code in entry-armv.S should be aware of its | ||
477 | * existence. Don't ever use this from user code. | ||
478 | */ | ||
479 | case 0xfff0: | ||
480 | { | ||
481 | extern void do_DataAbort(unsigned long addr, unsigned int fsr, | ||
482 | struct pt_regs *regs); | ||
483 | unsigned long val; | ||
484 | unsigned long addr = regs->ARM_r2; | ||
485 | struct mm_struct *mm = current->mm; | ||
486 | pgd_t *pgd; pmd_t *pmd; pte_t *pte; | ||
487 | |||
488 | regs->ARM_cpsr &= ~PSR_C_BIT; | ||
489 | spin_lock(&mm->page_table_lock); | ||
490 | pgd = pgd_offset(mm, addr); | ||
491 | if (!pgd_present(*pgd)) | ||
492 | goto bad_access; | ||
493 | pmd = pmd_offset(pgd, addr); | ||
494 | if (!pmd_present(*pmd)) | ||
495 | goto bad_access; | ||
496 | pte = pte_offset_map(pmd, addr); | ||
497 | if (!pte_present(*pte) || !pte_write(*pte)) | ||
498 | goto bad_access; | ||
499 | val = *(unsigned long *)addr; | ||
500 | val -= regs->ARM_r0; | ||
501 | if (val == 0) { | ||
502 | *(unsigned long *)addr = regs->ARM_r1; | ||
503 | regs->ARM_cpsr |= PSR_C_BIT; | ||
504 | } | ||
505 | spin_unlock(&mm->page_table_lock); | ||
506 | return val; | ||
507 | |||
508 | bad_access: | ||
509 | spin_unlock(&mm->page_table_lock); | ||
510 | /* simulate a read access fault */ | ||
511 | do_DataAbort(addr, 15 + (1 << 11), regs); | ||
512 | return -1; | ||
513 | } | ||
514 | #endif | ||
515 | |||
466 | default: | 516 | default: |
467 | /* Calls 9f00xx..9f07ff are defined to return -ENOSYS | 517 | /* Calls 9f00xx..9f07ff are defined to return -ENOSYS |
468 | if not implemented, rather than raising SIGILL. This | 518 | if not implemented, rather than raising SIGILL. This |
@@ -497,11 +547,14 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) | |||
497 | return 0; | 547 | return 0; |
498 | } | 548 | } |
499 | 549 | ||
500 | #if defined(CONFIG_CPU_32v6) && !defined(CONFIG_HAS_TLS_REG) | 550 | #ifdef CONFIG_TLS_REG_EMUL |
501 | 551 | ||
502 | /* | 552 | /* |
503 | * We might be running on an ARMv6+ processor which should have the TLS | 553 | * We might be running on an ARMv6+ processor which should have the TLS |
504 | * register, but for some reason we can't use it and have to emulate it. | 554 | * register but for some reason we can't use it, or maybe an SMP system |
555 | * using a pre-ARMv6 processor (there are apparently a few prototypes like | ||
556 | * that in existence) and therefore access to that register must be | ||
557 | * emulated. | ||
505 | */ | 558 | */ |
506 | 559 | ||
507 | static int get_tp_trap(struct pt_regs *regs, unsigned int instr) | 560 | static int get_tp_trap(struct pt_regs *regs, unsigned int instr) |
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index a39c6a42d68a..ad2d66c93a5c 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S | |||
@@ -5,6 +5,7 @@ | |||
5 | 5 | ||
6 | #include <asm-generic/vmlinux.lds.h> | 6 | #include <asm-generic/vmlinux.lds.h> |
7 | #include <linux/config.h> | 7 | #include <linux/config.h> |
8 | #include <asm/thread_info.h> | ||
8 | 9 | ||
9 | OUTPUT_ARCH(arm) | 10 | OUTPUT_ARCH(arm) |
10 | ENTRY(stext) | 11 | ENTRY(stext) |
@@ -103,7 +104,7 @@ SECTIONS | |||
103 | __data_loc = ALIGN(4); /* location in binary */ | 104 | __data_loc = ALIGN(4); /* location in binary */ |
104 | . = DATAADDR; | 105 | . = DATAADDR; |
105 | #else | 106 | #else |
106 | . = ALIGN(8192); | 107 | . = ALIGN(THREAD_SIZE); |
107 | __data_loc = .; | 108 | __data_loc = .; |
108 | #endif | 109 | #endif |
109 | 110 | ||
diff --git a/arch/arm/lib/io-writesw-armv4.S b/arch/arm/lib/io-writesw-armv4.S index 6d1d7c27806e..5e240e452af6 100644 --- a/arch/arm/lib/io-writesw-armv4.S +++ b/arch/arm/lib/io-writesw-armv4.S | |||
@@ -87,9 +87,9 @@ ENTRY(__raw_writesw) | |||
87 | subs r2, r2, #2 | 87 | subs r2, r2, #2 |
88 | orr ip, ip, r3, push_hbyte1 | 88 | orr ip, ip, r3, push_hbyte1 |
89 | strh ip, [r0] | 89 | strh ip, [r0] |
90 | bpl 2b | 90 | bpl 1b |
91 | 91 | ||
92 | 3: tst r2, #1 | 92 | tst r2, #1 |
93 | 2: movne ip, r3, lsr #8 | 93 | 3: movne ip, r3, lsr #8 |
94 | strneh ip, [r0] | 94 | strneh ip, [r0] |
95 | mov pc, lr | 95 | mov pc, lr |
diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig index f6e676322ca9..45c930ccd064 100644 --- a/arch/arm/mach-clps711x/Kconfig +++ b/arch/arm/mach-clps711x/Kconfig | |||
@@ -10,6 +10,7 @@ config ARCH_AUTCPU12 | |||
10 | 10 | ||
11 | config ARCH_CDB89712 | 11 | config ARCH_CDB89712 |
12 | bool "CDB89712" | 12 | bool "CDB89712" |
13 | select ISA | ||
13 | help | 14 | help |
14 | This is an evaluation board from Cirrus for the CS89712 processor. | 15 | This is an evaluation board from Cirrus for the CS89712 processor. |
15 | The board includes 2 serial ports, Ethernet, IRDA, and expansion | 16 | The board includes 2 serial ports, Ethernet, IRDA, and expansion |
@@ -26,6 +27,8 @@ config ARCH_CLEP7312 | |||
26 | 27 | ||
27 | config ARCH_EDB7211 | 28 | config ARCH_EDB7211 |
28 | bool "EDB7211" | 29 | bool "EDB7211" |
30 | select ISA | ||
31 | select DISCONTIGMEM | ||
29 | help | 32 | help |
30 | 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 |
31 | evaluation board. | 34 | evaluation board. |
diff --git a/arch/arm/mach-footbridge/Kconfig b/arch/arm/mach-footbridge/Kconfig index 1090c680b6dd..324d9edeec38 100644 --- a/arch/arm/mach-footbridge/Kconfig +++ b/arch/arm/mach-footbridge/Kconfig | |||
@@ -5,6 +5,9 @@ menu "Footbridge Implementations" | |||
5 | config ARCH_CATS | 5 | config ARCH_CATS |
6 | bool "CATS" | 6 | bool "CATS" |
7 | select FOOTBRIDGE_HOST | 7 | select FOOTBRIDGE_HOST |
8 | select ISA | ||
9 | select ISA_DMA | ||
10 | select PCI | ||
8 | help | 11 | help |
9 | Say Y here if you intend to run this kernel on the CATS. | 12 | Say Y here if you intend to run this kernel on the CATS. |
10 | 13 | ||
@@ -13,6 +16,9 @@ config ARCH_CATS | |||
13 | config ARCH_PERSONAL_SERVER | 16 | config ARCH_PERSONAL_SERVER |
14 | bool "Compaq Personal Server" | 17 | bool "Compaq Personal Server" |
15 | select FOOTBRIDGE_HOST | 18 | select FOOTBRIDGE_HOST |
19 | select ISA | ||
20 | select ISA_DMA | ||
21 | select PCI | ||
16 | ---help--- | 22 | ---help--- |
17 | Say Y here if you intend to run this kernel on the Compaq | 23 | Say Y here if you intend to run this kernel on the Compaq |
18 | Personal Server. | 24 | Personal Server. |
@@ -42,6 +48,9 @@ config ARCH_EBSA285_HOST | |||
42 | bool "EBSA285 (host mode)" | 48 | bool "EBSA285 (host mode)" |
43 | select ARCH_EBSA285 | 49 | select ARCH_EBSA285 |
44 | select FOOTBRIDGE_HOST | 50 | select FOOTBRIDGE_HOST |
51 | select ISA | ||
52 | select ISA_DMA | ||
53 | select PCI | ||
45 | help | 54 | help |
46 | Say Y here if you intend to run this kernel on the EBSA285 card | 55 | Say Y here if you intend to run this kernel on the EBSA285 card |
47 | in host ("central function") mode. | 56 | in host ("central function") mode. |
@@ -51,6 +60,9 @@ config ARCH_EBSA285_HOST | |||
51 | config ARCH_NETWINDER | 60 | config ARCH_NETWINDER |
52 | bool "NetWinder" | 61 | bool "NetWinder" |
53 | select FOOTBRIDGE_HOST | 62 | select FOOTBRIDGE_HOST |
63 | select ISA | ||
64 | select ISA_DMA | ||
65 | select PCI | ||
54 | help | 66 | help |
55 | Say Y here if you intend to run this kernel on the Rebel.COM | 67 | Say Y here if you intend to run this kernel on the Rebel.COM |
56 | NetWinder. Information about this machine can be found at: | 68 | NetWinder. Information about this machine can be found at: |
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index ec85813ee5dc..cddd194ac6eb 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig | |||
@@ -4,6 +4,7 @@ menu "IMX Implementations" | |||
4 | config ARCH_MX1ADS | 4 | config ARCH_MX1ADS |
5 | bool "mx1ads" | 5 | bool "mx1ads" |
6 | depends on ARCH_IMX | 6 | depends on ARCH_IMX |
7 | select ISA | ||
7 | help | 8 | help |
8 | Say Y here if you are using the Motorola MX1ADS board | 9 | Say Y here if you are using the Motorola MX1ADS board |
9 | 10 | ||
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index 94bcdb933e41..aa92e3708838 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c | |||
@@ -502,15 +502,6 @@ pci_set_dma_mask(struct pci_dev *dev, u64 mask) | |||
502 | } | 502 | } |
503 | 503 | ||
504 | int | 504 | int |
505 | pci_dac_set_dma_mask(struct pci_dev *dev, u64 mask) | ||
506 | { | ||
507 | if (mask >= SZ_64M - 1 ) | ||
508 | return 0; | ||
509 | |||
510 | return -EIO; | ||
511 | } | ||
512 | |||
513 | int | ||
514 | pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) | 505 | pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) |
515 | { | 506 | { |
516 | if (mask >= SZ_64M - 1 ) | 507 | if (mask >= SZ_64M - 1 ) |
@@ -520,7 +511,6 @@ pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) | |||
520 | } | 511 | } |
521 | 512 | ||
522 | EXPORT_SYMBOL(pci_set_dma_mask); | 513 | EXPORT_SYMBOL(pci_set_dma_mask); |
523 | EXPORT_SYMBOL(pci_dac_set_dma_mask); | ||
524 | EXPORT_SYMBOL(pci_set_consistent_dma_mask); | 514 | EXPORT_SYMBOL(pci_set_consistent_dma_mask); |
525 | EXPORT_SYMBOL(ixp4xx_pci_read); | 515 | EXPORT_SYMBOL(ixp4xx_pci_read); |
526 | EXPORT_SYMBOL(ixp4xx_pci_write); | 516 | EXPORT_SYMBOL(ixp4xx_pci_write); |
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 3f952237ae3d..6823ae28ae6a 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c | |||
@@ -304,6 +304,15 @@ static void __init mainstone_map_io(void) | |||
304 | PWER = 0xC0000002; | 304 | PWER = 0xC0000002; |
305 | PRER = 0x00000002; | 305 | PRER = 0x00000002; |
306 | PFER = 0x00000002; | 306 | PFER = 0x00000002; |
307 | /* for use I SRAM as framebuffer. */ | ||
308 | PSLR |= 0xF04; | ||
309 | PCFR = 0x66; | ||
310 | /* For Keypad wakeup. */ | ||
311 | KPC &=~KPC_ASACT; | ||
312 | KPC |=KPC_AS; | ||
313 | PKWR = 0x000FD000; | ||
314 | /* Need read PKWR back after set it. */ | ||
315 | PKWR; | ||
307 | } | 316 | } |
308 | 317 | ||
309 | MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") | 318 | MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") |
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c index 82a4bf34c251..9799fe80df23 100644 --- a/arch/arm/mach-pxa/pm.c +++ b/arch/arm/mach-pxa/pm.c | |||
@@ -29,9 +29,6 @@ | |||
29 | */ | 29 | */ |
30 | #undef DEBUG | 30 | #undef DEBUG |
31 | 31 | ||
32 | extern void pxa_cpu_suspend(void); | ||
33 | extern void pxa_cpu_resume(void); | ||
34 | |||
35 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x | 32 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x |
36 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] | 33 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] |
37 | 34 | ||
@@ -63,6 +60,12 @@ enum { SLEEP_SAVE_START = 0, | |||
63 | SLEEP_SAVE_ICMR, | 60 | SLEEP_SAVE_ICMR, |
64 | SLEEP_SAVE_CKEN, | 61 | SLEEP_SAVE_CKEN, |
65 | 62 | ||
63 | #ifdef CONFIG_PXA27x | ||
64 | SLEEP_SAVE_MDREFR, | ||
65 | SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER, | ||
66 | SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR, | ||
67 | #endif | ||
68 | |||
66 | SLEEP_SAVE_CKSUM, | 69 | SLEEP_SAVE_CKSUM, |
67 | 70 | ||
68 | SLEEP_SAVE_SIZE | 71 | SLEEP_SAVE_SIZE |
@@ -75,9 +78,7 @@ static int pxa_pm_enter(suspend_state_t state) | |||
75 | unsigned long checksum = 0; | 78 | unsigned long checksum = 0; |
76 | struct timespec delta, rtc; | 79 | struct timespec delta, rtc; |
77 | int i; | 80 | int i; |
78 | 81 | extern void pxa_cpu_pm_enter(suspend_state_t state); | |
79 | if (state != PM_SUSPEND_MEM) | ||
80 | return -EINVAL; | ||
81 | 82 | ||
82 | #ifdef CONFIG_IWMMXT | 83 | #ifdef CONFIG_IWMMXT |
83 | /* force any iWMMXt context to ram **/ | 84 | /* force any iWMMXt context to ram **/ |
@@ -100,16 +101,17 @@ static int pxa_pm_enter(suspend_state_t state) | |||
100 | SAVE(GAFR2_L); SAVE(GAFR2_U); | 101 | SAVE(GAFR2_L); SAVE(GAFR2_U); |
101 | 102 | ||
102 | #ifdef CONFIG_PXA27x | 103 | #ifdef CONFIG_PXA27x |
104 | SAVE(MDREFR); | ||
103 | SAVE(GPLR3); SAVE(GPDR3); SAVE(GRER3); SAVE(GFER3); SAVE(PGSR3); | 105 | SAVE(GPLR3); SAVE(GPDR3); SAVE(GRER3); SAVE(GFER3); SAVE(PGSR3); |
104 | SAVE(GAFR3_L); SAVE(GAFR3_U); | 106 | SAVE(GAFR3_L); SAVE(GAFR3_U); |
107 | SAVE(PWER); SAVE(PCFR); SAVE(PRER); | ||
108 | SAVE(PFER); SAVE(PKWR); | ||
105 | #endif | 109 | #endif |
106 | 110 | ||
107 | SAVE(ICMR); | 111 | SAVE(ICMR); |
108 | ICMR = 0; | 112 | ICMR = 0; |
109 | 113 | ||
110 | SAVE(CKEN); | 114 | SAVE(CKEN); |
111 | CKEN = 0; | ||
112 | |||
113 | SAVE(PSTR); | 115 | SAVE(PSTR); |
114 | 116 | ||
115 | /* Note: wake up source are set up in each machine specific files */ | 117 | /* Note: wake up source are set up in each machine specific files */ |
@@ -123,16 +125,13 @@ static int pxa_pm_enter(suspend_state_t state) | |||
123 | /* Clear sleep reset status */ | 125 | /* Clear sleep reset status */ |
124 | RCSR = RCSR_SMR; | 126 | RCSR = RCSR_SMR; |
125 | 127 | ||
126 | /* set resume return address */ | ||
127 | PSPR = virt_to_phys(pxa_cpu_resume); | ||
128 | |||
129 | /* before sleeping, calculate and save a checksum */ | 128 | /* before sleeping, calculate and save a checksum */ |
130 | for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++) | 129 | for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++) |
131 | checksum += sleep_save[i]; | 130 | checksum += sleep_save[i]; |
132 | sleep_save[SLEEP_SAVE_CKSUM] = checksum; | 131 | sleep_save[SLEEP_SAVE_CKSUM] = checksum; |
133 | 132 | ||
134 | /* *** go zzz *** */ | 133 | /* *** go zzz *** */ |
135 | pxa_cpu_suspend(); | 134 | pxa_cpu_pm_enter(state); |
136 | 135 | ||
137 | /* after sleeping, validate the checksum */ | 136 | /* after sleeping, validate the checksum */ |
138 | checksum = 0; | 137 | checksum = 0; |
@@ -145,7 +144,7 @@ static int pxa_pm_enter(suspend_state_t state) | |||
145 | LUB_HEXLED = 0xbadbadc5; | 144 | LUB_HEXLED = 0xbadbadc5; |
146 | #endif | 145 | #endif |
147 | while (1) | 146 | while (1) |
148 | pxa_cpu_suspend(); | 147 | pxa_cpu_pm_enter(state); |
149 | } | 148 | } |
150 | 149 | ||
151 | /* ensure not to come back here if it wasn't intended */ | 150 | /* ensure not to come back here if it wasn't intended */ |
@@ -162,8 +161,11 @@ static int pxa_pm_enter(suspend_state_t state) | |||
162 | RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); | 161 | RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); |
163 | 162 | ||
164 | #ifdef CONFIG_PXA27x | 163 | #ifdef CONFIG_PXA27x |
164 | RESTORE(MDREFR); | ||
165 | RESTORE(GAFR3_L); RESTORE(GAFR3_U); RESTORE_GPLEVEL(3); | 165 | RESTORE(GAFR3_L); RESTORE(GAFR3_U); RESTORE_GPLEVEL(3); |
166 | RESTORE(GPDR3); RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3); | 166 | RESTORE(GPDR3); RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3); |
167 | RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER); | ||
168 | RESTORE(PFER); RESTORE(PKWR); | ||
167 | #endif | 169 | #endif |
168 | 170 | ||
169 | PSSR = PSSR_RDH | PSSR_PH; | 171 | PSSR = PSSR_RDH | PSSR_PH; |
@@ -197,7 +199,9 @@ unsigned long sleep_phys_sp(void *sp) | |||
197 | */ | 199 | */ |
198 | static int pxa_pm_prepare(suspend_state_t state) | 200 | static int pxa_pm_prepare(suspend_state_t state) |
199 | { | 201 | { |
200 | return 0; | 202 | extern int pxa_cpu_pm_prepare(suspend_state_t state); |
203 | |||
204 | return pxa_cpu_pm_prepare(state); | ||
201 | } | 205 | } |
202 | 206 | ||
203 | /* | 207 | /* |
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index e887b7175ef3..7869c3b4e62f 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c | |||
@@ -16,6 +16,7 @@ | |||
16 | * initialization stuff for PXA machines which can be overridden later if | 16 | * initialization stuff for PXA machines which can be overridden later if |
17 | * need be. | 17 | * need be. |
18 | */ | 18 | */ |
19 | #include <linux/config.h> | ||
19 | #include <linux/module.h> | 20 | #include <linux/module.h> |
20 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
21 | #include <linux/init.h> | 22 | #include <linux/init.h> |
@@ -102,3 +103,35 @@ unsigned int get_lcdclk_frequency_10khz(void) | |||
102 | } | 103 | } |
103 | 104 | ||
104 | EXPORT_SYMBOL(get_lcdclk_frequency_10khz); | 105 | EXPORT_SYMBOL(get_lcdclk_frequency_10khz); |
106 | |||
107 | #ifdef CONFIG_PM | ||
108 | |||
109 | int pxa_cpu_pm_prepare(suspend_state_t state) | ||
110 | { | ||
111 | switch (state) { | ||
112 | case PM_SUSPEND_MEM: | ||
113 | break; | ||
114 | default: | ||
115 | return -EINVAL; | ||
116 | } | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | void pxa_cpu_pm_enter(suspend_state_t state) | ||
122 | { | ||
123 | extern void pxa_cpu_suspend(unsigned int); | ||
124 | extern void pxa_cpu_resume(void); | ||
125 | |||
126 | CKEN = 0; | ||
127 | |||
128 | switch (state) { | ||
129 | case PM_SUSPEND_MEM: | ||
130 | /* set resume return address */ | ||
131 | PSPR = virt_to_phys(pxa_cpu_resume); | ||
132 | pxa_cpu_suspend(3); | ||
133 | break; | ||
134 | } | ||
135 | } | ||
136 | |||
137 | #endif | ||
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 7e863afefb53..893964fb9659 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c | |||
@@ -120,6 +120,42 @@ EXPORT_SYMBOL(get_clk_frequency_khz); | |||
120 | EXPORT_SYMBOL(get_memclk_frequency_10khz); | 120 | EXPORT_SYMBOL(get_memclk_frequency_10khz); |
121 | EXPORT_SYMBOL(get_lcdclk_frequency_10khz); | 121 | EXPORT_SYMBOL(get_lcdclk_frequency_10khz); |
122 | 122 | ||
123 | #ifdef CONFIG_PM | ||
124 | |||
125 | int pxa_cpu_pm_prepare(suspend_state_t state) | ||
126 | { | ||
127 | switch (state) { | ||
128 | case PM_SUSPEND_MEM: | ||
129 | return 0; | ||
130 | default: | ||
131 | return -EINVAL; | ||
132 | } | ||
133 | } | ||
134 | |||
135 | void pxa_cpu_pm_enter(suspend_state_t state) | ||
136 | { | ||
137 | extern void pxa_cpu_standby(void); | ||
138 | extern void pxa_cpu_suspend(unsigned int); | ||
139 | extern void pxa_cpu_resume(void); | ||
140 | |||
141 | CKEN = CKEN22_MEMC | CKEN9_OSTIMER; | ||
142 | |||
143 | /* ensure voltage-change sequencer not initiated, which hangs */ | ||
144 | PCFR &= ~PCFR_FVC; | ||
145 | |||
146 | /* Clear edge-detect status register. */ | ||
147 | PEDR = 0xDF12FE1B; | ||
148 | |||
149 | switch (state) { | ||
150 | case PM_SUSPEND_MEM: | ||
151 | /* set resume return address */ | ||
152 | PSPR = virt_to_phys(pxa_cpu_resume); | ||
153 | pxa_cpu_suspend(3); | ||
154 | break; | ||
155 | } | ||
156 | } | ||
157 | |||
158 | #endif | ||
123 | 159 | ||
124 | /* | 160 | /* |
125 | * device registration specific to PXA27x. | 161 | * device registration specific to PXA27x. |
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c index e23f534d4e1d..8d986b8401c2 100644 --- a/arch/arm/mach-s3c2410/clock.c +++ b/arch/arm/mach-s3c2410/clock.c | |||
@@ -478,7 +478,7 @@ static int s3c2440_clk_add(struct sys_device *sysdev) | |||
478 | { | 478 | { |
479 | unsigned long upllcon = __raw_readl(S3C2410_UPLLCON); | 479 | unsigned long upllcon = __raw_readl(S3C2410_UPLLCON); |
480 | 480 | ||
481 | s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal.rate) * 2; | 481 | s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal.rate); |
482 | 482 | ||
483 | printk("S3C2440: Clock Support, UPLL %ld.%03ld MHz\n", | 483 | printk("S3C2440: Clock Support, UPLL %ld.%03ld MHz\n", |
484 | print_mhz(s3c2440_clk_upll.rate)); | 484 | print_mhz(s3c2440_clk_upll.rate)); |
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c index bc229fab86d4..c7c28890d406 100644 --- a/arch/arm/mach-s3c2410/dma.c +++ b/arch/arm/mach-s3c2410/dma.c | |||
@@ -785,6 +785,10 @@ int s3c2410_dma_free(dmach_t channel, s3c2410_dma_client_t *client) | |||
785 | chan->client = NULL; | 785 | chan->client = NULL; |
786 | chan->in_use = 0; | 786 | chan->in_use = 0; |
787 | 787 | ||
788 | if (chan->irq_claimed) | ||
789 | free_irq(chan->irq, (void *)chan); | ||
790 | chan->irq_claimed = 0; | ||
791 | |||
788 | local_irq_restore(flags); | 792 | local_irq_restore(flags); |
789 | 793 | ||
790 | return 0; | 794 | return 0; |
diff --git a/arch/arm/mach-s3c2410/s3c2440.c b/arch/arm/mach-s3c2410/s3c2440.c index 9a8cc5ae2255..d4c8281b55f6 100644 --- a/arch/arm/mach-s3c2410/s3c2440.c +++ b/arch/arm/mach-s3c2410/s3c2440.c | |||
@@ -192,9 +192,11 @@ void __init s3c2440_map_io(struct map_desc *mach_desc, int size) | |||
192 | 192 | ||
193 | iotable_init(s3c2440_iodesc, ARRAY_SIZE(s3c2440_iodesc)); | 193 | iotable_init(s3c2440_iodesc, ARRAY_SIZE(s3c2440_iodesc)); |
194 | iotable_init(mach_desc, size); | 194 | iotable_init(mach_desc, size); |
195 | |||
195 | /* rename any peripherals used differing from the s3c2410 */ | 196 | /* rename any peripherals used differing from the s3c2410 */ |
196 | 197 | ||
197 | s3c_device_i2c.name = "s3c2440-i2c"; | 198 | s3c_device_i2c.name = "s3c2440-i2c"; |
199 | s3c_device_nand.name = "s3c2440-nand"; | ||
198 | 200 | ||
199 | /* change irq for watchdog */ | 201 | /* change irq for watchdog */ |
200 | 202 | ||
@@ -225,7 +227,7 @@ void __init s3c2440_init_clocks(int xtal) | |||
225 | break; | 227 | break; |
226 | 228 | ||
227 | case S3C2440_CLKDIVN_HDIVN_2: | 229 | case S3C2440_CLKDIVN_HDIVN_2: |
228 | hdiv = 1; | 230 | hdiv = 2; |
229 | break; | 231 | break; |
230 | 232 | ||
231 | case S3C2440_CLKDIVN_HDIVN_4_8: | 233 | case S3C2440_CLKDIVN_HDIVN_4_8: |
diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig index 50cde576dadf..6923316b3d0d 100644 --- a/arch/arm/mach-sa1100/Kconfig +++ b/arch/arm/mach-sa1100/Kconfig | |||
@@ -150,7 +150,7 @@ config SA1100_SSP | |||
150 | 150 | ||
151 | config H3600_SLEEVE | 151 | config H3600_SLEEVE |
152 | tristate "Compaq iPAQ Handheld sleeve support" | 152 | tristate "Compaq iPAQ Handheld sleeve support" |
153 | depends on SA1100_H3600 | 153 | depends on SA1100_H3100 || SA1100_H3600 |
154 | help | 154 | help |
155 | Choose this option to enable support for extension packs (sleeves) | 155 | Choose this option to enable support for extension packs (sleeves) |
156 | for the Compaq iPAQ H3XXX series of handheld computers. This option | 156 | for the Compaq iPAQ H3XXX series of handheld computers. This option |
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 27892e34b060..3fefb43c67f7 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
@@ -228,7 +228,6 @@ config CPU_SA1100 | |||
228 | select CPU_CACHE_V4WB | 228 | select CPU_CACHE_V4WB |
229 | select CPU_CACHE_VIVT | 229 | select CPU_CACHE_VIVT |
230 | select CPU_TLB_V4WB | 230 | select CPU_TLB_V4WB |
231 | select CPU_MINICACHE | ||
232 | 231 | ||
233 | # XScale | 232 | # XScale |
234 | config CPU_XSCALE | 233 | config CPU_XSCALE |
@@ -239,7 +238,6 @@ config CPU_XSCALE | |||
239 | select CPU_ABRT_EV5T | 238 | select CPU_ABRT_EV5T |
240 | select CPU_CACHE_VIVT | 239 | select CPU_CACHE_VIVT |
241 | select CPU_TLB_V4WBI | 240 | select CPU_TLB_V4WBI |
242 | select CPU_MINICACHE | ||
243 | 241 | ||
244 | # ARMv6 | 242 | # ARMv6 |
245 | config CPU_V6 | 243 | config CPU_V6 |
@@ -345,11 +343,6 @@ config CPU_TLB_V4WBI | |||
345 | config CPU_TLB_V6 | 343 | config CPU_TLB_V6 |
346 | bool | 344 | bool |
347 | 345 | ||
348 | config CPU_MINICACHE | ||
349 | bool | ||
350 | help | ||
351 | Processor has a minicache. | ||
352 | |||
353 | comment "Processor Features" | 346 | comment "Processor Features" |
354 | 347 | ||
355 | config ARM_THUMB | 348 | config ARM_THUMB |
@@ -410,17 +403,30 @@ config CPU_BPREDICT_DISABLE | |||
410 | help | 403 | help |
411 | Say Y here to disable branch prediction. If unsure, say N. | 404 | Say Y here to disable branch prediction. If unsure, say N. |
412 | 405 | ||
406 | config TLS_REG_EMUL | ||
407 | bool | ||
408 | default y if SMP && (CPU_32v5 || CPU_32v4 || CPU_32v3) | ||
409 | help | ||
410 | An SMP system using a pre-ARMv6 processor (there are apparently | ||
411 | a few prototypes like that in existence) and therefore access to | ||
412 | that required register must be emulated. | ||
413 | |||
413 | config HAS_TLS_REG | 414 | config HAS_TLS_REG |
414 | bool | 415 | bool |
415 | depends on CPU_32v6 && !CPU_32v5 && !CPU_32v4 && !CPU_32v3 | 416 | depends on !TLS_REG_EMUL |
416 | default y | 417 | default y if SMP || CPU_32v7 |
417 | help | 418 | help |
418 | This selects support for the CP15 thread register. | 419 | This selects support for the CP15 thread register. |
419 | It is defined to be available on ARMv6 or later. However | 420 | It is defined to be available on some ARMv6 processors (including |
420 | if the kernel is configured to support multiple CPUs including | 421 | all SMP capable ARMv6's) or later processors. User space may |
421 | a pre-ARMv6 processors, or if a given ARMv6 processor doesn't | 422 | assume directly accessing that register and always obtain the |
422 | implement the thread register for some reason, then access to | 423 | expected value only on ARMv7 and above. |
423 | this register from user space must be trapped and emulated. | 424 | |
424 | If user space is relying on the __kuser_get_tls code then | 425 | config NEEDS_SYSCALL_FOR_CMPXCHG |
425 | there should not be any impact. | 426 | bool |
427 | default y if SMP && (CPU_32v5 || CPU_32v4 || CPU_32v3) | ||
428 | help | ||
429 | SMP on a pre-ARMv6 processor? Well OK then. | ||
430 | Forget about fast user space cmpxchg support. | ||
431 | It is just not possible. | ||
426 | 432 | ||
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index ccf316c11e02..59f47d4c2dfe 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile | |||
@@ -31,8 +31,6 @@ obj-$(CONFIG_CPU_COPY_V6) += copypage-v6.o mmu.o | |||
31 | obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o | 31 | obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o |
32 | obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o | 32 | obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o |
33 | 33 | ||
34 | obj-$(CONFIG_CPU_MINICACHE) += minicache.o | ||
35 | |||
36 | obj-$(CONFIG_CPU_TLB_V3) += tlb-v3.o | 34 | obj-$(CONFIG_CPU_TLB_V3) += tlb-v3.o |
37 | obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o | 35 | obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o |
38 | obj-$(CONFIG_CPU_TLB_V4WB) += tlb-v4wb.o | 36 | obj-$(CONFIG_CPU_TLB_V4WB) += tlb-v4wb.o |
diff --git a/arch/arm/mm/copypage-v4mc.S b/arch/arm/mm/copypage-v4mc.S deleted file mode 100644 index 305af3dab3d8..000000000000 --- a/arch/arm/mm/copypage-v4mc.S +++ /dev/null | |||
@@ -1,80 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/lib/copy_page-armv4mc.S | ||
3 | * | ||
4 | * Copyright (C) 1995-2001 Russell King | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * ASM optimised string functions | ||
11 | */ | ||
12 | #include <linux/linkage.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <asm/constants.h> | ||
15 | |||
16 | .text | ||
17 | .align 5 | ||
18 | /* | ||
19 | * ARMv4 mini-dcache optimised copy_user_page | ||
20 | * | ||
21 | * We flush the destination cache lines just before we write the data into the | ||
22 | * corresponding address. Since the Dcache is read-allocate, this removes the | ||
23 | * Dcache aliasing issue. The writes will be forwarded to the write buffer, | ||
24 | * and merged as appropriate. | ||
25 | * | ||
26 | * Note: We rely on all ARMv4 processors implementing the "invalidate D line" | ||
27 | * instruction. If your processor does not supply this, you have to write your | ||
28 | * own copy_user_page that does the right thing. | ||
29 | */ | ||
30 | ENTRY(v4_mc_copy_user_page) | ||
31 | stmfd sp!, {r4, lr} @ 2 | ||
32 | mov r4, r0 | ||
33 | mov r0, r1 | ||
34 | bl map_page_minicache | ||
35 | mov r1, #PAGE_SZ/64 @ 1 | ||
36 | ldmia r0!, {r2, r3, ip, lr} @ 4 | ||
37 | 1: mcr p15, 0, r4, c7, c6, 1 @ 1 invalidate D line | ||
38 | stmia r4!, {r2, r3, ip, lr} @ 4 | ||
39 | ldmia r0!, {r2, r3, ip, lr} @ 4+1 | ||
40 | stmia r4!, {r2, r3, ip, lr} @ 4 | ||
41 | ldmia r0!, {r2, r3, ip, lr} @ 4 | ||
42 | mcr p15, 0, r4, c7, c6, 1 @ 1 invalidate D line | ||
43 | stmia r4!, {r2, r3, ip, lr} @ 4 | ||
44 | ldmia r0!, {r2, r3, ip, lr} @ 4 | ||
45 | subs r1, r1, #1 @ 1 | ||
46 | stmia r4!, {r2, r3, ip, lr} @ 4 | ||
47 | ldmneia r0!, {r2, r3, ip, lr} @ 4 | ||
48 | bne 1b @ 1 | ||
49 | ldmfd sp!, {r4, pc} @ 3 | ||
50 | |||
51 | .align 5 | ||
52 | /* | ||
53 | * ARMv4 optimised clear_user_page | ||
54 | * | ||
55 | * Same story as above. | ||
56 | */ | ||
57 | ENTRY(v4_mc_clear_user_page) | ||
58 | str lr, [sp, #-4]! | ||
59 | mov r1, #PAGE_SZ/64 @ 1 | ||
60 | mov r2, #0 @ 1 | ||
61 | mov r3, #0 @ 1 | ||
62 | mov ip, #0 @ 1 | ||
63 | mov lr, #0 @ 1 | ||
64 | 1: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line | ||
65 | stmia r0!, {r2, r3, ip, lr} @ 4 | ||
66 | stmia r0!, {r2, r3, ip, lr} @ 4 | ||
67 | mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line | ||
68 | stmia r0!, {r2, r3, ip, lr} @ 4 | ||
69 | stmia r0!, {r2, r3, ip, lr} @ 4 | ||
70 | subs r1, r1, #1 @ 1 | ||
71 | bne 1b @ 1 | ||
72 | ldr pc, [sp], #4 | ||
73 | |||
74 | __INITDATA | ||
75 | |||
76 | .type v4_mc_user_fns, #object | ||
77 | ENTRY(v4_mc_user_fns) | ||
78 | .long v4_mc_clear_user_page | ||
79 | .long v4_mc_copy_user_page | ||
80 | .size v4_mc_user_fns, . - v4_mc_user_fns | ||
diff --git a/arch/arm/mm/copypage-v4mc.c b/arch/arm/mm/copypage-v4mc.c new file mode 100644 index 000000000000..fc69dccdace1 --- /dev/null +++ b/arch/arm/mm/copypage-v4mc.c | |||
@@ -0,0 +1,111 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/lib/copypage-armv4mc.S | ||
3 | * | ||
4 | * Copyright (C) 1995-2005 Russell King | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This handles the mini data cache, as found on SA11x0 and XScale | ||
11 | * processors. When we copy a user page page, we map it in such a way | ||
12 | * that accesses to this page will not touch the main data cache, but | ||
13 | * will be cached in the mini data cache. This prevents us thrashing | ||
14 | * the main data cache on page faults. | ||
15 | */ | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/mm.h> | ||
18 | |||
19 | #include <asm/page.h> | ||
20 | #include <asm/pgtable.h> | ||
21 | #include <asm/tlbflush.h> | ||
22 | |||
23 | /* | ||
24 | * 0xffff8000 to 0xffffffff is reserved for any ARM architecture | ||
25 | * specific hacks for copying pages efficiently. | ||
26 | */ | ||
27 | #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ | ||
28 | L_PTE_CACHEABLE) | ||
29 | |||
30 | #define TOP_PTE(x) pte_offset_kernel(top_pmd, x) | ||
31 | |||
32 | static DEFINE_SPINLOCK(minicache_lock); | ||
33 | |||
34 | /* | ||
35 | * ARMv4 mini-dcache optimised copy_user_page | ||
36 | * | ||
37 | * We flush the destination cache lines just before we write the data into the | ||
38 | * corresponding address. Since the Dcache is read-allocate, this removes the | ||
39 | * Dcache aliasing issue. The writes will be forwarded to the write buffer, | ||
40 | * and merged as appropriate. | ||
41 | * | ||
42 | * Note: We rely on all ARMv4 processors implementing the "invalidate D line" | ||
43 | * instruction. If your processor does not supply this, you have to write your | ||
44 | * own copy_user_page that does the right thing. | ||
45 | */ | ||
46 | static void __attribute__((naked)) | ||
47 | mc_copy_user_page(void *from, void *to) | ||
48 | { | ||
49 | asm volatile( | ||
50 | "stmfd sp!, {r4, lr} @ 2\n\ | ||
51 | mov r4, %2 @ 1\n\ | ||
52 | ldmia %0!, {r2, r3, ip, lr} @ 4\n\ | ||
53 | 1: mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\ | ||
54 | stmia %1!, {r2, r3, ip, lr} @ 4\n\ | ||
55 | ldmia %0!, {r2, r3, ip, lr} @ 4+1\n\ | ||
56 | stmia %1!, {r2, r3, ip, lr} @ 4\n\ | ||
57 | ldmia %0!, {r2, r3, ip, lr} @ 4\n\ | ||
58 | mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\ | ||
59 | stmia %1!, {r2, r3, ip, lr} @ 4\n\ | ||
60 | ldmia %0!, {r2, r3, ip, lr} @ 4\n\ | ||
61 | subs r4, r4, #1 @ 1\n\ | ||
62 | stmia %1!, {r2, r3, ip, lr} @ 4\n\ | ||
63 | ldmneia %0!, {r2, r3, ip, lr} @ 4\n\ | ||
64 | bne 1b @ 1\n\ | ||
65 | ldmfd sp!, {r4, pc} @ 3" | ||
66 | : | ||
67 | : "r" (from), "r" (to), "I" (PAGE_SIZE / 64)); | ||
68 | } | ||
69 | |||
70 | void v4_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr) | ||
71 | { | ||
72 | spin_lock(&minicache_lock); | ||
73 | |||
74 | set_pte(TOP_PTE(0xffff8000), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot)); | ||
75 | flush_tlb_kernel_page(0xffff8000); | ||
76 | |||
77 | mc_copy_user_page((void *)0xffff8000, kto); | ||
78 | |||
79 | spin_unlock(&minicache_lock); | ||
80 | } | ||
81 | |||
82 | /* | ||
83 | * ARMv4 optimised clear_user_page | ||
84 | */ | ||
85 | void __attribute__((naked)) | ||
86 | v4_mc_clear_user_page(void *kaddr, unsigned long vaddr) | ||
87 | { | ||
88 | asm volatile( | ||
89 | "str lr, [sp, #-4]!\n\ | ||
90 | mov r1, %0 @ 1\n\ | ||
91 | mov r2, #0 @ 1\n\ | ||
92 | mov r3, #0 @ 1\n\ | ||
93 | mov ip, #0 @ 1\n\ | ||
94 | mov lr, #0 @ 1\n\ | ||
95 | 1: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\ | ||
96 | stmia r0!, {r2, r3, ip, lr} @ 4\n\ | ||
97 | stmia r0!, {r2, r3, ip, lr} @ 4\n\ | ||
98 | mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\ | ||
99 | stmia r0!, {r2, r3, ip, lr} @ 4\n\ | ||
100 | stmia r0!, {r2, r3, ip, lr} @ 4\n\ | ||
101 | subs r1, r1, #1 @ 1\n\ | ||
102 | bne 1b @ 1\n\ | ||
103 | ldr pc, [sp], #4" | ||
104 | : | ||
105 | : "I" (PAGE_SIZE / 64)); | ||
106 | } | ||
107 | |||
108 | struct cpu_user_fns v4_mc_user_fns __initdata = { | ||
109 | .cpu_clear_user_page = v4_mc_clear_user_page, | ||
110 | .cpu_copy_user_page = v4_mc_copy_user_page, | ||
111 | }; | ||
diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c index 694ac8208858..a8c00236bd3d 100644 --- a/arch/arm/mm/copypage-v6.c +++ b/arch/arm/mm/copypage-v6.c | |||
@@ -26,8 +26,8 @@ | |||
26 | #define to_address (0xffffc000) | 26 | #define to_address (0xffffc000) |
27 | #define to_pgprot PAGE_KERNEL | 27 | #define to_pgprot PAGE_KERNEL |
28 | 28 | ||
29 | static pte_t *from_pte; | 29 | #define TOP_PTE(x) pte_offset_kernel(top_pmd, x) |
30 | static pte_t *to_pte; | 30 | |
31 | static DEFINE_SPINLOCK(v6_lock); | 31 | static DEFINE_SPINLOCK(v6_lock); |
32 | 32 | ||
33 | #define DCACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT) | 33 | #define DCACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT) |
@@ -74,8 +74,8 @@ void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vadd | |||
74 | */ | 74 | */ |
75 | spin_lock(&v6_lock); | 75 | spin_lock(&v6_lock); |
76 | 76 | ||
77 | set_pte(from_pte + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, from_pgprot)); | 77 | set_pte(TOP_PTE(from_address) + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, from_pgprot)); |
78 | set_pte(to_pte + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, to_pgprot)); | 78 | set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, to_pgprot)); |
79 | 79 | ||
80 | from = from_address + (offset << PAGE_SHIFT); | 80 | from = from_address + (offset << PAGE_SHIFT); |
81 | to = to_address + (offset << PAGE_SHIFT); | 81 | to = to_address + (offset << PAGE_SHIFT); |
@@ -114,7 +114,7 @@ void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr) | |||
114 | */ | 114 | */ |
115 | spin_lock(&v6_lock); | 115 | spin_lock(&v6_lock); |
116 | 116 | ||
117 | set_pte(to_pte + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, to_pgprot)); | 117 | set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, to_pgprot)); |
118 | flush_tlb_kernel_page(to); | 118 | flush_tlb_kernel_page(to); |
119 | clear_page((void *)to); | 119 | clear_page((void *)to); |
120 | 120 | ||
@@ -129,21 +129,6 @@ struct cpu_user_fns v6_user_fns __initdata = { | |||
129 | static int __init v6_userpage_init(void) | 129 | static int __init v6_userpage_init(void) |
130 | { | 130 | { |
131 | if (cache_is_vipt_aliasing()) { | 131 | if (cache_is_vipt_aliasing()) { |
132 | pgd_t *pgd; | ||
133 | pmd_t *pmd; | ||
134 | |||
135 | pgd = pgd_offset_k(from_address); | ||
136 | pmd = pmd_alloc(&init_mm, pgd, from_address); | ||
137 | if (!pmd) | ||
138 | BUG(); | ||
139 | from_pte = pte_alloc_kernel(&init_mm, pmd, from_address); | ||
140 | if (!from_pte) | ||
141 | BUG(); | ||
142 | |||
143 | to_pte = pte_alloc_kernel(&init_mm, pmd, to_address); | ||
144 | if (!to_pte) | ||
145 | BUG(); | ||
146 | |||
147 | cpu_user.cpu_clear_user_page = v6_clear_user_page_aliasing; | 132 | cpu_user.cpu_clear_user_page = v6_clear_user_page_aliasing; |
148 | cpu_user.cpu_copy_user_page = v6_copy_user_page_aliasing; | 133 | cpu_user.cpu_copy_user_page = v6_copy_user_page_aliasing; |
149 | } | 134 | } |
@@ -151,5 +136,4 @@ static int __init v6_userpage_init(void) | |||
151 | return 0; | 136 | return 0; |
152 | } | 137 | } |
153 | 138 | ||
154 | __initcall(v6_userpage_init); | 139 | core_initcall(v6_userpage_init); |
155 | |||
diff --git a/arch/arm/mm/copypage-xscale.S b/arch/arm/mm/copypage-xscale.S deleted file mode 100644 index bb277316ef52..000000000000 --- a/arch/arm/mm/copypage-xscale.S +++ /dev/null | |||
@@ -1,113 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/lib/copypage-xscale.S | ||
3 | * | ||
4 | * Copyright (C) 2001 Russell King | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #include <linux/linkage.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <asm/constants.h> | ||
13 | |||
14 | /* | ||
15 | * General note: | ||
16 | * We don't really want write-allocate cache behaviour for these functions | ||
17 | * since that will just eat through 8K of the cache. | ||
18 | */ | ||
19 | |||
20 | .text | ||
21 | .align 5 | ||
22 | /* | ||
23 | * XScale optimised copy_user_page | ||
24 | * r0 = destination | ||
25 | * r1 = source | ||
26 | * r2 = virtual user address of ultimate destination page | ||
27 | * | ||
28 | * The source page may have some clean entries in the cache already, but we | ||
29 | * can safely ignore them - break_cow() will flush them out of the cache | ||
30 | * if we eventually end up using our copied page. | ||
31 | * | ||
32 | * What we could do is use the mini-cache to buffer reads from the source | ||
33 | * page. We rely on the mini-cache being smaller than one page, so we'll | ||
34 | * cycle through the complete cache anyway. | ||
35 | */ | ||
36 | ENTRY(xscale_mc_copy_user_page) | ||
37 | stmfd sp!, {r4, r5, lr} | ||
38 | mov r5, r0 | ||
39 | mov r0, r1 | ||
40 | bl map_page_minicache | ||
41 | mov r1, r5 | ||
42 | mov lr, #PAGE_SZ/64-1 | ||
43 | |||
44 | /* | ||
45 | * Strangely enough, best performance is achieved | ||
46 | * when prefetching destination as well. (NP) | ||
47 | */ | ||
48 | pld [r0, #0] | ||
49 | pld [r0, #32] | ||
50 | pld [r1, #0] | ||
51 | pld [r1, #32] | ||
52 | |||
53 | 1: pld [r0, #64] | ||
54 | pld [r0, #96] | ||
55 | pld [r1, #64] | ||
56 | pld [r1, #96] | ||
57 | |||
58 | 2: ldrd r2, [r0], #8 | ||
59 | ldrd r4, [r0], #8 | ||
60 | mov ip, r1 | ||
61 | strd r2, [r1], #8 | ||
62 | ldrd r2, [r0], #8 | ||
63 | strd r4, [r1], #8 | ||
64 | ldrd r4, [r0], #8 | ||
65 | strd r2, [r1], #8 | ||
66 | strd r4, [r1], #8 | ||
67 | mcr p15, 0, ip, c7, c10, 1 @ clean D line | ||
68 | ldrd r2, [r0], #8 | ||
69 | mcr p15, 0, ip, c7, c6, 1 @ invalidate D line | ||
70 | ldrd r4, [r0], #8 | ||
71 | mov ip, r1 | ||
72 | strd r2, [r1], #8 | ||
73 | ldrd r2, [r0], #8 | ||
74 | strd r4, [r1], #8 | ||
75 | ldrd r4, [r0], #8 | ||
76 | strd r2, [r1], #8 | ||
77 | strd r4, [r1], #8 | ||
78 | mcr p15, 0, ip, c7, c10, 1 @ clean D line | ||
79 | subs lr, lr, #1 | ||
80 | mcr p15, 0, ip, c7, c6, 1 @ invalidate D line | ||
81 | bgt 1b | ||
82 | beq 2b | ||
83 | |||
84 | ldmfd sp!, {r4, r5, pc} | ||
85 | |||
86 | .align 5 | ||
87 | /* | ||
88 | * XScale optimised clear_user_page | ||
89 | * r0 = destination | ||
90 | * r1 = virtual user address of ultimate destination page | ||
91 | */ | ||
92 | ENTRY(xscale_mc_clear_user_page) | ||
93 | mov r1, #PAGE_SZ/32 | ||
94 | mov r2, #0 | ||
95 | mov r3, #0 | ||
96 | 1: mov ip, r0 | ||
97 | strd r2, [r0], #8 | ||
98 | strd r2, [r0], #8 | ||
99 | strd r2, [r0], #8 | ||
100 | strd r2, [r0], #8 | ||
101 | mcr p15, 0, ip, c7, c10, 1 @ clean D line | ||
102 | subs r1, r1, #1 | ||
103 | mcr p15, 0, ip, c7, c6, 1 @ invalidate D line | ||
104 | bne 1b | ||
105 | mov pc, lr | ||
106 | |||
107 | __INITDATA | ||
108 | |||
109 | .type xscale_mc_user_fns, #object | ||
110 | ENTRY(xscale_mc_user_fns) | ||
111 | .long xscale_mc_clear_user_page | ||
112 | .long xscale_mc_copy_user_page | ||
113 | .size xscale_mc_user_fns, . - xscale_mc_user_fns | ||
diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c new file mode 100644 index 000000000000..42a6ee255ce0 --- /dev/null +++ b/arch/arm/mm/copypage-xscale.c | |||
@@ -0,0 +1,131 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/lib/copypage-xscale.S | ||
3 | * | ||
4 | * Copyright (C) 1995-2005 Russell King | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This handles the mini data cache, as found on SA11x0 and XScale | ||
11 | * processors. When we copy a user page page, we map it in such a way | ||
12 | * that accesses to this page will not touch the main data cache, but | ||
13 | * will be cached in the mini data cache. This prevents us thrashing | ||
14 | * the main data cache on page faults. | ||
15 | */ | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/mm.h> | ||
18 | |||
19 | #include <asm/page.h> | ||
20 | #include <asm/pgtable.h> | ||
21 | #include <asm/tlbflush.h> | ||
22 | |||
23 | /* | ||
24 | * 0xffff8000 to 0xffffffff is reserved for any ARM architecture | ||
25 | * specific hacks for copying pages efficiently. | ||
26 | */ | ||
27 | #define COPYPAGE_MINICACHE 0xffff8000 | ||
28 | |||
29 | #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ | ||
30 | L_PTE_CACHEABLE) | ||
31 | |||
32 | #define TOP_PTE(x) pte_offset_kernel(top_pmd, x) | ||
33 | |||
34 | static DEFINE_SPINLOCK(minicache_lock); | ||
35 | |||
36 | /* | ||
37 | * XScale mini-dcache optimised copy_user_page | ||
38 | * | ||
39 | * We flush the destination cache lines just before we write the data into the | ||
40 | * corresponding address. Since the Dcache is read-allocate, this removes the | ||
41 | * Dcache aliasing issue. The writes will be forwarded to the write buffer, | ||
42 | * and merged as appropriate. | ||
43 | */ | ||
44 | static void __attribute__((naked)) | ||
45 | mc_copy_user_page(void *from, void *to) | ||
46 | { | ||
47 | /* | ||
48 | * Strangely enough, best performance is achieved | ||
49 | * when prefetching destination as well. (NP) | ||
50 | */ | ||
51 | asm volatile( | ||
52 | "stmfd sp!, {r4, r5, lr} \n\ | ||
53 | mov lr, %2 \n\ | ||
54 | pld [r0, #0] \n\ | ||
55 | pld [r0, #32] \n\ | ||
56 | pld [r1, #0] \n\ | ||
57 | pld [r1, #32] \n\ | ||
58 | 1: pld [r0, #64] \n\ | ||
59 | pld [r0, #96] \n\ | ||
60 | pld [r1, #64] \n\ | ||
61 | pld [r1, #96] \n\ | ||
62 | 2: ldrd r2, [r0], #8 \n\ | ||
63 | ldrd r4, [r0], #8 \n\ | ||
64 | mov ip, r1 \n\ | ||
65 | strd r2, [r1], #8 \n\ | ||
66 | ldrd r2, [r0], #8 \n\ | ||
67 | strd r4, [r1], #8 \n\ | ||
68 | ldrd r4, [r0], #8 \n\ | ||
69 | strd r2, [r1], #8 \n\ | ||
70 | strd r4, [r1], #8 \n\ | ||
71 | mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\ | ||
72 | ldrd r2, [r0], #8 \n\ | ||
73 | mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\ | ||
74 | ldrd r4, [r0], #8 \n\ | ||
75 | mov ip, r1 \n\ | ||
76 | strd r2, [r1], #8 \n\ | ||
77 | ldrd r2, [r0], #8 \n\ | ||
78 | strd r4, [r1], #8 \n\ | ||
79 | ldrd r4, [r0], #8 \n\ | ||
80 | strd r2, [r1], #8 \n\ | ||
81 | strd r4, [r1], #8 \n\ | ||
82 | mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\ | ||
83 | subs lr, lr, #1 \n\ | ||
84 | mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\ | ||
85 | bgt 1b \n\ | ||
86 | beq 2b \n\ | ||
87 | ldmfd sp!, {r4, r5, pc} " | ||
88 | : | ||
89 | : "r" (from), "r" (to), "I" (PAGE_SIZE / 64 - 1)); | ||
90 | } | ||
91 | |||
92 | void xscale_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr) | ||
93 | { | ||
94 | spin_lock(&minicache_lock); | ||
95 | |||
96 | set_pte(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot)); | ||
97 | flush_tlb_kernel_page(COPYPAGE_MINICACHE); | ||
98 | |||
99 | mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto); | ||
100 | |||
101 | spin_unlock(&minicache_lock); | ||
102 | } | ||
103 | |||
104 | /* | ||
105 | * XScale optimised clear_user_page | ||
106 | */ | ||
107 | void __attribute__((naked)) | ||
108 | xscale_mc_clear_user_page(void *kaddr, unsigned long vaddr) | ||
109 | { | ||
110 | asm volatile( | ||
111 | "mov r1, %0 \n\ | ||
112 | mov r2, #0 \n\ | ||
113 | mov r3, #0 \n\ | ||
114 | 1: mov ip, r0 \n\ | ||
115 | strd r2, [r0], #8 \n\ | ||
116 | strd r2, [r0], #8 \n\ | ||
117 | strd r2, [r0], #8 \n\ | ||
118 | strd r2, [r0], #8 \n\ | ||
119 | mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\ | ||
120 | subs r1, r1, #1 \n\ | ||
121 | mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\ | ||
122 | bne 1b \n\ | ||
123 | mov pc, lr" | ||
124 | : | ||
125 | : "I" (PAGE_SIZE / 32)); | ||
126 | } | ||
127 | |||
128 | struct cpu_user_fns xscale_mc_user_fns __initdata = { | ||
129 | .cpu_clear_user_page = xscale_mc_clear_user_page, | ||
130 | .cpu_copy_user_page = xscale_mc_copy_user_page, | ||
131 | }; | ||
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index c6de48d89503..4085ed983e46 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c | |||
@@ -13,6 +13,29 @@ | |||
13 | 13 | ||
14 | #include <asm/cacheflush.h> | 14 | #include <asm/cacheflush.h> |
15 | #include <asm/system.h> | 15 | #include <asm/system.h> |
16 | #include <asm/tlbflush.h> | ||
17 | |||
18 | #ifdef CONFIG_CPU_CACHE_VIPT | ||
19 | #define ALIAS_FLUSH_START 0xffff4000 | ||
20 | |||
21 | #define TOP_PTE(x) pte_offset_kernel(top_pmd, x) | ||
22 | |||
23 | static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr) | ||
24 | { | ||
25 | unsigned long to = ALIAS_FLUSH_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT); | ||
26 | |||
27 | set_pte(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL)); | ||
28 | flush_tlb_kernel_page(to); | ||
29 | |||
30 | asm( "mcrr p15, 0, %1, %0, c14\n" | ||
31 | " mcrr p15, 0, %1, %0, c5\n" | ||
32 | : | ||
33 | : "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES) | ||
34 | : "cc"); | ||
35 | } | ||
36 | #else | ||
37 | #define flush_pfn_alias(pfn,vaddr) do { } while (0) | ||
38 | #endif | ||
16 | 39 | ||
17 | static void __flush_dcache_page(struct address_space *mapping, struct page *page) | 40 | static void __flush_dcache_page(struct address_space *mapping, struct page *page) |
18 | { | 41 | { |
@@ -37,6 +60,18 @@ static void __flush_dcache_page(struct address_space *mapping, struct page *page | |||
37 | return; | 60 | return; |
38 | 61 | ||
39 | /* | 62 | /* |
63 | * This is a page cache page. If we have a VIPT cache, we | ||
64 | * only need to do one flush - which would be at the relevant | ||
65 | * userspace colour, which is congruent with page->index. | ||
66 | */ | ||
67 | if (cache_is_vipt()) { | ||
68 | if (cache_is_vipt_aliasing()) | ||
69 | flush_pfn_alias(page_to_pfn(page), | ||
70 | page->index << PAGE_CACHE_SHIFT); | ||
71 | return; | ||
72 | } | ||
73 | |||
74 | /* | ||
40 | * There are possible user space mappings of this page: | 75 | * There are possible user space mappings of this page: |
41 | * - VIVT cache: we need to also write back and invalidate all user | 76 | * - VIVT cache: we need to also write back and invalidate all user |
42 | * data in the current VM view associated with this page. | 77 | * data in the current VM view associated with this page. |
@@ -57,8 +92,6 @@ static void __flush_dcache_page(struct address_space *mapping, struct page *page | |||
57 | continue; | 92 | continue; |
58 | offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT; | 93 | offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT; |
59 | flush_cache_page(mpnt, mpnt->vm_start + offset, page_to_pfn(page)); | 94 | flush_cache_page(mpnt, mpnt->vm_start + offset, page_to_pfn(page)); |
60 | if (cache_is_vipt()) | ||
61 | break; | ||
62 | } | 95 | } |
63 | flush_dcache_mmap_unlock(mapping); | 96 | flush_dcache_mmap_unlock(mapping); |
64 | } | 97 | } |
diff --git a/arch/arm/mm/minicache.c b/arch/arm/mm/minicache.c deleted file mode 100644 index dedf2ab01b2a..000000000000 --- a/arch/arm/mm/minicache.c +++ /dev/null | |||
@@ -1,73 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mm/minicache.c | ||
3 | * | ||
4 | * Copyright (C) 2001 Russell King | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This handles the mini data cache, as found on SA11x0 and XScale | ||
11 | * processors. When we copy a user page page, we map it in such a way | ||
12 | * that accesses to this page will not touch the main data cache, but | ||
13 | * will be cached in the mini data cache. This prevents us thrashing | ||
14 | * the main data cache on page faults. | ||
15 | */ | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/mm.h> | ||
18 | |||
19 | #include <asm/page.h> | ||
20 | #include <asm/pgtable.h> | ||
21 | #include <asm/tlbflush.h> | ||
22 | |||
23 | /* | ||
24 | * 0xffff8000 to 0xffffffff is reserved for any ARM architecture | ||
25 | * specific hacks for copying pages efficiently. | ||
26 | */ | ||
27 | #define minicache_address (0xffff8000) | ||
28 | #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ | ||
29 | L_PTE_CACHEABLE) | ||
30 | |||
31 | static pte_t *minicache_pte; | ||
32 | |||
33 | /* | ||
34 | * Note that this is intended to be called only from the copy_user_page | ||
35 | * asm code; anything else will require special locking to prevent the | ||
36 | * mini-cache space being re-used. (Note: probably preempt unsafe). | ||
37 | * | ||
38 | * We rely on the fact that the minicache is 2K, and we'll be pushing | ||
39 | * 4K of data through it, so we don't actually have to specifically | ||
40 | * flush the minicache when we change the mapping. | ||
41 | * | ||
42 | * Note also: assert(PAGE_OFFSET <= virt < high_memory). | ||
43 | * Unsafe: preempt, kmap. | ||
44 | */ | ||
45 | unsigned long map_page_minicache(unsigned long virt) | ||
46 | { | ||
47 | set_pte(minicache_pte, pfn_pte(__pa(virt) >> PAGE_SHIFT, minicache_pgprot)); | ||
48 | flush_tlb_kernel_page(minicache_address); | ||
49 | |||
50 | return minicache_address; | ||
51 | } | ||
52 | |||
53 | static int __init minicache_init(void) | ||
54 | { | ||
55 | pgd_t *pgd; | ||
56 | pmd_t *pmd; | ||
57 | |||
58 | spin_lock(&init_mm.page_table_lock); | ||
59 | |||
60 | pgd = pgd_offset_k(minicache_address); | ||
61 | pmd = pmd_alloc(&init_mm, pgd, minicache_address); | ||
62 | if (!pmd) | ||
63 | BUG(); | ||
64 | minicache_pte = pte_alloc_kernel(&init_mm, pmd, minicache_address); | ||
65 | if (!minicache_pte) | ||
66 | BUG(); | ||
67 | |||
68 | spin_unlock(&init_mm.page_table_lock); | ||
69 | |||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | core_initcall(minicache_init); | ||
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index 585dfb8e20b9..2c2b93d77d43 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c | |||
@@ -37,6 +37,8 @@ pgprot_t pgprot_kernel; | |||
37 | 37 | ||
38 | EXPORT_SYMBOL(pgprot_kernel); | 38 | EXPORT_SYMBOL(pgprot_kernel); |
39 | 39 | ||
40 | pmd_t *top_pmd; | ||
41 | |||
40 | struct cachepolicy { | 42 | struct cachepolicy { |
41 | const char policy[16]; | 43 | const char policy[16]; |
42 | unsigned int cr_mask; | 44 | unsigned int cr_mask; |
@@ -142,6 +144,16 @@ __setup("noalign", noalign_setup); | |||
142 | 144 | ||
143 | #define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD) | 145 | #define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD) |
144 | 146 | ||
147 | static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt) | ||
148 | { | ||
149 | return pmd_offset(pgd, virt); | ||
150 | } | ||
151 | |||
152 | static inline pmd_t *pmd_off_k(unsigned long virt) | ||
153 | { | ||
154 | return pmd_off(pgd_offset_k(virt), virt); | ||
155 | } | ||
156 | |||
145 | /* | 157 | /* |
146 | * need to get a 16k page for level 1 | 158 | * need to get a 16k page for level 1 |
147 | */ | 159 | */ |
@@ -220,7 +232,7 @@ void free_pgd_slow(pgd_t *pgd) | |||
220 | return; | 232 | return; |
221 | 233 | ||
222 | /* pgd is always present and good */ | 234 | /* pgd is always present and good */ |
223 | pmd = (pmd_t *)pgd; | 235 | pmd = pmd_off(pgd, 0); |
224 | if (pmd_none(*pmd)) | 236 | if (pmd_none(*pmd)) |
225 | goto free; | 237 | goto free; |
226 | if (pmd_bad(*pmd)) { | 238 | if (pmd_bad(*pmd)) { |
@@ -246,9 +258,8 @@ free: | |||
246 | static inline void | 258 | static inline void |
247 | alloc_init_section(unsigned long virt, unsigned long phys, int prot) | 259 | alloc_init_section(unsigned long virt, unsigned long phys, int prot) |
248 | { | 260 | { |
249 | pmd_t *pmdp; | 261 | pmd_t *pmdp = pmd_off_k(virt); |
250 | 262 | ||
251 | pmdp = pmd_offset(pgd_offset_k(virt), virt); | ||
252 | if (virt & (1 << 20)) | 263 | if (virt & (1 << 20)) |
253 | pmdp++; | 264 | pmdp++; |
254 | 265 | ||
@@ -283,11 +294,9 @@ alloc_init_supersection(unsigned long virt, unsigned long phys, int prot) | |||
283 | static inline void | 294 | static inline void |
284 | alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot) | 295 | alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot) |
285 | { | 296 | { |
286 | pmd_t *pmdp; | 297 | pmd_t *pmdp = pmd_off_k(virt); |
287 | pte_t *ptep; | 298 | pte_t *ptep; |
288 | 299 | ||
289 | pmdp = pmd_offset(pgd_offset_k(virt), virt); | ||
290 | |||
291 | if (pmd_none(*pmdp)) { | 300 | if (pmd_none(*pmdp)) { |
292 | unsigned long pmdval; | 301 | unsigned long pmdval; |
293 | ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * | 302 | ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * |
@@ -310,7 +319,7 @@ alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pg | |||
310 | */ | 319 | */ |
311 | static inline void clear_mapping(unsigned long virt) | 320 | static inline void clear_mapping(unsigned long virt) |
312 | { | 321 | { |
313 | pmd_clear(pmd_offset(pgd_offset_k(virt), virt)); | 322 | pmd_clear(pmd_off_k(virt)); |
314 | } | 323 | } |
315 | 324 | ||
316 | struct mem_types { | 325 | struct mem_types { |
@@ -578,7 +587,7 @@ void setup_mm_for_reboot(char mode) | |||
578 | PMD_TYPE_SECT; | 587 | PMD_TYPE_SECT; |
579 | if (cpu_arch <= CPU_ARCH_ARMv5) | 588 | if (cpu_arch <= CPU_ARCH_ARMv5) |
580 | pmdval |= PMD_BIT4; | 589 | pmdval |= PMD_BIT4; |
581 | pmd = pmd_offset(pgd + i, i << PGDIR_SHIFT); | 590 | pmd = pmd_off(pgd, i << PGDIR_SHIFT); |
582 | pmd[0] = __pmd(pmdval); | 591 | pmd[0] = __pmd(pmdval); |
583 | pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1))); | 592 | pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1))); |
584 | flush_pmd_entry(pmd); | 593 | flush_pmd_entry(pmd); |
@@ -675,6 +684,8 @@ void __init memtable_init(struct meminfo *mi) | |||
675 | 684 | ||
676 | flush_cache_all(); | 685 | flush_cache_all(); |
677 | flush_tlb_all(); | 686 | flush_tlb_all(); |
687 | |||
688 | top_pmd = pmd_off_k(0xffff0000); | ||
678 | } | 689 | } |
679 | 690 | ||
680 | /* | 691 | /* |
diff --git a/arch/arm26/Kconfig b/arch/arm26/Kconfig index 3955de5af4c0..6caed90661fc 100644 --- a/arch/arm26/Kconfig +++ b/arch/arm26/Kconfig | |||
@@ -89,6 +89,10 @@ config PAGESIZE_16 | |||
89 | machine with 4MB of memory. | 89 | machine with 4MB of memory. |
90 | endmenu | 90 | endmenu |
91 | 91 | ||
92 | config ISA_DMA_API | ||
93 | bool | ||
94 | default y | ||
95 | |||
92 | menu "General setup" | 96 | menu "General setup" |
93 | 97 | ||
94 | # Compressed boot loader in ROM. Yes, we really want to ask about | 98 | # Compressed boot loader in ROM. Yes, we really want to ask about |
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c index 134aec1c6d19..b5f83e9f04db 100644 --- a/arch/h8300/kernel/process.c +++ b/arch/h8300/kernel/process.c | |||
@@ -54,7 +54,7 @@ asmlinkage void ret_from_fork(void); | |||
54 | void default_idle(void) | 54 | void default_idle(void) |
55 | { | 55 | { |
56 | while(1) { | 56 | while(1) { |
57 | if (need_resched()) { | 57 | if (!need_resched()) { |
58 | local_irq_enable(); | 58 | local_irq_enable(); |
59 | __asm__("sleep"); | 59 | __asm__("sleep"); |
60 | local_irq_disable(); | 60 | local_irq_disable(); |
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 99b4f294a52d..dfd904f6883b 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig | |||
@@ -183,7 +183,7 @@ config M386 | |||
183 | - "Winchip-C6" for original IDT Winchip. | 183 | - "Winchip-C6" for original IDT Winchip. |
184 | - "Winchip-2" for IDT Winchip 2. | 184 | - "Winchip-2" for IDT Winchip 2. |
185 | - "Winchip-2A" for IDT Winchips with 3dNow! capabilities. | 185 | - "Winchip-2A" for IDT Winchips with 3dNow! capabilities. |
186 | - "MediaGX/Geode" for Cyrix MediaGX aka Geode. | 186 | - "GeodeGX1" for Geode GX1 (Cyrix MediaGX). |
187 | - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3. | 187 | - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3. |
188 | - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above). | 188 | - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above). |
189 | 189 | ||
@@ -311,12 +311,10 @@ config MWINCHIP3D | |||
311 | stores for this CPU, which can increase performance of some | 311 | stores for this CPU, which can increase performance of some |
312 | operations. | 312 | operations. |
313 | 313 | ||
314 | config MGEODE | 314 | config MGEODEGX1 |
315 | bool "MediaGX/Geode" | 315 | bool "GeodeGX1" |
316 | help | 316 | help |
317 | Select this for a Cyrix MediaGX aka Geode chip. Linux and GCC | 317 | Select this for a Geode GX1 (Cyrix MediaGX) chip. |
318 | treat this chip as a 586TSC with some extended instructions | ||
319 | and alignment reqirements. | ||
320 | 318 | ||
321 | config MCYRIXIII | 319 | config MCYRIXIII |
322 | bool "CyrixIII/VIA-C3" | 320 | bool "CyrixIII/VIA-C3" |
@@ -368,7 +366,7 @@ config X86_L1_CACHE_SHIFT | |||
368 | int | 366 | int |
369 | default "7" if MPENTIUM4 || X86_GENERIC | 367 | default "7" if MPENTIUM4 || X86_GENERIC |
370 | default "4" if X86_ELAN || M486 || M386 | 368 | default "4" if X86_ELAN || M486 || M386 |
371 | default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE | 369 | default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODEGX1 |
372 | default "6" if MK7 || MK8 || MPENTIUMM | 370 | default "6" if MK7 || MK8 || MPENTIUMM |
373 | 371 | ||
374 | config RWSEM_GENERIC_SPINLOCK | 372 | config RWSEM_GENERIC_SPINLOCK |
@@ -387,7 +385,7 @@ config GENERIC_CALIBRATE_DELAY | |||
387 | 385 | ||
388 | config X86_PPRO_FENCE | 386 | config X86_PPRO_FENCE |
389 | bool | 387 | bool |
390 | depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODE | 388 | depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1 |
391 | default y | 389 | default y |
392 | 390 | ||
393 | config X86_F00F_BUG | 391 | config X86_F00F_BUG |
@@ -417,7 +415,7 @@ config X86_POPAD_OK | |||
417 | 415 | ||
418 | config X86_ALIGNMENT_16 | 416 | config X86_ALIGNMENT_16 |
419 | bool | 417 | bool |
420 | depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODE | 418 | depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1 |
421 | default y | 419 | default y |
422 | 420 | ||
423 | config X86_GOOD_APIC | 421 | config X86_GOOD_APIC |
@@ -442,7 +440,7 @@ config X86_USE_3DNOW | |||
442 | 440 | ||
443 | config X86_OOSTORE | 441 | config X86_OOSTORE |
444 | bool | 442 | bool |
445 | depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MGEODE) && MTRR | 443 | depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR |
446 | default y | 444 | default y |
447 | 445 | ||
448 | config HPET_TIMER | 446 | config HPET_TIMER |
@@ -578,7 +576,7 @@ config X86_VISWS_APIC | |||
578 | 576 | ||
579 | config X86_TSC | 577 | config X86_TSC |
580 | bool | 578 | bool |
581 | depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODE) && !X86_NUMAQ | 579 | depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ |
582 | default y | 580 | default y |
583 | 581 | ||
584 | config X86_MCE | 582 | config X86_MCE |
@@ -1165,7 +1163,7 @@ config PCI_DIRECT | |||
1165 | 1163 | ||
1166 | config PCI_MMCONFIG | 1164 | config PCI_MMCONFIG |
1167 | bool | 1165 | bool |
1168 | depends on PCI && (PCI_GOMMCONFIG || (PCI_GOANY && ACPI)) | 1166 | depends on PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY) |
1169 | select ACPI_BOOT | 1167 | select ACPI_BOOT |
1170 | default y | 1168 | default y |
1171 | 1169 | ||
@@ -1173,6 +1171,10 @@ source "drivers/pci/pcie/Kconfig" | |||
1173 | 1171 | ||
1174 | source "drivers/pci/Kconfig" | 1172 | source "drivers/pci/Kconfig" |
1175 | 1173 | ||
1174 | config ISA_DMA_API | ||
1175 | bool | ||
1176 | default y | ||
1177 | |||
1176 | config ISA | 1178 | config ISA |
1177 | bool "ISA support" | 1179 | bool "ISA support" |
1178 | depends on !(X86_VOYAGER || X86_VISWS) | 1180 | depends on !(X86_VOYAGER || X86_VISWS) |
diff --git a/arch/i386/Makefile b/arch/i386/Makefile index 04783ceb050c..1c36ca332a96 100644 --- a/arch/i386/Makefile +++ b/arch/i386/Makefile | |||
@@ -14,7 +14,7 @@ | |||
14 | # 19990713 Artur Skawina <skawina@geocities.com> | 14 | # 19990713 Artur Skawina <skawina@geocities.com> |
15 | # Added '-march' and '-mpreferred-stack-boundary' support | 15 | # Added '-march' and '-mpreferred-stack-boundary' support |
16 | # | 16 | # |
17 | # Kianusch Sayah Karadji <kianusch@sk-tech.net> | 17 | # 20050320 Kianusch Sayah Karadji <kianusch@sk-tech.net> |
18 | # Added support for GEODE CPU | 18 | # Added support for GEODE CPU |
19 | 19 | ||
20 | LDFLAGS := -m elf_i386 | 20 | LDFLAGS := -m elf_i386 |
@@ -54,8 +54,8 @@ cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686) | |||
54 | # AMD Elan support | 54 | # AMD Elan support |
55 | cflags-$(CONFIG_X86_ELAN) += -march=i486 | 55 | cflags-$(CONFIG_X86_ELAN) += -march=i486 |
56 | 56 | ||
57 | # MediaGX aka Geode support | 57 | # Geode GX1 support |
58 | cflags-$(CONFIG_MGEODE) += $(call cc-option,-march=pentium-mmx,-march=i586) | 58 | cflags-$(CONFIG_MGEODEGX1) += $(call cc-option,-march=pentium-mmx,-march=i486) |
59 | 59 | ||
60 | # -mregparm=3 works ok on gcc-3.0 and later | 60 | # -mregparm=3 works ok on gcc-3.0 and later |
61 | # | 61 | # |
diff --git a/arch/i386/boot/bootsect.S b/arch/i386/boot/bootsect.S index ba9fe14db6a9..011b7a4993d4 100644 --- a/arch/i386/boot/bootsect.S +++ b/arch/i386/boot/bootsect.S | |||
@@ -83,7 +83,7 @@ bugger_off_msg: | |||
83 | .ascii "\n" | 83 | .ascii "\n" |
84 | .ascii "Remove disk and press any key to reboot . . .\r\n" | 84 | .ascii "Remove disk and press any key to reboot . . .\r\n" |
85 | .byte 0 | 85 | .byte 0 |
86 | 86 | ||
87 | 87 | ||
88 | # Kernel attributes; used by setup | 88 | # Kernel attributes; used by setup |
89 | 89 | ||
diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S index 925d3f5a3824..0587477c99f2 100644 --- a/arch/i386/boot/video.S +++ b/arch/i386/boot/video.S | |||
@@ -1924,36 +1924,36 @@ skip10: movb %ah, %al | |||
1924 | ret | 1924 | ret |
1925 | 1925 | ||
1926 | store_edid: | 1926 | store_edid: |
1927 | pushw %es # just save all registers | 1927 | pushw %es # just save all registers |
1928 | pushw %ax | 1928 | pushw %ax |
1929 | pushw %bx | 1929 | pushw %bx |
1930 | pushw %cx | 1930 | pushw %cx |
1931 | pushw %dx | 1931 | pushw %dx |
1932 | pushw %di | 1932 | pushw %di |
1933 | 1933 | ||
1934 | pushw %fs | 1934 | pushw %fs |
1935 | popw %es | 1935 | popw %es |
1936 | 1936 | ||
1937 | movl $0x13131313, %eax # memset block with 0x13 | 1937 | movl $0x13131313, %eax # memset block with 0x13 |
1938 | movw $32, %cx | 1938 | movw $32, %cx |
1939 | movw $0x140, %di | 1939 | movw $0x140, %di |
1940 | cld | 1940 | cld |
1941 | rep | 1941 | rep |
1942 | stosl | 1942 | stosl |
1943 | 1943 | ||
1944 | movw $0x4f15, %ax # do VBE/DDC | 1944 | movw $0x4f15, %ax # do VBE/DDC |
1945 | movw $0x01, %bx | 1945 | movw $0x01, %bx |
1946 | movw $0x00, %cx | 1946 | movw $0x00, %cx |
1947 | movw $0x01, %dx | 1947 | movw $0x01, %dx |
1948 | movw $0x140, %di | 1948 | movw $0x140, %di |
1949 | int $0x10 | 1949 | int $0x10 |
1950 | 1950 | ||
1951 | popw %di # restore all registers | 1951 | popw %di # restore all registers |
1952 | popw %dx | 1952 | popw %dx |
1953 | popw %cx | 1953 | popw %cx |
1954 | popw %bx | 1954 | popw %bx |
1955 | popw %ax | 1955 | popw %ax |
1956 | popw %es | 1956 | popw %es |
1957 | ret | 1957 | ret |
1958 | 1958 | ||
1959 | # VIDEO_SELECT-only variables | 1959 | # VIDEO_SELECT-only variables |
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index 0fbcfe00dd8d..51ecd512603d 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile | |||
@@ -43,7 +43,7 @@ obj-$(CONFIG_SCx200) += scx200.o | |||
43 | # Note: kbuild does not track this dependency due to usage of .incbin | 43 | # Note: kbuild does not track this dependency due to usage of .incbin |
44 | $(obj)/vsyscall.o: $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so | 44 | $(obj)/vsyscall.o: $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so |
45 | targets += $(foreach F,int80 sysenter,vsyscall-$F.o vsyscall-$F.so) | 45 | targets += $(foreach F,int80 sysenter,vsyscall-$F.o vsyscall-$F.so) |
46 | targets += vsyscall.lds | 46 | targets += vsyscall-note.o vsyscall.lds |
47 | 47 | ||
48 | # The DSO images are built using a special linker script. | 48 | # The DSO images are built using a special linker script. |
49 | quiet_cmd_syscall = SYSCALL $@ | 49 | quiet_cmd_syscall = SYSCALL $@ |
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 53eb5cfd5b63..848bb97af7ca 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
@@ -650,7 +650,7 @@ acpi_find_rsdp (void) | |||
650 | */ | 650 | */ |
651 | rsdp_phys = acpi_scan_rsdp (0, 0x400); | 651 | rsdp_phys = acpi_scan_rsdp (0, 0x400); |
652 | if (!rsdp_phys) | 652 | if (!rsdp_phys) |
653 | rsdp_phys = acpi_scan_rsdp (0xE0000, 0xFFFFF); | 653 | rsdp_phys = acpi_scan_rsdp (0xE0000, 0x20000); |
654 | 654 | ||
655 | return rsdp_phys; | 655 | return rsdp_phys; |
656 | } | 656 | } |
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index 45641a872550..0ff65abcd56c 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c | |||
@@ -1222,6 +1222,7 @@ static int suspend(int vetoable) | |||
1222 | 1222 | ||
1223 | save_processor_state(); | 1223 | save_processor_state(); |
1224 | err = set_system_power_state(APM_STATE_SUSPEND); | 1224 | err = set_system_power_state(APM_STATE_SUSPEND); |
1225 | ignore_normal_resume = 1; | ||
1225 | restore_processor_state(); | 1226 | restore_processor_state(); |
1226 | 1227 | ||
1227 | local_irq_disable(); | 1228 | local_irq_disable(); |
@@ -1229,7 +1230,6 @@ static int suspend(int vetoable) | |||
1229 | spin_lock(&i8253_lock); | 1230 | spin_lock(&i8253_lock); |
1230 | reinit_timer(); | 1231 | reinit_timer(); |
1231 | set_time(); | 1232 | set_time(); |
1232 | ignore_normal_resume = 1; | ||
1233 | 1233 | ||
1234 | spin_unlock(&i8253_lock); | 1234 | spin_unlock(&i8253_lock); |
1235 | write_sequnlock(&xtime_lock); | 1235 | write_sequnlock(&xtime_lock); |
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c index 16dbc4151be4..73aeaf5a9d4e 100644 --- a/arch/i386/kernel/cpu/amd.c +++ b/arch/i386/kernel/cpu/amd.c | |||
@@ -24,9 +24,6 @@ __asm__(".align 4\nvide: ret"); | |||
24 | 24 | ||
25 | static void __init init_amd(struct cpuinfo_x86 *c) | 25 | static void __init init_amd(struct cpuinfo_x86 *c) |
26 | { | 26 | { |
27 | #ifdef CONFIG_X86_SMP | ||
28 | int cpu = c == &boot_cpu_data ? 0 : c - cpu_data; | ||
29 | #endif | ||
30 | u32 l, h; | 27 | u32 l, h; |
31 | int mbytes = num_physpages >> (20-PAGE_SHIFT); | 28 | int mbytes = num_physpages >> (20-PAGE_SHIFT); |
32 | int r; | 29 | int r; |
@@ -198,14 +195,19 @@ static void __init init_amd(struct cpuinfo_x86 *c) | |||
198 | c->x86_num_cores = 1; | 195 | c->x86_num_cores = 1; |
199 | } | 196 | } |
200 | 197 | ||
201 | #ifdef CONFIG_X86_SMP | 198 | #ifdef CONFIG_X86_HT |
202 | /* | 199 | /* |
203 | * On a AMD dual core setup the lower bits of the APIC id | 200 | * On a AMD dual core setup the lower bits of the APIC id |
204 | * distingush the cores. Assumes number of cores is a power | 201 | * distingush the cores. Assumes number of cores is a power |
205 | * of two. | 202 | * of two. |
206 | */ | 203 | */ |
207 | if (c->x86_num_cores > 1) { | 204 | if (c->x86_num_cores > 1) { |
208 | cpu_core_id[cpu] = cpu >> hweight32(c->x86_num_cores - 1); | 205 | int cpu = smp_processor_id(); |
206 | unsigned bits = 0; | ||
207 | while ((1 << bits) < c->x86_num_cores) | ||
208 | bits++; | ||
209 | cpu_core_id[cpu] = phys_proc_id[cpu] & ((1<<bits)-1); | ||
210 | phys_proc_id[cpu] >>= bits; | ||
209 | printk(KERN_INFO "CPU %d(%d) -> Core %d\n", | 211 | printk(KERN_INFO "CPU %d(%d) -> Core %d\n", |
210 | cpu, c->x86_num_cores, cpu_core_id[cpu]); | 212 | cpu, c->x86_num_cores, cpu_core_id[cpu]); |
211 | } | 213 | } |
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 6be0310e3cd3..d199e525680a 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c | |||
@@ -243,6 +243,10 @@ static void __init early_cpu_detect(void) | |||
243 | } | 243 | } |
244 | 244 | ||
245 | early_intel_workaround(c); | 245 | early_intel_workaround(c); |
246 | |||
247 | #ifdef CONFIG_X86_HT | ||
248 | phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff; | ||
249 | #endif | ||
246 | } | 250 | } |
247 | 251 | ||
248 | void __init generic_identify(struct cpuinfo_x86 * c) | 252 | void __init generic_identify(struct cpuinfo_x86 * c) |
diff --git a/arch/i386/kernel/cpu/cpufreq/Kconfig b/arch/i386/kernel/cpu/cpufreq/Kconfig index f25ffd74235c..0f1eb507233b 100644 --- a/arch/i386/kernel/cpu/cpufreq/Kconfig +++ b/arch/i386/kernel/cpu/cpufreq/Kconfig | |||
@@ -23,7 +23,7 @@ config X86_ACPI_CPUFREQ | |||
23 | If in doubt, say N. | 23 | If in doubt, say N. |
24 | 24 | ||
25 | config ELAN_CPUFREQ | 25 | config ELAN_CPUFREQ |
26 | tristate "AMD Elan" | 26 | tristate "AMD Elan SC400 and SC410" |
27 | select CPU_FREQ_TABLE | 27 | select CPU_FREQ_TABLE |
28 | depends on X86_ELAN | 28 | depends on X86_ELAN |
29 | ---help--- | 29 | ---help--- |
@@ -38,6 +38,18 @@ config ELAN_CPUFREQ | |||
38 | 38 | ||
39 | If in doubt, say N. | 39 | If in doubt, say N. |
40 | 40 | ||
41 | config SC520_CPUFREQ | ||
42 | tristate "AMD Elan SC520" | ||
43 | select CPU_FREQ_TABLE | ||
44 | depends on X86_ELAN | ||
45 | ---help--- | ||
46 | This adds the CPUFreq driver for AMD Elan SC520 processor. | ||
47 | |||
48 | For details, take a look at <file:Documentation/cpu-freq/>. | ||
49 | |||
50 | If in doubt, say N. | ||
51 | |||
52 | |||
41 | config X86_POWERNOW_K6 | 53 | config X86_POWERNOW_K6 |
42 | tristate "AMD Mobile K6-2/K6-3 PowerNow!" | 54 | tristate "AMD Mobile K6-2/K6-3 PowerNow!" |
43 | select CPU_FREQ_TABLE | 55 | select CPU_FREQ_TABLE |
diff --git a/arch/i386/kernel/cpu/cpufreq/Makefile b/arch/i386/kernel/cpu/cpufreq/Makefile index a922e97aeedd..2e894f1c8910 100644 --- a/arch/i386/kernel/cpu/cpufreq/Makefile +++ b/arch/i386/kernel/cpu/cpufreq/Makefile | |||
@@ -3,6 +3,7 @@ obj-$(CONFIG_X86_POWERNOW_K7) += powernow-k7.o | |||
3 | obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o | 3 | obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o |
4 | obj-$(CONFIG_X86_LONGHAUL) += longhaul.o | 4 | obj-$(CONFIG_X86_LONGHAUL) += longhaul.o |
5 | obj-$(CONFIG_ELAN_CPUFREQ) += elanfreq.o | 5 | obj-$(CONFIG_ELAN_CPUFREQ) += elanfreq.o |
6 | obj-$(CONFIG_SC520_CPUFREQ) += sc520_freq.o | ||
6 | obj-$(CONFIG_X86_LONGRUN) += longrun.o | 7 | obj-$(CONFIG_X86_LONGRUN) += longrun.o |
7 | obj-$(CONFIG_X86_GX_SUSPMOD) += gx-suspmod.o | 8 | obj-$(CONFIG_X86_GX_SUSPMOD) += gx-suspmod.o |
8 | obj-$(CONFIG_X86_SPEEDSTEP_ICH) += speedstep-ich.o | 9 | obj-$(CONFIG_X86_SPEEDSTEP_ICH) += speedstep-ich.o |
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c index ab0f9f5aac11..04e3563da4fe 100644 --- a/arch/i386/kernel/cpu/cpufreq/longhaul.c +++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/cpufreq.h> | 29 | #include <linux/cpufreq.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/string.h> | 31 | #include <linux/string.h> |
32 | #include <linux/pci.h> | ||
32 | 33 | ||
33 | #include <asm/msr.h> | 34 | #include <asm/msr.h> |
34 | #include <asm/timex.h> | 35 | #include <asm/timex.h> |
@@ -119,7 +120,13 @@ static int longhaul_get_cpu_mult(void) | |||
119 | static void do_powersaver(union msr_longhaul *longhaul, | 120 | static void do_powersaver(union msr_longhaul *longhaul, |
120 | unsigned int clock_ratio_index) | 121 | unsigned int clock_ratio_index) |
121 | { | 122 | { |
123 | struct pci_dev *dev; | ||
124 | unsigned long flags; | ||
125 | unsigned int tmp_mask; | ||
122 | int version; | 126 | int version; |
127 | int i; | ||
128 | u16 pci_cmd; | ||
129 | u16 cmd_state[64]; | ||
123 | 130 | ||
124 | switch (cpu_model) { | 131 | switch (cpu_model) { |
125 | case CPU_EZRA_T: | 132 | case CPU_EZRA_T: |
@@ -137,17 +144,58 @@ static void do_powersaver(union msr_longhaul *longhaul, | |||
137 | longhaul->bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4; | 144 | longhaul->bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4; |
138 | longhaul->bits.EnableSoftBusRatio = 1; | 145 | longhaul->bits.EnableSoftBusRatio = 1; |
139 | longhaul->bits.RevisionKey = 0; | 146 | longhaul->bits.RevisionKey = 0; |
140 | local_irq_disable(); | 147 | |
141 | wrmsrl(MSR_VIA_LONGHAUL, longhaul->val); | 148 | preempt_disable(); |
149 | local_irq_save(flags); | ||
150 | |||
151 | /* | ||
152 | * get current pci bus master state for all devices | ||
153 | * and clear bus master bit | ||
154 | */ | ||
155 | dev = NULL; | ||
156 | i = 0; | ||
157 | do { | ||
158 | dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev); | ||
159 | if (dev != NULL) { | ||
160 | pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); | ||
161 | cmd_state[i++] = pci_cmd; | ||
162 | pci_cmd &= ~PCI_COMMAND_MASTER; | ||
163 | pci_write_config_word(dev, PCI_COMMAND, pci_cmd); | ||
164 | } | ||
165 | } while (dev != NULL); | ||
166 | |||
167 | tmp_mask=inb(0x21); /* works on C3. save mask. */ | ||
168 | outb(0xFE,0x21); /* TMR0 only */ | ||
169 | outb(0xFF,0x80); /* delay */ | ||
170 | |||
142 | local_irq_enable(); | 171 | local_irq_enable(); |
172 | |||
173 | __hlt(); | ||
174 | wrmsrl(MSR_VIA_LONGHAUL, longhaul->val); | ||
143 | __hlt(); | 175 | __hlt(); |
144 | 176 | ||
177 | local_irq_disable(); | ||
178 | |||
179 | outb(tmp_mask,0x21); /* restore mask */ | ||
180 | |||
181 | /* restore pci bus master state for all devices */ | ||
182 | dev = NULL; | ||
183 | i = 0; | ||
184 | do { | ||
185 | dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev); | ||
186 | if (dev != NULL) { | ||
187 | pci_cmd = cmd_state[i++]; | ||
188 | pci_write_config_byte(dev, PCI_COMMAND, pci_cmd); | ||
189 | } | ||
190 | } while (dev != NULL); | ||
191 | local_irq_restore(flags); | ||
192 | preempt_enable(); | ||
193 | |||
194 | /* disable bus ratio bit */ | ||
145 | rdmsrl(MSR_VIA_LONGHAUL, longhaul->val); | 195 | rdmsrl(MSR_VIA_LONGHAUL, longhaul->val); |
146 | longhaul->bits.EnableSoftBusRatio = 0; | 196 | longhaul->bits.EnableSoftBusRatio = 0; |
147 | longhaul->bits.RevisionKey = version; | 197 | longhaul->bits.RevisionKey = version; |
148 | local_irq_disable(); | ||
149 | wrmsrl(MSR_VIA_LONGHAUL, longhaul->val); | 198 | wrmsrl(MSR_VIA_LONGHAUL, longhaul->val); |
150 | local_irq_enable(); | ||
151 | } | 199 | } |
152 | 200 | ||
153 | /** | 201 | /** |
@@ -578,7 +626,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) | |||
578 | longhaul_setup_voltagescaling(); | 626 | longhaul_setup_voltagescaling(); |
579 | 627 | ||
580 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | 628 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; |
581 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | 629 | policy->cpuinfo.transition_latency = 200000; /* nsec */ |
582 | policy->cur = calc_speed(longhaul_get_cpu_mult()); | 630 | policy->cur = calc_speed(longhaul_get_cpu_mult()); |
583 | 631 | ||
584 | ret = cpufreq_frequency_table_cpuinfo(policy, longhaul_table); | 632 | ret = cpufreq_frequency_table_cpuinfo(policy, longhaul_table); |
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c index 913f652623d9..5c530064eb74 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/dmi.h> | 23 | #include <linux/dmi.h> |
24 | 24 | ||
25 | #include <asm/msr.h> | 25 | #include <asm/msr.h> |
26 | #include <asm/timer.h> | ||
26 | #include <asm/timex.h> | 27 | #include <asm/timex.h> |
27 | #include <asm/io.h> | 28 | #include <asm/io.h> |
28 | #include <asm/system.h> | 29 | #include <asm/system.h> |
@@ -586,13 +587,17 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy) | |||
586 | 587 | ||
587 | rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val); | 588 | rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val); |
588 | 589 | ||
589 | /* A K7 with powernow technology is set to max frequency by BIOS */ | 590 | /* recalibrate cpu_khz */ |
590 | fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.MFID]; | 591 | result = recalibrate_cpu_khz(); |
592 | if (result) | ||
593 | return result; | ||
594 | |||
595 | fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.CFID]; | ||
591 | if (!fsb) { | 596 | if (!fsb) { |
592 | printk(KERN_WARNING PFX "can not determine bus frequency\n"); | 597 | printk(KERN_WARNING PFX "can not determine bus frequency\n"); |
593 | return -EINVAL; | 598 | return -EINVAL; |
594 | } | 599 | } |
595 | dprintk("FSB: %3d.%03d MHz\n", fsb/1000, fsb%1000); | 600 | dprintk("FSB: %3dMHz\n", fsb/1000); |
596 | 601 | ||
597 | if (dmi_check_system(powernow_dmi_table) || acpi_force) { | 602 | if (dmi_check_system(powernow_dmi_table) || acpi_force) { |
598 | printk (KERN_INFO PFX "PSB/PST known to be broken. Trying ACPI instead\n"); | 603 | printk (KERN_INFO PFX "PSB/PST known to be broken. Trying ACPI instead\n"); |
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index a65ff7e32e5d..10cc096c0ade 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * GNU general public license version 2. See "COPYING" or | 4 | * GNU general public license version 2. See "COPYING" or |
5 | * http://www.gnu.org/licenses/gpl.html | 5 | * http://www.gnu.org/licenses/gpl.html |
6 | * | 6 | * |
7 | * Support : paul.devriendt@amd.com | 7 | * Support : mark.langsdorf@amd.com |
8 | * | 8 | * |
9 | * Based on the powernow-k7.c module written by Dave Jones. | 9 | * Based on the powernow-k7.c module written by Dave Jones. |
10 | * (C) 2003 Dave Jones <davej@codemonkey.org.uk> on behalf of SuSE Labs | 10 | * (C) 2003 Dave Jones <davej@codemonkey.org.uk> on behalf of SuSE Labs |
@@ -15,12 +15,13 @@ | |||
15 | * | 15 | * |
16 | * Valuable input gratefully received from Dave Jones, Pavel Machek, | 16 | * Valuable input gratefully received from Dave Jones, Pavel Machek, |
17 | * Dominik Brodowski, and others. | 17 | * Dominik Brodowski, and others. |
18 | * Originally developed by Paul Devriendt. | ||
18 | * Processor information obtained from Chapter 9 (Power and Thermal Management) | 19 | * Processor information obtained from Chapter 9 (Power and Thermal Management) |
19 | * of the "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD | 20 | * of the "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD |
20 | * Opteron Processors" available for download from www.amd.com | 21 | * Opteron Processors" available for download from www.amd.com |
21 | * | 22 | * |
22 | * Tables for specific CPUs can be infrerred from | 23 | * Tables for specific CPUs can be infrerred from |
23 | * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/30430.pdf | 24 | * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/30430.pdf |
24 | */ | 25 | */ |
25 | 26 | ||
26 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
@@ -30,6 +31,7 @@ | |||
30 | #include <linux/cpufreq.h> | 31 | #include <linux/cpufreq.h> |
31 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
32 | #include <linux/string.h> | 33 | #include <linux/string.h> |
34 | #include <linux/cpumask.h> | ||
33 | 35 | ||
34 | #include <asm/msr.h> | 36 | #include <asm/msr.h> |
35 | #include <asm/io.h> | 37 | #include <asm/io.h> |
@@ -42,7 +44,7 @@ | |||
42 | 44 | ||
43 | #define PFX "powernow-k8: " | 45 | #define PFX "powernow-k8: " |
44 | #define BFX PFX "BIOS error: " | 46 | #define BFX PFX "BIOS error: " |
45 | #define VERSION "version 1.00.09e" | 47 | #define VERSION "version 1.40.2" |
46 | #include "powernow-k8.h" | 48 | #include "powernow-k8.h" |
47 | 49 | ||
48 | /* serialize freq changes */ | 50 | /* serialize freq changes */ |
@@ -50,6 +52,10 @@ static DECLARE_MUTEX(fidvid_sem); | |||
50 | 52 | ||
51 | static struct powernow_k8_data *powernow_data[NR_CPUS]; | 53 | static struct powernow_k8_data *powernow_data[NR_CPUS]; |
52 | 54 | ||
55 | #ifndef CONFIG_SMP | ||
56 | static cpumask_t cpu_core_map[1]; | ||
57 | #endif | ||
58 | |||
53 | /* Return a frequency in MHz, given an input fid */ | 59 | /* Return a frequency in MHz, given an input fid */ |
54 | static u32 find_freq_from_fid(u32 fid) | 60 | static u32 find_freq_from_fid(u32 fid) |
55 | { | 61 | { |
@@ -274,11 +280,18 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid | |||
274 | { | 280 | { |
275 | u32 rvosteps = data->rvo; | 281 | u32 rvosteps = data->rvo; |
276 | u32 savefid = data->currfid; | 282 | u32 savefid = data->currfid; |
283 | u32 maxvid, lo; | ||
277 | 284 | ||
278 | dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, reqvid 0x%x, rvo 0x%x\n", | 285 | dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, reqvid 0x%x, rvo 0x%x\n", |
279 | smp_processor_id(), | 286 | smp_processor_id(), |
280 | data->currfid, data->currvid, reqvid, data->rvo); | 287 | data->currfid, data->currvid, reqvid, data->rvo); |
281 | 288 | ||
289 | rdmsr(MSR_FIDVID_STATUS, lo, maxvid); | ||
290 | maxvid = 0x1f & (maxvid >> 16); | ||
291 | dprintk("ph1 maxvid=0x%x\n", maxvid); | ||
292 | if (reqvid < maxvid) /* lower numbers are higher voltages */ | ||
293 | reqvid = maxvid; | ||
294 | |||
282 | while (data->currvid > reqvid) { | 295 | while (data->currvid > reqvid) { |
283 | dprintk("ph1: curr 0x%x, req vid 0x%x\n", | 296 | dprintk("ph1: curr 0x%x, req vid 0x%x\n", |
284 | data->currvid, reqvid); | 297 | data->currvid, reqvid); |
@@ -286,8 +299,8 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid | |||
286 | return 1; | 299 | return 1; |
287 | } | 300 | } |
288 | 301 | ||
289 | while ((rvosteps > 0) && ((data->rvo + data->currvid) > reqvid)) { | 302 | while ((rvosteps > 0) && ((data->rvo + data->currvid) > reqvid)) { |
290 | if (data->currvid == 0) { | 303 | if (data->currvid == maxvid) { |
291 | rvosteps = 0; | 304 | rvosteps = 0; |
292 | } else { | 305 | } else { |
293 | dprintk("ph1: changing vid for rvo, req 0x%x\n", | 306 | dprintk("ph1: changing vid for rvo, req 0x%x\n", |
@@ -671,7 +684,7 @@ static int find_psb_table(struct powernow_k8_data *data) | |||
671 | * BIOS and Kernel Developer's Guide, which is available on | 684 | * BIOS and Kernel Developer's Guide, which is available on |
672 | * www.amd.com | 685 | * www.amd.com |
673 | */ | 686 | */ |
674 | printk(KERN_ERR PFX "BIOS error - no PSB\n"); | 687 | printk(KERN_INFO PFX "BIOS error - no PSB or ACPI _PSS objects\n"); |
675 | return -ENODEV; | 688 | return -ENODEV; |
676 | } | 689 | } |
677 | 690 | ||
@@ -695,7 +708,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | |||
695 | struct cpufreq_frequency_table *powernow_table; | 708 | struct cpufreq_frequency_table *powernow_table; |
696 | 709 | ||
697 | if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) { | 710 | if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) { |
698 | dprintk("register performance failed\n"); | 711 | dprintk("register performance failed: bad ACPI data\n"); |
699 | return -EIO; | 712 | return -EIO; |
700 | } | 713 | } |
701 | 714 | ||
@@ -746,22 +759,23 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | |||
746 | continue; | 759 | continue; |
747 | } | 760 | } |
748 | 761 | ||
749 | if (fid < HI_FID_TABLE_BOTTOM) { | 762 | /* verify only 1 entry from the lo frequency table */ |
750 | if (cntlofreq) { | 763 | if (fid < HI_FID_TABLE_BOTTOM) { |
751 | /* if both entries are the same, ignore this | 764 | if (cntlofreq) { |
752 | * one... | 765 | /* if both entries are the same, ignore this |
753 | */ | 766 | * one... |
754 | if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) || | 767 | */ |
755 | (powernow_table[i].index != powernow_table[cntlofreq].index)) { | 768 | if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) || |
756 | printk(KERN_ERR PFX "Too many lo freq table entries\n"); | 769 | (powernow_table[i].index != powernow_table[cntlofreq].index)) { |
757 | goto err_out_mem; | 770 | printk(KERN_ERR PFX "Too many lo freq table entries\n"); |
758 | } | 771 | goto err_out_mem; |
759 | 772 | } | |
760 | dprintk("double low frequency table entry, ignoring it.\n"); | 773 | |
761 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; | 774 | dprintk("double low frequency table entry, ignoring it.\n"); |
762 | continue; | 775 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; |
763 | } else | 776 | continue; |
764 | cntlofreq = i; | 777 | } else |
778 | cntlofreq = i; | ||
765 | } | 779 | } |
766 | 780 | ||
767 | if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) { | 781 | if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) { |
@@ -816,7 +830,7 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde | |||
816 | { | 830 | { |
817 | u32 fid; | 831 | u32 fid; |
818 | u32 vid; | 832 | u32 vid; |
819 | int res; | 833 | int res, i; |
820 | struct cpufreq_freqs freqs; | 834 | struct cpufreq_freqs freqs; |
821 | 835 | ||
822 | dprintk("cpu %d transition to index %u\n", smp_processor_id(), index); | 836 | dprintk("cpu %d transition to index %u\n", smp_processor_id(), index); |
@@ -841,7 +855,8 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde | |||
841 | } | 855 | } |
842 | 856 | ||
843 | if ((fid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) { | 857 | if ((fid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) { |
844 | printk("ignoring illegal change in lo freq table-%x to 0x%x\n", | 858 | printk(KERN_ERR PFX |
859 | "ignoring illegal change in lo freq table-%x to 0x%x\n", | ||
845 | data->currfid, fid); | 860 | data->currfid, fid); |
846 | return 1; | 861 | return 1; |
847 | } | 862 | } |
@@ -850,18 +865,20 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde | |||
850 | smp_processor_id(), fid, vid); | 865 | smp_processor_id(), fid, vid); |
851 | 866 | ||
852 | freqs.cpu = data->cpu; | 867 | freqs.cpu = data->cpu; |
853 | |||
854 | freqs.old = find_khz_freq_from_fid(data->currfid); | 868 | freqs.old = find_khz_freq_from_fid(data->currfid); |
855 | freqs.new = find_khz_freq_from_fid(fid); | 869 | freqs.new = find_khz_freq_from_fid(fid); |
856 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | 870 | for_each_cpu_mask(i, cpu_core_map[data->cpu]) { |
871 | freqs.cpu = i; | ||
872 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
873 | } | ||
857 | 874 | ||
858 | down(&fidvid_sem); | ||
859 | res = transition_fid_vid(data, fid, vid); | 875 | res = transition_fid_vid(data, fid, vid); |
860 | up(&fidvid_sem); | ||
861 | 876 | ||
862 | freqs.new = find_khz_freq_from_fid(data->currfid); | 877 | freqs.new = find_khz_freq_from_fid(data->currfid); |
863 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | 878 | for_each_cpu_mask(i, cpu_core_map[data->cpu]) { |
864 | 879 | freqs.cpu = i; | |
880 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
881 | } | ||
865 | return res; | 882 | return res; |
866 | } | 883 | } |
867 | 884 | ||
@@ -874,6 +891,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
874 | u32 checkvid = data->currvid; | 891 | u32 checkvid = data->currvid; |
875 | unsigned int newstate; | 892 | unsigned int newstate; |
876 | int ret = -EIO; | 893 | int ret = -EIO; |
894 | int i; | ||
877 | 895 | ||
878 | /* only run on specific CPU from here on */ | 896 | /* only run on specific CPU from here on */ |
879 | oldmask = current->cpus_allowed; | 897 | oldmask = current->cpus_allowed; |
@@ -902,22 +920,41 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
902 | data->currfid, data->currvid); | 920 | data->currfid, data->currvid); |
903 | 921 | ||
904 | if ((checkvid != data->currvid) || (checkfid != data->currfid)) { | 922 | if ((checkvid != data->currvid) || (checkfid != data->currfid)) { |
905 | printk(KERN_ERR PFX | 923 | printk(KERN_INFO PFX |
906 | "error - out of sync, fid 0x%x 0x%x, vid 0x%x 0x%x\n", | 924 | "error - out of sync, fix 0x%x 0x%x, vid 0x%x 0x%x\n", |
907 | checkfid, data->currfid, checkvid, data->currvid); | 925 | checkfid, data->currfid, checkvid, data->currvid); |
908 | } | 926 | } |
909 | 927 | ||
910 | if (cpufreq_frequency_table_target(pol, data->powernow_table, targfreq, relation, &newstate)) | 928 | if (cpufreq_frequency_table_target(pol, data->powernow_table, targfreq, relation, &newstate)) |
911 | goto err_out; | 929 | goto err_out; |
912 | 930 | ||
931 | down(&fidvid_sem); | ||
932 | |||
933 | for_each_cpu_mask(i, cpu_core_map[pol->cpu]) { | ||
934 | /* make sure the sibling is initialized */ | ||
935 | if (!powernow_data[i]) { | ||
936 | ret = 0; | ||
937 | up(&fidvid_sem); | ||
938 | goto err_out; | ||
939 | } | ||
940 | } | ||
941 | |||
913 | powernow_k8_acpi_pst_values(data, newstate); | 942 | powernow_k8_acpi_pst_values(data, newstate); |
914 | 943 | ||
915 | if (transition_frequency(data, newstate)) { | 944 | if (transition_frequency(data, newstate)) { |
916 | printk(KERN_ERR PFX "transition frequency failed\n"); | 945 | printk(KERN_ERR PFX "transition frequency failed\n"); |
917 | ret = 1; | 946 | ret = 1; |
947 | up(&fidvid_sem); | ||
918 | goto err_out; | 948 | goto err_out; |
919 | } | 949 | } |
920 | 950 | ||
951 | /* Update all the fid/vids of our siblings */ | ||
952 | for_each_cpu_mask(i, cpu_core_map[pol->cpu]) { | ||
953 | powernow_data[i]->currvid = data->currvid; | ||
954 | powernow_data[i]->currfid = data->currfid; | ||
955 | } | ||
956 | up(&fidvid_sem); | ||
957 | |||
921 | pol->cur = find_khz_freq_from_fid(data->currfid); | 958 | pol->cur = find_khz_freq_from_fid(data->currfid); |
922 | ret = 0; | 959 | ret = 0; |
923 | 960 | ||
@@ -962,7 +999,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
962 | */ | 999 | */ |
963 | 1000 | ||
964 | if ((num_online_cpus() != 1) || (num_possible_cpus() != 1)) { | 1001 | if ((num_online_cpus() != 1) || (num_possible_cpus() != 1)) { |
965 | printk(KERN_INFO PFX "MP systems not supported by PSB BIOS structure\n"); | 1002 | printk(KERN_ERR PFX "MP systems not supported by PSB BIOS structure\n"); |
966 | kfree(data); | 1003 | kfree(data); |
967 | return -ENODEV; | 1004 | return -ENODEV; |
968 | } | 1005 | } |
@@ -1003,6 +1040,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1003 | schedule(); | 1040 | schedule(); |
1004 | 1041 | ||
1005 | pol->governor = CPUFREQ_DEFAULT_GOVERNOR; | 1042 | pol->governor = CPUFREQ_DEFAULT_GOVERNOR; |
1043 | pol->cpus = cpu_core_map[pol->cpu]; | ||
1006 | 1044 | ||
1007 | /* Take a crude guess here. | 1045 | /* Take a crude guess here. |
1008 | * That guess was in microseconds, so multiply with 1000 */ | 1046 | * That guess was in microseconds, so multiply with 1000 */ |
@@ -1069,7 +1107,7 @@ static unsigned int powernowk8_get (unsigned int cpu) | |||
1069 | return 0; | 1107 | return 0; |
1070 | } | 1108 | } |
1071 | preempt_disable(); | 1109 | preempt_disable(); |
1072 | 1110 | ||
1073 | if (query_current_values_with_pending_wait(data)) | 1111 | if (query_current_values_with_pending_wait(data)) |
1074 | goto out; | 1112 | goto out; |
1075 | 1113 | ||
@@ -1127,9 +1165,10 @@ static void __exit powernowk8_exit(void) | |||
1127 | cpufreq_unregister_driver(&cpufreq_amd64_driver); | 1165 | cpufreq_unregister_driver(&cpufreq_amd64_driver); |
1128 | } | 1166 | } |
1129 | 1167 | ||
1130 | MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com>"); | 1168 | MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com."); |
1131 | MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver."); | 1169 | MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver."); |
1132 | MODULE_LICENSE("GPL"); | 1170 | MODULE_LICENSE("GPL"); |
1133 | 1171 | ||
1134 | late_initcall(powernowk8_init); | 1172 | late_initcall(powernowk8_init); |
1135 | module_exit(powernowk8_exit); | 1173 | module_exit(powernowk8_exit); |
1174 | |||
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h index 63ebc8470f52..9ed5bf221cb7 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h | |||
@@ -174,3 +174,18 @@ static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvi | |||
174 | static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid); | 174 | static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid); |
175 | 175 | ||
176 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index); | 176 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index); |
177 | |||
178 | #ifndef for_each_cpu_mask | ||
179 | #define for_each_cpu_mask(i,mask) for (i=0;i<1;i++) | ||
180 | #endif | ||
181 | |||
182 | #ifdef CONFIG_SMP | ||
183 | static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[]) | ||
184 | { | ||
185 | } | ||
186 | #else | ||
187 | static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[]) | ||
188 | { | ||
189 | cpu_set(0, cpu_sharedcore_mask[0]); | ||
190 | } | ||
191 | #endif | ||
diff --git a/arch/i386/kernel/cpu/cpufreq/sc520_freq.c b/arch/i386/kernel/cpu/cpufreq/sc520_freq.c new file mode 100644 index 000000000000..ef457d50f4ac --- /dev/null +++ b/arch/i386/kernel/cpu/cpufreq/sc520_freq.c | |||
@@ -0,0 +1,186 @@ | |||
1 | /* | ||
2 | * sc520_freq.c: cpufreq driver for the AMD Elan sc520 | ||
3 | * | ||
4 | * Copyright (C) 2005 Sean Young <sean@mess.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | * | ||
11 | * Based on elanfreq.c | ||
12 | * | ||
13 | * 2005-03-30: - initial revision | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/init.h> | ||
19 | |||
20 | #include <linux/delay.h> | ||
21 | #include <linux/cpufreq.h> | ||
22 | |||
23 | #include <asm/msr.h> | ||
24 | #include <asm/timex.h> | ||
25 | #include <asm/io.h> | ||
26 | |||
27 | #define MMCR_BASE 0xfffef000 /* The default base address */ | ||
28 | #define OFFS_CPUCTL 0x2 /* CPU Control Register */ | ||
29 | |||
30 | static __u8 __iomem *cpuctl; | ||
31 | |||
32 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "sc520_freq", msg) | ||
33 | |||
34 | static struct cpufreq_frequency_table sc520_freq_table[] = { | ||
35 | {0x01, 100000}, | ||
36 | {0x02, 133000}, | ||
37 | {0, CPUFREQ_TABLE_END}, | ||
38 | }; | ||
39 | |||
40 | static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu) | ||
41 | { | ||
42 | u8 clockspeed_reg = *cpuctl; | ||
43 | |||
44 | switch (clockspeed_reg & 0x03) { | ||
45 | default: | ||
46 | printk(KERN_ERR "sc520_freq: error: cpuctl register has unexpected value %02x\n", clockspeed_reg); | ||
47 | case 0x01: | ||
48 | return 100000; | ||
49 | case 0x02: | ||
50 | return 133000; | ||
51 | } | ||
52 | } | ||
53 | |||
54 | static void sc520_freq_set_cpu_state (unsigned int state) | ||
55 | { | ||
56 | |||
57 | struct cpufreq_freqs freqs; | ||
58 | u8 clockspeed_reg; | ||
59 | |||
60 | freqs.old = sc520_freq_get_cpu_frequency(0); | ||
61 | freqs.new = sc520_freq_table[state].frequency; | ||
62 | freqs.cpu = 0; /* AMD Elan is UP */ | ||
63 | |||
64 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
65 | |||
66 | dprintk("attempting to set frequency to %i kHz\n", | ||
67 | sc520_freq_table[state].frequency); | ||
68 | |||
69 | local_irq_disable(); | ||
70 | |||
71 | clockspeed_reg = *cpuctl & ~0x03; | ||
72 | *cpuctl = clockspeed_reg | sc520_freq_table[state].index; | ||
73 | |||
74 | local_irq_enable(); | ||
75 | |||
76 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
77 | }; | ||
78 | |||
79 | static int sc520_freq_verify (struct cpufreq_policy *policy) | ||
80 | { | ||
81 | return cpufreq_frequency_table_verify(policy, &sc520_freq_table[0]); | ||
82 | } | ||
83 | |||
84 | static int sc520_freq_target (struct cpufreq_policy *policy, | ||
85 | unsigned int target_freq, | ||
86 | unsigned int relation) | ||
87 | { | ||
88 | unsigned int newstate = 0; | ||
89 | |||
90 | if (cpufreq_frequency_table_target(policy, sc520_freq_table, target_freq, relation, &newstate)) | ||
91 | return -EINVAL; | ||
92 | |||
93 | sc520_freq_set_cpu_state(newstate); | ||
94 | |||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | |||
99 | /* | ||
100 | * Module init and exit code | ||
101 | */ | ||
102 | |||
103 | static int sc520_freq_cpu_init(struct cpufreq_policy *policy) | ||
104 | { | ||
105 | struct cpuinfo_x86 *c = cpu_data; | ||
106 | int result; | ||
107 | |||
108 | /* capability check */ | ||
109 | if (c->x86_vendor != X86_VENDOR_AMD || | ||
110 | c->x86 != 4 || c->x86_model != 9) | ||
111 | return -ENODEV; | ||
112 | |||
113 | /* cpuinfo and default policy values */ | ||
114 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | ||
115 | policy->cpuinfo.transition_latency = 1000000; /* 1ms */ | ||
116 | policy->cur = sc520_freq_get_cpu_frequency(0); | ||
117 | |||
118 | result = cpufreq_frequency_table_cpuinfo(policy, sc520_freq_table); | ||
119 | if (result) | ||
120 | return (result); | ||
121 | |||
122 | cpufreq_frequency_table_get_attr(sc520_freq_table, policy->cpu); | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | |||
128 | static int sc520_freq_cpu_exit(struct cpufreq_policy *policy) | ||
129 | { | ||
130 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | |||
135 | static struct freq_attr* sc520_freq_attr[] = { | ||
136 | &cpufreq_freq_attr_scaling_available_freqs, | ||
137 | NULL, | ||
138 | }; | ||
139 | |||
140 | |||
141 | static struct cpufreq_driver sc520_freq_driver = { | ||
142 | .get = sc520_freq_get_cpu_frequency, | ||
143 | .verify = sc520_freq_verify, | ||
144 | .target = sc520_freq_target, | ||
145 | .init = sc520_freq_cpu_init, | ||
146 | .exit = sc520_freq_cpu_exit, | ||
147 | .name = "sc520_freq", | ||
148 | .owner = THIS_MODULE, | ||
149 | .attr = sc520_freq_attr, | ||
150 | }; | ||
151 | |||
152 | |||
153 | static int __init sc520_freq_init(void) | ||
154 | { | ||
155 | struct cpuinfo_x86 *c = cpu_data; | ||
156 | |||
157 | /* Test if we have the right hardware */ | ||
158 | if(c->x86_vendor != X86_VENDOR_AMD || | ||
159 | c->x86 != 4 || c->x86_model != 9) { | ||
160 | dprintk("no Elan SC520 processor found!\n"); | ||
161 | return -ENODEV; | ||
162 | } | ||
163 | cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1); | ||
164 | if(!cpuctl) { | ||
165 | printk(KERN_ERR "sc520_freq: error: failed to remap memory\n"); | ||
166 | return -ENOMEM; | ||
167 | } | ||
168 | |||
169 | return cpufreq_register_driver(&sc520_freq_driver); | ||
170 | } | ||
171 | |||
172 | |||
173 | static void __exit sc520_freq_exit(void) | ||
174 | { | ||
175 | cpufreq_unregister_driver(&sc520_freq_driver); | ||
176 | iounmap(cpuctl); | ||
177 | } | ||
178 | |||
179 | |||
180 | MODULE_LICENSE("GPL"); | ||
181 | MODULE_AUTHOR("Sean Young <sean@mess.org>"); | ||
182 | MODULE_DESCRIPTION("cpufreq driver for AMD's Elan sc520 CPU"); | ||
183 | |||
184 | module_init(sc520_freq_init); | ||
185 | module_exit(sc520_freq_exit); | ||
186 | |||
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c index 07d5612dc00f..7dcbf70fc16f 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c | |||
@@ -54,6 +54,8 @@ enum { | |||
54 | CPU_DOTHAN_A1, | 54 | CPU_DOTHAN_A1, |
55 | CPU_DOTHAN_A2, | 55 | CPU_DOTHAN_A2, |
56 | CPU_DOTHAN_B0, | 56 | CPU_DOTHAN_B0, |
57 | CPU_MP4HT_D0, | ||
58 | CPU_MP4HT_E0, | ||
57 | }; | 59 | }; |
58 | 60 | ||
59 | static const struct cpu_id cpu_ids[] = { | 61 | static const struct cpu_id cpu_ids[] = { |
@@ -61,6 +63,8 @@ static const struct cpu_id cpu_ids[] = { | |||
61 | [CPU_DOTHAN_A1] = { 6, 13, 1 }, | 63 | [CPU_DOTHAN_A1] = { 6, 13, 1 }, |
62 | [CPU_DOTHAN_A2] = { 6, 13, 2 }, | 64 | [CPU_DOTHAN_A2] = { 6, 13, 2 }, |
63 | [CPU_DOTHAN_B0] = { 6, 13, 6 }, | 65 | [CPU_DOTHAN_B0] = { 6, 13, 6 }, |
66 | [CPU_MP4HT_D0] = {15, 3, 4 }, | ||
67 | [CPU_MP4HT_E0] = {15, 4, 1 }, | ||
64 | }; | 68 | }; |
65 | #define N_IDS (sizeof(cpu_ids)/sizeof(cpu_ids[0])) | 69 | #define N_IDS (sizeof(cpu_ids)/sizeof(cpu_ids[0])) |
66 | 70 | ||
@@ -226,6 +230,8 @@ static struct cpu_model models[] = | |||
226 | { &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL }, | 230 | { &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL }, |
227 | { &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL }, | 231 | { &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL }, |
228 | { &cpu_ids[CPU_DOTHAN_B0], NULL, 0, NULL }, | 232 | { &cpu_ids[CPU_DOTHAN_B0], NULL, 0, NULL }, |
233 | { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL }, | ||
234 | { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL }, | ||
229 | 235 | ||
230 | { NULL, } | 236 | { NULL, } |
231 | }; | 237 | }; |
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c index 8ba430a9c3a2..d368b3f5fce8 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c | |||
@@ -336,7 +336,7 @@ unsigned int speedstep_get_freqs(unsigned int processor, | |||
336 | if (!prev_speed) | 336 | if (!prev_speed) |
337 | return -EIO; | 337 | return -EIO; |
338 | 338 | ||
339 | dprintk("previous seped is %u\n", prev_speed); | 339 | dprintk("previous speed is %u\n", prev_speed); |
340 | 340 | ||
341 | local_irq_save(flags); | 341 | local_irq_save(flags); |
342 | 342 | ||
@@ -348,7 +348,7 @@ unsigned int speedstep_get_freqs(unsigned int processor, | |||
348 | goto out; | 348 | goto out; |
349 | } | 349 | } |
350 | 350 | ||
351 | dprintk("low seped is %u\n", *low_speed); | 351 | dprintk("low speed is %u\n", *low_speed); |
352 | 352 | ||
353 | /* switch to high state */ | 353 | /* switch to high state */ |
354 | set_state(SPEEDSTEP_HIGH); | 354 | set_state(SPEEDSTEP_HIGH); |
@@ -358,7 +358,7 @@ unsigned int speedstep_get_freqs(unsigned int processor, | |||
358 | goto out; | 358 | goto out; |
359 | } | 359 | } |
360 | 360 | ||
361 | dprintk("high seped is %u\n", *high_speed); | 361 | dprintk("high speed is %u\n", *high_speed); |
362 | 362 | ||
363 | if (*low_speed == *high_speed) { | 363 | if (*low_speed == *high_speed) { |
364 | ret = -ENODEV; | 364 | ret = -ENODEV; |
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c index 79440b3f087e..b25fb6b635ae 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c | |||
@@ -357,6 +357,9 @@ static int __init speedstep_init(void) | |||
357 | case SPEEDSTEP_PROCESSOR_PIII_C: | 357 | case SPEEDSTEP_PROCESSOR_PIII_C: |
358 | case SPEEDSTEP_PROCESSOR_PIII_C_EARLY: | 358 | case SPEEDSTEP_PROCESSOR_PIII_C_EARLY: |
359 | break; | 359 | break; |
360 | case SPEEDSTEP_PROCESSOR_P4M: | ||
361 | printk(KERN_INFO "speedstep-smi: you're trying to use this cpufreq driver on a Pentium 4-based CPU. Most likely it will not work.\n"); | ||
362 | break; | ||
360 | default: | 363 | default: |
361 | speedstep_processor = 0; | 364 | speedstep_processor = 0; |
362 | } | 365 | } |
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c index aeb5b4ef8c8b..a710dc4eb20e 100644 --- a/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/arch/i386/kernel/cpu/intel_cacheinfo.c | |||
@@ -118,7 +118,7 @@ struct _cpuid4_info { | |||
118 | }; | 118 | }; |
119 | 119 | ||
120 | #define MAX_CACHE_LEAVES 4 | 120 | #define MAX_CACHE_LEAVES 4 |
121 | static unsigned short __devinitdata num_cache_leaves; | 121 | static unsigned short num_cache_leaves; |
122 | 122 | ||
123 | static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf) | 123 | static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf) |
124 | { | 124 | { |
diff --git a/arch/i386/kernel/cpu/mtrr/cyrix.c b/arch/i386/kernel/cpu/mtrr/cyrix.c index 933b0dd62f48..9027a987006b 100644 --- a/arch/i386/kernel/cpu/mtrr/cyrix.c +++ b/arch/i386/kernel/cpu/mtrr/cyrix.c | |||
@@ -218,12 +218,12 @@ typedef struct { | |||
218 | mtrr_type type; | 218 | mtrr_type type; |
219 | } arr_state_t; | 219 | } arr_state_t; |
220 | 220 | ||
221 | static arr_state_t arr_state[8] __initdata = { | 221 | static arr_state_t arr_state[8] __devinitdata = { |
222 | {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, | 222 | {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, |
223 | {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL} | 223 | {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL} |
224 | }; | 224 | }; |
225 | 225 | ||
226 | static unsigned char ccr_state[7] __initdata = { 0, 0, 0, 0, 0, 0, 0 }; | 226 | static unsigned char ccr_state[7] __devinitdata = { 0, 0, 0, 0, 0, 0, 0 }; |
227 | 227 | ||
228 | static void cyrix_set_all(void) | 228 | static void cyrix_set_all(void) |
229 | { | 229 | { |
diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c index 14ec354bec92..903190a4b3ff 100644 --- a/arch/i386/kernel/i386_ksyms.c +++ b/arch/i386/kernel/i386_ksyms.c | |||
@@ -169,10 +169,6 @@ EXPORT_SYMBOL(rtc_lock); | |||
169 | EXPORT_SYMBOL_GPL(set_nmi_callback); | 169 | EXPORT_SYMBOL_GPL(set_nmi_callback); |
170 | EXPORT_SYMBOL_GPL(unset_nmi_callback); | 170 | EXPORT_SYMBOL_GPL(unset_nmi_callback); |
171 | 171 | ||
172 | #undef memcmp | ||
173 | extern int memcmp(const void *,const void *,__kernel_size_t); | ||
174 | EXPORT_SYMBOL(memcmp); | ||
175 | |||
176 | EXPORT_SYMBOL(register_die_notifier); | 172 | EXPORT_SYMBOL(register_die_notifier); |
177 | #ifdef CONFIG_HAVE_DEC_LOCK | 173 | #ifdef CONFIG_HAVE_DEC_LOCK |
178 | EXPORT_SYMBOL(_atomic_dec_and_lock); | 174 | EXPORT_SYMBOL(_atomic_dec_and_lock); |
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c index 671681659243..59ff9b455069 100644 --- a/arch/i386/kernel/kprobes.c +++ b/arch/i386/kernel/kprobes.c | |||
@@ -217,6 +217,13 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs) | |||
217 | *tos &= ~(TF_MASK | IF_MASK); | 217 | *tos &= ~(TF_MASK | IF_MASK); |
218 | *tos |= kprobe_old_eflags; | 218 | *tos |= kprobe_old_eflags; |
219 | break; | 219 | break; |
220 | case 0xc3: /* ret/lret */ | ||
221 | case 0xcb: | ||
222 | case 0xc2: | ||
223 | case 0xca: | ||
224 | regs->eflags &= ~TF_MASK; | ||
225 | /* eip is already adjusted, no more changes required*/ | ||
226 | return; | ||
220 | case 0xe8: /* call relative - Fix return addr */ | 227 | case 0xe8: /* call relative - Fix return addr */ |
221 | *tos = orig_eip + (*tos - copy_eip); | 228 | *tos = orig_eip + (*tos - copy_eip); |
222 | break; | 229 | break; |
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 85bd56d44314..96e3ea6b17c7 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c | |||
@@ -400,11 +400,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, | |||
400 | int err; | 400 | int err; |
401 | 401 | ||
402 | childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1; | 402 | childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1; |
403 | *childregs = *regs; | ||
404 | childregs->eax = 0; | ||
405 | childregs->esp = esp; | ||
406 | |||
407 | p->thread.esp = (unsigned long) childregs; | ||
408 | /* | 403 | /* |
409 | * The below -8 is to reserve 8 bytes on top of the ring0 stack. | 404 | * The below -8 is to reserve 8 bytes on top of the ring0 stack. |
410 | * This is necessary to guarantee that the entire "struct pt_regs" | 405 | * This is necessary to guarantee that the entire "struct pt_regs" |
@@ -415,7 +410,13 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, | |||
415 | * "struct pt_regs" is possible, but they may contain the | 410 | * "struct pt_regs" is possible, but they may contain the |
416 | * completely wrong values. | 411 | * completely wrong values. |
417 | */ | 412 | */ |
418 | p->thread.esp0 = (unsigned long) (childregs+1) - 8; | 413 | childregs = (struct pt_regs *) ((unsigned long) childregs - 8); |
414 | *childregs = *regs; | ||
415 | childregs->eax = 0; | ||
416 | childregs->esp = esp; | ||
417 | |||
418 | p->thread.esp = (unsigned long) childregs; | ||
419 | p->thread.esp0 = (unsigned long) (childregs+1); | ||
419 | 420 | ||
420 | p->thread.eip = (unsigned long) ret_from_fork; | 421 | p->thread.eip = (unsigned long) ret_from_fork; |
421 | 422 | ||
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c index e8c965ce86eb..e34f651fa13c 100644 --- a/arch/i386/kernel/ptrace.c +++ b/arch/i386/kernel/ptrace.c | |||
@@ -683,24 +683,18 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit) | |||
683 | /* do the secure computing check first */ | 683 | /* do the secure computing check first */ |
684 | secure_computing(regs->orig_eax); | 684 | secure_computing(regs->orig_eax); |
685 | 685 | ||
686 | if (unlikely(current->audit_context)) { | 686 | if (unlikely(current->audit_context) && entryexit) |
687 | if (!entryexit) | 687 | audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax); |
688 | audit_syscall_entry(current, regs->orig_eax, | ||
689 | regs->ebx, regs->ecx, | ||
690 | regs->edx, regs->esi); | ||
691 | else | ||
692 | audit_syscall_exit(current, regs->eax); | ||
693 | } | ||
694 | 688 | ||
695 | if (!(current->ptrace & PT_PTRACED)) | 689 | if (!(current->ptrace & PT_PTRACED)) |
696 | return; | 690 | goto out; |
697 | 691 | ||
698 | /* Fake a debug trap */ | 692 | /* Fake a debug trap */ |
699 | if (test_thread_flag(TIF_SINGLESTEP)) | 693 | if (test_thread_flag(TIF_SINGLESTEP)) |
700 | send_sigtrap(current, regs, 0); | 694 | send_sigtrap(current, regs, 0); |
701 | 695 | ||
702 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) | 696 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) |
703 | return; | 697 | goto out; |
704 | 698 | ||
705 | /* the 0x80 provides a way for the tracing parent to distinguish | 699 | /* the 0x80 provides a way for the tracing parent to distinguish |
706 | between a syscall stop and SIGTRAP delivery */ | 700 | between a syscall stop and SIGTRAP delivery */ |
@@ -715,4 +709,9 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit) | |||
715 | send_sig(current->exit_code, current, 1); | 709 | send_sig(current->exit_code, current, 1); |
716 | current->exit_code = 0; | 710 | current->exit_code = 0; |
717 | } | 711 | } |
712 | out: | ||
713 | if (unlikely(current->audit_context) && !entryexit) | ||
714 | audit_syscall_entry(current, AUDIT_ARCH_I386, regs->orig_eax, | ||
715 | regs->ebx, regs->ecx, regs->edx, regs->esi); | ||
716 | |||
718 | } | 717 | } |
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 945ec73163c8..2bfbddebdbf8 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c | |||
@@ -1502,11 +1502,13 @@ void __init setup_arch(char **cmdline_p) | |||
1502 | if (efi_enabled) | 1502 | if (efi_enabled) |
1503 | efi_map_memmap(); | 1503 | efi_map_memmap(); |
1504 | 1504 | ||
1505 | #ifdef CONFIG_ACPI_BOOT | ||
1505 | /* | 1506 | /* |
1506 | * Parse the ACPI tables for possible boot-time SMP configuration. | 1507 | * Parse the ACPI tables for possible boot-time SMP configuration. |
1507 | */ | 1508 | */ |
1508 | acpi_boot_table_init(); | 1509 | acpi_boot_table_init(); |
1509 | acpi_boot_init(); | 1510 | acpi_boot_init(); |
1511 | #endif | ||
1510 | 1512 | ||
1511 | #ifdef CONFIG_X86_LOCAL_APIC | 1513 | #ifdef CONFIG_X86_LOCAL_APIC |
1512 | if (smp_found_config) | 1514 | if (smp_found_config) |
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index cbea7ac582e5..bc1bb6919e6a 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c | |||
@@ -888,6 +888,7 @@ void *xquad_portio; | |||
888 | 888 | ||
889 | cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; | 889 | cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; |
890 | cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; | 890 | cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; |
891 | EXPORT_SYMBOL(cpu_core_map); | ||
891 | 892 | ||
892 | static void __init smp_boot_cpus(unsigned int max_cpus) | 893 | static void __init smp_boot_cpus(unsigned int max_cpus) |
893 | { | 894 | { |
@@ -1073,8 +1074,10 @@ static void __init smp_boot_cpus(unsigned int max_cpus) | |||
1073 | cpu_set(cpu, cpu_sibling_map[cpu]); | 1074 | cpu_set(cpu, cpu_sibling_map[cpu]); |
1074 | } | 1075 | } |
1075 | 1076 | ||
1076 | if (siblings != smp_num_siblings) | 1077 | if (siblings != smp_num_siblings) { |
1077 | printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings); | 1078 | printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings); |
1079 | smp_num_siblings = siblings; | ||
1080 | } | ||
1078 | 1081 | ||
1079 | if (c->x86_num_cores > 1) { | 1082 | if (c->x86_num_cores > 1) { |
1080 | for (i = 0; i < NR_CPUS; i++) { | 1083 | for (i = 0; i < NR_CPUS; i++) { |
diff --git a/arch/i386/kernel/timers/common.c b/arch/i386/kernel/timers/common.c index f7f90005e22e..8e201219f525 100644 --- a/arch/i386/kernel/timers/common.c +++ b/arch/i386/kernel/timers/common.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/timex.h> | 6 | #include <linux/timex.h> |
7 | #include <linux/errno.h> | 7 | #include <linux/errno.h> |
8 | #include <linux/jiffies.h> | 8 | #include <linux/jiffies.h> |
9 | #include <linux/module.h> | ||
9 | 10 | ||
10 | #include <asm/io.h> | 11 | #include <asm/io.h> |
11 | #include <asm/timer.h> | 12 | #include <asm/timer.h> |
@@ -24,7 +25,7 @@ | |||
24 | 25 | ||
25 | #define CALIBRATE_TIME (5 * 1000020/HZ) | 26 | #define CALIBRATE_TIME (5 * 1000020/HZ) |
26 | 27 | ||
27 | unsigned long __init calibrate_tsc(void) | 28 | unsigned long calibrate_tsc(void) |
28 | { | 29 | { |
29 | mach_prepare_counter(); | 30 | mach_prepare_counter(); |
30 | 31 | ||
@@ -139,7 +140,7 @@ bad_calibration: | |||
139 | #endif | 140 | #endif |
140 | 141 | ||
141 | /* calculate cpu_khz */ | 142 | /* calculate cpu_khz */ |
142 | void __init init_cpu_khz(void) | 143 | void init_cpu_khz(void) |
143 | { | 144 | { |
144 | if (cpu_has_tsc) { | 145 | if (cpu_has_tsc) { |
145 | unsigned long tsc_quotient = calibrate_tsc(); | 146 | unsigned long tsc_quotient = calibrate_tsc(); |
@@ -158,3 +159,4 @@ void __init init_cpu_khz(void) | |||
158 | } | 159 | } |
159 | } | 160 | } |
160 | } | 161 | } |
162 | |||
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c index 7926d967be00..180444d87824 100644 --- a/arch/i386/kernel/timers/timer_tsc.c +++ b/arch/i386/kernel/timers/timer_tsc.c | |||
@@ -320,6 +320,26 @@ core_initcall(cpufreq_tsc); | |||
320 | static inline void cpufreq_delayed_get(void) { return; } | 320 | static inline void cpufreq_delayed_get(void) { return; } |
321 | #endif | 321 | #endif |
322 | 322 | ||
323 | int recalibrate_cpu_khz(void) | ||
324 | { | ||
325 | #ifndef CONFIG_SMP | ||
326 | unsigned long cpu_khz_old = cpu_khz; | ||
327 | |||
328 | if (cpu_has_tsc) { | ||
329 | init_cpu_khz(); | ||
330 | cpu_data[0].loops_per_jiffy = | ||
331 | cpufreq_scale(cpu_data[0].loops_per_jiffy, | ||
332 | cpu_khz_old, | ||
333 | cpu_khz); | ||
334 | return 0; | ||
335 | } else | ||
336 | return -ENODEV; | ||
337 | #else | ||
338 | return -ENODEV; | ||
339 | #endif | ||
340 | } | ||
341 | EXPORT_SYMBOL(recalibrate_cpu_khz); | ||
342 | |||
323 | static void mark_offset_tsc(void) | 343 | static void mark_offset_tsc(void) |
324 | { | 344 | { |
325 | unsigned long lost,delay; | 345 | unsigned long lost,delay; |
diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c index 903d739ca74a..a6e0ddd65bd0 100644 --- a/arch/i386/mach-voyager/voyager_smp.c +++ b/arch/i386/mach-voyager/voyager_smp.c | |||
@@ -97,7 +97,6 @@ static void ack_vic_irq(unsigned int irq); | |||
97 | static void vic_enable_cpi(void); | 97 | static void vic_enable_cpi(void); |
98 | static void do_boot_cpu(__u8 cpuid); | 98 | static void do_boot_cpu(__u8 cpuid); |
99 | static void do_quad_bootstrap(void); | 99 | static void do_quad_bootstrap(void); |
100 | static inline void wrapper_smp_local_timer_interrupt(struct pt_regs *); | ||
101 | 100 | ||
102 | int hard_smp_processor_id(void); | 101 | int hard_smp_processor_id(void); |
103 | 102 | ||
@@ -126,6 +125,14 @@ send_QIC_CPI(__u32 cpuset, __u8 cpi) | |||
126 | } | 125 | } |
127 | 126 | ||
128 | static inline void | 127 | static inline void |
128 | wrapper_smp_local_timer_interrupt(struct pt_regs *regs) | ||
129 | { | ||
130 | irq_enter(); | ||
131 | smp_local_timer_interrupt(regs); | ||
132 | irq_exit(); | ||
133 | } | ||
134 | |||
135 | static inline void | ||
129 | send_one_CPI(__u8 cpu, __u8 cpi) | 136 | send_one_CPI(__u8 cpu, __u8 cpi) |
130 | { | 137 | { |
131 | if(voyager_quad_processors & (1<<cpu)) | 138 | if(voyager_quad_processors & (1<<cpu)) |
@@ -1249,14 +1256,6 @@ smp_vic_timer_interrupt(struct pt_regs *regs) | |||
1249 | smp_local_timer_interrupt(regs); | 1256 | smp_local_timer_interrupt(regs); |
1250 | } | 1257 | } |
1251 | 1258 | ||
1252 | static inline void | ||
1253 | wrapper_smp_local_timer_interrupt(struct pt_regs *regs) | ||
1254 | { | ||
1255 | irq_enter(); | ||
1256 | smp_local_timer_interrupt(regs); | ||
1257 | irq_exit(); | ||
1258 | } | ||
1259 | |||
1260 | /* local (per CPU) timer interrupt. It does both profiling and | 1259 | /* local (per CPU) timer interrupt. It does both profiling and |
1261 | * process statistics/rescheduling. | 1260 | * process statistics/rescheduling. |
1262 | * | 1261 | * |
diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c index db06f7399913..ab542792b27b 100644 --- a/arch/i386/mm/ioremap.c +++ b/arch/i386/mm/ioremap.c | |||
@@ -238,19 +238,21 @@ void iounmap(volatile void __iomem *addr) | |||
238 | addr < phys_to_virt(ISA_END_ADDRESS)) | 238 | addr < phys_to_virt(ISA_END_ADDRESS)) |
239 | return; | 239 | return; |
240 | 240 | ||
241 | p = remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr)); | 241 | write_lock(&vmlist_lock); |
242 | p = __remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr)); | ||
242 | if (!p) { | 243 | if (!p) { |
243 | printk("__iounmap: bad address %p\n", addr); | 244 | printk("iounmap: bad address %p\n", addr); |
244 | return; | 245 | goto out_unlock; |
245 | } | 246 | } |
246 | 247 | ||
247 | if ((p->flags >> 20) && p->phys_addr < virt_to_phys(high_memory) - 1) { | 248 | if ((p->flags >> 20) && p->phys_addr < virt_to_phys(high_memory) - 1) { |
248 | /* p->size includes the guard page, but cpa doesn't like that */ | ||
249 | change_page_attr(virt_to_page(__va(p->phys_addr)), | 249 | change_page_attr(virt_to_page(__va(p->phys_addr)), |
250 | p->size >> PAGE_SHIFT, | 250 | p->size >> PAGE_SHIFT, |
251 | PAGE_KERNEL); | 251 | PAGE_KERNEL); |
252 | global_flush_tlb(); | 252 | global_flush_tlb(); |
253 | } | 253 | } |
254 | out_unlock: | ||
255 | write_unlock(&vmlist_lock); | ||
254 | kfree(p); | 256 | kfree(p); |
255 | } | 257 | } |
256 | 258 | ||
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c index be52c5ac4e05..8e8e895e1b5a 100644 --- a/arch/i386/pci/fixup.c +++ b/arch/i386/pci/fixup.c | |||
@@ -253,7 +253,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci | |||
253 | #define MAX_PCIEROOT 6 | 253 | #define MAX_PCIEROOT 6 |
254 | static int quirk_aspm_offset[MAX_PCIEROOT << 3]; | 254 | static int quirk_aspm_offset[MAX_PCIEROOT << 3]; |
255 | 255 | ||
256 | #define GET_INDEX(a, b) (((a - PCI_DEVICE_ID_INTEL_MCH_PA) << 3) + b) | 256 | #define GET_INDEX(a, b) ((((a) - PCI_DEVICE_ID_INTEL_MCH_PA) << 3) + ((b) & 7)) |
257 | 257 | ||
258 | static int quirk_pcie_aspm_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) | 258 | static int quirk_pcie_aspm_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) |
259 | { | 259 | { |
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index d6598da4b67b..da21b1d07c15 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c | |||
@@ -1029,7 +1029,6 @@ void pcibios_penalize_isa_irq(int irq) | |||
1029 | static int pirq_enable_irq(struct pci_dev *dev) | 1029 | static int pirq_enable_irq(struct pci_dev *dev) |
1030 | { | 1030 | { |
1031 | u8 pin; | 1031 | u8 pin; |
1032 | extern int via_interrupt_line_quirk; | ||
1033 | struct pci_dev *temp_dev; | 1032 | struct pci_dev *temp_dev; |
1034 | 1033 | ||
1035 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); | 1034 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); |
@@ -1084,10 +1083,6 @@ static int pirq_enable_irq(struct pci_dev *dev) | |||
1084 | printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n", | 1083 | printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n", |
1085 | 'A' + pin, pci_name(dev), msg); | 1084 | 'A' + pin, pci_name(dev), msg); |
1086 | } | 1085 | } |
1087 | /* VIA bridges use interrupt line for apic/pci steering across | ||
1088 | the V-Link */ | ||
1089 | else if (via_interrupt_line_quirk) | ||
1090 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq & 15); | ||
1091 | return 0; | 1086 | return 0; |
1092 | } | 1087 | } |
1093 | 1088 | ||
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 468dbe8a6b9c..3ad2c4af099c 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
@@ -46,6 +46,10 @@ config GENERIC_IOMAP | |||
46 | bool | 46 | bool |
47 | default y | 47 | default y |
48 | 48 | ||
49 | config SCHED_NO_NO_OMIT_FRAME_POINTER | ||
50 | bool | ||
51 | default y | ||
52 | |||
49 | choice | 53 | choice |
50 | prompt "System type" | 54 | prompt "System type" |
51 | default IA64_GENERIC | 55 | default IA64_GENERIC |
@@ -217,6 +221,16 @@ config IA64_SGI_SN_SIM | |||
217 | If you are compiling a kernel that will run under SGI's IA-64 | 221 | If you are compiling a kernel that will run under SGI's IA-64 |
218 | simulator (Medusa) then say Y, otherwise say N. | 222 | simulator (Medusa) then say Y, otherwise say N. |
219 | 223 | ||
224 | config IA64_SGI_SN_XP | ||
225 | tristate "Support communication between SGI SSIs" | ||
226 | depends on MSPEC | ||
227 | help | ||
228 | An SGI machine can be divided into multiple Single System | ||
229 | Images which act independently of each other and have | ||
230 | hardware based memory protection from the others. Enabling | ||
231 | this feature will allow for direct communication between SSIs | ||
232 | based on a network adapter and DMA messaging. | ||
233 | |||
220 | config FORCE_MAX_ZONEORDER | 234 | config FORCE_MAX_ZONEORDER |
221 | int | 235 | int |
222 | default "18" | 236 | default "18" |
@@ -261,6 +275,15 @@ config HOTPLUG_CPU | |||
261 | can be controlled through /sys/devices/system/cpu/cpu#. | 275 | can be controlled through /sys/devices/system/cpu/cpu#. |
262 | Say N if you want to disable CPU hotplug. | 276 | Say N if you want to disable CPU hotplug. |
263 | 277 | ||
278 | config SCHED_SMT | ||
279 | bool "SMT scheduler support" | ||
280 | depends on SMP | ||
281 | default off | ||
282 | help | ||
283 | Improves the CPU scheduler's decision making when dealing with | ||
284 | Intel IA64 chips with MultiThreading at a cost of slightly increased | ||
285 | overhead in some places. If unsure say N here. | ||
286 | |||
264 | config PREEMPT | 287 | config PREEMPT |
265 | bool "Preemptible Kernel" | 288 | bool "Preemptible Kernel" |
266 | help | 289 | help |
diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig index 99830e8fc9ba..9086b789f6ac 100644 --- a/arch/ia64/configs/tiger_defconfig +++ b/arch/ia64/configs/tiger_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.11-rc2 | 3 | # Linux kernel version: 2.6.12-rc3 |
4 | # Sat Jan 22 11:17:02 2005 | 4 | # Tue May 3 15:55:04 2005 |
5 | # | 5 | # |
6 | 6 | ||
7 | # | 7 | # |
@@ -10,6 +10,7 @@ | |||
10 | CONFIG_EXPERIMENTAL=y | 10 | CONFIG_EXPERIMENTAL=y |
11 | CONFIG_CLEAN_COMPILE=y | 11 | CONFIG_CLEAN_COMPILE=y |
12 | CONFIG_LOCK_KERNEL=y | 12 | CONFIG_LOCK_KERNEL=y |
13 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
13 | 14 | ||
14 | # | 15 | # |
15 | # General setup | 16 | # General setup |
@@ -21,24 +22,27 @@ CONFIG_POSIX_MQUEUE=y | |||
21 | # CONFIG_BSD_PROCESS_ACCT is not set | 22 | # CONFIG_BSD_PROCESS_ACCT is not set |
22 | CONFIG_SYSCTL=y | 23 | CONFIG_SYSCTL=y |
23 | # CONFIG_AUDIT is not set | 24 | # CONFIG_AUDIT is not set |
24 | CONFIG_LOG_BUF_SHIFT=20 | ||
25 | CONFIG_HOTPLUG=y | 25 | CONFIG_HOTPLUG=y |
26 | CONFIG_KOBJECT_UEVENT=y | 26 | CONFIG_KOBJECT_UEVENT=y |
27 | CONFIG_IKCONFIG=y | 27 | CONFIG_IKCONFIG=y |
28 | CONFIG_IKCONFIG_PROC=y | 28 | CONFIG_IKCONFIG_PROC=y |
29 | # CONFIG_CPUSETS is not set | ||
29 | # CONFIG_EMBEDDED is not set | 30 | # CONFIG_EMBEDDED is not set |
30 | CONFIG_KALLSYMS=y | 31 | CONFIG_KALLSYMS=y |
31 | CONFIG_KALLSYMS_ALL=y | 32 | CONFIG_KALLSYMS_ALL=y |
32 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 33 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
34 | CONFIG_PRINTK=y | ||
35 | CONFIG_BUG=y | ||
36 | CONFIG_BASE_FULL=y | ||
33 | CONFIG_FUTEX=y | 37 | CONFIG_FUTEX=y |
34 | CONFIG_EPOLL=y | 38 | CONFIG_EPOLL=y |
35 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
36 | CONFIG_SHMEM=y | 39 | CONFIG_SHMEM=y |
37 | CONFIG_CC_ALIGN_FUNCTIONS=0 | 40 | CONFIG_CC_ALIGN_FUNCTIONS=0 |
38 | CONFIG_CC_ALIGN_LABELS=0 | 41 | CONFIG_CC_ALIGN_LABELS=0 |
39 | CONFIG_CC_ALIGN_LOOPS=0 | 42 | CONFIG_CC_ALIGN_LOOPS=0 |
40 | CONFIG_CC_ALIGN_JUMPS=0 | 43 | CONFIG_CC_ALIGN_JUMPS=0 |
41 | # CONFIG_TINY_SHMEM is not set | 44 | # CONFIG_TINY_SHMEM is not set |
45 | CONFIG_BASE_SMALL=0 | ||
42 | 46 | ||
43 | # | 47 | # |
44 | # Loadable module support | 48 | # Loadable module support |
@@ -85,6 +89,7 @@ CONFIG_FORCE_MAX_ZONEORDER=18 | |||
85 | CONFIG_SMP=y | 89 | CONFIG_SMP=y |
86 | CONFIG_NR_CPUS=4 | 90 | CONFIG_NR_CPUS=4 |
87 | CONFIG_HOTPLUG_CPU=y | 91 | CONFIG_HOTPLUG_CPU=y |
92 | # CONFIG_SCHED_SMT is not set | ||
88 | # CONFIG_PREEMPT is not set | 93 | # CONFIG_PREEMPT is not set |
89 | CONFIG_HAVE_DEC_LOCK=y | 94 | CONFIG_HAVE_DEC_LOCK=y |
90 | CONFIG_IA32_SUPPORT=y | 95 | CONFIG_IA32_SUPPORT=y |
@@ -135,6 +140,7 @@ CONFIG_PCI_DOMAINS=y | |||
135 | # CONFIG_PCI_MSI is not set | 140 | # CONFIG_PCI_MSI is not set |
136 | CONFIG_PCI_LEGACY_PROC=y | 141 | CONFIG_PCI_LEGACY_PROC=y |
137 | CONFIG_PCI_NAMES=y | 142 | CONFIG_PCI_NAMES=y |
143 | # CONFIG_PCI_DEBUG is not set | ||
138 | 144 | ||
139 | # | 145 | # |
140 | # PCI Hotplug Support | 146 | # PCI Hotplug Support |
@@ -152,10 +158,6 @@ CONFIG_HOTPLUG_PCI_ACPI=m | |||
152 | # CONFIG_PCCARD is not set | 158 | # CONFIG_PCCARD is not set |
153 | 159 | ||
154 | # | 160 | # |
155 | # PC-card bridges | ||
156 | # | ||
157 | |||
158 | # | ||
159 | # Device Drivers | 161 | # Device Drivers |
160 | # | 162 | # |
161 | 163 | ||
@@ -195,9 +197,10 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m | |||
195 | CONFIG_BLK_DEV_NBD=m | 197 | CONFIG_BLK_DEV_NBD=m |
196 | # CONFIG_BLK_DEV_SX8 is not set | 198 | # CONFIG_BLK_DEV_SX8 is not set |
197 | # CONFIG_BLK_DEV_UB is not set | 199 | # CONFIG_BLK_DEV_UB is not set |
198 | CONFIG_BLK_DEV_RAM=m | 200 | CONFIG_BLK_DEV_RAM=y |
199 | CONFIG_BLK_DEV_RAM_COUNT=16 | 201 | CONFIG_BLK_DEV_RAM_COUNT=16 |
200 | CONFIG_BLK_DEV_RAM_SIZE=4096 | 202 | CONFIG_BLK_DEV_RAM_SIZE=4096 |
203 | CONFIG_BLK_DEV_INITRD=y | ||
201 | CONFIG_INITRAMFS_SOURCE="" | 204 | CONFIG_INITRAMFS_SOURCE="" |
202 | # CONFIG_CDROM_PKTCDVD is not set | 205 | # CONFIG_CDROM_PKTCDVD is not set |
203 | 206 | ||
@@ -313,7 +316,6 @@ CONFIG_SCSI_FC_ATTRS=y | |||
313 | # CONFIG_SCSI_BUSLOGIC is not set | 316 | # CONFIG_SCSI_BUSLOGIC is not set |
314 | # CONFIG_SCSI_DMX3191D is not set | 317 | # CONFIG_SCSI_DMX3191D is not set |
315 | # CONFIG_SCSI_EATA is not set | 318 | # CONFIG_SCSI_EATA is not set |
316 | # CONFIG_SCSI_EATA_PIO is not set | ||
317 | # CONFIG_SCSI_FUTURE_DOMAIN is not set | 319 | # CONFIG_SCSI_FUTURE_DOMAIN is not set |
318 | # CONFIG_SCSI_GDTH is not set | 320 | # CONFIG_SCSI_GDTH is not set |
319 | # CONFIG_SCSI_IPS is not set | 321 | # CONFIG_SCSI_IPS is not set |
@@ -325,7 +327,6 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 | |||
325 | CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 | 327 | CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 |
326 | # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set | 328 | # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set |
327 | # CONFIG_SCSI_IPR is not set | 329 | # CONFIG_SCSI_IPR is not set |
328 | # CONFIG_SCSI_QLOGIC_ISP is not set | ||
329 | CONFIG_SCSI_QLOGIC_FC=y | 330 | CONFIG_SCSI_QLOGIC_FC=y |
330 | # CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set | 331 | # CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set |
331 | CONFIG_SCSI_QLOGIC_1280=y | 332 | CONFIG_SCSI_QLOGIC_1280=y |
@@ -336,6 +337,7 @@ CONFIG_SCSI_QLA22XX=m | |||
336 | CONFIG_SCSI_QLA2300=m | 337 | CONFIG_SCSI_QLA2300=m |
337 | CONFIG_SCSI_QLA2322=m | 338 | CONFIG_SCSI_QLA2322=m |
338 | # CONFIG_SCSI_QLA6312 is not set | 339 | # CONFIG_SCSI_QLA6312 is not set |
340 | # CONFIG_SCSI_LPFC is not set | ||
339 | # CONFIG_SCSI_DC395x is not set | 341 | # CONFIG_SCSI_DC395x is not set |
340 | # CONFIG_SCSI_DC390T is not set | 342 | # CONFIG_SCSI_DC390T is not set |
341 | # CONFIG_SCSI_DEBUG is not set | 343 | # CONFIG_SCSI_DEBUG is not set |
@@ -358,6 +360,7 @@ CONFIG_DM_CRYPT=m | |||
358 | CONFIG_DM_SNAPSHOT=m | 360 | CONFIG_DM_SNAPSHOT=m |
359 | CONFIG_DM_MIRROR=m | 361 | CONFIG_DM_MIRROR=m |
360 | CONFIG_DM_ZERO=m | 362 | CONFIG_DM_ZERO=m |
363 | # CONFIG_DM_MULTIPATH is not set | ||
361 | 364 | ||
362 | # | 365 | # |
363 | # Fusion MPT device support | 366 | # Fusion MPT device support |
@@ -386,7 +389,6 @@ CONFIG_NET=y | |||
386 | # | 389 | # |
387 | CONFIG_PACKET=y | 390 | CONFIG_PACKET=y |
388 | # CONFIG_PACKET_MMAP is not set | 391 | # CONFIG_PACKET_MMAP is not set |
389 | CONFIG_NETLINK_DEV=y | ||
390 | CONFIG_UNIX=y | 392 | CONFIG_UNIX=y |
391 | # CONFIG_NET_KEY is not set | 393 | # CONFIG_NET_KEY is not set |
392 | CONFIG_INET=y | 394 | CONFIG_INET=y |
@@ -446,7 +448,6 @@ CONFIG_DUMMY=m | |||
446 | # CONFIG_BONDING is not set | 448 | # CONFIG_BONDING is not set |
447 | # CONFIG_EQUALIZER is not set | 449 | # CONFIG_EQUALIZER is not set |
448 | # CONFIG_TUN is not set | 450 | # CONFIG_TUN is not set |
449 | # CONFIG_ETHERTAP is not set | ||
450 | 451 | ||
451 | # | 452 | # |
452 | # ARCnet devices | 453 | # ARCnet devices |
@@ -484,7 +485,6 @@ CONFIG_NET_PCI=y | |||
484 | # CONFIG_DGRS is not set | 485 | # CONFIG_DGRS is not set |
485 | CONFIG_EEPRO100=m | 486 | CONFIG_EEPRO100=m |
486 | CONFIG_E100=m | 487 | CONFIG_E100=m |
487 | # CONFIG_E100_NAPI is not set | ||
488 | # CONFIG_FEALNX is not set | 488 | # CONFIG_FEALNX is not set |
489 | # CONFIG_NATSEMI is not set | 489 | # CONFIG_NATSEMI is not set |
490 | # CONFIG_NE2K_PCI is not set | 490 | # CONFIG_NE2K_PCI is not set |
@@ -566,25 +566,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | |||
566 | # CONFIG_INPUT_EVBUG is not set | 566 | # CONFIG_INPUT_EVBUG is not set |
567 | 567 | ||
568 | # | 568 | # |
569 | # Input I/O drivers | ||
570 | # | ||
571 | CONFIG_GAMEPORT=m | ||
572 | CONFIG_SOUND_GAMEPORT=m | ||
573 | # CONFIG_GAMEPORT_NS558 is not set | ||
574 | # CONFIG_GAMEPORT_L4 is not set | ||
575 | # CONFIG_GAMEPORT_EMU10K1 is not set | ||
576 | # CONFIG_GAMEPORT_VORTEX is not set | ||
577 | # CONFIG_GAMEPORT_FM801 is not set | ||
578 | # CONFIG_GAMEPORT_CS461X is not set | ||
579 | CONFIG_SERIO=y | ||
580 | CONFIG_SERIO_I8042=y | ||
581 | # CONFIG_SERIO_SERPORT is not set | ||
582 | # CONFIG_SERIO_CT82C710 is not set | ||
583 | # CONFIG_SERIO_PCIPS2 is not set | ||
584 | CONFIG_SERIO_LIBPS2=y | ||
585 | # CONFIG_SERIO_RAW is not set | ||
586 | |||
587 | # | ||
588 | # Input Device Drivers | 569 | # Input Device Drivers |
589 | # | 570 | # |
590 | CONFIG_INPUT_KEYBOARD=y | 571 | CONFIG_INPUT_KEYBOARD=y |
@@ -602,6 +583,24 @@ CONFIG_MOUSE_PS2=y | |||
602 | # CONFIG_INPUT_MISC is not set | 583 | # CONFIG_INPUT_MISC is not set |
603 | 584 | ||
604 | # | 585 | # |
586 | # Hardware I/O ports | ||
587 | # | ||
588 | CONFIG_SERIO=y | ||
589 | CONFIG_SERIO_I8042=y | ||
590 | # CONFIG_SERIO_SERPORT is not set | ||
591 | # CONFIG_SERIO_PCIPS2 is not set | ||
592 | CONFIG_SERIO_LIBPS2=y | ||
593 | # CONFIG_SERIO_RAW is not set | ||
594 | CONFIG_GAMEPORT=m | ||
595 | # CONFIG_GAMEPORT_NS558 is not set | ||
596 | # CONFIG_GAMEPORT_L4 is not set | ||
597 | # CONFIG_GAMEPORT_EMU10K1 is not set | ||
598 | # CONFIG_GAMEPORT_VORTEX is not set | ||
599 | # CONFIG_GAMEPORT_FM801 is not set | ||
600 | # CONFIG_GAMEPORT_CS461X is not set | ||
601 | CONFIG_SOUND_GAMEPORT=m | ||
602 | |||
603 | # | ||
605 | # Character devices | 604 | # Character devices |
606 | # | 605 | # |
607 | CONFIG_VT=y | 606 | CONFIG_VT=y |
@@ -615,6 +614,8 @@ CONFIG_SERIAL_NONSTANDARD=y | |||
615 | # CONFIG_SYNCLINK is not set | 614 | # CONFIG_SYNCLINK is not set |
616 | # CONFIG_SYNCLINKMP is not set | 615 | # CONFIG_SYNCLINKMP is not set |
617 | # CONFIG_N_HDLC is not set | 616 | # CONFIG_N_HDLC is not set |
617 | # CONFIG_SPECIALIX is not set | ||
618 | # CONFIG_SX is not set | ||
618 | # CONFIG_STALDRV is not set | 619 | # CONFIG_STALDRV is not set |
619 | 620 | ||
620 | # | 621 | # |
@@ -635,6 +636,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y | |||
635 | # | 636 | # |
636 | CONFIG_SERIAL_CORE=y | 637 | CONFIG_SERIAL_CORE=y |
637 | CONFIG_SERIAL_CORE_CONSOLE=y | 638 | CONFIG_SERIAL_CORE_CONSOLE=y |
639 | # CONFIG_SERIAL_JSM is not set | ||
638 | CONFIG_UNIX98_PTYS=y | 640 | CONFIG_UNIX98_PTYS=y |
639 | CONFIG_LEGACY_PTYS=y | 641 | CONFIG_LEGACY_PTYS=y |
640 | CONFIG_LEGACY_PTY_COUNT=256 | 642 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -670,6 +672,12 @@ CONFIG_HPET=y | |||
670 | # CONFIG_HPET_RTC_IRQ is not set | 672 | # CONFIG_HPET_RTC_IRQ is not set |
671 | CONFIG_HPET_MMAP=y | 673 | CONFIG_HPET_MMAP=y |
672 | CONFIG_MAX_RAW_DEVS=256 | 674 | CONFIG_MAX_RAW_DEVS=256 |
675 | # CONFIG_HANGCHECK_TIMER is not set | ||
676 | |||
677 | # | ||
678 | # TPM devices | ||
679 | # | ||
680 | # CONFIG_TCG_TPM is not set | ||
673 | 681 | ||
674 | # | 682 | # |
675 | # I2C support | 683 | # I2C support |
@@ -705,7 +713,6 @@ CONFIG_MAX_RAW_DEVS=256 | |||
705 | # | 713 | # |
706 | CONFIG_VGA_CONSOLE=y | 714 | CONFIG_VGA_CONSOLE=y |
707 | CONFIG_DUMMY_CONSOLE=y | 715 | CONFIG_DUMMY_CONSOLE=y |
708 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | ||
709 | 716 | ||
710 | # | 717 | # |
711 | # Sound | 718 | # Sound |
@@ -715,6 +722,8 @@ CONFIG_DUMMY_CONSOLE=y | |||
715 | # | 722 | # |
716 | # USB support | 723 | # USB support |
717 | # | 724 | # |
725 | CONFIG_USB_ARCH_HAS_HCD=y | ||
726 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
718 | CONFIG_USB=y | 727 | CONFIG_USB=y |
719 | # CONFIG_USB_DEBUG is not set | 728 | # CONFIG_USB_DEBUG is not set |
720 | 729 | ||
@@ -726,8 +735,6 @@ CONFIG_USB_DEVICEFS=y | |||
726 | # CONFIG_USB_DYNAMIC_MINORS is not set | 735 | # CONFIG_USB_DYNAMIC_MINORS is not set |
727 | # CONFIG_USB_SUSPEND is not set | 736 | # CONFIG_USB_SUSPEND is not set |
728 | # CONFIG_USB_OTG is not set | 737 | # CONFIG_USB_OTG is not set |
729 | CONFIG_USB_ARCH_HAS_HCD=y | ||
730 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
731 | 738 | ||
732 | # | 739 | # |
733 | # USB Host Controller Drivers | 740 | # USB Host Controller Drivers |
@@ -736,6 +743,8 @@ CONFIG_USB_EHCI_HCD=m | |||
736 | # CONFIG_USB_EHCI_SPLIT_ISO is not set | 743 | # CONFIG_USB_EHCI_SPLIT_ISO is not set |
737 | # CONFIG_USB_EHCI_ROOT_HUB_TT is not set | 744 | # CONFIG_USB_EHCI_ROOT_HUB_TT is not set |
738 | CONFIG_USB_OHCI_HCD=m | 745 | CONFIG_USB_OHCI_HCD=m |
746 | # CONFIG_USB_OHCI_BIG_ENDIAN is not set | ||
747 | CONFIG_USB_OHCI_LITTLE_ENDIAN=y | ||
739 | CONFIG_USB_UHCI_HCD=y | 748 | CONFIG_USB_UHCI_HCD=y |
740 | # CONFIG_USB_SL811_HCD is not set | 749 | # CONFIG_USB_SL811_HCD is not set |
741 | 750 | ||
@@ -751,12 +760,11 @@ CONFIG_USB_UHCI_HCD=y | |||
751 | # | 760 | # |
752 | CONFIG_USB_STORAGE=m | 761 | CONFIG_USB_STORAGE=m |
753 | # CONFIG_USB_STORAGE_DEBUG is not set | 762 | # CONFIG_USB_STORAGE_DEBUG is not set |
754 | # CONFIG_USB_STORAGE_RW_DETECT is not set | ||
755 | # CONFIG_USB_STORAGE_DATAFAB is not set | 763 | # CONFIG_USB_STORAGE_DATAFAB is not set |
756 | # CONFIG_USB_STORAGE_FREECOM is not set | 764 | # CONFIG_USB_STORAGE_FREECOM is not set |
757 | # CONFIG_USB_STORAGE_ISD200 is not set | 765 | # CONFIG_USB_STORAGE_ISD200 is not set |
758 | # CONFIG_USB_STORAGE_DPCM is not set | 766 | # CONFIG_USB_STORAGE_DPCM is not set |
759 | # CONFIG_USB_STORAGE_HP8200e is not set | 767 | # CONFIG_USB_STORAGE_USBAT is not set |
760 | # CONFIG_USB_STORAGE_SDDR09 is not set | 768 | # CONFIG_USB_STORAGE_SDDR09 is not set |
761 | # CONFIG_USB_STORAGE_SDDR55 is not set | 769 | # CONFIG_USB_STORAGE_SDDR55 is not set |
762 | # CONFIG_USB_STORAGE_JUMPSHOT is not set | 770 | # CONFIG_USB_STORAGE_JUMPSHOT is not set |
@@ -800,6 +808,7 @@ CONFIG_USB_HIDINPUT=y | |||
800 | # CONFIG_USB_PEGASUS is not set | 808 | # CONFIG_USB_PEGASUS is not set |
801 | # CONFIG_USB_RTL8150 is not set | 809 | # CONFIG_USB_RTL8150 is not set |
802 | # CONFIG_USB_USBNET is not set | 810 | # CONFIG_USB_USBNET is not set |
811 | # CONFIG_USB_MON is not set | ||
803 | 812 | ||
804 | # | 813 | # |
805 | # USB port drivers | 814 | # USB port drivers |
@@ -824,6 +833,7 @@ CONFIG_USB_HIDINPUT=y | |||
824 | # CONFIG_USB_PHIDGETKIT is not set | 833 | # CONFIG_USB_PHIDGETKIT is not set |
825 | # CONFIG_USB_PHIDGETSERVO is not set | 834 | # CONFIG_USB_PHIDGETSERVO is not set |
826 | # CONFIG_USB_IDMOUSE is not set | 835 | # CONFIG_USB_IDMOUSE is not set |
836 | # CONFIG_USB_SISUSBVGA is not set | ||
827 | # CONFIG_USB_TEST is not set | 837 | # CONFIG_USB_TEST is not set |
828 | 838 | ||
829 | # | 839 | # |
@@ -867,7 +877,12 @@ CONFIG_REISERFS_FS_POSIX_ACL=y | |||
867 | CONFIG_REISERFS_FS_SECURITY=y | 877 | CONFIG_REISERFS_FS_SECURITY=y |
868 | # CONFIG_JFS_FS is not set | 878 | # CONFIG_JFS_FS is not set |
869 | CONFIG_FS_POSIX_ACL=y | 879 | CONFIG_FS_POSIX_ACL=y |
880 | |||
881 | # | ||
882 | # XFS support | ||
883 | # | ||
870 | CONFIG_XFS_FS=y | 884 | CONFIG_XFS_FS=y |
885 | CONFIG_XFS_EXPORT=y | ||
871 | # CONFIG_XFS_RT is not set | 886 | # CONFIG_XFS_RT is not set |
872 | # CONFIG_XFS_QUOTA is not set | 887 | # CONFIG_XFS_QUOTA is not set |
873 | # CONFIG_XFS_SECURITY is not set | 888 | # CONFIG_XFS_SECURITY is not set |
@@ -945,7 +960,7 @@ CONFIG_NFSD_V4=y | |||
945 | CONFIG_NFSD_TCP=y | 960 | CONFIG_NFSD_TCP=y |
946 | CONFIG_LOCKD=m | 961 | CONFIG_LOCKD=m |
947 | CONFIG_LOCKD_V4=y | 962 | CONFIG_LOCKD_V4=y |
948 | CONFIG_EXPORTFS=m | 963 | CONFIG_EXPORTFS=y |
949 | CONFIG_SUNRPC=m | 964 | CONFIG_SUNRPC=m |
950 | CONFIG_SUNRPC_GSS=m | 965 | CONFIG_SUNRPC_GSS=m |
951 | CONFIG_RPCSEC_GSS_KRB5=m | 966 | CONFIG_RPCSEC_GSS_KRB5=m |
@@ -1042,8 +1057,10 @@ CONFIG_GENERIC_IRQ_PROBE=y | |||
1042 | # | 1057 | # |
1043 | # Kernel hacking | 1058 | # Kernel hacking |
1044 | # | 1059 | # |
1060 | # CONFIG_PRINTK_TIME is not set | ||
1045 | CONFIG_DEBUG_KERNEL=y | 1061 | CONFIG_DEBUG_KERNEL=y |
1046 | CONFIG_MAGIC_SYSRQ=y | 1062 | CONFIG_MAGIC_SYSRQ=y |
1063 | CONFIG_LOG_BUF_SHIFT=20 | ||
1047 | # CONFIG_SCHEDSTATS is not set | 1064 | # CONFIG_SCHEDSTATS is not set |
1048 | # CONFIG_DEBUG_SLAB is not set | 1065 | # CONFIG_DEBUG_SLAB is not set |
1049 | # CONFIG_DEBUG_SPINLOCK is not set | 1066 | # CONFIG_DEBUG_SPINLOCK is not set |
@@ -1077,6 +1094,7 @@ CONFIG_CRYPTO_MD5=m | |||
1077 | # CONFIG_CRYPTO_SHA256 is not set | 1094 | # CONFIG_CRYPTO_SHA256 is not set |
1078 | # CONFIG_CRYPTO_SHA512 is not set | 1095 | # CONFIG_CRYPTO_SHA512 is not set |
1079 | # CONFIG_CRYPTO_WP512 is not set | 1096 | # CONFIG_CRYPTO_WP512 is not set |
1097 | # CONFIG_CRYPTO_TGR192 is not set | ||
1080 | CONFIG_CRYPTO_DES=m | 1098 | CONFIG_CRYPTO_DES=m |
1081 | # CONFIG_CRYPTO_BLOWFISH is not set | 1099 | # CONFIG_CRYPTO_BLOWFISH is not set |
1082 | # CONFIG_CRYPTO_TWOFISH is not set | 1100 | # CONFIG_CRYPTO_TWOFISH is not set |
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index 6a8fcba7a853..b8db6e3e5e81 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c | |||
@@ -1944,43 +1944,17 @@ sba_connect_bus(struct pci_bus *bus) | |||
1944 | static void __init | 1944 | static void __init |
1945 | sba_map_ioc_to_node(struct ioc *ioc, acpi_handle handle) | 1945 | sba_map_ioc_to_node(struct ioc *ioc, acpi_handle handle) |
1946 | { | 1946 | { |
1947 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
1948 | union acpi_object *obj; | ||
1949 | acpi_handle phandle; | ||
1950 | unsigned int node; | 1947 | unsigned int node; |
1948 | int pxm; | ||
1951 | 1949 | ||
1952 | ioc->node = MAX_NUMNODES; | 1950 | ioc->node = MAX_NUMNODES; |
1953 | 1951 | ||
1954 | /* | 1952 | pxm = acpi_get_pxm(handle); |
1955 | * Check for a _PXM on this node first. We don't typically see | ||
1956 | * one here, so we'll end up getting it from the parent. | ||
1957 | */ | ||
1958 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PXM", NULL, &buffer))) { | ||
1959 | if (ACPI_FAILURE(acpi_get_parent(handle, &phandle))) | ||
1960 | return; | ||
1961 | |||
1962 | /* Reset the acpi buffer */ | ||
1963 | buffer.length = ACPI_ALLOCATE_BUFFER; | ||
1964 | buffer.pointer = NULL; | ||
1965 | |||
1966 | if (ACPI_FAILURE(acpi_evaluate_object(phandle, "_PXM", NULL, | ||
1967 | &buffer))) | ||
1968 | return; | ||
1969 | } | ||
1970 | 1953 | ||
1971 | if (!buffer.length || !buffer.pointer) | 1954 | if (pxm < 0) |
1972 | return; | 1955 | return; |
1973 | 1956 | ||
1974 | obj = buffer.pointer; | 1957 | node = pxm_to_nid_map[pxm]; |
1975 | |||
1976 | if (obj->type != ACPI_TYPE_INTEGER || | ||
1977 | obj->integer.value >= MAX_PXM_DOMAINS) { | ||
1978 | acpi_os_free(buffer.pointer); | ||
1979 | return; | ||
1980 | } | ||
1981 | |||
1982 | node = pxm_to_nid_map[obj->integer.value]; | ||
1983 | acpi_os_free(buffer.pointer); | ||
1984 | 1958 | ||
1985 | if (node >= MAX_NUMNODES || !node_online(node)) | 1959 | if (node >= MAX_NUMNODES || !node_online(node)) |
1986 | return; | 1960 | return; |
diff --git a/arch/ia64/ia32/ia32_ioctl.c b/arch/ia64/ia32/ia32_ioctl.c index 9845dabe2613..164b211f4174 100644 --- a/arch/ia64/ia32/ia32_ioctl.c +++ b/arch/ia64/ia32/ia32_ioctl.c | |||
@@ -13,7 +13,6 @@ | |||
13 | 13 | ||
14 | #define INCLUDES | 14 | #define INCLUDES |
15 | #include "compat_ioctl.c" | 15 | #include "compat_ioctl.c" |
16 | #include <asm/ioctl32.h> | ||
17 | 16 | ||
18 | #define IOCTL_NR(a) ((a) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) | 17 | #define IOCTL_NR(a) ((a) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) |
19 | 18 | ||
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c index 247a21c64aea..c1e20d65dd6c 100644 --- a/arch/ia64/ia32/sys_ia32.c +++ b/arch/ia64/ia32/sys_ia32.c | |||
@@ -2427,7 +2427,7 @@ sys32_epoll_wait(int epfd, struct epoll_event32 __user * events, int maxevents, | |||
2427 | { | 2427 | { |
2428 | struct epoll_event *events64 = NULL; | 2428 | struct epoll_event *events64 = NULL; |
2429 | mm_segment_t old_fs = get_fs(); | 2429 | mm_segment_t old_fs = get_fs(); |
2430 | int error, numevents, size; | 2430 | int numevents, size; |
2431 | int evt_idx; | 2431 | int evt_idx; |
2432 | int do_free_pages = 0; | 2432 | int do_free_pages = 0; |
2433 | 2433 | ||
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index a8e99c56a768..72dfd9e7de0f 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c | |||
@@ -779,7 +779,7 @@ acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret) | |||
779 | union acpi_object *obj; | 779 | union acpi_object *obj; |
780 | struct acpi_table_iosapic *iosapic; | 780 | struct acpi_table_iosapic *iosapic; |
781 | unsigned int gsi_base; | 781 | unsigned int gsi_base; |
782 | int node; | 782 | int pxm, node; |
783 | 783 | ||
784 | /* Only care about objects w/ a method that returns the MADT */ | 784 | /* Only care about objects w/ a method that returns the MADT */ |
785 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) | 785 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) |
@@ -805,29 +805,16 @@ acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret) | |||
805 | gsi_base = iosapic->global_irq_base; | 805 | gsi_base = iosapic->global_irq_base; |
806 | 806 | ||
807 | acpi_os_free(buffer.pointer); | 807 | acpi_os_free(buffer.pointer); |
808 | buffer.length = ACPI_ALLOCATE_BUFFER; | ||
809 | buffer.pointer = NULL; | ||
810 | 808 | ||
811 | /* | 809 | /* |
812 | * OK, it's an IOSAPIC MADT entry, look for a _PXM method to tell | 810 | * OK, it's an IOSAPIC MADT entry, look for a _PXM value to tell |
813 | * us which node to associate this with. | 811 | * us which node to associate this with. |
814 | */ | 812 | */ |
815 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PXM", NULL, &buffer))) | 813 | pxm = acpi_get_pxm(handle); |
816 | return AE_OK; | 814 | if (pxm < 0) |
817 | |||
818 | if (!buffer.length || !buffer.pointer) | ||
819 | return AE_OK; | ||
820 | |||
821 | obj = buffer.pointer; | ||
822 | |||
823 | if (obj->type != ACPI_TYPE_INTEGER || | ||
824 | obj->integer.value >= MAX_PXM_DOMAINS) { | ||
825 | acpi_os_free(buffer.pointer); | ||
826 | return AE_OK; | 815 | return AE_OK; |
827 | } | ||
828 | 816 | ||
829 | node = pxm_to_nid_map[obj->integer.value]; | 817 | node = pxm_to_nid_map[pxm]; |
830 | acpi_os_free(buffer.pointer); | ||
831 | 818 | ||
832 | if (node >= MAX_NUMNODES || !node_online(node) || | 819 | if (node >= MAX_NUMNODES || !node_online(node) || |
833 | cpus_empty(node_to_cpumask(node))) | 820 | cpus_empty(node_to_cpumask(node))) |
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 9353adc18956..8ebfcc0c813a 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S | |||
@@ -777,7 +777,7 @@ GLOBAL_ENTRY(ia64_ret_from_ia32_execve) | |||
777 | st8.spill [r2]=r8 // store return value in slot for r8 and set unat bit | 777 | st8.spill [r2]=r8 // store return value in slot for r8 and set unat bit |
778 | .mem.offset 8,0 | 778 | .mem.offset 8,0 |
779 | st8.spill [r3]=r0 // clear error indication in slot for r10 and set unat bit | 779 | st8.spill [r3]=r0 // clear error indication in slot for r10 and set unat bit |
780 | END(ia64_ret_from_ia32_execve_syscall) | 780 | END(ia64_ret_from_ia32_execve) |
781 | // fall through | 781 | // fall through |
782 | #endif /* CONFIG_IA32_SUPPORT */ | 782 | #endif /* CONFIG_IA32_SUPPORT */ |
783 | GLOBAL_ENTRY(ia64_leave_kernel) | 783 | GLOBAL_ENTRY(ia64_leave_kernel) |
@@ -1176,7 +1176,7 @@ ENTRY(notify_resume_user) | |||
1176 | ;; | 1176 | ;; |
1177 | (pNonSys) mov out2=0 // out2==0 => not a syscall | 1177 | (pNonSys) mov out2=0 // out2==0 => not a syscall |
1178 | .fframe 16 | 1178 | .fframe 16 |
1179 | .spillpsp ar.unat, 16 // (note that offset is relative to psp+0x10!) | 1179 | .spillsp ar.unat, 16 |
1180 | st8 [sp]=r9,-16 // allocate space for ar.unat and save it | 1180 | st8 [sp]=r9,-16 // allocate space for ar.unat and save it |
1181 | st8 [out1]=loc1,-8 // save ar.pfs, out1=&sigscratch | 1181 | st8 [out1]=loc1,-8 // save ar.pfs, out1=&sigscratch |
1182 | .body | 1182 | .body |
@@ -1202,7 +1202,7 @@ GLOBAL_ENTRY(sys_rt_sigsuspend) | |||
1202 | adds out2=8,sp // out2=&sigscratch->ar_pfs | 1202 | adds out2=8,sp // out2=&sigscratch->ar_pfs |
1203 | ;; | 1203 | ;; |
1204 | .fframe 16 | 1204 | .fframe 16 |
1205 | .spillpsp ar.unat, 16 // (note that offset is relative to psp+0x10!) | 1205 | .spillsp ar.unat, 16 |
1206 | st8 [sp]=r9,-16 // allocate space for ar.unat and save it | 1206 | st8 [sp]=r9,-16 // allocate space for ar.unat and save it |
1207 | st8 [out2]=loc1,-8 // save ar.pfs, out2=&sigscratch | 1207 | st8 [out2]=loc1,-8 // save ar.pfs, out2=&sigscratch |
1208 | .body | 1208 | .body |
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index f566ff43a389..7d7684a369d3 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S | |||
@@ -460,9 +460,9 @@ EX(.fail_efault, ld8 r14=[r33]) // r14 <- *set | |||
460 | ;; | 460 | ;; |
461 | 461 | ||
462 | st8 [r2]=r14 // update current->blocked with new mask | 462 | st8 [r2]=r14 // update current->blocked with new mask |
463 | cmpxchg4.acq r14=[r9],r18,ar.ccv // current->thread_info->flags <- r18 | 463 | cmpxchg4.acq r8=[r9],r18,ar.ccv // current->thread_info->flags <- r18 |
464 | ;; | 464 | ;; |
465 | cmp.ne p6,p0=r17,r14 // update failed? | 465 | cmp.ne p6,p0=r17,r8 // update failed? |
466 | (p6) br.cond.spnt.few 1b // yes -> retry | 466 | (p6) br.cond.spnt.few 1b // yes -> retry |
467 | 467 | ||
468 | #ifdef CONFIG_SMP | 468 | #ifdef CONFIG_SMP |
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 4d6c7b8f667b..736e328b5e61 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c | |||
@@ -1103,8 +1103,6 @@ ia64_mca_cpe_int_caller(int cpe_irq, void *arg, struct pt_regs *ptregs) | |||
1103 | return IRQ_HANDLED; | 1103 | return IRQ_HANDLED; |
1104 | } | 1104 | } |
1105 | 1105 | ||
1106 | #endif /* CONFIG_ACPI */ | ||
1107 | |||
1108 | /* | 1106 | /* |
1109 | * ia64_mca_cpe_poll | 1107 | * ia64_mca_cpe_poll |
1110 | * | 1108 | * |
@@ -1122,6 +1120,8 @@ ia64_mca_cpe_poll (unsigned long dummy) | |||
1122 | platform_send_ipi(first_cpu(cpu_online_map), IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0); | 1120 | platform_send_ipi(first_cpu(cpu_online_map), IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0); |
1123 | } | 1121 | } |
1124 | 1122 | ||
1123 | #endif /* CONFIG_ACPI */ | ||
1124 | |||
1125 | /* | 1125 | /* |
1126 | * C portion of the OS INIT handler | 1126 | * C portion of the OS INIT handler |
1127 | * | 1127 | * |
@@ -1390,8 +1390,7 @@ ia64_mca_init(void) | |||
1390 | register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, &mca_wkup_irqaction); | 1390 | register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, &mca_wkup_irqaction); |
1391 | 1391 | ||
1392 | #ifdef CONFIG_ACPI | 1392 | #ifdef CONFIG_ACPI |
1393 | /* Setup the CPEI/P vector and handler */ | 1393 | /* Setup the CPEI/P handler */ |
1394 | cpe_vector = acpi_request_vector(ACPI_INTERRUPT_CPEI); | ||
1395 | register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction); | 1394 | register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction); |
1396 | #endif | 1395 | #endif |
1397 | 1396 | ||
@@ -1436,6 +1435,7 @@ ia64_mca_late_init(void) | |||
1436 | 1435 | ||
1437 | #ifdef CONFIG_ACPI | 1436 | #ifdef CONFIG_ACPI |
1438 | /* Setup the CPEI/P vector and handler */ | 1437 | /* Setup the CPEI/P vector and handler */ |
1438 | cpe_vector = acpi_request_vector(ACPI_INTERRUPT_CPEI); | ||
1439 | init_timer(&cpe_poll_timer); | 1439 | init_timer(&cpe_poll_timer); |
1440 | cpe_poll_timer.function = ia64_mca_cpe_poll; | 1440 | cpe_poll_timer.function = ia64_mca_cpe_poll; |
1441 | 1441 | ||
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c index ab478172c349..abc0113a821d 100644 --- a/arch/ia64/kernel/mca_drv.c +++ b/arch/ia64/kernel/mca_drv.c | |||
@@ -132,8 +132,7 @@ mca_handler_bh(unsigned long paddr) | |||
132 | spin_unlock(&mca_bh_lock); | 132 | spin_unlock(&mca_bh_lock); |
133 | 133 | ||
134 | /* This process is about to be killed itself */ | 134 | /* This process is about to be killed itself */ |
135 | force_sig(SIGKILL, current); | 135 | do_exit(SIGKILL); |
136 | schedule(); | ||
137 | } | 136 | } |
138 | 137 | ||
139 | /** | 138 | /** |
@@ -439,6 +438,7 @@ recover_from_read_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_chec | |||
439 | psr2 = (struct ia64_psr *)&pmsa->pmsa_ipsr; | 438 | psr2 = (struct ia64_psr *)&pmsa->pmsa_ipsr; |
440 | psr2->cpl = 0; | 439 | psr2->cpl = 0; |
441 | psr2->ri = 0; | 440 | psr2->ri = 0; |
441 | psr2->i = 0; | ||
442 | 442 | ||
443 | return 1; | 443 | return 1; |
444 | } | 444 | } |
diff --git a/arch/ia64/kernel/mca_drv_asm.S b/arch/ia64/kernel/mca_drv_asm.S index bcfa05acc561..2d7e0217638d 100644 --- a/arch/ia64/kernel/mca_drv_asm.S +++ b/arch/ia64/kernel/mca_drv_asm.S | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #include <asm/asmmacro.h> | 11 | #include <asm/asmmacro.h> |
12 | #include <asm/processor.h> | 12 | #include <asm/processor.h> |
13 | #include <asm/ptrace.h> | ||
13 | 14 | ||
14 | GLOBAL_ENTRY(mca_handler_bhhook) | 15 | GLOBAL_ENTRY(mca_handler_bhhook) |
15 | invala // clear RSE ? | 16 | invala // clear RSE ? |
@@ -20,12 +21,21 @@ GLOBAL_ENTRY(mca_handler_bhhook) | |||
20 | ;; | 21 | ;; |
21 | alloc r16=ar.pfs,0,2,1,0 // make a new frame | 22 | alloc r16=ar.pfs,0,2,1,0 // make a new frame |
22 | ;; | 23 | ;; |
24 | mov ar.rsc=0 | ||
25 | ;; | ||
23 | mov r13=IA64_KR(CURRENT) // current task pointer | 26 | mov r13=IA64_KR(CURRENT) // current task pointer |
24 | ;; | 27 | ;; |
25 | adds r12=IA64_TASK_THREAD_KSP_OFFSET,r13 | 28 | mov r2=r13 |
29 | ;; | ||
30 | addl r22=IA64_RBS_OFFSET,r2 | ||
31 | ;; | ||
32 | mov ar.bspstore=r22 | ||
26 | ;; | 33 | ;; |
27 | ld8 r12=[r12] // stack pointer | 34 | addl sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 |
28 | ;; | 35 | ;; |
36 | adds r2=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 | ||
37 | ;; | ||
38 | st1 [r2]=r0 // clear current->thread.on_ustack flag | ||
29 | mov loc0=r16 | 39 | mov loc0=r16 |
30 | movl loc1=mca_handler_bh // recovery C function | 40 | movl loc1=mca_handler_bh // recovery C function |
31 | ;; | 41 | ;; |
@@ -34,7 +44,9 @@ GLOBAL_ENTRY(mca_handler_bhhook) | |||
34 | ;; | 44 | ;; |
35 | mov loc1=rp | 45 | mov loc1=rp |
36 | ;; | 46 | ;; |
37 | br.call.sptk.many rp=b6 // not return ... | 47 | ssm psr.i |
48 | ;; | ||
49 | br.call.sptk.many rp=b6 // does not return ... | ||
38 | ;; | 50 | ;; |
39 | mov ar.pfs=loc0 | 51 | mov ar.pfs=loc0 |
40 | mov rp=loc1 | 52 | mov rp=loc1 |
diff --git a/arch/ia64/kernel/minstate.h b/arch/ia64/kernel/minstate.h index 1dbc7b2497c9..f6d8a010d99b 100644 --- a/arch/ia64/kernel/minstate.h +++ b/arch/ia64/kernel/minstate.h | |||
@@ -41,7 +41,7 @@ | |||
41 | (pKStk) addl r3=THIS_CPU(ia64_mca_data),r3;; \ | 41 | (pKStk) addl r3=THIS_CPU(ia64_mca_data),r3;; \ |
42 | (pKStk) ld8 r3 = [r3];; \ | 42 | (pKStk) ld8 r3 = [r3];; \ |
43 | (pKStk) addl r3=IA64_MCA_CPU_INIT_STACK_OFFSET,r3;; \ | 43 | (pKStk) addl r3=IA64_MCA_CPU_INIT_STACK_OFFSET,r3;; \ |
44 | (pKStk) addl sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3; \ | 44 | (pKStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3; \ |
45 | (pUStk) mov ar.rsc=0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \ | 45 | (pUStk) mov ar.rsc=0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \ |
46 | (pUStk) addl r22=IA64_RBS_OFFSET,r1; /* compute base of register backing store */ \ | 46 | (pUStk) addl r22=IA64_RBS_OFFSET,r1; /* compute base of register backing store */ \ |
47 | ;; \ | 47 | ;; \ |
@@ -50,7 +50,6 @@ | |||
50 | (pUStk) mov r23=ar.bspstore; /* save ar.bspstore */ \ | 50 | (pUStk) mov r23=ar.bspstore; /* save ar.bspstore */ \ |
51 | (pUStk) dep r22=-1,r22,61,3; /* compute kernel virtual addr of RBS */ \ | 51 | (pUStk) dep r22=-1,r22,61,3; /* compute kernel virtual addr of RBS */ \ |
52 | ;; \ | 52 | ;; \ |
53 | (pKStk) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode, use sp (r12) */ \ | ||
54 | (pUStk) mov ar.bspstore=r22; /* switch to kernel RBS */ \ | 53 | (pUStk) mov ar.bspstore=r22; /* switch to kernel RBS */ \ |
55 | ;; \ | 54 | ;; \ |
56 | (pUStk) mov r18=ar.bsp; \ | 55 | (pUStk) mov r18=ar.bsp; \ |
diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c index febc091c2f02..f1aca7cffd12 100644 --- a/arch/ia64/kernel/module.c +++ b/arch/ia64/kernel/module.c | |||
@@ -825,14 +825,16 @@ apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symind | |||
825 | * XXX Should have an arch-hook for running this after final section | 825 | * XXX Should have an arch-hook for running this after final section |
826 | * addresses have been selected... | 826 | * addresses have been selected... |
827 | */ | 827 | */ |
828 | /* See if gp can cover the entire core module: */ | 828 | uint64_t gp; |
829 | uint64_t gp = (uint64_t) mod->module_core + MAX_LTOFF / 2; | 829 | if (mod->core_size > MAX_LTOFF) |
830 | if (mod->core_size >= MAX_LTOFF) | ||
831 | /* | 830 | /* |
832 | * This takes advantage of fact that SHF_ARCH_SMALL gets allocated | 831 | * This takes advantage of fact that SHF_ARCH_SMALL gets allocated |
833 | * at the end of the module. | 832 | * at the end of the module. |
834 | */ | 833 | */ |
835 | gp = (uint64_t) mod->module_core + mod->core_size - MAX_LTOFF / 2; | 834 | gp = mod->core_size - MAX_LTOFF / 2; |
835 | else | ||
836 | gp = mod->core_size / 2; | ||
837 | gp = (uint64_t) mod->module_core + ((gp + 7) & -8); | ||
836 | mod->arch.gp = gp; | 838 | mod->arch.gp = gp; |
837 | DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp); | 839 | DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp); |
838 | } | 840 | } |
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 376fcbc3f8da..6407bff6bfd7 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c | |||
@@ -11,7 +11,7 @@ | |||
11 | * Version Perfmon-2.x is a rewrite of perfmon-1.x | 11 | * Version Perfmon-2.x is a rewrite of perfmon-1.x |
12 | * by Stephane Eranian, Hewlett Packard Co. | 12 | * by Stephane Eranian, Hewlett Packard Co. |
13 | * | 13 | * |
14 | * Copyright (C) 1999-2003, 2005 Hewlett Packard Co | 14 | * Copyright (C) 1999-2005 Hewlett Packard Co |
15 | * Stephane Eranian <eranian@hpl.hp.com> | 15 | * Stephane Eranian <eranian@hpl.hp.com> |
16 | * David Mosberger-Tang <davidm@hpl.hp.com> | 16 | * David Mosberger-Tang <davidm@hpl.hp.com> |
17 | * | 17 | * |
@@ -497,6 +497,9 @@ typedef struct { | |||
497 | static pfm_stats_t pfm_stats[NR_CPUS]; | 497 | static pfm_stats_t pfm_stats[NR_CPUS]; |
498 | static pfm_session_t pfm_sessions; /* global sessions information */ | 498 | static pfm_session_t pfm_sessions; /* global sessions information */ |
499 | 499 | ||
500 | static spinlock_t pfm_alt_install_check = SPIN_LOCK_UNLOCKED; | ||
501 | static pfm_intr_handler_desc_t *pfm_alt_intr_handler; | ||
502 | |||
500 | static struct proc_dir_entry *perfmon_dir; | 503 | static struct proc_dir_entry *perfmon_dir; |
501 | static pfm_uuid_t pfm_null_uuid = {0,}; | 504 | static pfm_uuid_t pfm_null_uuid = {0,}; |
502 | 505 | ||
@@ -606,6 +609,7 @@ DEFINE_PER_CPU(unsigned long, pfm_syst_info); | |||
606 | DEFINE_PER_CPU(struct task_struct *, pmu_owner); | 609 | DEFINE_PER_CPU(struct task_struct *, pmu_owner); |
607 | DEFINE_PER_CPU(pfm_context_t *, pmu_ctx); | 610 | DEFINE_PER_CPU(pfm_context_t *, pmu_ctx); |
608 | DEFINE_PER_CPU(unsigned long, pmu_activation_number); | 611 | DEFINE_PER_CPU(unsigned long, pmu_activation_number); |
612 | EXPORT_PER_CPU_SYMBOL_GPL(pfm_syst_info); | ||
609 | 613 | ||
610 | 614 | ||
611 | /* forward declaration */ | 615 | /* forward declaration */ |
@@ -1265,6 +1269,8 @@ out: | |||
1265 | } | 1269 | } |
1266 | EXPORT_SYMBOL(pfm_unregister_buffer_fmt); | 1270 | EXPORT_SYMBOL(pfm_unregister_buffer_fmt); |
1267 | 1271 | ||
1272 | extern void update_pal_halt_status(int); | ||
1273 | |||
1268 | static int | 1274 | static int |
1269 | pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu) | 1275 | pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu) |
1270 | { | 1276 | { |
@@ -1311,6 +1317,11 @@ pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu) | |||
1311 | is_syswide, | 1317 | is_syswide, |
1312 | cpu)); | 1318 | cpu)); |
1313 | 1319 | ||
1320 | /* | ||
1321 | * disable default_idle() to go to PAL_HALT | ||
1322 | */ | ||
1323 | update_pal_halt_status(0); | ||
1324 | |||
1314 | UNLOCK_PFS(flags); | 1325 | UNLOCK_PFS(flags); |
1315 | 1326 | ||
1316 | return 0; | 1327 | return 0; |
@@ -1318,7 +1329,7 @@ pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu) | |||
1318 | error_conflict: | 1329 | error_conflict: |
1319 | DPRINT(("system wide not possible, conflicting session [%d] on CPU%d\n", | 1330 | DPRINT(("system wide not possible, conflicting session [%d] on CPU%d\n", |
1320 | pfm_sessions.pfs_sys_session[cpu]->pid, | 1331 | pfm_sessions.pfs_sys_session[cpu]->pid, |
1321 | smp_processor_id())); | 1332 | cpu)); |
1322 | abort: | 1333 | abort: |
1323 | UNLOCK_PFS(flags); | 1334 | UNLOCK_PFS(flags); |
1324 | 1335 | ||
@@ -1366,6 +1377,12 @@ pfm_unreserve_session(pfm_context_t *ctx, int is_syswide, unsigned int cpu) | |||
1366 | is_syswide, | 1377 | is_syswide, |
1367 | cpu)); | 1378 | cpu)); |
1368 | 1379 | ||
1380 | /* | ||
1381 | * if possible, enable default_idle() to go into PAL_HALT | ||
1382 | */ | ||
1383 | if (pfm_sessions.pfs_task_sessions == 0 && pfm_sessions.pfs_sys_sessions == 0) | ||
1384 | update_pal_halt_status(1); | ||
1385 | |||
1369 | UNLOCK_PFS(flags); | 1386 | UNLOCK_PFS(flags); |
1370 | 1387 | ||
1371 | return 0; | 1388 | return 0; |
@@ -4202,7 +4219,7 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) | |||
4202 | DPRINT(("cannot load to [%d], invalid ctx_state=%d\n", | 4219 | DPRINT(("cannot load to [%d], invalid ctx_state=%d\n", |
4203 | req->load_pid, | 4220 | req->load_pid, |
4204 | ctx->ctx_state)); | 4221 | ctx->ctx_state)); |
4205 | return -EINVAL; | 4222 | return -EBUSY; |
4206 | } | 4223 | } |
4207 | 4224 | ||
4208 | DPRINT(("load_pid [%d] using_dbreg=%d\n", req->load_pid, ctx->ctx_fl_using_dbreg)); | 4225 | DPRINT(("load_pid [%d] using_dbreg=%d\n", req->load_pid, ctx->ctx_fl_using_dbreg)); |
@@ -4704,16 +4721,26 @@ recheck: | |||
4704 | if (task == current || ctx->ctx_fl_system) return 0; | 4721 | if (task == current || ctx->ctx_fl_system) return 0; |
4705 | 4722 | ||
4706 | /* | 4723 | /* |
4707 | * if context is UNLOADED we are safe to go | 4724 | * we are monitoring another thread |
4708 | */ | 4725 | */ |
4709 | if (state == PFM_CTX_UNLOADED) return 0; | 4726 | switch(state) { |
4710 | 4727 | case PFM_CTX_UNLOADED: | |
4711 | /* | 4728 | /* |
4712 | * no command can operate on a zombie context | 4729 | * if context is UNLOADED we are safe to go |
4713 | */ | 4730 | */ |
4714 | if (state == PFM_CTX_ZOMBIE) { | 4731 | return 0; |
4715 | DPRINT(("cmd %d state zombie cannot operate on context\n", cmd)); | 4732 | case PFM_CTX_ZOMBIE: |
4716 | return -EINVAL; | 4733 | /* |
4734 | * no command can operate on a zombie context | ||
4735 | */ | ||
4736 | DPRINT(("cmd %d state zombie cannot operate on context\n", cmd)); | ||
4737 | return -EINVAL; | ||
4738 | case PFM_CTX_MASKED: | ||
4739 | /* | ||
4740 | * PMU state has been saved to software even though | ||
4741 | * the thread may still be running. | ||
4742 | */ | ||
4743 | if (cmd != PFM_UNLOAD_CONTEXT) return 0; | ||
4717 | } | 4744 | } |
4718 | 4745 | ||
4719 | /* | 4746 | /* |
@@ -5532,26 +5559,32 @@ pfm_interrupt_handler(int irq, void *arg, struct pt_regs *regs) | |||
5532 | int ret; | 5559 | int ret; |
5533 | 5560 | ||
5534 | this_cpu = get_cpu(); | 5561 | this_cpu = get_cpu(); |
5535 | min = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min; | 5562 | if (likely(!pfm_alt_intr_handler)) { |
5536 | max = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max; | 5563 | min = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min; |
5564 | max = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max; | ||
5537 | 5565 | ||
5538 | start_cycles = ia64_get_itc(); | 5566 | start_cycles = ia64_get_itc(); |
5539 | 5567 | ||
5540 | ret = pfm_do_interrupt_handler(irq, arg, regs); | 5568 | ret = pfm_do_interrupt_handler(irq, arg, regs); |
5541 | 5569 | ||
5542 | total_cycles = ia64_get_itc(); | 5570 | total_cycles = ia64_get_itc(); |
5543 | 5571 | ||
5544 | /* | 5572 | /* |
5545 | * don't measure spurious interrupts | 5573 | * don't measure spurious interrupts |
5546 | */ | 5574 | */ |
5547 | if (likely(ret == 0)) { | 5575 | if (likely(ret == 0)) { |
5548 | total_cycles -= start_cycles; | 5576 | total_cycles -= start_cycles; |
5549 | 5577 | ||
5550 | if (total_cycles < min) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min = total_cycles; | 5578 | if (total_cycles < min) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min = total_cycles; |
5551 | if (total_cycles > max) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max = total_cycles; | 5579 | if (total_cycles > max) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max = total_cycles; |
5552 | 5580 | ||
5553 | pfm_stats[this_cpu].pfm_ovfl_intr_cycles += total_cycles; | 5581 | pfm_stats[this_cpu].pfm_ovfl_intr_cycles += total_cycles; |
5582 | } | ||
5554 | } | 5583 | } |
5584 | else { | ||
5585 | (*pfm_alt_intr_handler->handler)(irq, arg, regs); | ||
5586 | } | ||
5587 | |||
5555 | put_cpu_no_resched(); | 5588 | put_cpu_no_resched(); |
5556 | return IRQ_HANDLED; | 5589 | return IRQ_HANDLED; |
5557 | } | 5590 | } |
@@ -6402,6 +6435,141 @@ static struct irqaction perfmon_irqaction = { | |||
6402 | .name = "perfmon" | 6435 | .name = "perfmon" |
6403 | }; | 6436 | }; |
6404 | 6437 | ||
6438 | static void | ||
6439 | pfm_alt_save_pmu_state(void *data) | ||
6440 | { | ||
6441 | struct pt_regs *regs; | ||
6442 | |||
6443 | regs = ia64_task_regs(current); | ||
6444 | |||
6445 | DPRINT(("called\n")); | ||
6446 | |||
6447 | /* | ||
6448 | * should not be necessary but | ||
6449 | * let's take not risk | ||
6450 | */ | ||
6451 | pfm_clear_psr_up(); | ||
6452 | pfm_clear_psr_pp(); | ||
6453 | ia64_psr(regs)->pp = 0; | ||
6454 | |||
6455 | /* | ||
6456 | * This call is required | ||
6457 | * May cause a spurious interrupt on some processors | ||
6458 | */ | ||
6459 | pfm_freeze_pmu(); | ||
6460 | |||
6461 | ia64_srlz_d(); | ||
6462 | } | ||
6463 | |||
6464 | void | ||
6465 | pfm_alt_restore_pmu_state(void *data) | ||
6466 | { | ||
6467 | struct pt_regs *regs; | ||
6468 | |||
6469 | regs = ia64_task_regs(current); | ||
6470 | |||
6471 | DPRINT(("called\n")); | ||
6472 | |||
6473 | /* | ||
6474 | * put PMU back in state expected | ||
6475 | * by perfmon | ||
6476 | */ | ||
6477 | pfm_clear_psr_up(); | ||
6478 | pfm_clear_psr_pp(); | ||
6479 | ia64_psr(regs)->pp = 0; | ||
6480 | |||
6481 | /* | ||
6482 | * perfmon runs with PMU unfrozen at all times | ||
6483 | */ | ||
6484 | pfm_unfreeze_pmu(); | ||
6485 | |||
6486 | ia64_srlz_d(); | ||
6487 | } | ||
6488 | |||
6489 | int | ||
6490 | pfm_install_alt_pmu_interrupt(pfm_intr_handler_desc_t *hdl) | ||
6491 | { | ||
6492 | int ret, i; | ||
6493 | int reserve_cpu; | ||
6494 | |||
6495 | /* some sanity checks */ | ||
6496 | if (hdl == NULL || hdl->handler == NULL) return -EINVAL; | ||
6497 | |||
6498 | /* do the easy test first */ | ||
6499 | if (pfm_alt_intr_handler) return -EBUSY; | ||
6500 | |||
6501 | /* one at a time in the install or remove, just fail the others */ | ||
6502 | if (!spin_trylock(&pfm_alt_install_check)) { | ||
6503 | return -EBUSY; | ||
6504 | } | ||
6505 | |||
6506 | /* reserve our session */ | ||
6507 | for_each_online_cpu(reserve_cpu) { | ||
6508 | ret = pfm_reserve_session(NULL, 1, reserve_cpu); | ||
6509 | if (ret) goto cleanup_reserve; | ||
6510 | } | ||
6511 | |||
6512 | /* save the current system wide pmu states */ | ||
6513 | ret = on_each_cpu(pfm_alt_save_pmu_state, NULL, 0, 1); | ||
6514 | if (ret) { | ||
6515 | DPRINT(("on_each_cpu() failed: %d\n", ret)); | ||
6516 | goto cleanup_reserve; | ||
6517 | } | ||
6518 | |||
6519 | /* officially change to the alternate interrupt handler */ | ||
6520 | pfm_alt_intr_handler = hdl; | ||
6521 | |||
6522 | spin_unlock(&pfm_alt_install_check); | ||
6523 | |||
6524 | return 0; | ||
6525 | |||
6526 | cleanup_reserve: | ||
6527 | for_each_online_cpu(i) { | ||
6528 | /* don't unreserve more than we reserved */ | ||
6529 | if (i >= reserve_cpu) break; | ||
6530 | |||
6531 | pfm_unreserve_session(NULL, 1, i); | ||
6532 | } | ||
6533 | |||
6534 | spin_unlock(&pfm_alt_install_check); | ||
6535 | |||
6536 | return ret; | ||
6537 | } | ||
6538 | EXPORT_SYMBOL_GPL(pfm_install_alt_pmu_interrupt); | ||
6539 | |||
6540 | int | ||
6541 | pfm_remove_alt_pmu_interrupt(pfm_intr_handler_desc_t *hdl) | ||
6542 | { | ||
6543 | int i; | ||
6544 | int ret; | ||
6545 | |||
6546 | if (hdl == NULL) return -EINVAL; | ||
6547 | |||
6548 | /* cannot remove someone else's handler! */ | ||
6549 | if (pfm_alt_intr_handler != hdl) return -EINVAL; | ||
6550 | |||
6551 | /* one at a time in the install or remove, just fail the others */ | ||
6552 | if (!spin_trylock(&pfm_alt_install_check)) { | ||
6553 | return -EBUSY; | ||
6554 | } | ||
6555 | |||
6556 | pfm_alt_intr_handler = NULL; | ||
6557 | |||
6558 | ret = on_each_cpu(pfm_alt_restore_pmu_state, NULL, 0, 1); | ||
6559 | if (ret) { | ||
6560 | DPRINT(("on_each_cpu() failed: %d\n", ret)); | ||
6561 | } | ||
6562 | |||
6563 | for_each_online_cpu(i) { | ||
6564 | pfm_unreserve_session(NULL, 1, i); | ||
6565 | } | ||
6566 | |||
6567 | spin_unlock(&pfm_alt_install_check); | ||
6568 | |||
6569 | return 0; | ||
6570 | } | ||
6571 | EXPORT_SYMBOL_GPL(pfm_remove_alt_pmu_interrupt); | ||
6572 | |||
6405 | /* | 6573 | /* |
6406 | * perfmon initialization routine, called from the initcall() table | 6574 | * perfmon initialization routine, called from the initcall() table |
6407 | */ | 6575 | */ |
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 7c43aea5f7f7..ebb71f3d6d19 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c | |||
@@ -50,7 +50,7 @@ | |||
50 | #include "sigframe.h" | 50 | #include "sigframe.h" |
51 | 51 | ||
52 | void (*ia64_mark_idle)(int); | 52 | void (*ia64_mark_idle)(int); |
53 | static cpumask_t cpu_idle_map; | 53 | static DEFINE_PER_CPU(unsigned int, cpu_idle_state); |
54 | 54 | ||
55 | unsigned long boot_option_idle_override = 0; | 55 | unsigned long boot_option_idle_override = 0; |
56 | EXPORT_SYMBOL(boot_option_idle_override); | 56 | EXPORT_SYMBOL(boot_option_idle_override); |
@@ -173,7 +173,9 @@ do_notify_resume_user (sigset_t *oldset, struct sigscratch *scr, long in_syscall | |||
173 | ia64_do_signal(oldset, scr, in_syscall); | 173 | ia64_do_signal(oldset, scr, in_syscall); |
174 | } | 174 | } |
175 | 175 | ||
176 | static int pal_halt = 1; | 176 | static int pal_halt = 1; |
177 | static int can_do_pal_halt = 1; | ||
178 | |||
177 | static int __init nohalt_setup(char * str) | 179 | static int __init nohalt_setup(char * str) |
178 | { | 180 | { |
179 | pal_halt = 0; | 181 | pal_halt = 0; |
@@ -181,16 +183,20 @@ static int __init nohalt_setup(char * str) | |||
181 | } | 183 | } |
182 | __setup("nohalt", nohalt_setup); | 184 | __setup("nohalt", nohalt_setup); |
183 | 185 | ||
186 | void | ||
187 | update_pal_halt_status(int status) | ||
188 | { | ||
189 | can_do_pal_halt = pal_halt && status; | ||
190 | } | ||
191 | |||
184 | /* | 192 | /* |
185 | * We use this if we don't have any better idle routine.. | 193 | * We use this if we don't have any better idle routine.. |
186 | */ | 194 | */ |
187 | void | 195 | void |
188 | default_idle (void) | 196 | default_idle (void) |
189 | { | 197 | { |
190 | unsigned long pmu_active = ia64_getreg(_IA64_REG_PSR) & (IA64_PSR_PP | IA64_PSR_UP); | ||
191 | |||
192 | while (!need_resched()) | 198 | while (!need_resched()) |
193 | if (pal_halt && !pmu_active) | 199 | if (can_do_pal_halt) |
194 | safe_halt(); | 200 | safe_halt(); |
195 | else | 201 | else |
196 | cpu_relax(); | 202 | cpu_relax(); |
@@ -223,20 +229,31 @@ static inline void play_dead(void) | |||
223 | } | 229 | } |
224 | #endif /* CONFIG_HOTPLUG_CPU */ | 230 | #endif /* CONFIG_HOTPLUG_CPU */ |
225 | 231 | ||
226 | |||
227 | void cpu_idle_wait(void) | 232 | void cpu_idle_wait(void) |
228 | { | 233 | { |
229 | int cpu; | 234 | unsigned int cpu, this_cpu = get_cpu(); |
230 | cpumask_t map; | 235 | cpumask_t map; |
231 | 236 | ||
232 | for_each_online_cpu(cpu) | 237 | set_cpus_allowed(current, cpumask_of_cpu(this_cpu)); |
233 | cpu_set(cpu, cpu_idle_map); | 238 | put_cpu(); |
234 | 239 | ||
235 | wmb(); | 240 | cpus_clear(map); |
236 | do { | 241 | for_each_online_cpu(cpu) { |
237 | ssleep(1); | 242 | per_cpu(cpu_idle_state, cpu) = 1; |
238 | cpus_and(map, cpu_idle_map, cpu_online_map); | 243 | cpu_set(cpu, map); |
239 | } while (!cpus_empty(map)); | 244 | } |
245 | |||
246 | __get_cpu_var(cpu_idle_state) = 0; | ||
247 | |||
248 | wmb(); | ||
249 | do { | ||
250 | ssleep(1); | ||
251 | for_each_online_cpu(cpu) { | ||
252 | if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu)) | ||
253 | cpu_clear(cpu, map); | ||
254 | } | ||
255 | cpus_and(map, map, cpu_online_map); | ||
256 | } while (!cpus_empty(map)); | ||
240 | } | 257 | } |
241 | EXPORT_SYMBOL_GPL(cpu_idle_wait); | 258 | EXPORT_SYMBOL_GPL(cpu_idle_wait); |
242 | 259 | ||
@@ -244,7 +261,6 @@ void __attribute__((noreturn)) | |||
244 | cpu_idle (void) | 261 | cpu_idle (void) |
245 | { | 262 | { |
246 | void (*mark_idle)(int) = ia64_mark_idle; | 263 | void (*mark_idle)(int) = ia64_mark_idle; |
247 | int cpu = smp_processor_id(); | ||
248 | 264 | ||
249 | /* endless idle loop with no priority at all */ | 265 | /* endless idle loop with no priority at all */ |
250 | while (1) { | 266 | while (1) { |
@@ -255,12 +271,13 @@ cpu_idle (void) | |||
255 | while (!need_resched()) { | 271 | while (!need_resched()) { |
256 | void (*idle)(void); | 272 | void (*idle)(void); |
257 | 273 | ||
274 | if (__get_cpu_var(cpu_idle_state)) | ||
275 | __get_cpu_var(cpu_idle_state) = 0; | ||
276 | |||
277 | rmb(); | ||
258 | if (mark_idle) | 278 | if (mark_idle) |
259 | (*mark_idle)(1); | 279 | (*mark_idle)(1); |
260 | 280 | ||
261 | if (cpu_isset(cpu, cpu_idle_map)) | ||
262 | cpu_clear(cpu, cpu_idle_map); | ||
263 | rmb(); | ||
264 | idle = pm_idle; | 281 | idle = pm_idle; |
265 | if (!idle) | 282 | if (!idle) |
266 | idle = default_idle; | 283 | idle = default_idle; |
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 9e730c7bf0cd..4c1d2f5442b3 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c | |||
@@ -635,11 +635,17 @@ ia64_flush_fph (struct task_struct *task) | |||
635 | { | 635 | { |
636 | struct ia64_psr *psr = ia64_psr(ia64_task_regs(task)); | 636 | struct ia64_psr *psr = ia64_psr(ia64_task_regs(task)); |
637 | 637 | ||
638 | /* | ||
639 | * Prevent migrating this task while | ||
640 | * we're fiddling with the FPU state | ||
641 | */ | ||
642 | preempt_disable(); | ||
638 | if (ia64_is_local_fpu_owner(task) && psr->mfh) { | 643 | if (ia64_is_local_fpu_owner(task) && psr->mfh) { |
639 | psr->mfh = 0; | 644 | psr->mfh = 0; |
640 | task->thread.flags |= IA64_THREAD_FPH_VALID; | 645 | task->thread.flags |= IA64_THREAD_FPH_VALID; |
641 | ia64_save_fpu(&task->thread.fph[0]); | 646 | ia64_save_fpu(&task->thread.fph[0]); |
642 | } | 647 | } |
648 | preempt_enable(); | ||
643 | } | 649 | } |
644 | 650 | ||
645 | /* | 651 | /* |
@@ -692,16 +698,30 @@ convert_to_non_syscall (struct task_struct *child, struct pt_regs *pt, | |||
692 | unsigned long cfm) | 698 | unsigned long cfm) |
693 | { | 699 | { |
694 | struct unw_frame_info info, prev_info; | 700 | struct unw_frame_info info, prev_info; |
695 | unsigned long ip, pr; | 701 | unsigned long ip, sp, pr; |
696 | 702 | ||
697 | unw_init_from_blocked_task(&info, child); | 703 | unw_init_from_blocked_task(&info, child); |
698 | while (1) { | 704 | while (1) { |
699 | prev_info = info; | 705 | prev_info = info; |
700 | if (unw_unwind(&info) < 0) | 706 | if (unw_unwind(&info) < 0) |
701 | return; | 707 | return; |
702 | if (unw_get_rp(&info, &ip) < 0) | 708 | |
709 | unw_get_sp(&info, &sp); | ||
710 | if ((long)((unsigned long)child + IA64_STK_OFFSET - sp) | ||
711 | < IA64_PT_REGS_SIZE) { | ||
712 | dprintk("ptrace.%s: ran off the top of the kernel " | ||
713 | "stack\n", __FUNCTION__); | ||
714 | return; | ||
715 | } | ||
716 | if (unw_get_pr (&prev_info, &pr) < 0) { | ||
717 | unw_get_rp(&prev_info, &ip); | ||
718 | dprintk("ptrace.%s: failed to read " | ||
719 | "predicate register (ip=0x%lx)\n", | ||
720 | __FUNCTION__, ip); | ||
703 | return; | 721 | return; |
704 | if (ip < FIXADDR_USER_END) | 722 | } |
723 | if (unw_is_intr_frame(&info) | ||
724 | && (pr & (1UL << PRED_USER_STACK))) | ||
705 | break; | 725 | break; |
706 | } | 726 | } |
707 | 727 | ||
@@ -1616,20 +1636,25 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3, | |||
1616 | long arg4, long arg5, long arg6, long arg7, | 1636 | long arg4, long arg5, long arg6, long arg7, |
1617 | struct pt_regs regs) | 1637 | struct pt_regs regs) |
1618 | { | 1638 | { |
1619 | long syscall; | 1639 | if (test_thread_flag(TIF_SYSCALL_TRACE) |
1640 | && (current->ptrace & PT_PTRACED)) | ||
1641 | syscall_trace(); | ||
1620 | 1642 | ||
1621 | if (unlikely(current->audit_context)) { | 1643 | if (unlikely(current->audit_context)) { |
1622 | if (IS_IA32_PROCESS(®s)) | 1644 | long syscall; |
1645 | int arch; | ||
1646 | |||
1647 | if (IS_IA32_PROCESS(®s)) { | ||
1623 | syscall = regs.r1; | 1648 | syscall = regs.r1; |
1624 | else | 1649 | arch = AUDIT_ARCH_I386; |
1650 | } else { | ||
1625 | syscall = regs.r15; | 1651 | syscall = regs.r15; |
1652 | arch = AUDIT_ARCH_IA64; | ||
1653 | } | ||
1626 | 1654 | ||
1627 | audit_syscall_entry(current, syscall, arg0, arg1, arg2, arg3); | 1655 | audit_syscall_entry(current, arch, syscall, arg0, arg1, arg2, arg3); |
1628 | } | 1656 | } |
1629 | 1657 | ||
1630 | if (test_thread_flag(TIF_SYSCALL_TRACE) | ||
1631 | && (current->ptrace & PT_PTRACED)) | ||
1632 | syscall_trace(); | ||
1633 | } | 1658 | } |
1634 | 1659 | ||
1635 | /* "asmlinkage" so the input arguments are preserved... */ | 1660 | /* "asmlinkage" so the input arguments are preserved... */ |
@@ -1640,7 +1665,7 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3, | |||
1640 | struct pt_regs regs) | 1665 | struct pt_regs regs) |
1641 | { | 1666 | { |
1642 | if (unlikely(current->audit_context)) | 1667 | if (unlikely(current->audit_context)) |
1643 | audit_syscall_exit(current, regs.r8); | 1668 | audit_syscall_exit(current, AUDITSC_RESULT(regs.r10), regs.r8); |
1644 | 1669 | ||
1645 | if (test_thread_flag(TIF_SYSCALL_TRACE) | 1670 | if (test_thread_flag(TIF_SYSCALL_TRACE) |
1646 | && (current->ptrace & PT_PTRACED)) | 1671 | && (current->ptrace & PT_PTRACED)) |
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index b7e6b4cb374b..d14692e0920a 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c | |||
@@ -720,7 +720,8 @@ cpu_init (void) | |||
720 | ia64_set_kr(IA64_KR_PT_BASE, __pa(ia64_imva(empty_zero_page))); | 720 | ia64_set_kr(IA64_KR_PT_BASE, __pa(ia64_imva(empty_zero_page))); |
721 | 721 | ||
722 | /* | 722 | /* |
723 | * Initialize default control register to defer all speculative faults. The | 723 | * Initialize default control register to defer speculative faults except |
724 | * for those arising from TLB misses, which are not deferred. The | ||
724 | * kernel MUST NOT depend on a particular setting of these bits (in other words, | 725 | * kernel MUST NOT depend on a particular setting of these bits (in other words, |
725 | * the kernel must have recovery code for all speculative accesses). Turn on | 726 | * the kernel must have recovery code for all speculative accesses). Turn on |
726 | * dcr.lc as per recommendation by the architecture team. Most IA-32 apps | 727 | * dcr.lc as per recommendation by the architecture team. Most IA-32 apps |
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index 6891d86937d9..499b7e5317cf 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c | |||
@@ -224,7 +224,8 @@ ia64_rt_sigreturn (struct sigscratch *scr) | |||
224 | * could be corrupted. | 224 | * could be corrupted. |
225 | */ | 225 | */ |
226 | retval = (long) &ia64_leave_kernel; | 226 | retval = (long) &ia64_leave_kernel; |
227 | if (test_thread_flag(TIF_SYSCALL_TRACE)) | 227 | if (test_thread_flag(TIF_SYSCALL_TRACE) |
228 | || test_thread_flag(TIF_SYSCALL_AUDIT)) | ||
228 | /* | 229 | /* |
229 | * strace expects to be notified after sigreturn returns even though the | 230 | * strace expects to be notified after sigreturn returns even though the |
230 | * context to which we return may not be in the middle of a syscall. | 231 | * context to which we return may not be in the middle of a syscall. |
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 0d5ee57c9865..3865f088ffa2 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c | |||
@@ -624,7 +624,7 @@ static struct { | |||
624 | __u16 thread_id; | 624 | __u16 thread_id; |
625 | __u16 proc_fixed_addr; | 625 | __u16 proc_fixed_addr; |
626 | __u8 valid; | 626 | __u8 valid; |
627 | }mt_info[NR_CPUS] __devinit; | 627 | } mt_info[NR_CPUS] __devinitdata; |
628 | 628 | ||
629 | #ifdef CONFIG_HOTPLUG_CPU | 629 | #ifdef CONFIG_HOTPLUG_CPU |
630 | static inline void | 630 | static inline void |
diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c index a8cf6d8a509c..770fab37928e 100644 --- a/arch/ia64/kernel/sys_ia64.c +++ b/arch/ia64/kernel/sys_ia64.c | |||
@@ -182,13 +182,6 @@ do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, un | |||
182 | } | 182 | } |
183 | } | 183 | } |
184 | 184 | ||
185 | /* | ||
186 | * A zero mmap always succeeds in Linux, independent of whether or not the | ||
187 | * remaining arguments are valid. | ||
188 | */ | ||
189 | if (len == 0) | ||
190 | goto out; | ||
191 | |||
192 | /* Careful about overflows.. */ | 185 | /* Careful about overflows.. */ |
193 | len = PAGE_ALIGN(len); | 186 | len = PAGE_ALIGN(len); |
194 | if (!len || len > TASK_SIZE) { | 187 | if (!len || len > TASK_SIZE) { |
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index e82ad78081b3..1861173bd4f6 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c | |||
@@ -111,6 +111,24 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs) | |||
111 | siginfo_t siginfo; | 111 | siginfo_t siginfo; |
112 | int sig, code; | 112 | int sig, code; |
113 | 113 | ||
114 | /* break.b always sets cr.iim to 0, which causes problems for | ||
115 | * debuggers. Get the real break number from the original instruction, | ||
116 | * but only for kernel code. User space break.b is left alone, to | ||
117 | * preserve the existing behaviour. All break codings have the same | ||
118 | * format, so there is no need to check the slot type. | ||
119 | */ | ||
120 | if (break_num == 0 && !user_mode(regs)) { | ||
121 | struct ia64_psr *ipsr = ia64_psr(regs); | ||
122 | unsigned long *bundle = (unsigned long *)regs->cr_iip; | ||
123 | unsigned long slot; | ||
124 | switch (ipsr->ri) { | ||
125 | case 0: slot = (bundle[0] >> 5); break; | ||
126 | case 1: slot = (bundle[0] >> 46) | (bundle[1] << 18); break; | ||
127 | default: slot = (bundle[1] >> 23); break; | ||
128 | } | ||
129 | break_num = ((slot >> 36 & 1) << 20) | (slot >> 6 & 0xfffff); | ||
130 | } | ||
131 | |||
114 | /* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */ | 132 | /* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */ |
115 | siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri); | 133 | siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri); |
116 | siginfo.si_imm = break_num; | 134 | siginfo.si_imm = break_num; |
@@ -202,13 +220,21 @@ disabled_fph_fault (struct pt_regs *regs) | |||
202 | 220 | ||
203 | /* first, grant user-level access to fph partition: */ | 221 | /* first, grant user-level access to fph partition: */ |
204 | psr->dfh = 0; | 222 | psr->dfh = 0; |
223 | |||
224 | /* | ||
225 | * Make sure that no other task gets in on this processor | ||
226 | * while we're claiming the FPU | ||
227 | */ | ||
228 | preempt_disable(); | ||
205 | #ifndef CONFIG_SMP | 229 | #ifndef CONFIG_SMP |
206 | { | 230 | { |
207 | struct task_struct *fpu_owner | 231 | struct task_struct *fpu_owner |
208 | = (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER); | 232 | = (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER); |
209 | 233 | ||
210 | if (ia64_is_local_fpu_owner(current)) | 234 | if (ia64_is_local_fpu_owner(current)) { |
235 | preempt_enable_no_resched(); | ||
211 | return; | 236 | return; |
237 | } | ||
212 | 238 | ||
213 | if (fpu_owner) | 239 | if (fpu_owner) |
214 | ia64_flush_fph(fpu_owner); | 240 | ia64_flush_fph(fpu_owner); |
@@ -226,6 +252,7 @@ disabled_fph_fault (struct pt_regs *regs) | |||
226 | */ | 252 | */ |
227 | psr->mfh = 1; | 253 | psr->mfh = 1; |
228 | } | 254 | } |
255 | preempt_enable_no_resched(); | ||
229 | } | 256 | } |
230 | 257 | ||
231 | static inline int | 258 | static inline int |
diff --git a/arch/ia64/lib/flush.S b/arch/ia64/lib/flush.S index 29c802b19669..a1af9146cfdb 100644 --- a/arch/ia64/lib/flush.S +++ b/arch/ia64/lib/flush.S | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Cache flushing routines. | 2 | * Cache flushing routines. |
3 | * | 3 | * |
4 | * Copyright (C) 1999-2001 Hewlett-Packard Co | 4 | * Copyright (C) 1999-2001, 2005 Hewlett-Packard Co |
5 | * Copyright (C) 1999-2001 David Mosberger-Tang <davidm@hpl.hp.com> | 5 | * David Mosberger-Tang <davidm@hpl.hp.com> |
6 | */ | 6 | */ |
7 | #include <asm/asmmacro.h> | 7 | #include <asm/asmmacro.h> |
8 | #include <asm/page.h> | 8 | #include <asm/page.h> |
@@ -26,7 +26,7 @@ GLOBAL_ENTRY(flush_icache_range) | |||
26 | 26 | ||
27 | mov ar.lc=r8 | 27 | mov ar.lc=r8 |
28 | ;; | 28 | ;; |
29 | .Loop: fc in0 // issuable on M0 only | 29 | .Loop: fc.i in0 // issuable on M2 only |
30 | add in0=32,in0 | 30 | add in0=32,in0 |
31 | br.cloop.sptk.few .Loop | 31 | br.cloop.sptk.few .Loop |
32 | ;; | 32 | ;; |
diff --git a/arch/ia64/lib/memcpy_mck.S b/arch/ia64/lib/memcpy_mck.S index 3c2cd2f04db9..6f308e62c137 100644 --- a/arch/ia64/lib/memcpy_mck.S +++ b/arch/ia64/lib/memcpy_mck.S | |||
@@ -75,6 +75,7 @@ GLOBAL_ENTRY(memcpy) | |||
75 | mov f6=f0 | 75 | mov f6=f0 |
76 | br.cond.sptk .common_code | 76 | br.cond.sptk .common_code |
77 | ;; | 77 | ;; |
78 | END(memcpy) | ||
78 | GLOBAL_ENTRY(__copy_user) | 79 | GLOBAL_ENTRY(__copy_user) |
79 | .prologue | 80 | .prologue |
80 | // check dest alignment | 81 | // check dest alignment |
@@ -524,7 +525,6 @@ EK(.ex_handler, (p17) st8 [dst1]=r39,8); \ | |||
524 | #undef B | 525 | #undef B |
525 | #undef C | 526 | #undef C |
526 | #undef D | 527 | #undef D |
527 | END(memcpy) | ||
528 | 528 | ||
529 | /* | 529 | /* |
530 | * Due to lack of local tag support in gcc 2.x assembler, it is not clear which | 530 | * Due to lack of local tag support in gcc 2.x assembler, it is not clear which |
diff --git a/arch/ia64/lib/memset.S b/arch/ia64/lib/memset.S index bd8cf907fe22..f26c16aefb1c 100644 --- a/arch/ia64/lib/memset.S +++ b/arch/ia64/lib/memset.S | |||
@@ -57,10 +57,10 @@ GLOBAL_ENTRY(memset) | |||
57 | { .mmi | 57 | { .mmi |
58 | .prologue | 58 | .prologue |
59 | alloc tmp = ar.pfs, 3, 0, 0, 0 | 59 | alloc tmp = ar.pfs, 3, 0, 0, 0 |
60 | .body | ||
61 | lfetch.nt1 [dest] // | 60 | lfetch.nt1 [dest] // |
62 | .save ar.lc, save_lc | 61 | .save ar.lc, save_lc |
63 | mov.i save_lc = ar.lc | 62 | mov.i save_lc = ar.lc |
63 | .body | ||
64 | } { .mmi | 64 | } { .mmi |
65 | mov ret0 = dest // return value | 65 | mov ret0 = dest // return value |
66 | cmp.ne p_nz, p_zr = value, r0 // use stf.spill if value is zero | 66 | cmp.ne p_nz, p_zr = value, r0 // use stf.spill if value is zero |
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 547785e3cba2..4eb2f52b87a1 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c | |||
@@ -305,8 +305,9 @@ setup_gate (void) | |||
305 | struct page *page; | 305 | struct page *page; |
306 | 306 | ||
307 | /* | 307 | /* |
308 | * Map the gate page twice: once read-only to export the ELF headers etc. and once | 308 | * Map the gate page twice: once read-only to export the ELF |
309 | * execute-only page to enable privilege-promotion via "epc": | 309 | * headers etc. and once execute-only page to enable |
310 | * privilege-promotion via "epc": | ||
310 | */ | 311 | */ |
311 | page = virt_to_page(ia64_imva(__start_gate_section)); | 312 | page = virt_to_page(ia64_imva(__start_gate_section)); |
312 | put_kernel_page(page, GATE_ADDR, PAGE_READONLY); | 313 | put_kernel_page(page, GATE_ADDR, PAGE_READONLY); |
@@ -315,6 +316,20 @@ setup_gate (void) | |||
315 | put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE); | 316 | put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE); |
316 | #else | 317 | #else |
317 | put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE); | 318 | put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE); |
319 | /* Fill in the holes (if any) with read-only zero pages: */ | ||
320 | { | ||
321 | unsigned long addr; | ||
322 | |||
323 | for (addr = GATE_ADDR + PAGE_SIZE; | ||
324 | addr < GATE_ADDR + PERCPU_PAGE_SIZE; | ||
325 | addr += PAGE_SIZE) | ||
326 | { | ||
327 | put_kernel_page(ZERO_PAGE(0), addr, | ||
328 | PAGE_READONLY); | ||
329 | put_kernel_page(ZERO_PAGE(0), addr + PERCPU_PAGE_SIZE, | ||
330 | PAGE_READONLY); | ||
331 | } | ||
332 | } | ||
318 | #endif | 333 | #endif |
319 | ia64_patch_gate(); | 334 | ia64_patch_gate(); |
320 | } | 335 | } |
diff --git a/arch/ia64/sn/kernel/Makefile b/arch/ia64/sn/kernel/Makefile index 4f381fb25049..4351c4ff9845 100644 --- a/arch/ia64/sn/kernel/Makefile +++ b/arch/ia64/sn/kernel/Makefile | |||
@@ -4,10 +4,15 @@ | |||
4 | # License. See the file "COPYING" in the main directory of this archive | 4 | # License. See the file "COPYING" in the main directory of this archive |
5 | # for more details. | 5 | # for more details. |
6 | # | 6 | # |
7 | # Copyright (C) 1999,2001-2003 Silicon Graphics, Inc. All Rights Reserved. | 7 | # Copyright (C) 1999,2001-2005 Silicon Graphics, Inc. All Rights Reserved. |
8 | # | 8 | # |
9 | 9 | ||
10 | obj-y += setup.o bte.o bte_error.o irq.o mca.o idle.o \ | 10 | obj-y += setup.o bte.o bte_error.o irq.o mca.o idle.o \ |
11 | huberror.o io_init.o iomv.o klconflib.o sn2/ | 11 | huberror.o io_init.o iomv.o klconflib.o sn2/ |
12 | obj-$(CONFIG_IA64_GENERIC) += machvec.o | 12 | obj-$(CONFIG_IA64_GENERIC) += machvec.o |
13 | obj-$(CONFIG_SGI_TIOCX) += tiocx.o | 13 | obj-$(CONFIG_SGI_TIOCX) += tiocx.o |
14 | obj-$(CONFIG_IA64_SGI_SN_XP) += xp.o | ||
15 | xp-y := xp_main.o xp_nofault.o | ||
16 | obj-$(CONFIG_IA64_SGI_SN_XP) += xpc.o | ||
17 | xpc-y := xpc_main.o xpc_channel.o xpc_partition.o | ||
18 | obj-$(CONFIG_IA64_SGI_SN_XP) += xpnet.o | ||
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 18160a06a8c9..9e07f5463f21 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c | |||
@@ -174,6 +174,12 @@ static void sn_fixup_ionodes(void) | |||
174 | if (status) | 174 | if (status) |
175 | continue; | 175 | continue; |
176 | 176 | ||
177 | /* Attach the error interrupt handlers */ | ||
178 | if (nasid & 1) | ||
179 | ice_error_init(hubdev); | ||
180 | else | ||
181 | hub_error_init(hubdev); | ||
182 | |||
177 | for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) | 183 | for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) |
178 | hubdev->hdi_xwidget_info[widget].xwi_hubinfo = hubdev; | 184 | hubdev->hdi_xwidget_info[widget].xwi_hubinfo = hubdev; |
179 | 185 | ||
@@ -211,10 +217,6 @@ static void sn_fixup_ionodes(void) | |||
211 | sn_flush_device_list; | 217 | sn_flush_device_list; |
212 | } | 218 | } |
213 | 219 | ||
214 | if (!(i & 1)) | ||
215 | hub_error_init(hubdev); | ||
216 | else | ||
217 | ice_error_init(hubdev); | ||
218 | } | 220 | } |
219 | 221 | ||
220 | } | 222 | } |
diff --git a/arch/ia64/sn/kernel/mca.c b/arch/ia64/sn/kernel/mca.c index 857774bb2c9a..6546db6abdba 100644 --- a/arch/ia64/sn/kernel/mca.c +++ b/arch/ia64/sn/kernel/mca.c | |||
@@ -37,6 +37,11 @@ static u64 *sn_oemdata_size, sn_oemdata_bufsize; | |||
37 | * This function is the callback routine that SAL calls to log error | 37 | * This function is the callback routine that SAL calls to log error |
38 | * info for platform errors. buf is appended to sn_oemdata, resizing as | 38 | * info for platform errors. buf is appended to sn_oemdata, resizing as |
39 | * required. | 39 | * required. |
40 | * Note: this is a SAL to OS callback, running under the same rules as the SAL | ||
41 | * code. SAL calls are run with preempt disabled so this routine must not | ||
42 | * sleep. vmalloc can sleep so print_hook cannot resize the output buffer | ||
43 | * itself, instead it must set the required size and return to let the caller | ||
44 | * resize the buffer then redrive the SAL call. | ||
40 | */ | 45 | */ |
41 | static int print_hook(const char *fmt, ...) | 46 | static int print_hook(const char *fmt, ...) |
42 | { | 47 | { |
@@ -47,18 +52,8 @@ static int print_hook(const char *fmt, ...) | |||
47 | vsnprintf(buf, sizeof(buf), fmt, args); | 52 | vsnprintf(buf, sizeof(buf), fmt, args); |
48 | va_end(args); | 53 | va_end(args); |
49 | len = strlen(buf); | 54 | len = strlen(buf); |
50 | while (*sn_oemdata_size + len + 1 > sn_oemdata_bufsize) { | 55 | if (*sn_oemdata_size + len <= sn_oemdata_bufsize) |
51 | u8 *newbuf = vmalloc(sn_oemdata_bufsize += 1000); | 56 | memcpy(*sn_oemdata + *sn_oemdata_size, buf, len); |
52 | if (!newbuf) { | ||
53 | printk(KERN_ERR "%s: unable to extend sn_oemdata\n", | ||
54 | __FUNCTION__); | ||
55 | return 0; | ||
56 | } | ||
57 | memcpy(newbuf, *sn_oemdata, *sn_oemdata_size); | ||
58 | vfree(*sn_oemdata); | ||
59 | *sn_oemdata = newbuf; | ||
60 | } | ||
61 | memcpy(*sn_oemdata + *sn_oemdata_size, buf, len + 1); | ||
62 | *sn_oemdata_size += len; | 57 | *sn_oemdata_size += len; |
63 | return 0; | 58 | return 0; |
64 | } | 59 | } |
@@ -98,7 +93,20 @@ sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata, | |||
98 | sn_oemdata = oemdata; | 93 | sn_oemdata = oemdata; |
99 | sn_oemdata_size = oemdata_size; | 94 | sn_oemdata_size = oemdata_size; |
100 | sn_oemdata_bufsize = 0; | 95 | sn_oemdata_bufsize = 0; |
101 | ia64_sn_plat_specific_err_print(print_hook, (char *)sect_header); | 96 | *sn_oemdata_size = PAGE_SIZE; /* first guess at how much data will be generated */ |
97 | while (*sn_oemdata_size > sn_oemdata_bufsize) { | ||
98 | u8 *newbuf = vmalloc(*sn_oemdata_size); | ||
99 | if (!newbuf) { | ||
100 | printk(KERN_ERR "%s: unable to extend sn_oemdata\n", | ||
101 | __FUNCTION__); | ||
102 | return 1; | ||
103 | } | ||
104 | vfree(*sn_oemdata); | ||
105 | *sn_oemdata = newbuf; | ||
106 | sn_oemdata_bufsize = *sn_oemdata_size; | ||
107 | *sn_oemdata_size = 0; | ||
108 | ia64_sn_plat_specific_err_print(print_hook, (char *)sect_header); | ||
109 | } | ||
102 | up(&sn_oemdata_mutex); | 110 | up(&sn_oemdata_mutex); |
103 | return 0; | 111 | return 0; |
104 | } | 112 | } |
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index d35f2a6f9c94..44bfc7f318cb 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
4 | * for more details. | 4 | * for more details. |
5 | * | 5 | * |
6 | * Copyright (C) 1999,2001-2004 Silicon Graphics, Inc. All rights reserved. | 6 | * Copyright (C) 1999,2001-2005 Silicon Graphics, Inc. All rights reserved. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/config.h> | 9 | #include <linux/config.h> |
@@ -73,6 +73,12 @@ EXPORT_SYMBOL(sn_rtc_cycles_per_second); | |||
73 | DEFINE_PER_CPU(struct sn_hub_info_s, __sn_hub_info); | 73 | DEFINE_PER_CPU(struct sn_hub_info_s, __sn_hub_info); |
74 | EXPORT_PER_CPU_SYMBOL(__sn_hub_info); | 74 | EXPORT_PER_CPU_SYMBOL(__sn_hub_info); |
75 | 75 | ||
76 | DEFINE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_NUMNODES]); | ||
77 | EXPORT_PER_CPU_SYMBOL(__sn_cnodeid_to_nasid); | ||
78 | |||
79 | DEFINE_PER_CPU(struct nodepda_s *, __sn_nodepda); | ||
80 | EXPORT_PER_CPU_SYMBOL(__sn_nodepda); | ||
81 | |||
76 | partid_t sn_partid = -1; | 82 | partid_t sn_partid = -1; |
77 | EXPORT_SYMBOL(sn_partid); | 83 | EXPORT_SYMBOL(sn_partid); |
78 | char sn_system_serial_number_string[128]; | 84 | char sn_system_serial_number_string[128]; |
@@ -216,7 +222,7 @@ void __init early_sn_setup(void) | |||
216 | 222 | ||
217 | extern int platform_intr_list[]; | 223 | extern int platform_intr_list[]; |
218 | extern nasid_t master_nasid; | 224 | extern nasid_t master_nasid; |
219 | static int shub_1_1_found __initdata; | 225 | static int __initdata shub_1_1_found = 0; |
220 | 226 | ||
221 | /* | 227 | /* |
222 | * sn_check_for_wars | 228 | * sn_check_for_wars |
@@ -245,7 +251,7 @@ static void __init sn_check_for_wars(void) | |||
245 | } else { | 251 | } else { |
246 | for_each_online_node(cnode) { | 252 | for_each_online_node(cnode) { |
247 | if (is_shub_1_1(cnodeid_to_nasid(cnode))) | 253 | if (is_shub_1_1(cnodeid_to_nasid(cnode))) |
248 | sn_hub_info->shub_1_1_found = 1; | 254 | shub_1_1_found = 1; |
249 | } | 255 | } |
250 | } | 256 | } |
251 | } | 257 | } |
@@ -265,6 +271,8 @@ void __init sn_setup(char **cmdline_p) | |||
265 | int major = sn_sal_rev_major(), minor = sn_sal_rev_minor(); | 271 | int major = sn_sal_rev_major(), minor = sn_sal_rev_minor(); |
266 | extern void sn_cpu_init(void); | 272 | extern void sn_cpu_init(void); |
267 | 273 | ||
274 | ia64_sn_plat_set_error_handling_features(); | ||
275 | |||
268 | /* | 276 | /* |
269 | * If the generic code has enabled vga console support - lets | 277 | * If the generic code has enabled vga console support - lets |
270 | * get rid of it again. This is a kludge for the fact that ACPI | 278 | * get rid of it again. This is a kludge for the fact that ACPI |
@@ -373,11 +381,11 @@ static void __init sn_init_pdas(char **cmdline_p) | |||
373 | { | 381 | { |
374 | cnodeid_t cnode; | 382 | cnodeid_t cnode; |
375 | 383 | ||
376 | memset(pda->cnodeid_to_nasid_table, -1, | 384 | memset(sn_cnodeid_to_nasid, -1, |
377 | sizeof(pda->cnodeid_to_nasid_table)); | 385 | sizeof(__ia64_per_cpu_var(__sn_cnodeid_to_nasid))); |
378 | for_each_online_node(cnode) | 386 | for_each_online_node(cnode) |
379 | pda->cnodeid_to_nasid_table[cnode] = | 387 | sn_cnodeid_to_nasid[cnode] = |
380 | pxm_to_nasid(nid_to_pxm_map[cnode]); | 388 | pxm_to_nasid(nid_to_pxm_map[cnode]); |
381 | 389 | ||
382 | numionodes = num_online_nodes(); | 390 | numionodes = num_online_nodes(); |
383 | scan_for_ionodes(); | 391 | scan_for_ionodes(); |
@@ -477,7 +485,8 @@ void __init sn_cpu_init(void) | |||
477 | 485 | ||
478 | cnode = nasid_to_cnodeid(nasid); | 486 | cnode = nasid_to_cnodeid(nasid); |
479 | 487 | ||
480 | pda->p_nodepda = nodepdaindr[cnode]; | 488 | sn_nodepda = nodepdaindr[cnode]; |
489 | |||
481 | pda->led_address = | 490 | pda->led_address = |
482 | (typeof(pda->led_address)) (LED0 + (slice << LED_CPU_SHIFT)); | 491 | (typeof(pda->led_address)) (LED0 + (slice << LED_CPU_SHIFT)); |
483 | pda->led_state = LED_ALWAYS_SET; | 492 | pda->led_state = LED_ALWAYS_SET; |
@@ -486,15 +495,18 @@ void __init sn_cpu_init(void) | |||
486 | pda->idle_flag = 0; | 495 | pda->idle_flag = 0; |
487 | 496 | ||
488 | if (cpuid != 0) { | 497 | if (cpuid != 0) { |
489 | memcpy(pda->cnodeid_to_nasid_table, | 498 | /* copy cpu 0's sn_cnodeid_to_nasid table to this cpu's */ |
490 | pdacpu(0)->cnodeid_to_nasid_table, | 499 | memcpy(sn_cnodeid_to_nasid, |
491 | sizeof(pda->cnodeid_to_nasid_table)); | 500 | (&per_cpu(__sn_cnodeid_to_nasid, 0)), |
501 | sizeof(__ia64_per_cpu_var(__sn_cnodeid_to_nasid))); | ||
492 | } | 502 | } |
493 | 503 | ||
494 | /* | 504 | /* |
495 | * Check for WARs. | 505 | * Check for WARs. |
496 | * Only needs to be done once, on BSP. | 506 | * Only needs to be done once, on BSP. |
497 | * Has to be done after loop above, because it uses pda.cnodeid_to_nasid_table[i]. | 507 | * Has to be done after loop above, because it uses this cpu's |
508 | * sn_cnodeid_to_nasid table which was just initialized if this | ||
509 | * isn't cpu 0. | ||
498 | * Has to be done before assignment below. | 510 | * Has to be done before assignment below. |
499 | */ | 511 | */ |
500 | if (!wars_have_been_checked) { | 512 | if (!wars_have_been_checked) { |
@@ -580,8 +592,7 @@ static void __init scan_for_ionodes(void) | |||
580 | brd = find_lboard_any(brd, KLTYPE_SNIA); | 592 | brd = find_lboard_any(brd, KLTYPE_SNIA); |
581 | 593 | ||
582 | while (brd) { | 594 | while (brd) { |
583 | pda->cnodeid_to_nasid_table[numionodes] = | 595 | sn_cnodeid_to_nasid[numionodes] = brd->brd_nasid; |
584 | brd->brd_nasid; | ||
585 | physical_node_map[brd->brd_nasid] = numionodes; | 596 | physical_node_map[brd->brd_nasid] = numionodes; |
586 | root_lboard[numionodes] = brd; | 597 | root_lboard[numionodes] = brd; |
587 | numionodes++; | 598 | numionodes++; |
@@ -602,8 +613,7 @@ static void __init scan_for_ionodes(void) | |||
602 | root_lboard[nasid_to_cnodeid(nasid)], | 613 | root_lboard[nasid_to_cnodeid(nasid)], |
603 | KLTYPE_TIO); | 614 | KLTYPE_TIO); |
604 | while (brd) { | 615 | while (brd) { |
605 | pda->cnodeid_to_nasid_table[numionodes] = | 616 | sn_cnodeid_to_nasid[numionodes] = brd->brd_nasid; |
606 | brd->brd_nasid; | ||
607 | physical_node_map[brd->brd_nasid] = numionodes; | 617 | physical_node_map[brd->brd_nasid] = numionodes; |
608 | root_lboard[numionodes] = brd; | 618 | root_lboard[numionodes] = brd; |
609 | numionodes++; | 619 | numionodes++; |
@@ -614,7 +624,6 @@ static void __init scan_for_ionodes(void) | |||
614 | brd = find_lboard_any(brd, KLTYPE_TIO); | 624 | brd = find_lboard_any(brd, KLTYPE_TIO); |
615 | } | 625 | } |
616 | } | 626 | } |
617 | |||
618 | } | 627 | } |
619 | 628 | ||
620 | int | 629 | int |
@@ -623,7 +632,8 @@ nasid_slice_to_cpuid(int nasid, int slice) | |||
623 | long cpu; | 632 | long cpu; |
624 | 633 | ||
625 | for (cpu=0; cpu < NR_CPUS; cpu++) | 634 | for (cpu=0; cpu < NR_CPUS; cpu++) |
626 | if (nodepda->phys_cpuid[cpu].nasid == nasid && nodepda->phys_cpuid[cpu].slice == slice) | 635 | if (cpuid_to_nasid(cpu) == nasid && |
636 | cpuid_to_slice(cpu) == slice) | ||
627 | return cpu; | 637 | return cpu; |
628 | 638 | ||
629 | return -1; | 639 | return -1; |
diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c index 66190d7e492d..ab9b5f35c2a7 100644 --- a/arch/ia64/sn/kernel/tiocx.c +++ b/arch/ia64/sn/kernel/tiocx.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #include <asm/sn/types.h> | 21 | #include <asm/sn/types.h> |
22 | #include <asm/sn/shubio.h> | 22 | #include <asm/sn/shubio.h> |
23 | #include <asm/sn/tiocx.h> | 23 | #include <asm/sn/tiocx.h> |
24 | #include <asm/sn/l1.h> | ||
25 | #include <asm/sn/module.h> | ||
24 | #include "tio.h" | 26 | #include "tio.h" |
25 | #include "xtalk/xwidgetdev.h" | 27 | #include "xtalk/xwidgetdev.h" |
26 | #include "xtalk/hubdev.h" | 28 | #include "xtalk/hubdev.h" |
@@ -308,14 +310,12 @@ void tiocx_irq_free(struct sn_irq_info *sn_irq_info) | |||
308 | } | 310 | } |
309 | } | 311 | } |
310 | 312 | ||
311 | uint64_t | 313 | uint64_t tiocx_dma_addr(uint64_t addr) |
312 | tiocx_dma_addr(uint64_t addr) | ||
313 | { | 314 | { |
314 | return PHYS_TO_TIODMA(addr); | 315 | return PHYS_TO_TIODMA(addr); |
315 | } | 316 | } |
316 | 317 | ||
317 | uint64_t | 318 | uint64_t tiocx_swin_base(int nasid) |
318 | tiocx_swin_base(int nasid) | ||
319 | { | 319 | { |
320 | return TIO_SWIN_BASE(nasid, TIOCX_CORELET); | 320 | return TIO_SWIN_BASE(nasid, TIOCX_CORELET); |
321 | } | 321 | } |
@@ -330,19 +330,6 @@ EXPORT_SYMBOL(tiocx_bus_type); | |||
330 | EXPORT_SYMBOL(tiocx_dma_addr); | 330 | EXPORT_SYMBOL(tiocx_dma_addr); |
331 | EXPORT_SYMBOL(tiocx_swin_base); | 331 | EXPORT_SYMBOL(tiocx_swin_base); |
332 | 332 | ||
333 | static uint64_t tiocx_get_hubdev_info(u64 handle, u64 address) | ||
334 | { | ||
335 | |||
336 | struct ia64_sal_retval ret_stuff; | ||
337 | ret_stuff.status = 0; | ||
338 | ret_stuff.v0 = 0; | ||
339 | |||
340 | ia64_sal_oemcall_nolock(&ret_stuff, | ||
341 | SN_SAL_IOIF_GET_HUBDEV_INFO, | ||
342 | handle, address, 0, 0, 0, 0, 0); | ||
343 | return ret_stuff.v0; | ||
344 | } | ||
345 | |||
346 | static void tio_conveyor_set(nasid_t nasid, int enable_flag) | 333 | static void tio_conveyor_set(nasid_t nasid, int enable_flag) |
347 | { | 334 | { |
348 | uint64_t ice_frz; | 335 | uint64_t ice_frz; |
@@ -379,7 +366,29 @@ static void tio_corelet_reset(nasid_t nasid, int corelet) | |||
379 | udelay(2000); | 366 | udelay(2000); |
380 | } | 367 | } |
381 | 368 | ||
382 | static int fpga_attached(nasid_t nasid) | 369 | static int tiocx_btchar_get(int nasid) |
370 | { | ||
371 | moduleid_t module_id; | ||
372 | geoid_t geoid; | ||
373 | int cnodeid; | ||
374 | |||
375 | cnodeid = nasid_to_cnodeid(nasid); | ||
376 | geoid = cnodeid_get_geoid(cnodeid); | ||
377 | module_id = geo_module(geoid); | ||
378 | return MODULE_GET_BTCHAR(module_id); | ||
379 | } | ||
380 | |||
381 | static int is_fpga_brick(int nasid) | ||
382 | { | ||
383 | switch (tiocx_btchar_get(nasid)) { | ||
384 | case L1_BRICKTYPE_SA: | ||
385 | case L1_BRICKTYPE_ATHENA: | ||
386 | return 1; | ||
387 | } | ||
388 | return 0; | ||
389 | } | ||
390 | |||
391 | static int bitstream_loaded(nasid_t nasid) | ||
383 | { | 392 | { |
384 | uint64_t cx_credits; | 393 | uint64_t cx_credits; |
385 | 394 | ||
@@ -396,7 +405,7 @@ static int tiocx_reload(struct cx_dev *cx_dev) | |||
396 | int mfg_num = CX_DEV_NONE; | 405 | int mfg_num = CX_DEV_NONE; |
397 | nasid_t nasid = cx_dev->cx_id.nasid; | 406 | nasid_t nasid = cx_dev->cx_id.nasid; |
398 | 407 | ||
399 | if (fpga_attached(nasid)) { | 408 | if (bitstream_loaded(nasid)) { |
400 | uint64_t cx_id; | 409 | uint64_t cx_id; |
401 | 410 | ||
402 | cx_id = | 411 | cx_id = |
@@ -427,9 +436,10 @@ static ssize_t show_cxdev_control(struct device *dev, char *buf) | |||
427 | { | 436 | { |
428 | struct cx_dev *cx_dev = to_cx_dev(dev); | 437 | struct cx_dev *cx_dev = to_cx_dev(dev); |
429 | 438 | ||
430 | return sprintf(buf, "0x%x 0x%x 0x%x\n", | 439 | return sprintf(buf, "0x%x 0x%x 0x%x %d\n", |
431 | cx_dev->cx_id.nasid, | 440 | cx_dev->cx_id.nasid, |
432 | cx_dev->cx_id.part_num, cx_dev->cx_id.mfg_num); | 441 | cx_dev->cx_id.part_num, cx_dev->cx_id.mfg_num, |
442 | tiocx_btchar_get(cx_dev->cx_id.nasid)); | ||
433 | } | 443 | } |
434 | 444 | ||
435 | static ssize_t store_cxdev_control(struct device *dev, const char *buf, | 445 | static ssize_t store_cxdev_control(struct device *dev, const char *buf, |
@@ -475,20 +485,14 @@ static int __init tiocx_init(void) | |||
475 | if ((nasid = cnodeid_to_nasid(cnodeid)) < 0) | 485 | if ((nasid = cnodeid_to_nasid(cnodeid)) < 0) |
476 | break; /* No more nasids .. bail out of loop */ | 486 | break; /* No more nasids .. bail out of loop */ |
477 | 487 | ||
478 | if (nasid & 0x1) { /* TIO's are always odd */ | 488 | if ((nasid & 0x1) && is_fpga_brick(nasid)) { |
479 | struct hubdev_info *hubdev; | 489 | struct hubdev_info *hubdev; |
480 | uint64_t status; | ||
481 | struct xwidget_info *widgetp; | 490 | struct xwidget_info *widgetp; |
482 | 491 | ||
483 | DBG("Found TIO at nasid 0x%x\n", nasid); | 492 | DBG("Found TIO at nasid 0x%x\n", nasid); |
484 | 493 | ||
485 | hubdev = | 494 | hubdev = |
486 | (struct hubdev_info *)(NODEPDA(cnodeid)->pdinfo); | 495 | (struct hubdev_info *)(NODEPDA(cnodeid)->pdinfo); |
487 | status = | ||
488 | tiocx_get_hubdev_info(nasid, | ||
489 | (uint64_t) __pa(hubdev)); | ||
490 | if (status) | ||
491 | continue; | ||
492 | 496 | ||
493 | widgetp = &hubdev->hdi_xwidget_info[TIOCX_CORELET]; | 497 | widgetp = &hubdev->hdi_xwidget_info[TIOCX_CORELET]; |
494 | 498 | ||
diff --git a/arch/ia64/sn/kernel/xp_main.c b/arch/ia64/sn/kernel/xp_main.c new file mode 100644 index 000000000000..3be52a34c80f --- /dev/null +++ b/arch/ia64/sn/kernel/xp_main.c | |||
@@ -0,0 +1,289 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved. | ||
7 | */ | ||
8 | |||
9 | |||
10 | /* | ||
11 | * Cross Partition (XP) base. | ||
12 | * | ||
13 | * XP provides a base from which its users can interact | ||
14 | * with XPC, yet not be dependent on XPC. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <asm/sn/intr.h> | ||
23 | #include <asm/sn/sn_sal.h> | ||
24 | #include <asm/sn/xp.h> | ||
25 | |||
26 | |||
27 | /* | ||
28 | * Target of nofault PIO read. | ||
29 | */ | ||
30 | u64 xp_nofault_PIOR_target; | ||
31 | |||
32 | |||
33 | /* | ||
34 | * xpc_registrations[] keeps track of xpc_connect()'s done by the kernel-level | ||
35 | * users of XPC. | ||
36 | */ | ||
37 | struct xpc_registration xpc_registrations[XPC_NCHANNELS]; | ||
38 | |||
39 | |||
40 | /* | ||
41 | * Initialize the XPC interface to indicate that XPC isn't loaded. | ||
42 | */ | ||
43 | static enum xpc_retval xpc_notloaded(void) { return xpcNotLoaded; } | ||
44 | |||
45 | struct xpc_interface xpc_interface = { | ||
46 | (void (*)(int)) xpc_notloaded, | ||
47 | (void (*)(int)) xpc_notloaded, | ||
48 | (enum xpc_retval (*)(partid_t, int, u32, void **)) xpc_notloaded, | ||
49 | (enum xpc_retval (*)(partid_t, int, void *)) xpc_notloaded, | ||
50 | (enum xpc_retval (*)(partid_t, int, void *, xpc_notify_func, void *)) | ||
51 | xpc_notloaded, | ||
52 | (void (*)(partid_t, int, void *)) xpc_notloaded, | ||
53 | (enum xpc_retval (*)(partid_t, void *)) xpc_notloaded | ||
54 | }; | ||
55 | |||
56 | |||
57 | /* | ||
58 | * XPC calls this when it (the XPC module) has been loaded. | ||
59 | */ | ||
60 | void | ||
61 | xpc_set_interface(void (*connect)(int), | ||
62 | void (*disconnect)(int), | ||
63 | enum xpc_retval (*allocate)(partid_t, int, u32, void **), | ||
64 | enum xpc_retval (*send)(partid_t, int, void *), | ||
65 | enum xpc_retval (*send_notify)(partid_t, int, void *, | ||
66 | xpc_notify_func, void *), | ||
67 | void (*received)(partid_t, int, void *), | ||
68 | enum xpc_retval (*partid_to_nasids)(partid_t, void *)) | ||
69 | { | ||
70 | xpc_interface.connect = connect; | ||
71 | xpc_interface.disconnect = disconnect; | ||
72 | xpc_interface.allocate = allocate; | ||
73 | xpc_interface.send = send; | ||
74 | xpc_interface.send_notify = send_notify; | ||
75 | xpc_interface.received = received; | ||
76 | xpc_interface.partid_to_nasids = partid_to_nasids; | ||
77 | } | ||
78 | |||
79 | |||
80 | /* | ||
81 | * XPC calls this when it (the XPC module) is being unloaded. | ||
82 | */ | ||
83 | void | ||
84 | xpc_clear_interface(void) | ||
85 | { | ||
86 | xpc_interface.connect = (void (*)(int)) xpc_notloaded; | ||
87 | xpc_interface.disconnect = (void (*)(int)) xpc_notloaded; | ||
88 | xpc_interface.allocate = (enum xpc_retval (*)(partid_t, int, u32, | ||
89 | void **)) xpc_notloaded; | ||
90 | xpc_interface.send = (enum xpc_retval (*)(partid_t, int, void *)) | ||
91 | xpc_notloaded; | ||
92 | xpc_interface.send_notify = (enum xpc_retval (*)(partid_t, int, void *, | ||
93 | xpc_notify_func, void *)) xpc_notloaded; | ||
94 | xpc_interface.received = (void (*)(partid_t, int, void *)) | ||
95 | xpc_notloaded; | ||
96 | xpc_interface.partid_to_nasids = (enum xpc_retval (*)(partid_t, void *)) | ||
97 | xpc_notloaded; | ||
98 | } | ||
99 | |||
100 | |||
101 | /* | ||
102 | * Register for automatic establishment of a channel connection whenever | ||
103 | * a partition comes up. | ||
104 | * | ||
105 | * Arguments: | ||
106 | * | ||
107 | * ch_number - channel # to register for connection. | ||
108 | * func - function to call for asynchronous notification of channel | ||
109 | * state changes (i.e., connection, disconnection, error) and | ||
110 | * the arrival of incoming messages. | ||
111 | * key - pointer to optional user-defined value that gets passed back | ||
112 | * to the user on any callouts made to func. | ||
113 | * payload_size - size in bytes of the XPC message's payload area which | ||
114 | * contains a user-defined message. The user should make | ||
115 | * this large enough to hold their largest message. | ||
116 | * nentries - max #of XPC message entries a message queue can contain. | ||
117 | * The actual number, which is determined when a connection | ||
118 | * is established and may be less then requested, will be | ||
119 | * passed to the user via the xpcConnected callout. | ||
120 | * assigned_limit - max number of kthreads allowed to be processing | ||
121 | * messages (per connection) at any given instant. | ||
122 | * idle_limit - max number of kthreads allowed to be idle at any given | ||
123 | * instant. | ||
124 | */ | ||
125 | enum xpc_retval | ||
126 | xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size, | ||
127 | u16 nentries, u32 assigned_limit, u32 idle_limit) | ||
128 | { | ||
129 | struct xpc_registration *registration; | ||
130 | |||
131 | |||
132 | DBUG_ON(ch_number < 0 || ch_number >= XPC_NCHANNELS); | ||
133 | DBUG_ON(payload_size == 0 || nentries == 0); | ||
134 | DBUG_ON(func == NULL); | ||
135 | DBUG_ON(assigned_limit == 0 || idle_limit > assigned_limit); | ||
136 | |||
137 | registration = &xpc_registrations[ch_number]; | ||
138 | |||
139 | if (down_interruptible(®istration->sema) != 0) { | ||
140 | return xpcInterrupted; | ||
141 | } | ||
142 | |||
143 | /* if XPC_CHANNEL_REGISTERED(ch_number) */ | ||
144 | if (registration->func != NULL) { | ||
145 | up(®istration->sema); | ||
146 | return xpcAlreadyRegistered; | ||
147 | } | ||
148 | |||
149 | /* register the channel for connection */ | ||
150 | registration->msg_size = XPC_MSG_SIZE(payload_size); | ||
151 | registration->nentries = nentries; | ||
152 | registration->assigned_limit = assigned_limit; | ||
153 | registration->idle_limit = idle_limit; | ||
154 | registration->key = key; | ||
155 | registration->func = func; | ||
156 | |||
157 | up(®istration->sema); | ||
158 | |||
159 | xpc_interface.connect(ch_number); | ||
160 | |||
161 | return xpcSuccess; | ||
162 | } | ||
163 | |||
164 | |||
165 | /* | ||
166 | * Remove the registration for automatic connection of the specified channel | ||
167 | * when a partition comes up. | ||
168 | * | ||
169 | * Before returning this xpc_disconnect() will wait for all connections on the | ||
170 | * specified channel have been closed/torndown. So the caller can be assured | ||
171 | * that they will not be receiving any more callouts from XPC to their | ||
172 | * function registered via xpc_connect(). | ||
173 | * | ||
174 | * Arguments: | ||
175 | * | ||
176 | * ch_number - channel # to unregister. | ||
177 | */ | ||
178 | void | ||
179 | xpc_disconnect(int ch_number) | ||
180 | { | ||
181 | struct xpc_registration *registration; | ||
182 | |||
183 | |||
184 | DBUG_ON(ch_number < 0 || ch_number >= XPC_NCHANNELS); | ||
185 | |||
186 | registration = &xpc_registrations[ch_number]; | ||
187 | |||
188 | /* | ||
189 | * We've decided not to make this a down_interruptible(), since we | ||
190 | * figured XPC's users will just turn around and call xpc_disconnect() | ||
191 | * again anyways, so we might as well wait, if need be. | ||
192 | */ | ||
193 | down(®istration->sema); | ||
194 | |||
195 | /* if !XPC_CHANNEL_REGISTERED(ch_number) */ | ||
196 | if (registration->func == NULL) { | ||
197 | up(®istration->sema); | ||
198 | return; | ||
199 | } | ||
200 | |||
201 | /* remove the connection registration for the specified channel */ | ||
202 | registration->func = NULL; | ||
203 | registration->key = NULL; | ||
204 | registration->nentries = 0; | ||
205 | registration->msg_size = 0; | ||
206 | registration->assigned_limit = 0; | ||
207 | registration->idle_limit = 0; | ||
208 | |||
209 | xpc_interface.disconnect(ch_number); | ||
210 | |||
211 | up(®istration->sema); | ||
212 | |||
213 | return; | ||
214 | } | ||
215 | |||
216 | |||
217 | int __init | ||
218 | xp_init(void) | ||
219 | { | ||
220 | int ret, ch_number; | ||
221 | u64 func_addr = *(u64 *) xp_nofault_PIOR; | ||
222 | u64 err_func_addr = *(u64 *) xp_error_PIOR; | ||
223 | |||
224 | |||
225 | if (!ia64_platform_is("sn2")) { | ||
226 | return -ENODEV; | ||
227 | } | ||
228 | |||
229 | /* | ||
230 | * Register a nofault code region which performs a cross-partition | ||
231 | * PIO read. If the PIO read times out, the MCA handler will consume | ||
232 | * the error and return to a kernel-provided instruction to indicate | ||
233 | * an error. This PIO read exists because it is guaranteed to timeout | ||
234 | * if the destination is down (AMO operations do not timeout on at | ||
235 | * least some CPUs on Shubs <= v1.2, which unfortunately we have to | ||
236 | * work around). | ||
237 | */ | ||
238 | if ((ret = sn_register_nofault_code(func_addr, err_func_addr, | ||
239 | err_func_addr, 1, 1)) != 0) { | ||
240 | printk(KERN_ERR "XP: can't register nofault code, error=%d\n", | ||
241 | ret); | ||
242 | } | ||
243 | /* | ||
244 | * Setup the nofault PIO read target. (There is no special reason why | ||
245 | * SH_IPI_ACCESS was selected.) | ||
246 | */ | ||
247 | if (is_shub2()) { | ||
248 | xp_nofault_PIOR_target = SH2_IPI_ACCESS0; | ||
249 | } else { | ||
250 | xp_nofault_PIOR_target = SH1_IPI_ACCESS; | ||
251 | } | ||
252 | |||
253 | /* initialize the connection registration semaphores */ | ||
254 | for (ch_number = 0; ch_number < XPC_NCHANNELS; ch_number++) { | ||
255 | sema_init(&xpc_registrations[ch_number].sema, 1); /* mutex */ | ||
256 | } | ||
257 | |||
258 | return 0; | ||
259 | } | ||
260 | module_init(xp_init); | ||
261 | |||
262 | |||
263 | void __exit | ||
264 | xp_exit(void) | ||
265 | { | ||
266 | u64 func_addr = *(u64 *) xp_nofault_PIOR; | ||
267 | u64 err_func_addr = *(u64 *) xp_error_PIOR; | ||
268 | |||
269 | |||
270 | /* unregister the PIO read nofault code region */ | ||
271 | (void) sn_register_nofault_code(func_addr, err_func_addr, | ||
272 | err_func_addr, 1, 0); | ||
273 | } | ||
274 | module_exit(xp_exit); | ||
275 | |||
276 | |||
277 | MODULE_AUTHOR("Silicon Graphics, Inc."); | ||
278 | MODULE_DESCRIPTION("Cross Partition (XP) base"); | ||
279 | MODULE_LICENSE("GPL"); | ||
280 | |||
281 | EXPORT_SYMBOL(xp_nofault_PIOR); | ||
282 | EXPORT_SYMBOL(xp_nofault_PIOR_target); | ||
283 | EXPORT_SYMBOL(xpc_registrations); | ||
284 | EXPORT_SYMBOL(xpc_interface); | ||
285 | EXPORT_SYMBOL(xpc_clear_interface); | ||
286 | EXPORT_SYMBOL(xpc_set_interface); | ||
287 | EXPORT_SYMBOL(xpc_connect); | ||
288 | EXPORT_SYMBOL(xpc_disconnect); | ||
289 | |||
diff --git a/arch/ia64/sn/kernel/xp_nofault.S b/arch/ia64/sn/kernel/xp_nofault.S new file mode 100644 index 000000000000..b772543053c9 --- /dev/null +++ b/arch/ia64/sn/kernel/xp_nofault.S | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved. | ||
7 | */ | ||
8 | |||
9 | |||
10 | /* | ||
11 | * The xp_nofault_PIOR function takes a pointer to a remote PIO register | ||
12 | * and attempts to load and consume a value from it. This function | ||
13 | * will be registered as a nofault code block. In the event that the | ||
14 | * PIO read fails, the MCA handler will force the error to look | ||
15 | * corrected and vector to the xp_error_PIOR which will return an error. | ||
16 | * | ||
17 | * extern int xp_nofault_PIOR(void *remote_register); | ||
18 | */ | ||
19 | |||
20 | .global xp_nofault_PIOR | ||
21 | xp_nofault_PIOR: | ||
22 | mov r8=r0 // Stage a success return value | ||
23 | ld8.acq r9=[r32];; // PIO Read the specified register | ||
24 | adds r9=1,r9 // Add to force a consume | ||
25 | br.ret.sptk.many b0;; // Return success | ||
26 | |||
27 | .global xp_error_PIOR | ||
28 | xp_error_PIOR: | ||
29 | mov r8=1 // Return value of 1 | ||
30 | br.ret.sptk.many b0;; // Return failure | ||
31 | |||
diff --git a/arch/ia64/sn/kernel/xpc.h b/arch/ia64/sn/kernel/xpc.h new file mode 100644 index 000000000000..1a0aed8490d1 --- /dev/null +++ b/arch/ia64/sn/kernel/xpc.h | |||
@@ -0,0 +1,991 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved. | ||
7 | */ | ||
8 | |||
9 | |||
10 | /* | ||
11 | * Cross Partition Communication (XPC) structures and macros. | ||
12 | */ | ||
13 | |||
14 | #ifndef _IA64_SN_KERNEL_XPC_H | ||
15 | #define _IA64_SN_KERNEL_XPC_H | ||
16 | |||
17 | |||
18 | #include <linux/config.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/sysctl.h> | ||
21 | #include <linux/device.h> | ||
22 | #include <asm/pgtable.h> | ||
23 | #include <asm/processor.h> | ||
24 | #include <asm/sn/bte.h> | ||
25 | #include <asm/sn/clksupport.h> | ||
26 | #include <asm/sn/addrs.h> | ||
27 | #include <asm/sn/mspec.h> | ||
28 | #include <asm/sn/shub_mmr.h> | ||
29 | #include <asm/sn/xp.h> | ||
30 | |||
31 | |||
32 | /* | ||
33 | * XPC Version numbers consist of a major and minor number. XPC can always | ||
34 | * talk to versions with same major #, and never talk to versions with a | ||
35 | * different major #. | ||
36 | */ | ||
37 | #define _XPC_VERSION(_maj, _min) (((_maj) << 4) | ((_min) & 0xf)) | ||
38 | #define XPC_VERSION_MAJOR(_v) ((_v) >> 4) | ||
39 | #define XPC_VERSION_MINOR(_v) ((_v) & 0xf) | ||
40 | |||
41 | |||
42 | /* | ||
43 | * The next macros define word or bit representations for given | ||
44 | * C-brick nasid in either the SAL provided bit array representing | ||
45 | * nasids in the partition/machine or the AMO_t array used for | ||
46 | * inter-partition initiation communications. | ||
47 | * | ||
48 | * For SN2 machines, C-Bricks are alway even numbered NASIDs. As | ||
49 | * such, some space will be saved by insisting that nasid information | ||
50 | * passed from SAL always be packed for C-Bricks and the | ||
51 | * cross-partition interrupts use the same packing scheme. | ||
52 | */ | ||
53 | #define XPC_NASID_W_INDEX(_n) (((_n) / 64) / 2) | ||
54 | #define XPC_NASID_B_INDEX(_n) (((_n) / 2) & (64 - 1)) | ||
55 | #define XPC_NASID_IN_ARRAY(_n, _p) ((_p)[XPC_NASID_W_INDEX(_n)] & \ | ||
56 | (1UL << XPC_NASID_B_INDEX(_n))) | ||
57 | #define XPC_NASID_FROM_W_B(_w, _b) (((_w) * 64 + (_b)) * 2) | ||
58 | |||
59 | #define XPC_HB_DEFAULT_INTERVAL 5 /* incr HB every x secs */ | ||
60 | #define XPC_HB_CHECK_DEFAULT_TIMEOUT 20 /* check HB every x secs */ | ||
61 | |||
62 | /* define the process name of HB checker and the CPU it is pinned to */ | ||
63 | #define XPC_HB_CHECK_THREAD_NAME "xpc_hb" | ||
64 | #define XPC_HB_CHECK_CPU 0 | ||
65 | |||
66 | /* define the process name of the discovery thread */ | ||
67 | #define XPC_DISCOVERY_THREAD_NAME "xpc_discovery" | ||
68 | |||
69 | |||
70 | #define XPC_HB_ALLOWED(_p, _v) ((_v)->heartbeating_to_mask & (1UL << (_p))) | ||
71 | #define XPC_ALLOW_HB(_p, _v) (_v)->heartbeating_to_mask |= (1UL << (_p)) | ||
72 | #define XPC_DISALLOW_HB(_p, _v) (_v)->heartbeating_to_mask &= (~(1UL << (_p))) | ||
73 | |||
74 | |||
75 | /* | ||
76 | * Reserved Page provided by SAL. | ||
77 | * | ||
78 | * SAL provides one page per partition of reserved memory. When SAL | ||
79 | * initialization is complete, SAL_signature, SAL_version, partid, | ||
80 | * part_nasids, and mach_nasids are set. | ||
81 | * | ||
82 | * Note: Until vars_pa is set, the partition XPC code has not been initialized. | ||
83 | */ | ||
84 | struct xpc_rsvd_page { | ||
85 | u64 SAL_signature; /* SAL unique signature */ | ||
86 | u64 SAL_version; /* SAL specified version */ | ||
87 | u8 partid; /* partition ID from SAL */ | ||
88 | u8 version; | ||
89 | u8 pad[6]; /* pad to u64 align */ | ||
90 | u64 vars_pa; | ||
91 | u64 part_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned; | ||
92 | u64 mach_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned; | ||
93 | }; | ||
94 | #define XPC_RP_VERSION _XPC_VERSION(1,0) /* version 1.0 of the reserved page */ | ||
95 | |||
96 | #define XPC_RSVD_PAGE_ALIGNED_SIZE \ | ||
97 | (L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page))) | ||
98 | |||
99 | |||
100 | /* | ||
101 | * Define the structures by which XPC variables can be exported to other | ||
102 | * partitions. (There are two: struct xpc_vars and struct xpc_vars_part) | ||
103 | */ | ||
104 | |||
105 | /* | ||
106 | * The following structure describes the partition generic variables | ||
107 | * needed by other partitions in order to properly initialize. | ||
108 | * | ||
109 | * struct xpc_vars version number also applies to struct xpc_vars_part. | ||
110 | * Changes to either structure and/or related functionality should be | ||
111 | * reflected by incrementing either the major or minor version numbers | ||
112 | * of struct xpc_vars. | ||
113 | */ | ||
114 | struct xpc_vars { | ||
115 | u8 version; | ||
116 | u64 heartbeat; | ||
117 | u64 heartbeating_to_mask; | ||
118 | u64 kdb_status; /* 0 = machine running */ | ||
119 | int act_nasid; | ||
120 | int act_phys_cpuid; | ||
121 | u64 vars_part_pa; | ||
122 | u64 amos_page_pa; /* paddr of page of AMOs from MSPEC driver */ | ||
123 | AMO_t *amos_page; /* vaddr of page of AMOs from MSPEC driver */ | ||
124 | AMO_t *act_amos; /* pointer to the first activation AMO */ | ||
125 | }; | ||
126 | #define XPC_V_VERSION _XPC_VERSION(3,0) /* version 3.0 of the cross vars */ | ||
127 | |||
128 | #define XPC_VARS_ALIGNED_SIZE (L1_CACHE_ALIGN(sizeof(struct xpc_vars))) | ||
129 | |||
130 | /* | ||
131 | * The following structure describes the per partition specific variables. | ||
132 | * | ||
133 | * An array of these structures, one per partition, will be defined. As a | ||
134 | * partition becomes active XPC will copy the array entry corresponding to | ||
135 | * itself from that partition. It is desirable that the size of this | ||
136 | * structure evenly divide into a cacheline, such that none of the entries | ||
137 | * in this array crosses a cacheline boundary. As it is now, each entry | ||
138 | * occupies half a cacheline. | ||
139 | */ | ||
140 | struct xpc_vars_part { | ||
141 | u64 magic; | ||
142 | |||
143 | u64 openclose_args_pa; /* physical address of open and close args */ | ||
144 | u64 GPs_pa; /* physical address of Get/Put values */ | ||
145 | |||
146 | u64 IPI_amo_pa; /* physical address of IPI AMO_t structure */ | ||
147 | int IPI_nasid; /* nasid of where to send IPIs */ | ||
148 | int IPI_phys_cpuid; /* physical CPU ID of where to send IPIs */ | ||
149 | |||
150 | u8 nchannels; /* #of defined channels supported */ | ||
151 | |||
152 | u8 reserved[23]; /* pad to a full 64 bytes */ | ||
153 | }; | ||
154 | |||
155 | /* | ||
156 | * The vars_part MAGIC numbers play a part in the first contact protocol. | ||
157 | * | ||
158 | * MAGIC1 indicates that the per partition specific variables for a remote | ||
159 | * partition have been initialized by this partition. | ||
160 | * | ||
161 | * MAGIC2 indicates that this partition has pulled the remote partititions | ||
162 | * per partition variables that pertain to this partition. | ||
163 | */ | ||
164 | #define XPC_VP_MAGIC1 0x0053524156435058L /* 'XPCVARS\0'L (little endian) */ | ||
165 | #define XPC_VP_MAGIC2 0x0073726176435058L /* 'XPCvars\0'L (little endian) */ | ||
166 | |||
167 | |||
168 | |||
169 | /* | ||
170 | * Functions registered by add_timer() or called by kernel_thread() only | ||
171 | * allow for a single 64-bit argument. The following macros can be used to | ||
172 | * pack and unpack two (32-bit, 16-bit or 8-bit) arguments into or out from | ||
173 | * the passed argument. | ||
174 | */ | ||
175 | #define XPC_PACK_ARGS(_arg1, _arg2) \ | ||
176 | ((((u64) _arg1) & 0xffffffff) | \ | ||
177 | ((((u64) _arg2) & 0xffffffff) << 32)) | ||
178 | |||
179 | #define XPC_UNPACK_ARG1(_args) (((u64) _args) & 0xffffffff) | ||
180 | #define XPC_UNPACK_ARG2(_args) ((((u64) _args) >> 32) & 0xffffffff) | ||
181 | |||
182 | |||
183 | |||
184 | /* | ||
185 | * Define a Get/Put value pair (pointers) used with a message queue. | ||
186 | */ | ||
187 | struct xpc_gp { | ||
188 | s64 get; /* Get value */ | ||
189 | s64 put; /* Put value */ | ||
190 | }; | ||
191 | |||
192 | #define XPC_GP_SIZE \ | ||
193 | L1_CACHE_ALIGN(sizeof(struct xpc_gp) * XPC_NCHANNELS) | ||
194 | |||
195 | |||
196 | |||
197 | /* | ||
198 | * Define a structure that contains arguments associated with opening and | ||
199 | * closing a channel. | ||
200 | */ | ||
201 | struct xpc_openclose_args { | ||
202 | u16 reason; /* reason why channel is closing */ | ||
203 | u16 msg_size; /* sizeof each message entry */ | ||
204 | u16 remote_nentries; /* #of message entries in remote msg queue */ | ||
205 | u16 local_nentries; /* #of message entries in local msg queue */ | ||
206 | u64 local_msgqueue_pa; /* physical address of local message queue */ | ||
207 | }; | ||
208 | |||
209 | #define XPC_OPENCLOSE_ARGS_SIZE \ | ||
210 | L1_CACHE_ALIGN(sizeof(struct xpc_openclose_args) * XPC_NCHANNELS) | ||
211 | |||
212 | |||
213 | |||
214 | /* struct xpc_msg flags */ | ||
215 | |||
216 | #define XPC_M_DONE 0x01 /* msg has been received/consumed */ | ||
217 | #define XPC_M_READY 0x02 /* msg is ready to be sent */ | ||
218 | #define XPC_M_INTERRUPT 0x04 /* send interrupt when msg consumed */ | ||
219 | |||
220 | |||
221 | #define XPC_MSG_ADDRESS(_payload) \ | ||
222 | ((struct xpc_msg *)((u8 *)(_payload) - XPC_MSG_PAYLOAD_OFFSET)) | ||
223 | |||
224 | |||
225 | |||
226 | /* | ||
227 | * Defines notify entry. | ||
228 | * | ||
229 | * This is used to notify a message's sender that their message was received | ||
230 | * and consumed by the intended recipient. | ||
231 | */ | ||
232 | struct xpc_notify { | ||
233 | struct semaphore sema; /* notify semaphore */ | ||
234 | u8 type; /* type of notification */ | ||
235 | |||
236 | /* the following two fields are only used if type == XPC_N_CALL */ | ||
237 | xpc_notify_func func; /* user's notify function */ | ||
238 | void *key; /* pointer to user's key */ | ||
239 | }; | ||
240 | |||
241 | /* struct xpc_notify type of notification */ | ||
242 | |||
243 | #define XPC_N_CALL 0x01 /* notify function provided by user */ | ||
244 | |||
245 | |||
246 | |||
247 | /* | ||
248 | * Define the structure that manages all the stuff required by a channel. In | ||
249 | * particular, they are used to manage the messages sent across the channel. | ||
250 | * | ||
251 | * This structure is private to a partition, and is NOT shared across the | ||
252 | * partition boundary. | ||
253 | * | ||
254 | * There is an array of these structures for each remote partition. It is | ||
255 | * allocated at the time a partition becomes active. The array contains one | ||
256 | * of these structures for each potential channel connection to that partition. | ||
257 | * | ||
258 | * Each of these structures manages two message queues (circular buffers). | ||
259 | * They are allocated at the time a channel connection is made. One of | ||
260 | * these message queues (local_msgqueue) holds the locally created messages | ||
261 | * that are destined for the remote partition. The other of these message | ||
262 | * queues (remote_msgqueue) is a locally cached copy of the remote partition's | ||
263 | * own local_msgqueue. | ||
264 | * | ||
265 | * The following is a description of the Get/Put pointers used to manage these | ||
266 | * two message queues. Consider the local_msgqueue to be on one partition | ||
267 | * and the remote_msgqueue to be its cached copy on another partition. A | ||
268 | * description of what each of the lettered areas contains is included. | ||
269 | * | ||
270 | * | ||
271 | * local_msgqueue remote_msgqueue | ||
272 | * | ||
273 | * |/////////| |/////////| | ||
274 | * w_remote_GP.get --> +---------+ |/////////| | ||
275 | * | F | |/////////| | ||
276 | * remote_GP.get --> +---------+ +---------+ <-- local_GP->get | ||
277 | * | | | | | ||
278 | * | | | E | | ||
279 | * | | | | | ||
280 | * | | +---------+ <-- w_local_GP.get | ||
281 | * | B | |/////////| | ||
282 | * | | |////D////| | ||
283 | * | | |/////////| | ||
284 | * | | +---------+ <-- w_remote_GP.put | ||
285 | * | | |////C////| | ||
286 | * local_GP->put --> +---------+ +---------+ <-- remote_GP.put | ||
287 | * | | |/////////| | ||
288 | * | A | |/////////| | ||
289 | * | | |/////////| | ||
290 | * w_local_GP.put --> +---------+ |/////////| | ||
291 | * |/////////| |/////////| | ||
292 | * | ||
293 | * | ||
294 | * ( remote_GP.[get|put] are cached copies of the remote | ||
295 | * partition's local_GP->[get|put], and thus their values can | ||
296 | * lag behind their counterparts on the remote partition. ) | ||
297 | * | ||
298 | * | ||
299 | * A - Messages that have been allocated, but have not yet been sent to the | ||
300 | * remote partition. | ||
301 | * | ||
302 | * B - Messages that have been sent, but have not yet been acknowledged by the | ||
303 | * remote partition as having been received. | ||
304 | * | ||
305 | * C - Area that needs to be prepared for the copying of sent messages, by | ||
306 | * the clearing of the message flags of any previously received messages. | ||
307 | * | ||
308 | * D - Area into which sent messages are to be copied from the remote | ||
309 | * partition's local_msgqueue and then delivered to their intended | ||
310 | * recipients. [ To allow for a multi-message copy, another pointer | ||
311 | * (next_msg_to_pull) has been added to keep track of the next message | ||
312 | * number needing to be copied (pulled). It chases after w_remote_GP.put. | ||
313 | * Any messages lying between w_local_GP.get and next_msg_to_pull have | ||
314 | * been copied and are ready to be delivered. ] | ||
315 | * | ||
316 | * E - Messages that have been copied and delivered, but have not yet been | ||
317 | * acknowledged by the recipient as having been received. | ||
318 | * | ||
319 | * F - Messages that have been acknowledged, but XPC has not yet notified the | ||
320 | * sender that the message was received by its intended recipient. | ||
321 | * This is also an area that needs to be prepared for the allocating of | ||
322 | * new messages, by the clearing of the message flags of the acknowledged | ||
323 | * messages. | ||
324 | */ | ||
325 | struct xpc_channel { | ||
326 | partid_t partid; /* ID of remote partition connected */ | ||
327 | spinlock_t lock; /* lock for updating this structure */ | ||
328 | u32 flags; /* general flags */ | ||
329 | |||
330 | enum xpc_retval reason; /* reason why channel is disconnect'g */ | ||
331 | int reason_line; /* line# disconnect initiated from */ | ||
332 | |||
333 | u16 number; /* channel # */ | ||
334 | |||
335 | u16 msg_size; /* sizeof each msg entry */ | ||
336 | u16 local_nentries; /* #of msg entries in local msg queue */ | ||
337 | u16 remote_nentries; /* #of msg entries in remote msg queue*/ | ||
338 | |||
339 | void *local_msgqueue_base; /* base address of kmalloc'd space */ | ||
340 | struct xpc_msg *local_msgqueue; /* local message queue */ | ||
341 | void *remote_msgqueue_base; /* base address of kmalloc'd space */ | ||
342 | struct xpc_msg *remote_msgqueue;/* cached copy of remote partition's */ | ||
343 | /* local message queue */ | ||
344 | u64 remote_msgqueue_pa; /* phys addr of remote partition's */ | ||
345 | /* local message queue */ | ||
346 | |||
347 | atomic_t references; /* #of external references to queues */ | ||
348 | |||
349 | atomic_t n_on_msg_allocate_wq; /* #on msg allocation wait queue */ | ||
350 | wait_queue_head_t msg_allocate_wq; /* msg allocation wait queue */ | ||
351 | |||
352 | /* queue of msg senders who want to be notified when msg received */ | ||
353 | |||
354 | atomic_t n_to_notify; /* #of msg senders to notify */ | ||
355 | struct xpc_notify *notify_queue;/* notify queue for messages sent */ | ||
356 | |||
357 | xpc_channel_func func; /* user's channel function */ | ||
358 | void *key; /* pointer to user's key */ | ||
359 | |||
360 | struct semaphore msg_to_pull_sema; /* next msg to pull serialization */ | ||
361 | struct semaphore teardown_sema; /* wait for teardown completion */ | ||
362 | |||
363 | struct xpc_openclose_args *local_openclose_args; /* args passed on */ | ||
364 | /* opening or closing of channel */ | ||
365 | |||
366 | /* various flavors of local and remote Get/Put values */ | ||
367 | |||
368 | struct xpc_gp *local_GP; /* local Get/Put values */ | ||
369 | struct xpc_gp remote_GP; /* remote Get/Put values */ | ||
370 | struct xpc_gp w_local_GP; /* working local Get/Put values */ | ||
371 | struct xpc_gp w_remote_GP; /* working remote Get/Put values */ | ||
372 | s64 next_msg_to_pull; /* Put value of next msg to pull */ | ||
373 | |||
374 | /* kthread management related fields */ | ||
375 | |||
376 | // >>> rethink having kthreads_assigned_limit and kthreads_idle_limit; perhaps | ||
377 | // >>> allow the assigned limit be unbounded and let the idle limit be dynamic | ||
378 | // >>> dependent on activity over the last interval of time | ||
379 | atomic_t kthreads_assigned; /* #of kthreads assigned to channel */ | ||
380 | u32 kthreads_assigned_limit; /* limit on #of kthreads assigned */ | ||
381 | atomic_t kthreads_idle; /* #of kthreads idle waiting for work */ | ||
382 | u32 kthreads_idle_limit; /* limit on #of kthreads idle */ | ||
383 | atomic_t kthreads_active; /* #of kthreads actively working */ | ||
384 | // >>> following field is temporary | ||
385 | u32 kthreads_created; /* total #of kthreads created */ | ||
386 | |||
387 | wait_queue_head_t idle_wq; /* idle kthread wait queue */ | ||
388 | |||
389 | } ____cacheline_aligned; | ||
390 | |||
391 | |||
392 | /* struct xpc_channel flags */ | ||
393 | |||
394 | #define XPC_C_WASCONNECTED 0x00000001 /* channel was connected */ | ||
395 | |||
396 | #define XPC_C_ROPENREPLY 0x00000002 /* remote open channel reply */ | ||
397 | #define XPC_C_OPENREPLY 0x00000004 /* local open channel reply */ | ||
398 | #define XPC_C_ROPENREQUEST 0x00000008 /* remote open channel request */ | ||
399 | #define XPC_C_OPENREQUEST 0x00000010 /* local open channel request */ | ||
400 | |||
401 | #define XPC_C_SETUP 0x00000020 /* channel's msgqueues are alloc'd */ | ||
402 | #define XPC_C_CONNECTCALLOUT 0x00000040 /* channel connected callout made */ | ||
403 | #define XPC_C_CONNECTED 0x00000080 /* local channel is connected */ | ||
404 | #define XPC_C_CONNECTING 0x00000100 /* channel is being connected */ | ||
405 | |||
406 | #define XPC_C_RCLOSEREPLY 0x00000200 /* remote close channel reply */ | ||
407 | #define XPC_C_CLOSEREPLY 0x00000400 /* local close channel reply */ | ||
408 | #define XPC_C_RCLOSEREQUEST 0x00000800 /* remote close channel request */ | ||
409 | #define XPC_C_CLOSEREQUEST 0x00001000 /* local close channel request */ | ||
410 | |||
411 | #define XPC_C_DISCONNECTED 0x00002000 /* channel is disconnected */ | ||
412 | #define XPC_C_DISCONNECTING 0x00004000 /* channel is being disconnected */ | ||
413 | |||
414 | |||
415 | |||
416 | /* | ||
417 | * Manages channels on a partition basis. There is one of these structures | ||
418 | * for each partition (a partition will never utilize the structure that | ||
419 | * represents itself). | ||
420 | */ | ||
421 | struct xpc_partition { | ||
422 | |||
423 | /* XPC HB infrastructure */ | ||
424 | |||
425 | u64 remote_rp_pa; /* phys addr of partition's rsvd pg */ | ||
426 | u64 remote_vars_pa; /* phys addr of partition's vars */ | ||
427 | u64 remote_vars_part_pa; /* phys addr of partition's vars part */ | ||
428 | u64 last_heartbeat; /* HB at last read */ | ||
429 | u64 remote_amos_page_pa; /* phys addr of partition's amos page */ | ||
430 | int remote_act_nasid; /* active part's act/deact nasid */ | ||
431 | int remote_act_phys_cpuid; /* active part's act/deact phys cpuid */ | ||
432 | u32 act_IRQ_rcvd; /* IRQs since activation */ | ||
433 | spinlock_t act_lock; /* protect updating of act_state */ | ||
434 | u8 act_state; /* from XPC HB viewpoint */ | ||
435 | enum xpc_retval reason; /* reason partition is deactivating */ | ||
436 | int reason_line; /* line# deactivation initiated from */ | ||
437 | int reactivate_nasid; /* nasid in partition to reactivate */ | ||
438 | |||
439 | |||
440 | /* XPC infrastructure referencing and teardown control */ | ||
441 | |||
442 | u8 setup_state; /* infrastructure setup state */ | ||
443 | wait_queue_head_t teardown_wq; /* kthread waiting to teardown infra */ | ||
444 | atomic_t references; /* #of references to infrastructure */ | ||
445 | |||
446 | |||
447 | /* | ||
448 | * NONE OF THE PRECEDING FIELDS OF THIS STRUCTURE WILL BE CLEARED WHEN | ||
449 | * XPC SETS UP THE NECESSARY INFRASTRUCTURE TO SUPPORT CROSS PARTITION | ||
450 | * COMMUNICATION. ALL OF THE FOLLOWING FIELDS WILL BE CLEARED. (THE | ||
451 | * 'nchannels' FIELD MUST BE THE FIRST OF THE FIELDS TO BE CLEARED.) | ||
452 | */ | ||
453 | |||
454 | |||
455 | u8 nchannels; /* #of defined channels supported */ | ||
456 | atomic_t nchannels_active; /* #of channels that are not DISCONNECTED */ | ||
457 | struct xpc_channel *channels;/* array of channel structures */ | ||
458 | |||
459 | void *local_GPs_base; /* base address of kmalloc'd space */ | ||
460 | struct xpc_gp *local_GPs; /* local Get/Put values */ | ||
461 | void *remote_GPs_base; /* base address of kmalloc'd space */ | ||
462 | struct xpc_gp *remote_GPs;/* copy of remote partition's local Get/Put */ | ||
463 | /* values */ | ||
464 | u64 remote_GPs_pa; /* phys address of remote partition's local */ | ||
465 | /* Get/Put values */ | ||
466 | |||
467 | |||
468 | /* fields used to pass args when opening or closing a channel */ | ||
469 | |||
470 | void *local_openclose_args_base; /* base address of kmalloc'd space */ | ||
471 | struct xpc_openclose_args *local_openclose_args; /* local's args */ | ||
472 | void *remote_openclose_args_base; /* base address of kmalloc'd space */ | ||
473 | struct xpc_openclose_args *remote_openclose_args; /* copy of remote's */ | ||
474 | /* args */ | ||
475 | u64 remote_openclose_args_pa; /* phys addr of remote's args */ | ||
476 | |||
477 | |||
478 | /* IPI sending, receiving and handling related fields */ | ||
479 | |||
480 | int remote_IPI_nasid; /* nasid of where to send IPIs */ | ||
481 | int remote_IPI_phys_cpuid; /* phys CPU ID of where to send IPIs */ | ||
482 | AMO_t *remote_IPI_amo_va; /* address of remote IPI AMO_t structure */ | ||
483 | |||
484 | AMO_t *local_IPI_amo_va; /* address of IPI AMO_t structure */ | ||
485 | u64 local_IPI_amo; /* IPI amo flags yet to be handled */ | ||
486 | char IPI_owner[8]; /* IPI owner's name */ | ||
487 | struct timer_list dropped_IPI_timer; /* dropped IPI timer */ | ||
488 | |||
489 | spinlock_t IPI_lock; /* IPI handler lock */ | ||
490 | |||
491 | |||
492 | /* channel manager related fields */ | ||
493 | |||
494 | atomic_t channel_mgr_requests; /* #of requests to activate chan mgr */ | ||
495 | wait_queue_head_t channel_mgr_wq; /* channel mgr's wait queue */ | ||
496 | |||
497 | } ____cacheline_aligned; | ||
498 | |||
499 | |||
500 | /* struct xpc_partition act_state values (for XPC HB) */ | ||
501 | |||
502 | #define XPC_P_INACTIVE 0x00 /* partition is not active */ | ||
503 | #define XPC_P_ACTIVATION_REQ 0x01 /* created thread to activate */ | ||
504 | #define XPC_P_ACTIVATING 0x02 /* activation thread started */ | ||
505 | #define XPC_P_ACTIVE 0x03 /* xpc_partition_up() was called */ | ||
506 | #define XPC_P_DEACTIVATING 0x04 /* partition deactivation initiated */ | ||
507 | |||
508 | |||
509 | #define XPC_DEACTIVATE_PARTITION(_p, _reason) \ | ||
510 | xpc_deactivate_partition(__LINE__, (_p), (_reason)) | ||
511 | |||
512 | |||
513 | /* struct xpc_partition setup_state values */ | ||
514 | |||
515 | #define XPC_P_UNSET 0x00 /* infrastructure was never setup */ | ||
516 | #define XPC_P_SETUP 0x01 /* infrastructure is setup */ | ||
517 | #define XPC_P_WTEARDOWN 0x02 /* waiting to teardown infrastructure */ | ||
518 | #define XPC_P_TORNDOWN 0x03 /* infrastructure is torndown */ | ||
519 | |||
520 | |||
521 | /* | ||
522 | * struct xpc_partition IPI_timer #of seconds to wait before checking for | ||
523 | * dropped IPIs. These occur whenever an IPI amo write doesn't complete until | ||
524 | * after the IPI was received. | ||
525 | */ | ||
526 | #define XPC_P_DROPPED_IPI_WAIT (0.25 * HZ) | ||
527 | |||
528 | |||
529 | #define XPC_PARTID(_p) ((partid_t) ((_p) - &xpc_partitions[0])) | ||
530 | |||
531 | |||
532 | |||
533 | /* found in xp_main.c */ | ||
534 | extern struct xpc_registration xpc_registrations[]; | ||
535 | |||
536 | |||
537 | /* >>> found in xpc_main.c only */ | ||
538 | extern struct device *xpc_part; | ||
539 | extern struct device *xpc_chan; | ||
540 | extern irqreturn_t xpc_notify_IRQ_handler(int, void *, struct pt_regs *); | ||
541 | extern void xpc_dropped_IPI_check(struct xpc_partition *); | ||
542 | extern void xpc_activate_kthreads(struct xpc_channel *, int); | ||
543 | extern void xpc_create_kthreads(struct xpc_channel *, int); | ||
544 | extern void xpc_disconnect_wait(int); | ||
545 | |||
546 | |||
547 | /* found in xpc_main.c and efi-xpc.c */ | ||
548 | extern void xpc_activate_partition(struct xpc_partition *); | ||
549 | |||
550 | |||
551 | /* found in xpc_partition.c */ | ||
552 | extern int xpc_exiting; | ||
553 | extern int xpc_hb_interval; | ||
554 | extern int xpc_hb_check_interval; | ||
555 | extern struct xpc_vars *xpc_vars; | ||
556 | extern struct xpc_rsvd_page *xpc_rsvd_page; | ||
557 | extern struct xpc_vars_part *xpc_vars_part; | ||
558 | extern struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1]; | ||
559 | extern char xpc_remote_copy_buffer[]; | ||
560 | extern struct xpc_rsvd_page *xpc_rsvd_page_init(void); | ||
561 | extern void xpc_allow_IPI_ops(void); | ||
562 | extern void xpc_restrict_IPI_ops(void); | ||
563 | extern int xpc_identify_act_IRQ_sender(void); | ||
564 | extern enum xpc_retval xpc_mark_partition_active(struct xpc_partition *); | ||
565 | extern void xpc_mark_partition_inactive(struct xpc_partition *); | ||
566 | extern void xpc_discovery(void); | ||
567 | extern void xpc_check_remote_hb(void); | ||
568 | extern void xpc_deactivate_partition(const int, struct xpc_partition *, | ||
569 | enum xpc_retval); | ||
570 | extern enum xpc_retval xpc_initiate_partid_to_nasids(partid_t, void *); | ||
571 | |||
572 | |||
573 | /* found in xpc_channel.c */ | ||
574 | extern void xpc_initiate_connect(int); | ||
575 | extern void xpc_initiate_disconnect(int); | ||
576 | extern enum xpc_retval xpc_initiate_allocate(partid_t, int, u32, void **); | ||
577 | extern enum xpc_retval xpc_initiate_send(partid_t, int, void *); | ||
578 | extern enum xpc_retval xpc_initiate_send_notify(partid_t, int, void *, | ||
579 | xpc_notify_func, void *); | ||
580 | extern void xpc_initiate_received(partid_t, int, void *); | ||
581 | extern enum xpc_retval xpc_setup_infrastructure(struct xpc_partition *); | ||
582 | extern enum xpc_retval xpc_pull_remote_vars_part(struct xpc_partition *); | ||
583 | extern void xpc_process_channel_activity(struct xpc_partition *); | ||
584 | extern void xpc_connected_callout(struct xpc_channel *); | ||
585 | extern void xpc_deliver_msg(struct xpc_channel *); | ||
586 | extern void xpc_disconnect_channel(const int, struct xpc_channel *, | ||
587 | enum xpc_retval, unsigned long *); | ||
588 | extern void xpc_disconnected_callout(struct xpc_channel *); | ||
589 | extern void xpc_partition_down(struct xpc_partition *, enum xpc_retval); | ||
590 | extern void xpc_teardown_infrastructure(struct xpc_partition *); | ||
591 | |||
592 | |||
593 | |||
594 | static inline void | ||
595 | xpc_wakeup_channel_mgr(struct xpc_partition *part) | ||
596 | { | ||
597 | if (atomic_inc_return(&part->channel_mgr_requests) == 1) { | ||
598 | wake_up(&part->channel_mgr_wq); | ||
599 | } | ||
600 | } | ||
601 | |||
602 | |||
603 | |||
604 | /* | ||
605 | * These next two inlines are used to keep us from tearing down a channel's | ||
606 | * msg queues while a thread may be referencing them. | ||
607 | */ | ||
608 | static inline void | ||
609 | xpc_msgqueue_ref(struct xpc_channel *ch) | ||
610 | { | ||
611 | atomic_inc(&ch->references); | ||
612 | } | ||
613 | |||
614 | static inline void | ||
615 | xpc_msgqueue_deref(struct xpc_channel *ch) | ||
616 | { | ||
617 | s32 refs = atomic_dec_return(&ch->references); | ||
618 | |||
619 | DBUG_ON(refs < 0); | ||
620 | if (refs == 0) { | ||
621 | xpc_wakeup_channel_mgr(&xpc_partitions[ch->partid]); | ||
622 | } | ||
623 | } | ||
624 | |||
625 | |||
626 | |||
627 | #define XPC_DISCONNECT_CHANNEL(_ch, _reason, _irqflgs) \ | ||
628 | xpc_disconnect_channel(__LINE__, _ch, _reason, _irqflgs) | ||
629 | |||
630 | |||
631 | /* | ||
632 | * These two inlines are used to keep us from tearing down a partition's | ||
633 | * setup infrastructure while a thread may be referencing it. | ||
634 | */ | ||
635 | static inline void | ||
636 | xpc_part_deref(struct xpc_partition *part) | ||
637 | { | ||
638 | s32 refs = atomic_dec_return(&part->references); | ||
639 | |||
640 | |||
641 | DBUG_ON(refs < 0); | ||
642 | if (refs == 0 && part->setup_state == XPC_P_WTEARDOWN) { | ||
643 | wake_up(&part->teardown_wq); | ||
644 | } | ||
645 | } | ||
646 | |||
647 | static inline int | ||
648 | xpc_part_ref(struct xpc_partition *part) | ||
649 | { | ||
650 | int setup; | ||
651 | |||
652 | |||
653 | atomic_inc(&part->references); | ||
654 | setup = (part->setup_state == XPC_P_SETUP); | ||
655 | if (!setup) { | ||
656 | xpc_part_deref(part); | ||
657 | } | ||
658 | return setup; | ||
659 | } | ||
660 | |||
661 | |||
662 | |||
663 | /* | ||
664 | * The following macro is to be used for the setting of the reason and | ||
665 | * reason_line fields in both the struct xpc_channel and struct xpc_partition | ||
666 | * structures. | ||
667 | */ | ||
668 | #define XPC_SET_REASON(_p, _reason, _line) \ | ||
669 | { \ | ||
670 | (_p)->reason = _reason; \ | ||
671 | (_p)->reason_line = _line; \ | ||
672 | } | ||
673 | |||
674 | |||
675 | |||
676 | /* | ||
677 | * The following set of macros and inlines are used for the sending and | ||
678 | * receiving of IPIs (also known as IRQs). There are two flavors of IPIs, | ||
679 | * one that is associated with partition activity (SGI_XPC_ACTIVATE) and | ||
680 | * the other that is associated with channel activity (SGI_XPC_NOTIFY). | ||
681 | */ | ||
682 | |||
683 | static inline u64 | ||
684 | xpc_IPI_receive(AMO_t *amo) | ||
685 | { | ||
686 | return FETCHOP_LOAD_OP(TO_AMO((u64) &amo->variable), FETCHOP_CLEAR); | ||
687 | } | ||
688 | |||
689 | |||
690 | static inline enum xpc_retval | ||
691 | xpc_IPI_send(AMO_t *amo, u64 flag, int nasid, int phys_cpuid, int vector) | ||
692 | { | ||
693 | int ret = 0; | ||
694 | unsigned long irq_flags; | ||
695 | |||
696 | |||
697 | local_irq_save(irq_flags); | ||
698 | |||
699 | FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_OR, flag); | ||
700 | sn_send_IPI_phys(nasid, phys_cpuid, vector, 0); | ||
701 | |||
702 | /* | ||
703 | * We must always use the nofault function regardless of whether we | ||
704 | * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we | ||
705 | * didn't, we'd never know that the other partition is down and would | ||
706 | * keep sending IPIs and AMOs to it until the heartbeat times out. | ||
707 | */ | ||
708 | ret = xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo->variable), | ||
709 | xp_nofault_PIOR_target)); | ||
710 | |||
711 | local_irq_restore(irq_flags); | ||
712 | |||
713 | return ((ret == 0) ? xpcSuccess : xpcPioReadError); | ||
714 | } | ||
715 | |||
716 | |||
717 | /* | ||
718 | * IPIs associated with SGI_XPC_ACTIVATE IRQ. | ||
719 | */ | ||
720 | |||
721 | /* | ||
722 | * Flag the appropriate AMO variable and send an IPI to the specified node. | ||
723 | */ | ||
724 | static inline void | ||
725 | xpc_activate_IRQ_send(u64 amos_page, int from_nasid, int to_nasid, | ||
726 | int to_phys_cpuid) | ||
727 | { | ||
728 | int w_index = XPC_NASID_W_INDEX(from_nasid); | ||
729 | int b_index = XPC_NASID_B_INDEX(from_nasid); | ||
730 | AMO_t *amos = (AMO_t *) __va(amos_page + | ||
731 | (XP_MAX_PARTITIONS * sizeof(AMO_t))); | ||
732 | |||
733 | |||
734 | (void) xpc_IPI_send(&amos[w_index], (1UL << b_index), to_nasid, | ||
735 | to_phys_cpuid, SGI_XPC_ACTIVATE); | ||
736 | } | ||
737 | |||
738 | static inline void | ||
739 | xpc_IPI_send_activate(struct xpc_vars *vars) | ||
740 | { | ||
741 | xpc_activate_IRQ_send(vars->amos_page_pa, cnodeid_to_nasid(0), | ||
742 | vars->act_nasid, vars->act_phys_cpuid); | ||
743 | } | ||
744 | |||
745 | static inline void | ||
746 | xpc_IPI_send_activated(struct xpc_partition *part) | ||
747 | { | ||
748 | xpc_activate_IRQ_send(part->remote_amos_page_pa, cnodeid_to_nasid(0), | ||
749 | part->remote_act_nasid, part->remote_act_phys_cpuid); | ||
750 | } | ||
751 | |||
752 | static inline void | ||
753 | xpc_IPI_send_reactivate(struct xpc_partition *part) | ||
754 | { | ||
755 | xpc_activate_IRQ_send(xpc_vars->amos_page_pa, part->reactivate_nasid, | ||
756 | xpc_vars->act_nasid, xpc_vars->act_phys_cpuid); | ||
757 | } | ||
758 | |||
759 | |||
760 | /* | ||
761 | * IPIs associated with SGI_XPC_NOTIFY IRQ. | ||
762 | */ | ||
763 | |||
764 | /* | ||
765 | * Send an IPI to the remote partition that is associated with the | ||
766 | * specified channel. | ||
767 | */ | ||
768 | #define XPC_NOTIFY_IRQ_SEND(_ch, _ipi_f, _irq_f) \ | ||
769 | xpc_notify_IRQ_send(_ch, _ipi_f, #_ipi_f, _irq_f) | ||
770 | |||
771 | static inline void | ||
772 | xpc_notify_IRQ_send(struct xpc_channel *ch, u8 ipi_flag, char *ipi_flag_string, | ||
773 | unsigned long *irq_flags) | ||
774 | { | ||
775 | struct xpc_partition *part = &xpc_partitions[ch->partid]; | ||
776 | enum xpc_retval ret; | ||
777 | |||
778 | |||
779 | if (likely(part->act_state != XPC_P_DEACTIVATING)) { | ||
780 | ret = xpc_IPI_send(part->remote_IPI_amo_va, | ||
781 | (u64) ipi_flag << (ch->number * 8), | ||
782 | part->remote_IPI_nasid, | ||
783 | part->remote_IPI_phys_cpuid, | ||
784 | SGI_XPC_NOTIFY); | ||
785 | dev_dbg(xpc_chan, "%s sent to partid=%d, channel=%d, ret=%d\n", | ||
786 | ipi_flag_string, ch->partid, ch->number, ret); | ||
787 | if (unlikely(ret != xpcSuccess)) { | ||
788 | if (irq_flags != NULL) { | ||
789 | spin_unlock_irqrestore(&ch->lock, *irq_flags); | ||
790 | } | ||
791 | XPC_DEACTIVATE_PARTITION(part, ret); | ||
792 | if (irq_flags != NULL) { | ||
793 | spin_lock_irqsave(&ch->lock, *irq_flags); | ||
794 | } | ||
795 | } | ||
796 | } | ||
797 | } | ||
798 | |||
799 | |||
800 | /* | ||
801 | * Make it look like the remote partition, which is associated with the | ||
802 | * specified channel, sent us an IPI. This faked IPI will be handled | ||
803 | * by xpc_dropped_IPI_check(). | ||
804 | */ | ||
805 | #define XPC_NOTIFY_IRQ_SEND_LOCAL(_ch, _ipi_f) \ | ||
806 | xpc_notify_IRQ_send_local(_ch, _ipi_f, #_ipi_f) | ||
807 | |||
808 | static inline void | ||
809 | xpc_notify_IRQ_send_local(struct xpc_channel *ch, u8 ipi_flag, | ||
810 | char *ipi_flag_string) | ||
811 | { | ||
812 | struct xpc_partition *part = &xpc_partitions[ch->partid]; | ||
813 | |||
814 | |||
815 | FETCHOP_STORE_OP(TO_AMO((u64) &part->local_IPI_amo_va->variable), | ||
816 | FETCHOP_OR, ((u64) ipi_flag << (ch->number * 8))); | ||
817 | dev_dbg(xpc_chan, "%s sent local from partid=%d, channel=%d\n", | ||
818 | ipi_flag_string, ch->partid, ch->number); | ||
819 | } | ||
820 | |||
821 | |||
822 | /* | ||
823 | * The sending and receiving of IPIs includes the setting of an AMO variable | ||
824 | * to indicate the reason the IPI was sent. The 64-bit variable is divided | ||
825 | * up into eight bytes, ordered from right to left. Byte zero pertains to | ||
826 | * channel 0, byte one to channel 1, and so on. Each byte is described by | ||
827 | * the following IPI flags. | ||
828 | */ | ||
829 | |||
830 | #define XPC_IPI_CLOSEREQUEST 0x01 | ||
831 | #define XPC_IPI_CLOSEREPLY 0x02 | ||
832 | #define XPC_IPI_OPENREQUEST 0x04 | ||
833 | #define XPC_IPI_OPENREPLY 0x08 | ||
834 | #define XPC_IPI_MSGREQUEST 0x10 | ||
835 | |||
836 | |||
837 | /* given an AMO variable and a channel#, get its associated IPI flags */ | ||
838 | #define XPC_GET_IPI_FLAGS(_amo, _c) ((u8) (((_amo) >> ((_c) * 8)) & 0xff)) | ||
839 | |||
840 | #define XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(_amo) ((_amo) & 0x0f0f0f0f0f0f0f0f) | ||
841 | #define XPC_ANY_MSG_IPI_FLAGS_SET(_amo) ((_amo) & 0x1010101010101010) | ||
842 | |||
843 | |||
844 | static inline void | ||
845 | xpc_IPI_send_closerequest(struct xpc_channel *ch, unsigned long *irq_flags) | ||
846 | { | ||
847 | struct xpc_openclose_args *args = ch->local_openclose_args; | ||
848 | |||
849 | |||
850 | args->reason = ch->reason; | ||
851 | |||
852 | XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_CLOSEREQUEST, irq_flags); | ||
853 | } | ||
854 | |||
855 | static inline void | ||
856 | xpc_IPI_send_closereply(struct xpc_channel *ch, unsigned long *irq_flags) | ||
857 | { | ||
858 | XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_CLOSEREPLY, irq_flags); | ||
859 | } | ||
860 | |||
861 | static inline void | ||
862 | xpc_IPI_send_openrequest(struct xpc_channel *ch, unsigned long *irq_flags) | ||
863 | { | ||
864 | struct xpc_openclose_args *args = ch->local_openclose_args; | ||
865 | |||
866 | |||
867 | args->msg_size = ch->msg_size; | ||
868 | args->local_nentries = ch->local_nentries; | ||
869 | |||
870 | XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_OPENREQUEST, irq_flags); | ||
871 | } | ||
872 | |||
873 | static inline void | ||
874 | xpc_IPI_send_openreply(struct xpc_channel *ch, unsigned long *irq_flags) | ||
875 | { | ||
876 | struct xpc_openclose_args *args = ch->local_openclose_args; | ||
877 | |||
878 | |||
879 | args->remote_nentries = ch->remote_nentries; | ||
880 | args->local_nentries = ch->local_nentries; | ||
881 | args->local_msgqueue_pa = __pa(ch->local_msgqueue); | ||
882 | |||
883 | XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_OPENREPLY, irq_flags); | ||
884 | } | ||
885 | |||
886 | static inline void | ||
887 | xpc_IPI_send_msgrequest(struct xpc_channel *ch) | ||
888 | { | ||
889 | XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_MSGREQUEST, NULL); | ||
890 | } | ||
891 | |||
892 | static inline void | ||
893 | xpc_IPI_send_local_msgrequest(struct xpc_channel *ch) | ||
894 | { | ||
895 | XPC_NOTIFY_IRQ_SEND_LOCAL(ch, XPC_IPI_MSGREQUEST); | ||
896 | } | ||
897 | |||
898 | |||
899 | /* | ||
900 | * Memory for XPC's AMO variables is allocated by the MSPEC driver. These | ||
901 | * pages are located in the lowest granule. The lowest granule uses 4k pages | ||
902 | * for cached references and an alternate TLB handler to never provide a | ||
903 | * cacheable mapping for the entire region. This will prevent speculative | ||
904 | * reading of cached copies of our lines from being issued which will cause | ||
905 | * a PI FSB Protocol error to be generated by the SHUB. For XPC, we need 64 | ||
906 | * (XP_MAX_PARTITIONS) AMO variables for message notification (xpc_main.c) | ||
907 | * and an additional 16 AMO variables for partition activation (xpc_hb.c). | ||
908 | */ | ||
909 | static inline AMO_t * | ||
910 | xpc_IPI_init(partid_t partid) | ||
911 | { | ||
912 | AMO_t *part_amo = xpc_vars->amos_page + partid; | ||
913 | |||
914 | |||
915 | xpc_IPI_receive(part_amo); | ||
916 | return part_amo; | ||
917 | } | ||
918 | |||
919 | |||
920 | |||
921 | static inline enum xpc_retval | ||
922 | xpc_map_bte_errors(bte_result_t error) | ||
923 | { | ||
924 | switch (error) { | ||
925 | case BTE_SUCCESS: return xpcSuccess; | ||
926 | case BTEFAIL_DIR: return xpcBteDirectoryError; | ||
927 | case BTEFAIL_POISON: return xpcBtePoisonError; | ||
928 | case BTEFAIL_WERR: return xpcBteWriteError; | ||
929 | case BTEFAIL_ACCESS: return xpcBteAccessError; | ||
930 | case BTEFAIL_PWERR: return xpcBtePWriteError; | ||
931 | case BTEFAIL_PRERR: return xpcBtePReadError; | ||
932 | case BTEFAIL_TOUT: return xpcBteTimeOutError; | ||
933 | case BTEFAIL_XTERR: return xpcBteXtalkError; | ||
934 | case BTEFAIL_NOTAVAIL: return xpcBteNotAvailable; | ||
935 | default: return xpcBteUnmappedError; | ||
936 | } | ||
937 | } | ||
938 | |||
939 | |||
940 | |||
941 | static inline void * | ||
942 | xpc_kmalloc_cacheline_aligned(size_t size, int flags, void **base) | ||
943 | { | ||
944 | /* see if kmalloc will give us cachline aligned memory by default */ | ||
945 | *base = kmalloc(size, flags); | ||
946 | if (*base == NULL) { | ||
947 | return NULL; | ||
948 | } | ||
949 | if ((u64) *base == L1_CACHE_ALIGN((u64) *base)) { | ||
950 | return *base; | ||
951 | } | ||
952 | kfree(*base); | ||
953 | |||
954 | /* nope, we'll have to do it ourselves */ | ||
955 | *base = kmalloc(size + L1_CACHE_BYTES, flags); | ||
956 | if (*base == NULL) { | ||
957 | return NULL; | ||
958 | } | ||
959 | return (void *) L1_CACHE_ALIGN((u64) *base); | ||
960 | } | ||
961 | |||
962 | |||
963 | /* | ||
964 | * Check to see if there is any channel activity to/from the specified | ||
965 | * partition. | ||
966 | */ | ||
967 | static inline void | ||
968 | xpc_check_for_channel_activity(struct xpc_partition *part) | ||
969 | { | ||
970 | u64 IPI_amo; | ||
971 | unsigned long irq_flags; | ||
972 | |||
973 | |||
974 | IPI_amo = xpc_IPI_receive(part->local_IPI_amo_va); | ||
975 | if (IPI_amo == 0) { | ||
976 | return; | ||
977 | } | ||
978 | |||
979 | spin_lock_irqsave(&part->IPI_lock, irq_flags); | ||
980 | part->local_IPI_amo |= IPI_amo; | ||
981 | spin_unlock_irqrestore(&part->IPI_lock, irq_flags); | ||
982 | |||
983 | dev_dbg(xpc_chan, "received IPI from partid=%d, IPI_amo=0x%lx\n", | ||
984 | XPC_PARTID(part), IPI_amo); | ||
985 | |||
986 | xpc_wakeup_channel_mgr(part); | ||
987 | } | ||
988 | |||
989 | |||
990 | #endif /* _IA64_SN_KERNEL_XPC_H */ | ||
991 | |||
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c new file mode 100644 index 000000000000..0bf6fbcc46d2 --- /dev/null +++ b/arch/ia64/sn/kernel/xpc_channel.c | |||
@@ -0,0 +1,2297 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved. | ||
7 | */ | ||
8 | |||
9 | |||
10 | /* | ||
11 | * Cross Partition Communication (XPC) channel support. | ||
12 | * | ||
13 | * This is the part of XPC that manages the channels and | ||
14 | * sends/receives messages across them to/from other partitions. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/sched.h> | ||
22 | #include <linux/cache.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <asm/sn/bte.h> | ||
26 | #include <asm/sn/sn_sal.h> | ||
27 | #include "xpc.h" | ||
28 | |||
29 | |||
30 | /* | ||
31 | * Set up the initial values for the XPartition Communication channels. | ||
32 | */ | ||
33 | static void | ||
34 | xpc_initialize_channels(struct xpc_partition *part, partid_t partid) | ||
35 | { | ||
36 | int ch_number; | ||
37 | struct xpc_channel *ch; | ||
38 | |||
39 | |||
40 | for (ch_number = 0; ch_number < part->nchannels; ch_number++) { | ||
41 | ch = &part->channels[ch_number]; | ||
42 | |||
43 | ch->partid = partid; | ||
44 | ch->number = ch_number; | ||
45 | ch->flags = XPC_C_DISCONNECTED; | ||
46 | |||
47 | ch->local_GP = &part->local_GPs[ch_number]; | ||
48 | ch->local_openclose_args = | ||
49 | &part->local_openclose_args[ch_number]; | ||
50 | |||
51 | atomic_set(&ch->kthreads_assigned, 0); | ||
52 | atomic_set(&ch->kthreads_idle, 0); | ||
53 | atomic_set(&ch->kthreads_active, 0); | ||
54 | |||
55 | atomic_set(&ch->references, 0); | ||
56 | atomic_set(&ch->n_to_notify, 0); | ||
57 | |||
58 | spin_lock_init(&ch->lock); | ||
59 | sema_init(&ch->msg_to_pull_sema, 1); /* mutex */ | ||
60 | |||
61 | atomic_set(&ch->n_on_msg_allocate_wq, 0); | ||
62 | init_waitqueue_head(&ch->msg_allocate_wq); | ||
63 | init_waitqueue_head(&ch->idle_wq); | ||
64 | } | ||
65 | } | ||
66 | |||
67 | |||
68 | /* | ||
69 | * Setup the infrastructure necessary to support XPartition Communication | ||
70 | * between the specified remote partition and the local one. | ||
71 | */ | ||
72 | enum xpc_retval | ||
73 | xpc_setup_infrastructure(struct xpc_partition *part) | ||
74 | { | ||
75 | int ret; | ||
76 | struct timer_list *timer; | ||
77 | partid_t partid = XPC_PARTID(part); | ||
78 | |||
79 | |||
80 | /* | ||
81 | * Zero out MOST of the entry for this partition. Only the fields | ||
82 | * starting with `nchannels' will be zeroed. The preceding fields must | ||
83 | * remain `viable' across partition ups and downs, since they may be | ||
84 | * referenced during this memset() operation. | ||
85 | */ | ||
86 | memset(&part->nchannels, 0, sizeof(struct xpc_partition) - | ||
87 | offsetof(struct xpc_partition, nchannels)); | ||
88 | |||
89 | /* | ||
90 | * Allocate all of the channel structures as a contiguous chunk of | ||
91 | * memory. | ||
92 | */ | ||
93 | part->channels = kmalloc(sizeof(struct xpc_channel) * XPC_NCHANNELS, | ||
94 | GFP_KERNEL); | ||
95 | if (part->channels == NULL) { | ||
96 | dev_err(xpc_chan, "can't get memory for channels\n"); | ||
97 | return xpcNoMemory; | ||
98 | } | ||
99 | memset(part->channels, 0, sizeof(struct xpc_channel) * XPC_NCHANNELS); | ||
100 | |||
101 | part->nchannels = XPC_NCHANNELS; | ||
102 | |||
103 | |||
104 | /* allocate all the required GET/PUT values */ | ||
105 | |||
106 | part->local_GPs = xpc_kmalloc_cacheline_aligned(XPC_GP_SIZE, | ||
107 | GFP_KERNEL, &part->local_GPs_base); | ||
108 | if (part->local_GPs == NULL) { | ||
109 | kfree(part->channels); | ||
110 | part->channels = NULL; | ||
111 | dev_err(xpc_chan, "can't get memory for local get/put " | ||
112 | "values\n"); | ||
113 | return xpcNoMemory; | ||
114 | } | ||
115 | memset(part->local_GPs, 0, XPC_GP_SIZE); | ||
116 | |||
117 | part->remote_GPs = xpc_kmalloc_cacheline_aligned(XPC_GP_SIZE, | ||
118 | GFP_KERNEL, &part->remote_GPs_base); | ||
119 | if (part->remote_GPs == NULL) { | ||
120 | kfree(part->channels); | ||
121 | part->channels = NULL; | ||
122 | kfree(part->local_GPs_base); | ||
123 | part->local_GPs = NULL; | ||
124 | dev_err(xpc_chan, "can't get memory for remote get/put " | ||
125 | "values\n"); | ||
126 | return xpcNoMemory; | ||
127 | } | ||
128 | memset(part->remote_GPs, 0, XPC_GP_SIZE); | ||
129 | |||
130 | |||
131 | /* allocate all the required open and close args */ | ||
132 | |||
133 | part->local_openclose_args = xpc_kmalloc_cacheline_aligned( | ||
134 | XPC_OPENCLOSE_ARGS_SIZE, GFP_KERNEL, | ||
135 | &part->local_openclose_args_base); | ||
136 | if (part->local_openclose_args == NULL) { | ||
137 | kfree(part->channels); | ||
138 | part->channels = NULL; | ||
139 | kfree(part->local_GPs_base); | ||
140 | part->local_GPs = NULL; | ||
141 | kfree(part->remote_GPs_base); | ||
142 | part->remote_GPs = NULL; | ||
143 | dev_err(xpc_chan, "can't get memory for local connect args\n"); | ||
144 | return xpcNoMemory; | ||
145 | } | ||
146 | memset(part->local_openclose_args, 0, XPC_OPENCLOSE_ARGS_SIZE); | ||
147 | |||
148 | part->remote_openclose_args = xpc_kmalloc_cacheline_aligned( | ||
149 | XPC_OPENCLOSE_ARGS_SIZE, GFP_KERNEL, | ||
150 | &part->remote_openclose_args_base); | ||
151 | if (part->remote_openclose_args == NULL) { | ||
152 | kfree(part->channels); | ||
153 | part->channels = NULL; | ||
154 | kfree(part->local_GPs_base); | ||
155 | part->local_GPs = NULL; | ||
156 | kfree(part->remote_GPs_base); | ||
157 | part->remote_GPs = NULL; | ||
158 | kfree(part->local_openclose_args_base); | ||
159 | part->local_openclose_args = NULL; | ||
160 | dev_err(xpc_chan, "can't get memory for remote connect args\n"); | ||
161 | return xpcNoMemory; | ||
162 | } | ||
163 | memset(part->remote_openclose_args, 0, XPC_OPENCLOSE_ARGS_SIZE); | ||
164 | |||
165 | |||
166 | xpc_initialize_channels(part, partid); | ||
167 | |||
168 | atomic_set(&part->nchannels_active, 0); | ||
169 | |||
170 | |||
171 | /* local_IPI_amo were set to 0 by an earlier memset() */ | ||
172 | |||
173 | /* Initialize this partitions AMO_t structure */ | ||
174 | part->local_IPI_amo_va = xpc_IPI_init(partid); | ||
175 | |||
176 | spin_lock_init(&part->IPI_lock); | ||
177 | |||
178 | atomic_set(&part->channel_mgr_requests, 1); | ||
179 | init_waitqueue_head(&part->channel_mgr_wq); | ||
180 | |||
181 | sprintf(part->IPI_owner, "xpc%02d", partid); | ||
182 | ret = request_irq(SGI_XPC_NOTIFY, xpc_notify_IRQ_handler, SA_SHIRQ, | ||
183 | part->IPI_owner, (void *) (u64) partid); | ||
184 | if (ret != 0) { | ||
185 | kfree(part->channels); | ||
186 | part->channels = NULL; | ||
187 | kfree(part->local_GPs_base); | ||
188 | part->local_GPs = NULL; | ||
189 | kfree(part->remote_GPs_base); | ||
190 | part->remote_GPs = NULL; | ||
191 | kfree(part->local_openclose_args_base); | ||
192 | part->local_openclose_args = NULL; | ||
193 | kfree(part->remote_openclose_args_base); | ||
194 | part->remote_openclose_args = NULL; | ||
195 | dev_err(xpc_chan, "can't register NOTIFY IRQ handler, " | ||
196 | "errno=%d\n", -ret); | ||
197 | return xpcLackOfResources; | ||
198 | } | ||
199 | |||
200 | /* Setup a timer to check for dropped IPIs */ | ||
201 | timer = &part->dropped_IPI_timer; | ||
202 | init_timer(timer); | ||
203 | timer->function = (void (*)(unsigned long)) xpc_dropped_IPI_check; | ||
204 | timer->data = (unsigned long) part; | ||
205 | timer->expires = jiffies + XPC_P_DROPPED_IPI_WAIT; | ||
206 | add_timer(timer); | ||
207 | |||
208 | /* | ||
209 | * With the setting of the partition setup_state to XPC_P_SETUP, we're | ||
210 | * declaring that this partition is ready to go. | ||
211 | */ | ||
212 | (volatile u8) part->setup_state = XPC_P_SETUP; | ||
213 | |||
214 | |||
215 | /* | ||
216 | * Setup the per partition specific variables required by the | ||
217 | * remote partition to establish channel connections with us. | ||
218 | * | ||
219 | * The setting of the magic # indicates that these per partition | ||
220 | * specific variables are ready to be used. | ||
221 | */ | ||
222 | xpc_vars_part[partid].GPs_pa = __pa(part->local_GPs); | ||
223 | xpc_vars_part[partid].openclose_args_pa = | ||
224 | __pa(part->local_openclose_args); | ||
225 | xpc_vars_part[partid].IPI_amo_pa = __pa(part->local_IPI_amo_va); | ||
226 | xpc_vars_part[partid].IPI_nasid = cpuid_to_nasid(smp_processor_id()); | ||
227 | xpc_vars_part[partid].IPI_phys_cpuid = | ||
228 | cpu_physical_id(smp_processor_id()); | ||
229 | xpc_vars_part[partid].nchannels = part->nchannels; | ||
230 | (volatile u64) xpc_vars_part[partid].magic = XPC_VP_MAGIC1; | ||
231 | |||
232 | return xpcSuccess; | ||
233 | } | ||
234 | |||
235 | |||
236 | /* | ||
237 | * Create a wrapper that hides the underlying mechanism for pulling a cacheline | ||
238 | * (or multiple cachelines) from a remote partition. | ||
239 | * | ||
240 | * src must be a cacheline aligned physical address on the remote partition. | ||
241 | * dst must be a cacheline aligned virtual address on this partition. | ||
242 | * cnt must be an cacheline sized | ||
243 | */ | ||
244 | static enum xpc_retval | ||
245 | xpc_pull_remote_cachelines(struct xpc_partition *part, void *dst, | ||
246 | const void *src, size_t cnt) | ||
247 | { | ||
248 | bte_result_t bte_ret; | ||
249 | |||
250 | |||
251 | DBUG_ON((u64) src != L1_CACHE_ALIGN((u64) src)); | ||
252 | DBUG_ON((u64) dst != L1_CACHE_ALIGN((u64) dst)); | ||
253 | DBUG_ON(cnt != L1_CACHE_ALIGN(cnt)); | ||
254 | |||
255 | if (part->act_state == XPC_P_DEACTIVATING) { | ||
256 | return part->reason; | ||
257 | } | ||
258 | |||
259 | bte_ret = xp_bte_copy((u64) src, (u64) ia64_tpa((u64) dst), | ||
260 | (u64) cnt, (BTE_NORMAL | BTE_WACQUIRE), NULL); | ||
261 | if (bte_ret == BTE_SUCCESS) { | ||
262 | return xpcSuccess; | ||
263 | } | ||
264 | |||
265 | dev_dbg(xpc_chan, "xp_bte_copy() from partition %d failed, ret=%d\n", | ||
266 | XPC_PARTID(part), bte_ret); | ||
267 | |||
268 | return xpc_map_bte_errors(bte_ret); | ||
269 | } | ||
270 | |||
271 | |||
272 | /* | ||
273 | * Pull the remote per partititon specific variables from the specified | ||
274 | * partition. | ||
275 | */ | ||
276 | enum xpc_retval | ||
277 | xpc_pull_remote_vars_part(struct xpc_partition *part) | ||
278 | { | ||
279 | u8 buffer[L1_CACHE_BYTES * 2]; | ||
280 | struct xpc_vars_part *pulled_entry_cacheline = | ||
281 | (struct xpc_vars_part *) L1_CACHE_ALIGN((u64) buffer); | ||
282 | struct xpc_vars_part *pulled_entry; | ||
283 | u64 remote_entry_cacheline_pa, remote_entry_pa; | ||
284 | partid_t partid = XPC_PARTID(part); | ||
285 | enum xpc_retval ret; | ||
286 | |||
287 | |||
288 | /* pull the cacheline that contains the variables we're interested in */ | ||
289 | |||
290 | DBUG_ON(part->remote_vars_part_pa != | ||
291 | L1_CACHE_ALIGN(part->remote_vars_part_pa)); | ||
292 | DBUG_ON(sizeof(struct xpc_vars_part) != L1_CACHE_BYTES / 2); | ||
293 | |||
294 | remote_entry_pa = part->remote_vars_part_pa + | ||
295 | sn_partition_id * sizeof(struct xpc_vars_part); | ||
296 | |||
297 | remote_entry_cacheline_pa = (remote_entry_pa & ~(L1_CACHE_BYTES - 1)); | ||
298 | |||
299 | pulled_entry = (struct xpc_vars_part *) ((u64) pulled_entry_cacheline + | ||
300 | (remote_entry_pa & (L1_CACHE_BYTES - 1))); | ||
301 | |||
302 | ret = xpc_pull_remote_cachelines(part, pulled_entry_cacheline, | ||
303 | (void *) remote_entry_cacheline_pa, | ||
304 | L1_CACHE_BYTES); | ||
305 | if (ret != xpcSuccess) { | ||
306 | dev_dbg(xpc_chan, "failed to pull XPC vars_part from " | ||
307 | "partition %d, ret=%d\n", partid, ret); | ||
308 | return ret; | ||
309 | } | ||
310 | |||
311 | |||
312 | /* see if they've been set up yet */ | ||
313 | |||
314 | if (pulled_entry->magic != XPC_VP_MAGIC1 && | ||
315 | pulled_entry->magic != XPC_VP_MAGIC2) { | ||
316 | |||
317 | if (pulled_entry->magic != 0) { | ||
318 | dev_dbg(xpc_chan, "partition %d's XPC vars_part for " | ||
319 | "partition %d has bad magic value (=0x%lx)\n", | ||
320 | partid, sn_partition_id, pulled_entry->magic); | ||
321 | return xpcBadMagic; | ||
322 | } | ||
323 | |||
324 | /* they've not been initialized yet */ | ||
325 | return xpcRetry; | ||
326 | } | ||
327 | |||
328 | if (xpc_vars_part[partid].magic == XPC_VP_MAGIC1) { | ||
329 | |||
330 | /* validate the variables */ | ||
331 | |||
332 | if (pulled_entry->GPs_pa == 0 || | ||
333 | pulled_entry->openclose_args_pa == 0 || | ||
334 | pulled_entry->IPI_amo_pa == 0) { | ||
335 | |||
336 | dev_err(xpc_chan, "partition %d's XPC vars_part for " | ||
337 | "partition %d are not valid\n", partid, | ||
338 | sn_partition_id); | ||
339 | return xpcInvalidAddress; | ||
340 | } | ||
341 | |||
342 | /* the variables we imported look to be valid */ | ||
343 | |||
344 | part->remote_GPs_pa = pulled_entry->GPs_pa; | ||
345 | part->remote_openclose_args_pa = | ||
346 | pulled_entry->openclose_args_pa; | ||
347 | part->remote_IPI_amo_va = | ||
348 | (AMO_t *) __va(pulled_entry->IPI_amo_pa); | ||
349 | part->remote_IPI_nasid = pulled_entry->IPI_nasid; | ||
350 | part->remote_IPI_phys_cpuid = pulled_entry->IPI_phys_cpuid; | ||
351 | |||
352 | if (part->nchannels > pulled_entry->nchannels) { | ||
353 | part->nchannels = pulled_entry->nchannels; | ||
354 | } | ||
355 | |||
356 | /* let the other side know that we've pulled their variables */ | ||
357 | |||
358 | (volatile u64) xpc_vars_part[partid].magic = XPC_VP_MAGIC2; | ||
359 | } | ||
360 | |||
361 | if (pulled_entry->magic == XPC_VP_MAGIC1) { | ||
362 | return xpcRetry; | ||
363 | } | ||
364 | |||
365 | return xpcSuccess; | ||
366 | } | ||
367 | |||
368 | |||
369 | /* | ||
370 | * Get the IPI flags and pull the openclose args and/or remote GPs as needed. | ||
371 | */ | ||
372 | static u64 | ||
373 | xpc_get_IPI_flags(struct xpc_partition *part) | ||
374 | { | ||
375 | unsigned long irq_flags; | ||
376 | u64 IPI_amo; | ||
377 | enum xpc_retval ret; | ||
378 | |||
379 | |||
380 | /* | ||
381 | * See if there are any IPI flags to be handled. | ||
382 | */ | ||
383 | |||
384 | spin_lock_irqsave(&part->IPI_lock, irq_flags); | ||
385 | if ((IPI_amo = part->local_IPI_amo) != 0) { | ||
386 | part->local_IPI_amo = 0; | ||
387 | } | ||
388 | spin_unlock_irqrestore(&part->IPI_lock, irq_flags); | ||
389 | |||
390 | |||
391 | if (XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(IPI_amo)) { | ||
392 | ret = xpc_pull_remote_cachelines(part, | ||
393 | part->remote_openclose_args, | ||
394 | (void *) part->remote_openclose_args_pa, | ||
395 | XPC_OPENCLOSE_ARGS_SIZE); | ||
396 | if (ret != xpcSuccess) { | ||
397 | XPC_DEACTIVATE_PARTITION(part, ret); | ||
398 | |||
399 | dev_dbg(xpc_chan, "failed to pull openclose args from " | ||
400 | "partition %d, ret=%d\n", XPC_PARTID(part), | ||
401 | ret); | ||
402 | |||
403 | /* don't bother processing IPIs anymore */ | ||
404 | IPI_amo = 0; | ||
405 | } | ||
406 | } | ||
407 | |||
408 | if (XPC_ANY_MSG_IPI_FLAGS_SET(IPI_amo)) { | ||
409 | ret = xpc_pull_remote_cachelines(part, part->remote_GPs, | ||
410 | (void *) part->remote_GPs_pa, | ||
411 | XPC_GP_SIZE); | ||
412 | if (ret != xpcSuccess) { | ||
413 | XPC_DEACTIVATE_PARTITION(part, ret); | ||
414 | |||
415 | dev_dbg(xpc_chan, "failed to pull GPs from partition " | ||
416 | "%d, ret=%d\n", XPC_PARTID(part), ret); | ||
417 | |||
418 | /* don't bother processing IPIs anymore */ | ||
419 | IPI_amo = 0; | ||
420 | } | ||
421 | } | ||
422 | |||
423 | return IPI_amo; | ||
424 | } | ||
425 | |||
426 | |||
427 | /* | ||
428 | * Allocate the local message queue and the notify queue. | ||
429 | */ | ||
430 | static enum xpc_retval | ||
431 | xpc_allocate_local_msgqueue(struct xpc_channel *ch) | ||
432 | { | ||
433 | unsigned long irq_flags; | ||
434 | int nentries; | ||
435 | size_t nbytes; | ||
436 | |||
437 | |||
438 | // >>> may want to check for ch->flags & XPC_C_DISCONNECTING between | ||
439 | // >>> iterations of the for-loop, bail if set? | ||
440 | |||
441 | // >>> should we impose a minumum #of entries? like 4 or 8? | ||
442 | for (nentries = ch->local_nentries; nentries > 0; nentries--) { | ||
443 | |||
444 | nbytes = nentries * ch->msg_size; | ||
445 | ch->local_msgqueue = xpc_kmalloc_cacheline_aligned(nbytes, | ||
446 | (GFP_KERNEL | GFP_DMA), | ||
447 | &ch->local_msgqueue_base); | ||
448 | if (ch->local_msgqueue == NULL) { | ||
449 | continue; | ||
450 | } | ||
451 | memset(ch->local_msgqueue, 0, nbytes); | ||
452 | |||
453 | nbytes = nentries * sizeof(struct xpc_notify); | ||
454 | ch->notify_queue = kmalloc(nbytes, (GFP_KERNEL | GFP_DMA)); | ||
455 | if (ch->notify_queue == NULL) { | ||
456 | kfree(ch->local_msgqueue_base); | ||
457 | ch->local_msgqueue = NULL; | ||
458 | continue; | ||
459 | } | ||
460 | memset(ch->notify_queue, 0, nbytes); | ||
461 | |||
462 | spin_lock_irqsave(&ch->lock, irq_flags); | ||
463 | if (nentries < ch->local_nentries) { | ||
464 | dev_dbg(xpc_chan, "nentries=%d local_nentries=%d, " | ||
465 | "partid=%d, channel=%d\n", nentries, | ||
466 | ch->local_nentries, ch->partid, ch->number); | ||
467 | |||
468 | ch->local_nentries = nentries; | ||
469 | } | ||
470 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
471 | return xpcSuccess; | ||
472 | } | ||
473 | |||
474 | dev_dbg(xpc_chan, "can't get memory for local message queue and notify " | ||
475 | "queue, partid=%d, channel=%d\n", ch->partid, ch->number); | ||
476 | return xpcNoMemory; | ||
477 | } | ||
478 | |||
479 | |||
480 | /* | ||
481 | * Allocate the cached remote message queue. | ||
482 | */ | ||
483 | static enum xpc_retval | ||
484 | xpc_allocate_remote_msgqueue(struct xpc_channel *ch) | ||
485 | { | ||
486 | unsigned long irq_flags; | ||
487 | int nentries; | ||
488 | size_t nbytes; | ||
489 | |||
490 | |||
491 | DBUG_ON(ch->remote_nentries <= 0); | ||
492 | |||
493 | // >>> may want to check for ch->flags & XPC_C_DISCONNECTING between | ||
494 | // >>> iterations of the for-loop, bail if set? | ||
495 | |||
496 | // >>> should we impose a minumum #of entries? like 4 or 8? | ||
497 | for (nentries = ch->remote_nentries; nentries > 0; nentries--) { | ||
498 | |||
499 | nbytes = nentries * ch->msg_size; | ||
500 | ch->remote_msgqueue = xpc_kmalloc_cacheline_aligned(nbytes, | ||
501 | (GFP_KERNEL | GFP_DMA), | ||
502 | &ch->remote_msgqueue_base); | ||
503 | if (ch->remote_msgqueue == NULL) { | ||
504 | continue; | ||
505 | } | ||
506 | memset(ch->remote_msgqueue, 0, nbytes); | ||
507 | |||
508 | spin_lock_irqsave(&ch->lock, irq_flags); | ||
509 | if (nentries < ch->remote_nentries) { | ||
510 | dev_dbg(xpc_chan, "nentries=%d remote_nentries=%d, " | ||
511 | "partid=%d, channel=%d\n", nentries, | ||
512 | ch->remote_nentries, ch->partid, ch->number); | ||
513 | |||
514 | ch->remote_nentries = nentries; | ||
515 | } | ||
516 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
517 | return xpcSuccess; | ||
518 | } | ||
519 | |||
520 | dev_dbg(xpc_chan, "can't get memory for cached remote message queue, " | ||
521 | "partid=%d, channel=%d\n", ch->partid, ch->number); | ||
522 | return xpcNoMemory; | ||
523 | } | ||
524 | |||
525 | |||
526 | /* | ||
527 | * Allocate message queues and other stuff associated with a channel. | ||
528 | * | ||
529 | * Note: Assumes all of the channel sizes are filled in. | ||
530 | */ | ||
531 | static enum xpc_retval | ||
532 | xpc_allocate_msgqueues(struct xpc_channel *ch) | ||
533 | { | ||
534 | unsigned long irq_flags; | ||
535 | int i; | ||
536 | enum xpc_retval ret; | ||
537 | |||
538 | |||
539 | DBUG_ON(ch->flags & XPC_C_SETUP); | ||
540 | |||
541 | if ((ret = xpc_allocate_local_msgqueue(ch)) != xpcSuccess) { | ||
542 | return ret; | ||
543 | } | ||
544 | |||
545 | if ((ret = xpc_allocate_remote_msgqueue(ch)) != xpcSuccess) { | ||
546 | kfree(ch->local_msgqueue_base); | ||
547 | ch->local_msgqueue = NULL; | ||
548 | kfree(ch->notify_queue); | ||
549 | ch->notify_queue = NULL; | ||
550 | return ret; | ||
551 | } | ||
552 | |||
553 | for (i = 0; i < ch->local_nentries; i++) { | ||
554 | /* use a semaphore as an event wait queue */ | ||
555 | sema_init(&ch->notify_queue[i].sema, 0); | ||
556 | } | ||
557 | |||
558 | sema_init(&ch->teardown_sema, 0); /* event wait */ | ||
559 | |||
560 | spin_lock_irqsave(&ch->lock, irq_flags); | ||
561 | ch->flags |= XPC_C_SETUP; | ||
562 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
563 | |||
564 | return xpcSuccess; | ||
565 | } | ||
566 | |||
567 | |||
568 | /* | ||
569 | * Process a connect message from a remote partition. | ||
570 | * | ||
571 | * Note: xpc_process_connect() is expecting to be called with the | ||
572 | * spin_lock_irqsave held and will leave it locked upon return. | ||
573 | */ | ||
574 | static void | ||
575 | xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags) | ||
576 | { | ||
577 | enum xpc_retval ret; | ||
578 | |||
579 | |||
580 | DBUG_ON(!spin_is_locked(&ch->lock)); | ||
581 | |||
582 | if (!(ch->flags & XPC_C_OPENREQUEST) || | ||
583 | !(ch->flags & XPC_C_ROPENREQUEST)) { | ||
584 | /* nothing more to do for now */ | ||
585 | return; | ||
586 | } | ||
587 | DBUG_ON(!(ch->flags & XPC_C_CONNECTING)); | ||
588 | |||
589 | if (!(ch->flags & XPC_C_SETUP)) { | ||
590 | spin_unlock_irqrestore(&ch->lock, *irq_flags); | ||
591 | ret = xpc_allocate_msgqueues(ch); | ||
592 | spin_lock_irqsave(&ch->lock, *irq_flags); | ||
593 | |||
594 | if (ret != xpcSuccess) { | ||
595 | XPC_DISCONNECT_CHANNEL(ch, ret, irq_flags); | ||
596 | } | ||
597 | if (ch->flags & (XPC_C_CONNECTED | XPC_C_DISCONNECTING)) { | ||
598 | return; | ||
599 | } | ||
600 | |||
601 | DBUG_ON(!(ch->flags & XPC_C_SETUP)); | ||
602 | DBUG_ON(ch->local_msgqueue == NULL); | ||
603 | DBUG_ON(ch->remote_msgqueue == NULL); | ||
604 | } | ||
605 | |||
606 | if (!(ch->flags & XPC_C_OPENREPLY)) { | ||
607 | ch->flags |= XPC_C_OPENREPLY; | ||
608 | xpc_IPI_send_openreply(ch, irq_flags); | ||
609 | } | ||
610 | |||
611 | if (!(ch->flags & XPC_C_ROPENREPLY)) { | ||
612 | return; | ||
613 | } | ||
614 | |||
615 | DBUG_ON(ch->remote_msgqueue_pa == 0); | ||
616 | |||
617 | ch->flags = (XPC_C_CONNECTED | XPC_C_SETUP); /* clear all else */ | ||
618 | |||
619 | dev_info(xpc_chan, "channel %d to partition %d connected\n", | ||
620 | ch->number, ch->partid); | ||
621 | |||
622 | spin_unlock_irqrestore(&ch->lock, *irq_flags); | ||
623 | xpc_create_kthreads(ch, 1); | ||
624 | spin_lock_irqsave(&ch->lock, *irq_flags); | ||
625 | } | ||
626 | |||
627 | |||
628 | /* | ||
629 | * Free up message queues and other stuff that were allocated for the specified | ||
630 | * channel. | ||
631 | * | ||
632 | * Note: ch->reason and ch->reason_line are left set for debugging purposes, | ||
633 | * they're cleared when XPC_C_DISCONNECTED is cleared. | ||
634 | */ | ||
635 | static void | ||
636 | xpc_free_msgqueues(struct xpc_channel *ch) | ||
637 | { | ||
638 | DBUG_ON(!spin_is_locked(&ch->lock)); | ||
639 | DBUG_ON(atomic_read(&ch->n_to_notify) != 0); | ||
640 | |||
641 | ch->remote_msgqueue_pa = 0; | ||
642 | ch->func = NULL; | ||
643 | ch->key = NULL; | ||
644 | ch->msg_size = 0; | ||
645 | ch->local_nentries = 0; | ||
646 | ch->remote_nentries = 0; | ||
647 | ch->kthreads_assigned_limit = 0; | ||
648 | ch->kthreads_idle_limit = 0; | ||
649 | |||
650 | ch->local_GP->get = 0; | ||
651 | ch->local_GP->put = 0; | ||
652 | ch->remote_GP.get = 0; | ||
653 | ch->remote_GP.put = 0; | ||
654 | ch->w_local_GP.get = 0; | ||
655 | ch->w_local_GP.put = 0; | ||
656 | ch->w_remote_GP.get = 0; | ||
657 | ch->w_remote_GP.put = 0; | ||
658 | ch->next_msg_to_pull = 0; | ||
659 | |||
660 | if (ch->flags & XPC_C_SETUP) { | ||
661 | ch->flags &= ~XPC_C_SETUP; | ||
662 | |||
663 | dev_dbg(xpc_chan, "ch->flags=0x%x, partid=%d, channel=%d\n", | ||
664 | ch->flags, ch->partid, ch->number); | ||
665 | |||
666 | kfree(ch->local_msgqueue_base); | ||
667 | ch->local_msgqueue = NULL; | ||
668 | kfree(ch->remote_msgqueue_base); | ||
669 | ch->remote_msgqueue = NULL; | ||
670 | kfree(ch->notify_queue); | ||
671 | ch->notify_queue = NULL; | ||
672 | |||
673 | /* in case someone is waiting for the teardown to complete */ | ||
674 | up(&ch->teardown_sema); | ||
675 | } | ||
676 | } | ||
677 | |||
678 | |||
679 | /* | ||
680 | * spin_lock_irqsave() is expected to be held on entry. | ||
681 | */ | ||
682 | static void | ||
683 | xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags) | ||
684 | { | ||
685 | struct xpc_partition *part = &xpc_partitions[ch->partid]; | ||
686 | u32 ch_flags = ch->flags; | ||
687 | |||
688 | |||
689 | DBUG_ON(!spin_is_locked(&ch->lock)); | ||
690 | |||
691 | if (!(ch->flags & XPC_C_DISCONNECTING)) { | ||
692 | return; | ||
693 | } | ||
694 | |||
695 | DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST)); | ||
696 | |||
697 | /* make sure all activity has settled down first */ | ||
698 | |||
699 | if (atomic_read(&ch->references) > 0) { | ||
700 | return; | ||
701 | } | ||
702 | DBUG_ON(atomic_read(&ch->kthreads_assigned) != 0); | ||
703 | |||
704 | /* it's now safe to free the channel's message queues */ | ||
705 | |||
706 | xpc_free_msgqueues(ch); | ||
707 | DBUG_ON(ch->flags & XPC_C_SETUP); | ||
708 | |||
709 | if (part->act_state != XPC_P_DEACTIVATING) { | ||
710 | |||
711 | /* as long as the other side is up do the full protocol */ | ||
712 | |||
713 | if (!(ch->flags & XPC_C_RCLOSEREQUEST)) { | ||
714 | return; | ||
715 | } | ||
716 | |||
717 | if (!(ch->flags & XPC_C_CLOSEREPLY)) { | ||
718 | ch->flags |= XPC_C_CLOSEREPLY; | ||
719 | xpc_IPI_send_closereply(ch, irq_flags); | ||
720 | } | ||
721 | |||
722 | if (!(ch->flags & XPC_C_RCLOSEREPLY)) { | ||
723 | return; | ||
724 | } | ||
725 | } | ||
726 | |||
727 | /* both sides are disconnected now */ | ||
728 | |||
729 | ch->flags = XPC_C_DISCONNECTED; /* clear all flags, but this one */ | ||
730 | |||
731 | atomic_dec(&part->nchannels_active); | ||
732 | |||
733 | if (ch_flags & XPC_C_WASCONNECTED) { | ||
734 | dev_info(xpc_chan, "channel %d to partition %d disconnected, " | ||
735 | "reason=%d\n", ch->number, ch->partid, ch->reason); | ||
736 | } | ||
737 | } | ||
738 | |||
739 | |||
740 | /* | ||
741 | * Process a change in the channel's remote connection state. | ||
742 | */ | ||
743 | static void | ||
744 | xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number, | ||
745 | u8 IPI_flags) | ||
746 | { | ||
747 | unsigned long irq_flags; | ||
748 | struct xpc_openclose_args *args = | ||
749 | &part->remote_openclose_args[ch_number]; | ||
750 | struct xpc_channel *ch = &part->channels[ch_number]; | ||
751 | enum xpc_retval reason; | ||
752 | |||
753 | |||
754 | |||
755 | spin_lock_irqsave(&ch->lock, irq_flags); | ||
756 | |||
757 | |||
758 | if (IPI_flags & XPC_IPI_CLOSEREQUEST) { | ||
759 | |||
760 | dev_dbg(xpc_chan, "XPC_IPI_CLOSEREQUEST (reason=%d) received " | ||
761 | "from partid=%d, channel=%d\n", args->reason, | ||
762 | ch->partid, ch->number); | ||
763 | |||
764 | /* | ||
765 | * If RCLOSEREQUEST is set, we're probably waiting for | ||
766 | * RCLOSEREPLY. We should find it and a ROPENREQUEST packed | ||
767 | * with this RCLOSEQREUQEST in the IPI_flags. | ||
768 | */ | ||
769 | |||
770 | if (ch->flags & XPC_C_RCLOSEREQUEST) { | ||
771 | DBUG_ON(!(ch->flags & XPC_C_DISCONNECTING)); | ||
772 | DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST)); | ||
773 | DBUG_ON(!(ch->flags & XPC_C_CLOSEREPLY)); | ||
774 | DBUG_ON(ch->flags & XPC_C_RCLOSEREPLY); | ||
775 | |||
776 | DBUG_ON(!(IPI_flags & XPC_IPI_CLOSEREPLY)); | ||
777 | IPI_flags &= ~XPC_IPI_CLOSEREPLY; | ||
778 | ch->flags |= XPC_C_RCLOSEREPLY; | ||
779 | |||
780 | /* both sides have finished disconnecting */ | ||
781 | xpc_process_disconnect(ch, &irq_flags); | ||
782 | } | ||
783 | |||
784 | if (ch->flags & XPC_C_DISCONNECTED) { | ||
785 | // >>> explain this section | ||
786 | |||
787 | if (!(IPI_flags & XPC_IPI_OPENREQUEST)) { | ||
788 | DBUG_ON(part->act_state != | ||
789 | XPC_P_DEACTIVATING); | ||
790 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
791 | return; | ||
792 | } | ||
793 | |||
794 | XPC_SET_REASON(ch, 0, 0); | ||
795 | ch->flags &= ~XPC_C_DISCONNECTED; | ||
796 | |||
797 | atomic_inc(&part->nchannels_active); | ||
798 | ch->flags |= (XPC_C_CONNECTING | XPC_C_ROPENREQUEST); | ||
799 | } | ||
800 | |||
801 | IPI_flags &= ~(XPC_IPI_OPENREQUEST | XPC_IPI_OPENREPLY); | ||
802 | |||
803 | /* | ||
804 | * The meaningful CLOSEREQUEST connection state fields are: | ||
805 | * reason = reason connection is to be closed | ||
806 | */ | ||
807 | |||
808 | ch->flags |= XPC_C_RCLOSEREQUEST; | ||
809 | |||
810 | if (!(ch->flags & XPC_C_DISCONNECTING)) { | ||
811 | reason = args->reason; | ||
812 | if (reason <= xpcSuccess || reason > xpcUnknownReason) { | ||
813 | reason = xpcUnknownReason; | ||
814 | } else if (reason == xpcUnregistering) { | ||
815 | reason = xpcOtherUnregistering; | ||
816 | } | ||
817 | |||
818 | XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags); | ||
819 | } else { | ||
820 | xpc_process_disconnect(ch, &irq_flags); | ||
821 | } | ||
822 | } | ||
823 | |||
824 | |||
825 | if (IPI_flags & XPC_IPI_CLOSEREPLY) { | ||
826 | |||
827 | dev_dbg(xpc_chan, "XPC_IPI_CLOSEREPLY received from partid=%d," | ||
828 | " channel=%d\n", ch->partid, ch->number); | ||
829 | |||
830 | if (ch->flags & XPC_C_DISCONNECTED) { | ||
831 | DBUG_ON(part->act_state != XPC_P_DEACTIVATING); | ||
832 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
833 | return; | ||
834 | } | ||
835 | |||
836 | DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST)); | ||
837 | DBUG_ON(!(ch->flags & XPC_C_RCLOSEREQUEST)); | ||
838 | |||
839 | ch->flags |= XPC_C_RCLOSEREPLY; | ||
840 | |||
841 | if (ch->flags & XPC_C_CLOSEREPLY) { | ||
842 | /* both sides have finished disconnecting */ | ||
843 | xpc_process_disconnect(ch, &irq_flags); | ||
844 | } | ||
845 | } | ||
846 | |||
847 | |||
848 | if (IPI_flags & XPC_IPI_OPENREQUEST) { | ||
849 | |||
850 | dev_dbg(xpc_chan, "XPC_IPI_OPENREQUEST (msg_size=%d, " | ||
851 | "local_nentries=%d) received from partid=%d, " | ||
852 | "channel=%d\n", args->msg_size, args->local_nentries, | ||
853 | ch->partid, ch->number); | ||
854 | |||
855 | if ((ch->flags & XPC_C_DISCONNECTING) || | ||
856 | part->act_state == XPC_P_DEACTIVATING) { | ||
857 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
858 | return; | ||
859 | } | ||
860 | DBUG_ON(!(ch->flags & (XPC_C_DISCONNECTED | | ||
861 | XPC_C_OPENREQUEST))); | ||
862 | DBUG_ON(ch->flags & (XPC_C_ROPENREQUEST | XPC_C_ROPENREPLY | | ||
863 | XPC_C_OPENREPLY | XPC_C_CONNECTED)); | ||
864 | |||
865 | /* | ||
866 | * The meaningful OPENREQUEST connection state fields are: | ||
867 | * msg_size = size of channel's messages in bytes | ||
868 | * local_nentries = remote partition's local_nentries | ||
869 | */ | ||
870 | DBUG_ON(args->msg_size == 0); | ||
871 | DBUG_ON(args->local_nentries == 0); | ||
872 | |||
873 | ch->flags |= (XPC_C_ROPENREQUEST | XPC_C_CONNECTING); | ||
874 | ch->remote_nentries = args->local_nentries; | ||
875 | |||
876 | |||
877 | if (ch->flags & XPC_C_OPENREQUEST) { | ||
878 | if (args->msg_size != ch->msg_size) { | ||
879 | XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes, | ||
880 | &irq_flags); | ||
881 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
882 | return; | ||
883 | } | ||
884 | } else { | ||
885 | ch->msg_size = args->msg_size; | ||
886 | |||
887 | XPC_SET_REASON(ch, 0, 0); | ||
888 | ch->flags &= ~XPC_C_DISCONNECTED; | ||
889 | |||
890 | atomic_inc(&part->nchannels_active); | ||
891 | } | ||
892 | |||
893 | xpc_process_connect(ch, &irq_flags); | ||
894 | } | ||
895 | |||
896 | |||
897 | if (IPI_flags & XPC_IPI_OPENREPLY) { | ||
898 | |||
899 | dev_dbg(xpc_chan, "XPC_IPI_OPENREPLY (local_msgqueue_pa=0x%lx, " | ||
900 | "local_nentries=%d, remote_nentries=%d) received from " | ||
901 | "partid=%d, channel=%d\n", args->local_msgqueue_pa, | ||
902 | args->local_nentries, args->remote_nentries, | ||
903 | ch->partid, ch->number); | ||
904 | |||
905 | if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED)) { | ||
906 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
907 | return; | ||
908 | } | ||
909 | DBUG_ON(!(ch->flags & XPC_C_OPENREQUEST)); | ||
910 | DBUG_ON(!(ch->flags & XPC_C_ROPENREQUEST)); | ||
911 | DBUG_ON(ch->flags & XPC_C_CONNECTED); | ||
912 | |||
913 | /* | ||
914 | * The meaningful OPENREPLY connection state fields are: | ||
915 | * local_msgqueue_pa = physical address of remote | ||
916 | * partition's local_msgqueue | ||
917 | * local_nentries = remote partition's local_nentries | ||
918 | * remote_nentries = remote partition's remote_nentries | ||
919 | */ | ||
920 | DBUG_ON(args->local_msgqueue_pa == 0); | ||
921 | DBUG_ON(args->local_nentries == 0); | ||
922 | DBUG_ON(args->remote_nentries == 0); | ||
923 | |||
924 | ch->flags |= XPC_C_ROPENREPLY; | ||
925 | ch->remote_msgqueue_pa = args->local_msgqueue_pa; | ||
926 | |||
927 | if (args->local_nentries < ch->remote_nentries) { | ||
928 | dev_dbg(xpc_chan, "XPC_IPI_OPENREPLY: new " | ||
929 | "remote_nentries=%d, old remote_nentries=%d, " | ||
930 | "partid=%d, channel=%d\n", | ||
931 | args->local_nentries, ch->remote_nentries, | ||
932 | ch->partid, ch->number); | ||
933 | |||
934 | ch->remote_nentries = args->local_nentries; | ||
935 | } | ||
936 | if (args->remote_nentries < ch->local_nentries) { | ||
937 | dev_dbg(xpc_chan, "XPC_IPI_OPENREPLY: new " | ||
938 | "local_nentries=%d, old local_nentries=%d, " | ||
939 | "partid=%d, channel=%d\n", | ||
940 | args->remote_nentries, ch->local_nentries, | ||
941 | ch->partid, ch->number); | ||
942 | |||
943 | ch->local_nentries = args->remote_nentries; | ||
944 | } | ||
945 | |||
946 | xpc_process_connect(ch, &irq_flags); | ||
947 | } | ||
948 | |||
949 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
950 | } | ||
951 | |||
952 | |||
953 | /* | ||
954 | * Attempt to establish a channel connection to a remote partition. | ||
955 | */ | ||
956 | static enum xpc_retval | ||
957 | xpc_connect_channel(struct xpc_channel *ch) | ||
958 | { | ||
959 | unsigned long irq_flags; | ||
960 | struct xpc_registration *registration = &xpc_registrations[ch->number]; | ||
961 | |||
962 | |||
963 | if (down_interruptible(®istration->sema) != 0) { | ||
964 | return xpcInterrupted; | ||
965 | } | ||
966 | |||
967 | if (!XPC_CHANNEL_REGISTERED(ch->number)) { | ||
968 | up(®istration->sema); | ||
969 | return xpcUnregistered; | ||
970 | } | ||
971 | |||
972 | spin_lock_irqsave(&ch->lock, irq_flags); | ||
973 | |||
974 | DBUG_ON(ch->flags & XPC_C_CONNECTED); | ||
975 | DBUG_ON(ch->flags & XPC_C_OPENREQUEST); | ||
976 | |||
977 | if (ch->flags & XPC_C_DISCONNECTING) { | ||
978 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
979 | up(®istration->sema); | ||
980 | return ch->reason; | ||
981 | } | ||
982 | |||
983 | |||
984 | /* add info from the channel connect registration to the channel */ | ||
985 | |||
986 | ch->kthreads_assigned_limit = registration->assigned_limit; | ||
987 | ch->kthreads_idle_limit = registration->idle_limit; | ||
988 | DBUG_ON(atomic_read(&ch->kthreads_assigned) != 0); | ||
989 | DBUG_ON(atomic_read(&ch->kthreads_idle) != 0); | ||
990 | DBUG_ON(atomic_read(&ch->kthreads_active) != 0); | ||
991 | |||
992 | ch->func = registration->func; | ||
993 | DBUG_ON(registration->func == NULL); | ||
994 | ch->key = registration->key; | ||
995 | |||
996 | ch->local_nentries = registration->nentries; | ||
997 | |||
998 | if (ch->flags & XPC_C_ROPENREQUEST) { | ||
999 | if (registration->msg_size != ch->msg_size) { | ||
1000 | /* the local and remote sides aren't the same */ | ||
1001 | |||
1002 | /* | ||
1003 | * Because XPC_DISCONNECT_CHANNEL() can block we're | ||
1004 | * forced to up the registration sema before we unlock | ||
1005 | * the channel lock. But that's okay here because we're | ||
1006 | * done with the part that required the registration | ||
1007 | * sema. XPC_DISCONNECT_CHANNEL() requires that the | ||
1008 | * channel lock be locked and will unlock and relock | ||
1009 | * the channel lock as needed. | ||
1010 | */ | ||
1011 | up(®istration->sema); | ||
1012 | XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes, | ||
1013 | &irq_flags); | ||
1014 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
1015 | return xpcUnequalMsgSizes; | ||
1016 | } | ||
1017 | } else { | ||
1018 | ch->msg_size = registration->msg_size; | ||
1019 | |||
1020 | XPC_SET_REASON(ch, 0, 0); | ||
1021 | ch->flags &= ~XPC_C_DISCONNECTED; | ||
1022 | |||
1023 | atomic_inc(&xpc_partitions[ch->partid].nchannels_active); | ||
1024 | } | ||
1025 | |||
1026 | up(®istration->sema); | ||
1027 | |||
1028 | |||
1029 | /* initiate the connection */ | ||
1030 | |||
1031 | ch->flags |= (XPC_C_OPENREQUEST | XPC_C_CONNECTING); | ||
1032 | xpc_IPI_send_openrequest(ch, &irq_flags); | ||
1033 | |||
1034 | xpc_process_connect(ch, &irq_flags); | ||
1035 | |||
1036 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
1037 | |||
1038 | return xpcSuccess; | ||
1039 | } | ||
1040 | |||
1041 | |||
1042 | /* | ||
1043 | * Notify those who wanted to be notified upon delivery of their message. | ||
1044 | */ | ||
1045 | static void | ||
1046 | xpc_notify_senders(struct xpc_channel *ch, enum xpc_retval reason, s64 put) | ||
1047 | { | ||
1048 | struct xpc_notify *notify; | ||
1049 | u8 notify_type; | ||
1050 | s64 get = ch->w_remote_GP.get - 1; | ||
1051 | |||
1052 | |||
1053 | while (++get < put && atomic_read(&ch->n_to_notify) > 0) { | ||
1054 | |||
1055 | notify = &ch->notify_queue[get % ch->local_nentries]; | ||
1056 | |||
1057 | /* | ||
1058 | * See if the notify entry indicates it was associated with | ||
1059 | * a message who's sender wants to be notified. It is possible | ||
1060 | * that it is, but someone else is doing or has done the | ||
1061 | * notification. | ||
1062 | */ | ||
1063 | notify_type = notify->type; | ||
1064 | if (notify_type == 0 || | ||
1065 | cmpxchg(¬ify->type, notify_type, 0) != | ||
1066 | notify_type) { | ||
1067 | continue; | ||
1068 | } | ||
1069 | |||
1070 | DBUG_ON(notify_type != XPC_N_CALL); | ||
1071 | |||
1072 | atomic_dec(&ch->n_to_notify); | ||
1073 | |||
1074 | if (notify->func != NULL) { | ||
1075 | dev_dbg(xpc_chan, "notify->func() called, notify=0x%p, " | ||
1076 | "msg_number=%ld, partid=%d, channel=%d\n", | ||
1077 | (void *) notify, get, ch->partid, ch->number); | ||
1078 | |||
1079 | notify->func(reason, ch->partid, ch->number, | ||
1080 | notify->key); | ||
1081 | |||
1082 | dev_dbg(xpc_chan, "notify->func() returned, " | ||
1083 | "notify=0x%p, msg_number=%ld, partid=%d, " | ||
1084 | "channel=%d\n", (void *) notify, get, | ||
1085 | ch->partid, ch->number); | ||
1086 | } | ||
1087 | } | ||
1088 | } | ||
1089 | |||
1090 | |||
1091 | /* | ||
1092 | * Clear some of the msg flags in the local message queue. | ||
1093 | */ | ||
1094 | static inline void | ||
1095 | xpc_clear_local_msgqueue_flags(struct xpc_channel *ch) | ||
1096 | { | ||
1097 | struct xpc_msg *msg; | ||
1098 | s64 get; | ||
1099 | |||
1100 | |||
1101 | get = ch->w_remote_GP.get; | ||
1102 | do { | ||
1103 | msg = (struct xpc_msg *) ((u64) ch->local_msgqueue + | ||
1104 | (get % ch->local_nentries) * ch->msg_size); | ||
1105 | msg->flags = 0; | ||
1106 | } while (++get < (volatile s64) ch->remote_GP.get); | ||
1107 | } | ||
1108 | |||
1109 | |||
1110 | /* | ||
1111 | * Clear some of the msg flags in the remote message queue. | ||
1112 | */ | ||
1113 | static inline void | ||
1114 | xpc_clear_remote_msgqueue_flags(struct xpc_channel *ch) | ||
1115 | { | ||
1116 | struct xpc_msg *msg; | ||
1117 | s64 put; | ||
1118 | |||
1119 | |||
1120 | put = ch->w_remote_GP.put; | ||
1121 | do { | ||
1122 | msg = (struct xpc_msg *) ((u64) ch->remote_msgqueue + | ||
1123 | (put % ch->remote_nentries) * ch->msg_size); | ||
1124 | msg->flags = 0; | ||
1125 | } while (++put < (volatile s64) ch->remote_GP.put); | ||
1126 | } | ||
1127 | |||
1128 | |||
1129 | static void | ||
1130 | xpc_process_msg_IPI(struct xpc_partition *part, int ch_number) | ||
1131 | { | ||
1132 | struct xpc_channel *ch = &part->channels[ch_number]; | ||
1133 | int nmsgs_sent; | ||
1134 | |||
1135 | |||
1136 | ch->remote_GP = part->remote_GPs[ch_number]; | ||
1137 | |||
1138 | |||
1139 | /* See what, if anything, has changed for each connected channel */ | ||
1140 | |||
1141 | xpc_msgqueue_ref(ch); | ||
1142 | |||
1143 | if (ch->w_remote_GP.get == ch->remote_GP.get && | ||
1144 | ch->w_remote_GP.put == ch->remote_GP.put) { | ||
1145 | /* nothing changed since GPs were last pulled */ | ||
1146 | xpc_msgqueue_deref(ch); | ||
1147 | return; | ||
1148 | } | ||
1149 | |||
1150 | if (!(ch->flags & XPC_C_CONNECTED)){ | ||
1151 | xpc_msgqueue_deref(ch); | ||
1152 | return; | ||
1153 | } | ||
1154 | |||
1155 | |||
1156 | /* | ||
1157 | * First check to see if messages recently sent by us have been | ||
1158 | * received by the other side. (The remote GET value will have | ||
1159 | * changed since we last looked at it.) | ||
1160 | */ | ||
1161 | |||
1162 | if (ch->w_remote_GP.get != ch->remote_GP.get) { | ||
1163 | |||
1164 | /* | ||
1165 | * We need to notify any senders that want to be notified | ||
1166 | * that their sent messages have been received by their | ||
1167 | * intended recipients. We need to do this before updating | ||
1168 | * w_remote_GP.get so that we don't allocate the same message | ||
1169 | * queue entries prematurely (see xpc_allocate_msg()). | ||
1170 | */ | ||
1171 | if (atomic_read(&ch->n_to_notify) > 0) { | ||
1172 | /* | ||
1173 | * Notify senders that messages sent have been | ||
1174 | * received and delivered by the other side. | ||
1175 | */ | ||
1176 | xpc_notify_senders(ch, xpcMsgDelivered, | ||
1177 | ch->remote_GP.get); | ||
1178 | } | ||
1179 | |||
1180 | /* | ||
1181 | * Clear msg->flags in previously sent messages, so that | ||
1182 | * they're ready for xpc_allocate_msg(). | ||
1183 | */ | ||
1184 | xpc_clear_local_msgqueue_flags(ch); | ||
1185 | |||
1186 | (volatile s64) ch->w_remote_GP.get = ch->remote_GP.get; | ||
1187 | |||
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, | ||
1190 | ch->number); | ||
1191 | |||
1192 | /* | ||
1193 | * If anyone was waiting for message queue entries to become | ||
1194 | * available, wake them up. | ||
1195 | */ | ||
1196 | if (atomic_read(&ch->n_on_msg_allocate_wq) > 0) { | ||
1197 | wake_up(&ch->msg_allocate_wq); | ||
1198 | } | ||
1199 | } | ||
1200 | |||
1201 | |||
1202 | /* | ||
1203 | * Now check for newly sent messages by the other side. (The remote | ||
1204 | * PUT value will have changed since we last looked at it.) | ||
1205 | */ | ||
1206 | |||
1207 | if (ch->w_remote_GP.put != ch->remote_GP.put) { | ||
1208 | /* | ||
1209 | * Clear msg->flags in previously received messages, so that | ||
1210 | * they're ready for xpc_get_deliverable_msg(). | ||
1211 | */ | ||
1212 | xpc_clear_remote_msgqueue_flags(ch); | ||
1213 | |||
1214 | (volatile s64) ch->w_remote_GP.put = ch->remote_GP.put; | ||
1215 | |||
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, | ||
1218 | ch->number); | ||
1219 | |||
1220 | nmsgs_sent = ch->w_remote_GP.put - ch->w_local_GP.get; | ||
1221 | if (nmsgs_sent > 0) { | ||
1222 | dev_dbg(xpc_chan, "msgs waiting to be copied and " | ||
1223 | "delivered=%d, partid=%d, channel=%d\n", | ||
1224 | nmsgs_sent, ch->partid, ch->number); | ||
1225 | |||
1226 | if (ch->flags & XPC_C_CONNECTCALLOUT) { | ||
1227 | xpc_activate_kthreads(ch, nmsgs_sent); | ||
1228 | } | ||
1229 | } | ||
1230 | } | ||
1231 | |||
1232 | xpc_msgqueue_deref(ch); | ||
1233 | } | ||
1234 | |||
1235 | |||
1236 | void | ||
1237 | xpc_process_channel_activity(struct xpc_partition *part) | ||
1238 | { | ||
1239 | unsigned long irq_flags; | ||
1240 | u64 IPI_amo, IPI_flags; | ||
1241 | struct xpc_channel *ch; | ||
1242 | int ch_number; | ||
1243 | |||
1244 | |||
1245 | IPI_amo = xpc_get_IPI_flags(part); | ||
1246 | |||
1247 | /* | ||
1248 | * Initiate channel connections for registered channels. | ||
1249 | * | ||
1250 | * For each connected channel that has pending messages activate idle | ||
1251 | * kthreads and/or create new kthreads as needed. | ||
1252 | */ | ||
1253 | |||
1254 | for (ch_number = 0; ch_number < part->nchannels; ch_number++) { | ||
1255 | ch = &part->channels[ch_number]; | ||
1256 | |||
1257 | |||
1258 | /* | ||
1259 | * Process any open or close related IPI flags, and then deal | ||
1260 | * with connecting or disconnecting the channel as required. | ||
1261 | */ | ||
1262 | |||
1263 | IPI_flags = XPC_GET_IPI_FLAGS(IPI_amo, ch_number); | ||
1264 | |||
1265 | if (XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(IPI_flags)) { | ||
1266 | xpc_process_openclose_IPI(part, ch_number, IPI_flags); | ||
1267 | } | ||
1268 | |||
1269 | |||
1270 | if (ch->flags & XPC_C_DISCONNECTING) { | ||
1271 | spin_lock_irqsave(&ch->lock, irq_flags); | ||
1272 | xpc_process_disconnect(ch, &irq_flags); | ||
1273 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
1274 | continue; | ||
1275 | } | ||
1276 | |||
1277 | if (part->act_state == XPC_P_DEACTIVATING) { | ||
1278 | continue; | ||
1279 | } | ||
1280 | |||
1281 | if (!(ch->flags & XPC_C_CONNECTED)) { | ||
1282 | if (!(ch->flags & XPC_C_OPENREQUEST)) { | ||
1283 | DBUG_ON(ch->flags & XPC_C_SETUP); | ||
1284 | (void) xpc_connect_channel(ch); | ||
1285 | } else { | ||
1286 | spin_lock_irqsave(&ch->lock, irq_flags); | ||
1287 | xpc_process_connect(ch, &irq_flags); | ||
1288 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
1289 | } | ||
1290 | continue; | ||
1291 | } | ||
1292 | |||
1293 | |||
1294 | /* | ||
1295 | * Process any message related IPI flags, this may involve the | ||
1296 | * activation of kthreads to deliver any pending messages sent | ||
1297 | * from the other partition. | ||
1298 | */ | ||
1299 | |||
1300 | if (XPC_ANY_MSG_IPI_FLAGS_SET(IPI_flags)) { | ||
1301 | xpc_process_msg_IPI(part, ch_number); | ||
1302 | } | ||
1303 | } | ||
1304 | } | ||
1305 | |||
1306 | |||
1307 | /* | ||
1308 | * XPC's heartbeat code calls this function to inform XPC that a partition has | ||
1309 | * gone down. XPC responds by tearing down the XPartition Communication | ||
1310 | * infrastructure used for the just downed partition. | ||
1311 | * | ||
1312 | * XPC's heartbeat code will never call this function and xpc_partition_up() | ||
1313 | * at the same time. Nor will it ever make multiple calls to either function | ||
1314 | * at the same time. | ||
1315 | */ | ||
1316 | void | ||
1317 | xpc_partition_down(struct xpc_partition *part, enum xpc_retval reason) | ||
1318 | { | ||
1319 | unsigned long irq_flags; | ||
1320 | int ch_number; | ||
1321 | struct xpc_channel *ch; | ||
1322 | |||
1323 | |||
1324 | dev_dbg(xpc_chan, "deactivating partition %d, reason=%d\n", | ||
1325 | XPC_PARTID(part), reason); | ||
1326 | |||
1327 | if (!xpc_part_ref(part)) { | ||
1328 | /* infrastructure for this partition isn't currently set up */ | ||
1329 | return; | ||
1330 | } | ||
1331 | |||
1332 | |||
1333 | /* disconnect all channels associated with the downed partition */ | ||
1334 | |||
1335 | for (ch_number = 0; ch_number < part->nchannels; ch_number++) { | ||
1336 | ch = &part->channels[ch_number]; | ||
1337 | |||
1338 | |||
1339 | xpc_msgqueue_ref(ch); | ||
1340 | spin_lock_irqsave(&ch->lock, irq_flags); | ||
1341 | |||
1342 | XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags); | ||
1343 | |||
1344 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
1345 | xpc_msgqueue_deref(ch); | ||
1346 | } | ||
1347 | |||
1348 | xpc_wakeup_channel_mgr(part); | ||
1349 | |||
1350 | xpc_part_deref(part); | ||
1351 | } | ||
1352 | |||
1353 | |||
1354 | /* | ||
1355 | * Teardown the infrastructure necessary to support XPartition Communication | ||
1356 | * between the specified remote partition and the local one. | ||
1357 | */ | ||
1358 | void | ||
1359 | xpc_teardown_infrastructure(struct xpc_partition *part) | ||
1360 | { | ||
1361 | partid_t partid = XPC_PARTID(part); | ||
1362 | |||
1363 | |||
1364 | /* | ||
1365 | * We start off by making this partition inaccessible to local | ||
1366 | * processes by marking it as no longer setup. Then we make it | ||
1367 | * inaccessible to remote processes by clearing the XPC per partition | ||
1368 | * specific variable's magic # (which indicates that these variables | ||
1369 | * are no longer valid) and by ignoring all XPC notify IPIs sent to | ||
1370 | * this partition. | ||
1371 | */ | ||
1372 | |||
1373 | DBUG_ON(atomic_read(&part->nchannels_active) != 0); | ||
1374 | DBUG_ON(part->setup_state != XPC_P_SETUP); | ||
1375 | part->setup_state = XPC_P_WTEARDOWN; | ||
1376 | |||
1377 | xpc_vars_part[partid].magic = 0; | ||
1378 | |||
1379 | |||
1380 | free_irq(SGI_XPC_NOTIFY, (void *) (u64) partid); | ||
1381 | |||
1382 | |||
1383 | /* | ||
1384 | * Before proceding with the teardown we have to wait until all | ||
1385 | * existing references cease. | ||
1386 | */ | ||
1387 | wait_event(part->teardown_wq, (atomic_read(&part->references) == 0)); | ||
1388 | |||
1389 | |||
1390 | /* now we can begin tearing down the infrastructure */ | ||
1391 | |||
1392 | part->setup_state = XPC_P_TORNDOWN; | ||
1393 | |||
1394 | /* in case we've still got outstanding timers registered... */ | ||
1395 | del_timer_sync(&part->dropped_IPI_timer); | ||
1396 | |||
1397 | kfree(part->remote_openclose_args_base); | ||
1398 | part->remote_openclose_args = NULL; | ||
1399 | kfree(part->local_openclose_args_base); | ||
1400 | part->local_openclose_args = NULL; | ||
1401 | kfree(part->remote_GPs_base); | ||
1402 | part->remote_GPs = NULL; | ||
1403 | kfree(part->local_GPs_base); | ||
1404 | part->local_GPs = NULL; | ||
1405 | kfree(part->channels); | ||
1406 | part->channels = NULL; | ||
1407 | part->local_IPI_amo_va = NULL; | ||
1408 | } | ||
1409 | |||
1410 | |||
1411 | /* | ||
1412 | * Called by XP at the time of channel connection registration to cause | ||
1413 | * XPC to establish connections to all currently active partitions. | ||
1414 | */ | ||
1415 | void | ||
1416 | xpc_initiate_connect(int ch_number) | ||
1417 | { | ||
1418 | partid_t partid; | ||
1419 | struct xpc_partition *part; | ||
1420 | struct xpc_channel *ch; | ||
1421 | |||
1422 | |||
1423 | DBUG_ON(ch_number < 0 || ch_number >= XPC_NCHANNELS); | ||
1424 | |||
1425 | for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { | ||
1426 | part = &xpc_partitions[partid]; | ||
1427 | |||
1428 | if (xpc_part_ref(part)) { | ||
1429 | ch = &part->channels[ch_number]; | ||
1430 | |||
1431 | if (!(ch->flags & XPC_C_DISCONNECTING)) { | ||
1432 | DBUG_ON(ch->flags & XPC_C_OPENREQUEST); | ||
1433 | DBUG_ON(ch->flags & XPC_C_CONNECTED); | ||
1434 | DBUG_ON(ch->flags & XPC_C_SETUP); | ||
1435 | |||
1436 | /* | ||
1437 | * Initiate the establishment of a connection | ||
1438 | * on the newly registered channel to the | ||
1439 | * remote partition. | ||
1440 | */ | ||
1441 | xpc_wakeup_channel_mgr(part); | ||
1442 | } | ||
1443 | |||
1444 | xpc_part_deref(part); | ||
1445 | } | ||
1446 | } | ||
1447 | } | ||
1448 | |||
1449 | |||
1450 | void | ||
1451 | xpc_connected_callout(struct xpc_channel *ch) | ||
1452 | { | ||
1453 | unsigned long irq_flags; | ||
1454 | |||
1455 | |||
1456 | /* let the registerer know that a connection has been established */ | ||
1457 | |||
1458 | if (ch->func != NULL) { | ||
1459 | dev_dbg(xpc_chan, "ch->func() called, reason=xpcConnected, " | ||
1460 | "partid=%d, channel=%d\n", ch->partid, ch->number); | ||
1461 | |||
1462 | ch->func(xpcConnected, ch->partid, ch->number, | ||
1463 | (void *) (u64) ch->local_nentries, ch->key); | ||
1464 | |||
1465 | dev_dbg(xpc_chan, "ch->func() returned, reason=xpcConnected, " | ||
1466 | "partid=%d, channel=%d\n", ch->partid, ch->number); | ||
1467 | } | ||
1468 | |||
1469 | spin_lock_irqsave(&ch->lock, irq_flags); | ||
1470 | ch->flags |= XPC_C_CONNECTCALLOUT; | ||
1471 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
1472 | } | ||
1473 | |||
1474 | |||
1475 | /* | ||
1476 | * Called by XP at the time of channel connection unregistration to cause | ||
1477 | * XPC to teardown all current connections for the specified channel. | ||
1478 | * | ||
1479 | * Before returning xpc_initiate_disconnect() will wait until all connections | ||
1480 | * on the specified channel have been closed/torndown. So the caller can be | ||
1481 | * assured that they will not be receiving any more callouts from XPC to the | ||
1482 | * function they registered via xpc_connect(). | ||
1483 | * | ||
1484 | * Arguments: | ||
1485 | * | ||
1486 | * ch_number - channel # to unregister. | ||
1487 | */ | ||
1488 | void | ||
1489 | xpc_initiate_disconnect(int ch_number) | ||
1490 | { | ||
1491 | unsigned long irq_flags; | ||
1492 | partid_t partid; | ||
1493 | struct xpc_partition *part; | ||
1494 | struct xpc_channel *ch; | ||
1495 | |||
1496 | |||
1497 | DBUG_ON(ch_number < 0 || ch_number >= XPC_NCHANNELS); | ||
1498 | |||
1499 | /* initiate the channel disconnect for every active partition */ | ||
1500 | for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { | ||
1501 | part = &xpc_partitions[partid]; | ||
1502 | |||
1503 | if (xpc_part_ref(part)) { | ||
1504 | ch = &part->channels[ch_number]; | ||
1505 | xpc_msgqueue_ref(ch); | ||
1506 | |||
1507 | spin_lock_irqsave(&ch->lock, irq_flags); | ||
1508 | |||
1509 | XPC_DISCONNECT_CHANNEL(ch, xpcUnregistering, | ||
1510 | &irq_flags); | ||
1511 | |||
1512 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
1513 | |||
1514 | xpc_msgqueue_deref(ch); | ||
1515 | xpc_part_deref(part); | ||
1516 | } | ||
1517 | } | ||
1518 | |||
1519 | xpc_disconnect_wait(ch_number); | ||
1520 | } | ||
1521 | |||
1522 | |||
1523 | /* | ||
1524 | * To disconnect a channel, and reflect it back to all who may be waiting. | ||
1525 | * | ||
1526 | * >>> An OPEN is not allowed until XPC_C_DISCONNECTING is cleared by | ||
1527 | * >>> xpc_free_msgqueues(). | ||
1528 | * | ||
1529 | * THE CHANNEL IS TO BE LOCKED BY THE CALLER AND WILL REMAIN LOCKED UPON RETURN. | ||
1530 | */ | ||
1531 | void | ||
1532 | xpc_disconnect_channel(const int line, struct xpc_channel *ch, | ||
1533 | enum xpc_retval reason, unsigned long *irq_flags) | ||
1534 | { | ||
1535 | u32 flags; | ||
1536 | |||
1537 | |||
1538 | DBUG_ON(!spin_is_locked(&ch->lock)); | ||
1539 | |||
1540 | if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED)) { | ||
1541 | return; | ||
1542 | } | ||
1543 | DBUG_ON(!(ch->flags & (XPC_C_CONNECTING | XPC_C_CONNECTED))); | ||
1544 | |||
1545 | dev_dbg(xpc_chan, "reason=%d, line=%d, partid=%d, channel=%d\n", | ||
1546 | reason, line, ch->partid, ch->number); | ||
1547 | |||
1548 | XPC_SET_REASON(ch, reason, line); | ||
1549 | |||
1550 | flags = ch->flags; | ||
1551 | /* some of these may not have been set */ | ||
1552 | ch->flags &= ~(XPC_C_OPENREQUEST | XPC_C_OPENREPLY | | ||
1553 | XPC_C_ROPENREQUEST | XPC_C_ROPENREPLY | | ||
1554 | XPC_C_CONNECTING | XPC_C_CONNECTED); | ||
1555 | |||
1556 | ch->flags |= (XPC_C_CLOSEREQUEST | XPC_C_DISCONNECTING); | ||
1557 | xpc_IPI_send_closerequest(ch, irq_flags); | ||
1558 | |||
1559 | if (flags & XPC_C_CONNECTED) { | ||
1560 | ch->flags |= XPC_C_WASCONNECTED; | ||
1561 | } | ||
1562 | |||
1563 | if (atomic_read(&ch->kthreads_idle) > 0) { | ||
1564 | /* wake all idle kthreads so they can exit */ | ||
1565 | wake_up_all(&ch->idle_wq); | ||
1566 | } | ||
1567 | |||
1568 | spin_unlock_irqrestore(&ch->lock, *irq_flags); | ||
1569 | |||
1570 | |||
1571 | /* wake those waiting to allocate an entry from the local msg queue */ | ||
1572 | |||
1573 | if (atomic_read(&ch->n_on_msg_allocate_wq) > 0) { | ||
1574 | wake_up(&ch->msg_allocate_wq); | ||
1575 | } | ||
1576 | |||
1577 | /* wake those waiting for notify completion */ | ||
1578 | |||
1579 | if (atomic_read(&ch->n_to_notify) > 0) { | ||
1580 | xpc_notify_senders(ch, reason, ch->w_local_GP.put); | ||
1581 | } | ||
1582 | |||
1583 | spin_lock_irqsave(&ch->lock, *irq_flags); | ||
1584 | } | ||
1585 | |||
1586 | |||
1587 | void | ||
1588 | xpc_disconnected_callout(struct xpc_channel *ch) | ||
1589 | { | ||
1590 | /* | ||
1591 | * Let the channel's registerer know that the channel is now | ||
1592 | * disconnected. We don't want to do this if the registerer was never | ||
1593 | * informed of a connection being made, unless the disconnect was for | ||
1594 | * abnormal reasons. | ||
1595 | */ | ||
1596 | |||
1597 | if (ch->func != NULL) { | ||
1598 | dev_dbg(xpc_chan, "ch->func() called, reason=%d, partid=%d, " | ||
1599 | "channel=%d\n", ch->reason, ch->partid, ch->number); | ||
1600 | |||
1601 | ch->func(ch->reason, ch->partid, ch->number, NULL, ch->key); | ||
1602 | |||
1603 | dev_dbg(xpc_chan, "ch->func() returned, reason=%d, partid=%d, " | ||
1604 | "channel=%d\n", ch->reason, ch->partid, ch->number); | ||
1605 | } | ||
1606 | } | ||
1607 | |||
1608 | |||
1609 | /* | ||
1610 | * Wait for a message entry to become available for the specified channel, | ||
1611 | * but don't wait any longer than 1 jiffy. | ||
1612 | */ | ||
1613 | static enum xpc_retval | ||
1614 | xpc_allocate_msg_wait(struct xpc_channel *ch) | ||
1615 | { | ||
1616 | enum xpc_retval ret; | ||
1617 | |||
1618 | |||
1619 | if (ch->flags & XPC_C_DISCONNECTING) { | ||
1620 | DBUG_ON(ch->reason == xpcInterrupted); // >>> Is this true? | ||
1621 | return ch->reason; | ||
1622 | } | ||
1623 | |||
1624 | atomic_inc(&ch->n_on_msg_allocate_wq); | ||
1625 | ret = interruptible_sleep_on_timeout(&ch->msg_allocate_wq, 1); | ||
1626 | atomic_dec(&ch->n_on_msg_allocate_wq); | ||
1627 | |||
1628 | if (ch->flags & XPC_C_DISCONNECTING) { | ||
1629 | ret = ch->reason; | ||
1630 | DBUG_ON(ch->reason == xpcInterrupted); // >>> Is this true? | ||
1631 | } else if (ret == 0) { | ||
1632 | ret = xpcTimeout; | ||
1633 | } else { | ||
1634 | ret = xpcInterrupted; | ||
1635 | } | ||
1636 | |||
1637 | return ret; | ||
1638 | } | ||
1639 | |||
1640 | |||
1641 | /* | ||
1642 | * Allocate an entry for a message from the message queue associated with the | ||
1643 | * specified channel. | ||
1644 | */ | ||
1645 | static enum xpc_retval | ||
1646 | xpc_allocate_msg(struct xpc_channel *ch, u32 flags, | ||
1647 | struct xpc_msg **address_of_msg) | ||
1648 | { | ||
1649 | struct xpc_msg *msg; | ||
1650 | enum xpc_retval ret; | ||
1651 | s64 put; | ||
1652 | |||
1653 | |||
1654 | /* this reference will be dropped in xpc_send_msg() */ | ||
1655 | xpc_msgqueue_ref(ch); | ||
1656 | |||
1657 | if (ch->flags & XPC_C_DISCONNECTING) { | ||
1658 | xpc_msgqueue_deref(ch); | ||
1659 | return ch->reason; | ||
1660 | } | ||
1661 | if (!(ch->flags & XPC_C_CONNECTED)) { | ||
1662 | xpc_msgqueue_deref(ch); | ||
1663 | return xpcNotConnected; | ||
1664 | } | ||
1665 | |||
1666 | |||
1667 | /* | ||
1668 | * Get the next available message entry from the local message queue. | ||
1669 | * If none are available, we'll make sure that we grab the latest | ||
1670 | * GP values. | ||
1671 | */ | ||
1672 | ret = xpcTimeout; | ||
1673 | |||
1674 | while (1) { | ||
1675 | |||
1676 | put = (volatile s64) ch->w_local_GP.put; | ||
1677 | if (put - (volatile s64) ch->w_remote_GP.get < | ||
1678 | ch->local_nentries) { | ||
1679 | |||
1680 | /* There are available message entries. We need to try | ||
1681 | * to secure one for ourselves. We'll do this by trying | ||
1682 | * to increment w_local_GP.put as long as someone else | ||
1683 | * doesn't beat us to it. If they do, we'll have to | ||
1684 | * try again. | ||
1685 | */ | ||
1686 | if (cmpxchg(&ch->w_local_GP.put, put, put + 1) == | ||
1687 | put) { | ||
1688 | /* we got the entry referenced by put */ | ||
1689 | break; | ||
1690 | } | ||
1691 | continue; /* try again */ | ||
1692 | } | ||
1693 | |||
1694 | |||
1695 | /* | ||
1696 | * There aren't any available msg entries at this time. | ||
1697 | * | ||
1698 | * In waiting for a message entry to become available, | ||
1699 | * we set a timeout in case the other side is not | ||
1700 | * sending completion IPIs. This lets us fake an IPI | ||
1701 | * that will cause the IPI handler to fetch the latest | ||
1702 | * GP values as if an IPI was sent by the other side. | ||
1703 | */ | ||
1704 | if (ret == xpcTimeout) { | ||
1705 | xpc_IPI_send_local_msgrequest(ch); | ||
1706 | } | ||
1707 | |||
1708 | if (flags & XPC_NOWAIT) { | ||
1709 | xpc_msgqueue_deref(ch); | ||
1710 | return xpcNoWait; | ||
1711 | } | ||
1712 | |||
1713 | ret = xpc_allocate_msg_wait(ch); | ||
1714 | if (ret != xpcInterrupted && ret != xpcTimeout) { | ||
1715 | xpc_msgqueue_deref(ch); | ||
1716 | return ret; | ||
1717 | } | ||
1718 | } | ||
1719 | |||
1720 | |||
1721 | /* get the message's address and initialize it */ | ||
1722 | msg = (struct xpc_msg *) ((u64) ch->local_msgqueue + | ||
1723 | (put % ch->local_nentries) * ch->msg_size); | ||
1724 | |||
1725 | |||
1726 | DBUG_ON(msg->flags != 0); | ||
1727 | msg->number = put; | ||
1728 | |||
1729 | dev_dbg(xpc_chan, "w_local_GP.put changed to %ld; msg=0x%p, " | ||
1730 | "msg_number=%ld, partid=%d, channel=%d\n", put + 1, | ||
1731 | (void *) msg, msg->number, ch->partid, ch->number); | ||
1732 | |||
1733 | *address_of_msg = msg; | ||
1734 | |||
1735 | return xpcSuccess; | ||
1736 | } | ||
1737 | |||
1738 | |||
1739 | /* | ||
1740 | * Allocate an entry for a message from the message queue associated with the | ||
1741 | * specified channel. NOTE that this routine can sleep waiting for a message | ||
1742 | * entry to become available. To not sleep, pass in the XPC_NOWAIT flag. | ||
1743 | * | ||
1744 | * Arguments: | ||
1745 | * | ||
1746 | * partid - ID of partition to which the channel is connected. | ||
1747 | * ch_number - channel #. | ||
1748 | * flags - see xpc.h for valid flags. | ||
1749 | * payload - address of the allocated payload area pointer (filled in on | ||
1750 | * return) in which the user-defined message is constructed. | ||
1751 | */ | ||
1752 | enum xpc_retval | ||
1753 | xpc_initiate_allocate(partid_t partid, int ch_number, u32 flags, void **payload) | ||
1754 | { | ||
1755 | struct xpc_partition *part = &xpc_partitions[partid]; | ||
1756 | enum xpc_retval ret = xpcUnknownReason; | ||
1757 | struct xpc_msg *msg; | ||
1758 | |||
1759 | |||
1760 | DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS); | ||
1761 | DBUG_ON(ch_number < 0 || ch_number >= part->nchannels); | ||
1762 | |||
1763 | *payload = NULL; | ||
1764 | |||
1765 | if (xpc_part_ref(part)) { | ||
1766 | ret = xpc_allocate_msg(&part->channels[ch_number], flags, &msg); | ||
1767 | xpc_part_deref(part); | ||
1768 | |||
1769 | if (msg != NULL) { | ||
1770 | *payload = &msg->payload; | ||
1771 | } | ||
1772 | } | ||
1773 | |||
1774 | return ret; | ||
1775 | } | ||
1776 | |||
1777 | |||
1778 | /* | ||
1779 | * Now we actually send the messages that are ready to be sent by advancing | ||
1780 | * the local message queue's Put value and then send an IPI to the recipient | ||
1781 | * partition. | ||
1782 | */ | ||
1783 | static void | ||
1784 | xpc_send_msgs(struct xpc_channel *ch, s64 initial_put) | ||
1785 | { | ||
1786 | struct xpc_msg *msg; | ||
1787 | s64 put = initial_put + 1; | ||
1788 | int send_IPI = 0; | ||
1789 | |||
1790 | |||
1791 | while (1) { | ||
1792 | |||
1793 | while (1) { | ||
1794 | if (put == (volatile s64) ch->w_local_GP.put) { | ||
1795 | break; | ||
1796 | } | ||
1797 | |||
1798 | msg = (struct xpc_msg *) ((u64) ch->local_msgqueue + | ||
1799 | (put % ch->local_nentries) * ch->msg_size); | ||
1800 | |||
1801 | if (!(msg->flags & XPC_M_READY)) { | ||
1802 | break; | ||
1803 | } | ||
1804 | |||
1805 | put++; | ||
1806 | } | ||
1807 | |||
1808 | if (put == initial_put) { | ||
1809 | /* nothing's changed */ | ||
1810 | break; | ||
1811 | } | ||
1812 | |||
1813 | if (cmpxchg_rel(&ch->local_GP->put, initial_put, put) != | ||
1814 | initial_put) { | ||
1815 | /* someone else beat us to it */ | ||
1816 | DBUG_ON((volatile s64) ch->local_GP->put < initial_put); | ||
1817 | break; | ||
1818 | } | ||
1819 | |||
1820 | /* we just set the new value of local_GP->put */ | ||
1821 | |||
1822 | dev_dbg(xpc_chan, "local_GP->put changed to %ld, partid=%d, " | ||
1823 | "channel=%d\n", put, ch->partid, ch->number); | ||
1824 | |||
1825 | send_IPI = 1; | ||
1826 | |||
1827 | /* | ||
1828 | * We need to ensure that the message referenced by | ||
1829 | * local_GP->put is not XPC_M_READY or that local_GP->put | ||
1830 | * equals w_local_GP.put, so we'll go have a look. | ||
1831 | */ | ||
1832 | initial_put = put; | ||
1833 | } | ||
1834 | |||
1835 | if (send_IPI) { | ||
1836 | xpc_IPI_send_msgrequest(ch); | ||
1837 | } | ||
1838 | } | ||
1839 | |||
1840 | |||
1841 | /* | ||
1842 | * Common code that does the actual sending of the message by advancing the | ||
1843 | * local message queue's Put value and sends an IPI to the partition the | ||
1844 | * message is being sent to. | ||
1845 | */ | ||
1846 | static enum xpc_retval | ||
1847 | xpc_send_msg(struct xpc_channel *ch, struct xpc_msg *msg, u8 notify_type, | ||
1848 | xpc_notify_func func, void *key) | ||
1849 | { | ||
1850 | enum xpc_retval ret = xpcSuccess; | ||
1851 | struct xpc_notify *notify = NULL; // >>> to keep the compiler happy!! | ||
1852 | s64 put, msg_number = msg->number; | ||
1853 | |||
1854 | |||
1855 | DBUG_ON(notify_type == XPC_N_CALL && func == NULL); | ||
1856 | DBUG_ON((((u64) msg - (u64) ch->local_msgqueue) / ch->msg_size) != | ||
1857 | msg_number % ch->local_nentries); | ||
1858 | DBUG_ON(msg->flags & XPC_M_READY); | ||
1859 | |||
1860 | if (ch->flags & XPC_C_DISCONNECTING) { | ||
1861 | /* drop the reference grabbed in xpc_allocate_msg() */ | ||
1862 | xpc_msgqueue_deref(ch); | ||
1863 | return ch->reason; | ||
1864 | } | ||
1865 | |||
1866 | if (notify_type != 0) { | ||
1867 | /* | ||
1868 | * Tell the remote side to send an ACK interrupt when the | ||
1869 | * message has been delivered. | ||
1870 | */ | ||
1871 | msg->flags |= XPC_M_INTERRUPT; | ||
1872 | |||
1873 | atomic_inc(&ch->n_to_notify); | ||
1874 | |||
1875 | notify = &ch->notify_queue[msg_number % ch->local_nentries]; | ||
1876 | notify->func = func; | ||
1877 | notify->key = key; | ||
1878 | (volatile u8) notify->type = notify_type; | ||
1879 | |||
1880 | // >>> is a mb() needed here? | ||
1881 | |||
1882 | if (ch->flags & XPC_C_DISCONNECTING) { | ||
1883 | /* | ||
1884 | * An error occurred between our last error check and | ||
1885 | * this one. We will try to clear the type field from | ||
1886 | * the notify entry. If we succeed then | ||
1887 | * xpc_disconnect_channel() didn't already process | ||
1888 | * the notify entry. | ||
1889 | */ | ||
1890 | if (cmpxchg(¬ify->type, notify_type, 0) == | ||
1891 | notify_type) { | ||
1892 | atomic_dec(&ch->n_to_notify); | ||
1893 | ret = ch->reason; | ||
1894 | } | ||
1895 | |||
1896 | /* drop the reference grabbed in xpc_allocate_msg() */ | ||
1897 | xpc_msgqueue_deref(ch); | ||
1898 | return ret; | ||
1899 | } | ||
1900 | } | ||
1901 | |||
1902 | msg->flags |= XPC_M_READY; | ||
1903 | |||
1904 | /* | ||
1905 | * The preceding store of msg->flags must occur before the following | ||
1906 | * load of ch->local_GP->put. | ||
1907 | */ | ||
1908 | mb(); | ||
1909 | |||
1910 | /* see if the message is next in line to be sent, if so send it */ | ||
1911 | |||
1912 | put = ch->local_GP->put; | ||
1913 | if (put == msg_number) { | ||
1914 | xpc_send_msgs(ch, put); | ||
1915 | } | ||
1916 | |||
1917 | /* drop the reference grabbed in xpc_allocate_msg() */ | ||
1918 | xpc_msgqueue_deref(ch); | ||
1919 | return ret; | ||
1920 | } | ||
1921 | |||
1922 | |||
1923 | /* | ||
1924 | * Send a message previously allocated using xpc_initiate_allocate() on the | ||
1925 | * specified channel connected to the specified partition. | ||
1926 | * | ||
1927 | * This routine will not wait for the message to be received, nor will | ||
1928 | * notification be given when it does happen. Once this routine has returned | ||
1929 | * the message entry allocated via xpc_initiate_allocate() is no longer | ||
1930 | * accessable to the caller. | ||
1931 | * | ||
1932 | * This routine, although called by users, does not call xpc_part_ref() to | ||
1933 | * ensure that the partition infrastructure is in place. It relies on the | ||
1934 | * fact that we called xpc_msgqueue_ref() in xpc_allocate_msg(). | ||
1935 | * | ||
1936 | * Arguments: | ||
1937 | * | ||
1938 | * partid - ID of partition to which the channel is connected. | ||
1939 | * ch_number - channel # to send message on. | ||
1940 | * payload - pointer to the payload area allocated via | ||
1941 | * xpc_initiate_allocate(). | ||
1942 | */ | ||
1943 | enum xpc_retval | ||
1944 | xpc_initiate_send(partid_t partid, int ch_number, void *payload) | ||
1945 | { | ||
1946 | struct xpc_partition *part = &xpc_partitions[partid]; | ||
1947 | struct xpc_msg *msg = XPC_MSG_ADDRESS(payload); | ||
1948 | enum xpc_retval ret; | ||
1949 | |||
1950 | |||
1951 | dev_dbg(xpc_chan, "msg=0x%p, partid=%d, channel=%d\n", (void *) msg, | ||
1952 | partid, ch_number); | ||
1953 | |||
1954 | DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS); | ||
1955 | DBUG_ON(ch_number < 0 || ch_number >= part->nchannels); | ||
1956 | DBUG_ON(msg == NULL); | ||
1957 | |||
1958 | ret = xpc_send_msg(&part->channels[ch_number], msg, 0, NULL, NULL); | ||
1959 | |||
1960 | return ret; | ||
1961 | } | ||
1962 | |||
1963 | |||
1964 | /* | ||
1965 | * Send a message previously allocated using xpc_initiate_allocate on the | ||
1966 | * specified channel connected to the specified partition. | ||
1967 | * | ||
1968 | * This routine will not wait for the message to be sent. Once this routine | ||
1969 | * has returned the message entry allocated via xpc_initiate_allocate() is no | ||
1970 | * longer accessable to the caller. | ||
1971 | * | ||
1972 | * Once the remote end of the channel has received the message, the function | ||
1973 | * passed as an argument to xpc_initiate_send_notify() will be called. This | ||
1974 | * allows the sender to free up or re-use any buffers referenced by the | ||
1975 | * message, but does NOT mean the message has been processed at the remote | ||
1976 | * end by a receiver. | ||
1977 | * | ||
1978 | * If this routine returns an error, the caller's function will NOT be called. | ||
1979 | * | ||
1980 | * This routine, although called by users, does not call xpc_part_ref() to | ||
1981 | * ensure that the partition infrastructure is in place. It relies on the | ||
1982 | * fact that we called xpc_msgqueue_ref() in xpc_allocate_msg(). | ||
1983 | * | ||
1984 | * Arguments: | ||
1985 | * | ||
1986 | * partid - ID of partition to which the channel is connected. | ||
1987 | * ch_number - channel # to send message on. | ||
1988 | * payload - pointer to the payload area allocated via | ||
1989 | * xpc_initiate_allocate(). | ||
1990 | * func - function to call with asynchronous notification of message | ||
1991 | * receipt. THIS FUNCTION MUST BE NON-BLOCKING. | ||
1992 | * key - user-defined key to be passed to the function when it's called. | ||
1993 | */ | ||
1994 | enum xpc_retval | ||
1995 | xpc_initiate_send_notify(partid_t partid, int ch_number, void *payload, | ||
1996 | xpc_notify_func func, void *key) | ||
1997 | { | ||
1998 | struct xpc_partition *part = &xpc_partitions[partid]; | ||
1999 | struct xpc_msg *msg = XPC_MSG_ADDRESS(payload); | ||
2000 | enum xpc_retval ret; | ||
2001 | |||
2002 | |||
2003 | dev_dbg(xpc_chan, "msg=0x%p, partid=%d, channel=%d\n", (void *) msg, | ||
2004 | partid, ch_number); | ||
2005 | |||
2006 | DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS); | ||
2007 | DBUG_ON(ch_number < 0 || ch_number >= part->nchannels); | ||
2008 | DBUG_ON(msg == NULL); | ||
2009 | DBUG_ON(func == NULL); | ||
2010 | |||
2011 | ret = xpc_send_msg(&part->channels[ch_number], msg, XPC_N_CALL, | ||
2012 | func, key); | ||
2013 | return ret; | ||
2014 | } | ||
2015 | |||
2016 | |||
2017 | static struct xpc_msg * | ||
2018 | xpc_pull_remote_msg(struct xpc_channel *ch, s64 get) | ||
2019 | { | ||
2020 | struct xpc_partition *part = &xpc_partitions[ch->partid]; | ||
2021 | struct xpc_msg *remote_msg, *msg; | ||
2022 | u32 msg_index, nmsgs; | ||
2023 | u64 msg_offset; | ||
2024 | enum xpc_retval ret; | ||
2025 | |||
2026 | |||
2027 | if (down_interruptible(&ch->msg_to_pull_sema) != 0) { | ||
2028 | /* we were interrupted by a signal */ | ||
2029 | return NULL; | ||
2030 | } | ||
2031 | |||
2032 | while (get >= ch->next_msg_to_pull) { | ||
2033 | |||
2034 | /* pull as many messages as are ready and able to be pulled */ | ||
2035 | |||
2036 | msg_index = ch->next_msg_to_pull % ch->remote_nentries; | ||
2037 | |||
2038 | DBUG_ON(ch->next_msg_to_pull >= | ||
2039 | (volatile s64) ch->w_remote_GP.put); | ||
2040 | nmsgs = (volatile s64) ch->w_remote_GP.put - | ||
2041 | ch->next_msg_to_pull; | ||
2042 | if (msg_index + nmsgs > ch->remote_nentries) { | ||
2043 | /* ignore the ones that wrap the msg queue for now */ | ||
2044 | nmsgs = ch->remote_nentries - msg_index; | ||
2045 | } | ||
2046 | |||
2047 | msg_offset = msg_index * ch->msg_size; | ||
2048 | msg = (struct xpc_msg *) ((u64) ch->remote_msgqueue + | ||
2049 | msg_offset); | ||
2050 | remote_msg = (struct xpc_msg *) (ch->remote_msgqueue_pa + | ||
2051 | msg_offset); | ||
2052 | |||
2053 | if ((ret = xpc_pull_remote_cachelines(part, msg, remote_msg, | ||
2054 | nmsgs * ch->msg_size)) != xpcSuccess) { | ||
2055 | |||
2056 | dev_dbg(xpc_chan, "failed to pull %d msgs starting with" | ||
2057 | " msg %ld from partition %d, channel=%d, " | ||
2058 | "ret=%d\n", nmsgs, ch->next_msg_to_pull, | ||
2059 | ch->partid, ch->number, ret); | ||
2060 | |||
2061 | XPC_DEACTIVATE_PARTITION(part, ret); | ||
2062 | |||
2063 | up(&ch->msg_to_pull_sema); | ||
2064 | return NULL; | ||
2065 | } | ||
2066 | |||
2067 | mb(); /* >>> this may not be needed, we're not sure */ | ||
2068 | |||
2069 | ch->next_msg_to_pull += nmsgs; | ||
2070 | } | ||
2071 | |||
2072 | up(&ch->msg_to_pull_sema); | ||
2073 | |||
2074 | /* return the message we were looking for */ | ||
2075 | msg_offset = (get % ch->remote_nentries) * ch->msg_size; | ||
2076 | msg = (struct xpc_msg *) ((u64) ch->remote_msgqueue + msg_offset); | ||
2077 | |||
2078 | return msg; | ||
2079 | } | ||
2080 | |||
2081 | |||
2082 | /* | ||
2083 | * Get a message to be delivered. | ||
2084 | */ | ||
2085 | static struct xpc_msg * | ||
2086 | xpc_get_deliverable_msg(struct xpc_channel *ch) | ||
2087 | { | ||
2088 | struct xpc_msg *msg = NULL; | ||
2089 | s64 get; | ||
2090 | |||
2091 | |||
2092 | do { | ||
2093 | if ((volatile u32) ch->flags & XPC_C_DISCONNECTING) { | ||
2094 | break; | ||
2095 | } | ||
2096 | |||
2097 | get = (volatile s64) ch->w_local_GP.get; | ||
2098 | if (get == (volatile s64) ch->w_remote_GP.put) { | ||
2099 | break; | ||
2100 | } | ||
2101 | |||
2102 | /* There are messages waiting to be pulled and delivered. | ||
2103 | * We need to try to secure one for ourselves. We'll do this | ||
2104 | * by trying to increment w_local_GP.get and hope that no one | ||
2105 | * else beats us to it. If they do, we'll we'll simply have | ||
2106 | * to try again for the next one. | ||
2107 | */ | ||
2108 | |||
2109 | if (cmpxchg(&ch->w_local_GP.get, get, get + 1) == get) { | ||
2110 | /* we got the entry referenced by get */ | ||
2111 | |||
2112 | dev_dbg(xpc_chan, "w_local_GP.get changed to %ld, " | ||
2113 | "partid=%d, channel=%d\n", get + 1, | ||
2114 | ch->partid, ch->number); | ||
2115 | |||
2116 | /* pull the message from the remote partition */ | ||
2117 | |||
2118 | msg = xpc_pull_remote_msg(ch, get); | ||
2119 | |||
2120 | DBUG_ON(msg != NULL && msg->number != get); | ||
2121 | DBUG_ON(msg != NULL && (msg->flags & XPC_M_DONE)); | ||
2122 | DBUG_ON(msg != NULL && !(msg->flags & XPC_M_READY)); | ||
2123 | |||
2124 | break; | ||
2125 | } | ||
2126 | |||
2127 | } while (1); | ||
2128 | |||
2129 | return msg; | ||
2130 | } | ||
2131 | |||
2132 | |||
2133 | /* | ||
2134 | * Deliver a message to its intended recipient. | ||
2135 | */ | ||
2136 | void | ||
2137 | xpc_deliver_msg(struct xpc_channel *ch) | ||
2138 | { | ||
2139 | struct xpc_msg *msg; | ||
2140 | |||
2141 | |||
2142 | if ((msg = xpc_get_deliverable_msg(ch)) != NULL) { | ||
2143 | |||
2144 | /* | ||
2145 | * This ref is taken to protect the payload itself from being | ||
2146 | * freed before the user is finished with it, which the user | ||
2147 | * indicates by calling xpc_initiate_received(). | ||
2148 | */ | ||
2149 | xpc_msgqueue_ref(ch); | ||
2150 | |||
2151 | atomic_inc(&ch->kthreads_active); | ||
2152 | |||
2153 | if (ch->func != NULL) { | ||
2154 | dev_dbg(xpc_chan, "ch->func() called, msg=0x%p, " | ||
2155 | "msg_number=%ld, partid=%d, channel=%d\n", | ||
2156 | (void *) msg, msg->number, ch->partid, | ||
2157 | ch->number); | ||
2158 | |||
2159 | /* deliver the message to its intended recipient */ | ||
2160 | ch->func(xpcMsgReceived, ch->partid, ch->number, | ||
2161 | &msg->payload, ch->key); | ||
2162 | |||
2163 | dev_dbg(xpc_chan, "ch->func() returned, msg=0x%p, " | ||
2164 | "msg_number=%ld, partid=%d, channel=%d\n", | ||
2165 | (void *) msg, msg->number, ch->partid, | ||
2166 | ch->number); | ||
2167 | } | ||
2168 | |||
2169 | atomic_dec(&ch->kthreads_active); | ||
2170 | } | ||
2171 | } | ||
2172 | |||
2173 | |||
2174 | /* | ||
2175 | * Now we actually acknowledge the messages that have been delivered and ack'd | ||
2176 | * by advancing the cached remote message queue's Get value and if requested | ||
2177 | * send an IPI to the message sender's partition. | ||
2178 | */ | ||
2179 | static void | ||
2180 | xpc_acknowledge_msgs(struct xpc_channel *ch, s64 initial_get, u8 msg_flags) | ||
2181 | { | ||
2182 | struct xpc_msg *msg; | ||
2183 | s64 get = initial_get + 1; | ||
2184 | int send_IPI = 0; | ||
2185 | |||
2186 | |||
2187 | while (1) { | ||
2188 | |||
2189 | while (1) { | ||
2190 | if (get == (volatile s64) ch->w_local_GP.get) { | ||
2191 | break; | ||
2192 | } | ||
2193 | |||
2194 | msg = (struct xpc_msg *) ((u64) ch->remote_msgqueue + | ||
2195 | (get % ch->remote_nentries) * ch->msg_size); | ||
2196 | |||
2197 | if (!(msg->flags & XPC_M_DONE)) { | ||
2198 | break; | ||
2199 | } | ||
2200 | |||
2201 | msg_flags |= msg->flags; | ||
2202 | get++; | ||
2203 | } | ||
2204 | |||
2205 | if (get == initial_get) { | ||
2206 | /* nothing's changed */ | ||
2207 | break; | ||
2208 | } | ||
2209 | |||
2210 | if (cmpxchg_rel(&ch->local_GP->get, initial_get, get) != | ||
2211 | initial_get) { | ||
2212 | /* someone else beat us to it */ | ||
2213 | DBUG_ON((volatile s64) ch->local_GP->get <= | ||
2214 | initial_get); | ||
2215 | break; | ||
2216 | } | ||
2217 | |||
2218 | /* we just set the new value of local_GP->get */ | ||
2219 | |||
2220 | dev_dbg(xpc_chan, "local_GP->get changed to %ld, partid=%d, " | ||
2221 | "channel=%d\n", get, ch->partid, ch->number); | ||
2222 | |||
2223 | send_IPI = (msg_flags & XPC_M_INTERRUPT); | ||
2224 | |||
2225 | /* | ||
2226 | * We need to ensure that the message referenced by | ||
2227 | * local_GP->get is not XPC_M_DONE or that local_GP->get | ||
2228 | * equals w_local_GP.get, so we'll go have a look. | ||
2229 | */ | ||
2230 | initial_get = get; | ||
2231 | } | ||
2232 | |||
2233 | if (send_IPI) { | ||
2234 | xpc_IPI_send_msgrequest(ch); | ||
2235 | } | ||
2236 | } | ||
2237 | |||
2238 | |||
2239 | /* | ||
2240 | * Acknowledge receipt of a delivered message. | ||
2241 | * | ||
2242 | * If a message has XPC_M_INTERRUPT set, send an interrupt to the partition | ||
2243 | * that sent the message. | ||
2244 | * | ||
2245 | * This function, although called by users, does not call xpc_part_ref() to | ||
2246 | * ensure that the partition infrastructure is in place. It relies on the | ||
2247 | * fact that we called xpc_msgqueue_ref() in xpc_deliver_msg(). | ||
2248 | * | ||
2249 | * Arguments: | ||
2250 | * | ||
2251 | * partid - ID of partition to which the channel is connected. | ||
2252 | * ch_number - channel # message received on. | ||
2253 | * payload - pointer to the payload area allocated via | ||
2254 | * xpc_initiate_allocate(). | ||
2255 | */ | ||
2256 | void | ||
2257 | xpc_initiate_received(partid_t partid, int ch_number, void *payload) | ||
2258 | { | ||
2259 | struct xpc_partition *part = &xpc_partitions[partid]; | ||
2260 | struct xpc_channel *ch; | ||
2261 | struct xpc_msg *msg = XPC_MSG_ADDRESS(payload); | ||
2262 | s64 get, msg_number = msg->number; | ||
2263 | |||
2264 | |||
2265 | DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS); | ||
2266 | DBUG_ON(ch_number < 0 || ch_number >= part->nchannels); | ||
2267 | |||
2268 | ch = &part->channels[ch_number]; | ||
2269 | |||
2270 | dev_dbg(xpc_chan, "msg=0x%p, msg_number=%ld, partid=%d, channel=%d\n", | ||
2271 | (void *) msg, msg_number, ch->partid, ch->number); | ||
2272 | |||
2273 | DBUG_ON((((u64) msg - (u64) ch->remote_msgqueue) / ch->msg_size) != | ||
2274 | msg_number % ch->remote_nentries); | ||
2275 | DBUG_ON(msg->flags & XPC_M_DONE); | ||
2276 | |||
2277 | msg->flags |= XPC_M_DONE; | ||
2278 | |||
2279 | /* | ||
2280 | * The preceding store of msg->flags must occur before the following | ||
2281 | * load of ch->local_GP->get. | ||
2282 | */ | ||
2283 | mb(); | ||
2284 | |||
2285 | /* | ||
2286 | * See if this message is next in line to be acknowledged as having | ||
2287 | * been delivered. | ||
2288 | */ | ||
2289 | get = ch->local_GP->get; | ||
2290 | if (get == msg_number) { | ||
2291 | xpc_acknowledge_msgs(ch, get, msg->flags); | ||
2292 | } | ||
2293 | |||
2294 | /* the call to xpc_msgqueue_ref() was done by xpc_deliver_msg() */ | ||
2295 | xpc_msgqueue_deref(ch); | ||
2296 | } | ||
2297 | |||
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c new file mode 100644 index 000000000000..177ddb748ebe --- /dev/null +++ b/arch/ia64/sn/kernel/xpc_main.c | |||
@@ -0,0 +1,1064 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved. | ||
7 | */ | ||
8 | |||
9 | |||
10 | /* | ||
11 | * Cross Partition Communication (XPC) support - standard version. | ||
12 | * | ||
13 | * XPC provides a message passing capability that crosses partition | ||
14 | * boundaries. This module is made up of two parts: | ||
15 | * | ||
16 | * partition This part detects the presence/absence of other | ||
17 | * partitions. It provides a heartbeat and monitors | ||
18 | * the heartbeats of other partitions. | ||
19 | * | ||
20 | * channel This part manages the channels and sends/receives | ||
21 | * messages across them to/from other partitions. | ||
22 | * | ||
23 | * There are a couple of additional functions residing in XP, which | ||
24 | * provide an interface to XPC for its users. | ||
25 | * | ||
26 | * | ||
27 | * Caveats: | ||
28 | * | ||
29 | * . We currently have no way to determine which nasid an IPI came | ||
30 | * from. Thus, xpc_IPI_send() does a remote AMO write followed by | ||
31 | * an IPI. The AMO indicates where data is to be pulled from, so | ||
32 | * after the IPI arrives, the remote partition checks the AMO word. | ||
33 | * The IPI can actually arrive before the AMO however, so other code | ||
34 | * must periodically check for this case. Also, remote AMO operations | ||
35 | * do not reliably time out. Thus we do a remote PIO read solely to | ||
36 | * know whether the remote partition is down and whether we should | ||
37 | * stop sending IPIs to it. This remote PIO read operation is set up | ||
38 | * in a special nofault region so SAL knows to ignore (and cleanup) | ||
39 | * any errors due to the remote AMO write, PIO read, and/or PIO | ||
40 | * write operations. | ||
41 | * | ||
42 | * If/when new hardware solves this IPI problem, we should abandon | ||
43 | * the current approach. | ||
44 | * | ||
45 | */ | ||
46 | |||
47 | |||
48 | #include <linux/kernel.h> | ||
49 | #include <linux/module.h> | ||
50 | #include <linux/init.h> | ||
51 | #include <linux/sched.h> | ||
52 | #include <linux/syscalls.h> | ||
53 | #include <linux/cache.h> | ||
54 | #include <linux/interrupt.h> | ||
55 | #include <linux/slab.h> | ||
56 | #include <asm/sn/intr.h> | ||
57 | #include <asm/sn/sn_sal.h> | ||
58 | #include <asm/uaccess.h> | ||
59 | #include "xpc.h" | ||
60 | |||
61 | |||
62 | /* define two XPC debug device structures to be used with dev_dbg() et al */ | ||
63 | |||
64 | struct device_driver xpc_dbg_name = { | ||
65 | .name = "xpc" | ||
66 | }; | ||
67 | |||
68 | struct device xpc_part_dbg_subname = { | ||
69 | .bus_id = {0}, /* set to "part" at xpc_init() time */ | ||
70 | .driver = &xpc_dbg_name | ||
71 | }; | ||
72 | |||
73 | struct device xpc_chan_dbg_subname = { | ||
74 | .bus_id = {0}, /* set to "chan" at xpc_init() time */ | ||
75 | .driver = &xpc_dbg_name | ||
76 | }; | ||
77 | |||
78 | struct device *xpc_part = &xpc_part_dbg_subname; | ||
79 | struct device *xpc_chan = &xpc_chan_dbg_subname; | ||
80 | |||
81 | |||
82 | /* systune related variables for /proc/sys directories */ | ||
83 | |||
84 | static int xpc_hb_min = 1; | ||
85 | static int xpc_hb_max = 10; | ||
86 | |||
87 | static int xpc_hb_check_min = 10; | ||
88 | static int xpc_hb_check_max = 120; | ||
89 | |||
90 | static ctl_table xpc_sys_xpc_hb_dir[] = { | ||
91 | { | ||
92 | 1, | ||
93 | "hb_interval", | ||
94 | &xpc_hb_interval, | ||
95 | sizeof(int), | ||
96 | 0644, | ||
97 | NULL, | ||
98 | &proc_dointvec_minmax, | ||
99 | &sysctl_intvec, | ||
100 | NULL, | ||
101 | &xpc_hb_min, &xpc_hb_max | ||
102 | }, | ||
103 | { | ||
104 | 2, | ||
105 | "hb_check_interval", | ||
106 | &xpc_hb_check_interval, | ||
107 | sizeof(int), | ||
108 | 0644, | ||
109 | NULL, | ||
110 | &proc_dointvec_minmax, | ||
111 | &sysctl_intvec, | ||
112 | NULL, | ||
113 | &xpc_hb_check_min, &xpc_hb_check_max | ||
114 | }, | ||
115 | {0} | ||
116 | }; | ||
117 | static ctl_table xpc_sys_xpc_dir[] = { | ||
118 | { | ||
119 | 1, | ||
120 | "hb", | ||
121 | NULL, | ||
122 | 0, | ||
123 | 0555, | ||
124 | xpc_sys_xpc_hb_dir | ||
125 | }, | ||
126 | {0} | ||
127 | }; | ||
128 | static ctl_table xpc_sys_dir[] = { | ||
129 | { | ||
130 | 1, | ||
131 | "xpc", | ||
132 | NULL, | ||
133 | 0, | ||
134 | 0555, | ||
135 | xpc_sys_xpc_dir | ||
136 | }, | ||
137 | {0} | ||
138 | }; | ||
139 | static struct ctl_table_header *xpc_sysctl; | ||
140 | |||
141 | |||
142 | /* #of IRQs received */ | ||
143 | static atomic_t xpc_act_IRQ_rcvd; | ||
144 | |||
145 | /* IRQ handler notifies this wait queue on receipt of an IRQ */ | ||
146 | static DECLARE_WAIT_QUEUE_HEAD(xpc_act_IRQ_wq); | ||
147 | |||
148 | static unsigned long xpc_hb_check_timeout; | ||
149 | |||
150 | /* xpc_hb_checker thread exited notification */ | ||
151 | static DECLARE_MUTEX_LOCKED(xpc_hb_checker_exited); | ||
152 | |||
153 | /* xpc_discovery thread exited notification */ | ||
154 | static DECLARE_MUTEX_LOCKED(xpc_discovery_exited); | ||
155 | |||
156 | |||
157 | static struct timer_list xpc_hb_timer; | ||
158 | |||
159 | |||
160 | static void xpc_kthread_waitmsgs(struct xpc_partition *, struct xpc_channel *); | ||
161 | |||
162 | |||
163 | /* | ||
164 | * Notify the heartbeat check thread that an IRQ has been received. | ||
165 | */ | ||
166 | static irqreturn_t | ||
167 | xpc_act_IRQ_handler(int irq, void *dev_id, struct pt_regs *regs) | ||
168 | { | ||
169 | atomic_inc(&xpc_act_IRQ_rcvd); | ||
170 | wake_up_interruptible(&xpc_act_IRQ_wq); | ||
171 | return IRQ_HANDLED; | ||
172 | } | ||
173 | |||
174 | |||
175 | /* | ||
176 | * Timer to produce the heartbeat. The timer structures function is | ||
177 | * already set when this is initially called. A tunable is used to | ||
178 | * specify when the next timeout should occur. | ||
179 | */ | ||
180 | static void | ||
181 | xpc_hb_beater(unsigned long dummy) | ||
182 | { | ||
183 | xpc_vars->heartbeat++; | ||
184 | |||
185 | if (jiffies >= xpc_hb_check_timeout) { | ||
186 | wake_up_interruptible(&xpc_act_IRQ_wq); | ||
187 | } | ||
188 | |||
189 | xpc_hb_timer.expires = jiffies + (xpc_hb_interval * HZ); | ||
190 | add_timer(&xpc_hb_timer); | ||
191 | } | ||
192 | |||
193 | |||
194 | /* | ||
195 | * This thread is responsible for nearly all of the partition | ||
196 | * activation/deactivation. | ||
197 | */ | ||
198 | static int | ||
199 | xpc_hb_checker(void *ignore) | ||
200 | { | ||
201 | int last_IRQ_count = 0; | ||
202 | int new_IRQ_count; | ||
203 | int force_IRQ=0; | ||
204 | |||
205 | |||
206 | /* this thread was marked active by xpc_hb_init() */ | ||
207 | |||
208 | daemonize(XPC_HB_CHECK_THREAD_NAME); | ||
209 | |||
210 | set_cpus_allowed(current, cpumask_of_cpu(XPC_HB_CHECK_CPU)); | ||
211 | |||
212 | xpc_hb_check_timeout = jiffies + (xpc_hb_check_interval * HZ); | ||
213 | |||
214 | while (!(volatile int) xpc_exiting) { | ||
215 | |||
216 | /* wait for IRQ or timeout */ | ||
217 | (void) wait_event_interruptible(xpc_act_IRQ_wq, | ||
218 | (last_IRQ_count < atomic_read(&xpc_act_IRQ_rcvd) || | ||
219 | jiffies >= xpc_hb_check_timeout || | ||
220 | (volatile int) xpc_exiting)); | ||
221 | |||
222 | dev_dbg(xpc_part, "woke up with %d ticks rem; %d IRQs have " | ||
223 | "been received\n", | ||
224 | (int) (xpc_hb_check_timeout - jiffies), | ||
225 | atomic_read(&xpc_act_IRQ_rcvd) - last_IRQ_count); | ||
226 | |||
227 | |||
228 | /* checking of remote heartbeats is skewed by IRQ handling */ | ||
229 | if (jiffies >= xpc_hb_check_timeout) { | ||
230 | dev_dbg(xpc_part, "checking remote heartbeats\n"); | ||
231 | xpc_check_remote_hb(); | ||
232 | |||
233 | /* | ||
234 | * We need to periodically recheck to ensure no | ||
235 | * IPI/AMO pairs have been missed. That check | ||
236 | * must always reset xpc_hb_check_timeout. | ||
237 | */ | ||
238 | force_IRQ = 1; | ||
239 | } | ||
240 | |||
241 | |||
242 | new_IRQ_count = atomic_read(&xpc_act_IRQ_rcvd); | ||
243 | if (last_IRQ_count < new_IRQ_count || force_IRQ != 0) { | ||
244 | force_IRQ = 0; | ||
245 | |||
246 | dev_dbg(xpc_part, "found an IRQ to process; will be " | ||
247 | "resetting xpc_hb_check_timeout\n"); | ||
248 | |||
249 | last_IRQ_count += xpc_identify_act_IRQ_sender(); | ||
250 | if (last_IRQ_count < new_IRQ_count) { | ||
251 | /* retry once to help avoid missing AMO */ | ||
252 | (void) xpc_identify_act_IRQ_sender(); | ||
253 | } | ||
254 | last_IRQ_count = new_IRQ_count; | ||
255 | |||
256 | xpc_hb_check_timeout = jiffies + | ||
257 | (xpc_hb_check_interval * HZ); | ||
258 | } | ||
259 | } | ||
260 | |||
261 | dev_dbg(xpc_part, "heartbeat checker is exiting\n"); | ||
262 | |||
263 | |||
264 | /* mark this thread as inactive */ | ||
265 | up(&xpc_hb_checker_exited); | ||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | |||
270 | /* | ||
271 | * This thread will attempt to discover other partitions to activate | ||
272 | * based on info provided by SAL. This new thread is short lived and | ||
273 | * will exit once discovery is complete. | ||
274 | */ | ||
275 | static int | ||
276 | xpc_initiate_discovery(void *ignore) | ||
277 | { | ||
278 | daemonize(XPC_DISCOVERY_THREAD_NAME); | ||
279 | |||
280 | xpc_discovery(); | ||
281 | |||
282 | dev_dbg(xpc_part, "discovery thread is exiting\n"); | ||
283 | |||
284 | /* mark this thread as inactive */ | ||
285 | up(&xpc_discovery_exited); | ||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | |||
290 | /* | ||
291 | * Establish first contact with the remote partititon. This involves pulling | ||
292 | * the XPC per partition variables from the remote partition and waiting for | ||
293 | * the remote partition to pull ours. | ||
294 | */ | ||
295 | static enum xpc_retval | ||
296 | xpc_make_first_contact(struct xpc_partition *part) | ||
297 | { | ||
298 | enum xpc_retval ret; | ||
299 | |||
300 | |||
301 | while ((ret = xpc_pull_remote_vars_part(part)) != xpcSuccess) { | ||
302 | if (ret != xpcRetry) { | ||
303 | XPC_DEACTIVATE_PARTITION(part, ret); | ||
304 | return ret; | ||
305 | } | ||
306 | |||
307 | dev_dbg(xpc_chan, "waiting to make first contact with " | ||
308 | "partition %d\n", XPC_PARTID(part)); | ||
309 | |||
310 | /* wait a 1/4 of a second or so */ | ||
311 | set_current_state(TASK_INTERRUPTIBLE); | ||
312 | (void) schedule_timeout(0.25 * HZ); | ||
313 | |||
314 | if (part->act_state == XPC_P_DEACTIVATING) { | ||
315 | return part->reason; | ||
316 | } | ||
317 | } | ||
318 | |||
319 | return xpc_mark_partition_active(part); | ||
320 | } | ||
321 | |||
322 | |||
323 | /* | ||
324 | * The first kthread assigned to a newly activated partition is the one | ||
325 | * created by XPC HB with which it calls xpc_partition_up(). XPC hangs on to | ||
326 | * that kthread until the partition is brought down, at which time that kthread | ||
327 | * returns back to XPC HB. (The return of that kthread will signify to XPC HB | ||
328 | * that XPC has dismantled all communication infrastructure for the associated | ||
329 | * partition.) This kthread becomes the channel manager for that partition. | ||
330 | * | ||
331 | * Each active partition has a channel manager, who, besides connecting and | ||
332 | * disconnecting channels, will ensure that each of the partition's connected | ||
333 | * channels has the required number of assigned kthreads to get the work done. | ||
334 | */ | ||
335 | static void | ||
336 | xpc_channel_mgr(struct xpc_partition *part) | ||
337 | { | ||
338 | while (part->act_state != XPC_P_DEACTIVATING || | ||
339 | atomic_read(&part->nchannels_active) > 0) { | ||
340 | |||
341 | xpc_process_channel_activity(part); | ||
342 | |||
343 | |||
344 | /* | ||
345 | * Wait until we've been requested to activate kthreads or | ||
346 | * all of the channel's message queues have been torn down or | ||
347 | * a signal is pending. | ||
348 | * | ||
349 | * The channel_mgr_requests is set to 1 after being awakened, | ||
350 | * This is done to prevent the channel mgr from making one pass | ||
351 | * through the loop for each request, since he will | ||
352 | * be servicing all the requests in one pass. The reason it's | ||
353 | * set to 1 instead of 0 is so that other kthreads will know | ||
354 | * that the channel mgr is running and won't bother trying to | ||
355 | * wake him up. | ||
356 | */ | ||
357 | atomic_dec(&part->channel_mgr_requests); | ||
358 | (void) wait_event_interruptible(part->channel_mgr_wq, | ||
359 | (atomic_read(&part->channel_mgr_requests) > 0 || | ||
360 | (volatile u64) part->local_IPI_amo != 0 || | ||
361 | ((volatile u8) part->act_state == | ||
362 | XPC_P_DEACTIVATING && | ||
363 | atomic_read(&part->nchannels_active) == 0))); | ||
364 | atomic_set(&part->channel_mgr_requests, 1); | ||
365 | |||
366 | // >>> Does it need to wakeup periodically as well? In case we | ||
367 | // >>> miscalculated the #of kthreads to wakeup or create? | ||
368 | } | ||
369 | } | ||
370 | |||
371 | |||
372 | /* | ||
373 | * When XPC HB determines that a partition has come up, it will create a new | ||
374 | * kthread and that kthread will call this function to attempt to set up the | ||
375 | * basic infrastructure used for Cross Partition Communication with the newly | ||
376 | * upped partition. | ||
377 | * | ||
378 | * The kthread that was created by XPC HB and which setup the XPC | ||
379 | * infrastructure will remain assigned to the partition until the partition | ||
380 | * goes down. At which time the kthread will teardown the XPC infrastructure | ||
381 | * and then exit. | ||
382 | * | ||
383 | * XPC HB will put the remote partition's XPC per partition specific variables | ||
384 | * physical address into xpc_partitions[partid].remote_vars_part_pa prior to | ||
385 | * calling xpc_partition_up(). | ||
386 | */ | ||
387 | static void | ||
388 | xpc_partition_up(struct xpc_partition *part) | ||
389 | { | ||
390 | DBUG_ON(part->channels != NULL); | ||
391 | |||
392 | dev_dbg(xpc_chan, "activating partition %d\n", XPC_PARTID(part)); | ||
393 | |||
394 | if (xpc_setup_infrastructure(part) != xpcSuccess) { | ||
395 | return; | ||
396 | } | ||
397 | |||
398 | /* | ||
399 | * The kthread that XPC HB called us with will become the | ||
400 | * channel manager for this partition. It will not return | ||
401 | * back to XPC HB until the partition's XPC infrastructure | ||
402 | * has been dismantled. | ||
403 | */ | ||
404 | |||
405 | (void) xpc_part_ref(part); /* this will always succeed */ | ||
406 | |||
407 | if (xpc_make_first_contact(part) == xpcSuccess) { | ||
408 | xpc_channel_mgr(part); | ||
409 | } | ||
410 | |||
411 | xpc_part_deref(part); | ||
412 | |||
413 | xpc_teardown_infrastructure(part); | ||
414 | } | ||
415 | |||
416 | |||
417 | static int | ||
418 | xpc_activating(void *__partid) | ||
419 | { | ||
420 | partid_t partid = (u64) __partid; | ||
421 | struct xpc_partition *part = &xpc_partitions[partid]; | ||
422 | unsigned long irq_flags; | ||
423 | struct sched_param param = { sched_priority: MAX_USER_RT_PRIO - 1 }; | ||
424 | int ret; | ||
425 | |||
426 | |||
427 | DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS); | ||
428 | |||
429 | spin_lock_irqsave(&part->act_lock, irq_flags); | ||
430 | |||
431 | if (part->act_state == XPC_P_DEACTIVATING) { | ||
432 | part->act_state = XPC_P_INACTIVE; | ||
433 | spin_unlock_irqrestore(&part->act_lock, irq_flags); | ||
434 | part->remote_rp_pa = 0; | ||
435 | return 0; | ||
436 | } | ||
437 | |||
438 | /* indicate the thread is activating */ | ||
439 | DBUG_ON(part->act_state != XPC_P_ACTIVATION_REQ); | ||
440 | part->act_state = XPC_P_ACTIVATING; | ||
441 | |||
442 | XPC_SET_REASON(part, 0, 0); | ||
443 | spin_unlock_irqrestore(&part->act_lock, irq_flags); | ||
444 | |||
445 | dev_dbg(xpc_part, "bringing partition %d up\n", partid); | ||
446 | |||
447 | daemonize("xpc%02d", partid); | ||
448 | |||
449 | /* | ||
450 | * This thread needs to run at a realtime priority to prevent a | ||
451 | * significant performance degradation. | ||
452 | */ | ||
453 | ret = sched_setscheduler(current, SCHED_FIFO, ¶m); | ||
454 | if (ret != 0) { | ||
455 | dev_warn(xpc_part, "unable to set pid %d to a realtime " | ||
456 | "priority, ret=%d\n", current->pid, ret); | ||
457 | } | ||
458 | |||
459 | /* allow this thread and its children to run on any CPU */ | ||
460 | set_cpus_allowed(current, CPU_MASK_ALL); | ||
461 | |||
462 | /* | ||
463 | * Register the remote partition's AMOs with SAL so it can handle | ||
464 | * and cleanup errors within that address range should the remote | ||
465 | * partition go down. We don't unregister this range because it is | ||
466 | * difficult to tell when outstanding writes to the remote partition | ||
467 | * are finished and thus when it is safe to unregister. This should | ||
468 | * not result in wasted space in the SAL xp_addr_region table because | ||
469 | * we should get the same page for remote_amos_page_pa after module | ||
470 | * reloads and system reboots. | ||
471 | */ | ||
472 | if (sn_register_xp_addr_region(part->remote_amos_page_pa, | ||
473 | PAGE_SIZE, 1) < 0) { | ||
474 | dev_warn(xpc_part, "xpc_partition_up(%d) failed to register " | ||
475 | "xp_addr region\n", partid); | ||
476 | |||
477 | spin_lock_irqsave(&part->act_lock, irq_flags); | ||
478 | part->act_state = XPC_P_INACTIVE; | ||
479 | XPC_SET_REASON(part, xpcPhysAddrRegFailed, __LINE__); | ||
480 | spin_unlock_irqrestore(&part->act_lock, irq_flags); | ||
481 | part->remote_rp_pa = 0; | ||
482 | return 0; | ||
483 | } | ||
484 | |||
485 | XPC_ALLOW_HB(partid, xpc_vars); | ||
486 | xpc_IPI_send_activated(part); | ||
487 | |||
488 | |||
489 | /* | ||
490 | * xpc_partition_up() holds this thread and marks this partition as | ||
491 | * XPC_P_ACTIVE by calling xpc_hb_mark_active(). | ||
492 | */ | ||
493 | (void) xpc_partition_up(part); | ||
494 | |||
495 | xpc_mark_partition_inactive(part); | ||
496 | |||
497 | if (part->reason == xpcReactivating) { | ||
498 | /* interrupting ourselves results in activating partition */ | ||
499 | xpc_IPI_send_reactivate(part); | ||
500 | } | ||
501 | |||
502 | return 0; | ||
503 | } | ||
504 | |||
505 | |||
506 | void | ||
507 | xpc_activate_partition(struct xpc_partition *part) | ||
508 | { | ||
509 | partid_t partid = XPC_PARTID(part); | ||
510 | unsigned long irq_flags; | ||
511 | pid_t pid; | ||
512 | |||
513 | |||
514 | spin_lock_irqsave(&part->act_lock, irq_flags); | ||
515 | |||
516 | pid = kernel_thread(xpc_activating, (void *) ((u64) partid), 0); | ||
517 | |||
518 | DBUG_ON(part->act_state != XPC_P_INACTIVE); | ||
519 | |||
520 | if (pid > 0) { | ||
521 | part->act_state = XPC_P_ACTIVATION_REQ; | ||
522 | XPC_SET_REASON(part, xpcCloneKThread, __LINE__); | ||
523 | } else { | ||
524 | XPC_SET_REASON(part, xpcCloneKThreadFailed, __LINE__); | ||
525 | } | ||
526 | |||
527 | spin_unlock_irqrestore(&part->act_lock, irq_flags); | ||
528 | } | ||
529 | |||
530 | |||
531 | /* | ||
532 | * Handle the receipt of a SGI_XPC_NOTIFY IRQ by seeing whether the specified | ||
533 | * partition actually sent it. Since SGI_XPC_NOTIFY IRQs may be shared by more | ||
534 | * than one partition, we use an AMO_t structure per partition to indicate | ||
535 | * whether a partition has sent an IPI or not. >>> If it has, then wake up the | ||
536 | * associated kthread to handle it. | ||
537 | * | ||
538 | * All SGI_XPC_NOTIFY IRQs received by XPC are the result of IPIs sent by XPC | ||
539 | * running on other partitions. | ||
540 | * | ||
541 | * Noteworthy Arguments: | ||
542 | * | ||
543 | * irq - Interrupt ReQuest number. NOT USED. | ||
544 | * | ||
545 | * dev_id - partid of IPI's potential sender. | ||
546 | * | ||
547 | * regs - processor's context before the processor entered | ||
548 | * interrupt code. NOT USED. | ||
549 | */ | ||
550 | irqreturn_t | ||
551 | xpc_notify_IRQ_handler(int irq, void *dev_id, struct pt_regs *regs) | ||
552 | { | ||
553 | partid_t partid = (partid_t) (u64) dev_id; | ||
554 | struct xpc_partition *part = &xpc_partitions[partid]; | ||
555 | |||
556 | |||
557 | DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS); | ||
558 | |||
559 | if (xpc_part_ref(part)) { | ||
560 | xpc_check_for_channel_activity(part); | ||
561 | |||
562 | xpc_part_deref(part); | ||
563 | } | ||
564 | return IRQ_HANDLED; | ||
565 | } | ||
566 | |||
567 | |||
568 | /* | ||
569 | * Check to see if xpc_notify_IRQ_handler() dropped any IPIs on the floor | ||
570 | * because the write to their associated IPI amo completed after the IRQ/IPI | ||
571 | * was received. | ||
572 | */ | ||
573 | void | ||
574 | xpc_dropped_IPI_check(struct xpc_partition *part) | ||
575 | { | ||
576 | if (xpc_part_ref(part)) { | ||
577 | xpc_check_for_channel_activity(part); | ||
578 | |||
579 | part->dropped_IPI_timer.expires = jiffies + | ||
580 | XPC_P_DROPPED_IPI_WAIT; | ||
581 | add_timer(&part->dropped_IPI_timer); | ||
582 | xpc_part_deref(part); | ||
583 | } | ||
584 | } | ||
585 | |||
586 | |||
587 | void | ||
588 | xpc_activate_kthreads(struct xpc_channel *ch, int needed) | ||
589 | { | ||
590 | int idle = atomic_read(&ch->kthreads_idle); | ||
591 | int assigned = atomic_read(&ch->kthreads_assigned); | ||
592 | int wakeup; | ||
593 | |||
594 | |||
595 | DBUG_ON(needed <= 0); | ||
596 | |||
597 | if (idle > 0) { | ||
598 | wakeup = (needed > idle) ? idle : needed; | ||
599 | needed -= wakeup; | ||
600 | |||
601 | dev_dbg(xpc_chan, "wakeup %d idle kthreads, partid=%d, " | ||
602 | "channel=%d\n", wakeup, ch->partid, ch->number); | ||
603 | |||
604 | /* only wakeup the requested number of kthreads */ | ||
605 | wake_up_nr(&ch->idle_wq, wakeup); | ||
606 | } | ||
607 | |||
608 | if (needed <= 0) { | ||
609 | return; | ||
610 | } | ||
611 | |||
612 | if (needed + assigned > ch->kthreads_assigned_limit) { | ||
613 | needed = ch->kthreads_assigned_limit - assigned; | ||
614 | // >>>should never be less than 0 | ||
615 | if (needed <= 0) { | ||
616 | return; | ||
617 | } | ||
618 | } | ||
619 | |||
620 | dev_dbg(xpc_chan, "create %d new kthreads, partid=%d, channel=%d\n", | ||
621 | needed, ch->partid, ch->number); | ||
622 | |||
623 | xpc_create_kthreads(ch, needed); | ||
624 | } | ||
625 | |||
626 | |||
627 | /* | ||
628 | * This function is where XPC's kthreads wait for messages to deliver. | ||
629 | */ | ||
630 | static void | ||
631 | xpc_kthread_waitmsgs(struct xpc_partition *part, struct xpc_channel *ch) | ||
632 | { | ||
633 | do { | ||
634 | /* deliver messages to their intended recipients */ | ||
635 | |||
636 | while ((volatile s64) ch->w_local_GP.get < | ||
637 | (volatile s64) ch->w_remote_GP.put && | ||
638 | !((volatile u32) ch->flags & | ||
639 | XPC_C_DISCONNECTING)) { | ||
640 | xpc_deliver_msg(ch); | ||
641 | } | ||
642 | |||
643 | if (atomic_inc_return(&ch->kthreads_idle) > | ||
644 | ch->kthreads_idle_limit) { | ||
645 | /* too many idle kthreads on this channel */ | ||
646 | atomic_dec(&ch->kthreads_idle); | ||
647 | break; | ||
648 | } | ||
649 | |||
650 | dev_dbg(xpc_chan, "idle kthread calling " | ||
651 | "wait_event_interruptible_exclusive()\n"); | ||
652 | |||
653 | (void) wait_event_interruptible_exclusive(ch->idle_wq, | ||
654 | ((volatile s64) ch->w_local_GP.get < | ||
655 | (volatile s64) ch->w_remote_GP.put || | ||
656 | ((volatile u32) ch->flags & | ||
657 | XPC_C_DISCONNECTING))); | ||
658 | |||
659 | atomic_dec(&ch->kthreads_idle); | ||
660 | |||
661 | } while (!((volatile u32) ch->flags & XPC_C_DISCONNECTING)); | ||
662 | } | ||
663 | |||
664 | |||
665 | static int | ||
666 | xpc_daemonize_kthread(void *args) | ||
667 | { | ||
668 | partid_t partid = XPC_UNPACK_ARG1(args); | ||
669 | u16 ch_number = XPC_UNPACK_ARG2(args); | ||
670 | struct xpc_partition *part = &xpc_partitions[partid]; | ||
671 | struct xpc_channel *ch; | ||
672 | int n_needed; | ||
673 | |||
674 | |||
675 | daemonize("xpc%02dc%d", partid, ch_number); | ||
676 | |||
677 | dev_dbg(xpc_chan, "kthread starting, partid=%d, channel=%d\n", | ||
678 | partid, ch_number); | ||
679 | |||
680 | ch = &part->channels[ch_number]; | ||
681 | |||
682 | if (!(ch->flags & XPC_C_DISCONNECTING)) { | ||
683 | DBUG_ON(!(ch->flags & XPC_C_CONNECTED)); | ||
684 | |||
685 | /* let registerer know that connection has been established */ | ||
686 | |||
687 | if (atomic_read(&ch->kthreads_assigned) == 1) { | ||
688 | xpc_connected_callout(ch); | ||
689 | |||
690 | /* | ||
691 | * It is possible that while the callout was being | ||
692 | * made that the remote partition sent some messages. | ||
693 | * If that is the case, we may need to activate | ||
694 | * additional kthreads to help deliver them. We only | ||
695 | * need one less than total #of messages to deliver. | ||
696 | */ | ||
697 | n_needed = ch->w_remote_GP.put - ch->w_local_GP.get - 1; | ||
698 | if (n_needed > 0 && | ||
699 | !(ch->flags & XPC_C_DISCONNECTING)) { | ||
700 | xpc_activate_kthreads(ch, n_needed); | ||
701 | } | ||
702 | } | ||
703 | |||
704 | xpc_kthread_waitmsgs(part, ch); | ||
705 | } | ||
706 | |||
707 | if (atomic_dec_return(&ch->kthreads_assigned) == 0 && | ||
708 | ((ch->flags & XPC_C_CONNECTCALLOUT) || | ||
709 | (ch->reason != xpcUnregistering && | ||
710 | ch->reason != xpcOtherUnregistering))) { | ||
711 | xpc_disconnected_callout(ch); | ||
712 | } | ||
713 | |||
714 | |||
715 | xpc_msgqueue_deref(ch); | ||
716 | |||
717 | dev_dbg(xpc_chan, "kthread exiting, partid=%d, channel=%d\n", | ||
718 | partid, ch_number); | ||
719 | |||
720 | xpc_part_deref(part); | ||
721 | return 0; | ||
722 | } | ||
723 | |||
724 | |||
725 | /* | ||
726 | * For each partition that XPC has established communications with, there is | ||
727 | * a minimum of one kernel thread assigned to perform any operation that | ||
728 | * may potentially sleep or block (basically the callouts to the asynchronous | ||
729 | * functions registered via xpc_connect()). | ||
730 | * | ||
731 | * Additional kthreads are created and destroyed by XPC as the workload | ||
732 | * demands. | ||
733 | * | ||
734 | * A kthread is assigned to one of the active channels that exists for a given | ||
735 | * partition. | ||
736 | */ | ||
737 | void | ||
738 | xpc_create_kthreads(struct xpc_channel *ch, int needed) | ||
739 | { | ||
740 | unsigned long irq_flags; | ||
741 | pid_t pid; | ||
742 | u64 args = XPC_PACK_ARGS(ch->partid, ch->number); | ||
743 | |||
744 | |||
745 | while (needed-- > 0) { | ||
746 | pid = kernel_thread(xpc_daemonize_kthread, (void *) args, 0); | ||
747 | if (pid < 0) { | ||
748 | /* the fork failed */ | ||
749 | |||
750 | if (atomic_read(&ch->kthreads_assigned) < | ||
751 | ch->kthreads_idle_limit) { | ||
752 | /* | ||
753 | * Flag this as an error only if we have an | ||
754 | * insufficient #of kthreads for the channel | ||
755 | * to function. | ||
756 | * | ||
757 | * No xpc_msgqueue_ref() is needed here since | ||
758 | * the channel mgr is doing this. | ||
759 | */ | ||
760 | spin_lock_irqsave(&ch->lock, irq_flags); | ||
761 | XPC_DISCONNECT_CHANNEL(ch, xpcLackOfResources, | ||
762 | &irq_flags); | ||
763 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
764 | } | ||
765 | break; | ||
766 | } | ||
767 | |||
768 | /* | ||
769 | * The following is done on behalf of the newly created | ||
770 | * kthread. That kthread is responsible for doing the | ||
771 | * counterpart to the following before it exits. | ||
772 | */ | ||
773 | (void) xpc_part_ref(&xpc_partitions[ch->partid]); | ||
774 | xpc_msgqueue_ref(ch); | ||
775 | atomic_inc(&ch->kthreads_assigned); | ||
776 | ch->kthreads_created++; // >>> temporary debug only!!! | ||
777 | } | ||
778 | } | ||
779 | |||
780 | |||
781 | void | ||
782 | xpc_disconnect_wait(int ch_number) | ||
783 | { | ||
784 | partid_t partid; | ||
785 | struct xpc_partition *part; | ||
786 | struct xpc_channel *ch; | ||
787 | |||
788 | |||
789 | /* now wait for all callouts to the caller's function to cease */ | ||
790 | for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { | ||
791 | part = &xpc_partitions[partid]; | ||
792 | |||
793 | if (xpc_part_ref(part)) { | ||
794 | ch = &part->channels[ch_number]; | ||
795 | |||
796 | // >>> how do we keep from falling into the window between our check and going | ||
797 | // >>> down and coming back up where sema is re-inited? | ||
798 | if (ch->flags & XPC_C_SETUP) { | ||
799 | (void) down(&ch->teardown_sema); | ||
800 | } | ||
801 | |||
802 | xpc_part_deref(part); | ||
803 | } | ||
804 | } | ||
805 | } | ||
806 | |||
807 | |||
808 | static void | ||
809 | xpc_do_exit(void) | ||
810 | { | ||
811 | partid_t partid; | ||
812 | int active_part_count; | ||
813 | struct xpc_partition *part; | ||
814 | |||
815 | |||
816 | /* now it's time to eliminate our heartbeat */ | ||
817 | del_timer_sync(&xpc_hb_timer); | ||
818 | xpc_vars->heartbeating_to_mask = 0; | ||
819 | |||
820 | /* indicate to others that our reserved page is uninitialized */ | ||
821 | xpc_rsvd_page->vars_pa = 0; | ||
822 | |||
823 | /* | ||
824 | * Ignore all incoming interrupts. Without interupts the heartbeat | ||
825 | * checker won't activate any new partitions that may come up. | ||
826 | */ | ||
827 | free_irq(SGI_XPC_ACTIVATE, NULL); | ||
828 | |||
829 | /* | ||
830 | * Cause the heartbeat checker and the discovery threads to exit. | ||
831 | * We don't want them attempting to activate new partitions as we | ||
832 | * try to deactivate the existing ones. | ||
833 | */ | ||
834 | xpc_exiting = 1; | ||
835 | wake_up_interruptible(&xpc_act_IRQ_wq); | ||
836 | |||
837 | /* wait for the heartbeat checker thread to mark itself inactive */ | ||
838 | down(&xpc_hb_checker_exited); | ||
839 | |||
840 | /* wait for the discovery thread to mark itself inactive */ | ||
841 | down(&xpc_discovery_exited); | ||
842 | |||
843 | |||
844 | set_current_state(TASK_INTERRUPTIBLE); | ||
845 | schedule_timeout(0.3 * HZ); | ||
846 | set_current_state(TASK_RUNNING); | ||
847 | |||
848 | |||
849 | /* wait for all partitions to become inactive */ | ||
850 | |||
851 | do { | ||
852 | active_part_count = 0; | ||
853 | |||
854 | for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { | ||
855 | part = &xpc_partitions[partid]; | ||
856 | if (part->act_state != XPC_P_INACTIVE) { | ||
857 | active_part_count++; | ||
858 | |||
859 | XPC_DEACTIVATE_PARTITION(part, xpcUnloading); | ||
860 | } | ||
861 | } | ||
862 | |||
863 | if (active_part_count) { | ||
864 | set_current_state(TASK_INTERRUPTIBLE); | ||
865 | schedule_timeout(0.3 * HZ); | ||
866 | set_current_state(TASK_RUNNING); | ||
867 | } | ||
868 | |||
869 | } while (active_part_count > 0); | ||
870 | |||
871 | |||
872 | /* close down protections for IPI operations */ | ||
873 | xpc_restrict_IPI_ops(); | ||
874 | |||
875 | |||
876 | /* clear the interface to XPC's functions */ | ||
877 | xpc_clear_interface(); | ||
878 | |||
879 | if (xpc_sysctl) { | ||
880 | unregister_sysctl_table(xpc_sysctl); | ||
881 | } | ||
882 | } | ||
883 | |||
884 | |||
885 | int __init | ||
886 | xpc_init(void) | ||
887 | { | ||
888 | int ret; | ||
889 | partid_t partid; | ||
890 | struct xpc_partition *part; | ||
891 | pid_t pid; | ||
892 | |||
893 | |||
894 | /* | ||
895 | * xpc_remote_copy_buffer is used as a temporary buffer for bte_copy'ng | ||
896 | * both a partition's reserved page and its XPC variables. Its size was | ||
897 | * based on the size of a reserved page. So we need to ensure that the | ||
898 | * XPC variables will fit as well. | ||
899 | */ | ||
900 | if (XPC_VARS_ALIGNED_SIZE > XPC_RSVD_PAGE_ALIGNED_SIZE) { | ||
901 | dev_err(xpc_part, "xpc_remote_copy_buffer is not big enough\n"); | ||
902 | return -EPERM; | ||
903 | } | ||
904 | DBUG_ON((u64) xpc_remote_copy_buffer != | ||
905 | L1_CACHE_ALIGN((u64) xpc_remote_copy_buffer)); | ||
906 | |||
907 | snprintf(xpc_part->bus_id, BUS_ID_SIZE, "part"); | ||
908 | snprintf(xpc_chan->bus_id, BUS_ID_SIZE, "chan"); | ||
909 | |||
910 | xpc_sysctl = register_sysctl_table(xpc_sys_dir, 1); | ||
911 | |||
912 | /* | ||
913 | * The first few fields of each entry of xpc_partitions[] need to | ||
914 | * be initialized now so that calls to xpc_connect() and | ||
915 | * xpc_disconnect() can be made prior to the activation of any remote | ||
916 | * partition. NOTE THAT NONE OF THE OTHER FIELDS BELONGING TO THESE | ||
917 | * ENTRIES ARE MEANINGFUL UNTIL AFTER AN ENTRY'S CORRESPONDING | ||
918 | * PARTITION HAS BEEN ACTIVATED. | ||
919 | */ | ||
920 | for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { | ||
921 | part = &xpc_partitions[partid]; | ||
922 | |||
923 | DBUG_ON((u64) part != L1_CACHE_ALIGN((u64) part)); | ||
924 | |||
925 | part->act_IRQ_rcvd = 0; | ||
926 | spin_lock_init(&part->act_lock); | ||
927 | part->act_state = XPC_P_INACTIVE; | ||
928 | XPC_SET_REASON(part, 0, 0); | ||
929 | part->setup_state = XPC_P_UNSET; | ||
930 | init_waitqueue_head(&part->teardown_wq); | ||
931 | atomic_set(&part->references, 0); | ||
932 | } | ||
933 | |||
934 | /* | ||
935 | * Open up protections for IPI operations (and AMO operations on | ||
936 | * Shub 1.1 systems). | ||
937 | */ | ||
938 | xpc_allow_IPI_ops(); | ||
939 | |||
940 | /* | ||
941 | * Interrupts being processed will increment this atomic variable and | ||
942 | * awaken the heartbeat thread which will process the interrupts. | ||
943 | */ | ||
944 | atomic_set(&xpc_act_IRQ_rcvd, 0); | ||
945 | |||
946 | /* | ||
947 | * This is safe to do before the xpc_hb_checker thread has started | ||
948 | * because the handler releases a wait queue. If an interrupt is | ||
949 | * received before the thread is waiting, it will not go to sleep, | ||
950 | * but rather immediately process the interrupt. | ||
951 | */ | ||
952 | ret = request_irq(SGI_XPC_ACTIVATE, xpc_act_IRQ_handler, 0, | ||
953 | "xpc hb", NULL); | ||
954 | if (ret != 0) { | ||
955 | dev_err(xpc_part, "can't register ACTIVATE IRQ handler, " | ||
956 | "errno=%d\n", -ret); | ||
957 | |||
958 | xpc_restrict_IPI_ops(); | ||
959 | |||
960 | if (xpc_sysctl) { | ||
961 | unregister_sysctl_table(xpc_sysctl); | ||
962 | } | ||
963 | return -EBUSY; | ||
964 | } | ||
965 | |||
966 | /* | ||
967 | * Fill the partition reserved page with the information needed by | ||
968 | * other partitions to discover we are alive and establish initial | ||
969 | * communications. | ||
970 | */ | ||
971 | xpc_rsvd_page = xpc_rsvd_page_init(); | ||
972 | if (xpc_rsvd_page == NULL) { | ||
973 | dev_err(xpc_part, "could not setup our reserved page\n"); | ||
974 | |||
975 | free_irq(SGI_XPC_ACTIVATE, NULL); | ||
976 | xpc_restrict_IPI_ops(); | ||
977 | |||
978 | if (xpc_sysctl) { | ||
979 | unregister_sysctl_table(xpc_sysctl); | ||
980 | } | ||
981 | return -EBUSY; | ||
982 | } | ||
983 | |||
984 | |||
985 | /* | ||
986 | * Set the beating to other partitions into motion. This is | ||
987 | * the last requirement for other partitions' discovery to | ||
988 | * initiate communications with us. | ||
989 | */ | ||
990 | init_timer(&xpc_hb_timer); | ||
991 | xpc_hb_timer.function = xpc_hb_beater; | ||
992 | xpc_hb_beater(0); | ||
993 | |||
994 | |||
995 | /* | ||
996 | * The real work-horse behind xpc. This processes incoming | ||
997 | * interrupts and monitors remote heartbeats. | ||
998 | */ | ||
999 | pid = kernel_thread(xpc_hb_checker, NULL, 0); | ||
1000 | if (pid < 0) { | ||
1001 | dev_err(xpc_part, "failed while forking hb check thread\n"); | ||
1002 | |||
1003 | /* indicate to others that our reserved page is uninitialized */ | ||
1004 | xpc_rsvd_page->vars_pa = 0; | ||
1005 | |||
1006 | del_timer_sync(&xpc_hb_timer); | ||
1007 | free_irq(SGI_XPC_ACTIVATE, NULL); | ||
1008 | xpc_restrict_IPI_ops(); | ||
1009 | |||
1010 | if (xpc_sysctl) { | ||
1011 | unregister_sysctl_table(xpc_sysctl); | ||
1012 | } | ||
1013 | return -EBUSY; | ||
1014 | } | ||
1015 | |||
1016 | |||
1017 | /* | ||
1018 | * Startup a thread that will attempt to discover other partitions to | ||
1019 | * activate based on info provided by SAL. This new thread is short | ||
1020 | * lived and will exit once discovery is complete. | ||
1021 | */ | ||
1022 | pid = kernel_thread(xpc_initiate_discovery, NULL, 0); | ||
1023 | if (pid < 0) { | ||
1024 | dev_err(xpc_part, "failed while forking discovery thread\n"); | ||
1025 | |||
1026 | /* mark this new thread as a non-starter */ | ||
1027 | up(&xpc_discovery_exited); | ||
1028 | |||
1029 | xpc_do_exit(); | ||
1030 | return -EBUSY; | ||
1031 | } | ||
1032 | |||
1033 | |||
1034 | /* set the interface to point at XPC's functions */ | ||
1035 | xpc_set_interface(xpc_initiate_connect, xpc_initiate_disconnect, | ||
1036 | xpc_initiate_allocate, xpc_initiate_send, | ||
1037 | xpc_initiate_send_notify, xpc_initiate_received, | ||
1038 | xpc_initiate_partid_to_nasids); | ||
1039 | |||
1040 | return 0; | ||
1041 | } | ||
1042 | module_init(xpc_init); | ||
1043 | |||
1044 | |||
1045 | void __exit | ||
1046 | xpc_exit(void) | ||
1047 | { | ||
1048 | xpc_do_exit(); | ||
1049 | } | ||
1050 | module_exit(xpc_exit); | ||
1051 | |||
1052 | |||
1053 | MODULE_AUTHOR("Silicon Graphics, Inc."); | ||
1054 | MODULE_DESCRIPTION("Cross Partition Communication (XPC) support"); | ||
1055 | MODULE_LICENSE("GPL"); | ||
1056 | |||
1057 | module_param(xpc_hb_interval, int, 0); | ||
1058 | MODULE_PARM_DESC(xpc_hb_interval, "Number of seconds between " | ||
1059 | "heartbeat increments."); | ||
1060 | |||
1061 | module_param(xpc_hb_check_interval, int, 0); | ||
1062 | MODULE_PARM_DESC(xpc_hb_check_interval, "Number of seconds between " | ||
1063 | "heartbeat checks."); | ||
1064 | |||
diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c new file mode 100644 index 000000000000..2c3c4a8af553 --- /dev/null +++ b/arch/ia64/sn/kernel/xpc_partition.c | |||
@@ -0,0 +1,984 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved. | ||
7 | */ | ||
8 | |||
9 | |||
10 | /* | ||
11 | * Cross Partition Communication (XPC) partition support. | ||
12 | * | ||
13 | * This is the part of XPC that detects the presence/absence of | ||
14 | * other partitions. It provides a heartbeat and monitors the | ||
15 | * heartbeats of other partitions. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/sysctl.h> | ||
22 | #include <linux/cache.h> | ||
23 | #include <linux/mmzone.h> | ||
24 | #include <linux/nodemask.h> | ||
25 | #include <asm/sn/bte.h> | ||
26 | #include <asm/sn/intr.h> | ||
27 | #include <asm/sn/sn_sal.h> | ||
28 | #include <asm/sn/nodepda.h> | ||
29 | #include <asm/sn/addrs.h> | ||
30 | #include "xpc.h" | ||
31 | |||
32 | |||
33 | /* XPC is exiting flag */ | ||
34 | int xpc_exiting; | ||
35 | |||
36 | |||
37 | /* SH_IPI_ACCESS shub register value on startup */ | ||
38 | static u64 xpc_sh1_IPI_access; | ||
39 | static u64 xpc_sh2_IPI_access0; | ||
40 | static u64 xpc_sh2_IPI_access1; | ||
41 | static u64 xpc_sh2_IPI_access2; | ||
42 | static u64 xpc_sh2_IPI_access3; | ||
43 | |||
44 | |||
45 | /* original protection values for each node */ | ||
46 | u64 xpc_prot_vec[MAX_COMPACT_NODES]; | ||
47 | |||
48 | |||
49 | /* this partition's reserved page */ | ||
50 | struct xpc_rsvd_page *xpc_rsvd_page; | ||
51 | |||
52 | /* this partition's XPC variables (within the reserved page) */ | ||
53 | struct xpc_vars *xpc_vars; | ||
54 | struct xpc_vars_part *xpc_vars_part; | ||
55 | |||
56 | |||
57 | /* | ||
58 | * For performance reasons, each entry of xpc_partitions[] is cacheline | ||
59 | * aligned. And xpc_partitions[] is padded with an additional entry at the | ||
60 | * end so that the last legitimate entry doesn't share its cacheline with | ||
61 | * another variable. | ||
62 | */ | ||
63 | struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1]; | ||
64 | |||
65 | |||
66 | /* | ||
67 | * Generic buffer used to store a local copy of the remote partitions | ||
68 | * reserved page or XPC variables. | ||
69 | * | ||
70 | * xpc_discovery runs only once and is a seperate thread that is | ||
71 | * very likely going to be processing in parallel with receiving | ||
72 | * interrupts. | ||
73 | */ | ||
74 | char ____cacheline_aligned | ||
75 | xpc_remote_copy_buffer[XPC_RSVD_PAGE_ALIGNED_SIZE]; | ||
76 | |||
77 | |||
78 | /* systune related variables */ | ||
79 | int xpc_hb_interval = XPC_HB_DEFAULT_INTERVAL; | ||
80 | int xpc_hb_check_interval = XPC_HB_CHECK_DEFAULT_TIMEOUT; | ||
81 | |||
82 | |||
83 | /* | ||
84 | * Given a nasid, get the physical address of the partition's reserved page | ||
85 | * for that nasid. This function returns 0 on any error. | ||
86 | */ | ||
87 | static u64 | ||
88 | xpc_get_rsvd_page_pa(int nasid, u64 buf, u64 buf_size) | ||
89 | { | ||
90 | bte_result_t bte_res; | ||
91 | s64 status; | ||
92 | u64 cookie = 0; | ||
93 | u64 rp_pa = nasid; /* seed with nasid */ | ||
94 | u64 len = 0; | ||
95 | |||
96 | |||
97 | while (1) { | ||
98 | |||
99 | status = sn_partition_reserved_page_pa(buf, &cookie, &rp_pa, | ||
100 | &len); | ||
101 | |||
102 | dev_dbg(xpc_part, "SAL returned with status=%li, cookie=" | ||
103 | "0x%016lx, address=0x%016lx, len=0x%016lx\n", | ||
104 | status, cookie, rp_pa, len); | ||
105 | |||
106 | if (status != SALRET_MORE_PASSES) { | ||
107 | break; | ||
108 | } | ||
109 | |||
110 | if (len > buf_size) { | ||
111 | dev_err(xpc_part, "len (=0x%016lx) > buf_size\n", len); | ||
112 | status = SALRET_ERROR; | ||
113 | break; | ||
114 | } | ||
115 | |||
116 | bte_res = xp_bte_copy(rp_pa, ia64_tpa(buf), buf_size, | ||
117 | (BTE_NOTIFY | BTE_WACQUIRE), NULL); | ||
118 | if (bte_res != BTE_SUCCESS) { | ||
119 | dev_dbg(xpc_part, "xp_bte_copy failed %i\n", bte_res); | ||
120 | status = SALRET_ERROR; | ||
121 | break; | ||
122 | } | ||
123 | } | ||
124 | |||
125 | if (status != SALRET_OK) { | ||
126 | rp_pa = 0; | ||
127 | } | ||
128 | dev_dbg(xpc_part, "reserved page at phys address 0x%016lx\n", rp_pa); | ||
129 | return rp_pa; | ||
130 | } | ||
131 | |||
132 | |||
133 | /* | ||
134 | * Fill the partition reserved page with the information needed by | ||
135 | * other partitions to discover we are alive and establish initial | ||
136 | * communications. | ||
137 | */ | ||
138 | struct xpc_rsvd_page * | ||
139 | xpc_rsvd_page_init(void) | ||
140 | { | ||
141 | struct xpc_rsvd_page *rp; | ||
142 | AMO_t *amos_page; | ||
143 | u64 rp_pa, next_cl, nasid_array = 0; | ||
144 | int i, ret; | ||
145 | |||
146 | |||
147 | /* get the local reserved page's address */ | ||
148 | |||
149 | rp_pa = xpc_get_rsvd_page_pa(cnodeid_to_nasid(0), | ||
150 | (u64) xpc_remote_copy_buffer, | ||
151 | XPC_RSVD_PAGE_ALIGNED_SIZE); | ||
152 | if (rp_pa == 0) { | ||
153 | dev_err(xpc_part, "SAL failed to locate the reserved page\n"); | ||
154 | return NULL; | ||
155 | } | ||
156 | rp = (struct xpc_rsvd_page *) __va(rp_pa); | ||
157 | |||
158 | if (rp->partid != sn_partition_id) { | ||
159 | dev_err(xpc_part, "the reserved page's partid of %d should be " | ||
160 | "%d\n", rp->partid, sn_partition_id); | ||
161 | return NULL; | ||
162 | } | ||
163 | |||
164 | rp->version = XPC_RP_VERSION; | ||
165 | |||
166 | /* | ||
167 | * Place the XPC variables on the cache line following the | ||
168 | * reserved page structure. | ||
169 | */ | ||
170 | next_cl = (u64) rp + XPC_RSVD_PAGE_ALIGNED_SIZE; | ||
171 | xpc_vars = (struct xpc_vars *) next_cl; | ||
172 | |||
173 | /* | ||
174 | * Before clearing xpc_vars, see if a page of AMOs had been previously | ||
175 | * allocated. If not we'll need to allocate one and set permissions | ||
176 | * so that cross-partition AMOs are allowed. | ||
177 | * | ||
178 | * The allocated AMO page needs MCA reporting to remain disabled after | ||
179 | * XPC has unloaded. To make this work, we keep a copy of the pointer | ||
180 | * to this page (i.e., amos_page) in the struct xpc_vars structure, | ||
181 | * which is pointed to by the reserved page, and re-use that saved copy | ||
182 | * on subsequent loads of XPC. This AMO page is never freed, and its | ||
183 | * memory protections are never restricted. | ||
184 | */ | ||
185 | if ((amos_page = xpc_vars->amos_page) == NULL) { | ||
186 | amos_page = (AMO_t *) mspec_kalloc_page(0); | ||
187 | if (amos_page == NULL) { | ||
188 | dev_err(xpc_part, "can't allocate page of AMOs\n"); | ||
189 | return NULL; | ||
190 | } | ||
191 | |||
192 | /* | ||
193 | * Open up AMO-R/W to cpu. This is done for Shub 1.1 systems | ||
194 | * when xpc_allow_IPI_ops() is called via xpc_hb_init(). | ||
195 | */ | ||
196 | if (!enable_shub_wars_1_1()) { | ||
197 | ret = sn_change_memprotect(ia64_tpa((u64) amos_page), | ||
198 | PAGE_SIZE, SN_MEMPROT_ACCESS_CLASS_1, | ||
199 | &nasid_array); | ||
200 | if (ret != 0) { | ||
201 | dev_err(xpc_part, "can't change memory " | ||
202 | "protections\n"); | ||
203 | mspec_kfree_page((unsigned long) amos_page); | ||
204 | return NULL; | ||
205 | } | ||
206 | } | ||
207 | } else if (!IS_AMO_ADDRESS((u64) amos_page)) { | ||
208 | /* | ||
209 | * EFI's XPBOOT can also set amos_page in the reserved page, | ||
210 | * but it happens to leave it as an uncached physical address | ||
211 | * and we need it to be an uncached virtual, so we'll have to | ||
212 | * convert it. | ||
213 | */ | ||
214 | if (!IS_AMO_PHYS_ADDRESS((u64) amos_page)) { | ||
215 | dev_err(xpc_part, "previously used amos_page address " | ||
216 | "is bad = 0x%p\n", (void *) amos_page); | ||
217 | return NULL; | ||
218 | } | ||
219 | amos_page = (AMO_t *) TO_AMO((u64) amos_page); | ||
220 | } | ||
221 | |||
222 | memset(xpc_vars, 0, sizeof(struct xpc_vars)); | ||
223 | |||
224 | /* | ||
225 | * Place the XPC per partition specific variables on the cache line | ||
226 | * following the XPC variables structure. | ||
227 | */ | ||
228 | next_cl += XPC_VARS_ALIGNED_SIZE; | ||
229 | memset((u64 *) next_cl, 0, sizeof(struct xpc_vars_part) * | ||
230 | XP_MAX_PARTITIONS); | ||
231 | xpc_vars_part = (struct xpc_vars_part *) next_cl; | ||
232 | xpc_vars->vars_part_pa = __pa(next_cl); | ||
233 | |||
234 | xpc_vars->version = XPC_V_VERSION; | ||
235 | xpc_vars->act_nasid = cpuid_to_nasid(0); | ||
236 | xpc_vars->act_phys_cpuid = cpu_physical_id(0); | ||
237 | xpc_vars->amos_page = amos_page; /* save for next load of XPC */ | ||
238 | |||
239 | |||
240 | /* | ||
241 | * Initialize the activation related AMO variables. | ||
242 | */ | ||
243 | xpc_vars->act_amos = xpc_IPI_init(XP_MAX_PARTITIONS); | ||
244 | for (i = 1; i < XP_NASID_MASK_WORDS; i++) { | ||
245 | xpc_IPI_init(i + XP_MAX_PARTITIONS); | ||
246 | } | ||
247 | /* export AMO page's physical address to other partitions */ | ||
248 | xpc_vars->amos_page_pa = ia64_tpa((u64) xpc_vars->amos_page); | ||
249 | |||
250 | /* | ||
251 | * This signifies to the remote partition that our reserved | ||
252 | * page is initialized. | ||
253 | */ | ||
254 | (volatile u64) rp->vars_pa = __pa(xpc_vars); | ||
255 | |||
256 | return rp; | ||
257 | } | ||
258 | |||
259 | |||
260 | /* | ||
261 | * Change protections to allow IPI operations (and AMO operations on | ||
262 | * Shub 1.1 systems). | ||
263 | */ | ||
264 | void | ||
265 | xpc_allow_IPI_ops(void) | ||
266 | { | ||
267 | int node; | ||
268 | int nasid; | ||
269 | |||
270 | |||
271 | // >>> Change SH_IPI_ACCESS code to use SAL call once it is available. | ||
272 | |||
273 | if (is_shub2()) { | ||
274 | xpc_sh2_IPI_access0 = | ||
275 | (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH2_IPI_ACCESS0)); | ||
276 | xpc_sh2_IPI_access1 = | ||
277 | (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH2_IPI_ACCESS1)); | ||
278 | xpc_sh2_IPI_access2 = | ||
279 | (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH2_IPI_ACCESS2)); | ||
280 | xpc_sh2_IPI_access3 = | ||
281 | (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH2_IPI_ACCESS3)); | ||
282 | |||
283 | for_each_online_node(node) { | ||
284 | nasid = cnodeid_to_nasid(node); | ||
285 | HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS0), | ||
286 | -1UL); | ||
287 | HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS1), | ||
288 | -1UL); | ||
289 | HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS2), | ||
290 | -1UL); | ||
291 | HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS3), | ||
292 | -1UL); | ||
293 | } | ||
294 | |||
295 | } else { | ||
296 | xpc_sh1_IPI_access = | ||
297 | (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH1_IPI_ACCESS)); | ||
298 | |||
299 | for_each_online_node(node) { | ||
300 | nasid = cnodeid_to_nasid(node); | ||
301 | HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH1_IPI_ACCESS), | ||
302 | -1UL); | ||
303 | |||
304 | /* | ||
305 | * Since the BIST collides with memory operations on | ||
306 | * SHUB 1.1 sn_change_memprotect() cannot be used. | ||
307 | */ | ||
308 | if (enable_shub_wars_1_1()) { | ||
309 | /* open up everything */ | ||
310 | xpc_prot_vec[node] = (u64) HUB_L((u64 *) | ||
311 | GLOBAL_MMR_ADDR(nasid, | ||
312 | SH1_MD_DQLP_MMR_DIR_PRIVEC0)); | ||
313 | HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, | ||
314 | SH1_MD_DQLP_MMR_DIR_PRIVEC0), | ||
315 | -1UL); | ||
316 | HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, | ||
317 | SH1_MD_DQRP_MMR_DIR_PRIVEC0), | ||
318 | -1UL); | ||
319 | } | ||
320 | } | ||
321 | } | ||
322 | } | ||
323 | |||
324 | |||
325 | /* | ||
326 | * Restrict protections to disallow IPI operations (and AMO operations on | ||
327 | * Shub 1.1 systems). | ||
328 | */ | ||
329 | void | ||
330 | xpc_restrict_IPI_ops(void) | ||
331 | { | ||
332 | int node; | ||
333 | int nasid; | ||
334 | |||
335 | |||
336 | // >>> Change SH_IPI_ACCESS code to use SAL call once it is available. | ||
337 | |||
338 | if (is_shub2()) { | ||
339 | |||
340 | for_each_online_node(node) { | ||
341 | nasid = cnodeid_to_nasid(node); | ||
342 | HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS0), | ||
343 | xpc_sh2_IPI_access0); | ||
344 | HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS1), | ||
345 | xpc_sh2_IPI_access1); | ||
346 | HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS2), | ||
347 | xpc_sh2_IPI_access2); | ||
348 | HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS3), | ||
349 | xpc_sh2_IPI_access3); | ||
350 | } | ||
351 | |||
352 | } else { | ||
353 | |||
354 | for_each_online_node(node) { | ||
355 | nasid = cnodeid_to_nasid(node); | ||
356 | HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH1_IPI_ACCESS), | ||
357 | xpc_sh1_IPI_access); | ||
358 | |||
359 | if (enable_shub_wars_1_1()) { | ||
360 | HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, | ||
361 | SH1_MD_DQLP_MMR_DIR_PRIVEC0), | ||
362 | xpc_prot_vec[node]); | ||
363 | HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, | ||
364 | SH1_MD_DQRP_MMR_DIR_PRIVEC0), | ||
365 | xpc_prot_vec[node]); | ||
366 | } | ||
367 | } | ||
368 | } | ||
369 | } | ||
370 | |||
371 | |||
372 | /* | ||
373 | * At periodic intervals, scan through all active partitions and ensure | ||
374 | * their heartbeat is still active. If not, the partition is deactivated. | ||
375 | */ | ||
376 | void | ||
377 | xpc_check_remote_hb(void) | ||
378 | { | ||
379 | struct xpc_vars *remote_vars; | ||
380 | struct xpc_partition *part; | ||
381 | partid_t partid; | ||
382 | bte_result_t bres; | ||
383 | |||
384 | |||
385 | remote_vars = (struct xpc_vars *) xpc_remote_copy_buffer; | ||
386 | |||
387 | for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { | ||
388 | if (partid == sn_partition_id) { | ||
389 | continue; | ||
390 | } | ||
391 | |||
392 | part = &xpc_partitions[partid]; | ||
393 | |||
394 | if (part->act_state == XPC_P_INACTIVE || | ||
395 | part->act_state == XPC_P_DEACTIVATING) { | ||
396 | continue; | ||
397 | } | ||
398 | |||
399 | /* pull the remote_hb cache line */ | ||
400 | bres = xp_bte_copy(part->remote_vars_pa, | ||
401 | ia64_tpa((u64) remote_vars), | ||
402 | XPC_VARS_ALIGNED_SIZE, | ||
403 | (BTE_NOTIFY | BTE_WACQUIRE), NULL); | ||
404 | if (bres != BTE_SUCCESS) { | ||
405 | XPC_DEACTIVATE_PARTITION(part, | ||
406 | xpc_map_bte_errors(bres)); | ||
407 | continue; | ||
408 | } | ||
409 | |||
410 | dev_dbg(xpc_part, "partid = %d, heartbeat = %ld, last_heartbeat" | ||
411 | " = %ld, kdb_status = %ld, HB_mask = 0x%lx\n", partid, | ||
412 | remote_vars->heartbeat, part->last_heartbeat, | ||
413 | remote_vars->kdb_status, | ||
414 | remote_vars->heartbeating_to_mask); | ||
415 | |||
416 | if (((remote_vars->heartbeat == part->last_heartbeat) && | ||
417 | (remote_vars->kdb_status == 0)) || | ||
418 | !XPC_HB_ALLOWED(sn_partition_id, remote_vars)) { | ||
419 | |||
420 | XPC_DEACTIVATE_PARTITION(part, xpcNoHeartbeat); | ||
421 | continue; | ||
422 | } | ||
423 | |||
424 | part->last_heartbeat = remote_vars->heartbeat; | ||
425 | } | ||
426 | } | ||
427 | |||
428 | |||
429 | /* | ||
430 | * Get a copy of the remote partition's rsvd page. | ||
431 | * | ||
432 | * remote_rp points to a buffer that is cacheline aligned for BTE copies and | ||
433 | * assumed to be of size XPC_RSVD_PAGE_ALIGNED_SIZE. | ||
434 | */ | ||
435 | static enum xpc_retval | ||
436 | xpc_get_remote_rp(int nasid, u64 *discovered_nasids, | ||
437 | struct xpc_rsvd_page *remote_rp, u64 *remote_rsvd_page_pa) | ||
438 | { | ||
439 | int bres, i; | ||
440 | |||
441 | |||
442 | /* get the reserved page's physical address */ | ||
443 | |||
444 | *remote_rsvd_page_pa = xpc_get_rsvd_page_pa(nasid, (u64) remote_rp, | ||
445 | XPC_RSVD_PAGE_ALIGNED_SIZE); | ||
446 | if (*remote_rsvd_page_pa == 0) { | ||
447 | return xpcNoRsvdPageAddr; | ||
448 | } | ||
449 | |||
450 | |||
451 | /* pull over the reserved page structure */ | ||
452 | |||
453 | bres = xp_bte_copy(*remote_rsvd_page_pa, ia64_tpa((u64) remote_rp), | ||
454 | XPC_RSVD_PAGE_ALIGNED_SIZE, | ||
455 | (BTE_NOTIFY | BTE_WACQUIRE), NULL); | ||
456 | if (bres != BTE_SUCCESS) { | ||
457 | return xpc_map_bte_errors(bres); | ||
458 | } | ||
459 | |||
460 | |||
461 | if (discovered_nasids != NULL) { | ||
462 | for (i = 0; i < XP_NASID_MASK_WORDS; i++) { | ||
463 | discovered_nasids[i] |= remote_rp->part_nasids[i]; | ||
464 | } | ||
465 | } | ||
466 | |||
467 | |||
468 | /* check that the partid is for another partition */ | ||
469 | |||
470 | if (remote_rp->partid < 1 || | ||
471 | remote_rp->partid > (XP_MAX_PARTITIONS - 1)) { | ||
472 | return xpcInvalidPartid; | ||
473 | } | ||
474 | |||
475 | if (remote_rp->partid == sn_partition_id) { | ||
476 | return xpcLocalPartid; | ||
477 | } | ||
478 | |||
479 | |||
480 | if (XPC_VERSION_MAJOR(remote_rp->version) != | ||
481 | XPC_VERSION_MAJOR(XPC_RP_VERSION)) { | ||
482 | return xpcBadVersion; | ||
483 | } | ||
484 | |||
485 | return xpcSuccess; | ||
486 | } | ||
487 | |||
488 | |||
489 | /* | ||
490 | * Get a copy of the remote partition's XPC variables. | ||
491 | * | ||
492 | * remote_vars points to a buffer that is cacheline aligned for BTE copies and | ||
493 | * assumed to be of size XPC_VARS_ALIGNED_SIZE. | ||
494 | */ | ||
495 | static enum xpc_retval | ||
496 | xpc_get_remote_vars(u64 remote_vars_pa, struct xpc_vars *remote_vars) | ||
497 | { | ||
498 | int bres; | ||
499 | |||
500 | |||
501 | if (remote_vars_pa == 0) { | ||
502 | return xpcVarsNotSet; | ||
503 | } | ||
504 | |||
505 | |||
506 | /* pull over the cross partition variables */ | ||
507 | |||
508 | bres = xp_bte_copy(remote_vars_pa, ia64_tpa((u64) remote_vars), | ||
509 | XPC_VARS_ALIGNED_SIZE, | ||
510 | (BTE_NOTIFY | BTE_WACQUIRE), NULL); | ||
511 | if (bres != BTE_SUCCESS) { | ||
512 | return xpc_map_bte_errors(bres); | ||
513 | } | ||
514 | |||
515 | if (XPC_VERSION_MAJOR(remote_vars->version) != | ||
516 | XPC_VERSION_MAJOR(XPC_V_VERSION)) { | ||
517 | return xpcBadVersion; | ||
518 | } | ||
519 | |||
520 | return xpcSuccess; | ||
521 | } | ||
522 | |||
523 | |||
524 | /* | ||
525 | * Prior code has determine the nasid which generated an IPI. Inspect | ||
526 | * that nasid to determine if its partition needs to be activated or | ||
527 | * deactivated. | ||
528 | * | ||
529 | * A partition is consider "awaiting activation" if our partition | ||
530 | * flags indicate it is not active and it has a heartbeat. A | ||
531 | * partition is considered "awaiting deactivation" if our partition | ||
532 | * flags indicate it is active but it has no heartbeat or it is not | ||
533 | * sending its heartbeat to us. | ||
534 | * | ||
535 | * To determine the heartbeat, the remote nasid must have a properly | ||
536 | * initialized reserved page. | ||
537 | */ | ||
538 | static void | ||
539 | xpc_identify_act_IRQ_req(int nasid) | ||
540 | { | ||
541 | struct xpc_rsvd_page *remote_rp; | ||
542 | struct xpc_vars *remote_vars; | ||
543 | u64 remote_rsvd_page_pa; | ||
544 | u64 remote_vars_pa; | ||
545 | partid_t partid; | ||
546 | struct xpc_partition *part; | ||
547 | enum xpc_retval ret; | ||
548 | |||
549 | |||
550 | /* pull over the reserved page structure */ | ||
551 | |||
552 | remote_rp = (struct xpc_rsvd_page *) xpc_remote_copy_buffer; | ||
553 | |||
554 | ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rsvd_page_pa); | ||
555 | if (ret != xpcSuccess) { | ||
556 | dev_warn(xpc_part, "unable to get reserved page from nasid %d, " | ||
557 | "which sent interrupt, reason=%d\n", nasid, ret); | ||
558 | return; | ||
559 | } | ||
560 | |||
561 | remote_vars_pa = remote_rp->vars_pa; | ||
562 | partid = remote_rp->partid; | ||
563 | part = &xpc_partitions[partid]; | ||
564 | |||
565 | |||
566 | /* pull over the cross partition variables */ | ||
567 | |||
568 | remote_vars = (struct xpc_vars *) xpc_remote_copy_buffer; | ||
569 | |||
570 | ret = xpc_get_remote_vars(remote_vars_pa, remote_vars); | ||
571 | if (ret != xpcSuccess) { | ||
572 | |||
573 | dev_warn(xpc_part, "unable to get XPC variables from nasid %d, " | ||
574 | "which sent interrupt, reason=%d\n", nasid, ret); | ||
575 | |||
576 | XPC_DEACTIVATE_PARTITION(part, ret); | ||
577 | return; | ||
578 | } | ||
579 | |||
580 | |||
581 | part->act_IRQ_rcvd++; | ||
582 | |||
583 | dev_dbg(xpc_part, "partid for nasid %d is %d; IRQs = %d; HB = " | ||
584 | "%ld:0x%lx\n", (int) nasid, (int) partid, part->act_IRQ_rcvd, | ||
585 | remote_vars->heartbeat, remote_vars->heartbeating_to_mask); | ||
586 | |||
587 | |||
588 | if (part->act_state == XPC_P_INACTIVE) { | ||
589 | |||
590 | part->remote_rp_pa = remote_rsvd_page_pa; | ||
591 | dev_dbg(xpc_part, " remote_rp_pa = 0x%016lx\n", | ||
592 | part->remote_rp_pa); | ||
593 | |||
594 | part->remote_vars_pa = remote_vars_pa; | ||
595 | dev_dbg(xpc_part, " remote_vars_pa = 0x%016lx\n", | ||
596 | part->remote_vars_pa); | ||
597 | |||
598 | part->last_heartbeat = remote_vars->heartbeat; | ||
599 | dev_dbg(xpc_part, " last_heartbeat = 0x%016lx\n", | ||
600 | part->last_heartbeat); | ||
601 | |||
602 | part->remote_vars_part_pa = remote_vars->vars_part_pa; | ||
603 | dev_dbg(xpc_part, " remote_vars_part_pa = 0x%016lx\n", | ||
604 | part->remote_vars_part_pa); | ||
605 | |||
606 | part->remote_act_nasid = remote_vars->act_nasid; | ||
607 | dev_dbg(xpc_part, " remote_act_nasid = 0x%x\n", | ||
608 | part->remote_act_nasid); | ||
609 | |||
610 | part->remote_act_phys_cpuid = remote_vars->act_phys_cpuid; | ||
611 | dev_dbg(xpc_part, " remote_act_phys_cpuid = 0x%x\n", | ||
612 | part->remote_act_phys_cpuid); | ||
613 | |||
614 | part->remote_amos_page_pa = remote_vars->amos_page_pa; | ||
615 | dev_dbg(xpc_part, " remote_amos_page_pa = 0x%lx\n", | ||
616 | part->remote_amos_page_pa); | ||
617 | |||
618 | xpc_activate_partition(part); | ||
619 | |||
620 | } else if (part->remote_amos_page_pa != remote_vars->amos_page_pa || | ||
621 | !XPC_HB_ALLOWED(sn_partition_id, remote_vars)) { | ||
622 | |||
623 | part->reactivate_nasid = nasid; | ||
624 | XPC_DEACTIVATE_PARTITION(part, xpcReactivating); | ||
625 | } | ||
626 | } | ||
627 | |||
628 | |||
629 | /* | ||
630 | * Loop through the activation AMO variables and process any bits | ||
631 | * which are set. Each bit indicates a nasid sending a partition | ||
632 | * activation or deactivation request. | ||
633 | * | ||
634 | * Return #of IRQs detected. | ||
635 | */ | ||
636 | int | ||
637 | xpc_identify_act_IRQ_sender(void) | ||
638 | { | ||
639 | int word, bit; | ||
640 | u64 nasid_mask; | ||
641 | u64 nasid; /* remote nasid */ | ||
642 | int n_IRQs_detected = 0; | ||
643 | AMO_t *act_amos; | ||
644 | struct xpc_rsvd_page *rp = (struct xpc_rsvd_page *) xpc_rsvd_page; | ||
645 | |||
646 | |||
647 | act_amos = xpc_vars->act_amos; | ||
648 | |||
649 | |||
650 | /* scan through act AMO variable looking for non-zero entries */ | ||
651 | for (word = 0; word < XP_NASID_MASK_WORDS; word++) { | ||
652 | |||
653 | nasid_mask = xpc_IPI_receive(&act_amos[word]); | ||
654 | if (nasid_mask == 0) { | ||
655 | /* no IRQs from nasids in this variable */ | ||
656 | continue; | ||
657 | } | ||
658 | |||
659 | dev_dbg(xpc_part, "AMO[%d] gave back 0x%lx\n", word, | ||
660 | nasid_mask); | ||
661 | |||
662 | |||
663 | /* | ||
664 | * If this nasid has been added to the machine since | ||
665 | * our partition was reset, this will retain the | ||
666 | * remote nasid in our reserved pages machine mask. | ||
667 | * This is used in the event of module reload. | ||
668 | */ | ||
669 | rp->mach_nasids[word] |= nasid_mask; | ||
670 | |||
671 | |||
672 | /* locate the nasid(s) which sent interrupts */ | ||
673 | |||
674 | for (bit = 0; bit < (8 * sizeof(u64)); bit++) { | ||
675 | if (nasid_mask & (1UL << bit)) { | ||
676 | n_IRQs_detected++; | ||
677 | nasid = XPC_NASID_FROM_W_B(word, bit); | ||
678 | dev_dbg(xpc_part, "interrupt from nasid %ld\n", | ||
679 | nasid); | ||
680 | xpc_identify_act_IRQ_req(nasid); | ||
681 | } | ||
682 | } | ||
683 | } | ||
684 | return n_IRQs_detected; | ||
685 | } | ||
686 | |||
687 | |||
688 | /* | ||
689 | * Mark specified partition as active. | ||
690 | */ | ||
691 | enum xpc_retval | ||
692 | xpc_mark_partition_active(struct xpc_partition *part) | ||
693 | { | ||
694 | unsigned long irq_flags; | ||
695 | enum xpc_retval ret; | ||
696 | |||
697 | |||
698 | dev_dbg(xpc_part, "setting partition %d to ACTIVE\n", XPC_PARTID(part)); | ||
699 | |||
700 | spin_lock_irqsave(&part->act_lock, irq_flags); | ||
701 | if (part->act_state == XPC_P_ACTIVATING) { | ||
702 | part->act_state = XPC_P_ACTIVE; | ||
703 | ret = xpcSuccess; | ||
704 | } else { | ||
705 | DBUG_ON(part->reason == xpcSuccess); | ||
706 | ret = part->reason; | ||
707 | } | ||
708 | spin_unlock_irqrestore(&part->act_lock, irq_flags); | ||
709 | |||
710 | return ret; | ||
711 | } | ||
712 | |||
713 | |||
714 | /* | ||
715 | * Notify XPC that the partition is down. | ||
716 | */ | ||
717 | void | ||
718 | xpc_deactivate_partition(const int line, struct xpc_partition *part, | ||
719 | enum xpc_retval reason) | ||
720 | { | ||
721 | unsigned long irq_flags; | ||
722 | partid_t partid = XPC_PARTID(part); | ||
723 | |||
724 | |||
725 | spin_lock_irqsave(&part->act_lock, irq_flags); | ||
726 | |||
727 | if (part->act_state == XPC_P_INACTIVE) { | ||
728 | XPC_SET_REASON(part, reason, line); | ||
729 | spin_unlock_irqrestore(&part->act_lock, irq_flags); | ||
730 | if (reason == xpcReactivating) { | ||
731 | /* we interrupt ourselves to reactivate partition */ | ||
732 | xpc_IPI_send_reactivate(part); | ||
733 | } | ||
734 | return; | ||
735 | } | ||
736 | if (part->act_state == XPC_P_DEACTIVATING) { | ||
737 | if ((part->reason == xpcUnloading && reason != xpcUnloading) || | ||
738 | reason == xpcReactivating) { | ||
739 | XPC_SET_REASON(part, reason, line); | ||
740 | } | ||
741 | spin_unlock_irqrestore(&part->act_lock, irq_flags); | ||
742 | return; | ||
743 | } | ||
744 | |||
745 | part->act_state = XPC_P_DEACTIVATING; | ||
746 | XPC_SET_REASON(part, reason, line); | ||
747 | |||
748 | spin_unlock_irqrestore(&part->act_lock, irq_flags); | ||
749 | |||
750 | XPC_DISALLOW_HB(partid, xpc_vars); | ||
751 | |||
752 | dev_dbg(xpc_part, "bringing partition %d down, reason = %d\n", partid, | ||
753 | reason); | ||
754 | |||
755 | xpc_partition_down(part, reason); | ||
756 | } | ||
757 | |||
758 | |||
759 | /* | ||
760 | * Mark specified partition as active. | ||
761 | */ | ||
762 | void | ||
763 | xpc_mark_partition_inactive(struct xpc_partition *part) | ||
764 | { | ||
765 | unsigned long irq_flags; | ||
766 | |||
767 | |||
768 | dev_dbg(xpc_part, "setting partition %d to INACTIVE\n", | ||
769 | XPC_PARTID(part)); | ||
770 | |||
771 | spin_lock_irqsave(&part->act_lock, irq_flags); | ||
772 | part->act_state = XPC_P_INACTIVE; | ||
773 | spin_unlock_irqrestore(&part->act_lock, irq_flags); | ||
774 | part->remote_rp_pa = 0; | ||
775 | } | ||
776 | |||
777 | |||
778 | /* | ||
779 | * SAL has provided a partition and machine mask. The partition mask | ||
780 | * contains a bit for each even nasid in our partition. The machine | ||
781 | * mask contains a bit for each even nasid in the entire machine. | ||
782 | * | ||
783 | * Using those two bit arrays, we can determine which nasids are | ||
784 | * known in the machine. Each should also have a reserved page | ||
785 | * initialized if they are available for partitioning. | ||
786 | */ | ||
787 | void | ||
788 | xpc_discovery(void) | ||
789 | { | ||
790 | void *remote_rp_base; | ||
791 | struct xpc_rsvd_page *remote_rp; | ||
792 | struct xpc_vars *remote_vars; | ||
793 | u64 remote_rsvd_page_pa; | ||
794 | u64 remote_vars_pa; | ||
795 | int region; | ||
796 | int max_regions; | ||
797 | int nasid; | ||
798 | struct xpc_rsvd_page *rp; | ||
799 | partid_t partid; | ||
800 | struct xpc_partition *part; | ||
801 | u64 *discovered_nasids; | ||
802 | enum xpc_retval ret; | ||
803 | |||
804 | |||
805 | remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RSVD_PAGE_ALIGNED_SIZE, | ||
806 | GFP_KERNEL, &remote_rp_base); | ||
807 | if (remote_rp == NULL) { | ||
808 | return; | ||
809 | } | ||
810 | remote_vars = (struct xpc_vars *) remote_rp; | ||
811 | |||
812 | |||
813 | discovered_nasids = kmalloc(sizeof(u64) * XP_NASID_MASK_WORDS, | ||
814 | GFP_KERNEL); | ||
815 | if (discovered_nasids == NULL) { | ||
816 | kfree(remote_rp_base); | ||
817 | return; | ||
818 | } | ||
819 | memset(discovered_nasids, 0, sizeof(u64) * XP_NASID_MASK_WORDS); | ||
820 | |||
821 | rp = (struct xpc_rsvd_page *) xpc_rsvd_page; | ||
822 | |||
823 | /* | ||
824 | * The term 'region' in this context refers to the minimum number of | ||
825 | * nodes that can comprise an access protection grouping. The access | ||
826 | * protection is in regards to memory, IOI and IPI. | ||
827 | */ | ||
828 | //>>> move the next two #defines into either include/asm-ia64/sn/arch.h or | ||
829 | //>>> include/asm-ia64/sn/addrs.h | ||
830 | #define SH1_MAX_REGIONS 64 | ||
831 | #define SH2_MAX_REGIONS 256 | ||
832 | max_regions = is_shub2() ? SH2_MAX_REGIONS : SH1_MAX_REGIONS; | ||
833 | |||
834 | for (region = 0; region < max_regions; region++) { | ||
835 | |||
836 | if ((volatile int) xpc_exiting) { | ||
837 | break; | ||
838 | } | ||
839 | |||
840 | dev_dbg(xpc_part, "searching region %d\n", region); | ||
841 | |||
842 | for (nasid = (region * sn_region_size * 2); | ||
843 | nasid < ((region + 1) * sn_region_size * 2); | ||
844 | nasid += 2) { | ||
845 | |||
846 | if ((volatile int) xpc_exiting) { | ||
847 | break; | ||
848 | } | ||
849 | |||
850 | dev_dbg(xpc_part, "checking nasid %d\n", nasid); | ||
851 | |||
852 | |||
853 | if (XPC_NASID_IN_ARRAY(nasid, rp->part_nasids)) { | ||
854 | dev_dbg(xpc_part, "PROM indicates Nasid %d is " | ||
855 | "part of the local partition; skipping " | ||
856 | "region\n", nasid); | ||
857 | break; | ||
858 | } | ||
859 | |||
860 | if (!(XPC_NASID_IN_ARRAY(nasid, rp->mach_nasids))) { | ||
861 | dev_dbg(xpc_part, "PROM indicates Nasid %d was " | ||
862 | "not on Numa-Link network at reset\n", | ||
863 | nasid); | ||
864 | continue; | ||
865 | } | ||
866 | |||
867 | if (XPC_NASID_IN_ARRAY(nasid, discovered_nasids)) { | ||
868 | dev_dbg(xpc_part, "Nasid %d is part of a " | ||
869 | "partition which was previously " | ||
870 | "discovered\n", nasid); | ||
871 | continue; | ||
872 | } | ||
873 | |||
874 | |||
875 | /* pull over the reserved page structure */ | ||
876 | |||
877 | ret = xpc_get_remote_rp(nasid, discovered_nasids, | ||
878 | remote_rp, &remote_rsvd_page_pa); | ||
879 | if (ret != xpcSuccess) { | ||
880 | dev_dbg(xpc_part, "unable to get reserved page " | ||
881 | "from nasid %d, reason=%d\n", nasid, | ||
882 | ret); | ||
883 | |||
884 | if (ret == xpcLocalPartid) { | ||
885 | break; | ||
886 | } | ||
887 | continue; | ||
888 | } | ||
889 | |||
890 | remote_vars_pa = remote_rp->vars_pa; | ||
891 | |||
892 | partid = remote_rp->partid; | ||
893 | part = &xpc_partitions[partid]; | ||
894 | |||
895 | |||
896 | /* pull over the cross partition variables */ | ||
897 | |||
898 | ret = xpc_get_remote_vars(remote_vars_pa, remote_vars); | ||
899 | if (ret != xpcSuccess) { | ||
900 | dev_dbg(xpc_part, "unable to get XPC variables " | ||
901 | "from nasid %d, reason=%d\n", nasid, | ||
902 | ret); | ||
903 | |||
904 | XPC_DEACTIVATE_PARTITION(part, ret); | ||
905 | continue; | ||
906 | } | ||
907 | |||
908 | if (part->act_state != XPC_P_INACTIVE) { | ||
909 | dev_dbg(xpc_part, "partition %d on nasid %d is " | ||
910 | "already activating\n", partid, nasid); | ||
911 | break; | ||
912 | } | ||
913 | |||
914 | /* | ||
915 | * Register the remote partition's AMOs with SAL so it | ||
916 | * can handle and cleanup errors within that address | ||
917 | * range should the remote partition go down. We don't | ||
918 | * unregister this range because it is difficult to | ||
919 | * tell when outstanding writes to the remote partition | ||
920 | * are finished and thus when it is thus safe to | ||
921 | * unregister. This should not result in wasted space | ||
922 | * in the SAL xp_addr_region table because we should | ||
923 | * get the same page for remote_act_amos_pa after | ||
924 | * module reloads and system reboots. | ||
925 | */ | ||
926 | if (sn_register_xp_addr_region( | ||
927 | remote_vars->amos_page_pa, | ||
928 | PAGE_SIZE, 1) < 0) { | ||
929 | dev_dbg(xpc_part, "partition %d failed to " | ||
930 | "register xp_addr region 0x%016lx\n", | ||
931 | partid, remote_vars->amos_page_pa); | ||
932 | |||
933 | XPC_SET_REASON(part, xpcPhysAddrRegFailed, | ||
934 | __LINE__); | ||
935 | break; | ||
936 | } | ||
937 | |||
938 | /* | ||
939 | * The remote nasid is valid and available. | ||
940 | * Send an interrupt to that nasid to notify | ||
941 | * it that we are ready to begin activation. | ||
942 | */ | ||
943 | dev_dbg(xpc_part, "sending an interrupt to AMO 0x%lx, " | ||
944 | "nasid %d, phys_cpuid 0x%x\n", | ||
945 | remote_vars->amos_page_pa, | ||
946 | remote_vars->act_nasid, | ||
947 | remote_vars->act_phys_cpuid); | ||
948 | |||
949 | xpc_IPI_send_activate(remote_vars); | ||
950 | } | ||
951 | } | ||
952 | |||
953 | kfree(discovered_nasids); | ||
954 | kfree(remote_rp_base); | ||
955 | } | ||
956 | |||
957 | |||
958 | /* | ||
959 | * Given a partid, get the nasids owned by that partition from the | ||
960 | * remote partition's reserved page. | ||
961 | */ | ||
962 | enum xpc_retval | ||
963 | xpc_initiate_partid_to_nasids(partid_t partid, void *nasid_mask) | ||
964 | { | ||
965 | struct xpc_partition *part; | ||
966 | u64 part_nasid_pa; | ||
967 | int bte_res; | ||
968 | |||
969 | |||
970 | part = &xpc_partitions[partid]; | ||
971 | if (part->remote_rp_pa == 0) { | ||
972 | return xpcPartitionDown; | ||
973 | } | ||
974 | |||
975 | part_nasid_pa = part->remote_rp_pa + | ||
976 | (u64) &((struct xpc_rsvd_page *) 0)->part_nasids; | ||
977 | |||
978 | bte_res = xp_bte_copy(part_nasid_pa, ia64_tpa((u64) nasid_mask), | ||
979 | L1_CACHE_ALIGN(XP_NASID_MASK_BYTES), | ||
980 | (BTE_NOTIFY | BTE_WACQUIRE), NULL); | ||
981 | |||
982 | return xpc_map_bte_errors(bte_res); | ||
983 | } | ||
984 | |||
diff --git a/arch/ia64/sn/kernel/xpnet.c b/arch/ia64/sn/kernel/xpnet.c new file mode 100644 index 000000000000..78c13d676fa6 --- /dev/null +++ b/arch/ia64/sn/kernel/xpnet.c | |||
@@ -0,0 +1,715 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 1999,2001-2005 Silicon Graphics, Inc. All rights reserved. | ||
7 | */ | ||
8 | |||
9 | |||
10 | /* | ||
11 | * Cross Partition Network Interface (XPNET) support | ||
12 | * | ||
13 | * XPNET provides a virtual network layered on top of the Cross | ||
14 | * Partition communication layer. | ||
15 | * | ||
16 | * XPNET provides direct point-to-point and broadcast-like support | ||
17 | * for an ethernet-like device. The ethernet broadcast medium is | ||
18 | * replaced with a point-to-point message structure which passes | ||
19 | * pointers to a DMA-capable block that a remote partition should | ||
20 | * retrieve and pass to the upper level networking layer. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | |||
25 | #include <linux/config.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/pci.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/ioport.h> | ||
31 | #include <linux/netdevice.h> | ||
32 | #include <linux/etherdevice.h> | ||
33 | #include <linux/delay.h> | ||
34 | #include <linux/ethtool.h> | ||
35 | #include <linux/mii.h> | ||
36 | #include <linux/smp.h> | ||
37 | #include <linux/string.h> | ||
38 | #include <asm/sn/bte.h> | ||
39 | #include <asm/sn/io.h> | ||
40 | #include <asm/sn/sn_sal.h> | ||
41 | #include <asm/types.h> | ||
42 | #include <asm/atomic.h> | ||
43 | #include <asm/sn/xp.h> | ||
44 | |||
45 | |||
46 | /* | ||
47 | * The message payload transferred by XPC. | ||
48 | * | ||
49 | * buf_pa is the physical address where the DMA should pull from. | ||
50 | * | ||
51 | * NOTE: for performance reasons, buf_pa should _ALWAYS_ begin on a | ||
52 | * cacheline boundary. To accomplish this, we record the number of | ||
53 | * bytes from the beginning of the first cacheline to the first useful | ||
54 | * byte of the skb (leadin_ignore) and the number of bytes from the | ||
55 | * last useful byte of the skb to the end of the last cacheline | ||
56 | * (tailout_ignore). | ||
57 | * | ||
58 | * size is the number of bytes to transfer which includes the skb->len | ||
59 | * (useful bytes of the senders skb) plus the leadin and tailout | ||
60 | */ | ||
61 | struct xpnet_message { | ||
62 | u16 version; /* Version for this message */ | ||
63 | u16 embedded_bytes; /* #of bytes embedded in XPC message */ | ||
64 | u32 magic; /* Special number indicating this is xpnet */ | ||
65 | u64 buf_pa; /* phys address of buffer to retrieve */ | ||
66 | u32 size; /* #of bytes in buffer */ | ||
67 | u8 leadin_ignore; /* #of bytes to ignore at the beginning */ | ||
68 | u8 tailout_ignore; /* #of bytes to ignore at the end */ | ||
69 | unsigned char data; /* body of small packets */ | ||
70 | }; | ||
71 | |||
72 | /* | ||
73 | * Determine the size of our message, the cacheline aligned size, | ||
74 | * and then the number of message will request from XPC. | ||
75 | * | ||
76 | * XPC expects each message to exist in an individual cacheline. | ||
77 | */ | ||
78 | #define XPNET_MSG_SIZE (L1_CACHE_BYTES - XPC_MSG_PAYLOAD_OFFSET) | ||
79 | #define XPNET_MSG_DATA_MAX \ | ||
80 | (XPNET_MSG_SIZE - (u64)(&((struct xpnet_message *)0)->data)) | ||
81 | #define XPNET_MSG_ALIGNED_SIZE (L1_CACHE_ALIGN(XPNET_MSG_SIZE)) | ||
82 | #define XPNET_MSG_NENTRIES (PAGE_SIZE / XPNET_MSG_ALIGNED_SIZE) | ||
83 | |||
84 | |||
85 | #define XPNET_MAX_KTHREADS (XPNET_MSG_NENTRIES + 1) | ||
86 | #define XPNET_MAX_IDLE_KTHREADS (XPNET_MSG_NENTRIES + 1) | ||
87 | |||
88 | /* | ||
89 | * Version number of XPNET implementation. XPNET can always talk to versions | ||
90 | * with same major #, and never talk to versions with a different version. | ||
91 | */ | ||
92 | #define _XPNET_VERSION(_major, _minor) (((_major) << 4) | (_minor)) | ||
93 | #define XPNET_VERSION_MAJOR(_v) ((_v) >> 4) | ||
94 | #define XPNET_VERSION_MINOR(_v) ((_v) & 0xf) | ||
95 | |||
96 | #define XPNET_VERSION _XPNET_VERSION(1,0) /* version 1.0 */ | ||
97 | #define XPNET_VERSION_EMBED _XPNET_VERSION(1,1) /* version 1.1 */ | ||
98 | #define XPNET_MAGIC 0x88786984 /* "XNET" */ | ||
99 | |||
100 | #define XPNET_VALID_MSG(_m) \ | ||
101 | ((XPNET_VERSION_MAJOR(_m->version) == XPNET_VERSION_MAJOR(XPNET_VERSION)) \ | ||
102 | && (msg->magic == XPNET_MAGIC)) | ||
103 | |||
104 | #define XPNET_DEVICE_NAME "xp0" | ||
105 | |||
106 | |||
107 | /* | ||
108 | * When messages are queued with xpc_send_notify, a kmalloc'd buffer | ||
109 | * of the following type is passed as a notification cookie. When the | ||
110 | * notification function is called, we use the cookie to decide | ||
111 | * whether all outstanding message sends have completed. The skb can | ||
112 | * then be released. | ||
113 | */ | ||
114 | struct xpnet_pending_msg { | ||
115 | struct list_head free_list; | ||
116 | struct sk_buff *skb; | ||
117 | atomic_t use_count; | ||
118 | }; | ||
119 | |||
120 | /* driver specific structure pointed to by the device structure */ | ||
121 | struct xpnet_dev_private { | ||
122 | struct net_device_stats stats; | ||
123 | }; | ||
124 | |||
125 | struct net_device *xpnet_device; | ||
126 | |||
127 | /* | ||
128 | * When we are notified of other partitions activating, we add them to | ||
129 | * our bitmask of partitions to which we broadcast. | ||
130 | */ | ||
131 | static u64 xpnet_broadcast_partitions; | ||
132 | /* protect above */ | ||
133 | static spinlock_t xpnet_broadcast_lock = SPIN_LOCK_UNLOCKED; | ||
134 | |||
135 | /* | ||
136 | * Since the Block Transfer Engine (BTE) is being used for the transfer | ||
137 | * and it relies upon cache-line size transfers, we need to reserve at | ||
138 | * least one cache-line for head and tail alignment. The BTE is | ||
139 | * limited to 8MB transfers. | ||
140 | * | ||
141 | * Testing has shown that changing MTU to greater than 64KB has no effect | ||
142 | * on TCP as the two sides negotiate a Max Segment Size that is limited | ||
143 | * to 64K. Other protocols May use packets greater than this, but for | ||
144 | * now, the default is 64KB. | ||
145 | */ | ||
146 | #define XPNET_MAX_MTU (0x800000UL - L1_CACHE_BYTES) | ||
147 | /* 32KB has been determined to be the ideal */ | ||
148 | #define XPNET_DEF_MTU (0x8000UL) | ||
149 | |||
150 | |||
151 | /* | ||
152 | * The partition id is encapsulated in the MAC address. The following | ||
153 | * define locates the octet the partid is in. | ||
154 | */ | ||
155 | #define XPNET_PARTID_OCTET 1 | ||
156 | #define XPNET_LICENSE_OCTET 2 | ||
157 | |||
158 | |||
159 | /* | ||
160 | * Define the XPNET debug device structure that is to be used with dev_dbg(), | ||
161 | * dev_err(), dev_warn(), and dev_info(). | ||
162 | */ | ||
163 | struct device_driver xpnet_dbg_name = { | ||
164 | .name = "xpnet" | ||
165 | }; | ||
166 | |||
167 | struct device xpnet_dbg_subname = { | ||
168 | .bus_id = {0}, /* set to "" */ | ||
169 | .driver = &xpnet_dbg_name | ||
170 | }; | ||
171 | |||
172 | struct device *xpnet = &xpnet_dbg_subname; | ||
173 | |||
174 | /* | ||
175 | * Packet was recevied by XPC and forwarded to us. | ||
176 | */ | ||
177 | static void | ||
178 | xpnet_receive(partid_t partid, int channel, struct xpnet_message *msg) | ||
179 | { | ||
180 | struct sk_buff *skb; | ||
181 | bte_result_t bret; | ||
182 | struct xpnet_dev_private *priv = | ||
183 | (struct xpnet_dev_private *) xpnet_device->priv; | ||
184 | |||
185 | |||
186 | if (!XPNET_VALID_MSG(msg)) { | ||
187 | /* | ||
188 | * Packet with a different XPC version. Ignore. | ||
189 | */ | ||
190 | xpc_received(partid, channel, (void *) msg); | ||
191 | |||
192 | priv->stats.rx_errors++; | ||
193 | |||
194 | return; | ||
195 | } | ||
196 | dev_dbg(xpnet, "received 0x%lx, %d, %d, %d\n", msg->buf_pa, msg->size, | ||
197 | msg->leadin_ignore, msg->tailout_ignore); | ||
198 | |||
199 | |||
200 | /* reserve an extra cache line */ | ||
201 | skb = dev_alloc_skb(msg->size + L1_CACHE_BYTES); | ||
202 | if (!skb) { | ||
203 | dev_err(xpnet, "failed on dev_alloc_skb(%d)\n", | ||
204 | msg->size + L1_CACHE_BYTES); | ||
205 | |||
206 | xpc_received(partid, channel, (void *) msg); | ||
207 | |||
208 | priv->stats.rx_errors++; | ||
209 | |||
210 | return; | ||
211 | } | ||
212 | |||
213 | /* | ||
214 | * The allocated skb has some reserved space. | ||
215 | * In order to use bte_copy, we need to get the | ||
216 | * skb->data pointer moved forward. | ||
217 | */ | ||
218 | skb_reserve(skb, (L1_CACHE_BYTES - ((u64)skb->data & | ||
219 | (L1_CACHE_BYTES - 1)) + | ||
220 | msg->leadin_ignore)); | ||
221 | |||
222 | /* | ||
223 | * Update the tail pointer to indicate data actually | ||
224 | * transferred. | ||
225 | */ | ||
226 | skb_put(skb, (msg->size - msg->leadin_ignore - msg->tailout_ignore)); | ||
227 | |||
228 | /* | ||
229 | * Move the data over from the the other side. | ||
230 | */ | ||
231 | if ((XPNET_VERSION_MINOR(msg->version) == 1) && | ||
232 | (msg->embedded_bytes != 0)) { | ||
233 | dev_dbg(xpnet, "copying embedded message. memcpy(0x%p, 0x%p, " | ||
234 | "%lu)\n", skb->data, &msg->data, | ||
235 | (size_t) msg->embedded_bytes); | ||
236 | |||
237 | memcpy(skb->data, &msg->data, (size_t) msg->embedded_bytes); | ||
238 | } else { | ||
239 | dev_dbg(xpnet, "transferring buffer to the skb->data area;\n\t" | ||
240 | "bte_copy(0x%p, 0x%p, %hu)\n", (void *)msg->buf_pa, | ||
241 | (void *)__pa((u64)skb->data & ~(L1_CACHE_BYTES - 1)), | ||
242 | msg->size); | ||
243 | |||
244 | bret = bte_copy(msg->buf_pa, | ||
245 | __pa((u64)skb->data & ~(L1_CACHE_BYTES - 1)), | ||
246 | msg->size, (BTE_NOTIFY | BTE_WACQUIRE), NULL); | ||
247 | |||
248 | if (bret != BTE_SUCCESS) { | ||
249 | // >>> Need better way of cleaning skb. Currently skb | ||
250 | // >>> appears in_use and we can't just call | ||
251 | // >>> dev_kfree_skb. | ||
252 | dev_err(xpnet, "bte_copy(0x%p, 0x%p, 0x%hx) returned " | ||
253 | "error=0x%x\n", (void *)msg->buf_pa, | ||
254 | (void *)__pa((u64)skb->data & | ||
255 | ~(L1_CACHE_BYTES - 1)), | ||
256 | msg->size, bret); | ||
257 | |||
258 | xpc_received(partid, channel, (void *) msg); | ||
259 | |||
260 | priv->stats.rx_errors++; | ||
261 | |||
262 | return; | ||
263 | } | ||
264 | } | ||
265 | |||
266 | dev_dbg(xpnet, "<skb->head=0x%p skb->data=0x%p skb->tail=0x%p " | ||
267 | "skb->end=0x%p skb->len=%d\n", (void *) skb->head, | ||
268 | (void *) skb->data, (void *) skb->tail, (void *) skb->end, | ||
269 | skb->len); | ||
270 | |||
271 | skb->dev = xpnet_device; | ||
272 | skb->protocol = eth_type_trans(skb, xpnet_device); | ||
273 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
274 | |||
275 | dev_dbg(xpnet, "passing skb to network layer; \n\tskb->head=0x%p " | ||
276 | "skb->data=0x%p skb->tail=0x%p skb->end=0x%p skb->len=%d\n", | ||
277 | (void *) skb->head, (void *) skb->data, (void *) skb->tail, | ||
278 | (void *) skb->end, skb->len); | ||
279 | |||
280 | |||
281 | xpnet_device->last_rx = jiffies; | ||
282 | priv->stats.rx_packets++; | ||
283 | priv->stats.rx_bytes += skb->len + ETH_HLEN; | ||
284 | |||
285 | netif_rx_ni(skb); | ||
286 | xpc_received(partid, channel, (void *) msg); | ||
287 | } | ||
288 | |||
289 | |||
290 | /* | ||
291 | * This is the handler which XPC calls during any sort of change in | ||
292 | * state or message reception on a connection. | ||
293 | */ | ||
294 | static void | ||
295 | xpnet_connection_activity(enum xpc_retval reason, partid_t partid, int channel, | ||
296 | void *data, void *key) | ||
297 | { | ||
298 | long bp; | ||
299 | |||
300 | |||
301 | DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS); | ||
302 | DBUG_ON(channel != XPC_NET_CHANNEL); | ||
303 | |||
304 | switch(reason) { | ||
305 | case xpcMsgReceived: /* message received */ | ||
306 | DBUG_ON(data == NULL); | ||
307 | |||
308 | xpnet_receive(partid, channel, (struct xpnet_message *) data); | ||
309 | break; | ||
310 | |||
311 | case xpcConnected: /* connection completed to a partition */ | ||
312 | spin_lock_bh(&xpnet_broadcast_lock); | ||
313 | xpnet_broadcast_partitions |= 1UL << (partid -1 ); | ||
314 | bp = xpnet_broadcast_partitions; | ||
315 | spin_unlock_bh(&xpnet_broadcast_lock); | ||
316 | |||
317 | netif_carrier_on(xpnet_device); | ||
318 | |||
319 | dev_dbg(xpnet, "%s connection created to partition %d; " | ||
320 | "xpnet_broadcast_partitions=0x%lx\n", | ||
321 | xpnet_device->name, partid, bp); | ||
322 | break; | ||
323 | |||
324 | default: | ||
325 | spin_lock_bh(&xpnet_broadcast_lock); | ||
326 | xpnet_broadcast_partitions &= ~(1UL << (partid -1 )); | ||
327 | bp = xpnet_broadcast_partitions; | ||
328 | spin_unlock_bh(&xpnet_broadcast_lock); | ||
329 | |||
330 | if (bp == 0) { | ||
331 | netif_carrier_off(xpnet_device); | ||
332 | } | ||
333 | |||
334 | dev_dbg(xpnet, "%s disconnected from partition %d; " | ||
335 | "xpnet_broadcast_partitions=0x%lx\n", | ||
336 | xpnet_device->name, partid, bp); | ||
337 | break; | ||
338 | |||
339 | } | ||
340 | } | ||
341 | |||
342 | |||
343 | static int | ||
344 | xpnet_dev_open(struct net_device *dev) | ||
345 | { | ||
346 | enum xpc_retval ret; | ||
347 | |||
348 | |||
349 | dev_dbg(xpnet, "calling xpc_connect(%d, 0x%p, NULL, %ld, %ld, %d, " | ||
350 | "%d)\n", XPC_NET_CHANNEL, xpnet_connection_activity, | ||
351 | XPNET_MSG_SIZE, XPNET_MSG_NENTRIES, XPNET_MAX_KTHREADS, | ||
352 | XPNET_MAX_IDLE_KTHREADS); | ||
353 | |||
354 | ret = xpc_connect(XPC_NET_CHANNEL, xpnet_connection_activity, NULL, | ||
355 | XPNET_MSG_SIZE, XPNET_MSG_NENTRIES, | ||
356 | XPNET_MAX_KTHREADS, XPNET_MAX_IDLE_KTHREADS); | ||
357 | if (ret != xpcSuccess) { | ||
358 | dev_err(xpnet, "ifconfig up of %s failed on XPC connect, " | ||
359 | "ret=%d\n", dev->name, ret); | ||
360 | |||
361 | return -ENOMEM; | ||
362 | } | ||
363 | |||
364 | dev_dbg(xpnet, "ifconfig up of %s; XPC connected\n", dev->name); | ||
365 | |||
366 | return 0; | ||
367 | } | ||
368 | |||
369 | |||
370 | static int | ||
371 | xpnet_dev_stop(struct net_device *dev) | ||
372 | { | ||
373 | xpc_disconnect(XPC_NET_CHANNEL); | ||
374 | |||
375 | dev_dbg(xpnet, "ifconfig down of %s; XPC disconnected\n", dev->name); | ||
376 | |||
377 | return 0; | ||
378 | } | ||
379 | |||
380 | |||
381 | static int | ||
382 | xpnet_dev_change_mtu(struct net_device *dev, int new_mtu) | ||
383 | { | ||
384 | /* 68 comes from min TCP+IP+MAC header */ | ||
385 | if ((new_mtu < 68) || (new_mtu > XPNET_MAX_MTU)) { | ||
386 | dev_err(xpnet, "ifconfig %s mtu %d failed; value must be " | ||
387 | "between 68 and %ld\n", dev->name, new_mtu, | ||
388 | XPNET_MAX_MTU); | ||
389 | return -EINVAL; | ||
390 | } | ||
391 | |||
392 | dev->mtu = new_mtu; | ||
393 | dev_dbg(xpnet, "ifconfig %s mtu set to %d\n", dev->name, new_mtu); | ||
394 | return 0; | ||
395 | } | ||
396 | |||
397 | |||
398 | /* | ||
399 | * Required for the net_device structure. | ||
400 | */ | ||
401 | static int | ||
402 | xpnet_dev_set_config(struct net_device *dev, struct ifmap *new_map) | ||
403 | { | ||
404 | return 0; | ||
405 | } | ||
406 | |||
407 | |||
408 | /* | ||
409 | * Return statistics to the caller. | ||
410 | */ | ||
411 | static struct net_device_stats * | ||
412 | xpnet_dev_get_stats(struct net_device *dev) | ||
413 | { | ||
414 | struct xpnet_dev_private *priv; | ||
415 | |||
416 | |||
417 | priv = (struct xpnet_dev_private *) dev->priv; | ||
418 | |||
419 | return &priv->stats; | ||
420 | } | ||
421 | |||
422 | |||
423 | /* | ||
424 | * Notification that the other end has received the message and | ||
425 | * DMA'd the skb information. At this point, they are done with | ||
426 | * our side. When all recipients are done processing, we | ||
427 | * release the skb and then release our pending message structure. | ||
428 | */ | ||
429 | static void | ||
430 | xpnet_send_completed(enum xpc_retval reason, partid_t partid, int channel, | ||
431 | void *__qm) | ||
432 | { | ||
433 | struct xpnet_pending_msg *queued_msg = | ||
434 | (struct xpnet_pending_msg *) __qm; | ||
435 | |||
436 | |||
437 | DBUG_ON(queued_msg == NULL); | ||
438 | |||
439 | dev_dbg(xpnet, "message to %d notified with reason %d\n", | ||
440 | partid, reason); | ||
441 | |||
442 | if (atomic_dec_return(&queued_msg->use_count) == 0) { | ||
443 | dev_dbg(xpnet, "all acks for skb->head=-x%p\n", | ||
444 | (void *) queued_msg->skb->head); | ||
445 | |||
446 | dev_kfree_skb_any(queued_msg->skb); | ||
447 | kfree(queued_msg); | ||
448 | } | ||
449 | } | ||
450 | |||
451 | |||
452 | /* | ||
453 | * Network layer has formatted a packet (skb) and is ready to place it | ||
454 | * "on the wire". Prepare and send an xpnet_message to all partitions | ||
455 | * which have connected with us and are targets of this packet. | ||
456 | * | ||
457 | * MAC-NOTE: For the XPNET driver, the MAC address contains the | ||
458 | * destination partition_id. If the destination partition id word | ||
459 | * is 0xff, this packet is to broadcast to all partitions. | ||
460 | */ | ||
461 | static int | ||
462 | xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
463 | { | ||
464 | struct xpnet_pending_msg *queued_msg; | ||
465 | enum xpc_retval ret; | ||
466 | struct xpnet_message *msg; | ||
467 | u64 start_addr, end_addr; | ||
468 | long dp; | ||
469 | u8 second_mac_octet; | ||
470 | partid_t dest_partid; | ||
471 | struct xpnet_dev_private *priv; | ||
472 | u16 embedded_bytes; | ||
473 | |||
474 | |||
475 | priv = (struct xpnet_dev_private *) dev->priv; | ||
476 | |||
477 | |||
478 | dev_dbg(xpnet, ">skb->head=0x%p skb->data=0x%p skb->tail=0x%p " | ||
479 | "skb->end=0x%p skb->len=%d\n", (void *) skb->head, | ||
480 | (void *) skb->data, (void *) skb->tail, (void *) skb->end, | ||
481 | skb->len); | ||
482 | |||
483 | |||
484 | /* | ||
485 | * The xpnet_pending_msg tracks how many outstanding | ||
486 | * xpc_send_notifies are relying on this skb. When none | ||
487 | * remain, release the skb. | ||
488 | */ | ||
489 | queued_msg = kmalloc(sizeof(struct xpnet_pending_msg), GFP_ATOMIC); | ||
490 | if (queued_msg == NULL) { | ||
491 | dev_warn(xpnet, "failed to kmalloc %ld bytes; dropping " | ||
492 | "packet\n", sizeof(struct xpnet_pending_msg)); | ||
493 | |||
494 | priv->stats.tx_errors++; | ||
495 | |||
496 | return -ENOMEM; | ||
497 | } | ||
498 | |||
499 | |||
500 | /* get the beginning of the first cacheline and end of last */ | ||
501 | start_addr = ((u64) skb->data & ~(L1_CACHE_BYTES - 1)); | ||
502 | end_addr = L1_CACHE_ALIGN((u64) skb->tail); | ||
503 | |||
504 | /* calculate how many bytes to embed in the XPC message */ | ||
505 | embedded_bytes = 0; | ||
506 | if (unlikely(skb->len <= XPNET_MSG_DATA_MAX)) { | ||
507 | /* skb->data does fit so embed */ | ||
508 | embedded_bytes = skb->len; | ||
509 | } | ||
510 | |||
511 | |||
512 | /* | ||
513 | * Since the send occurs asynchronously, we set the count to one | ||
514 | * and begin sending. Any sends that happen to complete before | ||
515 | * we are done sending will not free the skb. We will be left | ||
516 | * with that task during exit. This also handles the case of | ||
517 | * a packet destined for a partition which is no longer up. | ||
518 | */ | ||
519 | atomic_set(&queued_msg->use_count, 1); | ||
520 | queued_msg->skb = skb; | ||
521 | |||
522 | |||
523 | second_mac_octet = skb->data[XPNET_PARTID_OCTET]; | ||
524 | if (second_mac_octet == 0xff) { | ||
525 | /* we are being asked to broadcast to all partitions */ | ||
526 | dp = xpnet_broadcast_partitions; | ||
527 | } else if (second_mac_octet != 0) { | ||
528 | dp = xpnet_broadcast_partitions & | ||
529 | (1UL << (second_mac_octet - 1)); | ||
530 | } else { | ||
531 | /* 0 is an invalid partid. Ignore */ | ||
532 | dp = 0; | ||
533 | } | ||
534 | dev_dbg(xpnet, "destination Partitions mask (dp) = 0x%lx\n", dp); | ||
535 | |||
536 | /* | ||
537 | * If we wanted to allow promiscous mode to work like an | ||
538 | * unswitched network, this would be a good point to OR in a | ||
539 | * mask of partitions which should be receiving all packets. | ||
540 | */ | ||
541 | |||
542 | /* | ||
543 | * Main send loop. | ||
544 | */ | ||
545 | for (dest_partid = 1; dp && dest_partid < XP_MAX_PARTITIONS; | ||
546 | dest_partid++) { | ||
547 | |||
548 | |||
549 | if (!(dp & (1UL << (dest_partid - 1)))) { | ||
550 | /* not destined for this partition */ | ||
551 | continue; | ||
552 | } | ||
553 | |||
554 | /* remove this partition from the destinations mask */ | ||
555 | dp &= ~(1UL << (dest_partid - 1)); | ||
556 | |||
557 | |||
558 | /* found a partition to send to */ | ||
559 | |||
560 | ret = xpc_allocate(dest_partid, XPC_NET_CHANNEL, | ||
561 | XPC_NOWAIT, (void **)&msg); | ||
562 | if (unlikely(ret != xpcSuccess)) { | ||
563 | continue; | ||
564 | } | ||
565 | |||
566 | msg->embedded_bytes = embedded_bytes; | ||
567 | if (unlikely(embedded_bytes != 0)) { | ||
568 | msg->version = XPNET_VERSION_EMBED; | ||
569 | dev_dbg(xpnet, "calling memcpy(0x%p, 0x%p, 0x%lx)\n", | ||
570 | &msg->data, skb->data, (size_t) embedded_bytes); | ||
571 | memcpy(&msg->data, skb->data, (size_t) embedded_bytes); | ||
572 | } else { | ||
573 | msg->version = XPNET_VERSION; | ||
574 | } | ||
575 | msg->magic = XPNET_MAGIC; | ||
576 | msg->size = end_addr - start_addr; | ||
577 | msg->leadin_ignore = (u64) skb->data - start_addr; | ||
578 | msg->tailout_ignore = end_addr - (u64) skb->tail; | ||
579 | msg->buf_pa = __pa(start_addr); | ||
580 | |||
581 | dev_dbg(xpnet, "sending XPC message to %d:%d\nmsg->buf_pa=" | ||
582 | "0x%lx, msg->size=%u, msg->leadin_ignore=%u, " | ||
583 | "msg->tailout_ignore=%u\n", dest_partid, | ||
584 | XPC_NET_CHANNEL, msg->buf_pa, msg->size, | ||
585 | msg->leadin_ignore, msg->tailout_ignore); | ||
586 | |||
587 | |||
588 | atomic_inc(&queued_msg->use_count); | ||
589 | |||
590 | ret = xpc_send_notify(dest_partid, XPC_NET_CHANNEL, msg, | ||
591 | xpnet_send_completed, queued_msg); | ||
592 | if (unlikely(ret != xpcSuccess)) { | ||
593 | atomic_dec(&queued_msg->use_count); | ||
594 | continue; | ||
595 | } | ||
596 | |||
597 | } | ||
598 | |||
599 | if (atomic_dec_return(&queued_msg->use_count) == 0) { | ||
600 | dev_dbg(xpnet, "no partitions to receive packet destined for " | ||
601 | "%d\n", dest_partid); | ||
602 | |||
603 | |||
604 | dev_kfree_skb(skb); | ||
605 | kfree(queued_msg); | ||
606 | } | ||
607 | |||
608 | priv->stats.tx_packets++; | ||
609 | priv->stats.tx_bytes += skb->len; | ||
610 | |||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | |||
615 | /* | ||
616 | * Deal with transmit timeouts coming from the network layer. | ||
617 | */ | ||
618 | static void | ||
619 | xpnet_dev_tx_timeout (struct net_device *dev) | ||
620 | { | ||
621 | struct xpnet_dev_private *priv; | ||
622 | |||
623 | |||
624 | priv = (struct xpnet_dev_private *) dev->priv; | ||
625 | |||
626 | priv->stats.tx_errors++; | ||
627 | return; | ||
628 | } | ||
629 | |||
630 | |||
631 | static int __init | ||
632 | xpnet_init(void) | ||
633 | { | ||
634 | int i; | ||
635 | u32 license_num; | ||
636 | int result = -ENOMEM; | ||
637 | |||
638 | |||
639 | dev_info(xpnet, "registering network device %s\n", XPNET_DEVICE_NAME); | ||
640 | |||
641 | /* | ||
642 | * use ether_setup() to init the majority of our device | ||
643 | * structure and then override the necessary pieces. | ||
644 | */ | ||
645 | xpnet_device = alloc_netdev(sizeof(struct xpnet_dev_private), | ||
646 | XPNET_DEVICE_NAME, ether_setup); | ||
647 | if (xpnet_device == NULL) { | ||
648 | return -ENOMEM; | ||
649 | } | ||
650 | |||
651 | netif_carrier_off(xpnet_device); | ||
652 | |||
653 | xpnet_device->mtu = XPNET_DEF_MTU; | ||
654 | xpnet_device->change_mtu = xpnet_dev_change_mtu; | ||
655 | xpnet_device->open = xpnet_dev_open; | ||
656 | xpnet_device->get_stats = xpnet_dev_get_stats; | ||
657 | xpnet_device->stop = xpnet_dev_stop; | ||
658 | xpnet_device->hard_start_xmit = xpnet_dev_hard_start_xmit; | ||
659 | xpnet_device->tx_timeout = xpnet_dev_tx_timeout; | ||
660 | xpnet_device->set_config = xpnet_dev_set_config; | ||
661 | |||
662 | /* | ||
663 | * Multicast assumes the LSB of the first octet is set for multicast | ||
664 | * MAC addresses. We chose the first octet of the MAC to be unlikely | ||
665 | * to collide with any vendor's officially issued MAC. | ||
666 | */ | ||
667 | xpnet_device->dev_addr[0] = 0xfe; | ||
668 | xpnet_device->dev_addr[XPNET_PARTID_OCTET] = sn_partition_id; | ||
669 | license_num = sn_partition_serial_number_val(); | ||
670 | for (i = 3; i >= 0; i--) { | ||
671 | xpnet_device->dev_addr[XPNET_LICENSE_OCTET + i] = | ||
672 | license_num & 0xff; | ||
673 | license_num = license_num >> 8; | ||
674 | } | ||
675 | |||
676 | /* | ||
677 | * ether_setup() sets this to a multicast device. We are | ||
678 | * really not supporting multicast at this time. | ||
679 | */ | ||
680 | xpnet_device->flags &= ~IFF_MULTICAST; | ||
681 | |||
682 | /* | ||
683 | * No need to checksum as it is a DMA transfer. The BTE will | ||
684 | * report an error if the data is not retrievable and the | ||
685 | * packet will be dropped. | ||
686 | */ | ||
687 | xpnet_device->features = NETIF_F_NO_CSUM; | ||
688 | |||
689 | result = register_netdev(xpnet_device); | ||
690 | if (result != 0) { | ||
691 | free_netdev(xpnet_device); | ||
692 | } | ||
693 | |||
694 | return result; | ||
695 | } | ||
696 | module_init(xpnet_init); | ||
697 | |||
698 | |||
699 | static void __exit | ||
700 | xpnet_exit(void) | ||
701 | { | ||
702 | dev_info(xpnet, "unregistering network device %s\n", | ||
703 | xpnet_device[0].name); | ||
704 | |||
705 | unregister_netdev(xpnet_device); | ||
706 | |||
707 | free_netdev(xpnet_device); | ||
708 | } | ||
709 | module_exit(xpnet_exit); | ||
710 | |||
711 | |||
712 | MODULE_AUTHOR("Silicon Graphics, Inc."); | ||
713 | MODULE_DESCRIPTION("Cross Partition Network adapter (XPNET)"); | ||
714 | MODULE_LICENSE("GPL"); | ||
715 | |||
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c index c90685985d81..64af2b2c1787 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_dma.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_dma.c | |||
@@ -301,7 +301,7 @@ void sn_dma_flush(uint64_t addr) | |||
301 | spin_lock_irqsave(&((struct sn_flush_device_list *)p)-> | 301 | spin_lock_irqsave(&((struct sn_flush_device_list *)p)-> |
302 | sfdl_flush_lock, flags); | 302 | sfdl_flush_lock, flags); |
303 | 303 | ||
304 | p->sfdl_flush_value = 0; | 304 | *p->sfdl_flush_addr = 0; |
305 | 305 | ||
306 | /* force an interrupt. */ | 306 | /* force an interrupt. */ |
307 | *(volatile uint32_t *)(p->sfdl_force_int_addr) = 1; | 307 | *(volatile uint32_t *)(p->sfdl_force_int_addr) = 1; |
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c index 54a0dd447e76..8dae9eb45456 100644 --- a/arch/ia64/sn/pci/tioca_provider.c +++ b/arch/ia64/sn/pci/tioca_provider.c | |||
@@ -431,7 +431,7 @@ tioca_dma_mapped(struct pci_dev *pdev, uint64_t paddr, size_t req_size) | |||
431 | ca_dmamap->cad_dma_addr = bus_addr; | 431 | ca_dmamap->cad_dma_addr = bus_addr; |
432 | ca_dmamap->cad_gart_size = entries; | 432 | ca_dmamap->cad_gart_size = entries; |
433 | ca_dmamap->cad_gart_entry = entry; | 433 | ca_dmamap->cad_gart_entry = entry; |
434 | list_add(&ca_dmamap->cad_list, &tioca_kern->ca_list); | 434 | list_add(&ca_dmamap->cad_list, &tioca_kern->ca_dmamaps); |
435 | 435 | ||
436 | if (xio_addr % ps) { | 436 | if (xio_addr % ps) { |
437 | tioca_kern->ca_pcigart[entry] = tioca_paddr_to_gart(xio_addr); | 437 | tioca_kern->ca_pcigart[entry] = tioca_paddr_to_gart(xio_addr); |
diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig index 7dbf997ff205..5649fbae430e 100644 --- a/arch/m68k/configs/amiga_defconfig +++ b/arch/m68k/configs/amiga_defconfig | |||
@@ -1,7 +1,7 @@ | |||
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-rc2-m68k | 3 | # Linux kernel version: 2.6.12-rc6-m68k |
4 | # Tue Apr 5 14:05:59 2005 | 4 | # Tue Jun 7 20:34:23 2005 |
5 | # | 5 | # |
6 | CONFIG_M68K=y | 6 | CONFIG_M68K=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=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 |
@@ -135,7 +137,6 @@ CONFIG_PARPORT_1284=y | |||
135 | # | 137 | # |
136 | CONFIG_AMIGA_FLOPPY=y | 138 | CONFIG_AMIGA_FLOPPY=y |
137 | CONFIG_AMIGA_Z2RAM=y | 139 | CONFIG_AMIGA_Z2RAM=y |
138 | # CONFIG_BLK_DEV_XD is not set | ||
139 | # CONFIG_PARIDE is not set | 140 | # CONFIG_PARIDE is not set |
140 | # CONFIG_BLK_DEV_COW_COMMON is not set | 141 | # CONFIG_BLK_DEV_COW_COMMON is not set |
141 | CONFIG_BLK_DEV_LOOP=y | 142 | CONFIG_BLK_DEV_LOOP=y |
@@ -223,17 +224,12 @@ CONFIG_SCSI_CONSTANTS=y | |||
223 | # | 224 | # |
224 | # SCSI low-level drivers | 225 | # SCSI low-level drivers |
225 | # | 226 | # |
226 | # CONFIG_SCSI_7000FASST is not set | ||
227 | # CONFIG_SCSI_AHA152X is not set | 227 | # CONFIG_SCSI_AHA152X is not set |
228 | # CONFIG_SCSI_AHA1542 is not set | ||
229 | # CONFIG_SCSI_AIC7XXX_OLD is not set | 228 | # CONFIG_SCSI_AIC7XXX_OLD is not set |
230 | # CONFIG_SCSI_IN2000 is not set | 229 | # CONFIG_SCSI_IN2000 is not set |
231 | # CONFIG_SCSI_SATA is not set | 230 | # CONFIG_SCSI_SATA is not set |
232 | # CONFIG_SCSI_BUSLOGIC is not set | ||
233 | # CONFIG_SCSI_DTC3280 is not set | 231 | # CONFIG_SCSI_DTC3280 is not set |
234 | # CONFIG_SCSI_EATA is not set | ||
235 | # CONFIG_SCSI_FUTURE_DOMAIN is not set | 232 | # CONFIG_SCSI_FUTURE_DOMAIN is not set |
236 | # CONFIG_SCSI_GDTH is not set | ||
237 | # CONFIG_SCSI_GENERIC_NCR5380 is not set | 233 | # CONFIG_SCSI_GENERIC_NCR5380 is not set |
238 | # CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set | 234 | # CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set |
239 | # CONFIG_SCSI_PPA is not set | 235 | # CONFIG_SCSI_PPA is not set |
@@ -244,7 +240,6 @@ CONFIG_SCSI_CONSTANTS=y | |||
244 | # CONFIG_SCSI_QLOGIC_FAS is not set | 240 | # CONFIG_SCSI_QLOGIC_FAS is not set |
245 | # CONFIG_SCSI_SYM53C416 is not set | 241 | # CONFIG_SCSI_SYM53C416 is not set |
246 | # CONFIG_SCSI_T128 is not set | 242 | # CONFIG_SCSI_T128 is not set |
247 | # CONFIG_SCSI_U14_34F is not set | ||
248 | # CONFIG_SCSI_DEBUG is not set | 243 | # CONFIG_SCSI_DEBUG is not set |
249 | CONFIG_A3000_SCSI=y | 244 | CONFIG_A3000_SCSI=y |
250 | CONFIG_A2091_SCSI=y | 245 | CONFIG_A2091_SCSI=y |
@@ -492,7 +487,6 @@ CONFIG_HYDRA=m | |||
492 | CONFIG_ZORRO8390=m | 487 | CONFIG_ZORRO8390=m |
493 | CONFIG_APNE=m | 488 | CONFIG_APNE=m |
494 | # CONFIG_NET_VENDOR_3COM is not set | 489 | # CONFIG_NET_VENDOR_3COM is not set |
495 | # CONFIG_LANCE is not set | ||
496 | # CONFIG_NET_VENDOR_SMC is not set | 490 | # CONFIG_NET_VENDOR_SMC is not set |
497 | # CONFIG_NET_VENDOR_RACAL is not set | 491 | # CONFIG_NET_VENDOR_RACAL is not set |
498 | # CONFIG_AT1700 is not set | 492 | # CONFIG_AT1700 is not set |
@@ -620,7 +614,6 @@ CONFIG_SERIO_SERPORT=m | |||
620 | # CONFIG_SERIO_PARKBD is not set | 614 | # CONFIG_SERIO_PARKBD is not set |
621 | # CONFIG_SERIO_RAW is not set | 615 | # CONFIG_SERIO_RAW is not set |
622 | # CONFIG_GAMEPORT is not set | 616 | # CONFIG_GAMEPORT is not set |
623 | CONFIG_SOUND_GAMEPORT=y | ||
624 | 617 | ||
625 | # | 618 | # |
626 | # Character devices | 619 | # Character devices |
diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig index 505a2968e604..63024b0b7ac3 100644 --- a/arch/m68k/configs/apollo_defconfig +++ b/arch/m68k/configs/apollo_defconfig | |||
@@ -1,7 +1,7 @@ | |||
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-rc2-m68k | 3 | # Linux kernel version: 2.6.12-rc6-m68k |
4 | # Tue Apr 5 14:06:00 2005 | 4 | # Tue Jun 7 20:34:27 2005 |
5 | # | 5 | # |
6 | CONFIG_M68K=y | 6 | CONFIG_M68K=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=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 |
@@ -497,7 +499,6 @@ CONFIG_SERIO_SERPORT=m | |||
497 | CONFIG_SERIO_LIBPS2=m | 499 | CONFIG_SERIO_LIBPS2=m |
498 | # CONFIG_SERIO_RAW is not set | 500 | # CONFIG_SERIO_RAW is not set |
499 | # CONFIG_GAMEPORT is not set | 501 | # CONFIG_GAMEPORT is not set |
500 | CONFIG_SOUND_GAMEPORT=y | ||
501 | 502 | ||
502 | # | 503 | # |
503 | # Character devices | 504 | # Character devices |
diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig index 617aa73c3250..6433da2d2ce2 100644 --- a/arch/m68k/configs/atari_defconfig +++ b/arch/m68k/configs/atari_defconfig | |||
@@ -1,7 +1,7 @@ | |||
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-rc2-m68k | 3 | # Linux kernel version: 2.6.12-rc6-m68k |
4 | # Tue Apr 5 14:06:18 2005 | 4 | # Tue Jun 7 20:34:32 2005 |
5 | # | 5 | # |
6 | CONFIG_M68K=y | 6 | CONFIG_M68K=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=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 |
@@ -531,7 +533,6 @@ CONFIG_SERIO_SERPORT=y | |||
531 | CONFIG_SERIO_LIBPS2=y | 533 | CONFIG_SERIO_LIBPS2=y |
532 | # CONFIG_SERIO_RAW is not set | 534 | # CONFIG_SERIO_RAW is not set |
533 | # CONFIG_GAMEPORT is not set | 535 | # CONFIG_GAMEPORT is not set |
534 | CONFIG_SOUND_GAMEPORT=y | ||
535 | 536 | ||
536 | # | 537 | # |
537 | # Character devices | 538 | # Character devices |
diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig index b501db51d9ec..da2a23a21463 100644 --- a/arch/m68k/configs/bvme6000_defconfig +++ b/arch/m68k/configs/bvme6000_defconfig | |||
@@ -1,7 +1,7 @@ | |||
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-rc2-m68k | 3 | # Linux kernel version: 2.6.12-rc6-m68k |
4 | # Tue Apr 5 14:06:19 2005 | 4 | # Tue Jun 7 20:34:37 2005 |
5 | # | 5 | # |
6 | CONFIG_M68K=y | 6 | CONFIG_M68K=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=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 |
@@ -496,7 +498,6 @@ CONFIG_SERIO_SERPORT=m | |||
496 | CONFIG_SERIO_LIBPS2=m | 498 | CONFIG_SERIO_LIBPS2=m |
497 | # CONFIG_SERIO_RAW is not set | 499 | # CONFIG_SERIO_RAW is not set |
498 | # CONFIG_GAMEPORT is not set | 500 | # CONFIG_GAMEPORT is not set |
499 | CONFIG_SOUND_GAMEPORT=y | ||
500 | 501 | ||
501 | # | 502 | # |
502 | # Character devices | 503 | # Character devices |
diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig index 2bf6cef4f2b2..51251883adf8 100644 --- a/arch/m68k/configs/hp300_defconfig +++ b/arch/m68k/configs/hp300_defconfig | |||
@@ -1,7 +1,7 @@ | |||
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-rc2-m68k | 3 | # Linux kernel version: 2.6.12-rc6-m68k |
4 | # Tue Apr 5 14:06:21 2005 | 4 | # Tue Jun 7 20:34:41 2005 |
5 | # | 5 | # |
6 | CONFIG_M68K=y | 6 | CONFIG_M68K=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=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 |
@@ -498,7 +500,6 @@ CONFIG_SERIO_SERPORT=m | |||
498 | CONFIG_SERIO_LIBPS2=m | 500 | CONFIG_SERIO_LIBPS2=m |
499 | # CONFIG_SERIO_RAW is not set | 501 | # CONFIG_SERIO_RAW is not set |
500 | # CONFIG_GAMEPORT is not set | 502 | # CONFIG_GAMEPORT is not set |
501 | CONFIG_SOUND_GAMEPORT=y | ||
502 | 503 | ||
503 | # | 504 | # |
504 | # Character devices | 505 | # Character devices |
diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig index 7074f856820c..15b80abfe94a 100644 --- a/arch/m68k/configs/mac_defconfig +++ b/arch/m68k/configs/mac_defconfig | |||
@@ -1,7 +1,7 @@ | |||
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-rc2-m68k | 3 | # Linux kernel version: 2.6.12-rc6-m68k |
4 | # Tue Apr 5 14:06:24 2005 | 4 | # Tue Jun 7 20:34:45 2005 |
5 | # | 5 | # |
6 | CONFIG_M68K=y | 6 | CONFIG_M68K=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=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 |
@@ -540,7 +542,6 @@ CONFIG_SERIO_SERPORT=m | |||
540 | CONFIG_SERIO_LIBPS2=m | 542 | CONFIG_SERIO_LIBPS2=m |
541 | # CONFIG_SERIO_RAW is not set | 543 | # CONFIG_SERIO_RAW is not set |
542 | # CONFIG_GAMEPORT is not set | 544 | # CONFIG_GAMEPORT is not set |
543 | CONFIG_SOUND_GAMEPORT=y | ||
544 | 545 | ||
545 | # | 546 | # |
546 | # Character devices | 547 | # Character devices |
diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig index 61f09bc4846a..f0d5534f6830 100644 --- a/arch/m68k/configs/mvme147_defconfig +++ b/arch/m68k/configs/mvme147_defconfig | |||
@@ -1,7 +1,7 @@ | |||
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-rc2-m68k | 3 | # Linux kernel version: 2.6.12-rc6-m68k |
4 | # Tue Apr 5 14:06:28 2005 | 4 | # Tue Jun 7 20:34:50 2005 |
5 | # | 5 | # |
6 | CONFIG_M68K=y | 6 | CONFIG_M68K=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=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 |
@@ -498,7 +500,6 @@ CONFIG_SERIO_SERPORT=m | |||
498 | CONFIG_SERIO_LIBPS2=m | 500 | CONFIG_SERIO_LIBPS2=m |
499 | # CONFIG_SERIO_RAW is not set | 501 | # CONFIG_SERIO_RAW is not set |
500 | # CONFIG_GAMEPORT is not set | 502 | # CONFIG_GAMEPORT is not set |
501 | CONFIG_SOUND_GAMEPORT=y | ||
502 | 503 | ||
503 | # | 504 | # |
504 | # Character devices | 505 | # Character devices |
diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig index 69c01004ec41..1d5c46ff3c81 100644 --- a/arch/m68k/configs/mvme16x_defconfig +++ b/arch/m68k/configs/mvme16x_defconfig | |||
@@ -1,7 +1,7 @@ | |||
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-rc2-m68k | 3 | # Linux kernel version: 2.6.12-rc6-m68k |
4 | # Tue Apr 5 14:06:31 2005 | 4 | # Tue Jun 7 20:34:53 2005 |
5 | # | 5 | # |
6 | CONFIG_M68K=y | 6 | CONFIG_M68K=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=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 |
@@ -497,7 +499,6 @@ CONFIG_SERIO_SERPORT=m | |||
497 | CONFIG_SERIO_LIBPS2=m | 499 | CONFIG_SERIO_LIBPS2=m |
498 | # CONFIG_SERIO_RAW is not set | 500 | # CONFIG_SERIO_RAW is not set |
499 | # CONFIG_GAMEPORT is not set | 501 | # CONFIG_GAMEPORT is not set |
500 | CONFIG_SOUND_GAMEPORT=y | ||
501 | 502 | ||
502 | # | 503 | # |
503 | # Character devices | 504 | # Character devices |
diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig index 550ec26006c1..856238634d42 100644 --- a/arch/m68k/configs/q40_defconfig +++ b/arch/m68k/configs/q40_defconfig | |||
@@ -1,7 +1,7 @@ | |||
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-rc2-m68k | 3 | # Linux kernel version: 2.6.12-rc6-m68k |
4 | # Tue Apr 5 14:06:34 2005 | 4 | # Tue Jun 7 20:34:58 2005 |
5 | # | 5 | # |
6 | CONFIG_M68K=y | 6 | CONFIG_M68K=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=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 |
@@ -125,7 +127,6 @@ CONFIG_FW_LOADER=m | |||
125 | # Block devices | 127 | # Block devices |
126 | # | 128 | # |
127 | # CONFIG_BLK_DEV_FD is not set | 129 | # CONFIG_BLK_DEV_FD is not set |
128 | # CONFIG_BLK_DEV_XD is not set | ||
129 | # CONFIG_BLK_DEV_COW_COMMON is not set | 130 | # CONFIG_BLK_DEV_COW_COMMON is not set |
130 | CONFIG_BLK_DEV_LOOP=y | 131 | CONFIG_BLK_DEV_LOOP=y |
131 | CONFIG_BLK_DEV_CRYPTOLOOP=m | 132 | CONFIG_BLK_DEV_CRYPTOLOOP=m |
@@ -210,17 +211,12 @@ CONFIG_SCSI_CONSTANTS=y | |||
210 | # | 211 | # |
211 | # SCSI low-level drivers | 212 | # SCSI low-level drivers |
212 | # | 213 | # |
213 | # CONFIG_SCSI_7000FASST is not set | ||
214 | # CONFIG_SCSI_AHA152X is not set | 214 | # CONFIG_SCSI_AHA152X is not set |
215 | # CONFIG_SCSI_AHA1542 is not set | ||
216 | # CONFIG_SCSI_AIC7XXX_OLD is not set | 215 | # CONFIG_SCSI_AIC7XXX_OLD is not set |
217 | # CONFIG_SCSI_IN2000 is not set | 216 | # CONFIG_SCSI_IN2000 is not set |
218 | # CONFIG_SCSI_SATA is not set | 217 | # CONFIG_SCSI_SATA is not set |
219 | # CONFIG_SCSI_BUSLOGIC is not set | ||
220 | # CONFIG_SCSI_DTC3280 is not set | 218 | # CONFIG_SCSI_DTC3280 is not set |
221 | # CONFIG_SCSI_EATA is not set | ||
222 | # CONFIG_SCSI_FUTURE_DOMAIN is not set | 219 | # CONFIG_SCSI_FUTURE_DOMAIN is not set |
223 | # CONFIG_SCSI_GDTH is not set | ||
224 | # CONFIG_SCSI_GENERIC_NCR5380 is not set | 220 | # CONFIG_SCSI_GENERIC_NCR5380 is not set |
225 | # CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set | 221 | # CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set |
226 | # CONFIG_SCSI_NCR53C406A is not set | 222 | # CONFIG_SCSI_NCR53C406A is not set |
@@ -229,7 +225,6 @@ CONFIG_SCSI_CONSTANTS=y | |||
229 | # CONFIG_SCSI_QLOGIC_FAS is not set | 225 | # CONFIG_SCSI_QLOGIC_FAS is not set |
230 | # CONFIG_SCSI_SYM53C416 is not set | 226 | # CONFIG_SCSI_SYM53C416 is not set |
231 | # CONFIG_SCSI_T128 is not set | 227 | # CONFIG_SCSI_T128 is not set |
232 | # CONFIG_SCSI_U14_34F is not set | ||
233 | # CONFIG_SCSI_DEBUG is not set | 228 | # CONFIG_SCSI_DEBUG is not set |
234 | 229 | ||
235 | # | 230 | # |
@@ -466,7 +461,6 @@ CONFIG_EQUALIZER=m | |||
466 | CONFIG_NET_ETHERNET=y | 461 | CONFIG_NET_ETHERNET=y |
467 | CONFIG_MII=m | 462 | CONFIG_MII=m |
468 | # CONFIG_NET_VENDOR_3COM is not set | 463 | # CONFIG_NET_VENDOR_3COM is not set |
469 | # CONFIG_LANCE is not set | ||
470 | # CONFIG_NET_VENDOR_SMC is not set | 464 | # CONFIG_NET_VENDOR_SMC is not set |
471 | # CONFIG_NET_VENDOR_RACAL is not set | 465 | # CONFIG_NET_VENDOR_RACAL is not set |
472 | # CONFIG_AT1700 is not set | 466 | # CONFIG_AT1700 is not set |
@@ -570,7 +564,6 @@ CONFIG_SERIO_Q40KBD=m | |||
570 | CONFIG_SERIO_LIBPS2=m | 564 | CONFIG_SERIO_LIBPS2=m |
571 | # CONFIG_SERIO_RAW is not set | 565 | # CONFIG_SERIO_RAW is not set |
572 | # CONFIG_GAMEPORT is not set | 566 | # CONFIG_GAMEPORT is not set |
573 | CONFIG_SOUND_GAMEPORT=y | ||
574 | 567 | ||
575 | # | 568 | # |
576 | # Character devices | 569 | # Character devices |
diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig index 5b5a619645aa..af903b5c5708 100644 --- a/arch/m68k/configs/sun3_defconfig +++ b/arch/m68k/configs/sun3_defconfig | |||
@@ -1,7 +1,7 @@ | |||
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-rc2-m68k | 3 | # Linux kernel version: 2.6.12-rc6-m68k |
4 | # Tue Apr 5 14:06:37 2005 | 4 | # Tue Jun 7 20:35:02 2005 |
5 | # | 5 | # |
6 | CONFIG_M68K=y | 6 | CONFIG_M68K=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=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 |
@@ -171,7 +173,6 @@ CONFIG_SCSI_CONSTANTS=y | |||
171 | # | 173 | # |
172 | # CONFIG_SCSI_SATA is not set | 174 | # CONFIG_SCSI_SATA is not set |
173 | # CONFIG_SCSI_DEBUG is not set | 175 | # CONFIG_SCSI_DEBUG is not set |
174 | CONFIG_SUN3_SCSI=y | ||
175 | 176 | ||
176 | # | 177 | # |
177 | # Multi-device support (RAID and LVM) | 178 | # Multi-device support (RAID and LVM) |
@@ -487,7 +488,6 @@ CONFIG_SERIO_SERPORT=m | |||
487 | CONFIG_SERIO_LIBPS2=m | 488 | CONFIG_SERIO_LIBPS2=m |
488 | # CONFIG_SERIO_RAW is not set | 489 | # CONFIG_SERIO_RAW is not set |
489 | # CONFIG_GAMEPORT is not set | 490 | # CONFIG_GAMEPORT is not set |
490 | CONFIG_SOUND_GAMEPORT=y | ||
491 | 491 | ||
492 | # | 492 | # |
493 | # Character devices | 493 | # Character devices |
diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig index 704e42344cba..997143b7928a 100644 --- a/arch/m68k/configs/sun3x_defconfig +++ b/arch/m68k/configs/sun3x_defconfig | |||
@@ -1,7 +1,7 @@ | |||
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-rc2-m68k | 3 | # Linux kernel version: 2.6.12-rc6-m68k |
4 | # Tue Apr 5 14:06:40 2005 | 4 | # Tue Jun 7 20:35:06 2005 |
5 | # | 5 | # |
6 | CONFIG_M68K=y | 6 | CONFIG_M68K=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=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 |
@@ -497,7 +499,6 @@ CONFIG_SERIO_SERPORT=m | |||
497 | CONFIG_SERIO_LIBPS2=m | 499 | CONFIG_SERIO_LIBPS2=m |
498 | # CONFIG_SERIO_RAW is not set | 500 | # CONFIG_SERIO_RAW is not set |
499 | # CONFIG_GAMEPORT is not set | 501 | # CONFIG_GAMEPORT is not set |
500 | CONFIG_SOUND_GAMEPORT=y | ||
501 | 502 | ||
502 | # | 503 | # |
503 | # Character devices | 504 | # Character devices |
diff --git a/arch/m68k/defconfig b/arch/m68k/defconfig index 5b2296ecba82..7d935e48a9a8 100644 --- a/arch/m68k/defconfig +++ b/arch/m68k/defconfig | |||
@@ -1,7 +1,7 @@ | |||
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-rc2-m68k | 3 | # Linux kernel version: 2.6.12-rc6-m68k |
4 | # Tue Apr 5 14:05:31 2005 | 4 | # Tue Jun 7 20:34:17 2005 |
5 | # | 5 | # |
6 | CONFIG_M68K=y | 6 | CONFIG_M68K=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
@@ -33,6 +33,8 @@ CONFIG_KOBJECT_UEVENT=y | |||
33 | # CONFIG_EMBEDDED is not set | 33 | # CONFIG_EMBEDDED is not set |
34 | CONFIG_KALLSYMS=y | 34 | CONFIG_KALLSYMS=y |
35 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 35 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
36 | CONFIG_PRINTK=y | ||
37 | CONFIG_BUG=y | ||
36 | CONFIG_BASE_FULL=y | 38 | CONFIG_BASE_FULL=y |
37 | CONFIG_FUTEX=y | 39 | CONFIG_FUTEX=y |
38 | CONFIG_EPOLL=y | 40 | CONFIG_EPOLL=y |
@@ -355,7 +357,6 @@ CONFIG_SERIO_SERPORT=y | |||
355 | CONFIG_SERIO_LIBPS2=y | 357 | CONFIG_SERIO_LIBPS2=y |
356 | # CONFIG_SERIO_RAW is not set | 358 | # CONFIG_SERIO_RAW is not set |
357 | # CONFIG_GAMEPORT is not set | 359 | # CONFIG_GAMEPORT is not set |
358 | CONFIG_SOUND_GAMEPORT=y | ||
359 | 360 | ||
360 | # | 361 | # |
361 | # Character devices | 362 | # Character devices |
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig index fc4615b6d3a9..e729bd280623 100644 --- a/arch/m68knommu/Kconfig +++ b/arch/m68knommu/Kconfig | |||
@@ -534,6 +534,11 @@ endchoice | |||
534 | 534 | ||
535 | endmenu | 535 | endmenu |
536 | 536 | ||
537 | config ISA_DMA_API | ||
538 | bool | ||
539 | depends on !M5272 | ||
540 | default y | ||
541 | |||
537 | menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)" | 542 | menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)" |
538 | 543 | ||
539 | config PCI | 544 | config PCI |
diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c index 2b6c9d32b7a6..c4a33f265dc0 100644 --- a/arch/m68knommu/kernel/process.c +++ b/arch/m68knommu/kernel/process.c | |||
@@ -45,11 +45,13 @@ asmlinkage void ret_from_fork(void); | |||
45 | */ | 45 | */ |
46 | void default_idle(void) | 46 | void default_idle(void) |
47 | { | 47 | { |
48 | while(1) { | 48 | local_irq_disable(); |
49 | if (need_resched()) | 49 | while (!need_resched()) { |
50 | __asm__("stop #0x2000" : : : "cc"); | 50 | /* This stop will re-enable interrupts */ |
51 | schedule(); | 51 | __asm__("stop #0x2000" : : : "cc"); |
52 | local_irq_disable(); | ||
52 | } | 53 | } |
54 | local_irq_enable(); | ||
53 | } | 55 | } |
54 | 56 | ||
55 | void (*idle)(void) = default_idle; | 57 | void (*idle)(void) = default_idle; |
@@ -63,7 +65,12 @@ void (*idle)(void) = default_idle; | |||
63 | void cpu_idle(void) | 65 | void cpu_idle(void) |
64 | { | 66 | { |
65 | /* endless idle loop with no priority at all */ | 67 | /* endless idle loop with no priority at all */ |
66 | idle(); | 68 | while (1) { |
69 | idle(); | ||
70 | preempt_enable_no_resched(); | ||
71 | schedule(); | ||
72 | preempt_disable(); | ||
73 | } | ||
67 | } | 74 | } |
68 | 75 | ||
69 | void machine_restart(char * __unused) | 76 | void machine_restart(char * __unused) |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 5e666aad8815..ab9944693f1f 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -1656,3 +1656,7 @@ config GENERIC_HARDIRQS | |||
1656 | config GENERIC_IRQ_PROBE | 1656 | config GENERIC_IRQ_PROBE |
1657 | bool | 1657 | bool |
1658 | default y | 1658 | default y |
1659 | |||
1660 | config ISA_DMA_API | ||
1661 | bool | ||
1662 | default y | ||
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index a2f899c2f4d4..92e70ca3bff9 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c | |||
@@ -301,25 +301,38 @@ out: | |||
301 | return ret; | 301 | return ret; |
302 | } | 302 | } |
303 | 303 | ||
304 | static inline int audit_arch(void) | ||
305 | { | ||
306 | #ifdef CONFIG_CPU_LITTLE_ENDIAN | ||
307 | #ifdef CONFIG_MIPS64 | ||
308 | if (!(current->thread.mflags & MF_32BIT_REGS)) | ||
309 | return AUDIT_ARCH_MIPSEL64; | ||
310 | #endif /* MIPS64 */ | ||
311 | return AUDIT_ARCH_MIPSEL; | ||
312 | |||
313 | #else /* big endian... */ | ||
314 | #ifdef CONFIG_MIPS64 | ||
315 | if (!(current->thread.mflags & MF_32BIT_REGS)) | ||
316 | return AUDIT_ARCH_MIPS64; | ||
317 | #endif /* MIPS64 */ | ||
318 | return AUDIT_ARCH_MIPS; | ||
319 | |||
320 | #endif /* endian */ | ||
321 | } | ||
322 | |||
304 | /* | 323 | /* |
305 | * Notification of system call entry/exit | 324 | * Notification of system call entry/exit |
306 | * - triggered by current->work.syscall_trace | 325 | * - triggered by current->work.syscall_trace |
307 | */ | 326 | */ |
308 | asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) | 327 | asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) |
309 | { | 328 | { |
310 | if (unlikely(current->audit_context)) { | 329 | if (unlikely(current->audit_context) && entryexit) |
311 | if (!entryexit) | 330 | audit_syscall_exit(current, AUDITSC_RESULT(regs->regs[2]), regs->regs[2]); |
312 | audit_syscall_entry(current, regs->regs[2], | ||
313 | regs->regs[4], regs->regs[5], | ||
314 | regs->regs[6], regs->regs[7]); | ||
315 | else | ||
316 | audit_syscall_exit(current, regs->regs[2]); | ||
317 | } | ||
318 | 331 | ||
319 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) | 332 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) |
320 | return; | 333 | goto out; |
321 | if (!(current->ptrace & PT_PTRACED)) | 334 | if (!(current->ptrace & PT_PTRACED)) |
322 | return; | 335 | goto out; |
323 | 336 | ||
324 | /* The 0x80 provides a way for the tracing parent to distinguish | 337 | /* The 0x80 provides a way for the tracing parent to distinguish |
325 | between a syscall stop and SIGTRAP delivery */ | 338 | between a syscall stop and SIGTRAP delivery */ |
@@ -335,4 +348,9 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) | |||
335 | send_sig(current->exit_code, current, 1); | 348 | send_sig(current->exit_code, current, 1); |
336 | current->exit_code = 0; | 349 | current->exit_code = 0; |
337 | } | 350 | } |
351 | out: | ||
352 | if (unlikely(current->audit_context) && !entryexit) | ||
353 | audit_syscall_entry(current, audit_arch(), regs->regs[2], | ||
354 | regs->regs[4], regs->regs[5], | ||
355 | regs->regs[6], regs->regs[7]); | ||
338 | } | 356 | } |
diff --git a/arch/mips/vr41xx/common/pmu.c b/arch/mips/vr41xx/common/pmu.c index c5f1043de938..53166f3598b2 100644 --- a/arch/mips/vr41xx/common/pmu.c +++ b/arch/mips/vr41xx/common/pmu.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * pmu.c, Power Management Unit routines for NEC VR4100 series. | 2 | * pmu.c, Power Management Unit routines for NEC VR4100 series. |
3 | * | 3 | * |
4 | * Copyright (C) 2003-2004 Yoichi Yuasa <yuasa@hh.iij4u.or.jp> | 4 | * Copyright (C) 2003-2005 Yoichi Yuasa <yuasa@hh.iij4u.or.jp> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -17,7 +17,9 @@ | |||
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | #include <linux/errno.h> | ||
20 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/ioport.h> | ||
21 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
22 | #include <linux/smp.h> | 24 | #include <linux/smp.h> |
23 | #include <linux/types.h> | 25 | #include <linux/types.h> |
@@ -27,20 +29,31 @@ | |||
27 | #include <asm/reboot.h> | 29 | #include <asm/reboot.h> |
28 | #include <asm/system.h> | 30 | #include <asm/system.h> |
29 | 31 | ||
30 | #define PMUCNT2REG KSEG1ADDR(0x0f0000c6) | 32 | #define PMU_TYPE1_BASE 0x0b0000a0UL |
33 | #define PMU_TYPE1_SIZE 0x0eUL | ||
34 | |||
35 | #define PMU_TYPE2_BASE 0x0f0000c0UL | ||
36 | #define PMU_TYPE2_SIZE 0x10UL | ||
37 | |||
38 | #define PMUCNT2REG 0x06 | ||
31 | #define SOFTRST 0x0010 | 39 | #define SOFTRST 0x0010 |
32 | 40 | ||
41 | static void __iomem *pmu_base; | ||
42 | |||
43 | #define pmu_read(offset) readw(pmu_base + (offset)) | ||
44 | #define pmu_write(offset, value) writew((value), pmu_base + (offset)) | ||
45 | |||
33 | static inline void software_reset(void) | 46 | static inline void software_reset(void) |
34 | { | 47 | { |
35 | uint16_t val; | 48 | uint16_t pmucnt2; |
36 | 49 | ||
37 | switch (current_cpu_data.cputype) { | 50 | switch (current_cpu_data.cputype) { |
38 | case CPU_VR4122: | 51 | case CPU_VR4122: |
39 | case CPU_VR4131: | 52 | case CPU_VR4131: |
40 | case CPU_VR4133: | 53 | case CPU_VR4133: |
41 | val = readw(PMUCNT2REG); | 54 | pmucnt2 = pmu_read(PMUCNT2REG); |
42 | val |= SOFTRST; | 55 | pmucnt2 |= SOFTRST; |
43 | writew(val, PMUCNT2REG); | 56 | pmu_write(PMUCNT2REG, pmucnt2); |
44 | break; | 57 | break; |
45 | default: | 58 | default: |
46 | break; | 59 | break; |
@@ -71,6 +84,34 @@ static void vr41xx_power_off(void) | |||
71 | 84 | ||
72 | static int __init vr41xx_pmu_init(void) | 85 | static int __init vr41xx_pmu_init(void) |
73 | { | 86 | { |
87 | unsigned long start, size; | ||
88 | |||
89 | switch (current_cpu_data.cputype) { | ||
90 | case CPU_VR4111: | ||
91 | case CPU_VR4121: | ||
92 | start = PMU_TYPE1_BASE; | ||
93 | size = PMU_TYPE1_SIZE; | ||
94 | break; | ||
95 | case CPU_VR4122: | ||
96 | case CPU_VR4131: | ||
97 | case CPU_VR4133: | ||
98 | start = PMU_TYPE2_BASE; | ||
99 | size = PMU_TYPE2_SIZE; | ||
100 | break; | ||
101 | default: | ||
102 | printk("Unexpected CPU of NEC VR4100 series\n"); | ||
103 | return -ENODEV; | ||
104 | } | ||
105 | |||
106 | if (request_mem_region(start, size, "PMU") == NULL) | ||
107 | return -EBUSY; | ||
108 | |||
109 | pmu_base = ioremap(start, size); | ||
110 | if (pmu_base == NULL) { | ||
111 | release_mem_region(start, size); | ||
112 | return -EBUSY; | ||
113 | } | ||
114 | |||
74 | _machine_restart = vr41xx_restart; | 115 | _machine_restart = vr41xx_restart; |
75 | _machine_halt = vr41xx_halt; | 116 | _machine_halt = vr41xx_halt; |
76 | _machine_power_off = vr41xx_power_off; | 117 | _machine_power_off = vr41xx_power_off; |
@@ -78,4 +119,4 @@ static int __init vr41xx_pmu_init(void) | |||
78 | return 0; | 119 | return 0; |
79 | } | 120 | } |
80 | 121 | ||
81 | early_initcall(vr41xx_pmu_init); | 122 | core_initcall(vr41xx_pmu_init); |
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 5b5cd00d98ca..e7e7c56fc212 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig | |||
@@ -45,6 +45,10 @@ config GENERIC_IRQ_PROBE | |||
45 | config PM | 45 | config PM |
46 | bool | 46 | bool |
47 | 47 | ||
48 | config ISA_DMA_API | ||
49 | bool | ||
50 | default y | ||
51 | |||
48 | source "init/Kconfig" | 52 | source "init/Kconfig" |
49 | 53 | ||
50 | 54 | ||
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index c3d941345e3d..6e6377a69d5b 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig | |||
@@ -43,6 +43,10 @@ config GENERIC_NVRAM | |||
43 | bool | 43 | bool |
44 | default y | 44 | default y |
45 | 45 | ||
46 | config SCHED_NO_NO_OMIT_FRAME_POINTER | ||
47 | bool | ||
48 | default y | ||
49 | |||
46 | source "init/Kconfig" | 50 | source "init/Kconfig" |
47 | 51 | ||
48 | menu "Processor" | 52 | menu "Processor" |
@@ -73,9 +77,11 @@ config 44x | |||
73 | bool "44x" | 77 | bool "44x" |
74 | 78 | ||
75 | config POWER3 | 79 | config POWER3 |
80 | select PPC_FPU | ||
76 | bool "POWER3" | 81 | bool "POWER3" |
77 | 82 | ||
78 | config POWER4 | 83 | config POWER4 |
84 | select PPC_FPU | ||
79 | bool "POWER4 and 970 (G5)" | 85 | bool "POWER4 and 970 (G5)" |
80 | 86 | ||
81 | config 8xx | 87 | config 8xx |
@@ -1079,6 +1085,10 @@ source kernel/power/Kconfig | |||
1079 | 1085 | ||
1080 | endmenu | 1086 | endmenu |
1081 | 1087 | ||
1088 | config ISA_DMA_API | ||
1089 | bool | ||
1090 | default y | ||
1091 | |||
1082 | menu "Bus options" | 1092 | menu "Bus options" |
1083 | 1093 | ||
1084 | config ISA | 1094 | config ISA |
@@ -1133,12 +1143,12 @@ config PCI_QSPAN | |||
1133 | 1143 | ||
1134 | config PCI_8260 | 1144 | config PCI_8260 |
1135 | bool | 1145 | bool |
1136 | depends on PCI && 8260 && !8272 | 1146 | depends on PCI && 8260 |
1137 | default y | 1147 | default y |
1138 | 1148 | ||
1139 | config 8260_PCI9 | 1149 | config 8260_PCI9 |
1140 | bool " Enable workaround for MPC826x erratum PCI 9" | 1150 | bool " Enable workaround for MPC826x erratum PCI 9" |
1141 | depends on PCI_8260 | 1151 | depends on PCI_8260 && !ADS8272 |
1142 | default y | 1152 | default y |
1143 | 1153 | ||
1144 | choice | 1154 | choice |
diff --git a/arch/ppc/boot/images/Makefile b/arch/ppc/boot/images/Makefile index f850fb0fb511..c9ac5f5fa9e4 100644 --- a/arch/ppc/boot/images/Makefile +++ b/arch/ppc/boot/images/Makefile | |||
@@ -22,7 +22,8 @@ targets += uImage | |||
22 | $(obj)/uImage: $(obj)/vmlinux.gz | 22 | $(obj)/uImage: $(obj)/vmlinux.gz |
23 | $(Q)rm -f $@ | 23 | $(Q)rm -f $@ |
24 | $(call if_changed,uimage) | 24 | $(call if_changed,uimage) |
25 | @echo ' Image: $@' $(if $(wildcard $@),'is ready','not made') | 25 | @echo -n ' Image: $@ ' |
26 | @if [ -f $@ ]; then echo 'is ready' ; else echo 'not made'; fi | ||
26 | 27 | ||
27 | # Files generated that shall be removed upon make clean | 28 | # Files generated that shall be removed upon make clean |
28 | clean-files := sImage vmapus vmlinux* miboot* zImage* uImage | 29 | clean-files := sImage vmapus vmlinux* miboot* zImage* uImage |
diff --git a/arch/ppc/configs/mpc8555_cds_defconfig b/arch/ppc/configs/mpc8555_cds_defconfig index 728bd9e1a8fa..15abebf46b96 100644 --- a/arch/ppc/configs/mpc8555_cds_defconfig +++ b/arch/ppc/configs/mpc8555_cds_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.11-rc1 | 3 | # Linux kernel version: 2.6.12-rc4 |
4 | # Thu Jan 20 01:25:35 2005 | 4 | # Tue May 17 11:56:01 2005 |
5 | # | 5 | # |
6 | CONFIG_MMU=y | 6 | CONFIG_MMU=y |
7 | CONFIG_GENERIC_HARDIRQS=y | 7 | CONFIG_GENERIC_HARDIRQS=y |
@@ -11,6 +11,7 @@ CONFIG_HAVE_DEC_LOCK=y | |||
11 | CONFIG_PPC=y | 11 | CONFIG_PPC=y |
12 | CONFIG_PPC32=y | 12 | CONFIG_PPC32=y |
13 | CONFIG_GENERIC_NVRAM=y | 13 | CONFIG_GENERIC_NVRAM=y |
14 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y | ||
14 | 15 | ||
15 | # | 16 | # |
16 | # Code maturity level options | 17 | # Code maturity level options |
@@ -18,6 +19,7 @@ CONFIG_GENERIC_NVRAM=y | |||
18 | CONFIG_EXPERIMENTAL=y | 19 | CONFIG_EXPERIMENTAL=y |
19 | CONFIG_CLEAN_COMPILE=y | 20 | CONFIG_CLEAN_COMPILE=y |
20 | CONFIG_BROKEN_ON_SMP=y | 21 | CONFIG_BROKEN_ON_SMP=y |
22 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
21 | 23 | ||
22 | # | 24 | # |
23 | # General setup | 25 | # General setup |
@@ -29,12 +31,14 @@ CONFIG_SYSVIPC=y | |||
29 | # CONFIG_BSD_PROCESS_ACCT is not set | 31 | # CONFIG_BSD_PROCESS_ACCT is not set |
30 | CONFIG_SYSCTL=y | 32 | CONFIG_SYSCTL=y |
31 | # CONFIG_AUDIT is not set | 33 | # CONFIG_AUDIT is not set |
32 | CONFIG_LOG_BUF_SHIFT=14 | ||
33 | # CONFIG_HOTPLUG is not set | 34 | # CONFIG_HOTPLUG is not set |
34 | CONFIG_KOBJECT_UEVENT=y | 35 | CONFIG_KOBJECT_UEVENT=y |
35 | # CONFIG_IKCONFIG is not set | 36 | # CONFIG_IKCONFIG is not set |
36 | CONFIG_EMBEDDED=y | 37 | CONFIG_EMBEDDED=y |
37 | # CONFIG_KALLSYMS is not set | 38 | # CONFIG_KALLSYMS is not set |
39 | CONFIG_PRINTK=y | ||
40 | CONFIG_BUG=y | ||
41 | CONFIG_BASE_FULL=y | ||
38 | CONFIG_FUTEX=y | 42 | CONFIG_FUTEX=y |
39 | # CONFIG_EPOLL is not set | 43 | # CONFIG_EPOLL is not set |
40 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | 44 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set |
@@ -44,6 +48,7 @@ CONFIG_CC_ALIGN_LABELS=0 | |||
44 | CONFIG_CC_ALIGN_LOOPS=0 | 48 | CONFIG_CC_ALIGN_LOOPS=0 |
45 | CONFIG_CC_ALIGN_JUMPS=0 | 49 | CONFIG_CC_ALIGN_JUMPS=0 |
46 | # CONFIG_TINY_SHMEM is not set | 50 | # CONFIG_TINY_SHMEM is not set |
51 | CONFIG_BASE_SMALL=0 | ||
47 | 52 | ||
48 | # | 53 | # |
49 | # Loadable module support | 54 | # Loadable module support |
@@ -62,10 +67,12 @@ CONFIG_CC_ALIGN_JUMPS=0 | |||
62 | CONFIG_E500=y | 67 | CONFIG_E500=y |
63 | CONFIG_BOOKE=y | 68 | CONFIG_BOOKE=y |
64 | CONFIG_FSL_BOOKE=y | 69 | CONFIG_FSL_BOOKE=y |
70 | # CONFIG_PHYS_64BIT is not set | ||
65 | CONFIG_SPE=y | 71 | CONFIG_SPE=y |
66 | CONFIG_MATH_EMULATION=y | 72 | CONFIG_MATH_EMULATION=y |
67 | # CONFIG_CPU_FREQ is not set | 73 | # CONFIG_CPU_FREQ is not set |
68 | CONFIG_PPC_GEN550=y | 74 | CONFIG_PPC_GEN550=y |
75 | # CONFIG_PM is not set | ||
69 | CONFIG_85xx=y | 76 | CONFIG_85xx=y |
70 | CONFIG_PPC_INDIRECT_PCI_BE=y | 77 | CONFIG_PPC_INDIRECT_PCI_BE=y |
71 | 78 | ||
@@ -76,6 +83,7 @@ CONFIG_PPC_INDIRECT_PCI_BE=y | |||
76 | CONFIG_MPC8555_CDS=y | 83 | CONFIG_MPC8555_CDS=y |
77 | # CONFIG_MPC8560_ADS is not set | 84 | # CONFIG_MPC8560_ADS is not set |
78 | # CONFIG_SBC8560 is not set | 85 | # CONFIG_SBC8560 is not set |
86 | # CONFIG_STX_GP3 is not set | ||
79 | CONFIG_MPC8555=y | 87 | CONFIG_MPC8555=y |
80 | CONFIG_85xx_PCI2=y | 88 | CONFIG_85xx_PCI2=y |
81 | 89 | ||
@@ -90,6 +98,7 @@ CONFIG_CPM2=y | |||
90 | CONFIG_BINFMT_ELF=y | 98 | CONFIG_BINFMT_ELF=y |
91 | # CONFIG_BINFMT_MISC is not set | 99 | # CONFIG_BINFMT_MISC is not set |
92 | # CONFIG_CMDLINE_BOOL is not set | 100 | # CONFIG_CMDLINE_BOOL is not set |
101 | CONFIG_ISA_DMA_API=y | ||
93 | 102 | ||
94 | # | 103 | # |
95 | # Bus options | 104 | # Bus options |
@@ -105,10 +114,6 @@ CONFIG_PCI_NAMES=y | |||
105 | # CONFIG_PCCARD is not set | 114 | # CONFIG_PCCARD is not set |
106 | 115 | ||
107 | # | 116 | # |
108 | # PC-card bridges | ||
109 | # | ||
110 | |||
111 | # | ||
112 | # Advanced setup | 117 | # Advanced setup |
113 | # | 118 | # |
114 | # CONFIG_ADVANCED_OPTIONS is not set | 119 | # CONFIG_ADVANCED_OPTIONS is not set |
@@ -180,7 +185,59 @@ CONFIG_IOSCHED_CFQ=y | |||
180 | # | 185 | # |
181 | # ATA/ATAPI/MFM/RLL support | 186 | # ATA/ATAPI/MFM/RLL support |
182 | # | 187 | # |
183 | # CONFIG_IDE is not set | 188 | CONFIG_IDE=y |
189 | CONFIG_BLK_DEV_IDE=y | ||
190 | |||
191 | # | ||
192 | # Please see Documentation/ide.txt for help/info on IDE drives | ||
193 | # | ||
194 | # CONFIG_BLK_DEV_IDE_SATA is not set | ||
195 | CONFIG_BLK_DEV_IDEDISK=y | ||
196 | # CONFIG_IDEDISK_MULTI_MODE is not set | ||
197 | # CONFIG_BLK_DEV_IDECD is not set | ||
198 | # CONFIG_BLK_DEV_IDETAPE is not set | ||
199 | # CONFIG_BLK_DEV_IDEFLOPPY is not set | ||
200 | # CONFIG_IDE_TASK_IOCTL is not set | ||
201 | |||
202 | # | ||
203 | # IDE chipset support/bugfixes | ||
204 | # | ||
205 | CONFIG_IDE_GENERIC=y | ||
206 | CONFIG_BLK_DEV_IDEPCI=y | ||
207 | CONFIG_IDEPCI_SHARE_IRQ=y | ||
208 | # CONFIG_BLK_DEV_OFFBOARD is not set | ||
209 | CONFIG_BLK_DEV_GENERIC=y | ||
210 | # CONFIG_BLK_DEV_OPTI621 is not set | ||
211 | # CONFIG_BLK_DEV_SL82C105 is not set | ||
212 | CONFIG_BLK_DEV_IDEDMA_PCI=y | ||
213 | # CONFIG_BLK_DEV_IDEDMA_FORCED is not set | ||
214 | CONFIG_IDEDMA_PCI_AUTO=y | ||
215 | # CONFIG_IDEDMA_ONLYDISK is not set | ||
216 | # CONFIG_BLK_DEV_AEC62XX is not set | ||
217 | # CONFIG_BLK_DEV_ALI15X3 is not set | ||
218 | # CONFIG_BLK_DEV_AMD74XX is not set | ||
219 | # CONFIG_BLK_DEV_CMD64X is not set | ||
220 | # CONFIG_BLK_DEV_TRIFLEX is not set | ||
221 | # CONFIG_BLK_DEV_CY82C693 is not set | ||
222 | # CONFIG_BLK_DEV_CS5520 is not set | ||
223 | # CONFIG_BLK_DEV_CS5530 is not set | ||
224 | # CONFIG_BLK_DEV_HPT34X is not set | ||
225 | # CONFIG_BLK_DEV_HPT366 is not set | ||
226 | # CONFIG_BLK_DEV_SC1200 is not set | ||
227 | # CONFIG_BLK_DEV_PIIX is not set | ||
228 | # CONFIG_BLK_DEV_NS87415 is not set | ||
229 | # CONFIG_BLK_DEV_PDC202XX_OLD is not set | ||
230 | # CONFIG_BLK_DEV_PDC202XX_NEW is not set | ||
231 | # CONFIG_BLK_DEV_SVWKS is not set | ||
232 | # CONFIG_BLK_DEV_SIIMAGE is not set | ||
233 | # CONFIG_BLK_DEV_SLC90E66 is not set | ||
234 | # CONFIG_BLK_DEV_TRM290 is not set | ||
235 | CONFIG_BLK_DEV_VIA82CXXX=y | ||
236 | # CONFIG_IDE_ARM is not set | ||
237 | CONFIG_BLK_DEV_IDEDMA=y | ||
238 | # CONFIG_IDEDMA_IVB is not set | ||
239 | CONFIG_IDEDMA_AUTO=y | ||
240 | # CONFIG_BLK_DEV_HD is not set | ||
184 | 241 | ||
185 | # | 242 | # |
186 | # SCSI device support | 243 | # SCSI device support |
@@ -220,7 +277,6 @@ CONFIG_NET=y | |||
220 | # | 277 | # |
221 | CONFIG_PACKET=y | 278 | CONFIG_PACKET=y |
222 | # CONFIG_PACKET_MMAP is not set | 279 | # CONFIG_PACKET_MMAP is not set |
223 | # CONFIG_NETLINK_DEV is not set | ||
224 | CONFIG_UNIX=y | 280 | CONFIG_UNIX=y |
225 | # CONFIG_NET_KEY is not set | 281 | # CONFIG_NET_KEY is not set |
226 | CONFIG_INET=y | 282 | CONFIG_INET=y |
@@ -370,14 +426,6 @@ CONFIG_INPUT=y | |||
370 | # CONFIG_INPUT_EVBUG is not set | 426 | # CONFIG_INPUT_EVBUG is not set |
371 | 427 | ||
372 | # | 428 | # |
373 | # Input I/O drivers | ||
374 | # | ||
375 | # CONFIG_GAMEPORT is not set | ||
376 | CONFIG_SOUND_GAMEPORT=y | ||
377 | # CONFIG_SERIO is not set | ||
378 | # CONFIG_SERIO_I8042 is not set | ||
379 | |||
380 | # | ||
381 | # Input Device Drivers | 429 | # Input Device Drivers |
382 | # | 430 | # |
383 | # CONFIG_INPUT_KEYBOARD is not set | 431 | # CONFIG_INPUT_KEYBOARD is not set |
@@ -387,6 +435,13 @@ CONFIG_SOUND_GAMEPORT=y | |||
387 | # CONFIG_INPUT_MISC is not set | 435 | # CONFIG_INPUT_MISC is not set |
388 | 436 | ||
389 | # | 437 | # |
438 | # Hardware I/O ports | ||
439 | # | ||
440 | # CONFIG_SERIO is not set | ||
441 | # CONFIG_GAMEPORT is not set | ||
442 | CONFIG_SOUND_GAMEPORT=y | ||
443 | |||
444 | # | ||
390 | # Character devices | 445 | # Character devices |
391 | # | 446 | # |
392 | # CONFIG_VT is not set | 447 | # CONFIG_VT is not set |
@@ -406,6 +461,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4 | |||
406 | CONFIG_SERIAL_CORE=y | 461 | CONFIG_SERIAL_CORE=y |
407 | CONFIG_SERIAL_CORE_CONSOLE=y | 462 | CONFIG_SERIAL_CORE_CONSOLE=y |
408 | # CONFIG_SERIAL_CPM is not set | 463 | # CONFIG_SERIAL_CPM is not set |
464 | # CONFIG_SERIAL_JSM is not set | ||
409 | CONFIG_UNIX98_PTYS=y | 465 | CONFIG_UNIX98_PTYS=y |
410 | CONFIG_LEGACY_PTYS=y | 466 | CONFIG_LEGACY_PTYS=y |
411 | CONFIG_LEGACY_PTY_COUNT=256 | 467 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -434,6 +490,11 @@ CONFIG_GEN_RTC=y | |||
434 | # CONFIG_RAW_DRIVER is not set | 490 | # CONFIG_RAW_DRIVER is not set |
435 | 491 | ||
436 | # | 492 | # |
493 | # TPM devices | ||
494 | # | ||
495 | # CONFIG_TCG_TPM is not set | ||
496 | |||
497 | # | ||
437 | # I2C support | 498 | # I2C support |
438 | # | 499 | # |
439 | CONFIG_I2C=y | 500 | CONFIG_I2C=y |
@@ -456,11 +517,11 @@ CONFIG_I2C_CHARDEV=y | |||
456 | # CONFIG_I2C_AMD8111 is not set | 517 | # CONFIG_I2C_AMD8111 is not set |
457 | # CONFIG_I2C_I801 is not set | 518 | # CONFIG_I2C_I801 is not set |
458 | # CONFIG_I2C_I810 is not set | 519 | # CONFIG_I2C_I810 is not set |
520 | # CONFIG_I2C_PIIX4 is not set | ||
459 | # CONFIG_I2C_ISA is not set | 521 | # CONFIG_I2C_ISA is not set |
460 | CONFIG_I2C_MPC=y | 522 | CONFIG_I2C_MPC=y |
461 | # CONFIG_I2C_NFORCE2 is not set | 523 | # CONFIG_I2C_NFORCE2 is not set |
462 | # CONFIG_I2C_PARPORT_LIGHT is not set | 524 | # CONFIG_I2C_PARPORT_LIGHT is not set |
463 | # CONFIG_I2C_PIIX4 is not set | ||
464 | # CONFIG_I2C_PROSAVAGE is not set | 525 | # CONFIG_I2C_PROSAVAGE is not set |
465 | # CONFIG_I2C_SAVAGE4 is not set | 526 | # CONFIG_I2C_SAVAGE4 is not set |
466 | # CONFIG_SCx200_ACB is not set | 527 | # CONFIG_SCx200_ACB is not set |
@@ -483,7 +544,9 @@ CONFIG_I2C_MPC=y | |||
483 | # CONFIG_SENSORS_ASB100 is not set | 544 | # CONFIG_SENSORS_ASB100 is not set |
484 | # CONFIG_SENSORS_DS1621 is not set | 545 | # CONFIG_SENSORS_DS1621 is not set |
485 | # CONFIG_SENSORS_FSCHER is not set | 546 | # CONFIG_SENSORS_FSCHER is not set |
547 | # CONFIG_SENSORS_FSCPOS is not set | ||
486 | # CONFIG_SENSORS_GL518SM is not set | 548 | # CONFIG_SENSORS_GL518SM is not set |
549 | # CONFIG_SENSORS_GL520SM is not set | ||
487 | # CONFIG_SENSORS_IT87 is not set | 550 | # CONFIG_SENSORS_IT87 is not set |
488 | # CONFIG_SENSORS_LM63 is not set | 551 | # CONFIG_SENSORS_LM63 is not set |
489 | # CONFIG_SENSORS_LM75 is not set | 552 | # CONFIG_SENSORS_LM75 is not set |
@@ -494,9 +557,11 @@ CONFIG_I2C_MPC=y | |||
494 | # CONFIG_SENSORS_LM85 is not set | 557 | # CONFIG_SENSORS_LM85 is not set |
495 | # CONFIG_SENSORS_LM87 is not set | 558 | # CONFIG_SENSORS_LM87 is not set |
496 | # CONFIG_SENSORS_LM90 is not set | 559 | # CONFIG_SENSORS_LM90 is not set |
560 | # CONFIG_SENSORS_LM92 is not set | ||
497 | # CONFIG_SENSORS_MAX1619 is not set | 561 | # CONFIG_SENSORS_MAX1619 is not set |
498 | # CONFIG_SENSORS_PC87360 is not set | 562 | # CONFIG_SENSORS_PC87360 is not set |
499 | # CONFIG_SENSORS_SMSC47B397 is not set | 563 | # CONFIG_SENSORS_SMSC47B397 is not set |
564 | # CONFIG_SENSORS_SIS5595 is not set | ||
500 | # CONFIG_SENSORS_SMSC47M1 is not set | 565 | # CONFIG_SENSORS_SMSC47M1 is not set |
501 | # CONFIG_SENSORS_VIA686A is not set | 566 | # CONFIG_SENSORS_VIA686A is not set |
502 | # CONFIG_SENSORS_W83781D is not set | 567 | # CONFIG_SENSORS_W83781D is not set |
@@ -506,10 +571,12 @@ CONFIG_I2C_MPC=y | |||
506 | # | 571 | # |
507 | # Other I2C Chip support | 572 | # Other I2C Chip support |
508 | # | 573 | # |
574 | # CONFIG_SENSORS_DS1337 is not set | ||
509 | # CONFIG_SENSORS_EEPROM is not set | 575 | # CONFIG_SENSORS_EEPROM is not set |
510 | # CONFIG_SENSORS_PCF8574 is not set | 576 | # CONFIG_SENSORS_PCF8574 is not set |
511 | # CONFIG_SENSORS_PCF8591 is not set | 577 | # CONFIG_SENSORS_PCF8591 is not set |
512 | # CONFIG_SENSORS_RTC8564 is not set | 578 | # CONFIG_SENSORS_RTC8564 is not set |
579 | # CONFIG_SENSORS_M41T00 is not set | ||
513 | # CONFIG_I2C_DEBUG_CORE is not set | 580 | # CONFIG_I2C_DEBUG_CORE is not set |
514 | # CONFIG_I2C_DEBUG_ALGO is not set | 581 | # CONFIG_I2C_DEBUG_ALGO is not set |
515 | # CONFIG_I2C_DEBUG_BUS is not set | 582 | # CONFIG_I2C_DEBUG_BUS is not set |
@@ -538,7 +605,6 @@ CONFIG_I2C_MPC=y | |||
538 | # Graphics support | 605 | # Graphics support |
539 | # | 606 | # |
540 | # CONFIG_FB is not set | 607 | # CONFIG_FB is not set |
541 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | ||
542 | 608 | ||
543 | # | 609 | # |
544 | # Sound | 610 | # Sound |
@@ -548,13 +614,9 @@ CONFIG_I2C_MPC=y | |||
548 | # | 614 | # |
549 | # USB support | 615 | # USB support |
550 | # | 616 | # |
551 | # CONFIG_USB is not set | ||
552 | CONFIG_USB_ARCH_HAS_HCD=y | 617 | CONFIG_USB_ARCH_HAS_HCD=y |
553 | CONFIG_USB_ARCH_HAS_OHCI=y | 618 | CONFIG_USB_ARCH_HAS_OHCI=y |
554 | 619 | # CONFIG_USB is not set | |
555 | # | ||
556 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information | ||
557 | # | ||
558 | 620 | ||
559 | # | 621 | # |
560 | # USB Gadget Support | 622 | # USB Gadget Support |
@@ -585,6 +647,10 @@ CONFIG_JBD=y | |||
585 | CONFIG_FS_MBCACHE=y | 647 | CONFIG_FS_MBCACHE=y |
586 | # CONFIG_REISERFS_FS is not set | 648 | # CONFIG_REISERFS_FS is not set |
587 | # CONFIG_JFS_FS is not set | 649 | # CONFIG_JFS_FS is not set |
650 | |||
651 | # | ||
652 | # XFS support | ||
653 | # | ||
588 | # CONFIG_XFS_FS is not set | 654 | # CONFIG_XFS_FS is not set |
589 | # CONFIG_MINIX_FS is not set | 655 | # CONFIG_MINIX_FS is not set |
590 | # CONFIG_ROMFS_FS is not set | 656 | # CONFIG_ROMFS_FS is not set |
@@ -646,7 +712,6 @@ CONFIG_NFS_FS=y | |||
646 | # CONFIG_NFSD is not set | 712 | # CONFIG_NFSD is not set |
647 | CONFIG_ROOT_NFS=y | 713 | CONFIG_ROOT_NFS=y |
648 | CONFIG_LOCKD=y | 714 | CONFIG_LOCKD=y |
649 | # CONFIG_EXPORTFS is not set | ||
650 | CONFIG_SUNRPC=y | 715 | CONFIG_SUNRPC=y |
651 | # CONFIG_RPCSEC_GSS_KRB5 is not set | 716 | # CONFIG_RPCSEC_GSS_KRB5 is not set |
652 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | 717 | # CONFIG_RPCSEC_GSS_SPKM3 is not set |
@@ -698,7 +763,9 @@ CONFIG_CRC32=y | |||
698 | # | 763 | # |
699 | # Kernel hacking | 764 | # Kernel hacking |
700 | # | 765 | # |
766 | # CONFIG_PRINTK_TIME is not set | ||
701 | # CONFIG_DEBUG_KERNEL is not set | 767 | # CONFIG_DEBUG_KERNEL is not set |
768 | CONFIG_LOG_BUF_SHIFT=14 | ||
702 | # CONFIG_KGDB_CONSOLE is not set | 769 | # CONFIG_KGDB_CONSOLE is not set |
703 | # CONFIG_SERIAL_TEXT_DEBUG is not set | 770 | # CONFIG_SERIAL_TEXT_DEBUG is not set |
704 | 771 | ||
diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c index 8aa5e8c69009..d44b7dc5390a 100644 --- a/arch/ppc/kernel/cputable.c +++ b/arch/ppc/kernel/cputable.c | |||
@@ -838,6 +838,17 @@ struct cpu_spec cpu_specs[] = { | |||
838 | .icache_bsize = 32, | 838 | .icache_bsize = 32, |
839 | .dcache_bsize = 32, | 839 | .dcache_bsize = 32, |
840 | }, | 840 | }, |
841 | { /* 405EP */ | ||
842 | .pvr_mask = 0xffff0000, | ||
843 | .pvr_value = 0x51210000, | ||
844 | .cpu_name = "405EP", | ||
845 | .cpu_features = CPU_FTR_SPLIT_ID_CACHE | | ||
846 | CPU_FTR_USE_TB, | ||
847 | .cpu_user_features = PPC_FEATURE_32 | | ||
848 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | ||
849 | .icache_bsize = 32, | ||
850 | .dcache_bsize = 32, | ||
851 | }, | ||
841 | 852 | ||
842 | #endif /* CONFIG_40x */ | 853 | #endif /* CONFIG_40x */ |
843 | #ifdef CONFIG_44x | 854 | #ifdef CONFIG_44x |
diff --git a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S index 9b6a8e513657..6c7ae6052464 100644 --- a/arch/ppc/kernel/head_44x.S +++ b/arch/ppc/kernel/head_44x.S | |||
@@ -330,8 +330,9 @@ interrupt_base: | |||
330 | /* If we are faulting a kernel address, we have to use the | 330 | /* If we are faulting a kernel address, we have to use the |
331 | * kernel page tables. | 331 | * kernel page tables. |
332 | */ | 332 | */ |
333 | andis. r11, r10, 0x8000 | 333 | lis r11, TASK_SIZE@h |
334 | beq 3f | 334 | cmplw r10, r11 |
335 | blt+ 3f | ||
335 | lis r11, swapper_pg_dir@h | 336 | lis r11, swapper_pg_dir@h |
336 | ori r11, r11, swapper_pg_dir@l | 337 | ori r11, r11, swapper_pg_dir@l |
337 | 338 | ||
@@ -464,8 +465,9 @@ interrupt_base: | |||
464 | /* If we are faulting a kernel address, we have to use the | 465 | /* If we are faulting a kernel address, we have to use the |
465 | * kernel page tables. | 466 | * kernel page tables. |
466 | */ | 467 | */ |
467 | andis. r11, r10, 0x8000 | 468 | lis r11, TASK_SIZE@h |
468 | beq 3f | 469 | cmplw r10, r11 |
470 | blt+ 3f | ||
469 | lis r11, swapper_pg_dir@h | 471 | lis r11, swapper_pg_dir@h |
470 | ori r11, r11, swapper_pg_dir@l | 472 | ori r11, r11, swapper_pg_dir@l |
471 | 473 | ||
@@ -533,8 +535,9 @@ interrupt_base: | |||
533 | /* If we are faulting a kernel address, we have to use the | 535 | /* If we are faulting a kernel address, we have to use the |
534 | * kernel page tables. | 536 | * kernel page tables. |
535 | */ | 537 | */ |
536 | andis. r11, r10, 0x8000 | 538 | lis r11, TASK_SIZE@h |
537 | beq 3f | 539 | cmplw r10, r11 |
540 | blt+ 3f | ||
538 | lis r11, swapper_pg_dir@h | 541 | lis r11, swapper_pg_dir@h |
539 | ori r11, r11, swapper_pg_dir@l | 542 | ori r11, r11, swapper_pg_dir@l |
540 | 543 | ||
diff --git a/arch/ppc/kernel/head_fsl_booke.S b/arch/ppc/kernel/head_fsl_booke.S index f22ddce36135..ce36e88ba627 100644 --- a/arch/ppc/kernel/head_fsl_booke.S +++ b/arch/ppc/kernel/head_fsl_booke.S | |||
@@ -232,7 +232,8 @@ skpinv: addi r6,r6,1 /* Increment */ | |||
232 | tlbwe | 232 | tlbwe |
233 | 233 | ||
234 | /* 7. Jump to KERNELBASE mapping */ | 234 | /* 7. Jump to KERNELBASE mapping */ |
235 | li r7,0 | 235 | lis r7,MSR_KERNEL@h |
236 | ori r7,r7,MSR_KERNEL@l | ||
236 | bl 1f /* Find our address */ | 237 | bl 1f /* Find our address */ |
237 | 1: mflr r9 | 238 | 1: mflr r9 |
238 | rlwimi r6,r9,0,20,31 | 239 | rlwimi r6,r9,0,20,31 |
@@ -293,6 +294,18 @@ skpinv: addi r6,r6,1 /* Increment */ | |||
293 | mtspr SPRN_HID0, r2 | 294 | mtspr SPRN_HID0, r2 |
294 | #endif | 295 | #endif |
295 | 296 | ||
297 | #if !defined(CONFIG_BDI_SWITCH) | ||
298 | /* | ||
299 | * The Abatron BDI JTAG debugger does not tolerate others | ||
300 | * mucking with the debug registers. | ||
301 | */ | ||
302 | lis r2,DBCR0_IDM@h | ||
303 | mtspr SPRN_DBCR0,r2 | ||
304 | /* clear any residual debug events */ | ||
305 | li r2,-1 | ||
306 | mtspr SPRN_DBSR,r2 | ||
307 | #endif | ||
308 | |||
296 | /* | 309 | /* |
297 | * This is where the main kernel code starts. | 310 | * This is where the main kernel code starts. |
298 | */ | 311 | */ |
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index e4f1615ec13f..7329ef177a18 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S | |||
@@ -619,7 +619,7 @@ _GLOBAL(flush_instruction_cache) | |||
619 | _GLOBAL(flush_icache_range) | 619 | _GLOBAL(flush_icache_range) |
620 | BEGIN_FTR_SECTION | 620 | BEGIN_FTR_SECTION |
621 | blr /* for 601, do nothing */ | 621 | blr /* for 601, do nothing */ |
622 | END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE) | 622 | END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) |
623 | li r5,L1_CACHE_LINE_SIZE-1 | 623 | li r5,L1_CACHE_LINE_SIZE-1 |
624 | andc r3,r3,r5 | 624 | andc r3,r3,r5 |
625 | subf r4,r3,r4 | 625 | subf r4,r3,r4 |
@@ -736,7 +736,7 @@ _GLOBAL(flush_dcache_all) | |||
736 | _GLOBAL(__flush_dcache_icache) | 736 | _GLOBAL(__flush_dcache_icache) |
737 | BEGIN_FTR_SECTION | 737 | BEGIN_FTR_SECTION |
738 | blr /* for 601, do nothing */ | 738 | blr /* for 601, do nothing */ |
739 | END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE) | 739 | END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) |
740 | rlwinm r3,r3,0,0,19 /* Get page base address */ | 740 | rlwinm r3,r3,0,0,19 /* Get page base address */ |
741 | li r4,4096/L1_CACHE_LINE_SIZE /* Number of lines in a page */ | 741 | li r4,4096/L1_CACHE_LINE_SIZE /* Number of lines in a page */ |
742 | mtctr r4 | 742 | mtctr r4 |
@@ -764,7 +764,7 @@ END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE) | |||
764 | _GLOBAL(__flush_dcache_icache_phys) | 764 | _GLOBAL(__flush_dcache_icache_phys) |
765 | BEGIN_FTR_SECTION | 765 | BEGIN_FTR_SECTION |
766 | blr /* for 601, do nothing */ | 766 | blr /* for 601, do nothing */ |
767 | END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE) | 767 | END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) |
768 | mfmsr r10 | 768 | mfmsr r10 |
769 | rlwinm r0,r10,0,28,26 /* clear DR */ | 769 | rlwinm r0,r10,0,28,26 /* clear DR */ |
770 | mtmsr r0 | 770 | mtmsr r0 |
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index e97ce635b99e..5c20266e3b1f 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c | |||
@@ -221,27 +221,26 @@ int show_cpuinfo(struct seq_file *m, void *v) | |||
221 | return err; | 221 | return err; |
222 | } | 222 | } |
223 | 223 | ||
224 | switch (PVR_VER(pvr)) { | 224 | /* If we are a Freescale core do a simple check so |
225 | case 0x0020: /* 403 family */ | 225 | * we dont have to keep adding cases in the future */ |
226 | maj = PVR_MAJ(pvr) + 1; | 226 | if ((PVR_VER(pvr) & 0x8000) == 0x8000) { |
227 | min = PVR_MIN(pvr); | ||
228 | break; | ||
229 | case 0x1008: /* 740P/750P ?? */ | ||
230 | maj = ((pvr >> 8) & 0xFF) - 1; | ||
231 | min = pvr & 0xFF; | ||
232 | break; | ||
233 | case 0x8083: /* e300 */ | ||
234 | maj = PVR_MAJ(pvr); | ||
235 | min = PVR_MIN(pvr); | ||
236 | break; | ||
237 | case 0x8020: /* e500 */ | ||
238 | maj = PVR_MAJ(pvr); | 227 | maj = PVR_MAJ(pvr); |
239 | min = PVR_MIN(pvr); | 228 | min = PVR_MIN(pvr); |
240 | break; | 229 | } else { |
241 | default: | 230 | switch (PVR_VER(pvr)) { |
242 | maj = (pvr >> 8) & 0xFF; | 231 | case 0x0020: /* 403 family */ |
243 | min = pvr & 0xFF; | 232 | maj = PVR_MAJ(pvr) + 1; |
244 | break; | 233 | min = PVR_MIN(pvr); |
234 | break; | ||
235 | case 0x1008: /* 740P/750P ?? */ | ||
236 | maj = ((pvr >> 8) & 0xFF) - 1; | ||
237 | min = pvr & 0xFF; | ||
238 | break; | ||
239 | default: | ||
240 | maj = (pvr >> 8) & 0xFF; | ||
241 | min = pvr & 0xFF; | ||
242 | break; | ||
243 | } | ||
245 | } | 244 | } |
246 | 245 | ||
247 | seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n", | 246 | seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n", |
@@ -500,7 +499,7 @@ static int __init set_preferred_console(void) | |||
500 | { | 499 | { |
501 | struct device_node *prom_stdout; | 500 | struct device_node *prom_stdout; |
502 | char *name; | 501 | char *name; |
503 | int offset; | 502 | int offset = 0; |
504 | 503 | ||
505 | if (of_stdout_device == NULL) | 504 | if (of_stdout_device == NULL) |
506 | return -ENODEV; | 505 | return -ENODEV; |
@@ -754,6 +753,8 @@ void __init setup_arch(char **cmdline_p) | |||
754 | strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); | 753 | strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); |
755 | *cmdline_p = cmd_line; | 754 | *cmdline_p = cmd_line; |
756 | 755 | ||
756 | parse_early_param(); | ||
757 | |||
757 | /* set up the bootmem stuff with available memory */ | 758 | /* set up the bootmem stuff with available memory */ |
758 | do_init_bootmem(); | 759 | do_init_bootmem(); |
759 | if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab); | 760 | if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab); |
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index f8e7e324a173..c65731e8bc65 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c | |||
@@ -408,12 +408,7 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword) | |||
408 | 408 | ||
409 | /* Early out if we are an invalid form of lswx */ | 409 | /* Early out if we are an invalid form of lswx */ |
410 | if ((instword & INST_STRING_MASK) == INST_LSWX) | 410 | if ((instword & INST_STRING_MASK) == INST_LSWX) |
411 | if ((rA >= rT) || (NB_RB >= rT) || (rT == rA) || (rT == NB_RB)) | 411 | if ((rT == rA) || (rT == NB_RB)) |
412 | return -EINVAL; | ||
413 | |||
414 | /* Early out if we are an invalid form of lswi */ | ||
415 | if ((instword & INST_STRING_MASK) == INST_LSWI) | ||
416 | if ((rA >= rT) || (rT == rA)) | ||
417 | return -EINVAL; | 412 | return -EINVAL; |
418 | 413 | ||
419 | EA = (rA == 0) ? 0 : regs->gpr[rA]; | 414 | EA = (rA == 0) ? 0 : regs->gpr[rA]; |
diff --git a/arch/ppc/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S index 0c0e714b84de..9353584fb710 100644 --- a/arch/ppc/kernel/vmlinux.lds.S +++ b/arch/ppc/kernel/vmlinux.lds.S | |||
@@ -145,6 +145,7 @@ SECTIONS | |||
145 | __init_end = .; | 145 | __init_end = .; |
146 | 146 | ||
147 | . = ALIGN(4096); | 147 | . = ALIGN(4096); |
148 | _sextratext = .; | ||
148 | __pmac_begin = .; | 149 | __pmac_begin = .; |
149 | .pmac.text : { *(.pmac.text) } | 150 | .pmac.text : { *(.pmac.text) } |
150 | .pmac.data : { *(.pmac.data) } | 151 | .pmac.data : { *(.pmac.data) } |
@@ -171,6 +172,7 @@ SECTIONS | |||
171 | .openfirmware.data : { *(.openfirmware.data) } | 172 | .openfirmware.data : { *(.openfirmware.data) } |
172 | . = ALIGN(4096); | 173 | . = ALIGN(4096); |
173 | __openfirmware_end = .; | 174 | __openfirmware_end = .; |
175 | _eextratext = .; | ||
174 | 176 | ||
175 | __bss_start = .; | 177 | __bss_start = .; |
176 | .bss : | 178 | .bss : |
diff --git a/arch/ppc/lib/string.S b/arch/ppc/lib/string.S index 8d08a2eb225e..36c9b97fd92a 100644 --- a/arch/ppc/lib/string.S +++ b/arch/ppc/lib/string.S | |||
@@ -446,6 +446,7 @@ _GLOBAL(__copy_tofrom_user) | |||
446 | #ifdef CONFIG_8xx | 446 | #ifdef CONFIG_8xx |
447 | /* Don't use prefetch on 8xx */ | 447 | /* Don't use prefetch on 8xx */ |
448 | mtctr r0 | 448 | mtctr r0 |
449 | li r0,0 | ||
449 | 53: COPY_16_BYTES_WITHEX(0) | 450 | 53: COPY_16_BYTES_WITHEX(0) |
450 | bdnz 53b | 451 | bdnz 53b |
451 | 452 | ||
@@ -564,7 +565,9 @@ _GLOBAL(__copy_tofrom_user) | |||
564 | /* or write fault in cacheline loop */ | 565 | /* or write fault in cacheline loop */ |
565 | 105: li r9,1 | 566 | 105: li r9,1 |
566 | 92: li r3,LG_CACHELINE_BYTES | 567 | 92: li r3,LG_CACHELINE_BYTES |
567 | b 99f | 568 | mfctr r8 |
569 | add r0,r0,r8 | ||
570 | b 106f | ||
568 | /* read fault in final word loop */ | 571 | /* read fault in final word loop */ |
569 | 108: li r9,0 | 572 | 108: li r9,0 |
570 | b 93f | 573 | b 93f |
@@ -585,7 +588,7 @@ _GLOBAL(__copy_tofrom_user) | |||
585 | * r5 + (ctr << r3), and r9 is 0 for read or 1 for write. | 588 | * r5 + (ctr << r3), and r9 is 0 for read or 1 for write. |
586 | */ | 589 | */ |
587 | 99: mfctr r0 | 590 | 99: mfctr r0 |
588 | slw r3,r0,r3 | 591 | 106: slw r3,r0,r3 |
589 | add. r3,r3,r5 | 592 | add. r3,r3,r5 |
590 | beq 120f /* shouldn't happen */ | 593 | beq 120f /* shouldn't happen */ |
591 | cmpwi 0,r9,0 | 594 | cmpwi 0,r9,0 |
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index be02a7fec2b7..363c157e3617 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c | |||
@@ -179,6 +179,7 @@ void free_initmem(void) | |||
179 | if (!have_of) | 179 | if (!have_of) |
180 | FREESEC(openfirmware); | 180 | FREESEC(openfirmware); |
181 | printk("\n"); | 181 | printk("\n"); |
182 | ppc_md.progress = NULL; | ||
182 | #undef FREESEC | 183 | #undef FREESEC |
183 | } | 184 | } |
184 | 185 | ||
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c index b3b0f51979d2..e6348b5a1ddc 100644 --- a/arch/ppc/platforms/83xx/mpc834x_sys.c +++ b/arch/ppc/platforms/83xx/mpc834x_sys.c | |||
@@ -127,7 +127,6 @@ mpc834x_sys_map_io(void) | |||
127 | { | 127 | { |
128 | /* we steal the lowest ioremap addr for virt space */ | 128 | /* we steal the lowest ioremap addr for virt space */ |
129 | io_block_mapping(VIRT_IMMRBAR, immrbar, 1024*1024, _PAGE_IO); | 129 | io_block_mapping(VIRT_IMMRBAR, immrbar, 1024*1024, _PAGE_IO); |
130 | io_block_mapping(BCSR_VIRT_ADDR, BCSR_PHYS_ADDR, BCSR_SIZE, _PAGE_IO); | ||
131 | } | 130 | } |
132 | 131 | ||
133 | int | 132 | int |
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.h b/arch/ppc/platforms/83xx/mpc834x_sys.h index f4d055ae19c1..a2f6e49d7151 100644 --- a/arch/ppc/platforms/83xx/mpc834x_sys.h +++ b/arch/ppc/platforms/83xx/mpc834x_sys.h | |||
@@ -26,9 +26,14 @@ | |||
26 | #define VIRT_IMMRBAR ((uint)0xfe000000) | 26 | #define VIRT_IMMRBAR ((uint)0xfe000000) |
27 | 27 | ||
28 | #define BCSR_PHYS_ADDR ((uint)0xf8000000) | 28 | #define BCSR_PHYS_ADDR ((uint)0xf8000000) |
29 | #define BCSR_VIRT_ADDR ((uint)0xfe100000) | ||
30 | #define BCSR_SIZE ((uint)(32 * 1024)) | 29 | #define BCSR_SIZE ((uint)(32 * 1024)) |
31 | 30 | ||
31 | #define BCSR_MISC_REG2_OFF 0x07 | ||
32 | #define BCSR_MISC_REG2_PORESET 0x01 | ||
33 | |||
34 | #define BCSR_MISC_REG3_OFF 0x08 | ||
35 | #define BCSR_MISC_REG3_CNFLOCK 0x80 | ||
36 | |||
32 | #ifdef CONFIG_PCI | 37 | #ifdef CONFIG_PCI |
33 | /* PCI interrupt controller */ | 38 | /* PCI interrupt controller */ |
34 | #define PIRQA MPC83xx_IRQ_IRQ4 | 39 | #define PIRQA MPC83xx_IRQ_IRQ4 |
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c index 4d857d6d633d..583838ab02d8 100644 --- a/arch/ppc/platforms/85xx/mpc8540_ads.c +++ b/arch/ppc/platforms/85xx/mpc8540_ads.c | |||
@@ -210,6 +210,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | |||
210 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) | 210 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) |
211 | ppc_md.progress = gen550_progress; | 211 | ppc_md.progress = gen550_progress; |
212 | #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ | 212 | #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ |
213 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB) | ||
214 | ppc_md.early_serial_map = mpc85xx_early_serial_map; | ||
215 | #endif /* CONFIG_SERIAL_8250 && CONFIG_KGDB */ | ||
213 | 216 | ||
214 | if (ppc_md.progress) | 217 | if (ppc_md.progress) |
215 | ppc_md.progress("mpc8540ads_init(): exit", 0); | 218 | ppc_md.progress("mpc8540ads_init(): exit", 0); |
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c index 6c020d67ad70..e7cfa498568c 100644 --- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c +++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <asm/machdep.h> | 44 | #include <asm/machdep.h> |
45 | #include <asm/prom.h> | 45 | #include <asm/prom.h> |
46 | #include <asm/open_pic.h> | 46 | #include <asm/open_pic.h> |
47 | #include <asm/i8259.h> | ||
47 | #include <asm/bootinfo.h> | 48 | #include <asm/bootinfo.h> |
48 | #include <asm/pci-bridge.h> | 49 | #include <asm/pci-bridge.h> |
49 | #include <asm/mpc85xx.h> | 50 | #include <asm/mpc85xx.h> |
@@ -181,6 +182,7 @@ void __init | |||
181 | mpc85xx_cds_init_IRQ(void) | 182 | mpc85xx_cds_init_IRQ(void) |
182 | { | 183 | { |
183 | bd_t *binfo = (bd_t *) __res; | 184 | bd_t *binfo = (bd_t *) __res; |
185 | int i; | ||
184 | 186 | ||
185 | /* Determine the Physical Address of the OpenPIC regs */ | 187 | /* Determine the Physical Address of the OpenPIC regs */ |
186 | phys_addr_t OpenPIC_PAddr = binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET; | 188 | phys_addr_t OpenPIC_PAddr = binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET; |
@@ -198,6 +200,15 @@ mpc85xx_cds_init_IRQ(void) | |||
198 | */ | 200 | */ |
199 | openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET); | 201 | openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET); |
200 | 202 | ||
203 | #ifdef CONFIG_PCI | ||
204 | openpic_hookup_cascade(PIRQ0A, "82c59 cascade", i8259_irq); | ||
205 | |||
206 | for (i = 0; i < NUM_8259_INTERRUPTS; i++) | ||
207 | irq_desc[i].handler = &i8259_pic; | ||
208 | |||
209 | i8259_init(0); | ||
210 | #endif | ||
211 | |||
201 | #ifdef CONFIG_CPM2 | 212 | #ifdef CONFIG_CPM2 |
202 | /* Setup CPM2 PIC */ | 213 | /* Setup CPM2 PIC */ |
203 | cpm2_init_IRQ(); | 214 | cpm2_init_IRQ(); |
@@ -231,7 +242,7 @@ mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | |||
231 | * interrupt on slot */ | 242 | * interrupt on slot */ |
232 | { | 243 | { |
233 | { 0, 1, 2, 3 }, /* 16 - PMC */ | 244 | { 0, 1, 2, 3 }, /* 16 - PMC */ |
234 | { 3, 0, 0, 0 }, /* 17 P2P (Tsi320) */ | 245 | { 0, 1, 2, 3 }, /* 17 P2P (Tsi320) */ |
235 | { 0, 1, 2, 3 }, /* 18 - Slot 1 */ | 246 | { 0, 1, 2, 3 }, /* 18 - Slot 1 */ |
236 | { 1, 2, 3, 0 }, /* 19 - Slot 2 */ | 247 | { 1, 2, 3, 0 }, /* 19 - Slot 2 */ |
237 | { 2, 3, 0, 1 }, /* 20 - Slot 3 */ | 248 | { 2, 3, 0, 1 }, /* 20 - Slot 3 */ |
@@ -280,13 +291,135 @@ mpc85xx_exclude_device(u_char bus, u_char devfn) | |||
280 | return PCIBIOS_DEVICE_NOT_FOUND; | 291 | return PCIBIOS_DEVICE_NOT_FOUND; |
281 | #endif | 292 | #endif |
282 | /* We explicitly do not go past the Tundra 320 Bridge */ | 293 | /* We explicitly do not go past the Tundra 320 Bridge */ |
283 | if (bus == 1) | 294 | if ((bus == 1) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL)) |
284 | return PCIBIOS_DEVICE_NOT_FOUND; | 295 | return PCIBIOS_DEVICE_NOT_FOUND; |
285 | if ((bus == 0) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL)) | 296 | if ((bus == 0) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL)) |
286 | return PCIBIOS_DEVICE_NOT_FOUND; | 297 | return PCIBIOS_DEVICE_NOT_FOUND; |
287 | else | 298 | else |
288 | return PCIBIOS_SUCCESSFUL; | 299 | return PCIBIOS_SUCCESSFUL; |
289 | } | 300 | } |
301 | |||
302 | void __init | ||
303 | mpc85xx_cds_enable_via(struct pci_controller *hose) | ||
304 | { | ||
305 | u32 pci_class; | ||
306 | u16 vid, did; | ||
307 | |||
308 | early_read_config_dword(hose, 0, 0x88, PCI_CLASS_REVISION, &pci_class); | ||
309 | if ((pci_class >> 16) != PCI_CLASS_BRIDGE_PCI) | ||
310 | return; | ||
311 | |||
312 | /* Configure P2P so that we can reach bus 1 */ | ||
313 | early_write_config_byte(hose, 0, 0x88, PCI_PRIMARY_BUS, 0); | ||
314 | early_write_config_byte(hose, 0, 0x88, PCI_SECONDARY_BUS, 1); | ||
315 | early_write_config_byte(hose, 0, 0x88, PCI_SUBORDINATE_BUS, 0xff); | ||
316 | |||
317 | early_read_config_word(hose, 1, 0x10, PCI_VENDOR_ID, &vid); | ||
318 | early_read_config_word(hose, 1, 0x10, PCI_DEVICE_ID, &did); | ||
319 | |||
320 | if ((vid != PCI_VENDOR_ID_VIA) || | ||
321 | (did != PCI_DEVICE_ID_VIA_82C686)) | ||
322 | return; | ||
323 | |||
324 | /* Enable USB and IDE functions */ | ||
325 | early_write_config_byte(hose, 1, 0x10, 0x48, 0x08); | ||
326 | } | ||
327 | |||
328 | void __init | ||
329 | mpc85xx_cds_fixup_via(struct pci_controller *hose) | ||
330 | { | ||
331 | u32 pci_class; | ||
332 | u16 vid, did; | ||
333 | |||
334 | early_read_config_dword(hose, 0, 0x88, PCI_CLASS_REVISION, &pci_class); | ||
335 | if ((pci_class >> 16) != PCI_CLASS_BRIDGE_PCI) | ||
336 | return; | ||
337 | |||
338 | /* | ||
339 | * Force the backplane P2P bridge to have a window | ||
340 | * open from 0x00000000-0x00001fff in PCI I/O space. | ||
341 | * This allows legacy I/O (i8259, etc) on the VIA | ||
342 | * southbridge to be accessed. | ||
343 | */ | ||
344 | early_write_config_byte(hose, 0, 0x88, PCI_IO_BASE, 0x00); | ||
345 | early_write_config_word(hose, 0, 0x88, PCI_IO_BASE_UPPER16, 0x0000); | ||
346 | early_write_config_byte(hose, 0, 0x88, PCI_IO_LIMIT, 0x10); | ||
347 | early_write_config_word(hose, 0, 0x88, PCI_IO_LIMIT_UPPER16, 0x0000); | ||
348 | |||
349 | early_read_config_word(hose, 1, 0x10, PCI_VENDOR_ID, &vid); | ||
350 | early_read_config_word(hose, 1, 0x10, PCI_DEVICE_ID, &did); | ||
351 | if ((vid != PCI_VENDOR_ID_VIA) || | ||
352 | (did != PCI_DEVICE_ID_VIA_82C686)) | ||
353 | return; | ||
354 | |||
355 | /* | ||
356 | * Since the P2P window was forced to cover the fixed | ||
357 | * legacy I/O addresses, it is necessary to manually | ||
358 | * place the base addresses for the IDE and USB functions | ||
359 | * within this window. | ||
360 | */ | ||
361 | /* Function 1, IDE */ | ||
362 | early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_0, 0x1ff8); | ||
363 | early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_1, 0x1ff4); | ||
364 | early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_2, 0x1fe8); | ||
365 | early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_3, 0x1fe4); | ||
366 | early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_4, 0x1fd0); | ||
367 | |||
368 | /* Function 2, USB ports 0-1 */ | ||
369 | early_write_config_dword(hose, 1, 0x12, PCI_BASE_ADDRESS_4, 0x1fa0); | ||
370 | |||
371 | /* Function 3, USB ports 2-3 */ | ||
372 | early_write_config_dword(hose, 1, 0x13, PCI_BASE_ADDRESS_4, 0x1f80); | ||
373 | |||
374 | /* Function 5, Power Management */ | ||
375 | early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_0, 0x1e00); | ||
376 | early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_1, 0x1dfc); | ||
377 | early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_2, 0x1df8); | ||
378 | |||
379 | /* Function 6, AC97 Interface */ | ||
380 | early_write_config_dword(hose, 1, 0x16, PCI_BASE_ADDRESS_0, 0x1c00); | ||
381 | } | ||
382 | |||
383 | void __init | ||
384 | mpc85xx_cds_pcibios_fixup(void) | ||
385 | { | ||
386 | struct pci_dev *dev = NULL; | ||
387 | u_char c; | ||
388 | |||
389 | if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, | ||
390 | PCI_DEVICE_ID_VIA_82C586_1, NULL))) { | ||
391 | /* | ||
392 | * U-Boot does not set the enable bits | ||
393 | * for the IDE device. Force them on here. | ||
394 | */ | ||
395 | pci_read_config_byte(dev, 0x40, &c); | ||
396 | c |= 0x03; /* IDE: Chip Enable Bits */ | ||
397 | pci_write_config_byte(dev, 0x40, c); | ||
398 | |||
399 | /* | ||
400 | * Since only primary interface works, force the | ||
401 | * IDE function to standard primary IDE interrupt | ||
402 | * w/ 8259 offset | ||
403 | */ | ||
404 | dev->irq = 14; | ||
405 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); | ||
406 | } | ||
407 | |||
408 | /* | ||
409 | * Force legacy USB interrupt routing | ||
410 | */ | ||
411 | if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, | ||
412 | PCI_DEVICE_ID_VIA_82C586_2, NULL))) { | ||
413 | dev->irq = 10; | ||
414 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 10); | ||
415 | } | ||
416 | |||
417 | if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, | ||
418 | PCI_DEVICE_ID_VIA_82C586_2, dev))) { | ||
419 | dev->irq = 11; | ||
420 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11); | ||
421 | } | ||
422 | } | ||
290 | #endif /* CONFIG_PCI */ | 423 | #endif /* CONFIG_PCI */ |
291 | 424 | ||
292 | TODC_ALLOC(); | 425 | TODC_ALLOC(); |
@@ -328,6 +461,9 @@ mpc85xx_cds_setup_arch(void) | |||
328 | loops_per_jiffy = freq / HZ; | 461 | loops_per_jiffy = freq / HZ; |
329 | 462 | ||
330 | #ifdef CONFIG_PCI | 463 | #ifdef CONFIG_PCI |
464 | /* VIA IDE configuration */ | ||
465 | ppc_md.pcibios_fixup = mpc85xx_cds_pcibios_fixup; | ||
466 | |||
331 | /* setup PCI host bridges */ | 467 | /* setup PCI host bridges */ |
332 | mpc85xx_setup_hose(); | 468 | mpc85xx_setup_hose(); |
333 | #endif | 469 | #endif |
@@ -459,6 +595,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | |||
459 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) | 595 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) |
460 | ppc_md.progress = gen550_progress; | 596 | ppc_md.progress = gen550_progress; |
461 | #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ | 597 | #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ |
598 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB) | ||
599 | ppc_md.early_serial_map = mpc85xx_early_serial_map; | ||
600 | #endif /* CONFIG_SERIAL_8250 && CONFIG_KGDB */ | ||
462 | 601 | ||
463 | if (ppc_md.progress) | 602 | if (ppc_md.progress) |
464 | ppc_md.progress("mpc85xx_cds_init(): exit", 0); | 603 | ppc_md.progress("mpc85xx_cds_init(): exit", 0); |
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.h b/arch/ppc/platforms/85xx/mpc85xx_cds_common.h index 7627d77504bd..12b292c6ae32 100644 --- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.h +++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.h | |||
@@ -77,4 +77,7 @@ | |||
77 | 77 | ||
78 | #define MPC85XX_PCI2_IO_SIZE 0x01000000 | 78 | #define MPC85XX_PCI2_IO_SIZE 0x01000000 |
79 | 79 | ||
80 | #define NR_8259_INTS 16 | ||
81 | #define CPM_IRQ_OFFSET NR_8259_INTS | ||
82 | |||
80 | #endif /* __MACH_MPC85XX_CDS_H__ */ | 83 | #endif /* __MACH_MPC85XX_CDS_H__ */ |
diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c index 9ab05e590c3e..7b9e1543e175 100644 --- a/arch/ppc/platforms/85xx/sbc8560.c +++ b/arch/ppc/platforms/85xx/sbc8560.c | |||
@@ -221,6 +221,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | |||
221 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) | 221 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) |
222 | ppc_md.progress = gen550_progress; | 222 | ppc_md.progress = gen550_progress; |
223 | #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ | 223 | #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ |
224 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB) | ||
225 | ppc_md.early_serial_map = sbc8560_early_serial_map; | ||
226 | #endif /* CONFIG_SERIAL_8250 && CONFIG_KGDB */ | ||
224 | 227 | ||
225 | if (ppc_md.progress) | 228 | if (ppc_md.progress) |
226 | ppc_md.progress("sbc8560_init(): exit", 0); | 229 | ppc_md.progress("sbc8560_init(): exit", 0); |
diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c index f7fb2786cd50..5fdd4f607a40 100644 --- a/arch/ppc/platforms/pmac_cpufreq.c +++ b/arch/ppc/platforms/pmac_cpufreq.c | |||
@@ -83,16 +83,13 @@ static u32 frequency_gpio; | |||
83 | static u32 slew_done_gpio; | 83 | static u32 slew_done_gpio; |
84 | static int no_schedule; | 84 | static int no_schedule; |
85 | static int has_cpu_l2lve; | 85 | static int has_cpu_l2lve; |
86 | 86 | static int is_pmu_based; | |
87 | |||
88 | #define PMAC_CPU_LOW_SPEED 1 | ||
89 | #define PMAC_CPU_HIGH_SPEED 0 | ||
90 | 87 | ||
91 | /* There are only two frequency states for each processor. Values | 88 | /* There are only two frequency states for each processor. Values |
92 | * are in kHz for the time being. | 89 | * are in kHz for the time being. |
93 | */ | 90 | */ |
94 | #define CPUFREQ_HIGH PMAC_CPU_HIGH_SPEED | 91 | #define CPUFREQ_HIGH 0 |
95 | #define CPUFREQ_LOW PMAC_CPU_LOW_SPEED | 92 | #define CPUFREQ_LOW 1 |
96 | 93 | ||
97 | static struct cpufreq_frequency_table pmac_cpu_freqs[] = { | 94 | static struct cpufreq_frequency_table pmac_cpu_freqs[] = { |
98 | {CPUFREQ_HIGH, 0}, | 95 | {CPUFREQ_HIGH, 0}, |
@@ -100,6 +97,11 @@ static struct cpufreq_frequency_table pmac_cpu_freqs[] = { | |||
100 | {0, CPUFREQ_TABLE_END}, | 97 | {0, CPUFREQ_TABLE_END}, |
101 | }; | 98 | }; |
102 | 99 | ||
100 | static struct freq_attr* pmac_cpu_freqs_attr[] = { | ||
101 | &cpufreq_freq_attr_scaling_available_freqs, | ||
102 | NULL, | ||
103 | }; | ||
104 | |||
103 | static inline void local_delay(unsigned long ms) | 105 | static inline void local_delay(unsigned long ms) |
104 | { | 106 | { |
105 | if (no_schedule) | 107 | if (no_schedule) |
@@ -269,6 +271,8 @@ static int __pmac pmu_set_cpu_speed(int low_speed) | |||
269 | #ifdef DEBUG_FREQ | 271 | #ifdef DEBUG_FREQ |
270 | printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1)); | 272 | printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1)); |
271 | #endif | 273 | #endif |
274 | pmu_suspend(); | ||
275 | |||
272 | /* Disable all interrupt sources on openpic */ | 276 | /* Disable all interrupt sources on openpic */ |
273 | pic_prio = openpic_get_priority(); | 277 | pic_prio = openpic_get_priority(); |
274 | openpic_set_priority(0xf); | 278 | openpic_set_priority(0xf); |
@@ -343,6 +347,8 @@ static int __pmac pmu_set_cpu_speed(int low_speed) | |||
343 | debug_calc_bogomips(); | 347 | debug_calc_bogomips(); |
344 | #endif | 348 | #endif |
345 | 349 | ||
350 | pmu_resume(); | ||
351 | |||
346 | preempt_enable(); | 352 | preempt_enable(); |
347 | 353 | ||
348 | return 0; | 354 | return 0; |
@@ -355,7 +361,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify) | |||
355 | static unsigned long prev_l3cr; | 361 | static unsigned long prev_l3cr; |
356 | 362 | ||
357 | freqs.old = cur_freq; | 363 | freqs.old = cur_freq; |
358 | freqs.new = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq; | 364 | freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq; |
359 | freqs.cpu = smp_processor_id(); | 365 | freqs.cpu = smp_processor_id(); |
360 | 366 | ||
361 | if (freqs.old == freqs.new) | 367 | if (freqs.old == freqs.new) |
@@ -363,7 +369,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify) | |||
363 | 369 | ||
364 | if (notify) | 370 | if (notify) |
365 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | 371 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); |
366 | if (speed_mode == PMAC_CPU_LOW_SPEED && | 372 | if (speed_mode == CPUFREQ_LOW && |
367 | cpu_has_feature(CPU_FTR_L3CR)) { | 373 | cpu_has_feature(CPU_FTR_L3CR)) { |
368 | l3cr = _get_L3CR(); | 374 | l3cr = _get_L3CR(); |
369 | if (l3cr & L3CR_L3E) { | 375 | if (l3cr & L3CR_L3E) { |
@@ -371,8 +377,8 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify) | |||
371 | _set_L3CR(0); | 377 | _set_L3CR(0); |
372 | } | 378 | } |
373 | } | 379 | } |
374 | set_speed_proc(speed_mode == PMAC_CPU_LOW_SPEED); | 380 | set_speed_proc(speed_mode == CPUFREQ_LOW); |
375 | if (speed_mode == PMAC_CPU_HIGH_SPEED && | 381 | if (speed_mode == CPUFREQ_HIGH && |
376 | cpu_has_feature(CPU_FTR_L3CR)) { | 382 | cpu_has_feature(CPU_FTR_L3CR)) { |
377 | l3cr = _get_L3CR(); | 383 | l3cr = _get_L3CR(); |
378 | if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr) | 384 | if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr) |
@@ -380,7 +386,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify) | |||
380 | } | 386 | } |
381 | if (notify) | 387 | if (notify) |
382 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | 388 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); |
383 | cur_freq = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq; | 389 | cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq; |
384 | 390 | ||
385 | return 0; | 391 | return 0; |
386 | } | 392 | } |
@@ -423,7 +429,8 @@ static int __pmac pmac_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
423 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | 429 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; |
424 | policy->cur = cur_freq; | 430 | policy->cur = cur_freq; |
425 | 431 | ||
426 | return cpufreq_frequency_table_cpuinfo(policy, &pmac_cpu_freqs[0]); | 432 | cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu); |
433 | return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs); | ||
427 | } | 434 | } |
428 | 435 | ||
429 | static u32 __pmac read_gpio(struct device_node *np) | 436 | static u32 __pmac read_gpio(struct device_node *np) |
@@ -456,8 +463,8 @@ static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, u32 state) | |||
456 | */ | 463 | */ |
457 | no_schedule = 1; | 464 | no_schedule = 1; |
458 | sleep_freq = cur_freq; | 465 | sleep_freq = cur_freq; |
459 | if (cur_freq == low_freq) | 466 | if (cur_freq == low_freq && !is_pmu_based) |
460 | do_set_cpu_speed(PMAC_CPU_HIGH_SPEED, 0); | 467 | do_set_cpu_speed(CPUFREQ_HIGH, 0); |
461 | return 0; | 468 | return 0; |
462 | } | 469 | } |
463 | 470 | ||
@@ -473,8 +480,8 @@ static int __pmac pmac_cpufreq_resume(struct cpufreq_policy *policy) | |||
473 | * is that we force a switch to whatever it was, which is | 480 | * is that we force a switch to whatever it was, which is |
474 | * probably high speed due to our suspend() routine | 481 | * probably high speed due to our suspend() routine |
475 | */ | 482 | */ |
476 | do_set_cpu_speed(sleep_freq == low_freq ? PMAC_CPU_LOW_SPEED | 483 | do_set_cpu_speed(sleep_freq == low_freq ? |
477 | : PMAC_CPU_HIGH_SPEED, 0); | 484 | CPUFREQ_LOW : CPUFREQ_HIGH, 0); |
478 | 485 | ||
479 | no_schedule = 0; | 486 | no_schedule = 0; |
480 | return 0; | 487 | return 0; |
@@ -488,6 +495,7 @@ static struct cpufreq_driver pmac_cpufreq_driver = { | |||
488 | .suspend = pmac_cpufreq_suspend, | 495 | .suspend = pmac_cpufreq_suspend, |
489 | .resume = pmac_cpufreq_resume, | 496 | .resume = pmac_cpufreq_resume, |
490 | .flags = CPUFREQ_PM_NO_WARN, | 497 | .flags = CPUFREQ_PM_NO_WARN, |
498 | .attr = pmac_cpu_freqs_attr, | ||
491 | .name = "powermac", | 499 | .name = "powermac", |
492 | .owner = THIS_MODULE, | 500 | .owner = THIS_MODULE, |
493 | }; | 501 | }; |
@@ -580,6 +588,7 @@ static int __pmac pmac_cpufreq_init_MacRISC3(struct device_node *cpunode) | |||
580 | return 1; | 588 | return 1; |
581 | hi_freq = (*value) / 1000; | 589 | hi_freq = (*value) / 1000; |
582 | set_speed_proc = pmu_set_cpu_speed; | 590 | set_speed_proc = pmu_set_cpu_speed; |
591 | is_pmu_based = 1; | ||
583 | 592 | ||
584 | return 0; | 593 | return 0; |
585 | } | 594 | } |
@@ -684,6 +693,7 @@ static int __init pmac_cpufreq_setup(void) | |||
684 | hi_freq = cur_freq; | 693 | hi_freq = cur_freq; |
685 | low_freq = 400000; | 694 | low_freq = 400000; |
686 | set_speed_proc = pmu_set_cpu_speed; | 695 | set_speed_proc = pmu_set_cpu_speed; |
696 | is_pmu_based = 1; | ||
687 | } | 697 | } |
688 | /* Else check for TiPb 400 & 500 */ | 698 | /* Else check for TiPb 400 & 500 */ |
689 | else if (machine_is_compatible("PowerBook3,2")) { | 699 | else if (machine_is_compatible("PowerBook3,2")) { |
@@ -695,6 +705,7 @@ static int __init pmac_cpufreq_setup(void) | |||
695 | hi_freq = cur_freq; | 705 | hi_freq = cur_freq; |
696 | low_freq = 300000; | 706 | low_freq = 300000; |
697 | set_speed_proc = pmu_set_cpu_speed; | 707 | set_speed_proc = pmu_set_cpu_speed; |
708 | is_pmu_based = 1; | ||
698 | } | 709 | } |
699 | /* Else check for 750FX */ | 710 | /* Else check for 750FX */ |
700 | else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000) | 711 | else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000) |
diff --git a/arch/ppc/platforms/pq2ads.h b/arch/ppc/platforms/pq2ads.h index cf5e5dd06d63..067d9a5aebc1 100644 --- a/arch/ppc/platforms/pq2ads.h +++ b/arch/ppc/platforms/pq2ads.h | |||
@@ -49,10 +49,10 @@ | |||
49 | /* PCI interrupt controller */ | 49 | /* PCI interrupt controller */ |
50 | #define PCI_INT_STAT_REG 0xF8200000 | 50 | #define PCI_INT_STAT_REG 0xF8200000 |
51 | #define PCI_INT_MASK_REG 0xF8200004 | 51 | #define PCI_INT_MASK_REG 0xF8200004 |
52 | #define PIRQA (NR_SIU_INTS + 0) | 52 | #define PIRQA (NR_CPM_INTS + 0) |
53 | #define PIRQB (NR_SIU_INTS + 1) | 53 | #define PIRQB (NR_CPM_INTS + 1) |
54 | #define PIRQC (NR_SIU_INTS + 2) | 54 | #define PIRQC (NR_CPM_INTS + 2) |
55 | #define PIRQD (NR_SIU_INTS + 3) | 55 | #define PIRQD (NR_CPM_INTS + 3) |
56 | 56 | ||
57 | /* | 57 | /* |
58 | * PCI memory map definitions for MPC8266ADS-PCI. | 58 | * PCI memory map definitions for MPC8266ADS-PCI. |
@@ -68,28 +68,23 @@ | |||
68 | * 0x00000000-0x1FFFFFFF 0x00000000-0x1FFFFFFF MPC8266 local memory | 68 | * 0x00000000-0x1FFFFFFF 0x00000000-0x1FFFFFFF MPC8266 local memory |
69 | */ | 69 | */ |
70 | 70 | ||
71 | /* window for a PCI master to access MPC8266 memory */ | 71 | /* All the other PCI memory map definitions reside at syslib/m82xx_pci.h |
72 | #define PCI_SLV_MEM_LOCAL 0x00000000 /* Local base */ | 72 | Here we should redefine what is unique for this board */ |
73 | #define PCI_SLV_MEM_BUS 0x00000000 /* PCI base */ | 73 | #define M82xx_PCI_SLAVE_MEM_LOCAL 0x00000000 /* Local base */ |
74 | #define M82xx_PCI_SLAVE_MEM_BUS 0x00000000 /* PCI base */ | ||
75 | #define M82xx_PCI_SLAVE_MEM_SIZE 0x10000000 /* 256 Mb */ | ||
74 | 76 | ||
75 | /* window for the processor to access PCI memory with prefetching */ | 77 | #define M82xx_PCI_SLAVE_SEC_WND_SIZE ~(0x40000000 - 1U) /* 2 x 512Mb */ |
76 | #define PCI_MSTR_MEM_LOCAL 0x80000000 /* Local base */ | 78 | #define M82xx_PCI_SLAVE_SEC_WND_BASE 0x80000000 /* PCI Memory base */ |
77 | #define PCI_MSTR_MEM_BUS 0x80000000 /* PCI base */ | ||
78 | #define PCI_MSTR_MEM_SIZE 0x20000000 /* 512MB */ | ||
79 | 79 | ||
80 | /* window for the processor to access PCI memory without prefetching */ | 80 | #if defined(CONFIG_ADS8272) |
81 | #define PCI_MSTR_MEMIO_LOCAL 0xA0000000 /* Local base */ | 81 | #define PCI_INT_TO_SIU SIU_INT_IRQ2 |
82 | #define PCI_MSTR_MEMIO_BUS 0xA0000000 /* PCI base */ | 82 | #elif defined(CONFIG_PQ2FADS) |
83 | #define PCI_MSTR_MEMIO_SIZE 0x20000000 /* 512MB */ | 83 | #define PCI_INT_TO_SIU SIU_INT_IRQ6 |
84 | #else | ||
85 | #warning PCI Bridge will be without interrupts support | ||
86 | #endif | ||
84 | 87 | ||
85 | /* window for the processor to access PCI I/O */ | ||
86 | #define PCI_MSTR_IO_LOCAL 0xF4000000 /* Local base */ | ||
87 | #define PCI_MSTR_IO_BUS 0x00000000 /* PCI base */ | ||
88 | #define PCI_MSTR_IO_SIZE 0x04000000 /* 64MB */ | ||
89 | |||
90 | #define _IO_BASE PCI_MSTR_IO_LOCAL | ||
91 | #define _ISA_MEM_BASE PCI_MSTR_MEMIO_LOCAL | ||
92 | #define PCI_DRAM_OFFSET PCI_SLV_MEM_BUS | ||
93 | #endif /* CONFIG_PCI */ | 88 | #endif /* CONFIG_PCI */ |
94 | 89 | ||
95 | #endif /* __MACH_ADS8260_DEFS */ | 90 | #endif /* __MACH_ADS8260_DEFS */ |
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile index dd418ea3426c..96acf85800d4 100644 --- a/arch/ppc/syslib/Makefile +++ b/arch/ppc/syslib/Makefile | |||
@@ -81,7 +81,7 @@ obj-$(CONFIG_SBC82xx) += todc_time.o | |||
81 | obj-$(CONFIG_SPRUCE) += cpc700_pic.o indirect_pci.o pci_auto.o \ | 81 | obj-$(CONFIG_SPRUCE) += cpc700_pic.o indirect_pci.o pci_auto.o \ |
82 | todc_time.o | 82 | todc_time.o |
83 | obj-$(CONFIG_8260) += m8260_setup.o | 83 | obj-$(CONFIG_8260) += m8260_setup.o |
84 | obj-$(CONFIG_PCI_8260) += m8260_pci.o indirect_pci.o | 84 | obj-$(CONFIG_PCI_8260) += m82xx_pci.o indirect_pci.o pci_auto.o |
85 | obj-$(CONFIG_8260_PCI9) += m8260_pci_erratum9.o | 85 | obj-$(CONFIG_8260_PCI9) += m8260_pci_erratum9.o |
86 | obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o | 86 | obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o |
87 | ifeq ($(CONFIG_PPC_GEN550),y) | 87 | ifeq ($(CONFIG_PPC_GEN550),y) |
@@ -97,7 +97,7 @@ obj-$(CONFIG_MPC10X_OPENPIC) += open_pic.o | |||
97 | obj-$(CONFIG_40x) += dcr.o | 97 | obj-$(CONFIG_40x) += dcr.o |
98 | obj-$(CONFIG_BOOKE) += dcr.o | 98 | obj-$(CONFIG_BOOKE) += dcr.o |
99 | obj-$(CONFIG_85xx) += open_pic.o ppc85xx_common.o ppc85xx_setup.o \ | 99 | obj-$(CONFIG_85xx) += open_pic.o ppc85xx_common.o ppc85xx_setup.o \ |
100 | ppc_sys.o mpc85xx_sys.o \ | 100 | ppc_sys.o i8259.o mpc85xx_sys.o \ |
101 | mpc85xx_devices.o | 101 | mpc85xx_devices.o |
102 | ifeq ($(CONFIG_85xx),y) | 102 | ifeq ($(CONFIG_85xx),y) |
103 | obj-$(CONFIG_PCI) += indirect_pci.o pci_auto.o | 103 | obj-$(CONFIG_PCI) += indirect_pci.o pci_auto.o |
diff --git a/arch/ppc/syslib/ipic.c b/arch/ppc/syslib/ipic.c index acb2cde3171f..580ed658e872 100644 --- a/arch/ppc/syslib/ipic.c +++ b/arch/ppc/syslib/ipic.c | |||
@@ -479,7 +479,7 @@ void __init ipic_init(phys_addr_t phys_addr, | |||
479 | temp = 0; | 479 | temp = 0; |
480 | for (i = 0 ; i < senses_count ; i++) { | 480 | for (i = 0 ; i < senses_count ; i++) { |
481 | if ((senses[i] & IRQ_SENSE_MASK) == IRQ_SENSE_EDGE) { | 481 | if ((senses[i] & IRQ_SENSE_MASK) == IRQ_SENSE_EDGE) { |
482 | temp |= 1 << (16 - i); | 482 | temp |= 1 << (15 - i); |
483 | if (i != 0) | 483 | if (i != 0) |
484 | irq_desc[i + irq_offset + MPC83xx_IRQ_EXT1 - 1].status = 0; | 484 | irq_desc[i + irq_offset + MPC83xx_IRQ_EXT1 - 1].status = 0; |
485 | else | 485 | else |
diff --git a/arch/ppc/syslib/m8260_pci.c b/arch/ppc/syslib/m8260_pci.c deleted file mode 100644 index 057cc3f8ff37..000000000000 --- a/arch/ppc/syslib/m8260_pci.c +++ /dev/null | |||
@@ -1,193 +0,0 @@ | |||
1 | /* | ||
2 | * (C) Copyright 2003 | ||
3 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | ||
4 | * | ||
5 | * (C) Copyright 2004 Red Hat, Inc. | ||
6 | * | ||
7 | * See file CREDITS for list of people who contributed to this | ||
8 | * project. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License as | ||
12 | * published by the Free Software Foundation; either version 2 of | ||
13 | * the License, or (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
23 | * MA 02111-1307 USA | ||
24 | */ | ||
25 | |||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/pci.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/delay.h> | ||
31 | |||
32 | #include <asm/byteorder.h> | ||
33 | #include <asm/io.h> | ||
34 | #include <asm/irq.h> | ||
35 | #include <asm/uaccess.h> | ||
36 | #include <asm/machdep.h> | ||
37 | #include <asm/pci-bridge.h> | ||
38 | #include <asm/immap_cpm2.h> | ||
39 | #include <asm/mpc8260.h> | ||
40 | |||
41 | #include "m8260_pci.h" | ||
42 | |||
43 | |||
44 | /* PCI bus configuration registers. | ||
45 | */ | ||
46 | |||
47 | static void __init m8260_setup_pci(struct pci_controller *hose) | ||
48 | { | ||
49 | volatile cpm2_map_t *immap = cpm2_immr; | ||
50 | unsigned long pocmr; | ||
51 | u16 tempShort; | ||
52 | |||
53 | #ifndef CONFIG_ATC /* already done in U-Boot */ | ||
54 | /* | ||
55 | * Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]), | ||
56 | * and local bus for PCI (SIUMCR [LBPC]). | ||
57 | */ | ||
58 | immap->im_siu_conf.siu_82xx.sc_siumcr = 0x00640000; | ||
59 | #endif | ||
60 | |||
61 | /* Make PCI lowest priority */ | ||
62 | /* Each 4 bits is a device bus request and the MS 4bits | ||
63 | is highest priority */ | ||
64 | /* Bus 4bit value | ||
65 | --- ---------- | ||
66 | CPM high 0b0000 | ||
67 | CPM middle 0b0001 | ||
68 | CPM low 0b0010 | ||
69 | PCI reguest 0b0011 | ||
70 | Reserved 0b0100 | ||
71 | Reserved 0b0101 | ||
72 | Internal Core 0b0110 | ||
73 | External Master 1 0b0111 | ||
74 | External Master 2 0b1000 | ||
75 | External Master 3 0b1001 | ||
76 | The rest are reserved */ | ||
77 | immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x61207893; | ||
78 | |||
79 | /* Park bus on core while modifying PCI Bus accesses */ | ||
80 | immap->im_siu_conf.siu_82xx.sc_ppc_acr = 0x6; | ||
81 | |||
82 | /* | ||
83 | * Set up master window that allows the CPU to access PCI space. This | ||
84 | * window is set up using the first SIU PCIBR registers. | ||
85 | */ | ||
86 | immap->im_memctl.memc_pcimsk0 = MPC826x_PCI_MASK; | ||
87 | immap->im_memctl.memc_pcibr0 = MPC826x_PCI_BASE | PCIBR_ENABLE; | ||
88 | |||
89 | /* Disable machine check on no response or target abort */ | ||
90 | immap->im_pci.pci_emr = cpu_to_le32(0x1fe7); | ||
91 | /* Release PCI RST (by default the PCI RST signal is held low) */ | ||
92 | immap->im_pci.pci_gcr = cpu_to_le32(PCIGCR_PCI_BUS_EN); | ||
93 | |||
94 | /* give it some time */ | ||
95 | mdelay(1); | ||
96 | |||
97 | /* | ||
98 | * Set up master window that allows the CPU to access PCI Memory (prefetch) | ||
99 | * space. This window is set up using the first set of Outbound ATU registers. | ||
100 | */ | ||
101 | immap->im_pci.pci_potar0 = cpu_to_le32(MPC826x_PCI_LOWER_MEM >> 12); | ||
102 | immap->im_pci.pci_pobar0 = cpu_to_le32((MPC826x_PCI_LOWER_MEM - MPC826x_PCI_MEM_OFFSET) >> 12); | ||
103 | pocmr = ((MPC826x_PCI_UPPER_MEM - MPC826x_PCI_LOWER_MEM) >> 12) ^ 0xfffff; | ||
104 | immap->im_pci.pci_pocmr0 = cpu_to_le32(pocmr | POCMR_ENABLE | POCMR_PREFETCH_EN); | ||
105 | |||
106 | /* | ||
107 | * Set up master window that allows the CPU to access PCI Memory (non-prefetch) | ||
108 | * space. This window is set up using the second set of Outbound ATU registers. | ||
109 | */ | ||
110 | immap->im_pci.pci_potar1 = cpu_to_le32(MPC826x_PCI_LOWER_MMIO >> 12); | ||
111 | immap->im_pci.pci_pobar1 = cpu_to_le32((MPC826x_PCI_LOWER_MMIO - MPC826x_PCI_MMIO_OFFSET) >> 12); | ||
112 | pocmr = ((MPC826x_PCI_UPPER_MMIO - MPC826x_PCI_LOWER_MMIO) >> 12) ^ 0xfffff; | ||
113 | immap->im_pci.pci_pocmr1 = cpu_to_le32(pocmr | POCMR_ENABLE); | ||
114 | |||
115 | /* | ||
116 | * Set up master window that allows the CPU to access PCI IO space. This window | ||
117 | * is set up using the third set of Outbound ATU registers. | ||
118 | */ | ||
119 | immap->im_pci.pci_potar2 = cpu_to_le32(MPC826x_PCI_IO_BASE >> 12); | ||
120 | immap->im_pci.pci_pobar2 = cpu_to_le32(MPC826x_PCI_LOWER_IO >> 12); | ||
121 | pocmr = ((MPC826x_PCI_UPPER_IO - MPC826x_PCI_LOWER_IO) >> 12) ^ 0xfffff; | ||
122 | immap->im_pci.pci_pocmr2 = cpu_to_le32(pocmr | POCMR_ENABLE | POCMR_PCI_IO); | ||
123 | |||
124 | /* | ||
125 | * Set up slave window that allows PCI masters to access MPC826x local memory. | ||
126 | * This window is set up using the first set of Inbound ATU registers | ||
127 | */ | ||
128 | |||
129 | immap->im_pci.pci_pitar0 = cpu_to_le32(MPC826x_PCI_SLAVE_MEM_LOCAL >> 12); | ||
130 | immap->im_pci.pci_pibar0 = cpu_to_le32(MPC826x_PCI_SLAVE_MEM_BUS >> 12); | ||
131 | pocmr = ((MPC826x_PCI_SLAVE_MEM_SIZE-1) >> 12) ^ 0xfffff; | ||
132 | immap->im_pci.pci_picmr0 = cpu_to_le32(pocmr | PICMR_ENABLE | PICMR_PREFETCH_EN); | ||
133 | |||
134 | /* See above for description - puts PCI request as highest priority */ | ||
135 | immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x03124567; | ||
136 | |||
137 | /* Park the bus on the PCI */ | ||
138 | immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_PCI; | ||
139 | |||
140 | /* Host mode - specify the bridge as a host-PCI bridge */ | ||
141 | early_write_config_word(hose, 0, 0, PCI_CLASS_DEVICE, PCI_CLASS_BRIDGE_HOST); | ||
142 | |||
143 | /* Enable the host bridge to be a master on the PCI bus, and to act as a PCI memory target */ | ||
144 | early_read_config_word(hose, 0, 0, PCI_COMMAND, &tempShort); | ||
145 | early_write_config_word(hose, 0, 0, PCI_COMMAND, | ||
146 | tempShort | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); | ||
147 | } | ||
148 | |||
149 | void __init m8260_find_bridges(void) | ||
150 | { | ||
151 | extern int pci_assign_all_busses; | ||
152 | struct pci_controller * hose; | ||
153 | |||
154 | pci_assign_all_busses = 1; | ||
155 | |||
156 | hose = pcibios_alloc_controller(); | ||
157 | |||
158 | if (!hose) | ||
159 | return; | ||
160 | |||
161 | ppc_md.pci_swizzle = common_swizzle; | ||
162 | |||
163 | hose->first_busno = 0; | ||
164 | hose->bus_offset = 0; | ||
165 | hose->last_busno = 0xff; | ||
166 | |||
167 | setup_m8260_indirect_pci(hose, | ||
168 | (unsigned long)&cpm2_immr->im_pci.pci_cfg_addr, | ||
169 | (unsigned long)&cpm2_immr->im_pci.pci_cfg_data); | ||
170 | |||
171 | m8260_setup_pci(hose); | ||
172 | hose->pci_mem_offset = MPC826x_PCI_MEM_OFFSET; | ||
173 | |||
174 | hose->io_base_virt = ioremap(MPC826x_PCI_IO_BASE, | ||
175 | MPC826x_PCI_IO_SIZE); | ||
176 | isa_io_base = (unsigned long) hose->io_base_virt; | ||
177 | |||
178 | /* setup resources */ | ||
179 | pci_init_resource(&hose->mem_resources[0], | ||
180 | MPC826x_PCI_LOWER_MEM, | ||
181 | MPC826x_PCI_UPPER_MEM, | ||
182 | IORESOURCE_MEM|IORESOURCE_PREFETCH, "PCI prefetchable memory"); | ||
183 | |||
184 | pci_init_resource(&hose->mem_resources[1], | ||
185 | MPC826x_PCI_LOWER_MMIO, | ||
186 | MPC826x_PCI_UPPER_MMIO, | ||
187 | IORESOURCE_MEM, "PCI memory"); | ||
188 | |||
189 | pci_init_resource(&hose->io_resource, | ||
190 | MPC826x_PCI_LOWER_IO, | ||
191 | MPC826x_PCI_UPPER_IO, | ||
192 | IORESOURCE_IO, "PCI I/O"); | ||
193 | } | ||
diff --git a/arch/ppc/syslib/m8260_pci.h b/arch/ppc/syslib/m8260_pci.h deleted file mode 100644 index d1352120acd7..000000000000 --- a/arch/ppc/syslib/m8260_pci.h +++ /dev/null | |||
@@ -1,76 +0,0 @@ | |||
1 | |||
2 | #ifndef _PPC_KERNEL_M8260_PCI_H | ||
3 | #define _PPC_KERNEL_M8260_PCI_H | ||
4 | |||
5 | #include <asm/m8260_pci.h> | ||
6 | |||
7 | /* | ||
8 | * Local->PCI map (from CPU) controlled by | ||
9 | * MPC826x master window | ||
10 | * | ||
11 | * 0x80000000 - 0xBFFFFFFF Total CPU2PCI space PCIBR0 | ||
12 | * | ||
13 | * 0x80000000 - 0x9FFFFFFF PCI Mem with prefetch (Outbound ATU #1) | ||
14 | * 0xA0000000 - 0xAFFFFFFF PCI Mem w/o prefetch (Outbound ATU #2) | ||
15 | * 0xB0000000 - 0xB0FFFFFF 32-bit PCI IO (Outbound ATU #3) | ||
16 | * | ||
17 | * PCI->Local map (from PCI) | ||
18 | * MPC826x slave window controlled by | ||
19 | * | ||
20 | * 0x00000000 - 0x07FFFFFF MPC826x local memory (Inbound ATU #1) | ||
21 | */ | ||
22 | |||
23 | /* | ||
24 | * Slave window that allows PCI masters to access MPC826x local memory. | ||
25 | * This window is set up using the first set of Inbound ATU registers | ||
26 | */ | ||
27 | |||
28 | #ifndef MPC826x_PCI_SLAVE_MEM_LOCAL | ||
29 | #define MPC826x_PCI_SLAVE_MEM_LOCAL (((struct bd_info *)__res)->bi_memstart) | ||
30 | #define MPC826x_PCI_SLAVE_MEM_BUS (((struct bd_info *)__res)->bi_memstart) | ||
31 | #define MPC826x_PCI_SLAVE_MEM_SIZE (((struct bd_info *)__res)->bi_memsize) | ||
32 | #endif | ||
33 | |||
34 | /* | ||
35 | * This is the window that allows the CPU to access PCI address space. | ||
36 | * It will be setup with the SIU PCIBR0 register. All three PCI master | ||
37 | * windows, which allow the CPU to access PCI prefetch, non prefetch, | ||
38 | * and IO space (see below), must all fit within this window. | ||
39 | */ | ||
40 | #ifndef MPC826x_PCI_BASE | ||
41 | #define MPC826x_PCI_BASE 0x80000000 | ||
42 | #define MPC826x_PCI_MASK 0xc0000000 | ||
43 | #endif | ||
44 | |||
45 | #ifndef MPC826x_PCI_LOWER_MEM | ||
46 | #define MPC826x_PCI_LOWER_MEM 0x80000000 | ||
47 | #define MPC826x_PCI_UPPER_MEM 0x9fffffff | ||
48 | #define MPC826x_PCI_MEM_OFFSET 0x00000000 | ||
49 | #endif | ||
50 | |||
51 | #ifndef MPC826x_PCI_LOWER_MMIO | ||
52 | #define MPC826x_PCI_LOWER_MMIO 0xa0000000 | ||
53 | #define MPC826x_PCI_UPPER_MMIO 0xafffffff | ||
54 | #define MPC826x_PCI_MMIO_OFFSET 0x00000000 | ||
55 | #endif | ||
56 | |||
57 | #ifndef MPC826x_PCI_LOWER_IO | ||
58 | #define MPC826x_PCI_LOWER_IO 0x00000000 | ||
59 | #define MPC826x_PCI_UPPER_IO 0x00ffffff | ||
60 | #define MPC826x_PCI_IO_BASE 0xb0000000 | ||
61 | #define MPC826x_PCI_IO_SIZE 0x01000000 | ||
62 | #endif | ||
63 | |||
64 | #ifndef _IO_BASE | ||
65 | #define _IO_BASE isa_io_base | ||
66 | #endif | ||
67 | |||
68 | #ifdef CONFIG_8260_PCI9 | ||
69 | struct pci_controller; | ||
70 | extern void setup_m8260_indirect_pci(struct pci_controller* hose, | ||
71 | u32 cfg_addr, u32 cfg_data); | ||
72 | #else | ||
73 | #define setup_m8260_indirect_pci setup_indirect_pci | ||
74 | #endif | ||
75 | |||
76 | #endif /* _PPC_KERNEL_M8260_PCI_H */ | ||
diff --git a/arch/ppc/syslib/m8260_pci_erratum9.c b/arch/ppc/syslib/m8260_pci_erratum9.c index 9c0582d639e0..1dc7e4e1d491 100644 --- a/arch/ppc/syslib/m8260_pci_erratum9.c +++ b/arch/ppc/syslib/m8260_pci_erratum9.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <asm/immap_cpm2.h> | 31 | #include <asm/immap_cpm2.h> |
32 | #include <asm/cpm2.h> | 32 | #include <asm/cpm2.h> |
33 | 33 | ||
34 | #include "m8260_pci.h" | 34 | #include "m82xx_pci.h" |
35 | 35 | ||
36 | #ifdef CONFIG_8260_PCI9 | 36 | #ifdef CONFIG_8260_PCI9 |
37 | /*#include <asm/mpc8260_pci9.h>*/ /* included in asm/io.h */ | 37 | /*#include <asm/mpc8260_pci9.h>*/ /* included in asm/io.h */ |
@@ -248,11 +248,11 @@ EXPORT_SYMBOL(idma_pci9_read_le); | |||
248 | 248 | ||
249 | static inline int is_pci_mem(unsigned long addr) | 249 | static inline int is_pci_mem(unsigned long addr) |
250 | { | 250 | { |
251 | if (addr >= MPC826x_PCI_LOWER_MMIO && | 251 | if (addr >= M82xx_PCI_LOWER_MMIO && |
252 | addr <= MPC826x_PCI_UPPER_MMIO) | 252 | addr <= M82xx_PCI_UPPER_MMIO) |
253 | return 1; | 253 | return 1; |
254 | if (addr >= MPC826x_PCI_LOWER_MEM && | 254 | if (addr >= M82xx_PCI_LOWER_MEM && |
255 | addr <= MPC826x_PCI_UPPER_MEM) | 255 | addr <= M82xx_PCI_UPPER_MEM) |
256 | return 1; | 256 | return 1; |
257 | return 0; | 257 | return 0; |
258 | } | 258 | } |
diff --git a/arch/ppc/syslib/m8260_setup.c b/arch/ppc/syslib/m8260_setup.c index 23ea3f694de2..fda75d79050c 100644 --- a/arch/ppc/syslib/m8260_setup.c +++ b/arch/ppc/syslib/m8260_setup.c | |||
@@ -34,7 +34,8 @@ | |||
34 | unsigned char __res[sizeof(bd_t)]; | 34 | unsigned char __res[sizeof(bd_t)]; |
35 | 35 | ||
36 | extern void cpm2_reset(void); | 36 | extern void cpm2_reset(void); |
37 | extern void m8260_find_bridges(void); | 37 | extern void pq2_find_bridges(void); |
38 | extern void pq2pci_init_irq(void); | ||
38 | extern void idma_pci9_init(void); | 39 | extern void idma_pci9_init(void); |
39 | 40 | ||
40 | /* Place-holder for board-specific init */ | 41 | /* Place-holder for board-specific init */ |
@@ -56,7 +57,7 @@ m8260_setup_arch(void) | |||
56 | idma_pci9_init(); | 57 | idma_pci9_init(); |
57 | #endif | 58 | #endif |
58 | #ifdef CONFIG_PCI_8260 | 59 | #ifdef CONFIG_PCI_8260 |
59 | m8260_find_bridges(); | 60 | pq2_find_bridges(); |
60 | #endif | 61 | #endif |
61 | #ifdef CONFIG_BLK_DEV_INITRD | 62 | #ifdef CONFIG_BLK_DEV_INITRD |
62 | if (initrd_start) | 63 | if (initrd_start) |
@@ -173,6 +174,12 @@ m8260_init_IRQ(void) | |||
173 | * in case the boot rom changed something on us. | 174 | * in case the boot rom changed something on us. |
174 | */ | 175 | */ |
175 | cpm2_immr->im_intctl.ic_siprr = 0x05309770; | 176 | cpm2_immr->im_intctl.ic_siprr = 0x05309770; |
177 | |||
178 | #if defined(CONFIG_PCI) && (defined(CONFIG_ADS8272) || defined(CONFIG_PQ2FADS)) | ||
179 | /* Initialize stuff for the 82xx CPLD IC and install demux */ | ||
180 | pq2pci_init_irq(); | ||
181 | #endif | ||
182 | |||
176 | } | 183 | } |
177 | 184 | ||
178 | /* | 185 | /* |
diff --git a/arch/ppc/syslib/m82xx_pci.c b/arch/ppc/syslib/m82xx_pci.c new file mode 100644 index 000000000000..5e7a7edcea74 --- /dev/null +++ b/arch/ppc/syslib/m82xx_pci.c | |||
@@ -0,0 +1,383 @@ | |||
1 | /* | ||
2 | * | ||
3 | * (C) Copyright 2003 | ||
4 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | ||
5 | * | ||
6 | * (C) Copyright 2004 Red Hat, Inc. | ||
7 | * | ||
8 | * 2005 (c) MontaVista Software, Inc. | ||
9 | * Vitaly Bordug <vbordug@ru.mvista.com> | ||
10 | * | ||
11 | * See file CREDITS for list of people who contributed to this | ||
12 | * project. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License as | ||
16 | * published by the Free Software Foundation; either version 2 of | ||
17 | * the License, or (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
27 | * MA 02111-1307 USA | ||
28 | */ | ||
29 | |||
30 | #include <linux/kernel.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/pci.h> | ||
33 | #include <linux/slab.h> | ||
34 | #include <linux/delay.h> | ||
35 | #include <linux/irq.h> | ||
36 | #include <linux/interrupt.h> | ||
37 | |||
38 | #include <asm/byteorder.h> | ||
39 | #include <asm/io.h> | ||
40 | #include <asm/irq.h> | ||
41 | #include <asm/uaccess.h> | ||
42 | #include <asm/machdep.h> | ||
43 | #include <asm/pci-bridge.h> | ||
44 | #include <asm/immap_cpm2.h> | ||
45 | #include <asm/mpc8260.h> | ||
46 | #include <asm/cpm2.h> | ||
47 | |||
48 | #include "m82xx_pci.h" | ||
49 | |||
50 | /* | ||
51 | * Interrupt routing | ||
52 | */ | ||
53 | |||
54 | static inline int | ||
55 | pq2pci_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | ||
56 | { | ||
57 | static char pci_irq_table[][4] = | ||
58 | /* | ||
59 | * PCI IDSEL/INTPIN->INTLINE | ||
60 | * A B C D | ||
61 | */ | ||
62 | { | ||
63 | { PIRQA, PIRQB, PIRQC, PIRQD }, /* IDSEL 22 - PCI slot 0 */ | ||
64 | { PIRQD, PIRQA, PIRQB, PIRQC }, /* IDSEL 23 - PCI slot 1 */ | ||
65 | { PIRQC, PIRQD, PIRQA, PIRQB }, /* IDSEL 24 - PCI slot 2 */ | ||
66 | }; | ||
67 | |||
68 | const long min_idsel = 22, max_idsel = 24, irqs_per_slot = 4; | ||
69 | return PCI_IRQ_TABLE_LOOKUP; | ||
70 | } | ||
71 | |||
72 | static void | ||
73 | pq2pci_mask_irq(unsigned int irq) | ||
74 | { | ||
75 | int bit = irq - NR_CPM_INTS; | ||
76 | |||
77 | *(volatile unsigned long *) PCI_INT_MASK_REG |= (1 << (31 - bit)); | ||
78 | return; | ||
79 | } | ||
80 | |||
81 | static void | ||
82 | pq2pci_unmask_irq(unsigned int irq) | ||
83 | { | ||
84 | int bit = irq - NR_CPM_INTS; | ||
85 | |||
86 | *(volatile unsigned long *) PCI_INT_MASK_REG &= ~(1 << (31 - bit)); | ||
87 | return; | ||
88 | } | ||
89 | |||
90 | static void | ||
91 | pq2pci_mask_and_ack(unsigned int irq) | ||
92 | { | ||
93 | int bit = irq - NR_CPM_INTS; | ||
94 | |||
95 | *(volatile unsigned long *) PCI_INT_MASK_REG |= (1 << (31 - bit)); | ||
96 | return; | ||
97 | } | ||
98 | |||
99 | static void | ||
100 | pq2pci_end_irq(unsigned int irq) | ||
101 | { | ||
102 | int bit = irq - NR_CPM_INTS; | ||
103 | |||
104 | *(volatile unsigned long *) PCI_INT_MASK_REG &= ~(1 << (31 - bit)); | ||
105 | return; | ||
106 | } | ||
107 | |||
108 | struct hw_interrupt_type pq2pci_ic = { | ||
109 | "PQ2 PCI", | ||
110 | NULL, | ||
111 | NULL, | ||
112 | pq2pci_unmask_irq, | ||
113 | pq2pci_mask_irq, | ||
114 | pq2pci_mask_and_ack, | ||
115 | pq2pci_end_irq, | ||
116 | 0 | ||
117 | }; | ||
118 | |||
119 | static irqreturn_t | ||
120 | pq2pci_irq_demux(int irq, void *dev_id, struct pt_regs *regs) | ||
121 | { | ||
122 | unsigned long stat, mask, pend; | ||
123 | int bit; | ||
124 | |||
125 | for(;;) { | ||
126 | stat = *(volatile unsigned long *) PCI_INT_STAT_REG; | ||
127 | mask = *(volatile unsigned long *) PCI_INT_MASK_REG; | ||
128 | pend = stat & ~mask & 0xf0000000; | ||
129 | if (!pend) | ||
130 | break; | ||
131 | for (bit = 0; pend != 0; ++bit, pend <<= 1) { | ||
132 | if (pend & 0x80000000) | ||
133 | __do_IRQ(NR_CPM_INTS + bit, regs); | ||
134 | } | ||
135 | } | ||
136 | |||
137 | return IRQ_HANDLED; | ||
138 | } | ||
139 | |||
140 | static struct irqaction pq2pci_irqaction = { | ||
141 | .handler = pq2pci_irq_demux, | ||
142 | .flags = SA_INTERRUPT, | ||
143 | .mask = CPU_MASK_NONE, | ||
144 | .name = "PQ2 PCI cascade", | ||
145 | }; | ||
146 | |||
147 | |||
148 | void | ||
149 | pq2pci_init_irq(void) | ||
150 | { | ||
151 | int irq; | ||
152 | volatile cpm2_map_t *immap = cpm2_immr; | ||
153 | #if defined CONFIG_ADS8272 | ||
154 | /* configure chip select for PCI interrupt controller */ | ||
155 | immap->im_memctl.memc_br3 = PCI_INT_STAT_REG | 0x00001801; | ||
156 | immap->im_memctl.memc_or3 = 0xffff8010; | ||
157 | #elif defined CONFIG_PQ2FADS | ||
158 | immap->im_memctl.memc_br8 = PCI_INT_STAT_REG | 0x00001801; | ||
159 | immap->im_memctl.memc_or8 = 0xffff8010; | ||
160 | #endif | ||
161 | for (irq = NR_CPM_INTS; irq < NR_CPM_INTS + 4; irq++) | ||
162 | irq_desc[irq].handler = &pq2pci_ic; | ||
163 | |||
164 | /* make PCI IRQ level sensitive */ | ||
165 | immap->im_intctl.ic_siexr &= | ||
166 | ~(1 << (14 - (PCI_INT_TO_SIU - SIU_INT_IRQ1))); | ||
167 | |||
168 | /* mask all PCI interrupts */ | ||
169 | *(volatile unsigned long *) PCI_INT_MASK_REG |= 0xfff00000; | ||
170 | |||
171 | /* install the demultiplexer for the PCI cascade interrupt */ | ||
172 | setup_irq(PCI_INT_TO_SIU, &pq2pci_irqaction); | ||
173 | return; | ||
174 | } | ||
175 | |||
176 | static int | ||
177 | pq2pci_exclude_device(u_char bus, u_char devfn) | ||
178 | { | ||
179 | return PCIBIOS_SUCCESSFUL; | ||
180 | } | ||
181 | |||
182 | /* PCI bus configuration registers. | ||
183 | */ | ||
184 | static void | ||
185 | pq2ads_setup_pci(struct pci_controller *hose) | ||
186 | { | ||
187 | __u32 val; | ||
188 | volatile cpm2_map_t *immap = cpm2_immr; | ||
189 | bd_t* binfo = (bd_t*) __res; | ||
190 | u32 sccr = immap->im_clkrst.car_sccr; | ||
191 | uint pci_div,freq,time; | ||
192 | /* PCI int lowest prio */ | ||
193 | /* Each 4 bits is a device bus request and the MS 4bits | ||
194 | is highest priority */ | ||
195 | /* Bus 4bit value | ||
196 | --- ---------- | ||
197 | CPM high 0b0000 | ||
198 | CPM middle 0b0001 | ||
199 | CPM low 0b0010 | ||
200 | PCI reguest 0b0011 | ||
201 | Reserved 0b0100 | ||
202 | Reserved 0b0101 | ||
203 | Internal Core 0b0110 | ||
204 | External Master 1 0b0111 | ||
205 | External Master 2 0b1000 | ||
206 | External Master 3 0b1001 | ||
207 | The rest are reserved | ||
208 | */ | ||
209 | immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x61207893; | ||
210 | /* park bus on core */ | ||
211 | immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_CORE; | ||
212 | /* | ||
213 | * Set up master windows that allow the CPU to access PCI space. These | ||
214 | * windows are set up using the two SIU PCIBR registers. | ||
215 | */ | ||
216 | |||
217 | immap->im_memctl.memc_pcimsk0 = M82xx_PCI_PRIM_WND_SIZE; | ||
218 | immap->im_memctl.memc_pcibr0 = M82xx_PCI_PRIM_WND_BASE | PCIBR_ENABLE; | ||
219 | |||
220 | #ifdef M82xx_PCI_SEC_WND_SIZE | ||
221 | immap->im_memctl.memc_pcimsk1 = M82xx_PCI_SEC_WND_SIZE; | ||
222 | immap->im_memctl.memc_pcibr1 = M82xx_PCI_SEC_WND_BASE | PCIBR_ENABLE; | ||
223 | #endif | ||
224 | |||
225 | #if defined CONFIG_ADS8272 | ||
226 | immap->im_siu_conf.siu_82xx.sc_siumcr = | ||
227 | (immap->im_siu_conf.siu_82xx.sc_siumcr & | ||
228 | ~(SIUMCR_BBD | SIUMCR_ESE | SIUMCR_PBSE | | ||
229 | SIUMCR_CDIS | SIUMCR_DPPC11 | SIUMCR_L2CPC11 | | ||
230 | SIUMCR_LBPC11 | SIUMCR_APPC11 | | ||
231 | SIUMCR_CS10PC11 | SIUMCR_BCTLC11 | SIUMCR_MMR11)) | | ||
232 | SIUMCR_DPPC11 | SIUMCR_L2CPC01 | SIUMCR_LBPC00 | | ||
233 | SIUMCR_APPC10 | SIUMCR_CS10PC00 | | ||
234 | SIUMCR_BCTLC00 | SIUMCR_MMR11 ; | ||
235 | |||
236 | #elif defined CONFIG_PQ2FADS | ||
237 | /* | ||
238 | * Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]), | ||
239 | * and local bus for PCI (SIUMCR [LBPC]). | ||
240 | */ | ||
241 | immap->im_siu_conf.siu_82xx.sc_siumcr = (immap->im_siu_conf.sc_siumcr & | ||
242 | ~(SIUMCR_L2PC11 | SIUMCR_LBPC11 | SIUMCR_CS10PC11 | SIUMCR_APPC11) | | ||
243 | SIUMCR_BBD | SIUMCR_LBPC01 | SIUMCR_DPPC11 | SIUMCR_APPC10; | ||
244 | #endif | ||
245 | /* Enable PCI */ | ||
246 | immap->im_pci.pci_gcr = cpu_to_le32(PCIGCR_PCI_BUS_EN); | ||
247 | |||
248 | pci_div = ( (sccr & SCCR_PCI_MODCK) ? 2 : 1) * | ||
249 | ( ( (sccr & SCCR_PCIDF_MSK) >> SCCR_PCIDF_SHIFT) + 1); | ||
250 | freq = (uint)((2*binfo->bi_cpmfreq)/(pci_div)); | ||
251 | time = (int)666666/freq; | ||
252 | /* due to PCI Local Bus spec, some devices needs to wait such a long | ||
253 | time after RST deassertion. More specifically, 0.508s for 66MHz & twice more for 33 */ | ||
254 | printk("%s: The PCI bus is %d Mhz.\nWaiting %s after deasserting RST...\n",__FILE__,freq, | ||
255 | (time==1) ? "0.5 seconds":"1 second" ); | ||
256 | |||
257 | { | ||
258 | int i; | ||
259 | for(i=0;i<(500*time);i++) | ||
260 | udelay(1000); | ||
261 | } | ||
262 | |||
263 | /* setup ATU registers */ | ||
264 | immap->im_pci.pci_pocmr0 = cpu_to_le32(POCMR_ENABLE | POCMR_PCI_IO | | ||
265 | ((~(M82xx_PCI_IO_SIZE - 1U)) >> POTA_ADDR_SHIFT)); | ||
266 | immap->im_pci.pci_potar0 = cpu_to_le32(M82xx_PCI_LOWER_IO >> POTA_ADDR_SHIFT); | ||
267 | immap->im_pci.pci_pobar0 = cpu_to_le32(M82xx_PCI_IO_BASE >> POTA_ADDR_SHIFT); | ||
268 | |||
269 | /* Set-up non-prefetchable window */ | ||
270 | immap->im_pci.pci_pocmr1 = cpu_to_le32(POCMR_ENABLE | ((~(M82xx_PCI_MMIO_SIZE-1U)) >> POTA_ADDR_SHIFT)); | ||
271 | immap->im_pci.pci_potar1 = cpu_to_le32(M82xx_PCI_LOWER_MMIO >> POTA_ADDR_SHIFT); | ||
272 | immap->im_pci.pci_pobar1 = cpu_to_le32((M82xx_PCI_LOWER_MMIO - M82xx_PCI_MMIO_OFFSET) >> POTA_ADDR_SHIFT); | ||
273 | |||
274 | /* Set-up prefetchable window */ | ||
275 | immap->im_pci.pci_pocmr2 = cpu_to_le32(POCMR_ENABLE |POCMR_PREFETCH_EN | | ||
276 | (~(M82xx_PCI_MEM_SIZE-1U) >> POTA_ADDR_SHIFT)); | ||
277 | immap->im_pci.pci_potar2 = cpu_to_le32(M82xx_PCI_LOWER_MEM >> POTA_ADDR_SHIFT); | ||
278 | immap->im_pci.pci_pobar2 = cpu_to_le32((M82xx_PCI_LOWER_MEM - M82xx_PCI_MEM_OFFSET) >> POTA_ADDR_SHIFT); | ||
279 | |||
280 | /* Inbound transactions from PCI memory space */ | ||
281 | immap->im_pci.pci_picmr0 = cpu_to_le32(PICMR_ENABLE | PICMR_PREFETCH_EN | | ||
282 | ((~(M82xx_PCI_SLAVE_MEM_SIZE-1U)) >> PITA_ADDR_SHIFT)); | ||
283 | immap->im_pci.pci_pibar0 = cpu_to_le32(M82xx_PCI_SLAVE_MEM_BUS >> PITA_ADDR_SHIFT); | ||
284 | immap->im_pci.pci_pitar0 = cpu_to_le32(M82xx_PCI_SLAVE_MEM_LOCAL>> PITA_ADDR_SHIFT); | ||
285 | |||
286 | #if defined CONFIG_ADS8272 | ||
287 | /* PCI int highest prio */ | ||
288 | immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x01236745; | ||
289 | #elif defined CONFIG_PQ2FADS | ||
290 | immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x03124567; | ||
291 | #endif | ||
292 | /* park bus on PCI */ | ||
293 | immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_PCI; | ||
294 | |||
295 | /* Enable bus mastering and inbound memory transactions */ | ||
296 | early_read_config_dword(hose, hose->first_busno, 0, PCI_COMMAND, &val); | ||
297 | val &= 0xffff0000; | ||
298 | val |= PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER; | ||
299 | early_write_config_dword(hose, hose->first_busno, 0, PCI_COMMAND, val); | ||
300 | |||
301 | } | ||
302 | |||
303 | void __init pq2_find_bridges(void) | ||
304 | { | ||
305 | extern int pci_assign_all_busses; | ||
306 | struct pci_controller * hose; | ||
307 | int host_bridge; | ||
308 | |||
309 | pci_assign_all_busses = 1; | ||
310 | |||
311 | hose = pcibios_alloc_controller(); | ||
312 | |||
313 | if (!hose) | ||
314 | return; | ||
315 | |||
316 | ppc_md.pci_swizzle = common_swizzle; | ||
317 | |||
318 | hose->first_busno = 0; | ||
319 | hose->bus_offset = 0; | ||
320 | hose->last_busno = 0xff; | ||
321 | |||
322 | #ifdef CONFIG_ADS8272 | ||
323 | hose->set_cfg_type = 1; | ||
324 | #endif | ||
325 | |||
326 | setup_m8260_indirect_pci(hose, | ||
327 | (unsigned long)&cpm2_immr->im_pci.pci_cfg_addr, | ||
328 | (unsigned long)&cpm2_immr->im_pci.pci_cfg_data); | ||
329 | |||
330 | /* Make sure it is a supported bridge */ | ||
331 | early_read_config_dword(hose, | ||
332 | 0, | ||
333 | PCI_DEVFN(0,0), | ||
334 | PCI_VENDOR_ID, | ||
335 | &host_bridge); | ||
336 | switch (host_bridge) { | ||
337 | case PCI_DEVICE_ID_MPC8265: | ||
338 | break; | ||
339 | case PCI_DEVICE_ID_MPC8272: | ||
340 | break; | ||
341 | default: | ||
342 | printk("Attempting to use unrecognized host bridge ID" | ||
343 | " 0x%08x.\n", host_bridge); | ||
344 | break; | ||
345 | } | ||
346 | |||
347 | pq2ads_setup_pci(hose); | ||
348 | |||
349 | hose->io_space.start = M82xx_PCI_LOWER_IO; | ||
350 | hose->io_space.end = M82xx_PCI_UPPER_IO; | ||
351 | hose->mem_space.start = M82xx_PCI_LOWER_MEM; | ||
352 | hose->mem_space.end = M82xx_PCI_UPPER_MMIO; | ||
353 | hose->pci_mem_offset = M82xx_PCI_MEM_OFFSET; | ||
354 | |||
355 | isa_io_base = | ||
356 | (unsigned long) ioremap(M82xx_PCI_IO_BASE, | ||
357 | M82xx_PCI_IO_SIZE); | ||
358 | hose->io_base_virt = (void *) isa_io_base; | ||
359 | |||
360 | /* setup resources */ | ||
361 | pci_init_resource(&hose->mem_resources[0], | ||
362 | M82xx_PCI_LOWER_MEM, | ||
363 | M82xx_PCI_UPPER_MEM, | ||
364 | IORESOURCE_MEM|IORESOURCE_PREFETCH, "PCI prefetchable memory"); | ||
365 | |||
366 | pci_init_resource(&hose->mem_resources[1], | ||
367 | M82xx_PCI_LOWER_MMIO, | ||
368 | M82xx_PCI_UPPER_MMIO, | ||
369 | IORESOURCE_MEM, "PCI memory"); | ||
370 | |||
371 | pci_init_resource(&hose->io_resource, | ||
372 | M82xx_PCI_LOWER_IO, | ||
373 | M82xx_PCI_UPPER_IO, | ||
374 | IORESOURCE_IO | 1, "PCI I/O"); | ||
375 | |||
376 | ppc_md.pci_exclude_device = pq2pci_exclude_device; | ||
377 | hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); | ||
378 | |||
379 | ppc_md.pci_map_irq = pq2pci_map_irq; | ||
380 | ppc_md.pcibios_fixup = NULL; | ||
381 | ppc_md.pcibios_fixup_bus = NULL; | ||
382 | |||
383 | } | ||
diff --git a/arch/ppc/syslib/m82xx_pci.h b/arch/ppc/syslib/m82xx_pci.h new file mode 100644 index 000000000000..924f73f8e595 --- /dev/null +++ b/arch/ppc/syslib/m82xx_pci.h | |||
@@ -0,0 +1,92 @@ | |||
1 | |||
2 | #ifndef _PPC_KERNEL_M82XX_PCI_H | ||
3 | #define _PPC_KERNEL_M82XX_PCI_H | ||
4 | |||
5 | #include <asm/m8260_pci.h> | ||
6 | /* | ||
7 | * Local->PCI map (from CPU) controlled by | ||
8 | * MPC826x master window | ||
9 | * | ||
10 | * 0xF6000000 - 0xF7FFFFFF IO space | ||
11 | * 0x80000000 - 0xBFFFFFFF CPU2PCI memory space PCIBR0 | ||
12 | * | ||
13 | * 0x80000000 - 0x9FFFFFFF PCI Mem with prefetch (Outbound ATU #1) | ||
14 | * 0xA0000000 - 0xBFFFFFFF PCI Mem w/o prefetch (Outbound ATU #2) | ||
15 | * 0xF6000000 - 0xF7FFFFFF 32-bit PCI IO (Outbound ATU #3) | ||
16 | * | ||
17 | * PCI->Local map (from PCI) | ||
18 | * MPC826x slave window controlled by | ||
19 | * | ||
20 | * 0x00000000 - 0x07FFFFFF MPC826x local memory (Inbound ATU #1) | ||
21 | */ | ||
22 | |||
23 | /* | ||
24 | * Slave window that allows PCI masters to access MPC826x local memory. | ||
25 | * This window is set up using the first set of Inbound ATU registers | ||
26 | */ | ||
27 | |||
28 | #ifndef M82xx_PCI_SLAVE_MEM_LOCAL | ||
29 | #define M82xx_PCI_SLAVE_MEM_LOCAL (((struct bd_info *)__res)->bi_memstart) | ||
30 | #define M82xx_PCI_SLAVE_MEM_BUS (((struct bd_info *)__res)->bi_memstart) | ||
31 | #define M82xx_PCI_SLAVE_MEM_SIZE (((struct bd_info *)__res)->bi_memsize) | ||
32 | #endif | ||
33 | |||
34 | /* | ||
35 | * This is the window that allows the CPU to access PCI address space. | ||
36 | * It will be setup with the SIU PCIBR0 register. All three PCI master | ||
37 | * windows, which allow the CPU to access PCI prefetch, non prefetch, | ||
38 | * and IO space (see below), must all fit within this window. | ||
39 | */ | ||
40 | |||
41 | #ifndef M82xx_PCI_LOWER_MEM | ||
42 | #define M82xx_PCI_LOWER_MEM 0x80000000 | ||
43 | #define M82xx_PCI_UPPER_MEM 0x9fffffff | ||
44 | #define M82xx_PCI_MEM_OFFSET 0x00000000 | ||
45 | #define M82xx_PCI_MEM_SIZE 0x20000000 | ||
46 | #endif | ||
47 | |||
48 | #ifndef M82xx_PCI_LOWER_MMIO | ||
49 | #define M82xx_PCI_LOWER_MMIO 0xa0000000 | ||
50 | #define M82xx_PCI_UPPER_MMIO 0xafffffff | ||
51 | #define M82xx_PCI_MMIO_OFFSET 0x00000000 | ||
52 | #define M82xx_PCI_MMIO_SIZE 0x20000000 | ||
53 | #endif | ||
54 | |||
55 | #ifndef M82xx_PCI_LOWER_IO | ||
56 | #define M82xx_PCI_LOWER_IO 0x00000000 | ||
57 | #define M82xx_PCI_UPPER_IO 0x01ffffff | ||
58 | #define M82xx_PCI_IO_BASE 0xf6000000 | ||
59 | #define M82xx_PCI_IO_SIZE 0x02000000 | ||
60 | #endif | ||
61 | |||
62 | #ifndef M82xx_PCI_PRIM_WND_SIZE | ||
63 | #define M82xx_PCI_PRIM_WND_SIZE ~(M82xx_PCI_IO_SIZE - 1U) | ||
64 | #define M82xx_PCI_PRIM_WND_BASE (M82xx_PCI_IO_BASE) | ||
65 | #endif | ||
66 | |||
67 | #ifndef M82xx_PCI_SEC_WND_SIZE | ||
68 | #define M82xx_PCI_SEC_WND_SIZE ~(M82xx_PCI_MEM_SIZE + M82xx_PCI_MMIO_SIZE - 1U) | ||
69 | #define M82xx_PCI_SEC_WND_BASE (M82xx_PCI_LOWER_MEM) | ||
70 | #endif | ||
71 | |||
72 | #ifndef POTA_ADDR_SHIFT | ||
73 | #define POTA_ADDR_SHIFT 12 | ||
74 | #endif | ||
75 | |||
76 | #ifndef PITA_ADDR_SHIFT | ||
77 | #define PITA_ADDR_SHIFT 12 | ||
78 | #endif | ||
79 | |||
80 | #ifndef _IO_BASE | ||
81 | #define _IO_BASE isa_io_base | ||
82 | #endif | ||
83 | |||
84 | #ifdef CONFIG_8260_PCI9 | ||
85 | struct pci_controller; | ||
86 | extern void setup_m8260_indirect_pci(struct pci_controller* hose, | ||
87 | u32 cfg_addr, u32 cfg_data); | ||
88 | #else | ||
89 | #define setup_m8260_indirect_pci setup_indirect_pci | ||
90 | #endif | ||
91 | |||
92 | #endif /* _PPC_KERNEL_M8260_PCI_H */ | ||
diff --git a/arch/ppc/syslib/mpc83xx_devices.c b/arch/ppc/syslib/mpc83xx_devices.c index 5c1a919eaabf..75c8e9834ae7 100644 --- a/arch/ppc/syslib/mpc83xx_devices.c +++ b/arch/ppc/syslib/mpc83xx_devices.c | |||
@@ -61,6 +61,7 @@ static struct plat_serial8250_port serial_platform_data[] = { | |||
61 | .iotype = UPIO_MEM, | 61 | .iotype = UPIO_MEM, |
62 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, | 62 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, |
63 | }, | 63 | }, |
64 | { }, | ||
64 | }; | 65 | }; |
65 | 66 | ||
66 | struct platform_device ppc_sys_platform_devices[] = { | 67 | struct platform_device ppc_sys_platform_devices[] = { |
diff --git a/arch/ppc/syslib/mpc85xx_devices.c b/arch/ppc/syslib/mpc85xx_devices.c index a231795ee26f..1e658ef57e75 100644 --- a/arch/ppc/syslib/mpc85xx_devices.c +++ b/arch/ppc/syslib/mpc85xx_devices.c | |||
@@ -61,6 +61,7 @@ static struct plat_serial8250_port serial_platform_data[] = { | |||
61 | .iotype = UPIO_MEM, | 61 | .iotype = UPIO_MEM, |
62 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ, | 62 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ, |
63 | }, | 63 | }, |
64 | { }, | ||
64 | }; | 65 | }; |
65 | 66 | ||
66 | struct platform_device ppc_sys_platform_devices[] = { | 67 | struct platform_device ppc_sys_platform_devices[] = { |
diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c index 7619e16fccae..000ba47c67cb 100644 --- a/arch/ppc/syslib/open_pic.c +++ b/arch/ppc/syslib/open_pic.c | |||
@@ -275,7 +275,7 @@ static void __init openpic_enable_sie(void) | |||
275 | } | 275 | } |
276 | #endif | 276 | #endif |
277 | 277 | ||
278 | #if defined(CONFIG_EPIC_SERIAL_MODE) || defined(CONFIG_PM) | 278 | #if defined(CONFIG_EPIC_SERIAL_MODE) |
279 | static void openpic_reset(void) | 279 | static void openpic_reset(void) |
280 | { | 280 | { |
281 | openpic_setfield(&OpenPIC->Global.Global_Configuration0, | 281 | openpic_setfield(&OpenPIC->Global.Global_Configuration0, |
@@ -557,12 +557,10 @@ static void __init openpic_initipi(u_int ipi, u_int pri, u_int vec) | |||
557 | */ | 557 | */ |
558 | void openpic_cause_IPI(u_int ipi, cpumask_t cpumask) | 558 | void openpic_cause_IPI(u_int ipi, cpumask_t cpumask) |
559 | { | 559 | { |
560 | cpumask_t phys; | ||
561 | DECL_THIS_CPU; | 560 | DECL_THIS_CPU; |
562 | 561 | ||
563 | CHECK_THIS_CPU; | 562 | CHECK_THIS_CPU; |
564 | check_arg_ipi(ipi); | 563 | check_arg_ipi(ipi); |
565 | phys = physmask(cpumask); | ||
566 | openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi), | 564 | openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi), |
567 | cpus_addr(physmask(cpumask))[0]); | 565 | cpus_addr(physmask(cpumask))[0]); |
568 | } | 566 | } |
@@ -995,8 +993,6 @@ int openpic_resume(struct sys_device *sysdev) | |||
995 | return 0; | 993 | return 0; |
996 | } | 994 | } |
997 | 995 | ||
998 | openpic_reset(); | ||
999 | |||
1000 | /* OpenPIC sometimes seem to need some time to be fully back up... */ | 996 | /* OpenPIC sometimes seem to need some time to be fully back up... */ |
1001 | do { | 997 | do { |
1002 | openpic_set_spurious(OPENPIC_VEC_SPURIOUS); | 998 | openpic_set_spurious(OPENPIC_VEC_SPURIOUS); |
diff --git a/arch/ppc/syslib/ppc83xx_setup.c b/arch/ppc/syslib/ppc83xx_setup.c index c28f9d679484..843cf8873e60 100644 --- a/arch/ppc/syslib/ppc83xx_setup.c +++ b/arch/ppc/syslib/ppc83xx_setup.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <asm/mmu.h> | 29 | #include <asm/mmu.h> |
30 | #include <asm/ppc_sys.h> | 30 | #include <asm/ppc_sys.h> |
31 | #include <asm/kgdb.h> | 31 | #include <asm/kgdb.h> |
32 | #include <asm/delay.h> | ||
32 | 33 | ||
33 | #include <syslib/ppc83xx_setup.h> | 34 | #include <syslib/ppc83xx_setup.h> |
34 | 35 | ||
@@ -117,7 +118,34 @@ mpc83xx_early_serial_map(void) | |||
117 | void | 118 | void |
118 | mpc83xx_restart(char *cmd) | 119 | mpc83xx_restart(char *cmd) |
119 | { | 120 | { |
121 | volatile unsigned char __iomem *reg; | ||
122 | unsigned char tmp; | ||
123 | |||
124 | reg = ioremap(BCSR_PHYS_ADDR, BCSR_SIZE); | ||
125 | |||
120 | local_irq_disable(); | 126 | local_irq_disable(); |
127 | |||
128 | /* | ||
129 | * Unlock the BCSR bits so a PRST will update the contents. | ||
130 | * Otherwise the reset asserts but doesn't clear. | ||
131 | */ | ||
132 | tmp = in_8(reg + BCSR_MISC_REG3_OFF); | ||
133 | tmp |= BCSR_MISC_REG3_CNFLOCK; /* low true, high false */ | ||
134 | out_8(reg + BCSR_MISC_REG3_OFF, tmp); | ||
135 | |||
136 | /* | ||
137 | * Trigger a reset via a low->high transition of the | ||
138 | * PORESET bit. | ||
139 | */ | ||
140 | tmp = in_8(reg + BCSR_MISC_REG2_OFF); | ||
141 | tmp &= ~BCSR_MISC_REG2_PORESET; | ||
142 | out_8(reg + BCSR_MISC_REG2_OFF, tmp); | ||
143 | |||
144 | udelay(1); | ||
145 | |||
146 | tmp |= BCSR_MISC_REG2_PORESET; | ||
147 | out_8(reg + BCSR_MISC_REG2_OFF, tmp); | ||
148 | |||
121 | for(;;); | 149 | for(;;); |
122 | } | 150 | } |
123 | 151 | ||
diff --git a/arch/ppc/syslib/ppc85xx_setup.c b/arch/ppc/syslib/ppc85xx_setup.c index 152c3ef1312a..f3277f469e78 100644 --- a/arch/ppc/syslib/ppc85xx_setup.c +++ b/arch/ppc/syslib/ppc85xx_setup.c | |||
@@ -132,6 +132,12 @@ mpc85xx_halt(void) | |||
132 | } | 132 | } |
133 | 133 | ||
134 | #ifdef CONFIG_PCI | 134 | #ifdef CONFIG_PCI |
135 | |||
136 | #if defined(CONFIG_MPC8555_CDS) | ||
137 | extern void mpc85xx_cds_enable_via(struct pci_controller *hose); | ||
138 | extern void mpc85xx_cds_fixup_via(struct pci_controller *hose); | ||
139 | #endif | ||
140 | |||
135 | static void __init | 141 | static void __init |
136 | mpc85xx_setup_pci1(struct pci_controller *hose) | 142 | mpc85xx_setup_pci1(struct pci_controller *hose) |
137 | { | 143 | { |
@@ -302,8 +308,18 @@ mpc85xx_setup_hose(void) | |||
302 | 308 | ||
303 | ppc_md.pci_exclude_device = mpc85xx_exclude_device; | 309 | ppc_md.pci_exclude_device = mpc85xx_exclude_device; |
304 | 310 | ||
311 | #if defined(CONFIG_MPC8555_CDS) | ||
312 | /* Pre pciauto_bus_scan VIA init */ | ||
313 | mpc85xx_cds_enable_via(hose_a); | ||
314 | #endif | ||
315 | |||
305 | hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno); | 316 | hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno); |
306 | 317 | ||
318 | #if defined(CONFIG_MPC8555_CDS) | ||
319 | /* Post pciauto_bus_scan VIA fixup */ | ||
320 | mpc85xx_cds_fixup_via(hose_a); | ||
321 | #endif | ||
322 | |||
307 | #ifdef CONFIG_85xx_PCI2 | 323 | #ifdef CONFIG_85xx_PCI2 |
308 | hose_b = pcibios_alloc_controller(); | 324 | hose_b = pcibios_alloc_controller(); |
309 | 325 | ||
diff --git a/arch/ppc/syslib/prom_init.c b/arch/ppc/syslib/prom_init.c index 2cee87137f2e..7f15136830f4 100644 --- a/arch/ppc/syslib/prom_init.c +++ b/arch/ppc/syslib/prom_init.c | |||
@@ -626,8 +626,18 @@ inspect_node(phandle node, struct device_node *dad, | |||
626 | l = call_prom("package-to-path", 3, 1, node, | 626 | l = call_prom("package-to-path", 3, 1, node, |
627 | mem_start, mem_end - mem_start); | 627 | mem_start, mem_end - mem_start); |
628 | if (l >= 0) { | 628 | if (l >= 0) { |
629 | char *p, *ep; | ||
630 | |||
629 | np->full_name = PTRUNRELOC((char *) mem_start); | 631 | np->full_name = PTRUNRELOC((char *) mem_start); |
630 | *(char *)(mem_start + l) = 0; | 632 | *(char *)(mem_start + l) = 0; |
633 | /* Fixup an Apple bug where they have bogus \0 chars in the | ||
634 | * middle of the path in some properties | ||
635 | */ | ||
636 | for (p = (char *)mem_start, ep = p + l; p < ep; p++) | ||
637 | if ((*p) == '\0') { | ||
638 | memmove(p, p+1, ep - p); | ||
639 | ep--; | ||
640 | } | ||
631 | mem_start = ALIGNUL(mem_start + l + 1); | 641 | mem_start = ALIGNUL(mem_start + l + 1); |
632 | } | 642 | } |
633 | 643 | ||
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index ef1f05e437c4..5cb343883e4d 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig | |||
@@ -40,6 +40,10 @@ config COMPAT | |||
40 | bool | 40 | bool |
41 | default y | 41 | default y |
42 | 42 | ||
43 | config SCHED_NO_NO_OMIT_FRAME_POINTER | ||
44 | bool | ||
45 | default y | ||
46 | |||
43 | # We optimistically allocate largepages from the VM, so make the limit | 47 | # We optimistically allocate largepages from the VM, so make the limit |
44 | # large enough (16MB). This badly named config option is actually | 48 | # large enough (16MB). This badly named config option is actually |
45 | # max order + 1 | 49 | # max order + 1 |
@@ -258,6 +262,7 @@ config PPC_RTAS | |||
258 | config RTAS_PROC | 262 | config RTAS_PROC |
259 | bool "Proc interface to RTAS" | 263 | bool "Proc interface to RTAS" |
260 | depends on PPC_RTAS | 264 | depends on PPC_RTAS |
265 | default y | ||
261 | 266 | ||
262 | config RTAS_FLASH | 267 | config RTAS_FLASH |
263 | tristate "Firmware flash interface" | 268 | tristate "Firmware flash interface" |
@@ -293,6 +298,9 @@ config SECCOMP | |||
293 | 298 | ||
294 | endmenu | 299 | endmenu |
295 | 300 | ||
301 | config ISA_DMA_API | ||
302 | bool | ||
303 | default y | ||
296 | 304 | ||
297 | menu "General setup" | 305 | menu "General setup" |
298 | 306 | ||
diff --git a/arch/ppc64/Kconfig.debug b/arch/ppc64/Kconfig.debug index e341a129da80..46b1ce58da3b 100644 --- a/arch/ppc64/Kconfig.debug +++ b/arch/ppc64/Kconfig.debug | |||
@@ -5,6 +5,9 @@ source "lib/Kconfig.debug" | |||
5 | config DEBUG_STACKOVERFLOW | 5 | config DEBUG_STACKOVERFLOW |
6 | bool "Check for stack overflows" | 6 | bool "Check for stack overflows" |
7 | depends on DEBUG_KERNEL | 7 | depends on DEBUG_KERNEL |
8 | help | ||
9 | This option will cause messages to be printed if free stack space | ||
10 | drops below a certain limit. | ||
8 | 11 | ||
9 | config KPROBES | 12 | config KPROBES |
10 | bool "Kprobes" | 13 | bool "Kprobes" |
diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c index b0fa86ad8b1b..da12ea2ca464 100644 --- a/arch/ppc64/boot/main.c +++ b/arch/ppc64/boot/main.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/string.h> | 14 | #include <linux/string.h> |
15 | #include <asm/processor.h> | 15 | #include <asm/processor.h> |
16 | #include <asm/page.h> | 16 | #include <asm/page.h> |
17 | #include <asm/bootinfo.h> | ||
18 | 17 | ||
19 | extern void *finddevice(const char *); | 18 | extern void *finddevice(const char *); |
20 | extern int getprop(void *, const char *, void *, int); | 19 | extern int getprop(void *, const char *, void *, int); |
diff --git a/arch/ppc64/boot/prom.c b/arch/ppc64/boot/prom.c index 7b607d1862cb..d5218b15824e 100644 --- a/arch/ppc64/boot/prom.c +++ b/arch/ppc64/boot/prom.c | |||
@@ -11,6 +11,23 @@ | |||
11 | #include <linux/string.h> | 11 | #include <linux/string.h> |
12 | #include <linux/ctype.h> | 12 | #include <linux/ctype.h> |
13 | 13 | ||
14 | extern __u32 __div64_32(unsigned long long *dividend, __u32 divisor); | ||
15 | |||
16 | /* The unnecessary pointer compare is there | ||
17 | * to check for type safety (n must be 64bit) | ||
18 | */ | ||
19 | # define do_div(n,base) ({ \ | ||
20 | __u32 __base = (base); \ | ||
21 | __u32 __rem; \ | ||
22 | (void)(((typeof((n)) *)0) == ((unsigned long long *)0)); \ | ||
23 | if (((n) >> 32) == 0) { \ | ||
24 | __rem = (__u32)(n) % __base; \ | ||
25 | (n) = (__u32)(n) / __base; \ | ||
26 | } else \ | ||
27 | __rem = __div64_32(&(n), __base); \ | ||
28 | __rem; \ | ||
29 | }) | ||
30 | |||
14 | int (*prom)(void *); | 31 | int (*prom)(void *); |
15 | 32 | ||
16 | void *chosen_handle; | 33 | void *chosen_handle; |
@@ -352,7 +369,7 @@ static int skip_atoi(const char **s) | |||
352 | #define SPECIAL 32 /* 0x */ | 369 | #define SPECIAL 32 /* 0x */ |
353 | #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ | 370 | #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ |
354 | 371 | ||
355 | static char * number(char * str, long num, int base, int size, int precision, int type) | 372 | static char * number(char * str, unsigned long long num, int base, int size, int precision, int type) |
356 | { | 373 | { |
357 | char c,sign,tmp[66]; | 374 | char c,sign,tmp[66]; |
358 | const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; | 375 | const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; |
@@ -367,9 +384,9 @@ static char * number(char * str, long num, int base, int size, int precision, in | |||
367 | c = (type & ZEROPAD) ? '0' : ' '; | 384 | c = (type & ZEROPAD) ? '0' : ' '; |
368 | sign = 0; | 385 | sign = 0; |
369 | if (type & SIGN) { | 386 | if (type & SIGN) { |
370 | if (num < 0) { | 387 | if ((signed long long)num < 0) { |
371 | sign = '-'; | 388 | sign = '-'; |
372 | num = -num; | 389 | num = - (signed long long)num; |
373 | size--; | 390 | size--; |
374 | } else if (type & PLUS) { | 391 | } else if (type & PLUS) { |
375 | sign = '+'; | 392 | sign = '+'; |
@@ -389,8 +406,7 @@ static char * number(char * str, long num, int base, int size, int precision, in | |||
389 | if (num == 0) | 406 | if (num == 0) |
390 | tmp[i++]='0'; | 407 | tmp[i++]='0'; |
391 | else while (num != 0) { | 408 | else while (num != 0) { |
392 | tmp[i++] = digits[num % base]; | 409 | tmp[i++] = digits[do_div(num, base)]; |
393 | num /= base; | ||
394 | } | 410 | } |
395 | if (i > precision) | 411 | if (i > precision) |
396 | precision = i; | 412 | precision = i; |
@@ -426,7 +442,7 @@ int sprintf(char * buf, const char *fmt, ...); | |||
426 | int vsprintf(char *buf, const char *fmt, va_list args) | 442 | int vsprintf(char *buf, const char *fmt, va_list args) |
427 | { | 443 | { |
428 | int len; | 444 | int len; |
429 | unsigned long num; | 445 | unsigned long long num; |
430 | int i, base; | 446 | int i, base; |
431 | char * str; | 447 | char * str; |
432 | const char *s; | 448 | const char *s; |
diff --git a/arch/ppc64/boot/start.c b/arch/ppc64/boot/start.c deleted file mode 100644 index ea247e79b55e..000000000000 --- a/arch/ppc64/boot/start.c +++ /dev/null | |||
@@ -1,654 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | #include <stdarg.h> | ||
10 | #include <linux/types.h> | ||
11 | #include <linux/string.h> | ||
12 | #include <linux/ctype.h> | ||
13 | |||
14 | #include <asm/div64.h> | ||
15 | |||
16 | int (*prom)(void *); | ||
17 | |||
18 | void *chosen_handle; | ||
19 | void *stdin; | ||
20 | void *stdout; | ||
21 | void *stderr; | ||
22 | |||
23 | void exit(void); | ||
24 | void *finddevice(const char *name); | ||
25 | int getprop(void *phandle, const char *name, void *buf, int buflen); | ||
26 | void chrpboot(int a1, int a2, void *prom); /* in main.c */ | ||
27 | |||
28 | void printk(char *fmt, ...); | ||
29 | |||
30 | void | ||
31 | start(int a1, int a2, void *promptr) | ||
32 | { | ||
33 | prom = (int (*)(void *)) promptr; | ||
34 | chosen_handle = finddevice("/chosen"); | ||
35 | if (chosen_handle == (void *) -1) | ||
36 | exit(); | ||
37 | if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4) | ||
38 | exit(); | ||
39 | stderr = stdout; | ||
40 | if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) | ||
41 | exit(); | ||
42 | |||
43 | chrpboot(a1, a2, promptr); | ||
44 | for (;;) | ||
45 | exit(); | ||
46 | } | ||
47 | |||
48 | int | ||
49 | write(void *handle, void *ptr, int nb) | ||
50 | { | ||
51 | struct prom_args { | ||
52 | char *service; | ||
53 | int nargs; | ||
54 | int nret; | ||
55 | void *ihandle; | ||
56 | void *addr; | ||
57 | int len; | ||
58 | int actual; | ||
59 | } args; | ||
60 | |||
61 | args.service = "write"; | ||
62 | args.nargs = 3; | ||
63 | args.nret = 1; | ||
64 | args.ihandle = handle; | ||
65 | args.addr = ptr; | ||
66 | args.len = nb; | ||
67 | args.actual = -1; | ||
68 | (*prom)(&args); | ||
69 | return args.actual; | ||
70 | } | ||
71 | |||
72 | int | ||
73 | read(void *handle, void *ptr, int nb) | ||
74 | { | ||
75 | struct prom_args { | ||
76 | char *service; | ||
77 | int nargs; | ||
78 | int nret; | ||
79 | void *ihandle; | ||
80 | void *addr; | ||
81 | int len; | ||
82 | int actual; | ||
83 | } args; | ||
84 | |||
85 | args.service = "read"; | ||
86 | args.nargs = 3; | ||
87 | args.nret = 1; | ||
88 | args.ihandle = handle; | ||
89 | args.addr = ptr; | ||
90 | args.len = nb; | ||
91 | args.actual = -1; | ||
92 | (*prom)(&args); | ||
93 | return args.actual; | ||
94 | } | ||
95 | |||
96 | void | ||
97 | exit() | ||
98 | { | ||
99 | struct prom_args { | ||
100 | char *service; | ||
101 | } args; | ||
102 | |||
103 | for (;;) { | ||
104 | args.service = "exit"; | ||
105 | (*prom)(&args); | ||
106 | } | ||
107 | } | ||
108 | |||
109 | void | ||
110 | pause(void) | ||
111 | { | ||
112 | struct prom_args { | ||
113 | char *service; | ||
114 | } args; | ||
115 | |||
116 | args.service = "enter"; | ||
117 | (*prom)(&args); | ||
118 | } | ||
119 | |||
120 | void * | ||
121 | finddevice(const char *name) | ||
122 | { | ||
123 | struct prom_args { | ||
124 | char *service; | ||
125 | int nargs; | ||
126 | int nret; | ||
127 | const char *devspec; | ||
128 | void *phandle; | ||
129 | } args; | ||
130 | |||
131 | args.service = "finddevice"; | ||
132 | args.nargs = 1; | ||
133 | args.nret = 1; | ||
134 | args.devspec = name; | ||
135 | args.phandle = (void *) -1; | ||
136 | (*prom)(&args); | ||
137 | return args.phandle; | ||
138 | } | ||
139 | |||
140 | void * | ||
141 | claim(unsigned long virt, unsigned long size, unsigned long align) | ||
142 | { | ||
143 | struct prom_args { | ||
144 | char *service; | ||
145 | int nargs; | ||
146 | int nret; | ||
147 | unsigned int virt; | ||
148 | unsigned int size; | ||
149 | unsigned int align; | ||
150 | void *ret; | ||
151 | } args; | ||
152 | |||
153 | args.service = "claim"; | ||
154 | args.nargs = 3; | ||
155 | args.nret = 1; | ||
156 | args.virt = virt; | ||
157 | args.size = size; | ||
158 | args.align = align; | ||
159 | (*prom)(&args); | ||
160 | return args.ret; | ||
161 | } | ||
162 | |||
163 | int | ||
164 | getprop(void *phandle, const char *name, void *buf, int buflen) | ||
165 | { | ||
166 | struct prom_args { | ||
167 | char *service; | ||
168 | int nargs; | ||
169 | int nret; | ||
170 | void *phandle; | ||
171 | const char *name; | ||
172 | void *buf; | ||
173 | int buflen; | ||
174 | int size; | ||
175 | } args; | ||
176 | |||
177 | args.service = "getprop"; | ||
178 | args.nargs = 4; | ||
179 | args.nret = 1; | ||
180 | args.phandle = phandle; | ||
181 | args.name = name; | ||
182 | args.buf = buf; | ||
183 | args.buflen = buflen; | ||
184 | args.size = -1; | ||
185 | (*prom)(&args); | ||
186 | return args.size; | ||
187 | } | ||
188 | |||
189 | int | ||
190 | putc(int c, void *f) | ||
191 | { | ||
192 | char ch = c; | ||
193 | |||
194 | if (c == '\n') | ||
195 | putc('\r', f); | ||
196 | return write(f, &ch, 1) == 1? c: -1; | ||
197 | } | ||
198 | |||
199 | int | ||
200 | putchar(int c) | ||
201 | { | ||
202 | return putc(c, stdout); | ||
203 | } | ||
204 | |||
205 | int | ||
206 | fputs(char *str, void *f) | ||
207 | { | ||
208 | int n = strlen(str); | ||
209 | |||
210 | return write(f, str, n) == n? 0: -1; | ||
211 | } | ||
212 | |||
213 | int | ||
214 | readchar(void) | ||
215 | { | ||
216 | char ch; | ||
217 | |||
218 | for (;;) { | ||
219 | switch (read(stdin, &ch, 1)) { | ||
220 | case 1: | ||
221 | return ch; | ||
222 | case -1: | ||
223 | printk("read(stdin) returned -1\r\n"); | ||
224 | return -1; | ||
225 | } | ||
226 | } | ||
227 | } | ||
228 | |||
229 | static char line[256]; | ||
230 | static char *lineptr; | ||
231 | static int lineleft; | ||
232 | |||
233 | int | ||
234 | getchar(void) | ||
235 | { | ||
236 | int c; | ||
237 | |||
238 | if (lineleft == 0) { | ||
239 | lineptr = line; | ||
240 | for (;;) { | ||
241 | c = readchar(); | ||
242 | if (c == -1 || c == 4) | ||
243 | break; | ||
244 | if (c == '\r' || c == '\n') { | ||
245 | *lineptr++ = '\n'; | ||
246 | putchar('\n'); | ||
247 | break; | ||
248 | } | ||
249 | switch (c) { | ||
250 | case 0177: | ||
251 | case '\b': | ||
252 | if (lineptr > line) { | ||
253 | putchar('\b'); | ||
254 | putchar(' '); | ||
255 | putchar('\b'); | ||
256 | --lineptr; | ||
257 | } | ||
258 | break; | ||
259 | case 'U' & 0x1F: | ||
260 | while (lineptr > line) { | ||
261 | putchar('\b'); | ||
262 | putchar(' '); | ||
263 | putchar('\b'); | ||
264 | --lineptr; | ||
265 | } | ||
266 | break; | ||
267 | default: | ||
268 | if (lineptr >= &line[sizeof(line) - 1]) | ||
269 | putchar('\a'); | ||
270 | else { | ||
271 | putchar(c); | ||
272 | *lineptr++ = c; | ||
273 | } | ||
274 | } | ||
275 | } | ||
276 | lineleft = lineptr - line; | ||
277 | lineptr = line; | ||
278 | } | ||
279 | if (lineleft == 0) | ||
280 | return -1; | ||
281 | --lineleft; | ||
282 | return *lineptr++; | ||
283 | } | ||
284 | |||
285 | |||
286 | |||
287 | /* String functions lifted from lib/vsprintf.c and lib/ctype.c */ | ||
288 | unsigned char _ctype[] = { | ||
289 | _C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ | ||
290 | _C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ | ||
291 | _C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ | ||
292 | _C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ | ||
293 | _S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ | ||
294 | _P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ | ||
295 | _D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ | ||
296 | _D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ | ||
297 | _P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ | ||
298 | _U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ | ||
299 | _U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ | ||
300 | _U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ | ||
301 | _P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ | ||
302 | _L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ | ||
303 | _L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ | ||
304 | _L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ | ||
305 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ | ||
306 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ | ||
307 | _S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */ | ||
308 | _P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */ | ||
309 | _U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */ | ||
310 | _U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */ | ||
311 | _L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */ | ||
312 | _L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */ | ||
313 | |||
314 | size_t strnlen(const char * s, size_t count) | ||
315 | { | ||
316 | const char *sc; | ||
317 | |||
318 | for (sc = s; count-- && *sc != '\0'; ++sc) | ||
319 | /* nothing */; | ||
320 | return sc - s; | ||
321 | } | ||
322 | |||
323 | unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base) | ||
324 | { | ||
325 | unsigned long result = 0,value; | ||
326 | |||
327 | if (!base) { | ||
328 | base = 10; | ||
329 | if (*cp == '0') { | ||
330 | base = 8; | ||
331 | cp++; | ||
332 | if ((*cp == 'x') && isxdigit(cp[1])) { | ||
333 | cp++; | ||
334 | base = 16; | ||
335 | } | ||
336 | } | ||
337 | } | ||
338 | while (isxdigit(*cp) && | ||
339 | (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) { | ||
340 | result = result*base + value; | ||
341 | cp++; | ||
342 | } | ||
343 | if (endp) | ||
344 | *endp = (char *)cp; | ||
345 | return result; | ||
346 | } | ||
347 | |||
348 | long simple_strtol(const char *cp,char **endp,unsigned int base) | ||
349 | { | ||
350 | if(*cp=='-') | ||
351 | return -simple_strtoul(cp+1,endp,base); | ||
352 | return simple_strtoul(cp,endp,base); | ||
353 | } | ||
354 | |||
355 | static int skip_atoi(const char **s) | ||
356 | { | ||
357 | int i=0; | ||
358 | |||
359 | while (isdigit(**s)) | ||
360 | i = i*10 + *((*s)++) - '0'; | ||
361 | return i; | ||
362 | } | ||
363 | |||
364 | #define ZEROPAD 1 /* pad with zero */ | ||
365 | #define SIGN 2 /* unsigned/signed long */ | ||
366 | #define PLUS 4 /* show plus */ | ||
367 | #define SPACE 8 /* space if plus */ | ||
368 | #define LEFT 16 /* left justified */ | ||
369 | #define SPECIAL 32 /* 0x */ | ||
370 | #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ | ||
371 | |||
372 | static char * number(char * str, long long num, int base, int size, int precision, int type) | ||
373 | { | ||
374 | char c,sign,tmp[66]; | ||
375 | const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; | ||
376 | int i; | ||
377 | |||
378 | if (type & LARGE) | ||
379 | digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | ||
380 | if (type & LEFT) | ||
381 | type &= ~ZEROPAD; | ||
382 | if (base < 2 || base > 36) | ||
383 | return 0; | ||
384 | c = (type & ZEROPAD) ? '0' : ' '; | ||
385 | sign = 0; | ||
386 | if (type & SIGN) { | ||
387 | if (num < 0) { | ||
388 | sign = '-'; | ||
389 | num = -num; | ||
390 | size--; | ||
391 | } else if (type & PLUS) { | ||
392 | sign = '+'; | ||
393 | size--; | ||
394 | } else if (type & SPACE) { | ||
395 | sign = ' '; | ||
396 | size--; | ||
397 | } | ||
398 | } | ||
399 | if (type & SPECIAL) { | ||
400 | if (base == 16) | ||
401 | size -= 2; | ||
402 | else if (base == 8) | ||
403 | size--; | ||
404 | } | ||
405 | i = 0; | ||
406 | if (num == 0) | ||
407 | tmp[i++]='0'; | ||
408 | else while (num != 0) | ||
409 | tmp[i++] = digits[do_div(num,base)]; | ||
410 | if (i > precision) | ||
411 | precision = i; | ||
412 | size -= precision; | ||
413 | if (!(type&(ZEROPAD+LEFT))) | ||
414 | while(size-->0) | ||
415 | *str++ = ' '; | ||
416 | if (sign) | ||
417 | *str++ = sign; | ||
418 | if (type & SPECIAL) { | ||
419 | if (base==8) | ||
420 | *str++ = '0'; | ||
421 | else if (base==16) { | ||
422 | *str++ = '0'; | ||
423 | *str++ = digits[33]; | ||
424 | } | ||
425 | } | ||
426 | if (!(type & LEFT)) | ||
427 | while (size-- > 0) | ||
428 | *str++ = c; | ||
429 | while (i < precision--) | ||
430 | *str++ = '0'; | ||
431 | while (i-- > 0) | ||
432 | *str++ = tmp[i]; | ||
433 | while (size-- > 0) | ||
434 | *str++ = ' '; | ||
435 | return str; | ||
436 | } | ||
437 | |||
438 | /* Forward decl. needed for IP address printing stuff... */ | ||
439 | int sprintf(char * buf, const char *fmt, ...); | ||
440 | |||
441 | int vsprintf(char *buf, const char *fmt, va_list args) | ||
442 | { | ||
443 | int len; | ||
444 | unsigned long long num; | ||
445 | int i, base; | ||
446 | char * str; | ||
447 | const char *s; | ||
448 | |||
449 | int flags; /* flags to number() */ | ||
450 | |||
451 | int field_width; /* width of output field */ | ||
452 | int precision; /* min. # of digits for integers; max | ||
453 | number of chars for from string */ | ||
454 | int qualifier; /* 'h', 'l', or 'L' for integer fields */ | ||
455 | /* 'z' support added 23/7/1999 S.H. */ | ||
456 | /* 'z' changed to 'Z' --davidm 1/25/99 */ | ||
457 | |||
458 | |||
459 | for (str=buf ; *fmt ; ++fmt) { | ||
460 | if (*fmt != '%') { | ||
461 | *str++ = *fmt; | ||
462 | continue; | ||
463 | } | ||
464 | |||
465 | /* process flags */ | ||
466 | flags = 0; | ||
467 | repeat: | ||
468 | ++fmt; /* this also skips first '%' */ | ||
469 | switch (*fmt) { | ||
470 | case '-': flags |= LEFT; goto repeat; | ||
471 | case '+': flags |= PLUS; goto repeat; | ||
472 | case ' ': flags |= SPACE; goto repeat; | ||
473 | case '#': flags |= SPECIAL; goto repeat; | ||
474 | case '0': flags |= ZEROPAD; goto repeat; | ||
475 | } | ||
476 | |||
477 | /* get field width */ | ||
478 | field_width = -1; | ||
479 | if (isdigit(*fmt)) | ||
480 | field_width = skip_atoi(&fmt); | ||
481 | else if (*fmt == '*') { | ||
482 | ++fmt; | ||
483 | /* it's the next argument */ | ||
484 | field_width = va_arg(args, int); | ||
485 | if (field_width < 0) { | ||
486 | field_width = -field_width; | ||
487 | flags |= LEFT; | ||
488 | } | ||
489 | } | ||
490 | |||
491 | /* get the precision */ | ||
492 | precision = -1; | ||
493 | if (*fmt == '.') { | ||
494 | ++fmt; | ||
495 | if (isdigit(*fmt)) | ||
496 | precision = skip_atoi(&fmt); | ||
497 | else if (*fmt == '*') { | ||
498 | ++fmt; | ||
499 | /* it's the next argument */ | ||
500 | precision = va_arg(args, int); | ||
501 | } | ||
502 | if (precision < 0) | ||
503 | precision = 0; | ||
504 | } | ||
505 | |||
506 | /* get the conversion qualifier */ | ||
507 | qualifier = -1; | ||
508 | if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') { | ||
509 | qualifier = *fmt; | ||
510 | ++fmt; | ||
511 | } | ||
512 | |||
513 | /* default base */ | ||
514 | base = 10; | ||
515 | |||
516 | switch (*fmt) { | ||
517 | case 'c': | ||
518 | if (!(flags & LEFT)) | ||
519 | while (--field_width > 0) | ||
520 | *str++ = ' '; | ||
521 | *str++ = (unsigned char) va_arg(args, int); | ||
522 | while (--field_width > 0) | ||
523 | *str++ = ' '; | ||
524 | continue; | ||
525 | |||
526 | case 's': | ||
527 | s = va_arg(args, char *); | ||
528 | if (!s) | ||
529 | s = "<NULL>"; | ||
530 | |||
531 | len = strnlen(s, precision); | ||
532 | |||
533 | if (!(flags & LEFT)) | ||
534 | while (len < field_width--) | ||
535 | *str++ = ' '; | ||
536 | for (i = 0; i < len; ++i) | ||
537 | *str++ = *s++; | ||
538 | while (len < field_width--) | ||
539 | *str++ = ' '; | ||
540 | continue; | ||
541 | |||
542 | case 'p': | ||
543 | if (field_width == -1) { | ||
544 | field_width = 2*sizeof(void *); | ||
545 | flags |= ZEROPAD; | ||
546 | } | ||
547 | str = number(str, | ||
548 | (unsigned long) va_arg(args, void *), 16, | ||
549 | field_width, precision, flags); | ||
550 | continue; | ||
551 | |||
552 | |||
553 | case 'n': | ||
554 | if (qualifier == 'l') { | ||
555 | long * ip = va_arg(args, long *); | ||
556 | *ip = (str - buf); | ||
557 | } else if (qualifier == 'Z') { | ||
558 | size_t * ip = va_arg(args, size_t *); | ||
559 | *ip = (str - buf); | ||
560 | } else { | ||
561 | int * ip = va_arg(args, int *); | ||
562 | *ip = (str - buf); | ||
563 | } | ||
564 | continue; | ||
565 | |||
566 | case '%': | ||
567 | *str++ = '%'; | ||
568 | continue; | ||
569 | |||
570 | /* integer number formats - set up the flags and "break" */ | ||
571 | case 'o': | ||
572 | base = 8; | ||
573 | break; | ||
574 | |||
575 | case 'X': | ||
576 | flags |= LARGE; | ||
577 | case 'x': | ||
578 | base = 16; | ||
579 | break; | ||
580 | |||
581 | case 'd': | ||
582 | case 'i': | ||
583 | flags |= SIGN; | ||
584 | case 'u': | ||
585 | break; | ||
586 | |||
587 | default: | ||
588 | *str++ = '%'; | ||
589 | if (*fmt) | ||
590 | *str++ = *fmt; | ||
591 | else | ||
592 | --fmt; | ||
593 | continue; | ||
594 | } | ||
595 | if (qualifier == 'L') | ||
596 | num = va_arg(args, long long); | ||
597 | else if (qualifier == 'l') { | ||
598 | num = va_arg(args, unsigned long); | ||
599 | if (flags & SIGN) | ||
600 | num = (signed long) num; | ||
601 | } else if (qualifier == 'Z') { | ||
602 | num = va_arg(args, size_t); | ||
603 | } else if (qualifier == 'h') { | ||
604 | num = (unsigned short) va_arg(args, int); | ||
605 | if (flags & SIGN) | ||
606 | num = (signed short) num; | ||
607 | } else { | ||
608 | num = va_arg(args, unsigned int); | ||
609 | if (flags & SIGN) | ||
610 | num = (signed int) num; | ||
611 | } | ||
612 | str = number(str, num, base, field_width, precision, flags); | ||
613 | } | ||
614 | *str = '\0'; | ||
615 | return str-buf; | ||
616 | } | ||
617 | |||
618 | int sprintf(char * buf, const char *fmt, ...) | ||
619 | { | ||
620 | va_list args; | ||
621 | int i; | ||
622 | |||
623 | va_start(args, fmt); | ||
624 | i=vsprintf(buf,fmt,args); | ||
625 | va_end(args); | ||
626 | return i; | ||
627 | } | ||
628 | |||
629 | static char sprint_buf[1024]; | ||
630 | |||
631 | void | ||
632 | printk(char *fmt, ...) | ||
633 | { | ||
634 | va_list args; | ||
635 | int n; | ||
636 | |||
637 | va_start(args, fmt); | ||
638 | n = vsprintf(sprint_buf, fmt, args); | ||
639 | va_end(args); | ||
640 | write(stdout, sprint_buf, n); | ||
641 | } | ||
642 | |||
643 | int | ||
644 | printf(char *fmt, ...) | ||
645 | { | ||
646 | va_list args; | ||
647 | int n; | ||
648 | |||
649 | va_start(args, fmt); | ||
650 | n = vsprintf(sprint_buf, fmt, args); | ||
651 | va_end(args); | ||
652 | write(stdout, sprint_buf, n); | ||
653 | return n; | ||
654 | } | ||
diff --git a/arch/ppc64/configs/g5_defconfig b/arch/ppc64/configs/g5_defconfig index 0f90df0b3f9c..1eb33398648e 100644 --- a/arch/ppc64/configs/g5_defconfig +++ b/arch/ppc64/configs/g5_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.11 | 3 | # Linux kernel version: 2.6.12-rc6 |
4 | # Thu Mar 10 16:47:04 2005 | 4 | # Tue Jun 14 16:59:20 2005 |
5 | # | 5 | # |
6 | CONFIG_64BIT=y | 6 | CONFIG_64BIT=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
@@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y | |||
11 | CONFIG_HAVE_DEC_LOCK=y | 11 | CONFIG_HAVE_DEC_LOCK=y |
12 | CONFIG_EARLY_PRINTK=y | 12 | CONFIG_EARLY_PRINTK=y |
13 | CONFIG_COMPAT=y | 13 | CONFIG_COMPAT=y |
14 | CONFIG_FRAME_POINTER=y | 14 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y |
15 | CONFIG_FORCE_MAX_ZONEORDER=13 | 15 | CONFIG_FORCE_MAX_ZONEORDER=13 |
16 | 16 | ||
17 | # | 17 | # |
@@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13 | |||
20 | CONFIG_EXPERIMENTAL=y | 20 | CONFIG_EXPERIMENTAL=y |
21 | CONFIG_CLEAN_COMPILE=y | 21 | CONFIG_CLEAN_COMPILE=y |
22 | CONFIG_LOCK_KERNEL=y | 22 | CONFIG_LOCK_KERNEL=y |
23 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
23 | 24 | ||
24 | # | 25 | # |
25 | # General setup | 26 | # General setup |
@@ -31,19 +32,20 @@ CONFIG_POSIX_MQUEUE=y | |||
31 | # CONFIG_BSD_PROCESS_ACCT is not set | 32 | # CONFIG_BSD_PROCESS_ACCT is not set |
32 | CONFIG_SYSCTL=y | 33 | CONFIG_SYSCTL=y |
33 | # CONFIG_AUDIT is not set | 34 | # CONFIG_AUDIT is not set |
34 | CONFIG_LOG_BUF_SHIFT=17 | ||
35 | CONFIG_HOTPLUG=y | 35 | CONFIG_HOTPLUG=y |
36 | CONFIG_KOBJECT_UEVENT=y | 36 | CONFIG_KOBJECT_UEVENT=y |
37 | CONFIG_IKCONFIG=y | 37 | CONFIG_IKCONFIG=y |
38 | CONFIG_IKCONFIG_PROC=y | 38 | CONFIG_IKCONFIG_PROC=y |
39 | # CONFIG_CPUSETS is not set | ||
39 | # CONFIG_EMBEDDED is not set | 40 | # CONFIG_EMBEDDED is not set |
40 | CONFIG_KALLSYMS=y | 41 | CONFIG_KALLSYMS=y |
41 | # CONFIG_KALLSYMS_ALL is not set | 42 | # CONFIG_KALLSYMS_ALL is not set |
42 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 43 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
44 | CONFIG_PRINTK=y | ||
45 | CONFIG_BUG=y | ||
43 | CONFIG_BASE_FULL=y | 46 | CONFIG_BASE_FULL=y |
44 | CONFIG_FUTEX=y | 47 | CONFIG_FUTEX=y |
45 | CONFIG_EPOLL=y | 48 | CONFIG_EPOLL=y |
46 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
47 | CONFIG_SHMEM=y | 49 | CONFIG_SHMEM=y |
48 | CONFIG_CC_ALIGN_FUNCTIONS=0 | 50 | CONFIG_CC_ALIGN_FUNCTIONS=0 |
49 | CONFIG_CC_ALIGN_LABELS=0 | 51 | CONFIG_CC_ALIGN_LABELS=0 |
@@ -87,6 +89,8 @@ CONFIG_NR_CPUS=2 | |||
87 | # CONFIG_SCHED_SMT is not set | 89 | # CONFIG_SCHED_SMT is not set |
88 | # CONFIG_PREEMPT is not set | 90 | # CONFIG_PREEMPT is not set |
89 | CONFIG_GENERIC_HARDIRQS=y | 91 | CONFIG_GENERIC_HARDIRQS=y |
92 | CONFIG_SECCOMP=y | ||
93 | CONFIG_ISA_DMA_API=y | ||
90 | 94 | ||
91 | # | 95 | # |
92 | # General setup | 96 | # General setup |
@@ -97,6 +101,7 @@ CONFIG_BINFMT_ELF=y | |||
97 | # CONFIG_BINFMT_MISC is not set | 101 | # CONFIG_BINFMT_MISC is not set |
98 | CONFIG_PCI_LEGACY_PROC=y | 102 | CONFIG_PCI_LEGACY_PROC=y |
99 | CONFIG_PCI_NAMES=y | 103 | CONFIG_PCI_NAMES=y |
104 | # CONFIG_PCI_DEBUG is not set | ||
100 | # CONFIG_HOTPLUG_CPU is not set | 105 | # CONFIG_HOTPLUG_CPU is not set |
101 | 106 | ||
102 | # | 107 | # |
@@ -105,10 +110,6 @@ CONFIG_PCI_NAMES=y | |||
105 | # CONFIG_PCCARD is not set | 110 | # CONFIG_PCCARD is not set |
106 | 111 | ||
107 | # | 112 | # |
108 | # PC-card bridges | ||
109 | # | ||
110 | |||
111 | # | ||
112 | # PCI Hotplug Support | 113 | # PCI Hotplug Support |
113 | # | 114 | # |
114 | # CONFIG_HOTPLUG_PCI is not set | 115 | # CONFIG_HOTPLUG_PCI is not set |
@@ -293,7 +294,6 @@ CONFIG_SCSI_SATA_SVW=y | |||
293 | # CONFIG_SCSI_BUSLOGIC is not set | 294 | # CONFIG_SCSI_BUSLOGIC is not set |
294 | # CONFIG_SCSI_DMX3191D is not set | 295 | # CONFIG_SCSI_DMX3191D is not set |
295 | # CONFIG_SCSI_EATA is not set | 296 | # CONFIG_SCSI_EATA is not set |
296 | # CONFIG_SCSI_EATA_PIO is not set | ||
297 | # CONFIG_SCSI_FUTURE_DOMAIN is not set | 297 | # CONFIG_SCSI_FUTURE_DOMAIN is not set |
298 | # CONFIG_SCSI_GDTH is not set | 298 | # CONFIG_SCSI_GDTH is not set |
299 | # CONFIG_SCSI_IPS is not set | 299 | # CONFIG_SCSI_IPS is not set |
@@ -301,7 +301,6 @@ CONFIG_SCSI_SATA_SVW=y | |||
301 | # CONFIG_SCSI_INIA100 is not set | 301 | # CONFIG_SCSI_INIA100 is not set |
302 | # CONFIG_SCSI_SYM53C8XX_2 is not set | 302 | # CONFIG_SCSI_SYM53C8XX_2 is not set |
303 | # CONFIG_SCSI_IPR is not set | 303 | # CONFIG_SCSI_IPR is not set |
304 | # CONFIG_SCSI_QLOGIC_ISP is not set | ||
305 | # CONFIG_SCSI_QLOGIC_FC is not set | 304 | # CONFIG_SCSI_QLOGIC_FC is not set |
306 | # CONFIG_SCSI_QLOGIC_1280 is not set | 305 | # CONFIG_SCSI_QLOGIC_1280 is not set |
307 | CONFIG_SCSI_QLA2XXX=y | 306 | CONFIG_SCSI_QLA2XXX=y |
@@ -310,6 +309,7 @@ CONFIG_SCSI_QLA2XXX=y | |||
310 | # CONFIG_SCSI_QLA2300 is not set | 309 | # CONFIG_SCSI_QLA2300 is not set |
311 | # CONFIG_SCSI_QLA2322 is not set | 310 | # CONFIG_SCSI_QLA2322 is not set |
312 | # CONFIG_SCSI_QLA6312 is not set | 311 | # CONFIG_SCSI_QLA6312 is not set |
312 | # CONFIG_SCSI_LPFC is not set | ||
313 | # CONFIG_SCSI_DC395x is not set | 313 | # CONFIG_SCSI_DC395x is not set |
314 | # CONFIG_SCSI_DC390T is not set | 314 | # CONFIG_SCSI_DC390T is not set |
315 | # CONFIG_SCSI_DEBUG is not set | 315 | # CONFIG_SCSI_DEBUG is not set |
@@ -332,6 +332,7 @@ CONFIG_DM_CRYPT=m | |||
332 | CONFIG_DM_SNAPSHOT=m | 332 | CONFIG_DM_SNAPSHOT=m |
333 | CONFIG_DM_MIRROR=m | 333 | CONFIG_DM_MIRROR=m |
334 | CONFIG_DM_ZERO=m | 334 | CONFIG_DM_ZERO=m |
335 | # CONFIG_DM_MULTIPATH is not set | ||
335 | 336 | ||
336 | # | 337 | # |
337 | # Fusion MPT device support | 338 | # Fusion MPT device support |
@@ -394,7 +395,6 @@ CONFIG_NET=y | |||
394 | # | 395 | # |
395 | CONFIG_PACKET=y | 396 | CONFIG_PACKET=y |
396 | # CONFIG_PACKET_MMAP is not set | 397 | # CONFIG_PACKET_MMAP is not set |
397 | # CONFIG_NETLINK_DEV is not set | ||
398 | CONFIG_UNIX=y | 398 | CONFIG_UNIX=y |
399 | CONFIG_NET_KEY=m | 399 | CONFIG_NET_KEY=m |
400 | CONFIG_INET=y | 400 | CONFIG_INET=y |
@@ -564,6 +564,8 @@ CONFIG_E1000=y | |||
564 | # CONFIG_R8169 is not set | 564 | # CONFIG_R8169 is not set |
565 | # CONFIG_SK98LIN is not set | 565 | # CONFIG_SK98LIN is not set |
566 | CONFIG_TIGON3=m | 566 | CONFIG_TIGON3=m |
567 | # CONFIG_BNX2 is not set | ||
568 | # CONFIG_MV643XX_ETH is not set | ||
567 | 569 | ||
568 | # | 570 | # |
569 | # Ethernet (10000 Mbit) | 571 | # Ethernet (10000 Mbit) |
@@ -631,18 +633,6 @@ CONFIG_INPUT_EVDEV=y | |||
631 | # CONFIG_INPUT_EVBUG is not set | 633 | # CONFIG_INPUT_EVBUG is not set |
632 | 634 | ||
633 | # | 635 | # |
634 | # Input I/O drivers | ||
635 | # | ||
636 | # CONFIG_GAMEPORT is not set | ||
637 | CONFIG_SOUND_GAMEPORT=y | ||
638 | CONFIG_SERIO=y | ||
639 | # CONFIG_SERIO_I8042 is not set | ||
640 | # CONFIG_SERIO_SERPORT is not set | ||
641 | # CONFIG_SERIO_CT82C710 is not set | ||
642 | # CONFIG_SERIO_PCIPS2 is not set | ||
643 | # CONFIG_SERIO_RAW is not set | ||
644 | |||
645 | # | ||
646 | # Input Device Drivers | 636 | # Input Device Drivers |
647 | # | 637 | # |
648 | CONFIG_INPUT_KEYBOARD=y | 638 | CONFIG_INPUT_KEYBOARD=y |
@@ -660,6 +650,16 @@ CONFIG_INPUT_MOUSE=y | |||
660 | # CONFIG_INPUT_MISC is not set | 650 | # CONFIG_INPUT_MISC is not set |
661 | 651 | ||
662 | # | 652 | # |
653 | # Hardware I/O ports | ||
654 | # | ||
655 | CONFIG_SERIO=y | ||
656 | # CONFIG_SERIO_I8042 is not set | ||
657 | # CONFIG_SERIO_SERPORT is not set | ||
658 | # CONFIG_SERIO_PCIPS2 is not set | ||
659 | # CONFIG_SERIO_RAW is not set | ||
660 | # CONFIG_GAMEPORT is not set | ||
661 | |||
662 | # | ||
663 | # Character devices | 663 | # Character devices |
664 | # | 664 | # |
665 | CONFIG_VT=y | 665 | CONFIG_VT=y |
@@ -676,6 +676,7 @@ CONFIG_HW_CONSOLE=y | |||
676 | # Non-8250 serial port support | 676 | # Non-8250 serial port support |
677 | # | 677 | # |
678 | # CONFIG_SERIAL_PMACZILOG is not set | 678 | # CONFIG_SERIAL_PMACZILOG is not set |
679 | # CONFIG_SERIAL_JSM is not set | ||
679 | CONFIG_UNIX98_PTYS=y | 680 | CONFIG_UNIX98_PTYS=y |
680 | CONFIG_LEGACY_PTYS=y | 681 | CONFIG_LEGACY_PTYS=y |
681 | CONFIG_LEGACY_PTY_COUNT=256 | 682 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -698,9 +699,12 @@ CONFIG_LEGACY_PTY_COUNT=256 | |||
698 | # | 699 | # |
699 | # Ftape, the floppy tape device driver | 700 | # Ftape, the floppy tape device driver |
700 | # | 701 | # |
702 | CONFIG_AGP=m | ||
703 | CONFIG_AGP_UNINORTH=m | ||
701 | # CONFIG_DRM is not set | 704 | # CONFIG_DRM is not set |
702 | CONFIG_RAW_DRIVER=y | 705 | CONFIG_RAW_DRIVER=y |
703 | CONFIG_MAX_RAW_DEVS=256 | 706 | CONFIG_MAX_RAW_DEVS=256 |
707 | # CONFIG_HANGCHECK_TIMER is not set | ||
704 | 708 | ||
705 | # | 709 | # |
706 | # TPM devices | 710 | # TPM devices |
@@ -730,12 +734,11 @@ CONFIG_I2C_ALGOBIT=y | |||
730 | # CONFIG_I2C_AMD8111 is not set | 734 | # CONFIG_I2C_AMD8111 is not set |
731 | # CONFIG_I2C_I801 is not set | 735 | # CONFIG_I2C_I801 is not set |
732 | # CONFIG_I2C_I810 is not set | 736 | # CONFIG_I2C_I810 is not set |
737 | # CONFIG_I2C_PIIX4 is not set | ||
733 | # CONFIG_I2C_ISA is not set | 738 | # CONFIG_I2C_ISA is not set |
734 | CONFIG_I2C_KEYWEST=y | 739 | CONFIG_I2C_KEYWEST=y |
735 | # CONFIG_I2C_MPC is not set | ||
736 | # CONFIG_I2C_NFORCE2 is not set | 740 | # CONFIG_I2C_NFORCE2 is not set |
737 | # CONFIG_I2C_PARPORT_LIGHT is not set | 741 | # CONFIG_I2C_PARPORT_LIGHT is not set |
738 | # CONFIG_I2C_PIIX4 is not set | ||
739 | # CONFIG_I2C_PROSAVAGE is not set | 742 | # CONFIG_I2C_PROSAVAGE is not set |
740 | # CONFIG_I2C_SAVAGE4 is not set | 743 | # CONFIG_I2C_SAVAGE4 is not set |
741 | # CONFIG_SCx200_ACB is not set | 744 | # CONFIG_SCx200_ACB is not set |
@@ -772,6 +775,7 @@ CONFIG_I2C_KEYWEST=y | |||
772 | # CONFIG_SENSORS_LM85 is not set | 775 | # CONFIG_SENSORS_LM85 is not set |
773 | # CONFIG_SENSORS_LM87 is not set | 776 | # CONFIG_SENSORS_LM87 is not set |
774 | # CONFIG_SENSORS_LM90 is not set | 777 | # CONFIG_SENSORS_LM90 is not set |
778 | # CONFIG_SENSORS_LM92 is not set | ||
775 | # CONFIG_SENSORS_MAX1619 is not set | 779 | # CONFIG_SENSORS_MAX1619 is not set |
776 | # CONFIG_SENSORS_PC87360 is not set | 780 | # CONFIG_SENSORS_PC87360 is not set |
777 | # CONFIG_SENSORS_SMSC47B397 is not set | 781 | # CONFIG_SENSORS_SMSC47B397 is not set |
@@ -785,6 +789,7 @@ CONFIG_I2C_KEYWEST=y | |||
785 | # | 789 | # |
786 | # Other I2C Chip support | 790 | # Other I2C Chip support |
787 | # | 791 | # |
792 | # CONFIG_SENSORS_DS1337 is not set | ||
788 | # CONFIG_SENSORS_EEPROM is not set | 793 | # CONFIG_SENSORS_EEPROM is not set |
789 | # CONFIG_SENSORS_PCF8574 is not set | 794 | # CONFIG_SENSORS_PCF8574 is not set |
790 | # CONFIG_SENSORS_PCF8591 is not set | 795 | # CONFIG_SENSORS_PCF8591 is not set |
@@ -817,6 +822,11 @@ CONFIG_I2C_KEYWEST=y | |||
817 | # Graphics support | 822 | # Graphics support |
818 | # | 823 | # |
819 | CONFIG_FB=y | 824 | CONFIG_FB=y |
825 | CONFIG_FB_CFB_FILLRECT=y | ||
826 | CONFIG_FB_CFB_COPYAREA=y | ||
827 | CONFIG_FB_CFB_IMAGEBLIT=y | ||
828 | CONFIG_FB_SOFT_CURSOR=y | ||
829 | CONFIG_FB_MACMODES=y | ||
820 | CONFIG_FB_MODE_HELPERS=y | 830 | CONFIG_FB_MODE_HELPERS=y |
821 | CONFIG_FB_TILEBLITTING=y | 831 | CONFIG_FB_TILEBLITTING=y |
822 | # CONFIG_FB_CIRRUS is not set | 832 | # CONFIG_FB_CIRRUS is not set |
@@ -830,6 +840,7 @@ CONFIG_FB_OF=y | |||
830 | # CONFIG_FB_ASILIANT is not set | 840 | # CONFIG_FB_ASILIANT is not set |
831 | # CONFIG_FB_IMSTT is not set | 841 | # CONFIG_FB_IMSTT is not set |
832 | # CONFIG_FB_VGA16 is not set | 842 | # CONFIG_FB_VGA16 is not set |
843 | # CONFIG_FB_NVIDIA is not set | ||
833 | CONFIG_FB_RIVA=y | 844 | CONFIG_FB_RIVA=y |
834 | # CONFIG_FB_RIVA_I2C is not set | 845 | # CONFIG_FB_RIVA_I2C is not set |
835 | # CONFIG_FB_RIVA_DEBUG is not set | 846 | # CONFIG_FB_RIVA_DEBUG is not set |
@@ -847,6 +858,7 @@ CONFIG_FB_RADEON_I2C=y | |||
847 | # CONFIG_FB_3DFX is not set | 858 | # CONFIG_FB_3DFX is not set |
848 | # CONFIG_FB_VOODOO1 is not set | 859 | # CONFIG_FB_VOODOO1 is not set |
849 | # CONFIG_FB_TRIDENT is not set | 860 | # CONFIG_FB_TRIDENT is not set |
861 | # CONFIG_FB_S1D13XXX is not set | ||
850 | # CONFIG_FB_VIRTUAL is not set | 862 | # CONFIG_FB_VIRTUAL is not set |
851 | 863 | ||
852 | # | 864 | # |
@@ -880,6 +892,8 @@ CONFIG_LCD_DEVICE=y | |||
880 | # | 892 | # |
881 | # USB support | 893 | # USB support |
882 | # | 894 | # |
895 | CONFIG_USB_ARCH_HAS_HCD=y | ||
896 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
883 | CONFIG_USB=y | 897 | CONFIG_USB=y |
884 | # CONFIG_USB_DEBUG is not set | 898 | # CONFIG_USB_DEBUG is not set |
885 | 899 | ||
@@ -890,8 +904,6 @@ CONFIG_USB_DEVICEFS=y | |||
890 | # CONFIG_USB_BANDWIDTH is not set | 904 | # CONFIG_USB_BANDWIDTH is not set |
891 | # CONFIG_USB_DYNAMIC_MINORS is not set | 905 | # CONFIG_USB_DYNAMIC_MINORS is not set |
892 | # CONFIG_USB_OTG is not set | 906 | # CONFIG_USB_OTG is not set |
893 | CONFIG_USB_ARCH_HAS_HCD=y | ||
894 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
895 | 907 | ||
896 | # | 908 | # |
897 | # USB Host Controller Drivers | 909 | # USB Host Controller Drivers |
@@ -917,7 +929,6 @@ CONFIG_USB_PRINTER=y | |||
917 | # | 929 | # |
918 | CONFIG_USB_STORAGE=y | 930 | CONFIG_USB_STORAGE=y |
919 | # CONFIG_USB_STORAGE_DEBUG is not set | 931 | # CONFIG_USB_STORAGE_DEBUG is not set |
920 | CONFIG_USB_STORAGE_RW_DETECT=y | ||
921 | CONFIG_USB_STORAGE_DATAFAB=y | 932 | CONFIG_USB_STORAGE_DATAFAB=y |
922 | CONFIG_USB_STORAGE_FREECOM=y | 933 | CONFIG_USB_STORAGE_FREECOM=y |
923 | CONFIG_USB_STORAGE_ISD200=y | 934 | CONFIG_USB_STORAGE_ISD200=y |
@@ -1004,8 +1015,10 @@ CONFIG_USB_MON=y | |||
1004 | # | 1015 | # |
1005 | CONFIG_USB_SERIAL=m | 1016 | CONFIG_USB_SERIAL=m |
1006 | CONFIG_USB_SERIAL_GENERIC=y | 1017 | CONFIG_USB_SERIAL_GENERIC=y |
1018 | # CONFIG_USB_SERIAL_AIRPRIME is not set | ||
1007 | CONFIG_USB_SERIAL_BELKIN=m | 1019 | CONFIG_USB_SERIAL_BELKIN=m |
1008 | CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m | 1020 | CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m |
1021 | # CONFIG_USB_SERIAL_CP2101 is not set | ||
1009 | CONFIG_USB_SERIAL_CYPRESS_M8=m | 1022 | CONFIG_USB_SERIAL_CYPRESS_M8=m |
1010 | CONFIG_USB_SERIAL_EMPEG=m | 1023 | CONFIG_USB_SERIAL_EMPEG=m |
1011 | CONFIG_USB_SERIAL_FTDI_SIO=m | 1024 | CONFIG_USB_SERIAL_FTDI_SIO=m |
@@ -1034,6 +1047,7 @@ CONFIG_USB_SERIAL_KLSI=m | |||
1034 | CONFIG_USB_SERIAL_KOBIL_SCT=m | 1047 | CONFIG_USB_SERIAL_KOBIL_SCT=m |
1035 | CONFIG_USB_SERIAL_MCT_U232=m | 1048 | CONFIG_USB_SERIAL_MCT_U232=m |
1036 | CONFIG_USB_SERIAL_PL2303=m | 1049 | CONFIG_USB_SERIAL_PL2303=m |
1050 | # CONFIG_USB_SERIAL_HP4X is not set | ||
1037 | CONFIG_USB_SERIAL_SAFE=m | 1051 | CONFIG_USB_SERIAL_SAFE=m |
1038 | CONFIG_USB_SERIAL_SAFE_PADDED=y | 1052 | CONFIG_USB_SERIAL_SAFE_PADDED=y |
1039 | CONFIG_USB_SERIAL_TI=m | 1053 | CONFIG_USB_SERIAL_TI=m |
@@ -1270,11 +1284,13 @@ CONFIG_OPROFILE=y | |||
1270 | # | 1284 | # |
1271 | # Kernel hacking | 1285 | # Kernel hacking |
1272 | # | 1286 | # |
1287 | # CONFIG_PRINTK_TIME is not set | ||
1273 | CONFIG_DEBUG_KERNEL=y | 1288 | CONFIG_DEBUG_KERNEL=y |
1274 | CONFIG_MAGIC_SYSRQ=y | 1289 | CONFIG_MAGIC_SYSRQ=y |
1275 | # CONFIG_PRINTK_TIME is not set | 1290 | CONFIG_LOG_BUF_SHIFT=17 |
1276 | # CONFIG_SCHEDSTATS is not set | 1291 | # CONFIG_SCHEDSTATS is not set |
1277 | # CONFIG_DEBUG_SLAB is not set | 1292 | # CONFIG_DEBUG_SLAB is not set |
1293 | # CONFIG_DEBUG_SPINLOCK is not set | ||
1278 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | 1294 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set |
1279 | # CONFIG_DEBUG_KOBJECT is not set | 1295 | # CONFIG_DEBUG_KOBJECT is not set |
1280 | # CONFIG_DEBUG_INFO is not set | 1296 | # CONFIG_DEBUG_INFO is not set |
diff --git a/arch/ppc64/configs/iSeries_defconfig b/arch/ppc64/configs/iSeries_defconfig index a39e9d2e25da..f6a2b99afd63 100644 --- a/arch/ppc64/configs/iSeries_defconfig +++ b/arch/ppc64/configs/iSeries_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.11-rc3-bk6 | 3 | # Linux kernel version: 2.6.12-rc6 |
4 | # Wed Feb 9 23:34:52 2005 | 4 | # Tue Jun 14 17:01:28 2005 |
5 | # | 5 | # |
6 | CONFIG_64BIT=y | 6 | CONFIG_64BIT=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
@@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y | |||
11 | CONFIG_HAVE_DEC_LOCK=y | 11 | CONFIG_HAVE_DEC_LOCK=y |
12 | CONFIG_EARLY_PRINTK=y | 12 | CONFIG_EARLY_PRINTK=y |
13 | CONFIG_COMPAT=y | 13 | CONFIG_COMPAT=y |
14 | CONFIG_FRAME_POINTER=y | 14 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y |
15 | CONFIG_FORCE_MAX_ZONEORDER=13 | 15 | CONFIG_FORCE_MAX_ZONEORDER=13 |
16 | 16 | ||
17 | # | 17 | # |
@@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13 | |||
20 | CONFIG_EXPERIMENTAL=y | 20 | CONFIG_EXPERIMENTAL=y |
21 | CONFIG_CLEAN_COMPILE=y | 21 | CONFIG_CLEAN_COMPILE=y |
22 | CONFIG_LOCK_KERNEL=y | 22 | CONFIG_LOCK_KERNEL=y |
23 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
23 | 24 | ||
24 | # | 25 | # |
25 | # General setup | 26 | # General setup |
@@ -30,24 +31,29 @@ CONFIG_SYSVIPC=y | |||
30 | CONFIG_POSIX_MQUEUE=y | 31 | CONFIG_POSIX_MQUEUE=y |
31 | # CONFIG_BSD_PROCESS_ACCT is not set | 32 | # CONFIG_BSD_PROCESS_ACCT is not set |
32 | CONFIG_SYSCTL=y | 33 | CONFIG_SYSCTL=y |
33 | CONFIG_LOG_BUF_SHIFT=17 | 34 | CONFIG_AUDIT=y |
35 | CONFIG_AUDITSYSCALL=y | ||
34 | CONFIG_HOTPLUG=y | 36 | CONFIG_HOTPLUG=y |
35 | CONFIG_KOBJECT_UEVENT=y | 37 | CONFIG_KOBJECT_UEVENT=y |
36 | CONFIG_IKCONFIG=y | 38 | CONFIG_IKCONFIG=y |
37 | CONFIG_IKCONFIG_PROC=y | 39 | CONFIG_IKCONFIG_PROC=y |
40 | # CONFIG_CPUSETS is not set | ||
38 | # CONFIG_EMBEDDED is not set | 41 | # CONFIG_EMBEDDED is not set |
39 | CONFIG_KALLSYMS=y | 42 | CONFIG_KALLSYMS=y |
40 | # CONFIG_KALLSYMS_ALL is not set | 43 | # CONFIG_KALLSYMS_ALL is not set |
41 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 44 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
45 | CONFIG_PRINTK=y | ||
46 | CONFIG_BUG=y | ||
47 | CONFIG_BASE_FULL=y | ||
42 | CONFIG_FUTEX=y | 48 | CONFIG_FUTEX=y |
43 | CONFIG_EPOLL=y | 49 | CONFIG_EPOLL=y |
44 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
45 | CONFIG_SHMEM=y | 50 | CONFIG_SHMEM=y |
46 | CONFIG_CC_ALIGN_FUNCTIONS=0 | 51 | CONFIG_CC_ALIGN_FUNCTIONS=0 |
47 | CONFIG_CC_ALIGN_LABELS=0 | 52 | CONFIG_CC_ALIGN_LABELS=0 |
48 | CONFIG_CC_ALIGN_LOOPS=0 | 53 | CONFIG_CC_ALIGN_LOOPS=0 |
49 | CONFIG_CC_ALIGN_JUMPS=0 | 54 | CONFIG_CC_ALIGN_JUMPS=0 |
50 | # CONFIG_TINY_SHMEM is not set | 55 | # CONFIG_TINY_SHMEM is not set |
56 | CONFIG_BASE_SMALL=0 | ||
51 | 57 | ||
52 | # | 58 | # |
53 | # Loadable module support | 59 | # Loadable module support |
@@ -79,6 +85,8 @@ CONFIG_NR_CPUS=32 | |||
79 | CONFIG_GENERIC_HARDIRQS=y | 85 | CONFIG_GENERIC_HARDIRQS=y |
80 | CONFIG_MSCHUNKS=y | 86 | CONFIG_MSCHUNKS=y |
81 | CONFIG_LPARCFG=y | 87 | CONFIG_LPARCFG=y |
88 | CONFIG_SECCOMP=y | ||
89 | CONFIG_ISA_DMA_API=y | ||
82 | 90 | ||
83 | # | 91 | # |
84 | # General setup | 92 | # General setup |
@@ -89,6 +97,7 @@ CONFIG_BINFMT_ELF=y | |||
89 | # CONFIG_BINFMT_MISC is not set | 97 | # CONFIG_BINFMT_MISC is not set |
90 | CONFIG_PCI_LEGACY_PROC=y | 98 | CONFIG_PCI_LEGACY_PROC=y |
91 | CONFIG_PCI_NAMES=y | 99 | CONFIG_PCI_NAMES=y |
100 | # CONFIG_PCI_DEBUG is not set | ||
92 | 101 | ||
93 | # | 102 | # |
94 | # PCCARD (PCMCIA/CardBus) support | 103 | # PCCARD (PCMCIA/CardBus) support |
@@ -96,10 +105,6 @@ CONFIG_PCI_NAMES=y | |||
96 | # CONFIG_PCCARD is not set | 105 | # CONFIG_PCCARD is not set |
97 | 106 | ||
98 | # | 107 | # |
99 | # PC-card bridges | ||
100 | # | ||
101 | |||
102 | # | ||
103 | # PCI Hotplug Support | 108 | # PCI Hotplug Support |
104 | # | 109 | # |
105 | # CONFIG_HOTPLUG_PCI is not set | 110 | # CONFIG_HOTPLUG_PCI is not set |
@@ -210,7 +215,6 @@ CONFIG_SCSI_FC_ATTRS=y | |||
210 | # CONFIG_SCSI_BUSLOGIC is not set | 215 | # CONFIG_SCSI_BUSLOGIC is not set |
211 | # CONFIG_SCSI_DMX3191D is not set | 216 | # CONFIG_SCSI_DMX3191D is not set |
212 | # CONFIG_SCSI_EATA is not set | 217 | # CONFIG_SCSI_EATA is not set |
213 | # CONFIG_SCSI_EATA_PIO is not set | ||
214 | # CONFIG_SCSI_FUTURE_DOMAIN is not set | 218 | # CONFIG_SCSI_FUTURE_DOMAIN is not set |
215 | # CONFIG_SCSI_GDTH is not set | 219 | # CONFIG_SCSI_GDTH is not set |
216 | # CONFIG_SCSI_IPS is not set | 220 | # CONFIG_SCSI_IPS is not set |
@@ -219,7 +223,6 @@ CONFIG_SCSI_IBMVSCSI=m | |||
219 | # CONFIG_SCSI_INIA100 is not set | 223 | # CONFIG_SCSI_INIA100 is not set |
220 | # CONFIG_SCSI_SYM53C8XX_2 is not set | 224 | # CONFIG_SCSI_SYM53C8XX_2 is not set |
221 | # CONFIG_SCSI_IPR is not set | 225 | # CONFIG_SCSI_IPR is not set |
222 | # CONFIG_SCSI_QLOGIC_ISP is not set | ||
223 | # CONFIG_SCSI_QLOGIC_FC is not set | 226 | # CONFIG_SCSI_QLOGIC_FC is not set |
224 | # CONFIG_SCSI_QLOGIC_1280 is not set | 227 | # CONFIG_SCSI_QLOGIC_1280 is not set |
225 | CONFIG_SCSI_QLA2XXX=y | 228 | CONFIG_SCSI_QLA2XXX=y |
@@ -228,6 +231,7 @@ CONFIG_SCSI_QLA2XXX=y | |||
228 | # CONFIG_SCSI_QLA2300 is not set | 231 | # CONFIG_SCSI_QLA2300 is not set |
229 | # CONFIG_SCSI_QLA2322 is not set | 232 | # CONFIG_SCSI_QLA2322 is not set |
230 | # CONFIG_SCSI_QLA6312 is not set | 233 | # CONFIG_SCSI_QLA6312 is not set |
234 | # CONFIG_SCSI_LPFC is not set | ||
231 | # CONFIG_SCSI_DC395x is not set | 235 | # CONFIG_SCSI_DC395x is not set |
232 | # CONFIG_SCSI_DC390T is not set | 236 | # CONFIG_SCSI_DC390T is not set |
233 | # CONFIG_SCSI_DEBUG is not set | 237 | # CONFIG_SCSI_DEBUG is not set |
@@ -250,6 +254,7 @@ CONFIG_DM_CRYPT=m | |||
250 | CONFIG_DM_SNAPSHOT=m | 254 | CONFIG_DM_SNAPSHOT=m |
251 | CONFIG_DM_MIRROR=m | 255 | CONFIG_DM_MIRROR=m |
252 | CONFIG_DM_ZERO=m | 256 | CONFIG_DM_ZERO=m |
257 | # CONFIG_DM_MULTIPATH is not set | ||
253 | 258 | ||
254 | # | 259 | # |
255 | # Fusion MPT device support | 260 | # Fusion MPT device support |
@@ -280,7 +285,6 @@ CONFIG_NET=y | |||
280 | # | 285 | # |
281 | CONFIG_PACKET=y | 286 | CONFIG_PACKET=y |
282 | # CONFIG_PACKET_MMAP is not set | 287 | # CONFIG_PACKET_MMAP is not set |
283 | # CONFIG_NETLINK_DEV is not set | ||
284 | CONFIG_UNIX=y | 288 | CONFIG_UNIX=y |
285 | CONFIG_NET_KEY=m | 289 | CONFIG_NET_KEY=m |
286 | CONFIG_INET=y | 290 | CONFIG_INET=y |
@@ -445,7 +449,6 @@ CONFIG_PCNET32=y | |||
445 | # CONFIG_DGRS is not set | 449 | # CONFIG_DGRS is not set |
446 | # CONFIG_EEPRO100 is not set | 450 | # CONFIG_EEPRO100 is not set |
447 | CONFIG_E100=y | 451 | CONFIG_E100=y |
448 | # CONFIG_E100_NAPI is not set | ||
449 | # CONFIG_FEALNX is not set | 452 | # CONFIG_FEALNX is not set |
450 | # CONFIG_NATSEMI is not set | 453 | # CONFIG_NATSEMI is not set |
451 | # CONFIG_NE2K_PCI is not set | 454 | # CONFIG_NE2K_PCI is not set |
@@ -471,6 +474,7 @@ CONFIG_E1000=m | |||
471 | # CONFIG_SK98LIN is not set | 474 | # CONFIG_SK98LIN is not set |
472 | # CONFIG_VIA_VELOCITY is not set | 475 | # CONFIG_VIA_VELOCITY is not set |
473 | # CONFIG_TIGON3 is not set | 476 | # CONFIG_TIGON3 is not set |
477 | # CONFIG_BNX2 is not set | ||
474 | 478 | ||
475 | # | 479 | # |
476 | # Ethernet (10000 Mbit) | 480 | # Ethernet (10000 Mbit) |
@@ -539,14 +543,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | |||
539 | # CONFIG_INPUT_EVBUG is not set | 543 | # CONFIG_INPUT_EVBUG is not set |
540 | 544 | ||
541 | # | 545 | # |
542 | # Input I/O drivers | ||
543 | # | ||
544 | # CONFIG_GAMEPORT is not set | ||
545 | CONFIG_SOUND_GAMEPORT=y | ||
546 | # CONFIG_SERIO is not set | ||
547 | # CONFIG_SERIO_I8042 is not set | ||
548 | |||
549 | # | ||
550 | # Input Device Drivers | 546 | # Input Device Drivers |
551 | # | 547 | # |
552 | # CONFIG_INPUT_KEYBOARD is not set | 548 | # CONFIG_INPUT_KEYBOARD is not set |
@@ -556,6 +552,12 @@ CONFIG_SOUND_GAMEPORT=y | |||
556 | # CONFIG_INPUT_MISC is not set | 552 | # CONFIG_INPUT_MISC is not set |
557 | 553 | ||
558 | # | 554 | # |
555 | # Hardware I/O ports | ||
556 | # | ||
557 | # CONFIG_SERIO is not set | ||
558 | # CONFIG_GAMEPORT is not set | ||
559 | |||
560 | # | ||
559 | # Character devices | 561 | # Character devices |
560 | # | 562 | # |
561 | # CONFIG_SERIAL_NONSTANDARD is not set | 563 | # CONFIG_SERIAL_NONSTANDARD is not set |
@@ -570,6 +572,7 @@ CONFIG_SOUND_GAMEPORT=y | |||
570 | # | 572 | # |
571 | CONFIG_SERIAL_CORE=m | 573 | CONFIG_SERIAL_CORE=m |
572 | CONFIG_SERIAL_ICOM=m | 574 | CONFIG_SERIAL_ICOM=m |
575 | # CONFIG_SERIAL_JSM is not set | ||
573 | CONFIG_UNIX98_PTYS=y | 576 | CONFIG_UNIX98_PTYS=y |
574 | CONFIG_LEGACY_PTYS=y | 577 | CONFIG_LEGACY_PTYS=y |
575 | CONFIG_LEGACY_PTY_COUNT=256 | 578 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -592,9 +595,16 @@ CONFIG_LEGACY_PTY_COUNT=256 | |||
592 | # | 595 | # |
593 | # Ftape, the floppy tape device driver | 596 | # Ftape, the floppy tape device driver |
594 | # | 597 | # |
598 | # CONFIG_AGP is not set | ||
595 | # CONFIG_DRM is not set | 599 | # CONFIG_DRM is not set |
596 | CONFIG_RAW_DRIVER=y | 600 | CONFIG_RAW_DRIVER=y |
597 | CONFIG_MAX_RAW_DEVS=256 | 601 | CONFIG_MAX_RAW_DEVS=256 |
602 | # CONFIG_HANGCHECK_TIMER is not set | ||
603 | |||
604 | # | ||
605 | # TPM devices | ||
606 | # | ||
607 | # CONFIG_TCG_TPM is not set | ||
598 | 608 | ||
599 | # | 609 | # |
600 | # I2C support | 610 | # I2C support |
@@ -633,13 +643,9 @@ CONFIG_MAX_RAW_DEVS=256 | |||
633 | # | 643 | # |
634 | # USB support | 644 | # USB support |
635 | # | 645 | # |
636 | # CONFIG_USB is not set | ||
637 | CONFIG_USB_ARCH_HAS_HCD=y | 646 | CONFIG_USB_ARCH_HAS_HCD=y |
638 | CONFIG_USB_ARCH_HAS_OHCI=y | 647 | CONFIG_USB_ARCH_HAS_OHCI=y |
639 | 648 | # CONFIG_USB is not set | |
640 | # | ||
641 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information | ||
642 | # | ||
643 | 649 | ||
644 | # | 650 | # |
645 | # USB Gadget Support | 651 | # USB Gadget Support |
@@ -848,10 +854,13 @@ CONFIG_OPROFILE=y | |||
848 | # | 854 | # |
849 | # Kernel hacking | 855 | # Kernel hacking |
850 | # | 856 | # |
857 | # CONFIG_PRINTK_TIME is not set | ||
851 | CONFIG_DEBUG_KERNEL=y | 858 | CONFIG_DEBUG_KERNEL=y |
852 | CONFIG_MAGIC_SYSRQ=y | 859 | CONFIG_MAGIC_SYSRQ=y |
860 | CONFIG_LOG_BUF_SHIFT=17 | ||
853 | # CONFIG_SCHEDSTATS is not set | 861 | # CONFIG_SCHEDSTATS is not set |
854 | # CONFIG_DEBUG_SLAB is not set | 862 | # CONFIG_DEBUG_SLAB is not set |
863 | # CONFIG_DEBUG_SPINLOCK is not set | ||
855 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | 864 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set |
856 | # CONFIG_DEBUG_KOBJECT is not set | 865 | # CONFIG_DEBUG_KOBJECT is not set |
857 | # CONFIG_DEBUG_INFO is not set | 866 | # CONFIG_DEBUG_INFO is not set |
@@ -881,6 +890,7 @@ CONFIG_CRYPTO_SHA1=m | |||
881 | CONFIG_CRYPTO_SHA256=m | 890 | CONFIG_CRYPTO_SHA256=m |
882 | CONFIG_CRYPTO_SHA512=m | 891 | CONFIG_CRYPTO_SHA512=m |
883 | CONFIG_CRYPTO_WP512=m | 892 | CONFIG_CRYPTO_WP512=m |
893 | CONFIG_CRYPTO_TGR192=m | ||
884 | CONFIG_CRYPTO_DES=y | 894 | CONFIG_CRYPTO_DES=y |
885 | CONFIG_CRYPTO_BLOWFISH=m | 895 | CONFIG_CRYPTO_BLOWFISH=m |
886 | CONFIG_CRYPTO_TWOFISH=m | 896 | CONFIG_CRYPTO_TWOFISH=m |
diff --git a/arch/ppc64/configs/maple_defconfig b/arch/ppc64/configs/maple_defconfig index cf527501915c..8051b0f47b6f 100644 --- a/arch/ppc64/configs/maple_defconfig +++ b/arch/ppc64/configs/maple_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.11-rc3-bk6 | 3 | # Linux kernel version: 2.6.12-rc6 |
4 | # Wed Feb 9 23:34:53 2005 | 4 | # Tue Jun 14 17:12:48 2005 |
5 | # | 5 | # |
6 | CONFIG_64BIT=y | 6 | CONFIG_64BIT=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
@@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y | |||
11 | CONFIG_HAVE_DEC_LOCK=y | 11 | CONFIG_HAVE_DEC_LOCK=y |
12 | CONFIG_EARLY_PRINTK=y | 12 | CONFIG_EARLY_PRINTK=y |
13 | CONFIG_COMPAT=y | 13 | CONFIG_COMPAT=y |
14 | CONFIG_FRAME_POINTER=y | 14 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y |
15 | CONFIG_FORCE_MAX_ZONEORDER=13 | 15 | CONFIG_FORCE_MAX_ZONEORDER=13 |
16 | 16 | ||
17 | # | 17 | # |
@@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13 | |||
20 | CONFIG_EXPERIMENTAL=y | 20 | CONFIG_EXPERIMENTAL=y |
21 | CONFIG_CLEAN_COMPILE=y | 21 | CONFIG_CLEAN_COMPILE=y |
22 | CONFIG_LOCK_KERNEL=y | 22 | CONFIG_LOCK_KERNEL=y |
23 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
23 | 24 | ||
24 | # | 25 | # |
25 | # General setup | 26 | # General setup |
@@ -30,24 +31,28 @@ CONFIG_SYSVIPC=y | |||
30 | CONFIG_POSIX_MQUEUE=y | 31 | CONFIG_POSIX_MQUEUE=y |
31 | # CONFIG_BSD_PROCESS_ACCT is not set | 32 | # CONFIG_BSD_PROCESS_ACCT is not set |
32 | CONFIG_SYSCTL=y | 33 | CONFIG_SYSCTL=y |
33 | CONFIG_LOG_BUF_SHIFT=17 | 34 | # CONFIG_AUDIT is not set |
34 | # CONFIG_HOTPLUG is not set | 35 | # CONFIG_HOTPLUG is not set |
35 | CONFIG_KOBJECT_UEVENT=y | 36 | CONFIG_KOBJECT_UEVENT=y |
36 | CONFIG_IKCONFIG=y | 37 | CONFIG_IKCONFIG=y |
37 | CONFIG_IKCONFIG_PROC=y | 38 | CONFIG_IKCONFIG_PROC=y |
39 | # CONFIG_CPUSETS is not set | ||
38 | # CONFIG_EMBEDDED is not set | 40 | # CONFIG_EMBEDDED is not set |
39 | CONFIG_KALLSYMS=y | 41 | CONFIG_KALLSYMS=y |
40 | CONFIG_KALLSYMS_ALL=y | 42 | CONFIG_KALLSYMS_ALL=y |
41 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 43 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
44 | CONFIG_PRINTK=y | ||
45 | CONFIG_BUG=y | ||
46 | CONFIG_BASE_FULL=y | ||
42 | CONFIG_FUTEX=y | 47 | CONFIG_FUTEX=y |
43 | CONFIG_EPOLL=y | 48 | CONFIG_EPOLL=y |
44 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
45 | CONFIG_SHMEM=y | 49 | CONFIG_SHMEM=y |
46 | CONFIG_CC_ALIGN_FUNCTIONS=0 | 50 | CONFIG_CC_ALIGN_FUNCTIONS=0 |
47 | CONFIG_CC_ALIGN_LABELS=0 | 51 | CONFIG_CC_ALIGN_LABELS=0 |
48 | CONFIG_CC_ALIGN_LOOPS=0 | 52 | CONFIG_CC_ALIGN_LOOPS=0 |
49 | CONFIG_CC_ALIGN_JUMPS=0 | 53 | CONFIG_CC_ALIGN_JUMPS=0 |
50 | # CONFIG_TINY_SHMEM is not set | 54 | # CONFIG_TINY_SHMEM is not set |
55 | CONFIG_BASE_SMALL=0 | ||
51 | 56 | ||
52 | # | 57 | # |
53 | # Loadable module support | 58 | # Loadable module support |
@@ -84,6 +89,8 @@ CONFIG_NR_CPUS=2 | |||
84 | # CONFIG_SCHED_SMT is not set | 89 | # CONFIG_SCHED_SMT is not set |
85 | # CONFIG_PREEMPT is not set | 90 | # CONFIG_PREEMPT is not set |
86 | CONFIG_GENERIC_HARDIRQS=y | 91 | CONFIG_GENERIC_HARDIRQS=y |
92 | CONFIG_SECCOMP=y | ||
93 | CONFIG_ISA_DMA_API=y | ||
87 | 94 | ||
88 | # | 95 | # |
89 | # General setup | 96 | # General setup |
@@ -94,6 +101,7 @@ CONFIG_BINFMT_ELF=y | |||
94 | # CONFIG_BINFMT_MISC is not set | 101 | # CONFIG_BINFMT_MISC is not set |
95 | CONFIG_PCI_LEGACY_PROC=y | 102 | CONFIG_PCI_LEGACY_PROC=y |
96 | CONFIG_PCI_NAMES=y | 103 | CONFIG_PCI_NAMES=y |
104 | # CONFIG_PCI_DEBUG is not set | ||
97 | 105 | ||
98 | # | 106 | # |
99 | # PCCARD (PCMCIA/CardBus) support | 107 | # PCCARD (PCMCIA/CardBus) support |
@@ -101,10 +109,6 @@ CONFIG_PCI_NAMES=y | |||
101 | # CONFIG_PCCARD is not set | 109 | # CONFIG_PCCARD is not set |
102 | 110 | ||
103 | # | 111 | # |
104 | # PC-card bridges | ||
105 | # | ||
106 | |||
107 | # | ||
108 | # PCI Hotplug Support | 112 | # PCI Hotplug Support |
109 | # | 113 | # |
110 | # CONFIG_HOTPLUG_PCI is not set | 114 | # CONFIG_HOTPLUG_PCI is not set |
@@ -261,7 +265,6 @@ CONFIG_NET=y | |||
261 | # | 265 | # |
262 | CONFIG_PACKET=y | 266 | CONFIG_PACKET=y |
263 | CONFIG_PACKET_MMAP=y | 267 | CONFIG_PACKET_MMAP=y |
264 | # CONFIG_NETLINK_DEV is not set | ||
265 | CONFIG_UNIX=y | 268 | CONFIG_UNIX=y |
266 | # CONFIG_NET_KEY is not set | 269 | # CONFIG_NET_KEY is not set |
267 | CONFIG_INET=y | 270 | CONFIG_INET=y |
@@ -376,6 +379,8 @@ CONFIG_E1000=y | |||
376 | # CONFIG_SK98LIN is not set | 379 | # CONFIG_SK98LIN is not set |
377 | # CONFIG_VIA_VELOCITY is not set | 380 | # CONFIG_VIA_VELOCITY is not set |
378 | # CONFIG_TIGON3 is not set | 381 | # CONFIG_TIGON3 is not set |
382 | # CONFIG_BNX2 is not set | ||
383 | # CONFIG_MV643XX_ETH is not set | ||
379 | 384 | ||
380 | # | 385 | # |
381 | # Ethernet (10000 Mbit) | 386 | # Ethernet (10000 Mbit) |
@@ -432,14 +437,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1200 | |||
432 | # CONFIG_INPUT_EVBUG is not set | 437 | # CONFIG_INPUT_EVBUG is not set |
433 | 438 | ||
434 | # | 439 | # |
435 | # Input I/O drivers | ||
436 | # | ||
437 | # CONFIG_GAMEPORT is not set | ||
438 | CONFIG_SOUND_GAMEPORT=y | ||
439 | # CONFIG_SERIO is not set | ||
440 | # CONFIG_SERIO_I8042 is not set | ||
441 | |||
442 | # | ||
443 | # Input Device Drivers | 440 | # Input Device Drivers |
444 | # | 441 | # |
445 | # CONFIG_INPUT_KEYBOARD is not set | 442 | # CONFIG_INPUT_KEYBOARD is not set |
@@ -449,6 +446,12 @@ CONFIG_SOUND_GAMEPORT=y | |||
449 | # CONFIG_INPUT_MISC is not set | 446 | # CONFIG_INPUT_MISC is not set |
450 | 447 | ||
451 | # | 448 | # |
449 | # Hardware I/O ports | ||
450 | # | ||
451 | # CONFIG_SERIO is not set | ||
452 | # CONFIG_GAMEPORT is not set | ||
453 | |||
454 | # | ||
452 | # Character devices | 455 | # Character devices |
453 | # | 456 | # |
454 | CONFIG_VT=y | 457 | CONFIG_VT=y |
@@ -469,7 +472,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4 | |||
469 | # | 472 | # |
470 | CONFIG_SERIAL_CORE=y | 473 | CONFIG_SERIAL_CORE=y |
471 | CONFIG_SERIAL_CORE_CONSOLE=y | 474 | CONFIG_SERIAL_CORE_CONSOLE=y |
472 | # CONFIG_SERIAL_PMACZILOG is not set | 475 | # CONFIG_SERIAL_JSM is not set |
473 | CONFIG_UNIX98_PTYS=y | 476 | CONFIG_UNIX98_PTYS=y |
474 | CONFIG_LEGACY_PTYS=y | 477 | CONFIG_LEGACY_PTYS=y |
475 | CONFIG_LEGACY_PTY_COUNT=256 | 478 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -492,8 +495,15 @@ CONFIG_LEGACY_PTY_COUNT=256 | |||
492 | # | 495 | # |
493 | # Ftape, the floppy tape device driver | 496 | # Ftape, the floppy tape device driver |
494 | # | 497 | # |
498 | # CONFIG_AGP is not set | ||
495 | # CONFIG_DRM is not set | 499 | # CONFIG_DRM is not set |
496 | # CONFIG_RAW_DRIVER is not set | 500 | # CONFIG_RAW_DRIVER is not set |
501 | # CONFIG_HANGCHECK_TIMER is not set | ||
502 | |||
503 | # | ||
504 | # TPM devices | ||
505 | # | ||
506 | # CONFIG_TCG_TPM is not set | ||
497 | 507 | ||
498 | # | 508 | # |
499 | # I2C support | 509 | # I2C support |
@@ -518,8 +528,8 @@ CONFIG_I2C_ALGOBIT=y | |||
518 | CONFIG_I2C_AMD8111=y | 528 | CONFIG_I2C_AMD8111=y |
519 | # CONFIG_I2C_I801 is not set | 529 | # CONFIG_I2C_I801 is not set |
520 | # CONFIG_I2C_I810 is not set | 530 | # CONFIG_I2C_I810 is not set |
531 | # CONFIG_I2C_PIIX4 is not set | ||
521 | # CONFIG_I2C_ISA is not set | 532 | # CONFIG_I2C_ISA is not set |
522 | # CONFIG_I2C_MPC is not set | ||
523 | # CONFIG_I2C_NFORCE2 is not set | 533 | # CONFIG_I2C_NFORCE2 is not set |
524 | # CONFIG_I2C_PARPORT_LIGHT is not set | 534 | # CONFIG_I2C_PARPORT_LIGHT is not set |
525 | # CONFIG_I2C_PROSAVAGE is not set | 535 | # CONFIG_I2C_PROSAVAGE is not set |
@@ -545,7 +555,9 @@ CONFIG_I2C_AMD8111=y | |||
545 | # CONFIG_SENSORS_ASB100 is not set | 555 | # CONFIG_SENSORS_ASB100 is not set |
546 | # CONFIG_SENSORS_DS1621 is not set | 556 | # CONFIG_SENSORS_DS1621 is not set |
547 | # CONFIG_SENSORS_FSCHER is not set | 557 | # CONFIG_SENSORS_FSCHER is not set |
558 | # CONFIG_SENSORS_FSCPOS is not set | ||
548 | # CONFIG_SENSORS_GL518SM is not set | 559 | # CONFIG_SENSORS_GL518SM is not set |
560 | # CONFIG_SENSORS_GL520SM is not set | ||
549 | # CONFIG_SENSORS_IT87 is not set | 561 | # CONFIG_SENSORS_IT87 is not set |
550 | # CONFIG_SENSORS_LM63 is not set | 562 | # CONFIG_SENSORS_LM63 is not set |
551 | # CONFIG_SENSORS_LM75 is not set | 563 | # CONFIG_SENSORS_LM75 is not set |
@@ -556,9 +568,11 @@ CONFIG_I2C_AMD8111=y | |||
556 | # CONFIG_SENSORS_LM85 is not set | 568 | # CONFIG_SENSORS_LM85 is not set |
557 | # CONFIG_SENSORS_LM87 is not set | 569 | # CONFIG_SENSORS_LM87 is not set |
558 | # CONFIG_SENSORS_LM90 is not set | 570 | # CONFIG_SENSORS_LM90 is not set |
571 | # CONFIG_SENSORS_LM92 is not set | ||
559 | # CONFIG_SENSORS_MAX1619 is not set | 572 | # CONFIG_SENSORS_MAX1619 is not set |
560 | # CONFIG_SENSORS_PC87360 is not set | 573 | # CONFIG_SENSORS_PC87360 is not set |
561 | # CONFIG_SENSORS_SMSC47B397 is not set | 574 | # CONFIG_SENSORS_SMSC47B397 is not set |
575 | # CONFIG_SENSORS_SIS5595 is not set | ||
562 | # CONFIG_SENSORS_SMSC47M1 is not set | 576 | # CONFIG_SENSORS_SMSC47M1 is not set |
563 | # CONFIG_SENSORS_VIA686A is not set | 577 | # CONFIG_SENSORS_VIA686A is not set |
564 | # CONFIG_SENSORS_W83781D is not set | 578 | # CONFIG_SENSORS_W83781D is not set |
@@ -568,6 +582,7 @@ CONFIG_I2C_AMD8111=y | |||
568 | # | 582 | # |
569 | # Other I2C Chip support | 583 | # Other I2C Chip support |
570 | # | 584 | # |
585 | # CONFIG_SENSORS_DS1337 is not set | ||
571 | # CONFIG_SENSORS_EEPROM is not set | 586 | # CONFIG_SENSORS_EEPROM is not set |
572 | # CONFIG_SENSORS_PCF8574 is not set | 587 | # CONFIG_SENSORS_PCF8574 is not set |
573 | # CONFIG_SENSORS_PCF8591 is not set | 588 | # CONFIG_SENSORS_PCF8591 is not set |
@@ -615,6 +630,8 @@ CONFIG_DUMMY_CONSOLE=y | |||
615 | # | 630 | # |
616 | # USB support | 631 | # USB support |
617 | # | 632 | # |
633 | CONFIG_USB_ARCH_HAS_HCD=y | ||
634 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
618 | CONFIG_USB=y | 635 | CONFIG_USB=y |
619 | # CONFIG_USB_DEBUG is not set | 636 | # CONFIG_USB_DEBUG is not set |
620 | 637 | ||
@@ -625,8 +642,6 @@ CONFIG_USB_DEVICEFS=y | |||
625 | # CONFIG_USB_BANDWIDTH is not set | 642 | # CONFIG_USB_BANDWIDTH is not set |
626 | # CONFIG_USB_DYNAMIC_MINORS is not set | 643 | # CONFIG_USB_DYNAMIC_MINORS is not set |
627 | # CONFIG_USB_OTG is not set | 644 | # CONFIG_USB_OTG is not set |
628 | CONFIG_USB_ARCH_HAS_HCD=y | ||
629 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
630 | 645 | ||
631 | # | 646 | # |
632 | # USB Host Controller Drivers | 647 | # USB Host Controller Drivers |
@@ -635,6 +650,8 @@ CONFIG_USB_EHCI_HCD=y | |||
635 | CONFIG_USB_EHCI_SPLIT_ISO=y | 650 | CONFIG_USB_EHCI_SPLIT_ISO=y |
636 | CONFIG_USB_EHCI_ROOT_HUB_TT=y | 651 | CONFIG_USB_EHCI_ROOT_HUB_TT=y |
637 | CONFIG_USB_OHCI_HCD=y | 652 | CONFIG_USB_OHCI_HCD=y |
653 | # CONFIG_USB_OHCI_BIG_ENDIAN is not set | ||
654 | CONFIG_USB_OHCI_LITTLE_ENDIAN=y | ||
638 | CONFIG_USB_UHCI_HCD=y | 655 | CONFIG_USB_UHCI_HCD=y |
639 | # CONFIG_USB_SL811_HCD is not set | 656 | # CONFIG_USB_SL811_HCD is not set |
640 | 657 | ||
@@ -688,6 +705,7 @@ CONFIG_USB_HIDINPUT=y | |||
688 | CONFIG_USB_PEGASUS=y | 705 | CONFIG_USB_PEGASUS=y |
689 | # CONFIG_USB_RTL8150 is not set | 706 | # CONFIG_USB_RTL8150 is not set |
690 | # CONFIG_USB_USBNET is not set | 707 | # CONFIG_USB_USBNET is not set |
708 | CONFIG_USB_MON=y | ||
691 | 709 | ||
692 | # | 710 | # |
693 | # USB port drivers | 711 | # USB port drivers |
@@ -699,8 +717,10 @@ CONFIG_USB_PEGASUS=y | |||
699 | CONFIG_USB_SERIAL=y | 717 | CONFIG_USB_SERIAL=y |
700 | # CONFIG_USB_SERIAL_CONSOLE is not set | 718 | # CONFIG_USB_SERIAL_CONSOLE is not set |
701 | CONFIG_USB_SERIAL_GENERIC=y | 719 | CONFIG_USB_SERIAL_GENERIC=y |
720 | # CONFIG_USB_SERIAL_AIRPRIME is not set | ||
702 | # CONFIG_USB_SERIAL_BELKIN is not set | 721 | # CONFIG_USB_SERIAL_BELKIN is not set |
703 | # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set | 722 | # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set |
723 | # CONFIG_USB_SERIAL_CP2101 is not set | ||
704 | CONFIG_USB_SERIAL_CYPRESS_M8=m | 724 | CONFIG_USB_SERIAL_CYPRESS_M8=m |
705 | # CONFIG_USB_SERIAL_EMPEG is not set | 725 | # CONFIG_USB_SERIAL_EMPEG is not set |
706 | # CONFIG_USB_SERIAL_FTDI_SIO is not set | 726 | # CONFIG_USB_SERIAL_FTDI_SIO is not set |
@@ -729,6 +749,7 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y | |||
729 | # CONFIG_USB_SERIAL_KOBIL_SCT is not set | 749 | # CONFIG_USB_SERIAL_KOBIL_SCT is not set |
730 | # CONFIG_USB_SERIAL_MCT_U232 is not set | 750 | # CONFIG_USB_SERIAL_MCT_U232 is not set |
731 | # CONFIG_USB_SERIAL_PL2303 is not set | 751 | # CONFIG_USB_SERIAL_PL2303 is not set |
752 | # CONFIG_USB_SERIAL_HP4X is not set | ||
732 | # CONFIG_USB_SERIAL_SAFE is not set | 753 | # CONFIG_USB_SERIAL_SAFE is not set |
733 | CONFIG_USB_SERIAL_TI=m | 754 | CONFIG_USB_SERIAL_TI=m |
734 | # CONFIG_USB_SERIAL_CYBERJACK is not set | 755 | # CONFIG_USB_SERIAL_CYBERJACK is not set |
@@ -750,6 +771,7 @@ CONFIG_USB_EZUSB=y | |||
750 | # CONFIG_USB_PHIDGETKIT is not set | 771 | # CONFIG_USB_PHIDGETKIT is not set |
751 | # CONFIG_USB_PHIDGETSERVO is not set | 772 | # CONFIG_USB_PHIDGETSERVO is not set |
752 | # CONFIG_USB_IDMOUSE is not set | 773 | # CONFIG_USB_IDMOUSE is not set |
774 | # CONFIG_USB_SISUSBVGA is not set | ||
753 | # CONFIG_USB_TEST is not set | 775 | # CONFIG_USB_TEST is not set |
754 | 776 | ||
755 | # | 777 | # |
@@ -936,10 +958,13 @@ CONFIG_NLS_UTF8=y | |||
936 | # | 958 | # |
937 | # Kernel hacking | 959 | # Kernel hacking |
938 | # | 960 | # |
961 | # CONFIG_PRINTK_TIME is not set | ||
939 | CONFIG_DEBUG_KERNEL=y | 962 | CONFIG_DEBUG_KERNEL=y |
940 | CONFIG_MAGIC_SYSRQ=y | 963 | CONFIG_MAGIC_SYSRQ=y |
964 | CONFIG_LOG_BUF_SHIFT=17 | ||
941 | # CONFIG_SCHEDSTATS is not set | 965 | # CONFIG_SCHEDSTATS is not set |
942 | CONFIG_DEBUG_SLAB=y | 966 | CONFIG_DEBUG_SLAB=y |
967 | # CONFIG_DEBUG_SPINLOCK is not set | ||
943 | CONFIG_DEBUG_SPINLOCK_SLEEP=y | 968 | CONFIG_DEBUG_SPINLOCK_SLEEP=y |
944 | # CONFIG_DEBUG_KOBJECT is not set | 969 | # CONFIG_DEBUG_KOBJECT is not set |
945 | # CONFIG_DEBUG_INFO is not set | 970 | # CONFIG_DEBUG_INFO is not set |
@@ -971,6 +996,7 @@ CONFIG_CRYPTO_MD5=y | |||
971 | # CONFIG_CRYPTO_SHA256 is not set | 996 | # CONFIG_CRYPTO_SHA256 is not set |
972 | # CONFIG_CRYPTO_SHA512 is not set | 997 | # CONFIG_CRYPTO_SHA512 is not set |
973 | # CONFIG_CRYPTO_WP512 is not set | 998 | # CONFIG_CRYPTO_WP512 is not set |
999 | # CONFIG_CRYPTO_TGR192 is not set | ||
974 | CONFIG_CRYPTO_DES=y | 1000 | CONFIG_CRYPTO_DES=y |
975 | # CONFIG_CRYPTO_BLOWFISH is not set | 1001 | # CONFIG_CRYPTO_BLOWFISH is not set |
976 | # CONFIG_CRYPTO_TWOFISH is not set | 1002 | # CONFIG_CRYPTO_TWOFISH is not set |
diff --git a/arch/ppc64/configs/pSeries_defconfig b/arch/ppc64/configs/pSeries_defconfig index 4fecf237d5c9..3eb5ef25d3a3 100644 --- a/arch/ppc64/configs/pSeries_defconfig +++ b/arch/ppc64/configs/pSeries_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.11-rc3-bk6 | 3 | # Linux kernel version: 2.6.12-rc6 |
4 | # Wed Feb 9 23:34:54 2005 | 4 | # Tue Jun 14 17:13:47 2005 |
5 | # | 5 | # |
6 | CONFIG_64BIT=y | 6 | CONFIG_64BIT=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
@@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y | |||
11 | CONFIG_HAVE_DEC_LOCK=y | 11 | CONFIG_HAVE_DEC_LOCK=y |
12 | CONFIG_EARLY_PRINTK=y | 12 | CONFIG_EARLY_PRINTK=y |
13 | CONFIG_COMPAT=y | 13 | CONFIG_COMPAT=y |
14 | CONFIG_FRAME_POINTER=y | 14 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y |
15 | CONFIG_FORCE_MAX_ZONEORDER=13 | 15 | CONFIG_FORCE_MAX_ZONEORDER=13 |
16 | 16 | ||
17 | # | 17 | # |
@@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13 | |||
20 | CONFIG_EXPERIMENTAL=y | 20 | CONFIG_EXPERIMENTAL=y |
21 | CONFIG_CLEAN_COMPILE=y | 21 | CONFIG_CLEAN_COMPILE=y |
22 | CONFIG_LOCK_KERNEL=y | 22 | CONFIG_LOCK_KERNEL=y |
23 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
23 | 24 | ||
24 | # | 25 | # |
25 | # General setup | 26 | # General setup |
@@ -30,24 +31,29 @@ CONFIG_SYSVIPC=y | |||
30 | CONFIG_POSIX_MQUEUE=y | 31 | CONFIG_POSIX_MQUEUE=y |
31 | # CONFIG_BSD_PROCESS_ACCT is not set | 32 | # CONFIG_BSD_PROCESS_ACCT is not set |
32 | CONFIG_SYSCTL=y | 33 | CONFIG_SYSCTL=y |
33 | CONFIG_LOG_BUF_SHIFT=17 | 34 | CONFIG_AUDIT=y |
35 | CONFIG_AUDITSYSCALL=y | ||
34 | CONFIG_HOTPLUG=y | 36 | CONFIG_HOTPLUG=y |
35 | CONFIG_KOBJECT_UEVENT=y | 37 | CONFIG_KOBJECT_UEVENT=y |
36 | CONFIG_IKCONFIG=y | 38 | CONFIG_IKCONFIG=y |
37 | CONFIG_IKCONFIG_PROC=y | 39 | CONFIG_IKCONFIG_PROC=y |
40 | CONFIG_CPUSETS=y | ||
38 | # CONFIG_EMBEDDED is not set | 41 | # CONFIG_EMBEDDED is not set |
39 | CONFIG_KALLSYMS=y | 42 | CONFIG_KALLSYMS=y |
40 | CONFIG_KALLSYMS_ALL=y | 43 | CONFIG_KALLSYMS_ALL=y |
41 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 44 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
45 | CONFIG_PRINTK=y | ||
46 | CONFIG_BUG=y | ||
47 | CONFIG_BASE_FULL=y | ||
42 | CONFIG_FUTEX=y | 48 | CONFIG_FUTEX=y |
43 | CONFIG_EPOLL=y | 49 | CONFIG_EPOLL=y |
44 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
45 | CONFIG_SHMEM=y | 50 | CONFIG_SHMEM=y |
46 | CONFIG_CC_ALIGN_FUNCTIONS=0 | 51 | CONFIG_CC_ALIGN_FUNCTIONS=0 |
47 | CONFIG_CC_ALIGN_LABELS=0 | 52 | CONFIG_CC_ALIGN_LABELS=0 |
48 | CONFIG_CC_ALIGN_LOOPS=0 | 53 | CONFIG_CC_ALIGN_LOOPS=0 |
49 | CONFIG_CC_ALIGN_JUMPS=0 | 54 | CONFIG_CC_ALIGN_JUMPS=0 |
50 | # CONFIG_TINY_SHMEM is not set | 55 | # CONFIG_TINY_SHMEM is not set |
56 | CONFIG_BASE_SMALL=0 | ||
51 | 57 | ||
52 | # | 58 | # |
53 | # Loadable module support | 59 | # Loadable module support |
@@ -89,9 +95,12 @@ CONFIG_SCHED_SMT=y | |||
89 | CONFIG_EEH=y | 95 | CONFIG_EEH=y |
90 | CONFIG_GENERIC_HARDIRQS=y | 96 | CONFIG_GENERIC_HARDIRQS=y |
91 | CONFIG_PPC_RTAS=y | 97 | CONFIG_PPC_RTAS=y |
98 | CONFIG_RTAS_PROC=y | ||
92 | CONFIG_RTAS_FLASH=m | 99 | CONFIG_RTAS_FLASH=m |
93 | CONFIG_SCANLOG=m | 100 | CONFIG_SCANLOG=m |
94 | CONFIG_LPARCFG=y | 101 | CONFIG_LPARCFG=y |
102 | CONFIG_SECCOMP=y | ||
103 | CONFIG_ISA_DMA_API=y | ||
95 | 104 | ||
96 | # | 105 | # |
97 | # General setup | 106 | # General setup |
@@ -102,6 +111,7 @@ CONFIG_BINFMT_ELF=y | |||
102 | # CONFIG_BINFMT_MISC is not set | 111 | # CONFIG_BINFMT_MISC is not set |
103 | CONFIG_PCI_LEGACY_PROC=y | 112 | CONFIG_PCI_LEGACY_PROC=y |
104 | CONFIG_PCI_NAMES=y | 113 | CONFIG_PCI_NAMES=y |
114 | # CONFIG_PCI_DEBUG is not set | ||
105 | CONFIG_HOTPLUG_CPU=y | 115 | CONFIG_HOTPLUG_CPU=y |
106 | 116 | ||
107 | # | 117 | # |
@@ -110,10 +120,6 @@ CONFIG_HOTPLUG_CPU=y | |||
110 | # CONFIG_PCCARD is not set | 120 | # CONFIG_PCCARD is not set |
111 | 121 | ||
112 | # | 122 | # |
113 | # PC-card bridges | ||
114 | # | ||
115 | |||
116 | # | ||
117 | # PCI Hotplug Support | 123 | # PCI Hotplug Support |
118 | # | 124 | # |
119 | CONFIG_HOTPLUG_PCI=m | 125 | CONFIG_HOTPLUG_PCI=m |
@@ -147,11 +153,10 @@ CONFIG_FW_LOADER=y | |||
147 | # | 153 | # |
148 | CONFIG_PARPORT=m | 154 | CONFIG_PARPORT=m |
149 | CONFIG_PARPORT_PC=m | 155 | CONFIG_PARPORT_PC=m |
150 | CONFIG_PARPORT_PC_CML1=m | ||
151 | # CONFIG_PARPORT_SERIAL is not set | 156 | # CONFIG_PARPORT_SERIAL is not set |
152 | # CONFIG_PARPORT_PC_FIFO is not set | 157 | # CONFIG_PARPORT_PC_FIFO is not set |
153 | # CONFIG_PARPORT_PC_SUPERIO is not set | 158 | # CONFIG_PARPORT_PC_SUPERIO is not set |
154 | # CONFIG_PARPORT_OTHER is not set | 159 | # CONFIG_PARPORT_GSC is not set |
155 | # CONFIG_PARPORT_1284 is not set | 160 | # CONFIG_PARPORT_1284 is not set |
156 | 161 | ||
157 | # | 162 | # |
@@ -293,7 +298,6 @@ CONFIG_SCSI_ISCSI_ATTRS=m | |||
293 | # CONFIG_SCSI_BUSLOGIC is not set | 298 | # CONFIG_SCSI_BUSLOGIC is not set |
294 | # CONFIG_SCSI_DMX3191D is not set | 299 | # CONFIG_SCSI_DMX3191D is not set |
295 | # CONFIG_SCSI_EATA is not set | 300 | # CONFIG_SCSI_EATA is not set |
296 | # CONFIG_SCSI_EATA_PIO is not set | ||
297 | # CONFIG_SCSI_FUTURE_DOMAIN is not set | 301 | # CONFIG_SCSI_FUTURE_DOMAIN is not set |
298 | # CONFIG_SCSI_GDTH is not set | 302 | # CONFIG_SCSI_GDTH is not set |
299 | # CONFIG_SCSI_IPS is not set | 303 | # CONFIG_SCSI_IPS is not set |
@@ -310,7 +314,6 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 | |||
310 | CONFIG_SCSI_IPR=y | 314 | CONFIG_SCSI_IPR=y |
311 | CONFIG_SCSI_IPR_TRACE=y | 315 | CONFIG_SCSI_IPR_TRACE=y |
312 | CONFIG_SCSI_IPR_DUMP=y | 316 | CONFIG_SCSI_IPR_DUMP=y |
313 | # CONFIG_SCSI_QLOGIC_ISP is not set | ||
314 | # CONFIG_SCSI_QLOGIC_FC is not set | 317 | # CONFIG_SCSI_QLOGIC_FC is not set |
315 | # CONFIG_SCSI_QLOGIC_1280 is not set | 318 | # CONFIG_SCSI_QLOGIC_1280 is not set |
316 | CONFIG_SCSI_QLA2XXX=y | 319 | CONFIG_SCSI_QLA2XXX=y |
@@ -319,6 +322,7 @@ CONFIG_SCSI_QLA22XX=m | |||
319 | CONFIG_SCSI_QLA2300=m | 322 | CONFIG_SCSI_QLA2300=m |
320 | CONFIG_SCSI_QLA2322=m | 323 | CONFIG_SCSI_QLA2322=m |
321 | CONFIG_SCSI_QLA6312=m | 324 | CONFIG_SCSI_QLA6312=m |
325 | CONFIG_SCSI_LPFC=m | ||
322 | # CONFIG_SCSI_DC395x is not set | 326 | # CONFIG_SCSI_DC395x is not set |
323 | # CONFIG_SCSI_DC390T is not set | 327 | # CONFIG_SCSI_DC390T is not set |
324 | # CONFIG_SCSI_DEBUG is not set | 328 | # CONFIG_SCSI_DEBUG is not set |
@@ -341,6 +345,8 @@ CONFIG_DM_CRYPT=m | |||
341 | CONFIG_DM_SNAPSHOT=m | 345 | CONFIG_DM_SNAPSHOT=m |
342 | CONFIG_DM_MIRROR=m | 346 | CONFIG_DM_MIRROR=m |
343 | CONFIG_DM_ZERO=m | 347 | CONFIG_DM_ZERO=m |
348 | CONFIG_DM_MULTIPATH=m | ||
349 | CONFIG_DM_MULTIPATH_EMC=m | ||
344 | 350 | ||
345 | # | 351 | # |
346 | # Fusion MPT device support | 352 | # Fusion MPT device support |
@@ -371,7 +377,6 @@ CONFIG_NET=y | |||
371 | # | 377 | # |
372 | CONFIG_PACKET=y | 378 | CONFIG_PACKET=y |
373 | # CONFIG_PACKET_MMAP is not set | 379 | # CONFIG_PACKET_MMAP is not set |
374 | # CONFIG_NETLINK_DEV is not set | ||
375 | CONFIG_UNIX=y | 380 | CONFIG_UNIX=y |
376 | CONFIG_NET_KEY=m | 381 | CONFIG_NET_KEY=m |
377 | CONFIG_INET=y | 382 | CONFIG_INET=y |
@@ -539,7 +544,6 @@ CONFIG_PCNET32=y | |||
539 | # CONFIG_DGRS is not set | 544 | # CONFIG_DGRS is not set |
540 | # CONFIG_EEPRO100 is not set | 545 | # CONFIG_EEPRO100 is not set |
541 | CONFIG_E100=y | 546 | CONFIG_E100=y |
542 | # CONFIG_E100_NAPI is not set | ||
543 | # CONFIG_FEALNX is not set | 547 | # CONFIG_FEALNX is not set |
544 | # CONFIG_NATSEMI is not set | 548 | # CONFIG_NATSEMI is not set |
545 | # CONFIG_NE2K_PCI is not set | 549 | # CONFIG_NE2K_PCI is not set |
@@ -565,6 +569,8 @@ CONFIG_E1000=y | |||
565 | # CONFIG_SK98LIN is not set | 569 | # CONFIG_SK98LIN is not set |
566 | # CONFIG_VIA_VELOCITY is not set | 570 | # CONFIG_VIA_VELOCITY is not set |
567 | CONFIG_TIGON3=y | 571 | CONFIG_TIGON3=y |
572 | # CONFIG_BNX2 is not set | ||
573 | # CONFIG_MV643XX_ETH is not set | ||
568 | 574 | ||
569 | # | 575 | # |
570 | # Ethernet (10000 Mbit) | 576 | # Ethernet (10000 Mbit) |
@@ -636,20 +642,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | |||
636 | # CONFIG_INPUT_EVBUG is not set | 642 | # CONFIG_INPUT_EVBUG is not set |
637 | 643 | ||
638 | # | 644 | # |
639 | # Input I/O drivers | ||
640 | # | ||
641 | # CONFIG_GAMEPORT is not set | ||
642 | CONFIG_SOUND_GAMEPORT=y | ||
643 | CONFIG_SERIO=y | ||
644 | CONFIG_SERIO_I8042=y | ||
645 | # CONFIG_SERIO_SERPORT is not set | ||
646 | # CONFIG_SERIO_CT82C710 is not set | ||
647 | # CONFIG_SERIO_PARKBD is not set | ||
648 | # CONFIG_SERIO_PCIPS2 is not set | ||
649 | CONFIG_SERIO_LIBPS2=y | ||
650 | # CONFIG_SERIO_RAW is not set | ||
651 | |||
652 | # | ||
653 | # Input Device Drivers | 645 | # Input Device Drivers |
654 | # | 646 | # |
655 | CONFIG_INPUT_KEYBOARD=y | 647 | CONFIG_INPUT_KEYBOARD=y |
@@ -669,6 +661,18 @@ CONFIG_INPUT_PCSPKR=m | |||
669 | # CONFIG_INPUT_UINPUT is not set | 661 | # CONFIG_INPUT_UINPUT is not set |
670 | 662 | ||
671 | # | 663 | # |
664 | # Hardware I/O ports | ||
665 | # | ||
666 | CONFIG_SERIO=y | ||
667 | CONFIG_SERIO_I8042=y | ||
668 | # CONFIG_SERIO_SERPORT is not set | ||
669 | # CONFIG_SERIO_PARKBD is not set | ||
670 | # CONFIG_SERIO_PCIPS2 is not set | ||
671 | CONFIG_SERIO_LIBPS2=y | ||
672 | # CONFIG_SERIO_RAW is not set | ||
673 | # CONFIG_GAMEPORT is not set | ||
674 | |||
675 | # | ||
672 | # Character devices | 676 | # Character devices |
673 | # | 677 | # |
674 | CONFIG_VT=y | 678 | CONFIG_VT=y |
@@ -689,8 +693,8 @@ CONFIG_SERIAL_8250_NR_UARTS=4 | |||
689 | # | 693 | # |
690 | CONFIG_SERIAL_CORE=y | 694 | CONFIG_SERIAL_CORE=y |
691 | CONFIG_SERIAL_CORE_CONSOLE=y | 695 | CONFIG_SERIAL_CORE_CONSOLE=y |
692 | # CONFIG_SERIAL_PMACZILOG is not set | ||
693 | CONFIG_SERIAL_ICOM=m | 696 | CONFIG_SERIAL_ICOM=m |
697 | # CONFIG_SERIAL_JSM is not set | ||
694 | CONFIG_UNIX98_PTYS=y | 698 | CONFIG_UNIX98_PTYS=y |
695 | CONFIG_LEGACY_PTYS=y | 699 | CONFIG_LEGACY_PTYS=y |
696 | CONFIG_LEGACY_PTY_COUNT=256 | 700 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -718,9 +722,16 @@ CONFIG_HVCS=m | |||
718 | # | 722 | # |
719 | # Ftape, the floppy tape device driver | 723 | # Ftape, the floppy tape device driver |
720 | # | 724 | # |
725 | # CONFIG_AGP is not set | ||
721 | # CONFIG_DRM is not set | 726 | # CONFIG_DRM is not set |
722 | CONFIG_RAW_DRIVER=y | 727 | CONFIG_RAW_DRIVER=y |
723 | CONFIG_MAX_RAW_DEVS=1024 | 728 | CONFIG_MAX_RAW_DEVS=1024 |
729 | # CONFIG_HANGCHECK_TIMER is not set | ||
730 | |||
731 | # | ||
732 | # TPM devices | ||
733 | # | ||
734 | # CONFIG_TCG_TPM is not set | ||
724 | 735 | ||
725 | # | 736 | # |
726 | # I2C support | 737 | # I2C support |
@@ -745,8 +756,8 @@ CONFIG_I2C_ALGOBIT=y | |||
745 | # CONFIG_I2C_AMD8111 is not set | 756 | # CONFIG_I2C_AMD8111 is not set |
746 | # CONFIG_I2C_I801 is not set | 757 | # CONFIG_I2C_I801 is not set |
747 | # CONFIG_I2C_I810 is not set | 758 | # CONFIG_I2C_I810 is not set |
759 | # CONFIG_I2C_PIIX4 is not set | ||
748 | # CONFIG_I2C_ISA is not set | 760 | # CONFIG_I2C_ISA is not set |
749 | # CONFIG_I2C_MPC is not set | ||
750 | # CONFIG_I2C_NFORCE2 is not set | 761 | # CONFIG_I2C_NFORCE2 is not set |
751 | # CONFIG_I2C_PARPORT is not set | 762 | # CONFIG_I2C_PARPORT is not set |
752 | # CONFIG_I2C_PARPORT_LIGHT is not set | 763 | # CONFIG_I2C_PARPORT_LIGHT is not set |
@@ -773,7 +784,9 @@ CONFIG_I2C_ALGOBIT=y | |||
773 | # CONFIG_SENSORS_ASB100 is not set | 784 | # CONFIG_SENSORS_ASB100 is not set |
774 | # CONFIG_SENSORS_DS1621 is not set | 785 | # CONFIG_SENSORS_DS1621 is not set |
775 | # CONFIG_SENSORS_FSCHER is not set | 786 | # CONFIG_SENSORS_FSCHER is not set |
787 | # CONFIG_SENSORS_FSCPOS is not set | ||
776 | # CONFIG_SENSORS_GL518SM is not set | 788 | # CONFIG_SENSORS_GL518SM is not set |
789 | # CONFIG_SENSORS_GL520SM is not set | ||
777 | # CONFIG_SENSORS_IT87 is not set | 790 | # CONFIG_SENSORS_IT87 is not set |
778 | # CONFIG_SENSORS_LM63 is not set | 791 | # CONFIG_SENSORS_LM63 is not set |
779 | # CONFIG_SENSORS_LM75 is not set | 792 | # CONFIG_SENSORS_LM75 is not set |
@@ -784,9 +797,11 @@ CONFIG_I2C_ALGOBIT=y | |||
784 | # CONFIG_SENSORS_LM85 is not set | 797 | # CONFIG_SENSORS_LM85 is not set |
785 | # CONFIG_SENSORS_LM87 is not set | 798 | # CONFIG_SENSORS_LM87 is not set |
786 | # CONFIG_SENSORS_LM90 is not set | 799 | # CONFIG_SENSORS_LM90 is not set |
800 | # CONFIG_SENSORS_LM92 is not set | ||
787 | # CONFIG_SENSORS_MAX1619 is not set | 801 | # CONFIG_SENSORS_MAX1619 is not set |
788 | # CONFIG_SENSORS_PC87360 is not set | 802 | # CONFIG_SENSORS_PC87360 is not set |
789 | # CONFIG_SENSORS_SMSC47B397 is not set | 803 | # CONFIG_SENSORS_SMSC47B397 is not set |
804 | # CONFIG_SENSORS_SIS5595 is not set | ||
790 | # CONFIG_SENSORS_SMSC47M1 is not set | 805 | # CONFIG_SENSORS_SMSC47M1 is not set |
791 | # CONFIG_SENSORS_VIA686A is not set | 806 | # CONFIG_SENSORS_VIA686A is not set |
792 | # CONFIG_SENSORS_W83781D is not set | 807 | # CONFIG_SENSORS_W83781D is not set |
@@ -796,6 +811,7 @@ CONFIG_I2C_ALGOBIT=y | |||
796 | # | 811 | # |
797 | # Other I2C Chip support | 812 | # Other I2C Chip support |
798 | # | 813 | # |
814 | # CONFIG_SENSORS_DS1337 is not set | ||
799 | # CONFIG_SENSORS_EEPROM is not set | 815 | # CONFIG_SENSORS_EEPROM is not set |
800 | # CONFIG_SENSORS_PCF8574 is not set | 816 | # CONFIG_SENSORS_PCF8574 is not set |
801 | # CONFIG_SENSORS_PCF8591 is not set | 817 | # CONFIG_SENSORS_PCF8591 is not set |
@@ -828,8 +844,13 @@ CONFIG_I2C_ALGOBIT=y | |||
828 | # Graphics support | 844 | # Graphics support |
829 | # | 845 | # |
830 | CONFIG_FB=y | 846 | CONFIG_FB=y |
847 | CONFIG_FB_CFB_FILLRECT=y | ||
848 | CONFIG_FB_CFB_COPYAREA=y | ||
849 | CONFIG_FB_CFB_IMAGEBLIT=y | ||
850 | CONFIG_FB_SOFT_CURSOR=y | ||
851 | CONFIG_FB_MACMODES=y | ||
831 | CONFIG_FB_MODE_HELPERS=y | 852 | CONFIG_FB_MODE_HELPERS=y |
832 | # CONFIG_FB_TILEBLITTING is not set | 853 | CONFIG_FB_TILEBLITTING=y |
833 | # CONFIG_FB_CIRRUS is not set | 854 | # CONFIG_FB_CIRRUS is not set |
834 | # CONFIG_FB_PM2 is not set | 855 | # CONFIG_FB_PM2 is not set |
835 | # CONFIG_FB_CYBER2000 is not set | 856 | # CONFIG_FB_CYBER2000 is not set |
@@ -838,6 +859,7 @@ CONFIG_FB_OF=y | |||
838 | # CONFIG_FB_ASILIANT is not set | 859 | # CONFIG_FB_ASILIANT is not set |
839 | # CONFIG_FB_IMSTT is not set | 860 | # CONFIG_FB_IMSTT is not set |
840 | # CONFIG_FB_VGA16 is not set | 861 | # CONFIG_FB_VGA16 is not set |
862 | # CONFIG_FB_NVIDIA is not set | ||
841 | # CONFIG_FB_RIVA is not set | 863 | # CONFIG_FB_RIVA is not set |
842 | CONFIG_FB_MATROX=y | 864 | CONFIG_FB_MATROX=y |
843 | CONFIG_FB_MATROX_MILLENIUM=y | 865 | CONFIG_FB_MATROX_MILLENIUM=y |
@@ -858,6 +880,7 @@ CONFIG_FB_RADEON_I2C=y | |||
858 | # CONFIG_FB_3DFX is not set | 880 | # CONFIG_FB_3DFX is not set |
859 | # CONFIG_FB_VOODOO1 is not set | 881 | # CONFIG_FB_VOODOO1 is not set |
860 | # CONFIG_FB_TRIDENT is not set | 882 | # CONFIG_FB_TRIDENT is not set |
883 | # CONFIG_FB_S1D13XXX is not set | ||
861 | # CONFIG_FB_VIRTUAL is not set | 884 | # CONFIG_FB_VIRTUAL is not set |
862 | 885 | ||
863 | # | 886 | # |
@@ -891,6 +914,8 @@ CONFIG_LCD_DEVICE=y | |||
891 | # | 914 | # |
892 | # USB support | 915 | # USB support |
893 | # | 916 | # |
917 | CONFIG_USB_ARCH_HAS_HCD=y | ||
918 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
894 | CONFIG_USB=y | 919 | CONFIG_USB=y |
895 | # CONFIG_USB_DEBUG is not set | 920 | # CONFIG_USB_DEBUG is not set |
896 | 921 | ||
@@ -901,8 +926,6 @@ CONFIG_USB_DEVICEFS=y | |||
901 | # CONFIG_USB_BANDWIDTH is not set | 926 | # CONFIG_USB_BANDWIDTH is not set |
902 | # CONFIG_USB_DYNAMIC_MINORS is not set | 927 | # CONFIG_USB_DYNAMIC_MINORS is not set |
903 | # CONFIG_USB_OTG is not set | 928 | # CONFIG_USB_OTG is not set |
904 | CONFIG_USB_ARCH_HAS_HCD=y | ||
905 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
906 | 929 | ||
907 | # | 930 | # |
908 | # USB Host Controller Drivers | 931 | # USB Host Controller Drivers |
@@ -911,6 +934,8 @@ CONFIG_USB_EHCI_HCD=y | |||
911 | # CONFIG_USB_EHCI_SPLIT_ISO is not set | 934 | # CONFIG_USB_EHCI_SPLIT_ISO is not set |
912 | # CONFIG_USB_EHCI_ROOT_HUB_TT is not set | 935 | # CONFIG_USB_EHCI_ROOT_HUB_TT is not set |
913 | CONFIG_USB_OHCI_HCD=y | 936 | CONFIG_USB_OHCI_HCD=y |
937 | # CONFIG_USB_OHCI_BIG_ENDIAN is not set | ||
938 | CONFIG_USB_OHCI_LITTLE_ENDIAN=y | ||
914 | # CONFIG_USB_UHCI_HCD is not set | 939 | # CONFIG_USB_UHCI_HCD is not set |
915 | # CONFIG_USB_SL811_HCD is not set | 940 | # CONFIG_USB_SL811_HCD is not set |
916 | 941 | ||
@@ -926,12 +951,11 @@ CONFIG_USB_OHCI_HCD=y | |||
926 | # | 951 | # |
927 | CONFIG_USB_STORAGE=y | 952 | CONFIG_USB_STORAGE=y |
928 | # CONFIG_USB_STORAGE_DEBUG is not set | 953 | # CONFIG_USB_STORAGE_DEBUG is not set |
929 | # CONFIG_USB_STORAGE_RW_DETECT is not set | ||
930 | # CONFIG_USB_STORAGE_DATAFAB is not set | 954 | # CONFIG_USB_STORAGE_DATAFAB is not set |
931 | # CONFIG_USB_STORAGE_FREECOM is not set | 955 | # CONFIG_USB_STORAGE_FREECOM is not set |
932 | # CONFIG_USB_STORAGE_ISD200 is not set | 956 | # CONFIG_USB_STORAGE_ISD200 is not set |
933 | # CONFIG_USB_STORAGE_DPCM is not set | 957 | # CONFIG_USB_STORAGE_DPCM is not set |
934 | # CONFIG_USB_STORAGE_HP8200e is not set | 958 | # CONFIG_USB_STORAGE_USBAT is not set |
935 | # CONFIG_USB_STORAGE_SDDR09 is not set | 959 | # CONFIG_USB_STORAGE_SDDR09 is not set |
936 | # CONFIG_USB_STORAGE_SDDR55 is not set | 960 | # CONFIG_USB_STORAGE_SDDR55 is not set |
937 | # CONFIG_USB_STORAGE_JUMPSHOT is not set | 961 | # CONFIG_USB_STORAGE_JUMPSHOT is not set |
@@ -975,6 +999,7 @@ CONFIG_USB_HIDDEV=y | |||
975 | # CONFIG_USB_PEGASUS is not set | 999 | # CONFIG_USB_PEGASUS is not set |
976 | # CONFIG_USB_RTL8150 is not set | 1000 | # CONFIG_USB_RTL8150 is not set |
977 | # CONFIG_USB_USBNET is not set | 1001 | # CONFIG_USB_USBNET is not set |
1002 | CONFIG_USB_MON=y | ||
978 | 1003 | ||
979 | # | 1004 | # |
980 | # USB port drivers | 1005 | # USB port drivers |
@@ -1000,6 +1025,7 @@ CONFIG_USB_HIDDEV=y | |||
1000 | # CONFIG_USB_PHIDGETKIT is not set | 1025 | # CONFIG_USB_PHIDGETKIT is not set |
1001 | # CONFIG_USB_PHIDGETSERVO is not set | 1026 | # CONFIG_USB_PHIDGETSERVO is not set |
1002 | # CONFIG_USB_IDMOUSE is not set | 1027 | # CONFIG_USB_IDMOUSE is not set |
1028 | # CONFIG_USB_SISUSBVGA is not set | ||
1003 | # CONFIG_USB_TEST is not set | 1029 | # CONFIG_USB_TEST is not set |
1004 | 1030 | ||
1005 | # | 1031 | # |
@@ -1208,10 +1234,13 @@ CONFIG_OPROFILE=y | |||
1208 | # | 1234 | # |
1209 | # Kernel hacking | 1235 | # Kernel hacking |
1210 | # | 1236 | # |
1237 | # CONFIG_PRINTK_TIME is not set | ||
1211 | CONFIG_DEBUG_KERNEL=y | 1238 | CONFIG_DEBUG_KERNEL=y |
1212 | CONFIG_MAGIC_SYSRQ=y | 1239 | CONFIG_MAGIC_SYSRQ=y |
1240 | CONFIG_LOG_BUF_SHIFT=17 | ||
1213 | # CONFIG_SCHEDSTATS is not set | 1241 | # CONFIG_SCHEDSTATS is not set |
1214 | # CONFIG_DEBUG_SLAB is not set | 1242 | # CONFIG_DEBUG_SLAB is not set |
1243 | # CONFIG_DEBUG_SPINLOCK is not set | ||
1215 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | 1244 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set |
1216 | # CONFIG_DEBUG_KOBJECT is not set | 1245 | # CONFIG_DEBUG_KOBJECT is not set |
1217 | # CONFIG_DEBUG_INFO is not set | 1246 | # CONFIG_DEBUG_INFO is not set |
@@ -1243,6 +1272,7 @@ CONFIG_CRYPTO_SHA1=m | |||
1243 | CONFIG_CRYPTO_SHA256=m | 1272 | CONFIG_CRYPTO_SHA256=m |
1244 | CONFIG_CRYPTO_SHA512=m | 1273 | CONFIG_CRYPTO_SHA512=m |
1245 | CONFIG_CRYPTO_WP512=m | 1274 | CONFIG_CRYPTO_WP512=m |
1275 | CONFIG_CRYPTO_TGR192=m | ||
1246 | CONFIG_CRYPTO_DES=y | 1276 | CONFIG_CRYPTO_DES=y |
1247 | CONFIG_CRYPTO_BLOWFISH=m | 1277 | CONFIG_CRYPTO_BLOWFISH=m |
1248 | CONFIG_CRYPTO_TWOFISH=m | 1278 | CONFIG_CRYPTO_TWOFISH=m |
diff --git a/arch/ppc64/defconfig b/arch/ppc64/defconfig index 537b1cc82eab..2f31bf3046f9 100644 --- a/arch/ppc64/defconfig +++ b/arch/ppc64/defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.11-rc3-bk6 | 3 | # Linux kernel version: 2.6.12-rc5-git9 |
4 | # Wed Feb 9 23:34:51 2005 | 4 | # Sun Jun 5 09:26:47 2005 |
5 | # | 5 | # |
6 | CONFIG_64BIT=y | 6 | CONFIG_64BIT=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
@@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y | |||
11 | CONFIG_HAVE_DEC_LOCK=y | 11 | CONFIG_HAVE_DEC_LOCK=y |
12 | CONFIG_EARLY_PRINTK=y | 12 | CONFIG_EARLY_PRINTK=y |
13 | CONFIG_COMPAT=y | 13 | CONFIG_COMPAT=y |
14 | CONFIG_FRAME_POINTER=y | 14 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y |
15 | CONFIG_FORCE_MAX_ZONEORDER=13 | 15 | CONFIG_FORCE_MAX_ZONEORDER=13 |
16 | 16 | ||
17 | # | 17 | # |
@@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13 | |||
20 | CONFIG_EXPERIMENTAL=y | 20 | CONFIG_EXPERIMENTAL=y |
21 | CONFIG_CLEAN_COMPILE=y | 21 | CONFIG_CLEAN_COMPILE=y |
22 | CONFIG_LOCK_KERNEL=y | 22 | CONFIG_LOCK_KERNEL=y |
23 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
23 | 24 | ||
24 | # | 25 | # |
25 | # General setup | 26 | # General setup |
@@ -30,24 +31,28 @@ CONFIG_SYSVIPC=y | |||
30 | CONFIG_POSIX_MQUEUE=y | 31 | CONFIG_POSIX_MQUEUE=y |
31 | # CONFIG_BSD_PROCESS_ACCT is not set | 32 | # CONFIG_BSD_PROCESS_ACCT is not set |
32 | CONFIG_SYSCTL=y | 33 | CONFIG_SYSCTL=y |
33 | CONFIG_LOG_BUF_SHIFT=17 | 34 | # CONFIG_AUDIT is not set |
34 | CONFIG_HOTPLUG=y | 35 | CONFIG_HOTPLUG=y |
35 | CONFIG_KOBJECT_UEVENT=y | 36 | CONFIG_KOBJECT_UEVENT=y |
36 | CONFIG_IKCONFIG=y | 37 | CONFIG_IKCONFIG=y |
37 | CONFIG_IKCONFIG_PROC=y | 38 | CONFIG_IKCONFIG_PROC=y |
39 | CONFIG_CPUSETS=y | ||
38 | # CONFIG_EMBEDDED is not set | 40 | # CONFIG_EMBEDDED is not set |
39 | CONFIG_KALLSYMS=y | 41 | CONFIG_KALLSYMS=y |
40 | # CONFIG_KALLSYMS_ALL is not set | 42 | # CONFIG_KALLSYMS_ALL is not set |
41 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 43 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
44 | CONFIG_PRINTK=y | ||
45 | CONFIG_BUG=y | ||
46 | CONFIG_BASE_FULL=y | ||
42 | CONFIG_FUTEX=y | 47 | CONFIG_FUTEX=y |
43 | CONFIG_EPOLL=y | 48 | CONFIG_EPOLL=y |
44 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
45 | CONFIG_SHMEM=y | 49 | CONFIG_SHMEM=y |
46 | CONFIG_CC_ALIGN_FUNCTIONS=0 | 50 | CONFIG_CC_ALIGN_FUNCTIONS=0 |
47 | CONFIG_CC_ALIGN_LABELS=0 | 51 | CONFIG_CC_ALIGN_LABELS=0 |
48 | CONFIG_CC_ALIGN_LOOPS=0 | 52 | CONFIG_CC_ALIGN_LOOPS=0 |
49 | CONFIG_CC_ALIGN_JUMPS=0 | 53 | CONFIG_CC_ALIGN_JUMPS=0 |
50 | # CONFIG_TINY_SHMEM is not set | 54 | # CONFIG_TINY_SHMEM is not set |
55 | CONFIG_BASE_SMALL=0 | ||
51 | 56 | ||
52 | # | 57 | # |
53 | # Loadable module support | 58 | # Loadable module support |
@@ -91,9 +96,12 @@ CONFIG_DISCONTIGMEM=y | |||
91 | CONFIG_EEH=y | 96 | CONFIG_EEH=y |
92 | CONFIG_GENERIC_HARDIRQS=y | 97 | CONFIG_GENERIC_HARDIRQS=y |
93 | CONFIG_PPC_RTAS=y | 98 | CONFIG_PPC_RTAS=y |
99 | CONFIG_RTAS_PROC=y | ||
94 | CONFIG_RTAS_FLASH=m | 100 | CONFIG_RTAS_FLASH=m |
95 | CONFIG_SCANLOG=m | 101 | CONFIG_SCANLOG=m |
96 | CONFIG_LPARCFG=y | 102 | CONFIG_LPARCFG=y |
103 | CONFIG_SECCOMP=y | ||
104 | CONFIG_ISA_DMA_API=y | ||
97 | 105 | ||
98 | # | 106 | # |
99 | # General setup | 107 | # General setup |
@@ -104,6 +112,7 @@ CONFIG_BINFMT_ELF=y | |||
104 | CONFIG_BINFMT_MISC=m | 112 | CONFIG_BINFMT_MISC=m |
105 | # CONFIG_PCI_LEGACY_PROC is not set | 113 | # CONFIG_PCI_LEGACY_PROC is not set |
106 | # CONFIG_PCI_NAMES is not set | 114 | # CONFIG_PCI_NAMES is not set |
115 | # CONFIG_PCI_DEBUG is not set | ||
107 | CONFIG_HOTPLUG_CPU=y | 116 | CONFIG_HOTPLUG_CPU=y |
108 | 117 | ||
109 | # | 118 | # |
@@ -112,10 +121,6 @@ CONFIG_HOTPLUG_CPU=y | |||
112 | # CONFIG_PCCARD is not set | 121 | # CONFIG_PCCARD is not set |
113 | 122 | ||
114 | # | 123 | # |
115 | # PC-card bridges | ||
116 | # | ||
117 | |||
118 | # | ||
119 | # PCI Hotplug Support | 124 | # PCI Hotplug Support |
120 | # | 125 | # |
121 | CONFIG_HOTPLUG_PCI=m | 126 | CONFIG_HOTPLUG_PCI=m |
@@ -149,11 +154,10 @@ CONFIG_FW_LOADER=y | |||
149 | # | 154 | # |
150 | CONFIG_PARPORT=m | 155 | CONFIG_PARPORT=m |
151 | CONFIG_PARPORT_PC=m | 156 | CONFIG_PARPORT_PC=m |
152 | CONFIG_PARPORT_PC_CML1=m | ||
153 | # CONFIG_PARPORT_SERIAL is not set | 157 | # CONFIG_PARPORT_SERIAL is not set |
154 | # CONFIG_PARPORT_PC_FIFO is not set | 158 | # CONFIG_PARPORT_PC_FIFO is not set |
155 | # CONFIG_PARPORT_PC_SUPERIO is not set | 159 | # CONFIG_PARPORT_PC_SUPERIO is not set |
156 | # CONFIG_PARPORT_OTHER is not set | 160 | # CONFIG_PARPORT_GSC is not set |
157 | # CONFIG_PARPORT_1284 is not set | 161 | # CONFIG_PARPORT_1284 is not set |
158 | 162 | ||
159 | # | 163 | # |
@@ -301,6 +305,7 @@ CONFIG_SCSI_SATA_SVW=y | |||
301 | # CONFIG_SCSI_ATA_PIIX is not set | 305 | # CONFIG_SCSI_ATA_PIIX is not set |
302 | # CONFIG_SCSI_SATA_NV is not set | 306 | # CONFIG_SCSI_SATA_NV is not set |
303 | # CONFIG_SCSI_SATA_PROMISE is not set | 307 | # CONFIG_SCSI_SATA_PROMISE is not set |
308 | # CONFIG_SCSI_SATA_QSTOR is not set | ||
304 | # CONFIG_SCSI_SATA_SX4 is not set | 309 | # CONFIG_SCSI_SATA_SX4 is not set |
305 | # CONFIG_SCSI_SATA_SIL is not set | 310 | # CONFIG_SCSI_SATA_SIL is not set |
306 | # CONFIG_SCSI_SATA_SIS is not set | 311 | # CONFIG_SCSI_SATA_SIS is not set |
@@ -310,7 +315,6 @@ CONFIG_SCSI_SATA_SVW=y | |||
310 | # CONFIG_SCSI_BUSLOGIC is not set | 315 | # CONFIG_SCSI_BUSLOGIC is not set |
311 | # CONFIG_SCSI_DMX3191D is not set | 316 | # CONFIG_SCSI_DMX3191D is not set |
312 | # CONFIG_SCSI_EATA is not set | 317 | # CONFIG_SCSI_EATA is not set |
313 | # CONFIG_SCSI_EATA_PIO is not set | ||
314 | # CONFIG_SCSI_FUTURE_DOMAIN is not set | 318 | # CONFIG_SCSI_FUTURE_DOMAIN is not set |
315 | # CONFIG_SCSI_GDTH is not set | 319 | # CONFIG_SCSI_GDTH is not set |
316 | # CONFIG_SCSI_IPS is not set | 320 | # CONFIG_SCSI_IPS is not set |
@@ -327,7 +331,6 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 | |||
327 | CONFIG_SCSI_IPR=y | 331 | CONFIG_SCSI_IPR=y |
328 | CONFIG_SCSI_IPR_TRACE=y | 332 | CONFIG_SCSI_IPR_TRACE=y |
329 | CONFIG_SCSI_IPR_DUMP=y | 333 | CONFIG_SCSI_IPR_DUMP=y |
330 | # CONFIG_SCSI_QLOGIC_ISP is not set | ||
331 | # CONFIG_SCSI_QLOGIC_FC is not set | 334 | # CONFIG_SCSI_QLOGIC_FC is not set |
332 | # CONFIG_SCSI_QLOGIC_1280 is not set | 335 | # CONFIG_SCSI_QLOGIC_1280 is not set |
333 | CONFIG_SCSI_QLA2XXX=y | 336 | CONFIG_SCSI_QLA2XXX=y |
@@ -336,6 +339,7 @@ CONFIG_SCSI_QLA22XX=m | |||
336 | CONFIG_SCSI_QLA2300=m | 339 | CONFIG_SCSI_QLA2300=m |
337 | CONFIG_SCSI_QLA2322=m | 340 | CONFIG_SCSI_QLA2322=m |
338 | CONFIG_SCSI_QLA6312=m | 341 | CONFIG_SCSI_QLA6312=m |
342 | CONFIG_SCSI_LPFC=m | ||
339 | # CONFIG_SCSI_DC395x is not set | 343 | # CONFIG_SCSI_DC395x is not set |
340 | # CONFIG_SCSI_DC390T is not set | 344 | # CONFIG_SCSI_DC390T is not set |
341 | CONFIG_SCSI_DEBUG=m | 345 | CONFIG_SCSI_DEBUG=m |
@@ -358,6 +362,8 @@ CONFIG_DM_CRYPT=m | |||
358 | CONFIG_DM_SNAPSHOT=m | 362 | CONFIG_DM_SNAPSHOT=m |
359 | CONFIG_DM_MIRROR=m | 363 | CONFIG_DM_MIRROR=m |
360 | CONFIG_DM_ZERO=m | 364 | CONFIG_DM_ZERO=m |
365 | CONFIG_DM_MULTIPATH=m | ||
366 | CONFIG_DM_MULTIPATH_EMC=m | ||
361 | 367 | ||
362 | # | 368 | # |
363 | # Fusion MPT device support | 369 | # Fusion MPT device support |
@@ -405,6 +411,7 @@ CONFIG_IEEE1394_AMDTP=m | |||
405 | # | 411 | # |
406 | CONFIG_ADB=y | 412 | CONFIG_ADB=y |
407 | CONFIG_ADB_PMU=y | 413 | CONFIG_ADB_PMU=y |
414 | CONFIG_PMAC_SMU=y | ||
408 | # CONFIG_PMAC_PBOOK is not set | 415 | # CONFIG_PMAC_PBOOK is not set |
409 | # CONFIG_PMAC_BACKLIGHT is not set | 416 | # CONFIG_PMAC_BACKLIGHT is not set |
410 | # CONFIG_INPUT_ADBHID is not set | 417 | # CONFIG_INPUT_ADBHID is not set |
@@ -420,7 +427,6 @@ CONFIG_NET=y | |||
420 | # | 427 | # |
421 | CONFIG_PACKET=y | 428 | CONFIG_PACKET=y |
422 | # CONFIG_PACKET_MMAP is not set | 429 | # CONFIG_PACKET_MMAP is not set |
423 | # CONFIG_NETLINK_DEV is not set | ||
424 | CONFIG_UNIX=y | 430 | CONFIG_UNIX=y |
425 | CONFIG_NET_KEY=m | 431 | CONFIG_NET_KEY=m |
426 | CONFIG_INET=y | 432 | CONFIG_INET=y |
@@ -588,7 +594,6 @@ CONFIG_PCNET32=y | |||
588 | # CONFIG_DGRS is not set | 594 | # CONFIG_DGRS is not set |
589 | # CONFIG_EEPRO100 is not set | 595 | # CONFIG_EEPRO100 is not set |
590 | CONFIG_E100=y | 596 | CONFIG_E100=y |
591 | # CONFIG_E100_NAPI is not set | ||
592 | # CONFIG_FEALNX is not set | 597 | # CONFIG_FEALNX is not set |
593 | # CONFIG_NATSEMI is not set | 598 | # CONFIG_NATSEMI is not set |
594 | # CONFIG_NE2K_PCI is not set | 599 | # CONFIG_NE2K_PCI is not set |
@@ -614,6 +619,8 @@ CONFIG_E1000=y | |||
614 | # CONFIG_SK98LIN is not set | 619 | # CONFIG_SK98LIN is not set |
615 | # CONFIG_VIA_VELOCITY is not set | 620 | # CONFIG_VIA_VELOCITY is not set |
616 | CONFIG_TIGON3=y | 621 | CONFIG_TIGON3=y |
622 | # CONFIG_BNX2 is not set | ||
623 | # CONFIG_MV643XX_ETH is not set | ||
617 | 624 | ||
618 | # | 625 | # |
619 | # Ethernet (10000 Mbit) | 626 | # Ethernet (10000 Mbit) |
@@ -683,20 +690,6 @@ CONFIG_INPUT_EVDEV=m | |||
683 | # CONFIG_INPUT_EVBUG is not set | 690 | # CONFIG_INPUT_EVBUG is not set |
684 | 691 | ||
685 | # | 692 | # |
686 | # Input I/O drivers | ||
687 | # | ||
688 | # CONFIG_GAMEPORT is not set | ||
689 | CONFIG_SOUND_GAMEPORT=y | ||
690 | CONFIG_SERIO=y | ||
691 | CONFIG_SERIO_I8042=y | ||
692 | # CONFIG_SERIO_SERPORT is not set | ||
693 | # CONFIG_SERIO_CT82C710 is not set | ||
694 | # CONFIG_SERIO_PARKBD is not set | ||
695 | # CONFIG_SERIO_PCIPS2 is not set | ||
696 | CONFIG_SERIO_LIBPS2=y | ||
697 | # CONFIG_SERIO_RAW is not set | ||
698 | |||
699 | # | ||
700 | # Input Device Drivers | 693 | # Input Device Drivers |
701 | # | 694 | # |
702 | CONFIG_INPUT_KEYBOARD=y | 695 | CONFIG_INPUT_KEYBOARD=y |
@@ -716,6 +709,18 @@ CONFIG_INPUT_PCSPKR=m | |||
716 | # CONFIG_INPUT_UINPUT is not set | 709 | # CONFIG_INPUT_UINPUT is not set |
717 | 710 | ||
718 | # | 711 | # |
712 | # Hardware I/O ports | ||
713 | # | ||
714 | CONFIG_SERIO=y | ||
715 | CONFIG_SERIO_I8042=y | ||
716 | # CONFIG_SERIO_SERPORT is not set | ||
717 | # CONFIG_SERIO_PARKBD is not set | ||
718 | # CONFIG_SERIO_PCIPS2 is not set | ||
719 | CONFIG_SERIO_LIBPS2=y | ||
720 | # CONFIG_SERIO_RAW is not set | ||
721 | # CONFIG_GAMEPORT is not set | ||
722 | |||
723 | # | ||
719 | # Character devices | 724 | # Character devices |
720 | # | 725 | # |
721 | CONFIG_VT=y | 726 | CONFIG_VT=y |
@@ -738,6 +743,7 @@ CONFIG_SERIAL_CORE=y | |||
738 | CONFIG_SERIAL_CORE_CONSOLE=y | 743 | CONFIG_SERIAL_CORE_CONSOLE=y |
739 | # CONFIG_SERIAL_PMACZILOG is not set | 744 | # CONFIG_SERIAL_PMACZILOG is not set |
740 | CONFIG_SERIAL_ICOM=m | 745 | CONFIG_SERIAL_ICOM=m |
746 | CONFIG_SERIAL_JSM=m | ||
741 | CONFIG_UNIX98_PTYS=y | 747 | CONFIG_UNIX98_PTYS=y |
742 | CONFIG_LEGACY_PTYS=y | 748 | CONFIG_LEGACY_PTYS=y |
743 | CONFIG_LEGACY_PTY_COUNT=256 | 749 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -766,9 +772,16 @@ CONFIG_HVCS=m | |||
766 | # | 772 | # |
767 | # Ftape, the floppy tape device driver | 773 | # Ftape, the floppy tape device driver |
768 | # | 774 | # |
775 | # CONFIG_AGP is not set | ||
769 | # CONFIG_DRM is not set | 776 | # CONFIG_DRM is not set |
770 | CONFIG_RAW_DRIVER=y | 777 | CONFIG_RAW_DRIVER=y |
771 | CONFIG_MAX_RAW_DEVS=256 | 778 | CONFIG_MAX_RAW_DEVS=256 |
779 | # CONFIG_HANGCHECK_TIMER is not set | ||
780 | |||
781 | # | ||
782 | # TPM devices | ||
783 | # | ||
784 | # CONFIG_TCG_TPM is not set | ||
772 | 785 | ||
773 | # | 786 | # |
774 | # I2C support | 787 | # I2C support |
@@ -793,9 +806,9 @@ CONFIG_I2C_ALGOBIT=y | |||
793 | CONFIG_I2C_AMD8111=y | 806 | CONFIG_I2C_AMD8111=y |
794 | # CONFIG_I2C_I801 is not set | 807 | # CONFIG_I2C_I801 is not set |
795 | # CONFIG_I2C_I810 is not set | 808 | # CONFIG_I2C_I810 is not set |
809 | # CONFIG_I2C_PIIX4 is not set | ||
796 | # CONFIG_I2C_ISA is not set | 810 | # CONFIG_I2C_ISA is not set |
797 | CONFIG_I2C_KEYWEST=y | 811 | CONFIG_I2C_KEYWEST=y |
798 | # CONFIG_I2C_MPC is not set | ||
799 | # CONFIG_I2C_NFORCE2 is not set | 812 | # CONFIG_I2C_NFORCE2 is not set |
800 | # CONFIG_I2C_PARPORT is not set | 813 | # CONFIG_I2C_PARPORT is not set |
801 | # CONFIG_I2C_PARPORT_LIGHT is not set | 814 | # CONFIG_I2C_PARPORT_LIGHT is not set |
@@ -822,7 +835,9 @@ CONFIG_I2C_KEYWEST=y | |||
822 | # CONFIG_SENSORS_ASB100 is not set | 835 | # CONFIG_SENSORS_ASB100 is not set |
823 | # CONFIG_SENSORS_DS1621 is not set | 836 | # CONFIG_SENSORS_DS1621 is not set |
824 | # CONFIG_SENSORS_FSCHER is not set | 837 | # CONFIG_SENSORS_FSCHER is not set |
838 | # CONFIG_SENSORS_FSCPOS is not set | ||
825 | # CONFIG_SENSORS_GL518SM is not set | 839 | # CONFIG_SENSORS_GL518SM is not set |
840 | # CONFIG_SENSORS_GL520SM is not set | ||
826 | # CONFIG_SENSORS_IT87 is not set | 841 | # CONFIG_SENSORS_IT87 is not set |
827 | # CONFIG_SENSORS_LM63 is not set | 842 | # CONFIG_SENSORS_LM63 is not set |
828 | # CONFIG_SENSORS_LM75 is not set | 843 | # CONFIG_SENSORS_LM75 is not set |
@@ -833,9 +848,11 @@ CONFIG_I2C_KEYWEST=y | |||
833 | # CONFIG_SENSORS_LM85 is not set | 848 | # CONFIG_SENSORS_LM85 is not set |
834 | # CONFIG_SENSORS_LM87 is not set | 849 | # CONFIG_SENSORS_LM87 is not set |
835 | # CONFIG_SENSORS_LM90 is not set | 850 | # CONFIG_SENSORS_LM90 is not set |
851 | # CONFIG_SENSORS_LM92 is not set | ||
836 | # CONFIG_SENSORS_MAX1619 is not set | 852 | # CONFIG_SENSORS_MAX1619 is not set |
837 | # CONFIG_SENSORS_PC87360 is not set | 853 | # CONFIG_SENSORS_PC87360 is not set |
838 | # CONFIG_SENSORS_SMSC47B397 is not set | 854 | # CONFIG_SENSORS_SMSC47B397 is not set |
855 | # CONFIG_SENSORS_SIS5595 is not set | ||
839 | # CONFIG_SENSORS_SMSC47M1 is not set | 856 | # CONFIG_SENSORS_SMSC47M1 is not set |
840 | # CONFIG_SENSORS_VIA686A is not set | 857 | # CONFIG_SENSORS_VIA686A is not set |
841 | # CONFIG_SENSORS_W83781D is not set | 858 | # CONFIG_SENSORS_W83781D is not set |
@@ -845,6 +862,7 @@ CONFIG_I2C_KEYWEST=y | |||
845 | # | 862 | # |
846 | # Other I2C Chip support | 863 | # Other I2C Chip support |
847 | # | 864 | # |
865 | # CONFIG_SENSORS_DS1337 is not set | ||
848 | # CONFIG_SENSORS_EEPROM is not set | 866 | # CONFIG_SENSORS_EEPROM is not set |
849 | # CONFIG_SENSORS_PCF8574 is not set | 867 | # CONFIG_SENSORS_PCF8574 is not set |
850 | # CONFIG_SENSORS_PCF8591 is not set | 868 | # CONFIG_SENSORS_PCF8591 is not set |
@@ -877,6 +895,11 @@ CONFIG_I2C_KEYWEST=y | |||
877 | # Graphics support | 895 | # Graphics support |
878 | # | 896 | # |
879 | CONFIG_FB=y | 897 | CONFIG_FB=y |
898 | CONFIG_FB_CFB_FILLRECT=y | ||
899 | CONFIG_FB_CFB_COPYAREA=y | ||
900 | CONFIG_FB_CFB_IMAGEBLIT=y | ||
901 | CONFIG_FB_SOFT_CURSOR=y | ||
902 | CONFIG_FB_MACMODES=y | ||
880 | CONFIG_FB_MODE_HELPERS=y | 903 | CONFIG_FB_MODE_HELPERS=y |
881 | CONFIG_FB_TILEBLITTING=y | 904 | CONFIG_FB_TILEBLITTING=y |
882 | # CONFIG_FB_CIRRUS is not set | 905 | # CONFIG_FB_CIRRUS is not set |
@@ -890,9 +913,8 @@ CONFIG_FB_OF=y | |||
890 | # CONFIG_FB_ASILIANT is not set | 913 | # CONFIG_FB_ASILIANT is not set |
891 | # CONFIG_FB_IMSTT is not set | 914 | # CONFIG_FB_IMSTT is not set |
892 | # CONFIG_FB_VGA16 is not set | 915 | # CONFIG_FB_VGA16 is not set |
893 | CONFIG_FB_RIVA=y | 916 | # CONFIG_FB_NVIDIA is not set |
894 | CONFIG_FB_RIVA_I2C=y | 917 | # CONFIG_FB_RIVA is not set |
895 | # CONFIG_FB_RIVA_DEBUG is not set | ||
896 | CONFIG_FB_MATROX=y | 918 | CONFIG_FB_MATROX=y |
897 | CONFIG_FB_MATROX_MILLENIUM=y | 919 | CONFIG_FB_MATROX_MILLENIUM=y |
898 | CONFIG_FB_MATROX_MYSTIQUE=y | 920 | CONFIG_FB_MATROX_MYSTIQUE=y |
@@ -913,6 +935,7 @@ CONFIG_FB_RADEON_I2C=y | |||
913 | # CONFIG_FB_3DFX is not set | 935 | # CONFIG_FB_3DFX is not set |
914 | # CONFIG_FB_VOODOO1 is not set | 936 | # CONFIG_FB_VOODOO1 is not set |
915 | # CONFIG_FB_TRIDENT is not set | 937 | # CONFIG_FB_TRIDENT is not set |
938 | # CONFIG_FB_S1D13XXX is not set | ||
916 | # CONFIG_FB_VIRTUAL is not set | 939 | # CONFIG_FB_VIRTUAL is not set |
917 | 940 | ||
918 | # | 941 | # |
@@ -946,6 +969,8 @@ CONFIG_LCD_DEVICE=y | |||
946 | # | 969 | # |
947 | # USB support | 970 | # USB support |
948 | # | 971 | # |
972 | CONFIG_USB_ARCH_HAS_HCD=y | ||
973 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
949 | CONFIG_USB=y | 974 | CONFIG_USB=y |
950 | # CONFIG_USB_DEBUG is not set | 975 | # CONFIG_USB_DEBUG is not set |
951 | 976 | ||
@@ -956,8 +981,6 @@ CONFIG_USB_DEVICEFS=y | |||
956 | # CONFIG_USB_BANDWIDTH is not set | 981 | # CONFIG_USB_BANDWIDTH is not set |
957 | # CONFIG_USB_DYNAMIC_MINORS is not set | 982 | # CONFIG_USB_DYNAMIC_MINORS is not set |
958 | # CONFIG_USB_OTG is not set | 983 | # CONFIG_USB_OTG is not set |
959 | CONFIG_USB_ARCH_HAS_HCD=y | ||
960 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
961 | 984 | ||
962 | # | 985 | # |
963 | # USB Host Controller Drivers | 986 | # USB Host Controller Drivers |
@@ -966,6 +989,8 @@ CONFIG_USB_EHCI_HCD=y | |||
966 | # CONFIG_USB_EHCI_SPLIT_ISO is not set | 989 | # CONFIG_USB_EHCI_SPLIT_ISO is not set |
967 | # CONFIG_USB_EHCI_ROOT_HUB_TT is not set | 990 | # CONFIG_USB_EHCI_ROOT_HUB_TT is not set |
968 | CONFIG_USB_OHCI_HCD=y | 991 | CONFIG_USB_OHCI_HCD=y |
992 | # CONFIG_USB_OHCI_BIG_ENDIAN is not set | ||
993 | CONFIG_USB_OHCI_LITTLE_ENDIAN=y | ||
969 | # CONFIG_USB_UHCI_HCD is not set | 994 | # CONFIG_USB_UHCI_HCD is not set |
970 | # CONFIG_USB_SL811_HCD is not set | 995 | # CONFIG_USB_SL811_HCD is not set |
971 | 996 | ||
@@ -981,12 +1006,11 @@ CONFIG_USB_OHCI_HCD=y | |||
981 | # | 1006 | # |
982 | CONFIG_USB_STORAGE=m | 1007 | CONFIG_USB_STORAGE=m |
983 | # CONFIG_USB_STORAGE_DEBUG is not set | 1008 | # CONFIG_USB_STORAGE_DEBUG is not set |
984 | CONFIG_USB_STORAGE_RW_DETECT=y | ||
985 | # CONFIG_USB_STORAGE_DATAFAB is not set | 1009 | # CONFIG_USB_STORAGE_DATAFAB is not set |
986 | # CONFIG_USB_STORAGE_FREECOM is not set | 1010 | # CONFIG_USB_STORAGE_FREECOM is not set |
987 | # CONFIG_USB_STORAGE_ISD200 is not set | 1011 | # CONFIG_USB_STORAGE_ISD200 is not set |
988 | # CONFIG_USB_STORAGE_DPCM is not set | 1012 | # CONFIG_USB_STORAGE_DPCM is not set |
989 | # CONFIG_USB_STORAGE_HP8200e is not set | 1013 | # CONFIG_USB_STORAGE_USBAT is not set |
990 | # CONFIG_USB_STORAGE_SDDR09 is not set | 1014 | # CONFIG_USB_STORAGE_SDDR09 is not set |
991 | # CONFIG_USB_STORAGE_SDDR55 is not set | 1015 | # CONFIG_USB_STORAGE_SDDR55 is not set |
992 | # CONFIG_USB_STORAGE_JUMPSHOT is not set | 1016 | # CONFIG_USB_STORAGE_JUMPSHOT is not set |
@@ -1030,6 +1054,7 @@ CONFIG_USB_HIDDEV=y | |||
1030 | CONFIG_USB_PEGASUS=y | 1054 | CONFIG_USB_PEGASUS=y |
1031 | # CONFIG_USB_RTL8150 is not set | 1055 | # CONFIG_USB_RTL8150 is not set |
1032 | # CONFIG_USB_USBNET is not set | 1056 | # CONFIG_USB_USBNET is not set |
1057 | # CONFIG_USB_MON is not set | ||
1033 | 1058 | ||
1034 | # | 1059 | # |
1035 | # USB port drivers | 1060 | # USB port drivers |
@@ -1055,6 +1080,7 @@ CONFIG_USB_PEGASUS=y | |||
1055 | # CONFIG_USB_PHIDGETKIT is not set | 1080 | # CONFIG_USB_PHIDGETKIT is not set |
1056 | # CONFIG_USB_PHIDGETSERVO is not set | 1081 | # CONFIG_USB_PHIDGETSERVO is not set |
1057 | # CONFIG_USB_IDMOUSE is not set | 1082 | # CONFIG_USB_IDMOUSE is not set |
1083 | # CONFIG_USB_SISUSBVGA is not set | ||
1058 | # CONFIG_USB_TEST is not set | 1084 | # CONFIG_USB_TEST is not set |
1059 | 1085 | ||
1060 | # | 1086 | # |
@@ -1276,10 +1302,13 @@ CONFIG_OPROFILE=y | |||
1276 | # | 1302 | # |
1277 | # Kernel hacking | 1303 | # Kernel hacking |
1278 | # | 1304 | # |
1305 | # CONFIG_PRINTK_TIME is not set | ||
1279 | CONFIG_DEBUG_KERNEL=y | 1306 | CONFIG_DEBUG_KERNEL=y |
1280 | CONFIG_MAGIC_SYSRQ=y | 1307 | CONFIG_MAGIC_SYSRQ=y |
1308 | CONFIG_LOG_BUF_SHIFT=17 | ||
1281 | # CONFIG_SCHEDSTATS is not set | 1309 | # CONFIG_SCHEDSTATS is not set |
1282 | # CONFIG_DEBUG_SLAB is not set | 1310 | # CONFIG_DEBUG_SLAB is not set |
1311 | # CONFIG_DEBUG_SPINLOCK is not set | ||
1283 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | 1312 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set |
1284 | # CONFIG_DEBUG_KOBJECT is not set | 1313 | # CONFIG_DEBUG_KOBJECT is not set |
1285 | # CONFIG_DEBUG_INFO is not set | 1314 | # CONFIG_DEBUG_INFO is not set |
@@ -1311,6 +1340,7 @@ CONFIG_CRYPTO_SHA1=m | |||
1311 | CONFIG_CRYPTO_SHA256=m | 1340 | CONFIG_CRYPTO_SHA256=m |
1312 | CONFIG_CRYPTO_SHA512=m | 1341 | CONFIG_CRYPTO_SHA512=m |
1313 | CONFIG_CRYPTO_WP512=m | 1342 | CONFIG_CRYPTO_WP512=m |
1343 | CONFIG_CRYPTO_TGR192=m | ||
1314 | CONFIG_CRYPTO_DES=y | 1344 | CONFIG_CRYPTO_DES=y |
1315 | CONFIG_CRYPTO_BLOWFISH=m | 1345 | CONFIG_CRYPTO_BLOWFISH=m |
1316 | CONFIG_CRYPTO_TWOFISH=m | 1346 | CONFIG_CRYPTO_TWOFISH=m |
diff --git a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S index d3604056e1a9..b61572eb2a71 100644 --- a/arch/ppc64/kernel/entry.S +++ b/arch/ppc64/kernel/entry.S | |||
@@ -436,15 +436,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | |||
436 | REST_8GPRS(14, r1) | 436 | REST_8GPRS(14, r1) |
437 | REST_10GPRS(22, r1) | 437 | REST_10GPRS(22, r1) |
438 | 438 | ||
439 | #ifdef CONFIG_PPC_ISERIES | ||
440 | clrrdi r7,r1,THREAD_SHIFT /* get current_thread_info() */ | ||
441 | ld r7,TI_FLAGS(r7) /* Get run light flag */ | ||
442 | mfspr r9,CTRLF | ||
443 | srdi r7,r7,TIF_RUN_LIGHT | ||
444 | insrdi r9,r7,1,63 /* Insert run light into CTRL */ | ||
445 | mtspr CTRLT,r9 | ||
446 | #endif | ||
447 | |||
448 | /* convert old thread to its task_struct for return value */ | 439 | /* convert old thread to its task_struct for return value */ |
449 | addi r3,r3,-THREAD | 440 | addi r3,r3,-THREAD |
450 | ld r7,_NIP(r1) /* Return to _switch caller in new task */ | 441 | ld r7,_NIP(r1) /* Return to _switch caller in new task */ |
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index 92a744c31ab1..346dbf606b5d 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S | |||
@@ -626,10 +626,10 @@ system_reset_iSeries: | |||
626 | lhz r24,PACAPACAINDEX(r13) /* Get processor # */ | 626 | lhz r24,PACAPACAINDEX(r13) /* Get processor # */ |
627 | cmpwi 0,r24,0 /* Are we processor 0? */ | 627 | cmpwi 0,r24,0 /* Are we processor 0? */ |
628 | beq .__start_initialization_iSeries /* Start up the first processor */ | 628 | beq .__start_initialization_iSeries /* Start up the first processor */ |
629 | mfspr r4,CTRLF | 629 | mfspr r4,SPRN_CTRLF |
630 | li r5,RUNLATCH /* Turn off the run light */ | 630 | li r5,CTRL_RUNLATCH /* Turn off the run light */ |
631 | andc r4,r4,r5 | 631 | andc r4,r4,r5 |
632 | mtspr CTRLT,r4 | 632 | mtspr SPRN_CTRLT,r4 |
633 | 633 | ||
634 | 1: | 634 | 1: |
635 | HMT_LOW | 635 | HMT_LOW |
@@ -2082,9 +2082,9 @@ _GLOBAL(hmt_start_secondary) | |||
2082 | mfspr r4, HID0 | 2082 | mfspr r4, HID0 |
2083 | ori r4, r4, 0x1 | 2083 | ori r4, r4, 0x1 |
2084 | mtspr HID0, r4 | 2084 | mtspr HID0, r4 |
2085 | mfspr r4, CTRLF | 2085 | mfspr r4, SPRN_CTRLF |
2086 | oris r4, r4, 0x40 | 2086 | oris r4, r4, 0x40 |
2087 | mtspr CTRLT, r4 | 2087 | mtspr SPRN_CTRLT, r4 |
2088 | blr | 2088 | blr |
2089 | #endif | 2089 | #endif |
2090 | 2090 | ||
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index da20120f2261..6d06eb550a3f 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c | |||
@@ -852,6 +852,28 @@ static int __init iSeries_src_init(void) | |||
852 | 852 | ||
853 | late_initcall(iSeries_src_init); | 853 | late_initcall(iSeries_src_init); |
854 | 854 | ||
855 | static int set_spread_lpevents(char *str) | ||
856 | { | ||
857 | unsigned long i; | ||
858 | unsigned long val = simple_strtoul(str, NULL, 0); | ||
859 | |||
860 | /* | ||
861 | * The parameter is the number of processors to share in processing | ||
862 | * lp events. | ||
863 | */ | ||
864 | if (( val > 0) && (val <= NR_CPUS)) { | ||
865 | for (i = 1; i < val; ++i) | ||
866 | paca[i].lpqueue_ptr = paca[0].lpqueue_ptr; | ||
867 | |||
868 | printk("lpevent processing spread over %ld processors\n", val); | ||
869 | } else { | ||
870 | printk("invalid spread_lpevents %ld\n", val); | ||
871 | } | ||
872 | |||
873 | return 1; | ||
874 | } | ||
875 | __setup("spread_lpevents=", set_spread_lpevents); | ||
876 | |||
855 | void __init iSeries_early_setup(void) | 877 | void __init iSeries_early_setup(void) |
856 | { | 878 | { |
857 | iSeries_fixup_klimit(); | 879 | iSeries_fixup_klimit(); |
diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c index 6abc621d3ba0..f24ce2b87200 100644 --- a/arch/ppc64/kernel/idle.c +++ b/arch/ppc64/kernel/idle.c | |||
@@ -75,13 +75,9 @@ static int iSeries_idle(void) | |||
75 | { | 75 | { |
76 | struct paca_struct *lpaca; | 76 | struct paca_struct *lpaca; |
77 | long oldval; | 77 | long oldval; |
78 | unsigned long CTRL; | ||
79 | 78 | ||
80 | /* ensure iSeries run light will be out when idle */ | 79 | /* ensure iSeries run light will be out when idle */ |
81 | clear_thread_flag(TIF_RUN_LIGHT); | 80 | ppc64_runlatch_off(); |
82 | CTRL = mfspr(CTRLF); | ||
83 | CTRL &= ~RUNLATCH; | ||
84 | mtspr(CTRLT, CTRL); | ||
85 | 81 | ||
86 | lpaca = get_paca(); | 82 | lpaca = get_paca(); |
87 | 83 | ||
@@ -111,7 +107,9 @@ static int iSeries_idle(void) | |||
111 | } | 107 | } |
112 | } | 108 | } |
113 | 109 | ||
110 | ppc64_runlatch_on(); | ||
114 | schedule(); | 111 | schedule(); |
112 | ppc64_runlatch_off(); | ||
115 | } | 113 | } |
116 | 114 | ||
117 | return 0; | 115 | return 0; |
diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c index 103daaf73573..e950a2058a19 100644 --- a/arch/ppc64/kernel/kprobes.c +++ b/arch/ppc64/kernel/kprobes.c | |||
@@ -45,12 +45,17 @@ static struct pt_regs jprobe_saved_regs; | |||
45 | 45 | ||
46 | int arch_prepare_kprobe(struct kprobe *p) | 46 | int arch_prepare_kprobe(struct kprobe *p) |
47 | { | 47 | { |
48 | int ret = 0; | ||
48 | kprobe_opcode_t insn = *p->addr; | 49 | kprobe_opcode_t insn = *p->addr; |
49 | 50 | ||
50 | if (IS_MTMSRD(insn) || IS_RFID(insn)) | 51 | if ((unsigned long)p->addr & 0x03) { |
51 | /* cannot put bp on RFID/MTMSRD */ | 52 | printk("Attempt to register kprobe at an unaligned address\n"); |
52 | return 1; | 53 | ret = -EINVAL; |
53 | return 0; | 54 | } else if (IS_MTMSRD(insn) || IS_RFID(insn)) { |
55 | printk("Cannot register a kprobe on rfid or mtmsrd\n"); | ||
56 | ret = -EINVAL; | ||
57 | } | ||
58 | return ret; | ||
54 | } | 59 | } |
55 | 60 | ||
56 | void arch_copy_kprobe(struct kprobe *p) | 61 | void arch_copy_kprobe(struct kprobe *p) |
@@ -172,8 +177,6 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs) | |||
172 | ret = emulate_step(regs, p->ainsn.insn[0]); | 177 | ret = emulate_step(regs, p->ainsn.insn[0]); |
173 | if (ret == 0) | 178 | if (ret == 0) |
174 | regs->nip = (unsigned long)p->addr + 4; | 179 | regs->nip = (unsigned long)p->addr + 4; |
175 | |||
176 | regs->msr &= ~MSR_SE; | ||
177 | } | 180 | } |
178 | 181 | ||
179 | static inline int post_kprobe_handler(struct pt_regs *regs) | 182 | static inline int post_kprobe_handler(struct pt_regs *regs) |
@@ -210,6 +213,7 @@ static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) | |||
210 | 213 | ||
211 | if (kprobe_status & KPROBE_HIT_SS) { | 214 | if (kprobe_status & KPROBE_HIT_SS) { |
212 | resume_execution(current_kprobe, regs); | 215 | resume_execution(current_kprobe, regs); |
216 | regs->msr &= ~MSR_SE; | ||
213 | regs->msr |= kprobe_saved_msr; | 217 | regs->msr |= kprobe_saved_msr; |
214 | 218 | ||
215 | unlock_kprobes(); | 219 | unlock_kprobes(); |
@@ -233,8 +237,6 @@ int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, | |||
233 | */ | 237 | */ |
234 | preempt_disable(); | 238 | preempt_disable(); |
235 | switch (val) { | 239 | switch (val) { |
236 | case DIE_IABR_MATCH: | ||
237 | case DIE_DABR_MATCH: | ||
238 | case DIE_BPT: | 240 | case DIE_BPT: |
239 | if (kprobe_handler(args->regs)) | 241 | if (kprobe_handler(args->regs)) |
240 | ret = NOTIFY_STOP; | 242 | ret = NOTIFY_STOP; |
diff --git a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c index 1bd52ece497c..5aca7e8005a8 100644 --- a/arch/ppc64/kernel/mf.c +++ b/arch/ppc64/kernel/mf.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mf.c | 2 | * mf.c |
3 | * Copyright (C) 2001 Troy D. Armstrong IBM Corporation | 3 | * Copyright (C) 2001 Troy D. Armstrong IBM Corporation |
4 | * Copyright (C) 2004 Stephen Rothwell IBM Corporation | 4 | * Copyright (C) 2004-2005 Stephen Rothwell IBM Corporation |
5 | * | 5 | * |
6 | * This modules exists as an interface between a Linux secondary partition | 6 | * This modules exists as an interface between a Linux secondary partition |
7 | * running on an iSeries and the primary partition's Virtual Service | 7 | * running on an iSeries and the primary partition's Virtual Service |
@@ -36,10 +36,12 @@ | |||
36 | 36 | ||
37 | #include <asm/time.h> | 37 | #include <asm/time.h> |
38 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
39 | #include <asm/paca.h> | ||
39 | #include <asm/iSeries/vio.h> | 40 | #include <asm/iSeries/vio.h> |
40 | #include <asm/iSeries/mf.h> | 41 | #include <asm/iSeries/mf.h> |
41 | #include <asm/iSeries/HvLpConfig.h> | 42 | #include <asm/iSeries/HvLpConfig.h> |
42 | #include <asm/iSeries/ItSpCommArea.h> | 43 | #include <asm/iSeries/ItSpCommArea.h> |
44 | #include <asm/iSeries/ItLpQueue.h> | ||
43 | 45 | ||
44 | /* | 46 | /* |
45 | * This is the structure layout for the Machine Facilites LPAR event | 47 | * This is the structure layout for the Machine Facilites LPAR event |
@@ -696,36 +698,23 @@ static void get_rtc_time_complete(void *token, struct ce_msg_data *ce_msg) | |||
696 | complete(&rtc->com); | 698 | complete(&rtc->com); |
697 | } | 699 | } |
698 | 700 | ||
699 | int mf_get_rtc(struct rtc_time *tm) | 701 | static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm) |
700 | { | 702 | { |
701 | struct ce_msg_comp_data ce_complete; | ||
702 | struct rtc_time_data rtc_data; | ||
703 | int rc; | ||
704 | |||
705 | memset(&ce_complete, 0, sizeof(ce_complete)); | ||
706 | memset(&rtc_data, 0, sizeof(rtc_data)); | ||
707 | init_completion(&rtc_data.com); | ||
708 | ce_complete.handler = &get_rtc_time_complete; | ||
709 | ce_complete.token = &rtc_data; | ||
710 | rc = signal_ce_msg_simple(0x40, &ce_complete); | ||
711 | if (rc) | ||
712 | return rc; | ||
713 | wait_for_completion(&rtc_data.com); | ||
714 | tm->tm_wday = 0; | 703 | tm->tm_wday = 0; |
715 | tm->tm_yday = 0; | 704 | tm->tm_yday = 0; |
716 | tm->tm_isdst = 0; | 705 | tm->tm_isdst = 0; |
717 | if (rtc_data.rc) { | 706 | if (rc) { |
718 | tm->tm_sec = 0; | 707 | tm->tm_sec = 0; |
719 | tm->tm_min = 0; | 708 | tm->tm_min = 0; |
720 | tm->tm_hour = 0; | 709 | tm->tm_hour = 0; |
721 | tm->tm_mday = 15; | 710 | tm->tm_mday = 15; |
722 | tm->tm_mon = 5; | 711 | tm->tm_mon = 5; |
723 | tm->tm_year = 52; | 712 | tm->tm_year = 52; |
724 | return rtc_data.rc; | 713 | return rc; |
725 | } | 714 | } |
726 | 715 | ||
727 | if ((rtc_data.ce_msg.ce_msg[2] == 0xa9) || | 716 | if ((ce_msg[2] == 0xa9) || |
728 | (rtc_data.ce_msg.ce_msg[2] == 0xaf)) { | 717 | (ce_msg[2] == 0xaf)) { |
729 | /* TOD clock is not set */ | 718 | /* TOD clock is not set */ |
730 | tm->tm_sec = 1; | 719 | tm->tm_sec = 1; |
731 | tm->tm_min = 1; | 720 | tm->tm_min = 1; |
@@ -736,7 +725,6 @@ int mf_get_rtc(struct rtc_time *tm) | |||
736 | mf_set_rtc(tm); | 725 | mf_set_rtc(tm); |
737 | } | 726 | } |
738 | { | 727 | { |
739 | u8 *ce_msg = rtc_data.ce_msg.ce_msg; | ||
740 | u8 year = ce_msg[5]; | 728 | u8 year = ce_msg[5]; |
741 | u8 sec = ce_msg[6]; | 729 | u8 sec = ce_msg[6]; |
742 | u8 min = ce_msg[7]; | 730 | u8 min = ce_msg[7]; |
@@ -765,6 +753,63 @@ int mf_get_rtc(struct rtc_time *tm) | |||
765 | return 0; | 753 | return 0; |
766 | } | 754 | } |
767 | 755 | ||
756 | int mf_get_rtc(struct rtc_time *tm) | ||
757 | { | ||
758 | struct ce_msg_comp_data ce_complete; | ||
759 | struct rtc_time_data rtc_data; | ||
760 | int rc; | ||
761 | |||
762 | memset(&ce_complete, 0, sizeof(ce_complete)); | ||
763 | memset(&rtc_data, 0, sizeof(rtc_data)); | ||
764 | init_completion(&rtc_data.com); | ||
765 | ce_complete.handler = &get_rtc_time_complete; | ||
766 | ce_complete.token = &rtc_data; | ||
767 | rc = signal_ce_msg_simple(0x40, &ce_complete); | ||
768 | if (rc) | ||
769 | return rc; | ||
770 | wait_for_completion(&rtc_data.com); | ||
771 | return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm); | ||
772 | } | ||
773 | |||
774 | struct boot_rtc_time_data { | ||
775 | int busy; | ||
776 | struct ce_msg_data ce_msg; | ||
777 | int rc; | ||
778 | }; | ||
779 | |||
780 | static void get_boot_rtc_time_complete(void *token, struct ce_msg_data *ce_msg) | ||
781 | { | ||
782 | struct boot_rtc_time_data *rtc = token; | ||
783 | |||
784 | memcpy(&rtc->ce_msg, ce_msg, sizeof(rtc->ce_msg)); | ||
785 | rtc->rc = 0; | ||
786 | rtc->busy = 0; | ||
787 | } | ||
788 | |||
789 | int mf_get_boot_rtc(struct rtc_time *tm) | ||
790 | { | ||
791 | struct ce_msg_comp_data ce_complete; | ||
792 | struct boot_rtc_time_data rtc_data; | ||
793 | int rc; | ||
794 | |||
795 | memset(&ce_complete, 0, sizeof(ce_complete)); | ||
796 | memset(&rtc_data, 0, sizeof(rtc_data)); | ||
797 | rtc_data.busy = 1; | ||
798 | ce_complete.handler = &get_boot_rtc_time_complete; | ||
799 | ce_complete.token = &rtc_data; | ||
800 | rc = signal_ce_msg_simple(0x40, &ce_complete); | ||
801 | if (rc) | ||
802 | return rc; | ||
803 | /* We need to poll here as we are not yet taking interrupts */ | ||
804 | while (rtc_data.busy) { | ||
805 | extern unsigned long lpevent_count; | ||
806 | struct ItLpQueue *lpq = get_paca()->lpqueue_ptr; | ||
807 | if (lpq && ItLpQueue_isLpIntPending(lpq)) | ||
808 | lpevent_count += ItLpQueue_process(lpq, NULL); | ||
809 | } | ||
810 | return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm); | ||
811 | } | ||
812 | |||
768 | int mf_set_rtc(struct rtc_time *tm) | 813 | int mf_set_rtc(struct rtc_time *tm) |
769 | { | 814 | { |
770 | char ce_time[12]; | 815 | char ce_time[12]; |
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index 90b41f48d21c..e3c73b3425dc 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S | |||
@@ -32,7 +32,7 @@ | |||
32 | .text | 32 | .text |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * Returns (address we're running at) - (address we were linked at) | 35 | * Returns (address we were linked at) - (address we are running at) |
36 | * for use before the text and data are mapped to KERNELBASE. | 36 | * for use before the text and data are mapped to KERNELBASE. |
37 | */ | 37 | */ |
38 | 38 | ||
@@ -792,7 +792,7 @@ _GLOBAL(sys_call_table32) | |||
792 | .llong .compat_sys_newstat | 792 | .llong .compat_sys_newstat |
793 | .llong .compat_sys_newlstat | 793 | .llong .compat_sys_newlstat |
794 | .llong .compat_sys_newfstat | 794 | .llong .compat_sys_newfstat |
795 | .llong .sys_uname | 795 | .llong .sys32_uname |
796 | .llong .sys_ni_syscall /* 110 old iopl syscall */ | 796 | .llong .sys_ni_syscall /* 110 old iopl syscall */ |
797 | .llong .sys_vhangup | 797 | .llong .sys_vhangup |
798 | .llong .sys_ni_syscall /* old idle syscall */ | 798 | .llong .sys_ni_syscall /* old idle syscall */ |
diff --git a/arch/ppc64/kernel/pSeries_reconfig.c b/arch/ppc64/kernel/pSeries_reconfig.c index cb5443f2e49b..dc2a69d412a2 100644 --- a/arch/ppc64/kernel/pSeries_reconfig.c +++ b/arch/ppc64/kernel/pSeries_reconfig.c | |||
@@ -47,14 +47,6 @@ static void remove_node_proc_entries(struct device_node *np) | |||
47 | remove_proc_entry(pp->name, np->pde); | 47 | remove_proc_entry(pp->name, np->pde); |
48 | pp = pp->next; | 48 | pp = pp->next; |
49 | } | 49 | } |
50 | |||
51 | /* Assuming that symlinks have the same parent directory as | ||
52 | * np->pde. | ||
53 | */ | ||
54 | if (np->name_link) | ||
55 | remove_proc_entry(np->name_link->name, parent->pde); | ||
56 | if (np->addr_link) | ||
57 | remove_proc_entry(np->addr_link->name, parent->pde); | ||
58 | if (np->pde) | 50 | if (np->pde) |
59 | remove_proc_entry(np->pde->name, parent->pde); | 51 | remove_proc_entry(np->pde->name, parent->pde); |
60 | } | 52 | } |
diff --git a/arch/ppc64/kernel/pSeries_smp.c b/arch/ppc64/kernel/pSeries_smp.c index c60d8cb2b84d..fbad349ec58c 100644 --- a/arch/ppc64/kernel/pSeries_smp.c +++ b/arch/ppc64/kernel/pSeries_smp.c | |||
@@ -326,13 +326,6 @@ static void __devinit smp_xics_setup_cpu(int cpu) | |||
326 | 326 | ||
327 | cpu_clear(cpu, of_spin_map); | 327 | cpu_clear(cpu, of_spin_map); |
328 | 328 | ||
329 | /* | ||
330 | * Put the calling processor into the GIQ. This is really only | ||
331 | * necessary from a secondary thread as the OF start-cpu interface | ||
332 | * performs this function for us on primary threads. | ||
333 | */ | ||
334 | rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, | ||
335 | (1UL << interrupt_server_size) - 1 - default_distrib_server, 1); | ||
336 | } | 329 | } |
337 | 330 | ||
338 | static DEFINE_SPINLOCK(timebase_lock); | 331 | static DEFINE_SPINLOCK(timebase_lock); |
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c index be3cc387c1ec..d786d4b6af0b 100644 --- a/arch/ppc64/kernel/pci.c +++ b/arch/ppc64/kernel/pci.c | |||
@@ -438,7 +438,7 @@ pgprot_t pci_phys_mem_access_prot(struct file *file, | |||
438 | int i; | 438 | int i; |
439 | 439 | ||
440 | if (page_is_ram(offset >> PAGE_SHIFT)) | 440 | if (page_is_ram(offset >> PAGE_SHIFT)) |
441 | return prot; | 441 | return __pgprot(prot); |
442 | 442 | ||
443 | prot |= _PAGE_NO_CACHE | _PAGE_GUARDED; | 443 | prot |= _PAGE_NO_CACHE | _PAGE_GUARDED; |
444 | 444 | ||
diff --git a/arch/ppc64/kernel/pmac_smp.c b/arch/ppc64/kernel/pmac_smp.c index c27588ede2fe..a23de37227bf 100644 --- a/arch/ppc64/kernel/pmac_smp.c +++ b/arch/ppc64/kernel/pmac_smp.c | |||
@@ -68,6 +68,7 @@ extern struct smp_ops_t *smp_ops; | |||
68 | 68 | ||
69 | static void (*pmac_tb_freeze)(int freeze); | 69 | static void (*pmac_tb_freeze)(int freeze); |
70 | static struct device_node *pmac_tb_clock_chip_host; | 70 | static struct device_node *pmac_tb_clock_chip_host; |
71 | static u8 pmac_tb_pulsar_addr; | ||
71 | static DEFINE_SPINLOCK(timebase_lock); | 72 | static DEFINE_SPINLOCK(timebase_lock); |
72 | static unsigned long timebase; | 73 | static unsigned long timebase; |
73 | 74 | ||
@@ -106,12 +107,9 @@ static void smp_core99_pulsar_tb_freeze(int freeze) | |||
106 | u8 data; | 107 | u8 data; |
107 | int rc; | 108 | int rc; |
108 | 109 | ||
109 | /* Strangely, the device-tree says address is 0xd2, but darwin | ||
110 | * accesses 0xd0 ... | ||
111 | */ | ||
112 | pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined); | 110 | pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined); |
113 | rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, | 111 | rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, |
114 | 0xd4 | pmac_low_i2c_read, | 112 | pmac_tb_pulsar_addr | pmac_low_i2c_read, |
115 | 0x2e, &data, 1); | 113 | 0x2e, &data, 1); |
116 | if (rc != 0) | 114 | if (rc != 0) |
117 | goto bail; | 115 | goto bail; |
@@ -120,7 +118,7 @@ static void smp_core99_pulsar_tb_freeze(int freeze) | |||
120 | 118 | ||
121 | pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub); | 119 | pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub); |
122 | rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, | 120 | rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, |
123 | 0xd4 | pmac_low_i2c_write, | 121 | pmac_tb_pulsar_addr | pmac_low_i2c_write, |
124 | 0x2e, &data, 1); | 122 | 0x2e, &data, 1); |
125 | bail: | 123 | bail: |
126 | if (rc != 0) { | 124 | if (rc != 0) { |
@@ -185,6 +183,12 @@ static int __init smp_core99_probe(void) | |||
185 | if (ncpus <= 1) | 183 | if (ncpus <= 1) |
186 | return 1; | 184 | return 1; |
187 | 185 | ||
186 | /* HW sync only on these platforms */ | ||
187 | if (!machine_is_compatible("PowerMac7,2") && | ||
188 | !machine_is_compatible("PowerMac7,3") && | ||
189 | !machine_is_compatible("RackMac3,1")) | ||
190 | goto nohwsync; | ||
191 | |||
188 | /* Look for the clock chip */ | 192 | /* Look for the clock chip */ |
189 | for (cc = NULL; (cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL;) { | 193 | for (cc = NULL; (cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL;) { |
190 | struct device_node *p = of_get_parent(cc); | 194 | struct device_node *p = of_get_parent(cc); |
@@ -198,11 +202,18 @@ static int __init smp_core99_probe(void) | |||
198 | goto next; | 202 | goto next; |
199 | switch (*reg) { | 203 | switch (*reg) { |
200 | case 0xd2: | 204 | case 0xd2: |
201 | pmac_tb_freeze = smp_core99_cypress_tb_freeze; | 205 | if (device_is_compatible(cc, "pulsar-legacy-slewing")) { |
202 | printk(KERN_INFO "Timebase clock is Cypress chip\n"); | 206 | pmac_tb_freeze = smp_core99_pulsar_tb_freeze; |
207 | pmac_tb_pulsar_addr = 0xd2; | ||
208 | printk(KERN_INFO "Timebase clock is Pulsar chip\n"); | ||
209 | } else if (device_is_compatible(cc, "cy28508")) { | ||
210 | pmac_tb_freeze = smp_core99_cypress_tb_freeze; | ||
211 | printk(KERN_INFO "Timebase clock is Cypress chip\n"); | ||
212 | } | ||
203 | break; | 213 | break; |
204 | case 0xd4: | 214 | case 0xd4: |
205 | pmac_tb_freeze = smp_core99_pulsar_tb_freeze; | 215 | pmac_tb_freeze = smp_core99_pulsar_tb_freeze; |
216 | pmac_tb_pulsar_addr = 0xd4; | ||
206 | printk(KERN_INFO "Timebase clock is Pulsar chip\n"); | 217 | printk(KERN_INFO "Timebase clock is Pulsar chip\n"); |
207 | break; | 218 | break; |
208 | } | 219 | } |
@@ -210,12 +221,15 @@ static int __init smp_core99_probe(void) | |||
210 | pmac_tb_clock_chip_host = p; | 221 | pmac_tb_clock_chip_host = p; |
211 | smp_ops->give_timebase = smp_core99_give_timebase; | 222 | smp_ops->give_timebase = smp_core99_give_timebase; |
212 | smp_ops->take_timebase = smp_core99_take_timebase; | 223 | smp_ops->take_timebase = smp_core99_take_timebase; |
224 | of_node_put(cc); | ||
225 | of_node_put(p); | ||
213 | break; | 226 | break; |
214 | } | 227 | } |
215 | next: | 228 | next: |
216 | of_node_put(p); | 229 | of_node_put(p); |
217 | } | 230 | } |
218 | 231 | ||
232 | nohwsync: | ||
219 | mpic_request_ipis(); | 233 | mpic_request_ipis(); |
220 | 234 | ||
221 | return ncpus; | 235 | return ncpus; |
diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c index 8b0686122738..cdfecbeb331f 100644 --- a/arch/ppc64/kernel/process.c +++ b/arch/ppc64/kernel/process.c | |||
@@ -378,9 +378,6 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, | |||
378 | childregs->gpr[1] = sp + sizeof(struct pt_regs); | 378 | childregs->gpr[1] = sp + sizeof(struct pt_regs); |
379 | p->thread.regs = NULL; /* no user register state */ | 379 | p->thread.regs = NULL; /* no user register state */ |
380 | clear_ti_thread_flag(p->thread_info, TIF_32BIT); | 380 | clear_ti_thread_flag(p->thread_info, TIF_32BIT); |
381 | #ifdef CONFIG_PPC_ISERIES | ||
382 | set_ti_thread_flag(p->thread_info, TIF_RUN_LIGHT); | ||
383 | #endif | ||
384 | } else { | 381 | } else { |
385 | childregs->gpr[1] = usp; | 382 | childregs->gpr[1] = usp; |
386 | p->thread.regs = childregs; | 383 | p->thread.regs = childregs; |
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c index fe2946c58314..eb6538b58008 100644 --- a/arch/ppc64/kernel/prom.c +++ b/arch/ppc64/kernel/prom.c | |||
@@ -834,7 +834,7 @@ void __init unflatten_device_tree(void) | |||
834 | { | 834 | { |
835 | unsigned long start, mem, size; | 835 | unsigned long start, mem, size; |
836 | struct device_node **allnextp = &allnodes; | 836 | struct device_node **allnextp = &allnodes; |
837 | char *p; | 837 | char *p = NULL; |
838 | int l = 0; | 838 | int l = 0; |
839 | 839 | ||
840 | DBG(" -> unflatten_device_tree()\n"); | 840 | DBG(" -> unflatten_device_tree()\n"); |
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c index 35ec42de962e..b7683abfbe6a 100644 --- a/arch/ppc64/kernel/prom_init.c +++ b/arch/ppc64/kernel/prom_init.c | |||
@@ -211,13 +211,23 @@ struct { | |||
211 | */ | 211 | */ |
212 | #define ADDR(x) (u32) ((unsigned long)(x) - offset) | 212 | #define ADDR(x) (u32) ((unsigned long)(x) - offset) |
213 | 213 | ||
214 | /* | ||
215 | * Error results ... some OF calls will return "-1" on error, some | ||
216 | * will return 0, some will return either. To simplify, here are | ||
217 | * macros to use with any ihandle or phandle return value to check if | ||
218 | * it is valid | ||
219 | */ | ||
220 | |||
221 | #define PROM_ERROR (-1u) | ||
222 | #define PHANDLE_VALID(p) ((p) != 0 && (p) != PROM_ERROR) | ||
223 | #define IHANDLE_VALID(i) ((i) != 0 && (i) != PROM_ERROR) | ||
224 | |||
225 | |||
214 | /* This is the one and *ONLY* place where we actually call open | 226 | /* This is the one and *ONLY* place where we actually call open |
215 | * firmware from, since we need to make sure we're running in 32b | 227 | * firmware from, since we need to make sure we're running in 32b |
216 | * mode when we do. We switch back to 64b mode upon return. | 228 | * mode when we do. We switch back to 64b mode upon return. |
217 | */ | 229 | */ |
218 | 230 | ||
219 | #define PROM_ERROR (-1) | ||
220 | |||
221 | static int __init call_prom(const char *service, int nargs, int nret, ...) | 231 | static int __init call_prom(const char *service, int nargs, int nret, ...) |
222 | { | 232 | { |
223 | int i; | 233 | int i; |
@@ -587,14 +597,13 @@ static void __init prom_send_capabilities(void) | |||
587 | { | 597 | { |
588 | unsigned long offset = reloc_offset(); | 598 | unsigned long offset = reloc_offset(); |
589 | ihandle elfloader; | 599 | ihandle elfloader; |
590 | int ret; | ||
591 | 600 | ||
592 | elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader")); | 601 | elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader")); |
593 | if (elfloader == 0) { | 602 | if (elfloader == 0) { |
594 | prom_printf("couldn't open /packages/elf-loader\n"); | 603 | prom_printf("couldn't open /packages/elf-loader\n"); |
595 | return; | 604 | return; |
596 | } | 605 | } |
597 | ret = call_prom("call-method", 3, 1, ADDR("process-elf-header"), | 606 | call_prom("call-method", 3, 1, ADDR("process-elf-header"), |
598 | elfloader, ADDR(&fake_elf)); | 607 | elfloader, ADDR(&fake_elf)); |
599 | call_prom("close", 1, 0, elfloader); | 608 | call_prom("close", 1, 0, elfloader); |
600 | } | 609 | } |
@@ -646,7 +655,7 @@ static unsigned long __init alloc_up(unsigned long size, unsigned long align) | |||
646 | base = _ALIGN_UP(base + 0x100000, align)) { | 655 | base = _ALIGN_UP(base + 0x100000, align)) { |
647 | prom_debug(" trying: 0x%x\n\r", base); | 656 | prom_debug(" trying: 0x%x\n\r", base); |
648 | addr = (unsigned long)prom_claim(base, size, 0); | 657 | addr = (unsigned long)prom_claim(base, size, 0); |
649 | if ((int)addr != PROM_ERROR) | 658 | if (addr != PROM_ERROR) |
650 | break; | 659 | break; |
651 | addr = 0; | 660 | addr = 0; |
652 | if (align == 0) | 661 | if (align == 0) |
@@ -708,7 +717,7 @@ static unsigned long __init alloc_down(unsigned long size, unsigned long align, | |||
708 | for(; base > RELOC(alloc_bottom); base = _ALIGN_DOWN(base - 0x100000, align)) { | 717 | for(; base > RELOC(alloc_bottom); base = _ALIGN_DOWN(base - 0x100000, align)) { |
709 | prom_debug(" trying: 0x%x\n\r", base); | 718 | prom_debug(" trying: 0x%x\n\r", base); |
710 | addr = (unsigned long)prom_claim(base, size, 0); | 719 | addr = (unsigned long)prom_claim(base, size, 0); |
711 | if ((int)addr != PROM_ERROR) | 720 | if (addr != PROM_ERROR) |
712 | break; | 721 | break; |
713 | addr = 0; | 722 | addr = 0; |
714 | } | 723 | } |
@@ -902,18 +911,19 @@ static void __init prom_instantiate_rtas(void) | |||
902 | { | 911 | { |
903 | unsigned long offset = reloc_offset(); | 912 | unsigned long offset = reloc_offset(); |
904 | struct prom_t *_prom = PTRRELOC(&prom); | 913 | struct prom_t *_prom = PTRRELOC(&prom); |
905 | phandle prom_rtas, rtas_node; | 914 | phandle rtas_node; |
915 | ihandle rtas_inst; | ||
906 | u32 base, entry = 0; | 916 | u32 base, entry = 0; |
907 | u32 size = 0; | 917 | u32 size = 0; |
908 | 918 | ||
909 | prom_debug("prom_instantiate_rtas: start...\n"); | 919 | prom_debug("prom_instantiate_rtas: start...\n"); |
910 | 920 | ||
911 | prom_rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); | 921 | rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas")); |
912 | prom_debug("prom_rtas: %x\n", prom_rtas); | 922 | prom_debug("rtas_node: %x\n", rtas_node); |
913 | if (prom_rtas == (phandle) -1) | 923 | if (!PHANDLE_VALID(rtas_node)) |
914 | return; | 924 | return; |
915 | 925 | ||
916 | prom_getprop(prom_rtas, "rtas-size", &size, sizeof(size)); | 926 | prom_getprop(rtas_node, "rtas-size", &size, sizeof(size)); |
917 | if (size == 0) | 927 | if (size == 0) |
918 | return; | 928 | return; |
919 | 929 | ||
@@ -922,14 +932,18 @@ static void __init prom_instantiate_rtas(void) | |||
922 | prom_printf("RTAS allocation failed !\n"); | 932 | prom_printf("RTAS allocation failed !\n"); |
923 | return; | 933 | return; |
924 | } | 934 | } |
925 | prom_printf("instantiating rtas at 0x%x", base); | ||
926 | 935 | ||
927 | rtas_node = call_prom("open", 1, 1, ADDR("/rtas")); | 936 | rtas_inst = call_prom("open", 1, 1, ADDR("/rtas")); |
928 | prom_printf("..."); | 937 | if (!IHANDLE_VALID(rtas_inst)) { |
938 | prom_printf("opening rtas package failed"); | ||
939 | return; | ||
940 | } | ||
941 | |||
942 | prom_printf("instantiating rtas at 0x%x ...", base); | ||
929 | 943 | ||
930 | if (call_prom("call-method", 3, 2, | 944 | if (call_prom("call-method", 3, 2, |
931 | ADDR("instantiate-rtas"), | 945 | ADDR("instantiate-rtas"), |
932 | rtas_node, base) != PROM_ERROR) { | 946 | rtas_inst, base) != PROM_ERROR) { |
933 | entry = (long)_prom->args.rets[1]; | 947 | entry = (long)_prom->args.rets[1]; |
934 | } | 948 | } |
935 | if (entry == 0) { | 949 | if (entry == 0) { |
@@ -940,8 +954,8 @@ static void __init prom_instantiate_rtas(void) | |||
940 | 954 | ||
941 | reserve_mem(base, size); | 955 | reserve_mem(base, size); |
942 | 956 | ||
943 | prom_setprop(prom_rtas, "linux,rtas-base", &base, sizeof(base)); | 957 | prom_setprop(rtas_node, "linux,rtas-base", &base, sizeof(base)); |
944 | prom_setprop(prom_rtas, "linux,rtas-entry", &entry, sizeof(entry)); | 958 | prom_setprop(rtas_node, "linux,rtas-entry", &entry, sizeof(entry)); |
945 | 959 | ||
946 | prom_debug("rtas base = 0x%x\n", base); | 960 | prom_debug("rtas base = 0x%x\n", base); |
947 | prom_debug("rtas entry = 0x%x\n", entry); | 961 | prom_debug("rtas entry = 0x%x\n", entry); |
@@ -1062,7 +1076,7 @@ static void __init prom_initialize_tce_table(void) | |||
1062 | 1076 | ||
1063 | prom_printf("opening PHB %s", path); | 1077 | prom_printf("opening PHB %s", path); |
1064 | phb_node = call_prom("open", 1, 1, path); | 1078 | phb_node = call_prom("open", 1, 1, path); |
1065 | if ( (long)phb_node <= 0) | 1079 | if (phb_node == 0) |
1066 | prom_printf("... failed\n"); | 1080 | prom_printf("... failed\n"); |
1067 | else | 1081 | else |
1068 | prom_printf("... done\n"); | 1082 | prom_printf("... done\n"); |
@@ -1279,12 +1293,12 @@ static void __init prom_init_client_services(unsigned long pp) | |||
1279 | 1293 | ||
1280 | /* get a handle for the stdout device */ | 1294 | /* get a handle for the stdout device */ |
1281 | _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen")); | 1295 | _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen")); |
1282 | if ((long)_prom->chosen <= 0) | 1296 | if (!PHANDLE_VALID(_prom->chosen)) |
1283 | prom_panic("cannot find chosen"); /* msg won't be printed :( */ | 1297 | prom_panic("cannot find chosen"); /* msg won't be printed :( */ |
1284 | 1298 | ||
1285 | /* get device tree root */ | 1299 | /* get device tree root */ |
1286 | _prom->root = call_prom("finddevice", 1, 1, ADDR("/")); | 1300 | _prom->root = call_prom("finddevice", 1, 1, ADDR("/")); |
1287 | if ((long)_prom->root <= 0) | 1301 | if (!PHANDLE_VALID(_prom->root)) |
1288 | prom_panic("cannot find device tree root"); /* msg won't be printed :( */ | 1302 | prom_panic("cannot find device tree root"); /* msg won't be printed :( */ |
1289 | } | 1303 | } |
1290 | 1304 | ||
@@ -1356,9 +1370,8 @@ static int __init prom_find_machine_type(void) | |||
1356 | } | 1370 | } |
1357 | /* Default to pSeries. We need to know if we are running LPAR */ | 1371 | /* Default to pSeries. We need to know if we are running LPAR */ |
1358 | rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); | 1372 | rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); |
1359 | if (rtas != (phandle) -1) { | 1373 | if (PHANDLE_VALID(rtas)) { |
1360 | unsigned long x; | 1374 | int x = prom_getproplen(rtas, "ibm,hypertas-functions"); |
1361 | x = prom_getproplen(rtas, "ibm,hypertas-functions"); | ||
1362 | if (x != PROM_ERROR) { | 1375 | if (x != PROM_ERROR) { |
1363 | prom_printf("Hypertas detected, assuming LPAR !\n"); | 1376 | prom_printf("Hypertas detected, assuming LPAR !\n"); |
1364 | return PLATFORM_PSERIES_LPAR; | 1377 | return PLATFORM_PSERIES_LPAR; |
@@ -1426,12 +1439,13 @@ static void __init prom_check_displays(void) | |||
1426 | * leave some room at the end of the path for appending extra | 1439 | * leave some room at the end of the path for appending extra |
1427 | * arguments | 1440 | * arguments |
1428 | */ | 1441 | */ |
1429 | if (call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-10) < 0) | 1442 | if (call_prom("package-to-path", 3, 1, node, path, |
1443 | PROM_SCRATCH_SIZE-10) == PROM_ERROR) | ||
1430 | continue; | 1444 | continue; |
1431 | prom_printf("found display : %s, opening ... ", path); | 1445 | prom_printf("found display : %s, opening ... ", path); |
1432 | 1446 | ||
1433 | ih = call_prom("open", 1, 1, path); | 1447 | ih = call_prom("open", 1, 1, path); |
1434 | if (ih == (ihandle)0 || ih == (ihandle)-1) { | 1448 | if (ih == 0) { |
1435 | prom_printf("failed\n"); | 1449 | prom_printf("failed\n"); |
1436 | continue; | 1450 | continue; |
1437 | } | 1451 | } |
@@ -1514,6 +1528,12 @@ static unsigned long __init dt_find_string(char *str) | |||
1514 | return 0; | 1528 | return 0; |
1515 | } | 1529 | } |
1516 | 1530 | ||
1531 | /* | ||
1532 | * The Open Firmware 1275 specification states properties must be 31 bytes or | ||
1533 | * less, however not all firmwares obey this. Make it 64 bytes to be safe. | ||
1534 | */ | ||
1535 | #define MAX_PROPERTY_NAME 64 | ||
1536 | |||
1517 | static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start, | 1537 | static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start, |
1518 | unsigned long *mem_end) | 1538 | unsigned long *mem_end) |
1519 | { | 1539 | { |
@@ -1527,10 +1547,12 @@ static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start, | |||
1527 | /* get and store all property names */ | 1547 | /* get and store all property names */ |
1528 | prev_name = RELOC(""); | 1548 | prev_name = RELOC(""); |
1529 | for (;;) { | 1549 | for (;;) { |
1530 | 1550 | int rc; | |
1531 | /* 32 is max len of name including nul. */ | 1551 | |
1532 | namep = make_room(mem_start, mem_end, 32, 1); | 1552 | /* 64 is max len of name including nul. */ |
1533 | if (call_prom("nextprop", 3, 1, node, prev_name, namep) <= 0) { | 1553 | namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1); |
1554 | rc = call_prom("nextprop", 3, 1, node, prev_name, namep); | ||
1555 | if (rc != 1) { | ||
1534 | /* No more nodes: unwind alloc */ | 1556 | /* No more nodes: unwind alloc */ |
1535 | *mem_start = (unsigned long)namep; | 1557 | *mem_start = (unsigned long)namep; |
1536 | break; | 1558 | break; |
@@ -1555,18 +1577,12 @@ static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start, | |||
1555 | } | 1577 | } |
1556 | } | 1578 | } |
1557 | 1579 | ||
1558 | /* | ||
1559 | * The Open Firmware 1275 specification states properties must be 31 bytes or | ||
1560 | * less, however not all firmwares obey this. Make it 64 bytes to be safe. | ||
1561 | */ | ||
1562 | #define MAX_PROPERTY_NAME 64 | ||
1563 | |||
1564 | static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, | 1580 | static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, |
1565 | unsigned long *mem_end) | 1581 | unsigned long *mem_end) |
1566 | { | 1582 | { |
1567 | int l, align; | 1583 | int l, align; |
1568 | phandle child; | 1584 | phandle child; |
1569 | char *namep, *prev_name, *sstart; | 1585 | char *namep, *prev_name, *sstart, *p, *ep; |
1570 | unsigned long soff; | 1586 | unsigned long soff; |
1571 | unsigned char *valp; | 1587 | unsigned char *valp; |
1572 | unsigned long offset = reloc_offset(); | 1588 | unsigned long offset = reloc_offset(); |
@@ -1588,6 +1604,14 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, | |||
1588 | call_prom("package-to-path", 3, 1, node, namep, l); | 1604 | call_prom("package-to-path", 3, 1, node, namep, l); |
1589 | } | 1605 | } |
1590 | namep[l] = '\0'; | 1606 | namep[l] = '\0'; |
1607 | /* Fixup an Apple bug where they have bogus \0 chars in the | ||
1608 | * middle of the path in some properties | ||
1609 | */ | ||
1610 | for (p = namep, ep = namep + l; p < ep; p++) | ||
1611 | if (*p == '\0') { | ||
1612 | memmove(p, p+1, ep - p); | ||
1613 | ep--; l--; | ||
1614 | } | ||
1591 | *mem_start = _ALIGN(((unsigned long) namep) + strlen(namep) + 1, 4); | 1615 | *mem_start = _ALIGN(((unsigned long) namep) + strlen(namep) + 1, 4); |
1592 | } | 1616 | } |
1593 | 1617 | ||
@@ -1599,7 +1623,10 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, | |||
1599 | prev_name = RELOC(""); | 1623 | prev_name = RELOC(""); |
1600 | sstart = (char *)RELOC(dt_string_start); | 1624 | sstart = (char *)RELOC(dt_string_start); |
1601 | for (;;) { | 1625 | for (;;) { |
1602 | if (call_prom("nextprop", 3, 1, node, prev_name, pname) <= 0) | 1626 | int rc; |
1627 | |||
1628 | rc = call_prom("nextprop", 3, 1, node, prev_name, pname); | ||
1629 | if (rc != 1) | ||
1603 | break; | 1630 | break; |
1604 | 1631 | ||
1605 | /* find string offset */ | 1632 | /* find string offset */ |
@@ -1615,7 +1642,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, | |||
1615 | l = call_prom("getproplen", 2, 1, node, pname); | 1642 | l = call_prom("getproplen", 2, 1, node, pname); |
1616 | 1643 | ||
1617 | /* sanity checks */ | 1644 | /* sanity checks */ |
1618 | if (l < 0) | 1645 | if (l == PROM_ERROR) |
1619 | continue; | 1646 | continue; |
1620 | if (l > MAX_PROPERTY_LENGTH) { | 1647 | if (l > MAX_PROPERTY_LENGTH) { |
1621 | prom_printf("WARNING: ignoring large property "); | 1648 | prom_printf("WARNING: ignoring large property "); |
@@ -1750,7 +1777,45 @@ static void __init flatten_device_tree(void) | |||
1750 | prom_printf("Device tree struct 0x%x -> 0x%x\n", | 1777 | prom_printf("Device tree struct 0x%x -> 0x%x\n", |
1751 | RELOC(dt_struct_start), RELOC(dt_struct_end)); | 1778 | RELOC(dt_struct_start), RELOC(dt_struct_end)); |
1752 | 1779 | ||
1753 | } | 1780 | } |
1781 | |||
1782 | |||
1783 | static void __init fixup_device_tree(void) | ||
1784 | { | ||
1785 | unsigned long offset = reloc_offset(); | ||
1786 | phandle u3, i2c, mpic; | ||
1787 | u32 u3_rev; | ||
1788 | u32 interrupts[2]; | ||
1789 | u32 parent; | ||
1790 | |||
1791 | /* Some G5s have a missing interrupt definition, fix it up here */ | ||
1792 | u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000")); | ||
1793 | if (!PHANDLE_VALID(u3)) | ||
1794 | return; | ||
1795 | i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000")); | ||
1796 | if (!PHANDLE_VALID(i2c)) | ||
1797 | return; | ||
1798 | mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000")); | ||
1799 | if (!PHANDLE_VALID(mpic)) | ||
1800 | return; | ||
1801 | |||
1802 | /* check if proper rev of u3 */ | ||
1803 | if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev)) | ||
1804 | == PROM_ERROR) | ||
1805 | return; | ||
1806 | if (u3_rev != 0x35) | ||
1807 | return; | ||
1808 | /* does it need fixup ? */ | ||
1809 | if (prom_getproplen(i2c, "interrupts") > 0) | ||
1810 | return; | ||
1811 | /* interrupt on this revision of u3 is number 0 and level */ | ||
1812 | interrupts[0] = 0; | ||
1813 | interrupts[1] = 1; | ||
1814 | prom_setprop(i2c, "interrupts", &interrupts, sizeof(interrupts)); | ||
1815 | parent = (u32)mpic; | ||
1816 | prom_setprop(i2c, "interrupt-parent", &parent, sizeof(parent)); | ||
1817 | } | ||
1818 | |||
1754 | 1819 | ||
1755 | static void __init prom_find_boot_cpu(void) | 1820 | static void __init prom_find_boot_cpu(void) |
1756 | { | 1821 | { |
@@ -1844,6 +1909,12 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long | |||
1844 | &getprop_rval, sizeof(getprop_rval)); | 1909 | &getprop_rval, sizeof(getprop_rval)); |
1845 | 1910 | ||
1846 | /* | 1911 | /* |
1912 | * On pSeries, inform the firmware about our capabilities | ||
1913 | */ | ||
1914 | if (RELOC(of_platform) & PLATFORM_PSERIES) | ||
1915 | prom_send_capabilities(); | ||
1916 | |||
1917 | /* | ||
1847 | * On pSeries, copy the CPU hold code | 1918 | * On pSeries, copy the CPU hold code |
1848 | */ | 1919 | */ |
1849 | if (RELOC(of_platform) & PLATFORM_PSERIES) | 1920 | if (RELOC(of_platform) & PLATFORM_PSERIES) |
@@ -1920,6 +1991,11 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long | |||
1920 | } | 1991 | } |
1921 | 1992 | ||
1922 | /* | 1993 | /* |
1994 | * Fixup any known bugs in the device-tree | ||
1995 | */ | ||
1996 | fixup_device_tree(); | ||
1997 | |||
1998 | /* | ||
1923 | * Now finally create the flattened device-tree | 1999 | * Now finally create the flattened device-tree |
1924 | */ | 2000 | */ |
1925 | prom_printf("copying OF device tree ...\n"); | 2001 | prom_printf("copying OF device tree ...\n"); |
diff --git a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c index 5a846324ca8c..9f8c6087ae56 100644 --- a/arch/ppc64/kernel/ptrace.c +++ b/arch/ppc64/kernel/ptrace.c | |||
@@ -305,14 +305,17 @@ static void do_syscall_trace(void) | |||
305 | 305 | ||
306 | void do_syscall_trace_enter(struct pt_regs *regs) | 306 | void do_syscall_trace_enter(struct pt_regs *regs) |
307 | { | 307 | { |
308 | if (test_thread_flag(TIF_SYSCALL_TRACE) | ||
309 | && (current->ptrace & PT_PTRACED)) | ||
310 | do_syscall_trace(); | ||
311 | |||
308 | if (unlikely(current->audit_context)) | 312 | if (unlikely(current->audit_context)) |
309 | audit_syscall_entry(current, regs->gpr[0], | 313 | audit_syscall_entry(current, |
314 | test_thread_flag(TIF_32BIT)?AUDIT_ARCH_PPC:AUDIT_ARCH_PPC64, | ||
315 | regs->gpr[0], | ||
310 | regs->gpr[3], regs->gpr[4], | 316 | regs->gpr[3], regs->gpr[4], |
311 | regs->gpr[5], regs->gpr[6]); | 317 | regs->gpr[5], regs->gpr[6]); |
312 | 318 | ||
313 | if (test_thread_flag(TIF_SYSCALL_TRACE) | ||
314 | && (current->ptrace & PT_PTRACED)) | ||
315 | do_syscall_trace(); | ||
316 | } | 319 | } |
317 | 320 | ||
318 | void do_syscall_trace_leave(struct pt_regs *regs) | 321 | void do_syscall_trace_leave(struct pt_regs *regs) |
@@ -320,7 +323,9 @@ void do_syscall_trace_leave(struct pt_regs *regs) | |||
320 | secure_computing(regs->gpr[0]); | 323 | secure_computing(regs->gpr[0]); |
321 | 324 | ||
322 | if (unlikely(current->audit_context)) | 325 | if (unlikely(current->audit_context)) |
323 | audit_syscall_exit(current, regs->result); | 326 | audit_syscall_exit(current, |
327 | (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS, | ||
328 | regs->result); | ||
324 | 329 | ||
325 | if ((test_thread_flag(TIF_SYSCALL_TRACE) | 330 | if ((test_thread_flag(TIF_SYSCALL_TRACE) |
326 | || test_thread_flag(TIF_SINGLESTEP)) | 331 | || test_thread_flag(TIF_SINGLESTEP)) |
diff --git a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c index 3e70b91375fc..67989055a9fe 100644 --- a/arch/ppc64/kernel/rtc.c +++ b/arch/ppc64/kernel/rtc.c | |||
@@ -292,47 +292,10 @@ int iSeries_set_rtc_time(struct rtc_time *tm) | |||
292 | 292 | ||
293 | void iSeries_get_boot_time(struct rtc_time *tm) | 293 | void iSeries_get_boot_time(struct rtc_time *tm) |
294 | { | 294 | { |
295 | unsigned long time; | ||
296 | static unsigned long lastsec = 1; | ||
297 | |||
298 | u32 dataWord1 = *((u32 *)(&xSpCommArea.xBcdTimeAtIplStart)); | ||
299 | u32 dataWord2 = *(((u32 *)&(xSpCommArea.xBcdTimeAtIplStart)) + 1); | ||
300 | int year = 1970; | ||
301 | int year1 = ( dataWord1 >> 24 ) & 0x000000FF; | ||
302 | int year2 = ( dataWord1 >> 16 ) & 0x000000FF; | ||
303 | int sec = ( dataWord1 >> 8 ) & 0x000000FF; | ||
304 | int min = dataWord1 & 0x000000FF; | ||
305 | int hour = ( dataWord2 >> 24 ) & 0x000000FF; | ||
306 | int day = ( dataWord2 >> 8 ) & 0x000000FF; | ||
307 | int mon = dataWord2 & 0x000000FF; | ||
308 | |||
309 | if ( piranha_simulator ) | 295 | if ( piranha_simulator ) |
310 | return; | 296 | return; |
311 | 297 | ||
312 | BCD_TO_BIN(sec); | 298 | mf_get_boot_rtc(tm); |
313 | BCD_TO_BIN(min); | ||
314 | BCD_TO_BIN(hour); | ||
315 | BCD_TO_BIN(day); | ||
316 | BCD_TO_BIN(mon); | ||
317 | BCD_TO_BIN(year1); | ||
318 | BCD_TO_BIN(year2); | ||
319 | year = year1 * 100 + year2; | ||
320 | |||
321 | time = mktime(year, mon, day, hour, min, sec); | ||
322 | time += ( jiffies / HZ ); | ||
323 | |||
324 | /* Now THIS is a nasty hack! | ||
325 | * It ensures that the first two calls get different answers. | ||
326 | * That way the loop in init_time (time.c) will not think | ||
327 | * the clock is stuck. | ||
328 | */ | ||
329 | if ( lastsec ) { | ||
330 | time -= lastsec; | ||
331 | --lastsec; | ||
332 | } | ||
333 | |||
334 | to_tm(time, tm); | ||
335 | tm->tm_year -= 1900; | ||
336 | tm->tm_mon -= 1; | 299 | tm->tm_mon -= 1; |
337 | } | 300 | } |
338 | #endif | 301 | #endif |
diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index 21c57f539c29..dce198d39328 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c | |||
@@ -103,11 +103,6 @@ extern void unflatten_device_tree(void); | |||
103 | 103 | ||
104 | extern void smp_release_cpus(void); | 104 | extern void smp_release_cpus(void); |
105 | 105 | ||
106 | unsigned long decr_overclock = 1; | ||
107 | unsigned long decr_overclock_proc0 = 1; | ||
108 | unsigned long decr_overclock_set = 0; | ||
109 | unsigned long decr_overclock_proc0_set = 0; | ||
110 | |||
111 | int have_of = 1; | 106 | int have_of = 1; |
112 | int boot_cpuid = 0; | 107 | int boot_cpuid = 0; |
113 | int boot_cpuid_phys = 0; | 108 | int boot_cpuid_phys = 0; |
@@ -1120,64 +1115,15 @@ void ppc64_dump_msg(unsigned int src, const char *msg) | |||
1120 | printk("[dump]%04x %s\n", src, msg); | 1115 | printk("[dump]%04x %s\n", src, msg); |
1121 | } | 1116 | } |
1122 | 1117 | ||
1123 | int set_spread_lpevents( char * str ) | ||
1124 | { | ||
1125 | /* The parameter is the number of processors to share in processing lp events */ | ||
1126 | unsigned long i; | ||
1127 | unsigned long val = simple_strtoul( str, NULL, 0 ); | ||
1128 | if ( ( val > 0 ) && ( val <= NR_CPUS ) ) { | ||
1129 | for ( i=1; i<val; ++i ) | ||
1130 | paca[i].lpqueue_ptr = paca[0].lpqueue_ptr; | ||
1131 | printk("lpevent processing spread over %ld processors\n", val); | ||
1132 | } | ||
1133 | else | ||
1134 | printk("invalid spreaqd_lpevents %ld\n", val); | ||
1135 | return 1; | ||
1136 | } | ||
1137 | |||
1138 | /* This should only be called on processor 0 during calibrate decr */ | 1118 | /* This should only be called on processor 0 during calibrate decr */ |
1139 | void setup_default_decr(void) | 1119 | void setup_default_decr(void) |
1140 | { | 1120 | { |
1141 | struct paca_struct *lpaca = get_paca(); | 1121 | struct paca_struct *lpaca = get_paca(); |
1142 | 1122 | ||
1143 | if ( decr_overclock_set && !decr_overclock_proc0_set ) | 1123 | lpaca->default_decr = tb_ticks_per_jiffy; |
1144 | decr_overclock_proc0 = decr_overclock; | ||
1145 | |||
1146 | lpaca->default_decr = tb_ticks_per_jiffy / decr_overclock_proc0; | ||
1147 | lpaca->next_jiffy_update_tb = get_tb() + tb_ticks_per_jiffy; | 1124 | lpaca->next_jiffy_update_tb = get_tb() + tb_ticks_per_jiffy; |
1148 | } | 1125 | } |
1149 | 1126 | ||
1150 | int set_decr_overclock_proc0( char * str ) | ||
1151 | { | ||
1152 | unsigned long val = simple_strtoul( str, NULL, 0 ); | ||
1153 | if ( ( val >= 1 ) && ( val <= 48 ) ) { | ||
1154 | decr_overclock_proc0_set = 1; | ||
1155 | decr_overclock_proc0 = val; | ||
1156 | printk("proc 0 decrementer overclock factor of %ld\n", val); | ||
1157 | } | ||
1158 | else | ||
1159 | printk("invalid proc 0 decrementer overclock factor of %ld\n", val); | ||
1160 | return 1; | ||
1161 | } | ||
1162 | |||
1163 | int set_decr_overclock( char * str ) | ||
1164 | { | ||
1165 | unsigned long val = simple_strtoul( str, NULL, 0 ); | ||
1166 | if ( ( val >= 1 ) && ( val <= 48 ) ) { | ||
1167 | decr_overclock_set = 1; | ||
1168 | decr_overclock = val; | ||
1169 | printk("decrementer overclock factor of %ld\n", val); | ||
1170 | } | ||
1171 | else | ||
1172 | printk("invalid decrementer overclock factor of %ld\n", val); | ||
1173 | return 1; | ||
1174 | |||
1175 | } | ||
1176 | |||
1177 | __setup("spread_lpevents=", set_spread_lpevents ); | ||
1178 | __setup("decr_overclock_proc0=", set_decr_overclock_proc0 ); | ||
1179 | __setup("decr_overclock=", set_decr_overclock ); | ||
1180 | |||
1181 | #ifndef CONFIG_PPC_ISERIES | 1127 | #ifndef CONFIG_PPC_ISERIES |
1182 | /* | 1128 | /* |
1183 | * This function can be used by platforms to "find" legacy serial ports. | 1129 | * This function can be used by platforms to "find" legacy serial ports. |
diff --git a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c index a95a2b49a1d5..bf782276984c 100644 --- a/arch/ppc64/kernel/signal.c +++ b/arch/ppc64/kernel/signal.c | |||
@@ -42,11 +42,7 @@ | |||
42 | 42 | ||
43 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | 43 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) |
44 | 44 | ||
45 | #ifndef MIN | 45 | #define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs)) |
46 | #define MIN(a,b) (((a) < (b)) ? (a) : (b)) | ||
47 | #endif | ||
48 | |||
49 | #define GP_REGS_SIZE MIN(sizeof(elf_gregset_t), sizeof(struct pt_regs)) | ||
50 | #define FP_REGS_SIZE sizeof(elf_fpregset_t) | 46 | #define FP_REGS_SIZE sizeof(elf_fpregset_t) |
51 | 47 | ||
52 | #define TRAMP_TRACEBACK 3 | 48 | #define TRAMP_TRACEBACK 3 |
diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c index 3b906cd94037..9ef5d36d6b25 100644 --- a/arch/ppc64/kernel/smp.c +++ b/arch/ppc64/kernel/smp.c | |||
@@ -334,7 +334,6 @@ void smp_call_function_interrupt(void) | |||
334 | } | 334 | } |
335 | } | 335 | } |
336 | 336 | ||
337 | extern unsigned long decr_overclock; | ||
338 | extern struct gettimeofday_struct do_gtod; | 337 | extern struct gettimeofday_struct do_gtod; |
339 | 338 | ||
340 | struct thread_info *current_set[NR_CPUS]; | 339 | struct thread_info *current_set[NR_CPUS]; |
@@ -491,7 +490,7 @@ int __devinit __cpu_up(unsigned int cpu) | |||
491 | if (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)) | 490 | if (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)) |
492 | return -EINVAL; | 491 | return -EINVAL; |
493 | 492 | ||
494 | paca[cpu].default_decr = tb_ticks_per_jiffy / decr_overclock; | 493 | paca[cpu].default_decr = tb_ticks_per_jiffy; |
495 | 494 | ||
496 | if (!cpu_has_feature(CPU_FTR_SLB)) { | 495 | if (!cpu_has_feature(CPU_FTR_SLB)) { |
497 | void *tmp; | 496 | void *tmp; |
diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c index 7cf7a9600025..9c8e317c598d 100644 --- a/arch/ppc64/kernel/sys_ppc32.c +++ b/arch/ppc64/kernel/sys_ppc32.c | |||
@@ -791,31 +791,6 @@ asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn) | |||
791 | } | 791 | } |
792 | 792 | ||
793 | 793 | ||
794 | asmlinkage int ppc64_newuname(struct new_utsname __user * name) | ||
795 | { | ||
796 | int errno = sys_newuname(name); | ||
797 | |||
798 | if (current->personality == PER_LINUX32 && !errno) { | ||
799 | if(copy_to_user(name->machine, "ppc\0\0", 8)) { | ||
800 | errno = -EFAULT; | ||
801 | } | ||
802 | } | ||
803 | return errno; | ||
804 | } | ||
805 | |||
806 | asmlinkage int ppc64_personality(unsigned long personality) | ||
807 | { | ||
808 | int ret; | ||
809 | if (current->personality == PER_LINUX32 && personality == PER_LINUX) | ||
810 | personality = PER_LINUX32; | ||
811 | ret = sys_personality(personality); | ||
812 | if (ret == PER_LINUX32) | ||
813 | ret = PER_LINUX; | ||
814 | return ret; | ||
815 | } | ||
816 | |||
817 | |||
818 | |||
819 | /* Note: it is necessary to treat mode as an unsigned int, | 794 | /* Note: it is necessary to treat mode as an unsigned int, |
820 | * with the corresponding cast to a signed int to insure that the | 795 | * with the corresponding cast to a signed int to insure that the |
821 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | 796 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) |
@@ -1158,26 +1133,47 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) | |||
1158 | } | 1133 | } |
1159 | #endif | 1134 | #endif |
1160 | 1135 | ||
1136 | asmlinkage int sys32_uname(struct old_utsname __user * name) | ||
1137 | { | ||
1138 | int err = 0; | ||
1139 | |||
1140 | down_read(&uts_sem); | ||
1141 | if (copy_to_user(name, &system_utsname, sizeof(*name))) | ||
1142 | err = -EFAULT; | ||
1143 | up_read(&uts_sem); | ||
1144 | if (!err && personality(current->personality) == PER_LINUX32) { | ||
1145 | /* change "ppc64" to "ppc" */ | ||
1146 | if (__put_user(0, name->machine + 3) | ||
1147 | || __put_user(0, name->machine + 4)) | ||
1148 | err = -EFAULT; | ||
1149 | } | ||
1150 | return err; | ||
1151 | } | ||
1152 | |||
1161 | asmlinkage int sys32_olduname(struct oldold_utsname __user * name) | 1153 | asmlinkage int sys32_olduname(struct oldold_utsname __user * name) |
1162 | { | 1154 | { |
1163 | int error; | 1155 | int error; |
1164 | 1156 | ||
1165 | if (!name) | ||
1166 | return -EFAULT; | ||
1167 | if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) | 1157 | if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) |
1168 | return -EFAULT; | 1158 | return -EFAULT; |
1169 | 1159 | ||
1170 | down_read(&uts_sem); | 1160 | down_read(&uts_sem); |
1171 | error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); | 1161 | error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); |
1172 | error -= __put_user(0,name->sysname+__OLD_UTS_LEN); | 1162 | error |= __put_user(0,name->sysname+__OLD_UTS_LEN); |
1173 | error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); | 1163 | error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); |
1174 | error -= __put_user(0,name->nodename+__OLD_UTS_LEN); | 1164 | error |= __put_user(0,name->nodename+__OLD_UTS_LEN); |
1175 | error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); | 1165 | error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); |
1176 | error -= __put_user(0,name->release+__OLD_UTS_LEN); | 1166 | error |= __put_user(0,name->release+__OLD_UTS_LEN); |
1177 | error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); | 1167 | error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); |
1178 | error -= __put_user(0,name->version+__OLD_UTS_LEN); | 1168 | error |= __put_user(0,name->version+__OLD_UTS_LEN); |
1179 | error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); | 1169 | error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); |
1180 | error = __put_user(0,name->machine+__OLD_UTS_LEN); | 1170 | error |= __put_user(0,name->machine+__OLD_UTS_LEN); |
1171 | if (personality(current->personality) == PER_LINUX32) { | ||
1172 | /* change "ppc64" to "ppc" */ | ||
1173 | error |= __put_user(0, name->machine + 3); | ||
1174 | error |= __put_user(0, name->machine + 4); | ||
1175 | } | ||
1176 | |||
1181 | up_read(&uts_sem); | 1177 | up_read(&uts_sem); |
1182 | 1178 | ||
1183 | error = error ? -EFAULT : 0; | 1179 | error = error ? -EFAULT : 0; |
diff --git a/arch/ppc64/kernel/syscalls.c b/arch/ppc64/kernel/syscalls.c index f2865ff8d2f9..a8cbb202b8cd 100644 --- a/arch/ppc64/kernel/syscalls.c +++ b/arch/ppc64/kernel/syscalls.c | |||
@@ -199,24 +199,33 @@ out: | |||
199 | return ret; | 199 | return ret; |
200 | } | 200 | } |
201 | 201 | ||
202 | static int __init set_fakeppc(char *str) | 202 | long ppc64_personality(unsigned long personality) |
203 | { | 203 | { |
204 | if (*str) | 204 | long ret; |
205 | return 0; | 205 | |
206 | init_task.personality = PER_LINUX32; | 206 | if (personality(current->personality) == PER_LINUX32 |
207 | return 1; | 207 | && personality == PER_LINUX) |
208 | personality = PER_LINUX32; | ||
209 | ret = sys_personality(personality); | ||
210 | if (ret == PER_LINUX32) | ||
211 | ret = PER_LINUX; | ||
212 | return ret; | ||
208 | } | 213 | } |
209 | __setup("fakeppc", set_fakeppc); | ||
210 | 214 | ||
211 | asmlinkage int sys_uname(struct old_utsname __user * name) | 215 | long ppc64_newuname(struct new_utsname __user * name) |
212 | { | 216 | { |
213 | int err = -EFAULT; | 217 | int err = 0; |
214 | 218 | ||
215 | down_read(&uts_sem); | 219 | down_read(&uts_sem); |
216 | if (name && !copy_to_user(name, &system_utsname, sizeof (*name))) | 220 | if (copy_to_user(name, &system_utsname, sizeof(*name))) |
217 | err = 0; | 221 | err = -EFAULT; |
218 | up_read(&uts_sem); | 222 | up_read(&uts_sem); |
219 | 223 | if (!err && personality(current->personality) == PER_LINUX32) { | |
224 | /* change ppc64 to ppc */ | ||
225 | if (__put_user(0, name->machine + 3) | ||
226 | || __put_user(0, name->machine + 4)) | ||
227 | err = -EFAULT; | ||
228 | } | ||
220 | return err; | 229 | return err; |
221 | } | 230 | } |
222 | 231 | ||
diff --git a/arch/ppc64/kernel/sysfs.c b/arch/ppc64/kernel/sysfs.c index 0925694c3ce5..c8fa6569b2fd 100644 --- a/arch/ppc64/kernel/sysfs.c +++ b/arch/ppc64/kernel/sysfs.c | |||
@@ -113,7 +113,6 @@ void ppc64_enable_pmcs(void) | |||
113 | #ifdef CONFIG_PPC_PSERIES | 113 | #ifdef CONFIG_PPC_PSERIES |
114 | unsigned long set, reset; | 114 | unsigned long set, reset; |
115 | int ret; | 115 | int ret; |
116 | unsigned int ctrl; | ||
117 | #endif /* CONFIG_PPC_PSERIES */ | 116 | #endif /* CONFIG_PPC_PSERIES */ |
118 | 117 | ||
119 | /* Only need to enable them once */ | 118 | /* Only need to enable them once */ |
@@ -167,11 +166,8 @@ void ppc64_enable_pmcs(void) | |||
167 | * On SMT machines we have to set the run latch in the ctrl register | 166 | * On SMT machines we have to set the run latch in the ctrl register |
168 | * in order to make PMC6 spin. | 167 | * in order to make PMC6 spin. |
169 | */ | 168 | */ |
170 | if (cpu_has_feature(CPU_FTR_SMT)) { | 169 | if (cpu_has_feature(CPU_FTR_SMT)) |
171 | ctrl = mfspr(CTRLF); | 170 | ppc64_runlatch_on(); |
172 | ctrl |= RUNLATCH; | ||
173 | mtspr(CTRLT, ctrl); | ||
174 | } | ||
175 | #endif /* CONFIG_PPC_PSERIES */ | 171 | #endif /* CONFIG_PPC_PSERIES */ |
176 | } | 172 | } |
177 | 173 | ||
diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c index 772a465b49f9..33364a7d2cd2 100644 --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c | |||
@@ -325,9 +325,7 @@ int timer_interrupt(struct pt_regs * regs) | |||
325 | 325 | ||
326 | irq_enter(); | 326 | irq_enter(); |
327 | 327 | ||
328 | #ifndef CONFIG_PPC_ISERIES | ||
329 | profile_tick(CPU_PROFILING, regs); | 328 | profile_tick(CPU_PROFILING, regs); |
330 | #endif | ||
331 | 329 | ||
332 | lpaca->lppaca.int_dword.fields.decr_int = 0; | 330 | lpaca->lppaca.int_dword.fields.decr_int = 0; |
333 | 331 | ||
@@ -515,6 +513,7 @@ void __init time_init(void) | |||
515 | do_gtod.varp = &do_gtod.vars[0]; | 513 | do_gtod.varp = &do_gtod.vars[0]; |
516 | do_gtod.var_idx = 0; | 514 | do_gtod.var_idx = 0; |
517 | do_gtod.varp->tb_orig_stamp = tb_last_stamp; | 515 | do_gtod.varp->tb_orig_stamp = tb_last_stamp; |
516 | get_paca()->next_jiffy_update_tb = tb_last_stamp + tb_ticks_per_jiffy; | ||
518 | do_gtod.varp->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC; | 517 | do_gtod.varp->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC; |
519 | do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; | 518 | do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; |
520 | do_gtod.varp->tb_to_xs = tb_to_xs; | 519 | do_gtod.varp->tb_to_xs = tb_to_xs; |
diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c index eedd1d3c2a10..879f39b90a33 100644 --- a/arch/ppc64/kernel/xics.c +++ b/arch/ppc64/kernel/xics.c | |||
@@ -432,6 +432,7 @@ void xics_cause_IPI(int cpu) | |||
432 | { | 432 | { |
433 | ops->qirr_info(cpu, IPI_PRIORITY); | 433 | ops->qirr_info(cpu, IPI_PRIORITY); |
434 | } | 434 | } |
435 | #endif /* CONFIG_SMP */ | ||
435 | 436 | ||
436 | void xics_setup_cpu(void) | 437 | void xics_setup_cpu(void) |
437 | { | 438 | { |
@@ -439,9 +440,17 @@ void xics_setup_cpu(void) | |||
439 | 440 | ||
440 | ops->cppr_info(cpu, 0xff); | 441 | ops->cppr_info(cpu, 0xff); |
441 | iosync(); | 442 | iosync(); |
442 | } | ||
443 | 443 | ||
444 | #endif /* CONFIG_SMP */ | 444 | /* |
445 | * Put the calling processor into the GIQ. This is really only | ||
446 | * necessary from a secondary thread as the OF start-cpu interface | ||
447 | * performs this function for us on primary threads. | ||
448 | * | ||
449 | * XXX: undo of teardown on kexec needs this too, as may hotplug | ||
450 | */ | ||
451 | rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, | ||
452 | (1UL << interrupt_server_size) - 1 - default_distrib_server, 1); | ||
453 | } | ||
445 | 454 | ||
446 | void xics_init_IRQ(void) | 455 | void xics_init_IRQ(void) |
447 | { | 456 | { |
@@ -563,8 +572,7 @@ nextnode: | |||
563 | for (; i < NR_IRQS; ++i) | 572 | for (; i < NR_IRQS; ++i) |
564 | get_irq_desc(i)->handler = &xics_pic; | 573 | get_irq_desc(i)->handler = &xics_pic; |
565 | 574 | ||
566 | ops->cppr_info(boot_cpuid, 0xff); | 575 | xics_setup_cpu(); |
567 | iosync(); | ||
568 | 576 | ||
569 | ppc64_boot_msg(0x21, "XICS Done"); | 577 | ppc64_boot_msg(0x21, "XICS Done"); |
570 | } | 578 | } |
diff --git a/arch/ppc64/mm/hash_native.c b/arch/ppc64/mm/hash_native.c index 144657e0c3d5..52b6b9305341 100644 --- a/arch/ppc64/mm/hash_native.c +++ b/arch/ppc64/mm/hash_native.c | |||
@@ -320,8 +320,7 @@ static void native_flush_hash_range(unsigned long context, | |||
320 | 320 | ||
321 | j = 0; | 321 | j = 0; |
322 | for (i = 0; i < number; i++) { | 322 | for (i = 0; i < number; i++) { |
323 | if ((batch->addr[i] >= USER_START) && | 323 | if (batch->addr[i] < KERNELBASE) |
324 | (batch->addr[i] <= USER_END)) | ||
325 | vsid = get_vsid(context, batch->addr[i]); | 324 | vsid = get_vsid(context, batch->addr[i]); |
326 | else | 325 | else |
327 | vsid = get_kernel_vsid(batch->addr[i]); | 326 | vsid = get_kernel_vsid(batch->addr[i]); |
diff --git a/arch/ppc64/mm/hash_utils.c b/arch/ppc64/mm/hash_utils.c index e48be12f518c..0a0f97008d02 100644 --- a/arch/ppc64/mm/hash_utils.c +++ b/arch/ppc64/mm/hash_utils.c | |||
@@ -298,24 +298,23 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | |||
298 | int local = 0; | 298 | int local = 0; |
299 | cpumask_t tmp; | 299 | cpumask_t tmp; |
300 | 300 | ||
301 | if ((ea & ~REGION_MASK) > EADDR_MASK) | ||
302 | return 1; | ||
303 | |||
301 | switch (REGION_ID(ea)) { | 304 | switch (REGION_ID(ea)) { |
302 | case USER_REGION_ID: | 305 | case USER_REGION_ID: |
303 | user_region = 1; | 306 | user_region = 1; |
304 | mm = current->mm; | 307 | mm = current->mm; |
305 | if ((ea > USER_END) || (! mm)) | 308 | if (! mm) |
306 | return 1; | 309 | return 1; |
307 | 310 | ||
308 | vsid = get_vsid(mm->context.id, ea); | 311 | vsid = get_vsid(mm->context.id, ea); |
309 | break; | 312 | break; |
310 | case IO_REGION_ID: | 313 | case IO_REGION_ID: |
311 | if (ea > IMALLOC_END) | ||
312 | return 1; | ||
313 | mm = &ioremap_mm; | 314 | mm = &ioremap_mm; |
314 | vsid = get_kernel_vsid(ea); | 315 | vsid = get_kernel_vsid(ea); |
315 | break; | 316 | break; |
316 | case VMALLOC_REGION_ID: | 317 | case VMALLOC_REGION_ID: |
317 | if (ea > VMALLOC_END) | ||
318 | return 1; | ||
319 | mm = &init_mm; | 318 | mm = &init_mm; |
320 | vsid = get_kernel_vsid(ea); | 319 | vsid = get_kernel_vsid(ea); |
321 | break; | 320 | break; |
@@ -362,7 +361,7 @@ void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte, | |||
362 | unsigned long vsid, vpn, va, hash, secondary, slot; | 361 | unsigned long vsid, vpn, va, hash, secondary, slot; |
363 | unsigned long huge = pte_huge(pte); | 362 | unsigned long huge = pte_huge(pte); |
364 | 363 | ||
365 | if ((ea >= USER_START) && (ea <= USER_END)) | 364 | if (ea < KERNELBASE) |
366 | vsid = get_vsid(context, ea); | 365 | vsid = get_vsid(context, ea); |
367 | else | 366 | else |
368 | vsid = get_kernel_vsid(ea); | 367 | vsid = get_kernel_vsid(ea); |
diff --git a/arch/ppc64/mm/imalloc.c b/arch/ppc64/mm/imalloc.c index 9d92b0d9cde5..cb8727f3267a 100644 --- a/arch/ppc64/mm/imalloc.c +++ b/arch/ppc64/mm/imalloc.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <asm/pgalloc.h> | 14 | #include <asm/pgalloc.h> |
15 | #include <asm/pgtable.h> | 15 | #include <asm/pgtable.h> |
16 | #include <asm/semaphore.h> | 16 | #include <asm/semaphore.h> |
17 | #include <asm/imalloc.h> | ||
17 | 18 | ||
18 | static DECLARE_MUTEX(imlist_sem); | 19 | static DECLARE_MUTEX(imlist_sem); |
19 | struct vm_struct * imlist = NULL; | 20 | struct vm_struct * imlist = NULL; |
@@ -23,11 +24,11 @@ static int get_free_im_addr(unsigned long size, unsigned long *im_addr) | |||
23 | unsigned long addr; | 24 | unsigned long addr; |
24 | struct vm_struct **p, *tmp; | 25 | struct vm_struct **p, *tmp; |
25 | 26 | ||
26 | addr = IMALLOC_START; | 27 | addr = ioremap_bot; |
27 | for (p = &imlist; (tmp = *p) ; p = &tmp->next) { | 28 | for (p = &imlist; (tmp = *p) ; p = &tmp->next) { |
28 | if (size + addr < (unsigned long) tmp->addr) | 29 | if (size + addr < (unsigned long) tmp->addr) |
29 | break; | 30 | break; |
30 | if ((unsigned long)tmp->addr >= IMALLOC_START) | 31 | if ((unsigned long)tmp->addr >= ioremap_bot) |
31 | addr = tmp->size + (unsigned long) tmp->addr; | 32 | addr = tmp->size + (unsigned long) tmp->addr; |
32 | if (addr > IMALLOC_END-size) | 33 | if (addr > IMALLOC_END-size) |
33 | return 1; | 34 | return 1; |
diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c index cf33d7ec2e29..4b42aff74d73 100644 --- a/arch/ppc64/mm/init.c +++ b/arch/ppc64/mm/init.c | |||
@@ -64,6 +64,7 @@ | |||
64 | #include <asm/iommu.h> | 64 | #include <asm/iommu.h> |
65 | #include <asm/abs_addr.h> | 65 | #include <asm/abs_addr.h> |
66 | #include <asm/vdso.h> | 66 | #include <asm/vdso.h> |
67 | #include <asm/imalloc.h> | ||
67 | 68 | ||
68 | int mem_init_done; | 69 | int mem_init_done; |
69 | unsigned long ioremap_bot = IMALLOC_BASE; | 70 | unsigned long ioremap_bot = IMALLOC_BASE; |
@@ -668,7 +669,7 @@ void __init paging_init(void) | |||
668 | zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT; | 669 | zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT; |
669 | zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT; | 670 | zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT; |
670 | 671 | ||
671 | free_area_init_node(0, &contig_page_data, zones_size, | 672 | free_area_init_node(0, NODE_DATA(0), zones_size, |
672 | __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); | 673 | __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); |
673 | } | 674 | } |
674 | #endif /* CONFIG_DISCONTIGMEM */ | 675 | #endif /* CONFIG_DISCONTIGMEM */ |
diff --git a/arch/ppc64/mm/stab.c b/arch/ppc64/mm/stab.c index 31491131d5e4..df4bbe14153c 100644 --- a/arch/ppc64/mm/stab.c +++ b/arch/ppc64/mm/stab.c | |||
@@ -19,6 +19,11 @@ | |||
19 | #include <asm/paca.h> | 19 | #include <asm/paca.h> |
20 | #include <asm/cputable.h> | 20 | #include <asm/cputable.h> |
21 | 21 | ||
22 | struct stab_entry { | ||
23 | unsigned long esid_data; | ||
24 | unsigned long vsid_data; | ||
25 | }; | ||
26 | |||
22 | /* Both the segment table and SLB code uses the following cache */ | 27 | /* Both the segment table and SLB code uses the following cache */ |
23 | #define NR_STAB_CACHE_ENTRIES 8 | 28 | #define NR_STAB_CACHE_ENTRIES 8 |
24 | DEFINE_PER_CPU(long, stab_cache_ptr); | 29 | DEFINE_PER_CPU(long, stab_cache_ptr); |
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index 01ae1964c938..c067435bae45 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c | |||
@@ -28,6 +28,7 @@ | |||
28 | //#include <linux/kernel_stat.h> | 28 | //#include <linux/kernel_stat.h> |
29 | #include <linux/notifier.h> | 29 | #include <linux/notifier.h> |
30 | #include <linux/cpu.h> | 30 | #include <linux/cpu.h> |
31 | #include <linux/workqueue.h> | ||
31 | 32 | ||
32 | #include "appldata.h" | 33 | #include "appldata.h" |
33 | 34 | ||
@@ -133,9 +134,12 @@ static int appldata_interval = APPLDATA_CPU_INTERVAL; | |||
133 | static int appldata_timer_active; | 134 | static int appldata_timer_active; |
134 | 135 | ||
135 | /* | 136 | /* |
136 | * Tasklet | 137 | * Work queue |
137 | */ | 138 | */ |
138 | static struct tasklet_struct appldata_tasklet_struct; | 139 | static struct workqueue_struct *appldata_wq; |
140 | static void appldata_work_fn(void *data); | ||
141 | static DECLARE_WORK(appldata_work, appldata_work_fn, NULL); | ||
142 | |||
139 | 143 | ||
140 | /* | 144 | /* |
141 | * Ops list | 145 | * Ops list |
@@ -144,11 +148,11 @@ static DEFINE_SPINLOCK(appldata_ops_lock); | |||
144 | static LIST_HEAD(appldata_ops_list); | 148 | static LIST_HEAD(appldata_ops_list); |
145 | 149 | ||
146 | 150 | ||
147 | /************************* timer, tasklet, DIAG ******************************/ | 151 | /*************************** timer, work, DIAG *******************************/ |
148 | /* | 152 | /* |
149 | * appldata_timer_function() | 153 | * appldata_timer_function() |
150 | * | 154 | * |
151 | * schedule tasklet and reschedule timer | 155 | * schedule work and reschedule timer |
152 | */ | 156 | */ |
153 | static void appldata_timer_function(unsigned long data, struct pt_regs *regs) | 157 | static void appldata_timer_function(unsigned long data, struct pt_regs *regs) |
154 | { | 158 | { |
@@ -157,22 +161,22 @@ static void appldata_timer_function(unsigned long data, struct pt_regs *regs) | |||
157 | atomic_read(&appldata_expire_count)); | 161 | atomic_read(&appldata_expire_count)); |
158 | if (atomic_dec_and_test(&appldata_expire_count)) { | 162 | if (atomic_dec_and_test(&appldata_expire_count)) { |
159 | atomic_set(&appldata_expire_count, num_online_cpus()); | 163 | atomic_set(&appldata_expire_count, num_online_cpus()); |
160 | tasklet_schedule((struct tasklet_struct *) data); | 164 | queue_work(appldata_wq, (struct work_struct *) data); |
161 | } | 165 | } |
162 | } | 166 | } |
163 | 167 | ||
164 | /* | 168 | /* |
165 | * appldata_tasklet_function() | 169 | * appldata_work_fn() |
166 | * | 170 | * |
167 | * call data gathering function for each (active) module | 171 | * call data gathering function for each (active) module |
168 | */ | 172 | */ |
169 | static void appldata_tasklet_function(unsigned long data) | 173 | static void appldata_work_fn(void *data) |
170 | { | 174 | { |
171 | struct list_head *lh; | 175 | struct list_head *lh; |
172 | struct appldata_ops *ops; | 176 | struct appldata_ops *ops; |
173 | int i; | 177 | int i; |
174 | 178 | ||
175 | P_DEBUG(" -= Tasklet =-\n"); | 179 | P_DEBUG(" -= Work Queue =-\n"); |
176 | i = 0; | 180 | i = 0; |
177 | spin_lock(&appldata_ops_lock); | 181 | spin_lock(&appldata_ops_lock); |
178 | list_for_each(lh, &appldata_ops_list) { | 182 | list_for_each(lh, &appldata_ops_list) { |
@@ -231,7 +235,7 @@ static int appldata_diag(char record_nr, u16 function, unsigned long buffer, | |||
231 | : "=d" (ry) : "d" (&(appldata_parameter_list)) : "cc"); | 235 | : "=d" (ry) : "d" (&(appldata_parameter_list)) : "cc"); |
232 | return (int) ry; | 236 | return (int) ry; |
233 | } | 237 | } |
234 | /********************** timer, tasklet, DIAG <END> ***************************/ | 238 | /************************ timer, work, DIAG <END> ****************************/ |
235 | 239 | ||
236 | 240 | ||
237 | /****************************** /proc stuff **********************************/ | 241 | /****************************** /proc stuff **********************************/ |
@@ -411,7 +415,7 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, | |||
411 | struct list_head *lh; | 415 | struct list_head *lh; |
412 | 416 | ||
413 | found = 0; | 417 | found = 0; |
414 | spin_lock_bh(&appldata_ops_lock); | 418 | spin_lock(&appldata_ops_lock); |
415 | list_for_each(lh, &appldata_ops_list) { | 419 | list_for_each(lh, &appldata_ops_list) { |
416 | tmp_ops = list_entry(lh, struct appldata_ops, list); | 420 | tmp_ops = list_entry(lh, struct appldata_ops, list); |
417 | if (&tmp_ops->ctl_table[2] == ctl) { | 421 | if (&tmp_ops->ctl_table[2] == ctl) { |
@@ -419,15 +423,15 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, | |||
419 | } | 423 | } |
420 | } | 424 | } |
421 | if (!found) { | 425 | if (!found) { |
422 | spin_unlock_bh(&appldata_ops_lock); | 426 | spin_unlock(&appldata_ops_lock); |
423 | return -ENODEV; | 427 | return -ENODEV; |
424 | } | 428 | } |
425 | ops = ctl->data; | 429 | ops = ctl->data; |
426 | if (!try_module_get(ops->owner)) { // protect this function | 430 | if (!try_module_get(ops->owner)) { // protect this function |
427 | spin_unlock_bh(&appldata_ops_lock); | 431 | spin_unlock(&appldata_ops_lock); |
428 | return -ENODEV; | 432 | return -ENODEV; |
429 | } | 433 | } |
430 | spin_unlock_bh(&appldata_ops_lock); | 434 | spin_unlock(&appldata_ops_lock); |
431 | 435 | ||
432 | if (!*lenp || *ppos) { | 436 | if (!*lenp || *ppos) { |
433 | *lenp = 0; | 437 | *lenp = 0; |
@@ -451,10 +455,11 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, | |||
451 | return -EFAULT; | 455 | return -EFAULT; |
452 | } | 456 | } |
453 | 457 | ||
454 | spin_lock_bh(&appldata_ops_lock); | 458 | spin_lock(&appldata_ops_lock); |
455 | if ((buf[0] == '1') && (ops->active == 0)) { | 459 | if ((buf[0] == '1') && (ops->active == 0)) { |
456 | if (!try_module_get(ops->owner)) { // protect tasklet | 460 | // protect work queue callback |
457 | spin_unlock_bh(&appldata_ops_lock); | 461 | if (!try_module_get(ops->owner)) { |
462 | spin_unlock(&appldata_ops_lock); | ||
458 | module_put(ops->owner); | 463 | module_put(ops->owner); |
459 | return -ENODEV; | 464 | return -ENODEV; |
460 | } | 465 | } |
@@ -485,7 +490,7 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, | |||
485 | } | 490 | } |
486 | module_put(ops->owner); | 491 | module_put(ops->owner); |
487 | } | 492 | } |
488 | spin_unlock_bh(&appldata_ops_lock); | 493 | spin_unlock(&appldata_ops_lock); |
489 | out: | 494 | out: |
490 | *lenp = len; | 495 | *lenp = len; |
491 | *ppos += len; | 496 | *ppos += len; |
@@ -529,7 +534,7 @@ int appldata_register_ops(struct appldata_ops *ops) | |||
529 | } | 534 | } |
530 | memset(ops->ctl_table, 0, 4*sizeof(struct ctl_table)); | 535 | memset(ops->ctl_table, 0, 4*sizeof(struct ctl_table)); |
531 | 536 | ||
532 | spin_lock_bh(&appldata_ops_lock); | 537 | spin_lock(&appldata_ops_lock); |
533 | list_for_each(lh, &appldata_ops_list) { | 538 | list_for_each(lh, &appldata_ops_list) { |
534 | tmp_ops = list_entry(lh, struct appldata_ops, list); | 539 | tmp_ops = list_entry(lh, struct appldata_ops, list); |
535 | P_DEBUG("register_ops loop: %i) name = %s, ctl = %i\n", | 540 | P_DEBUG("register_ops loop: %i) name = %s, ctl = %i\n", |
@@ -541,18 +546,18 @@ int appldata_register_ops(struct appldata_ops *ops) | |||
541 | APPLDATA_PROC_NAME_LENGTH) == 0) { | 546 | APPLDATA_PROC_NAME_LENGTH) == 0) { |
542 | P_ERROR("Name \"%s\" already registered!\n", ops->name); | 547 | P_ERROR("Name \"%s\" already registered!\n", ops->name); |
543 | kfree(ops->ctl_table); | 548 | kfree(ops->ctl_table); |
544 | spin_unlock_bh(&appldata_ops_lock); | 549 | spin_unlock(&appldata_ops_lock); |
545 | return -EBUSY; | 550 | return -EBUSY; |
546 | } | 551 | } |
547 | if (tmp_ops->ctl_nr == ops->ctl_nr) { | 552 | if (tmp_ops->ctl_nr == ops->ctl_nr) { |
548 | P_ERROR("ctl_nr %i already registered!\n", ops->ctl_nr); | 553 | P_ERROR("ctl_nr %i already registered!\n", ops->ctl_nr); |
549 | kfree(ops->ctl_table); | 554 | kfree(ops->ctl_table); |
550 | spin_unlock_bh(&appldata_ops_lock); | 555 | spin_unlock(&appldata_ops_lock); |
551 | return -EBUSY; | 556 | return -EBUSY; |
552 | } | 557 | } |
553 | } | 558 | } |
554 | list_add(&ops->list, &appldata_ops_list); | 559 | list_add(&ops->list, &appldata_ops_list); |
555 | spin_unlock_bh(&appldata_ops_lock); | 560 | spin_unlock(&appldata_ops_lock); |
556 | 561 | ||
557 | ops->ctl_table[0].ctl_name = CTL_APPLDATA; | 562 | ops->ctl_table[0].ctl_name = CTL_APPLDATA; |
558 | ops->ctl_table[0].procname = appldata_proc_name; | 563 | ops->ctl_table[0].procname = appldata_proc_name; |
@@ -583,12 +588,12 @@ int appldata_register_ops(struct appldata_ops *ops) | |||
583 | */ | 588 | */ |
584 | void appldata_unregister_ops(struct appldata_ops *ops) | 589 | void appldata_unregister_ops(struct appldata_ops *ops) |
585 | { | 590 | { |
586 | spin_lock_bh(&appldata_ops_lock); | 591 | spin_lock(&appldata_ops_lock); |
587 | unregister_sysctl_table(ops->sysctl_header); | 592 | unregister_sysctl_table(ops->sysctl_header); |
588 | list_del(&ops->list); | 593 | list_del(&ops->list); |
589 | kfree(ops->ctl_table); | 594 | kfree(ops->ctl_table); |
590 | ops->ctl_table = NULL; | 595 | ops->ctl_table = NULL; |
591 | spin_unlock_bh(&appldata_ops_lock); | 596 | spin_unlock(&appldata_ops_lock); |
592 | P_INFO("%s-ops unregistered!\n", ops->name); | 597 | P_INFO("%s-ops unregistered!\n", ops->name); |
593 | } | 598 | } |
594 | /********************** module-ops management <END> **************************/ | 599 | /********************** module-ops management <END> **************************/ |
@@ -602,7 +607,7 @@ appldata_online_cpu(int cpu) | |||
602 | init_virt_timer(&per_cpu(appldata_timer, cpu)); | 607 | init_virt_timer(&per_cpu(appldata_timer, cpu)); |
603 | per_cpu(appldata_timer, cpu).function = appldata_timer_function; | 608 | per_cpu(appldata_timer, cpu).function = appldata_timer_function; |
604 | per_cpu(appldata_timer, cpu).data = (unsigned long) | 609 | per_cpu(appldata_timer, cpu).data = (unsigned long) |
605 | &appldata_tasklet_struct; | 610 | &appldata_work; |
606 | atomic_inc(&appldata_expire_count); | 611 | atomic_inc(&appldata_expire_count); |
607 | spin_lock(&appldata_timer_lock); | 612 | spin_lock(&appldata_timer_lock); |
608 | __appldata_vtimer_setup(APPLDATA_MOD_TIMER); | 613 | __appldata_vtimer_setup(APPLDATA_MOD_TIMER); |
@@ -615,7 +620,7 @@ appldata_offline_cpu(int cpu) | |||
615 | del_virt_timer(&per_cpu(appldata_timer, cpu)); | 620 | del_virt_timer(&per_cpu(appldata_timer, cpu)); |
616 | if (atomic_dec_and_test(&appldata_expire_count)) { | 621 | if (atomic_dec_and_test(&appldata_expire_count)) { |
617 | atomic_set(&appldata_expire_count, num_online_cpus()); | 622 | atomic_set(&appldata_expire_count, num_online_cpus()); |
618 | tasklet_schedule(&appldata_tasklet_struct); | 623 | queue_work(appldata_wq, &appldata_work); |
619 | } | 624 | } |
620 | spin_lock(&appldata_timer_lock); | 625 | spin_lock(&appldata_timer_lock); |
621 | __appldata_vtimer_setup(APPLDATA_MOD_TIMER); | 626 | __appldata_vtimer_setup(APPLDATA_MOD_TIMER); |
@@ -648,7 +653,7 @@ static struct notifier_block __devinitdata appldata_nb = { | |||
648 | /* | 653 | /* |
649 | * appldata_init() | 654 | * appldata_init() |
650 | * | 655 | * |
651 | * init timer and tasklet, register /proc entries | 656 | * init timer, register /proc entries |
652 | */ | 657 | */ |
653 | static int __init appldata_init(void) | 658 | static int __init appldata_init(void) |
654 | { | 659 | { |
@@ -657,6 +662,12 @@ static int __init appldata_init(void) | |||
657 | P_DEBUG("sizeof(parameter_list) = %lu\n", | 662 | P_DEBUG("sizeof(parameter_list) = %lu\n", |
658 | sizeof(struct appldata_parameter_list)); | 663 | sizeof(struct appldata_parameter_list)); |
659 | 664 | ||
665 | appldata_wq = create_singlethread_workqueue("appldata"); | ||
666 | if (!appldata_wq) { | ||
667 | P_ERROR("Could not create work queue\n"); | ||
668 | return -ENOMEM; | ||
669 | } | ||
670 | |||
660 | for_each_online_cpu(i) | 671 | for_each_online_cpu(i) |
661 | appldata_online_cpu(i); | 672 | appldata_online_cpu(i); |
662 | 673 | ||
@@ -670,7 +681,6 @@ static int __init appldata_init(void) | |||
670 | appldata_table[1].de->owner = THIS_MODULE; | 681 | appldata_table[1].de->owner = THIS_MODULE; |
671 | #endif | 682 | #endif |
672 | 683 | ||
673 | tasklet_init(&appldata_tasklet_struct, appldata_tasklet_function, 0); | ||
674 | P_DEBUG("Base interface initialized.\n"); | 684 | P_DEBUG("Base interface initialized.\n"); |
675 | return 0; | 685 | return 0; |
676 | } | 686 | } |
@@ -678,7 +688,7 @@ static int __init appldata_init(void) | |||
678 | /* | 688 | /* |
679 | * appldata_exit() | 689 | * appldata_exit() |
680 | * | 690 | * |
681 | * stop timer and tasklet, unregister /proc entries | 691 | * stop timer, unregister /proc entries |
682 | */ | 692 | */ |
683 | static void __exit appldata_exit(void) | 693 | static void __exit appldata_exit(void) |
684 | { | 694 | { |
@@ -690,7 +700,7 @@ static void __exit appldata_exit(void) | |||
690 | /* | 700 | /* |
691 | * ops list should be empty, but just in case something went wrong... | 701 | * ops list should be empty, but just in case something went wrong... |
692 | */ | 702 | */ |
693 | spin_lock_bh(&appldata_ops_lock); | 703 | spin_lock(&appldata_ops_lock); |
694 | list_for_each(lh, &appldata_ops_list) { | 704 | list_for_each(lh, &appldata_ops_list) { |
695 | ops = list_entry(lh, struct appldata_ops, list); | 705 | ops = list_entry(lh, struct appldata_ops, list); |
696 | rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC, | 706 | rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC, |
@@ -700,7 +710,7 @@ static void __exit appldata_exit(void) | |||
700 | "return code: %d\n", ops->name, rc); | 710 | "return code: %d\n", ops->name, rc); |
701 | } | 711 | } |
702 | } | 712 | } |
703 | spin_unlock_bh(&appldata_ops_lock); | 713 | spin_unlock(&appldata_ops_lock); |
704 | 714 | ||
705 | for_each_online_cpu(i) | 715 | for_each_online_cpu(i) |
706 | appldata_offline_cpu(i); | 716 | appldata_offline_cpu(i); |
@@ -709,7 +719,7 @@ static void __exit appldata_exit(void) | |||
709 | 719 | ||
710 | unregister_sysctl_table(appldata_sysctl_header); | 720 | unregister_sysctl_table(appldata_sysctl_header); |
711 | 721 | ||
712 | tasklet_kill(&appldata_tasklet_struct); | 722 | destroy_workqueue(appldata_wq); |
713 | P_DEBUG("... module unloaded!\n"); | 723 | P_DEBUG("... module unloaded!\n"); |
714 | } | 724 | } |
715 | /**************************** init / exit <END> ******************************/ | 725 | /**************************** init / exit <END> ******************************/ |
diff --git a/arch/s390/appldata/appldata_mem.c b/arch/s390/appldata/appldata_mem.c index 462ee9a84e76..f0e2fbed3d4c 100644 --- a/arch/s390/appldata/appldata_mem.c +++ b/arch/s390/appldata/appldata_mem.c | |||
@@ -68,7 +68,7 @@ struct appldata_mem_data { | |||
68 | u64 pgmajfault; /* page faults (major only) */ | 68 | u64 pgmajfault; /* page faults (major only) */ |
69 | // <-- New in 2.6 | 69 | // <-- New in 2.6 |
70 | 70 | ||
71 | } appldata_mem_data; | 71 | } __attribute__((packed)) appldata_mem_data; |
72 | 72 | ||
73 | 73 | ||
74 | static inline void appldata_debug_print(struct appldata_mem_data *mem_data) | 74 | static inline void appldata_debug_print(struct appldata_mem_data *mem_data) |
diff --git a/arch/s390/appldata/appldata_net_sum.c b/arch/s390/appldata/appldata_net_sum.c index dd61638d3027..2a4c7432db4a 100644 --- a/arch/s390/appldata/appldata_net_sum.c +++ b/arch/s390/appldata/appldata_net_sum.c | |||
@@ -57,7 +57,7 @@ struct appldata_net_sum_data { | |||
57 | u64 rx_dropped; /* no space in linux buffers */ | 57 | u64 rx_dropped; /* no space in linux buffers */ |
58 | u64 tx_dropped; /* no space available in linux */ | 58 | u64 tx_dropped; /* no space available in linux */ |
59 | u64 collisions; /* collisions while transmitting */ | 59 | u64 collisions; /* collisions while transmitting */ |
60 | } appldata_net_sum_data; | 60 | } __attribute__((packed)) appldata_net_sum_data; |
61 | 61 | ||
62 | 62 | ||
63 | static inline void appldata_print_debug(struct appldata_net_sum_data *net_data) | 63 | static inline void appldata_print_debug(struct appldata_net_sum_data *net_data) |
diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c index b83f07484551..e0a476bf4fd6 100644 --- a/arch/s390/appldata/appldata_os.c +++ b/arch/s390/appldata/appldata_os.c | |||
@@ -49,7 +49,7 @@ struct appldata_os_per_cpu { | |||
49 | u32 per_cpu_softirq; /* ... spent in softirqs */ | 49 | u32 per_cpu_softirq; /* ... spent in softirqs */ |
50 | u32 per_cpu_iowait; /* ... spent while waiting for I/O */ | 50 | u32 per_cpu_iowait; /* ... spent while waiting for I/O */ |
51 | // <-- New in 2.6 | 51 | // <-- New in 2.6 |
52 | }; | 52 | } __attribute__((packed)); |
53 | 53 | ||
54 | struct appldata_os_data { | 54 | struct appldata_os_data { |
55 | u64 timestamp; | 55 | u64 timestamp; |
@@ -75,7 +75,7 @@ struct appldata_os_data { | |||
75 | 75 | ||
76 | /* per cpu data */ | 76 | /* per cpu data */ |
77 | struct appldata_os_per_cpu os_cpu[0]; | 77 | struct appldata_os_per_cpu os_cpu[0]; |
78 | }; | 78 | } __attribute__((packed)); |
79 | 79 | ||
80 | static struct appldata_os_data *appldata_os_data; | 80 | static struct appldata_os_data *appldata_os_data; |
81 | 81 | ||
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 9f0d73e3f5f7..06afa3103ace 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <asm/pgalloc.h> | 40 | #include <asm/pgalloc.h> |
41 | #include <asm/system.h> | 41 | #include <asm/system.h> |
42 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
43 | #include <asm/unistd.h> | ||
43 | 44 | ||
44 | #ifdef CONFIG_S390_SUPPORT | 45 | #ifdef CONFIG_S390_SUPPORT |
45 | #include "compat_ptrace.h" | 46 | #include "compat_ptrace.h" |
@@ -130,13 +131,19 @@ static int | |||
130 | peek_user(struct task_struct *child, addr_t addr, addr_t data) | 131 | peek_user(struct task_struct *child, addr_t addr, addr_t data) |
131 | { | 132 | { |
132 | struct user *dummy = NULL; | 133 | struct user *dummy = NULL; |
133 | addr_t offset, tmp; | 134 | addr_t offset, tmp, mask; |
134 | 135 | ||
135 | /* | 136 | /* |
136 | * Stupid gdb peeks/pokes the access registers in 64 bit with | 137 | * Stupid gdb peeks/pokes the access registers in 64 bit with |
137 | * an alignment of 4. Programmers from hell... | 138 | * an alignment of 4. Programmers from hell... |
138 | */ | 139 | */ |
139 | if ((addr & 3) || addr > sizeof(struct user) - __ADDR_MASK) | 140 | mask = __ADDR_MASK; |
141 | #ifdef CONFIG_ARCH_S390X | ||
142 | if (addr >= (addr_t) &dummy->regs.acrs && | ||
143 | addr < (addr_t) &dummy->regs.orig_gpr2) | ||
144 | mask = 3; | ||
145 | #endif | ||
146 | if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK) | ||
140 | return -EIO; | 147 | return -EIO; |
141 | 148 | ||
142 | if (addr < (addr_t) &dummy->regs.acrs) { | 149 | if (addr < (addr_t) &dummy->regs.acrs) { |
@@ -153,6 +160,16 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data) | |||
153 | * access registers are stored in the thread structure | 160 | * access registers are stored in the thread structure |
154 | */ | 161 | */ |
155 | offset = addr - (addr_t) &dummy->regs.acrs; | 162 | offset = addr - (addr_t) &dummy->regs.acrs; |
163 | #ifdef CONFIG_ARCH_S390X | ||
164 | /* | ||
165 | * Very special case: old & broken 64 bit gdb reading | ||
166 | * from acrs[15]. Result is a 64 bit value. Read the | ||
167 | * 32 bit acrs[15] value and shift it by 32. Sick... | ||
168 | */ | ||
169 | if (addr == (addr_t) &dummy->regs.acrs[15]) | ||
170 | tmp = ((unsigned long) child->thread.acrs[15]) << 32; | ||
171 | else | ||
172 | #endif | ||
156 | tmp = *(addr_t *)((addr_t) &child->thread.acrs + offset); | 173 | tmp = *(addr_t *)((addr_t) &child->thread.acrs + offset); |
157 | 174 | ||
158 | } else if (addr == (addr_t) &dummy->regs.orig_gpr2) { | 175 | } else if (addr == (addr_t) &dummy->regs.orig_gpr2) { |
@@ -167,6 +184,9 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data) | |||
167 | */ | 184 | */ |
168 | offset = addr - (addr_t) &dummy->regs.fp_regs; | 185 | offset = addr - (addr_t) &dummy->regs.fp_regs; |
169 | tmp = *(addr_t *)((addr_t) &child->thread.fp_regs + offset); | 186 | tmp = *(addr_t *)((addr_t) &child->thread.fp_regs + offset); |
187 | if (addr == (addr_t) &dummy->regs.fp_regs.fpc) | ||
188 | tmp &= (unsigned long) FPC_VALID_MASK | ||
189 | << (BITS_PER_LONG - 32); | ||
170 | 190 | ||
171 | } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) { | 191 | } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) { |
172 | /* | 192 | /* |
@@ -191,13 +211,19 @@ static int | |||
191 | poke_user(struct task_struct *child, addr_t addr, addr_t data) | 211 | poke_user(struct task_struct *child, addr_t addr, addr_t data) |
192 | { | 212 | { |
193 | struct user *dummy = NULL; | 213 | struct user *dummy = NULL; |
194 | addr_t offset; | 214 | addr_t offset, mask; |
195 | 215 | ||
196 | /* | 216 | /* |
197 | * Stupid gdb peeks/pokes the access registers in 64 bit with | 217 | * Stupid gdb peeks/pokes the access registers in 64 bit with |
198 | * an alignment of 4. Programmers from hell indeed... | 218 | * an alignment of 4. Programmers from hell indeed... |
199 | */ | 219 | */ |
200 | if ((addr & 3) || addr > sizeof(struct user) - __ADDR_MASK) | 220 | mask = __ADDR_MASK; |
221 | #ifdef CONFIG_ARCH_S390X | ||
222 | if (addr >= (addr_t) &dummy->regs.acrs && | ||
223 | addr < (addr_t) &dummy->regs.orig_gpr2) | ||
224 | mask = 3; | ||
225 | #endif | ||
226 | if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK) | ||
201 | return -EIO; | 227 | return -EIO; |
202 | 228 | ||
203 | if (addr < (addr_t) &dummy->regs.acrs) { | 229 | if (addr < (addr_t) &dummy->regs.acrs) { |
@@ -224,6 +250,17 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data) | |||
224 | * access registers are stored in the thread structure | 250 | * access registers are stored in the thread structure |
225 | */ | 251 | */ |
226 | offset = addr - (addr_t) &dummy->regs.acrs; | 252 | offset = addr - (addr_t) &dummy->regs.acrs; |
253 | #ifdef CONFIG_ARCH_S390X | ||
254 | /* | ||
255 | * Very special case: old & broken 64 bit gdb writing | ||
256 | * to acrs[15] with a 64 bit value. Ignore the lower | ||
257 | * half of the value and write the upper 32 bit to | ||
258 | * acrs[15]. Sick... | ||
259 | */ | ||
260 | if (addr == (addr_t) &dummy->regs.acrs[15]) | ||
261 | child->thread.acrs[15] = (unsigned int) (data >> 32); | ||
262 | else | ||
263 | #endif | ||
227 | *(addr_t *)((addr_t) &child->thread.acrs + offset) = data; | 264 | *(addr_t *)((addr_t) &child->thread.acrs + offset) = data; |
228 | 265 | ||
229 | } else if (addr == (addr_t) &dummy->regs.orig_gpr2) { | 266 | } else if (addr == (addr_t) &dummy->regs.orig_gpr2) { |
@@ -237,7 +274,8 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data) | |||
237 | * floating point regs. are stored in the thread structure | 274 | * floating point regs. are stored in the thread structure |
238 | */ | 275 | */ |
239 | if (addr == (addr_t) &dummy->regs.fp_regs.fpc && | 276 | if (addr == (addr_t) &dummy->regs.fp_regs.fpc && |
240 | (data & ~FPC_VALID_MASK) != 0) | 277 | (data & ~((unsigned long) FPC_VALID_MASK |
278 | << (BITS_PER_LONG - 32))) != 0) | ||
241 | return -EINVAL; | 279 | return -EINVAL; |
242 | offset = addr - (addr_t) &dummy->regs.fp_regs; | 280 | offset = addr - (addr_t) &dummy->regs.fp_regs; |
243 | *(addr_t *)((addr_t) &child->thread.fp_regs + offset) = data; | 281 | *(addr_t *)((addr_t) &child->thread.fp_regs + offset) = data; |
@@ -712,22 +750,24 @@ out: | |||
712 | asmlinkage void | 750 | asmlinkage void |
713 | syscall_trace(struct pt_regs *regs, int entryexit) | 751 | syscall_trace(struct pt_regs *regs, int entryexit) |
714 | { | 752 | { |
715 | if (unlikely(current->audit_context)) { | 753 | if (unlikely(current->audit_context) && entryexit) |
716 | if (!entryexit) | 754 | audit_syscall_exit(current, AUDITSC_RESULT(regs->gprs[2]), regs->gprs[2]); |
717 | audit_syscall_entry(current, regs->gprs[2], | 755 | |
718 | regs->orig_gpr2, regs->gprs[3], | ||
719 | regs->gprs[4], regs->gprs[5]); | ||
720 | else | ||
721 | audit_syscall_exit(current, regs->gprs[2]); | ||
722 | } | ||
723 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) | 756 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) |
724 | return; | 757 | goto out; |
725 | if (!(current->ptrace & PT_PTRACED)) | 758 | if (!(current->ptrace & PT_PTRACED)) |
726 | return; | 759 | goto out; |
727 | ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) | 760 | ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) |
728 | ? 0x80 : 0)); | 761 | ? 0x80 : 0)); |
729 | 762 | ||
730 | /* | 763 | /* |
764 | * If the debuffer has set an invalid system call number, | ||
765 | * we prepare to skip the system call restart handling. | ||
766 | */ | ||
767 | if (!entryexit && regs->gprs[2] >= NR_syscalls) | ||
768 | regs->trap = -1; | ||
769 | |||
770 | /* | ||
731 | * this isn't the same as continuing with a signal, but it will do | 771 | * this isn't the same as continuing with a signal, but it will do |
732 | * for normal use. strace only continues with a signal if the | 772 | * for normal use. strace only continues with a signal if the |
733 | * stopping signal is not SIGTRAP. -brl | 773 | * stopping signal is not SIGTRAP. -brl |
@@ -736,4 +776,10 @@ syscall_trace(struct pt_regs *regs, int entryexit) | |||
736 | send_sig(current->exit_code, current, 1); | 776 | send_sig(current->exit_code, current, 1); |
737 | current->exit_code = 0; | 777 | current->exit_code = 0; |
738 | } | 778 | } |
779 | out: | ||
780 | if (unlikely(current->audit_context) && !entryexit) | ||
781 | audit_syscall_entry(current, | ||
782 | test_thread_flag(TIF_31BIT)?AUDIT_ARCH_S390:AUDIT_ARCH_S390X, | ||
783 | regs->gprs[2], regs->orig_gpr2, regs->gprs[3], | ||
784 | regs->gprs[4], regs->gprs[5]); | ||
739 | } | 785 | } |
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 80306bc8c799..75fde949d125 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c | |||
@@ -207,7 +207,7 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection) | |||
207 | * we are not in an interrupt and that there is a | 207 | * we are not in an interrupt and that there is a |
208 | * user context. | 208 | * user context. |
209 | */ | 209 | */ |
210 | if (user_address == 0 || in_interrupt() || !mm) | 210 | if (user_address == 0 || in_atomic() || !mm) |
211 | goto no_context; | 211 | goto no_context; |
212 | 212 | ||
213 | /* | 213 | /* |
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 722ea1d63c94..3468d5127223 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
@@ -693,6 +693,10 @@ config RTC_9701JE | |||
693 | 693 | ||
694 | endmenu | 694 | endmenu |
695 | 695 | ||
696 | config ISA_DMA_API | ||
697 | bool | ||
698 | depends on MPC1211 | ||
699 | default y | ||
696 | 700 | ||
697 | menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)" | 701 | menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)" |
698 | 702 | ||
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index 066e253f9c12..2c216ffeea90 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c | |||
@@ -83,9 +83,6 @@ void default_idle(void) | |||
83 | */ | 83 | */ |
84 | void cpu_idle(void) | 84 | void cpu_idle(void) |
85 | { | 85 | { |
86 | if (current->pid != 0) | ||
87 | goto out; | ||
88 | |||
89 | /* endless idle loop with no priority at all */ | 86 | /* endless idle loop with no priority at all */ |
90 | for (;;) { | 87 | for (;;) { |
91 | if (ARCH_SUN4C_SUN4) { | 88 | if (ARCH_SUN4C_SUN4) { |
@@ -126,8 +123,6 @@ void cpu_idle(void) | |||
126 | schedule(); | 123 | schedule(); |
127 | check_pgt_cache(); | 124 | check_pgt_cache(); |
128 | } | 125 | } |
129 | out: | ||
130 | return; | ||
131 | } | 126 | } |
132 | 127 | ||
133 | #else | 128 | #else |
diff --git a/arch/sparc/prom/memory.c b/arch/sparc/prom/memory.c index 46aa51afec14..c20e5309f8aa 100644 --- a/arch/sparc/prom/memory.c +++ b/arch/sparc/prom/memory.c | |||
@@ -47,9 +47,9 @@ prom_sortmemlist(struct linux_mlist_v0 *thislist) | |||
47 | char *tmpaddr; | 47 | char *tmpaddr; |
48 | char *lowest; | 48 | char *lowest; |
49 | 49 | ||
50 | for(i=0; thislist[i].theres_more != 0; i++) { | 50 | for(i=0; thislist[i].theres_more; i++) { |
51 | lowest = thislist[i].start_adr; | 51 | lowest = thislist[i].start_adr; |
52 | for(mitr = i+1; thislist[mitr-1].theres_more != 0; mitr++) | 52 | for(mitr = i+1; thislist[mitr-1].theres_more; mitr++) |
53 | if(thislist[mitr].start_adr < lowest) { | 53 | if(thislist[mitr].start_adr < lowest) { |
54 | lowest = thislist[mitr].start_adr; | 54 | lowest = thislist[mitr].start_adr; |
55 | swapi = mitr; | 55 | swapi = mitr; |
@@ -85,7 +85,7 @@ void __init prom_meminit(void) | |||
85 | prom_phys_total[iter].num_bytes = mptr->num_bytes; | 85 | prom_phys_total[iter].num_bytes = mptr->num_bytes; |
86 | prom_phys_total[iter].theres_more = &prom_phys_total[iter+1]; | 86 | prom_phys_total[iter].theres_more = &prom_phys_total[iter+1]; |
87 | } | 87 | } |
88 | prom_phys_total[iter-1].theres_more = 0x0; | 88 | prom_phys_total[iter-1].theres_more = NULL; |
89 | /* Second, the total prom taken descriptors. */ | 89 | /* Second, the total prom taken descriptors. */ |
90 | for(mptr = (*(romvec->pv_v0mem.v0_prommap)), iter=0; | 90 | for(mptr = (*(romvec->pv_v0mem.v0_prommap)), iter=0; |
91 | mptr; mptr=mptr->theres_more, iter++) { | 91 | mptr; mptr=mptr->theres_more, iter++) { |
@@ -93,7 +93,7 @@ void __init prom_meminit(void) | |||
93 | prom_prom_taken[iter].num_bytes = mptr->num_bytes; | 93 | prom_prom_taken[iter].num_bytes = mptr->num_bytes; |
94 | prom_prom_taken[iter].theres_more = &prom_prom_taken[iter+1]; | 94 | prom_prom_taken[iter].theres_more = &prom_prom_taken[iter+1]; |
95 | } | 95 | } |
96 | prom_prom_taken[iter-1].theres_more = 0x0; | 96 | prom_prom_taken[iter-1].theres_more = NULL; |
97 | /* Last, the available physical descriptors. */ | 97 | /* Last, the available physical descriptors. */ |
98 | for(mptr = (*(romvec->pv_v0mem.v0_available)), iter=0; | 98 | for(mptr = (*(romvec->pv_v0mem.v0_available)), iter=0; |
99 | mptr; mptr=mptr->theres_more, iter++) { | 99 | mptr; mptr=mptr->theres_more, iter++) { |
@@ -101,7 +101,7 @@ void __init prom_meminit(void) | |||
101 | prom_phys_avail[iter].num_bytes = mptr->num_bytes; | 101 | prom_phys_avail[iter].num_bytes = mptr->num_bytes; |
102 | prom_phys_avail[iter].theres_more = &prom_phys_avail[iter+1]; | 102 | prom_phys_avail[iter].theres_more = &prom_phys_avail[iter+1]; |
103 | } | 103 | } |
104 | prom_phys_avail[iter-1].theres_more = 0x0; | 104 | prom_phys_avail[iter-1].theres_more = NULL; |
105 | /* Sort all the lists. */ | 105 | /* Sort all the lists. */ |
106 | prom_sortmemlist(prom_phys_total); | 106 | prom_sortmemlist(prom_phys_total); |
107 | prom_sortmemlist(prom_prom_taken); | 107 | prom_sortmemlist(prom_prom_taken); |
@@ -124,7 +124,7 @@ void __init prom_meminit(void) | |||
124 | prom_phys_avail[iter].theres_more = | 124 | prom_phys_avail[iter].theres_more = |
125 | &prom_phys_avail[iter+1]; | 125 | &prom_phys_avail[iter+1]; |
126 | } | 126 | } |
127 | prom_phys_avail[iter-1].theres_more = 0x0; | 127 | prom_phys_avail[iter-1].theres_more = NULL; |
128 | 128 | ||
129 | num_regs = prom_getproperty(node, "reg", | 129 | num_regs = prom_getproperty(node, "reg", |
130 | (char *) prom_reg_memlist, | 130 | (char *) prom_reg_memlist, |
@@ -138,7 +138,7 @@ void __init prom_meminit(void) | |||
138 | prom_phys_total[iter].theres_more = | 138 | prom_phys_total[iter].theres_more = |
139 | &prom_phys_total[iter+1]; | 139 | &prom_phys_total[iter+1]; |
140 | } | 140 | } |
141 | prom_phys_total[iter-1].theres_more = 0x0; | 141 | prom_phys_total[iter-1].theres_more = NULL; |
142 | 142 | ||
143 | node = prom_getchild(prom_root_node); | 143 | node = prom_getchild(prom_root_node); |
144 | node = prom_searchsiblings(node, "virtual-memory"); | 144 | node = prom_searchsiblings(node, "virtual-memory"); |
@@ -158,7 +158,7 @@ void __init prom_meminit(void) | |||
158 | prom_prom_taken[iter].theres_more = | 158 | prom_prom_taken[iter].theres_more = |
159 | &prom_prom_taken[iter+1]; | 159 | &prom_prom_taken[iter+1]; |
160 | } | 160 | } |
161 | prom_prom_taken[iter-1].theres_more = 0x0; | 161 | prom_prom_taken[iter-1].theres_more = NULL; |
162 | 162 | ||
163 | prom_sortmemlist(prom_prom_taken); | 163 | prom_sortmemlist(prom_prom_taken); |
164 | 164 | ||
@@ -182,15 +182,15 @@ void __init prom_meminit(void) | |||
182 | case PROM_SUN4: | 182 | case PROM_SUN4: |
183 | #ifdef CONFIG_SUN4 | 183 | #ifdef CONFIG_SUN4 |
184 | /* how simple :) */ | 184 | /* how simple :) */ |
185 | prom_phys_total[0].start_adr = 0x0; | 185 | prom_phys_total[0].start_adr = NULL; |
186 | prom_phys_total[0].num_bytes = *(sun4_romvec->memorysize); | 186 | prom_phys_total[0].num_bytes = *(sun4_romvec->memorysize); |
187 | prom_phys_total[0].theres_more = 0x0; | 187 | prom_phys_total[0].theres_more = NULL; |
188 | prom_prom_taken[0].start_adr = 0x0; | 188 | prom_prom_taken[0].start_adr = NULL; |
189 | prom_prom_taken[0].num_bytes = 0x0; | 189 | prom_prom_taken[0].num_bytes = 0x0; |
190 | prom_prom_taken[0].theres_more = 0x0; | 190 | prom_prom_taken[0].theres_more = NULL; |
191 | prom_phys_avail[0].start_adr = 0x0; | 191 | prom_phys_avail[0].start_adr = NULL; |
192 | prom_phys_avail[0].num_bytes = *(sun4_romvec->memoryavail); | 192 | prom_phys_avail[0].num_bytes = *(sun4_romvec->memoryavail); |
193 | prom_phys_avail[0].theres_more = 0x0; | 193 | prom_phys_avail[0].theres_more = NULL; |
194 | #endif | 194 | #endif |
195 | break; | 195 | break; |
196 | 196 | ||
diff --git a/arch/sparc/prom/sun4prom.c b/arch/sparc/prom/sun4prom.c index 69ca735f0d4e..00390a2652aa 100644 --- a/arch/sparc/prom/sun4prom.c +++ b/arch/sparc/prom/sun4prom.c | |||
@@ -151,7 +151,7 @@ struct linux_romvec * __init sun4_prom_init(void) | |||
151 | * have more time, we can teach the penguin to say "By your | 151 | * have more time, we can teach the penguin to say "By your |
152 | * command" or "Activating turbo boost, Michael". :-) | 152 | * command" or "Activating turbo boost, Michael". :-) |
153 | */ | 153 | */ |
154 | sun4_romvec->setLEDs(0x0); | 154 | sun4_romvec->setLEDs(NULL); |
155 | 155 | ||
156 | printk("PROMLIB: Old Sun4 boot PROM monitor %s, romvec version %d\n", | 156 | printk("PROMLIB: Old Sun4 boot PROM monitor %s, romvec version %d\n", |
157 | sun4_romvec->monid, | 157 | sun4_romvec->monid, |
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index a38cb5036df0..4dcb8af94090 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c | |||
@@ -756,7 +756,7 @@ void handler_irq(int irq, struct pt_regs *regs) | |||
756 | clear_softint(clr_mask); | 756 | clear_softint(clr_mask); |
757 | } | 757 | } |
758 | #else | 758 | #else |
759 | int should_forward = 1; | 759 | int should_forward = 0; |
760 | 760 | ||
761 | clear_softint(1 << irq); | 761 | clear_softint(1 << irq); |
762 | #endif | 762 | #endif |
@@ -1007,10 +1007,10 @@ static int retarget_one_irq(struct irqaction *p, int goal_cpu) | |||
1007 | } | 1007 | } |
1008 | upa_writel(tid | IMAP_VALID, imap); | 1008 | upa_writel(tid | IMAP_VALID, imap); |
1009 | 1009 | ||
1010 | while (!cpu_online(goal_cpu)) { | 1010 | do { |
1011 | if (++goal_cpu >= NR_CPUS) | 1011 | if (++goal_cpu >= NR_CPUS) |
1012 | goal_cpu = 0; | 1012 | goal_cpu = 0; |
1013 | } | 1013 | } while (!cpu_online(goal_cpu)); |
1014 | 1014 | ||
1015 | return goal_cpu; | 1015 | return goal_cpu; |
1016 | } | 1016 | } |
diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c index 292983413ae2..2803bc7c2c79 100644 --- a/arch/sparc64/kernel/pci_iommu.c +++ b/arch/sparc64/kernel/pci_iommu.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
9 | #include <linux/sched.h> | 9 | #include <linux/sched.h> |
10 | #include <linux/mm.h> | 10 | #include <linux/mm.h> |
11 | #include <linux/delay.h> | ||
11 | 12 | ||
12 | #include <asm/pbm.h> | 13 | #include <asm/pbm.h> |
13 | 14 | ||
@@ -195,6 +196,34 @@ static iopte_t *alloc_consistent_cluster(struct pci_iommu *iommu, unsigned long | |||
195 | return NULL; | 196 | return NULL; |
196 | } | 197 | } |
197 | 198 | ||
199 | static int iommu_alloc_ctx(struct pci_iommu *iommu) | ||
200 | { | ||
201 | int lowest = iommu->ctx_lowest_free; | ||
202 | int sz = IOMMU_NUM_CTXS - lowest; | ||
203 | int n = find_next_zero_bit(iommu->ctx_bitmap, sz, lowest); | ||
204 | |||
205 | if (unlikely(n == sz)) { | ||
206 | n = find_next_zero_bit(iommu->ctx_bitmap, lowest, 1); | ||
207 | if (unlikely(n == lowest)) { | ||
208 | printk(KERN_WARNING "IOMMU: Ran out of contexts.\n"); | ||
209 | n = 0; | ||
210 | } | ||
211 | } | ||
212 | if (n) | ||
213 | __set_bit(n, iommu->ctx_bitmap); | ||
214 | |||
215 | return n; | ||
216 | } | ||
217 | |||
218 | static inline void iommu_free_ctx(struct pci_iommu *iommu, int ctx) | ||
219 | { | ||
220 | if (likely(ctx)) { | ||
221 | __clear_bit(ctx, iommu->ctx_bitmap); | ||
222 | if (ctx < iommu->ctx_lowest_free) | ||
223 | iommu->ctx_lowest_free = ctx; | ||
224 | } | ||
225 | } | ||
226 | |||
198 | /* Allocate and map kernel buffer of size SIZE using consistent mode | 227 | /* Allocate and map kernel buffer of size SIZE using consistent mode |
199 | * DMA for PCI device PDEV. Return non-NULL cpu-side address if | 228 | * DMA for PCI device PDEV. Return non-NULL cpu-side address if |
200 | * successful and set *DMA_ADDRP to the PCI side dma address. | 229 | * successful and set *DMA_ADDRP to the PCI side dma address. |
@@ -235,7 +264,7 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_ad | |||
235 | npages = size >> IO_PAGE_SHIFT; | 264 | npages = size >> IO_PAGE_SHIFT; |
236 | ctx = 0; | 265 | ctx = 0; |
237 | if (iommu->iommu_ctxflush) | 266 | if (iommu->iommu_ctxflush) |
238 | ctx = iommu->iommu_cur_ctx++; | 267 | ctx = iommu_alloc_ctx(iommu); |
239 | first_page = __pa(first_page); | 268 | first_page = __pa(first_page); |
240 | while (npages--) { | 269 | while (npages--) { |
241 | iopte_val(*iopte) = (IOPTE_CONSISTENT(ctx) | | 270 | iopte_val(*iopte) = (IOPTE_CONSISTENT(ctx) | |
@@ -316,6 +345,8 @@ void pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_ | |||
316 | } | 345 | } |
317 | } | 346 | } |
318 | 347 | ||
348 | iommu_free_ctx(iommu, ctx); | ||
349 | |||
319 | spin_unlock_irqrestore(&iommu->lock, flags); | 350 | spin_unlock_irqrestore(&iommu->lock, flags); |
320 | 351 | ||
321 | order = get_order(size); | 352 | order = get_order(size); |
@@ -359,7 +390,7 @@ dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direct | |||
359 | base_paddr = __pa(oaddr & IO_PAGE_MASK); | 390 | base_paddr = __pa(oaddr & IO_PAGE_MASK); |
360 | ctx = 0; | 391 | ctx = 0; |
361 | if (iommu->iommu_ctxflush) | 392 | if (iommu->iommu_ctxflush) |
362 | ctx = iommu->iommu_cur_ctx++; | 393 | ctx = iommu_alloc_ctx(iommu); |
363 | if (strbuf->strbuf_enabled) | 394 | if (strbuf->strbuf_enabled) |
364 | iopte_protection = IOPTE_STREAMING(ctx); | 395 | iopte_protection = IOPTE_STREAMING(ctx); |
365 | else | 396 | else |
@@ -379,6 +410,70 @@ bad: | |||
379 | return PCI_DMA_ERROR_CODE; | 410 | return PCI_DMA_ERROR_CODE; |
380 | } | 411 | } |
381 | 412 | ||
413 | static void pci_strbuf_flush(struct pci_strbuf *strbuf, struct pci_iommu *iommu, u32 vaddr, unsigned long ctx, unsigned long npages, int direction) | ||
414 | { | ||
415 | int limit; | ||
416 | |||
417 | if (strbuf->strbuf_ctxflush && | ||
418 | iommu->iommu_ctxflush) { | ||
419 | unsigned long matchreg, flushreg; | ||
420 | u64 val; | ||
421 | |||
422 | flushreg = strbuf->strbuf_ctxflush; | ||
423 | matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx); | ||
424 | |||
425 | pci_iommu_write(flushreg, ctx); | ||
426 | val = pci_iommu_read(matchreg); | ||
427 | val &= 0xffff; | ||
428 | if (!val) | ||
429 | goto do_flush_sync; | ||
430 | |||
431 | while (val) { | ||
432 | if (val & 0x1) | ||
433 | pci_iommu_write(flushreg, ctx); | ||
434 | val >>= 1; | ||
435 | } | ||
436 | val = pci_iommu_read(matchreg); | ||
437 | if (unlikely(val)) { | ||
438 | printk(KERN_WARNING "pci_strbuf_flush: ctx flush " | ||
439 | "timeout matchreg[%lx] ctx[%lx]\n", | ||
440 | val, ctx); | ||
441 | goto do_page_flush; | ||
442 | } | ||
443 | } else { | ||
444 | unsigned long i; | ||
445 | |||
446 | do_page_flush: | ||
447 | for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE) | ||
448 | pci_iommu_write(strbuf->strbuf_pflush, vaddr); | ||
449 | } | ||
450 | |||
451 | do_flush_sync: | ||
452 | /* If the device could not have possibly put dirty data into | ||
453 | * the streaming cache, no flush-flag synchronization needs | ||
454 | * to be performed. | ||
455 | */ | ||
456 | if (direction == PCI_DMA_TODEVICE) | ||
457 | return; | ||
458 | |||
459 | PCI_STC_FLUSHFLAG_INIT(strbuf); | ||
460 | pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa); | ||
461 | (void) pci_iommu_read(iommu->write_complete_reg); | ||
462 | |||
463 | limit = 100000; | ||
464 | while (!PCI_STC_FLUSHFLAG_SET(strbuf)) { | ||
465 | limit--; | ||
466 | if (!limit) | ||
467 | break; | ||
468 | udelay(1); | ||
469 | membar("#LoadLoad"); | ||
470 | } | ||
471 | if (!limit) | ||
472 | printk(KERN_WARNING "pci_strbuf_flush: flushflag timeout " | ||
473 | "vaddr[%08x] ctx[%lx] npages[%ld]\n", | ||
474 | vaddr, ctx, npages); | ||
475 | } | ||
476 | |||
382 | /* Unmap a single streaming mode DMA translation. */ | 477 | /* Unmap a single streaming mode DMA translation. */ |
383 | void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction) | 478 | void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction) |
384 | { | 479 | { |
@@ -386,7 +481,7 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int | |||
386 | struct pci_iommu *iommu; | 481 | struct pci_iommu *iommu; |
387 | struct pci_strbuf *strbuf; | 482 | struct pci_strbuf *strbuf; |
388 | iopte_t *base; | 483 | iopte_t *base; |
389 | unsigned long flags, npages, i, ctx; | 484 | unsigned long flags, npages, ctx; |
390 | 485 | ||
391 | if (direction == PCI_DMA_NONE) | 486 | if (direction == PCI_DMA_NONE) |
392 | BUG(); | 487 | BUG(); |
@@ -414,29 +509,8 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int | |||
414 | ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL; | 509 | ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL; |
415 | 510 | ||
416 | /* Step 1: Kick data out of streaming buffers if necessary. */ | 511 | /* Step 1: Kick data out of streaming buffers if necessary. */ |
417 | if (strbuf->strbuf_enabled) { | 512 | if (strbuf->strbuf_enabled) |
418 | u32 vaddr = bus_addr; | 513 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction); |
419 | |||
420 | PCI_STC_FLUSHFLAG_INIT(strbuf); | ||
421 | if (strbuf->strbuf_ctxflush && | ||
422 | iommu->iommu_ctxflush) { | ||
423 | unsigned long matchreg, flushreg; | ||
424 | |||
425 | flushreg = strbuf->strbuf_ctxflush; | ||
426 | matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx); | ||
427 | do { | ||
428 | pci_iommu_write(flushreg, ctx); | ||
429 | } while(((long)pci_iommu_read(matchreg)) < 0L); | ||
430 | } else { | ||
431 | for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE) | ||
432 | pci_iommu_write(strbuf->strbuf_pflush, vaddr); | ||
433 | } | ||
434 | |||
435 | pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa); | ||
436 | (void) pci_iommu_read(iommu->write_complete_reg); | ||
437 | while (!PCI_STC_FLUSHFLAG_SET(strbuf)) | ||
438 | membar("#LoadLoad"); | ||
439 | } | ||
440 | 514 | ||
441 | /* Step 2: Clear out first TSB entry. */ | 515 | /* Step 2: Clear out first TSB entry. */ |
442 | iopte_make_dummy(iommu, base); | 516 | iopte_make_dummy(iommu, base); |
@@ -444,6 +518,8 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int | |||
444 | free_streaming_cluster(iommu, bus_addr - iommu->page_table_map_base, | 518 | free_streaming_cluster(iommu, bus_addr - iommu->page_table_map_base, |
445 | npages, ctx); | 519 | npages, ctx); |
446 | 520 | ||
521 | iommu_free_ctx(iommu, ctx); | ||
522 | |||
447 | spin_unlock_irqrestore(&iommu->lock, flags); | 523 | spin_unlock_irqrestore(&iommu->lock, flags); |
448 | } | 524 | } |
449 | 525 | ||
@@ -583,7 +659,7 @@ int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int | |||
583 | /* Step 4: Choose a context if necessary. */ | 659 | /* Step 4: Choose a context if necessary. */ |
584 | ctx = 0; | 660 | ctx = 0; |
585 | if (iommu->iommu_ctxflush) | 661 | if (iommu->iommu_ctxflush) |
586 | ctx = iommu->iommu_cur_ctx++; | 662 | ctx = iommu_alloc_ctx(iommu); |
587 | 663 | ||
588 | /* Step 5: Create the mappings. */ | 664 | /* Step 5: Create the mappings. */ |
589 | if (strbuf->strbuf_enabled) | 665 | if (strbuf->strbuf_enabled) |
@@ -647,29 +723,8 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, | |||
647 | ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL; | 723 | ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL; |
648 | 724 | ||
649 | /* Step 1: Kick data out of streaming buffers if necessary. */ | 725 | /* Step 1: Kick data out of streaming buffers if necessary. */ |
650 | if (strbuf->strbuf_enabled) { | 726 | if (strbuf->strbuf_enabled) |
651 | u32 vaddr = (u32) bus_addr; | 727 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction); |
652 | |||
653 | PCI_STC_FLUSHFLAG_INIT(strbuf); | ||
654 | if (strbuf->strbuf_ctxflush && | ||
655 | iommu->iommu_ctxflush) { | ||
656 | unsigned long matchreg, flushreg; | ||
657 | |||
658 | flushreg = strbuf->strbuf_ctxflush; | ||
659 | matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx); | ||
660 | do { | ||
661 | pci_iommu_write(flushreg, ctx); | ||
662 | } while(((long)pci_iommu_read(matchreg)) < 0L); | ||
663 | } else { | ||
664 | for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE) | ||
665 | pci_iommu_write(strbuf->strbuf_pflush, vaddr); | ||
666 | } | ||
667 | |||
668 | pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa); | ||
669 | (void) pci_iommu_read(iommu->write_complete_reg); | ||
670 | while (!PCI_STC_FLUSHFLAG_SET(strbuf)) | ||
671 | membar("#LoadLoad"); | ||
672 | } | ||
673 | 728 | ||
674 | /* Step 2: Clear out first TSB entry. */ | 729 | /* Step 2: Clear out first TSB entry. */ |
675 | iopte_make_dummy(iommu, base); | 730 | iopte_make_dummy(iommu, base); |
@@ -677,6 +732,8 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, | |||
677 | free_streaming_cluster(iommu, bus_addr - iommu->page_table_map_base, | 732 | free_streaming_cluster(iommu, bus_addr - iommu->page_table_map_base, |
678 | npages, ctx); | 733 | npages, ctx); |
679 | 734 | ||
735 | iommu_free_ctx(iommu, ctx); | ||
736 | |||
680 | spin_unlock_irqrestore(&iommu->lock, flags); | 737 | spin_unlock_irqrestore(&iommu->lock, flags); |
681 | } | 738 | } |
682 | 739 | ||
@@ -715,28 +772,7 @@ void pci_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_addr, size | |||
715 | } | 772 | } |
716 | 773 | ||
717 | /* Step 2: Kick data out of streaming buffers. */ | 774 | /* Step 2: Kick data out of streaming buffers. */ |
718 | PCI_STC_FLUSHFLAG_INIT(strbuf); | 775 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction); |
719 | if (iommu->iommu_ctxflush && | ||
720 | strbuf->strbuf_ctxflush) { | ||
721 | unsigned long matchreg, flushreg; | ||
722 | |||
723 | flushreg = strbuf->strbuf_ctxflush; | ||
724 | matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx); | ||
725 | do { | ||
726 | pci_iommu_write(flushreg, ctx); | ||
727 | } while(((long)pci_iommu_read(matchreg)) < 0L); | ||
728 | } else { | ||
729 | unsigned long i; | ||
730 | |||
731 | for (i = 0; i < npages; i++, bus_addr += IO_PAGE_SIZE) | ||
732 | pci_iommu_write(strbuf->strbuf_pflush, bus_addr); | ||
733 | } | ||
734 | |||
735 | /* Step 3: Perform flush synchronization sequence. */ | ||
736 | pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa); | ||
737 | (void) pci_iommu_read(iommu->write_complete_reg); | ||
738 | while (!PCI_STC_FLUSHFLAG_SET(strbuf)) | ||
739 | membar("#LoadLoad"); | ||
740 | 776 | ||
741 | spin_unlock_irqrestore(&iommu->lock, flags); | 777 | spin_unlock_irqrestore(&iommu->lock, flags); |
742 | } | 778 | } |
@@ -749,7 +785,8 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, i | |||
749 | struct pcidev_cookie *pcp; | 785 | struct pcidev_cookie *pcp; |
750 | struct pci_iommu *iommu; | 786 | struct pci_iommu *iommu; |
751 | struct pci_strbuf *strbuf; | 787 | struct pci_strbuf *strbuf; |
752 | unsigned long flags, ctx; | 788 | unsigned long flags, ctx, npages, i; |
789 | u32 bus_addr; | ||
753 | 790 | ||
754 | pcp = pdev->sysdata; | 791 | pcp = pdev->sysdata; |
755 | iommu = pcp->pbm->iommu; | 792 | iommu = pcp->pbm->iommu; |
@@ -772,36 +809,14 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, i | |||
772 | } | 809 | } |
773 | 810 | ||
774 | /* Step 2: Kick data out of streaming buffers. */ | 811 | /* Step 2: Kick data out of streaming buffers. */ |
775 | PCI_STC_FLUSHFLAG_INIT(strbuf); | 812 | bus_addr = sglist[0].dma_address & IO_PAGE_MASK; |
776 | if (iommu->iommu_ctxflush && | 813 | for(i = 1; i < nelems; i++) |
777 | strbuf->strbuf_ctxflush) { | 814 | if (!sglist[i].dma_length) |
778 | unsigned long matchreg, flushreg; | 815 | break; |
779 | 816 | i--; | |
780 | flushreg = strbuf->strbuf_ctxflush; | 817 | npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) |
781 | matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx); | 818 | - bus_addr) >> IO_PAGE_SHIFT; |
782 | do { | 819 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction); |
783 | pci_iommu_write(flushreg, ctx); | ||
784 | } while (((long)pci_iommu_read(matchreg)) < 0L); | ||
785 | } else { | ||
786 | unsigned long i, npages; | ||
787 | u32 bus_addr; | ||
788 | |||
789 | bus_addr = sglist[0].dma_address & IO_PAGE_MASK; | ||
790 | |||
791 | for(i = 1; i < nelems; i++) | ||
792 | if (!sglist[i].dma_length) | ||
793 | break; | ||
794 | i--; | ||
795 | npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) - bus_addr) >> IO_PAGE_SHIFT; | ||
796 | for (i = 0; i < npages; i++, bus_addr += IO_PAGE_SIZE) | ||
797 | pci_iommu_write(strbuf->strbuf_pflush, bus_addr); | ||
798 | } | ||
799 | |||
800 | /* Step 3: Perform flush synchronization sequence. */ | ||
801 | pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa); | ||
802 | (void) pci_iommu_read(iommu->write_complete_reg); | ||
803 | while (!PCI_STC_FLUSHFLAG_SET(strbuf)) | ||
804 | membar("#LoadLoad"); | ||
805 | 820 | ||
806 | spin_unlock_irqrestore(&iommu->lock, flags); | 821 | spin_unlock_irqrestore(&iommu->lock, flags); |
807 | } | 822 | } |
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 3567fa879e1f..534320ef0db2 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c | |||
@@ -1212,7 +1212,7 @@ static void __init psycho_iommu_init(struct pci_controller_info *p) | |||
1212 | 1212 | ||
1213 | /* Setup initial software IOMMU state. */ | 1213 | /* Setup initial software IOMMU state. */ |
1214 | spin_lock_init(&iommu->lock); | 1214 | spin_lock_init(&iommu->lock); |
1215 | iommu->iommu_cur_ctx = 0; | 1215 | iommu->ctx_lowest_free = 1; |
1216 | 1216 | ||
1217 | /* Register addresses. */ | 1217 | /* Register addresses. */ |
1218 | iommu->iommu_control = p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL; | 1218 | iommu->iommu_control = p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL; |
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 5525d1ec4af8..53d333b4a4e8 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c | |||
@@ -1265,7 +1265,7 @@ static void __init sabre_iommu_init(struct pci_controller_info *p, | |||
1265 | 1265 | ||
1266 | /* Setup initial software IOMMU state. */ | 1266 | /* Setup initial software IOMMU state. */ |
1267 | spin_lock_init(&iommu->lock); | 1267 | spin_lock_init(&iommu->lock); |
1268 | iommu->iommu_cur_ctx = 0; | 1268 | iommu->ctx_lowest_free = 1; |
1269 | 1269 | ||
1270 | /* Register addresses. */ | 1270 | /* Register addresses. */ |
1271 | iommu->iommu_control = p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL; | 1271 | iommu->iommu_control = p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL; |
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index e93fcadc3722..5753175b94e6 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c | |||
@@ -1753,7 +1753,7 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm) | |||
1753 | 1753 | ||
1754 | /* Setup initial software IOMMU state. */ | 1754 | /* Setup initial software IOMMU state. */ |
1755 | spin_lock_init(&iommu->lock); | 1755 | spin_lock_init(&iommu->lock); |
1756 | iommu->iommu_cur_ctx = 0; | 1756 | iommu->ctx_lowest_free = 1; |
1757 | 1757 | ||
1758 | /* Register addresses, SCHIZO has iommu ctx flushing. */ | 1758 | /* Register addresses, SCHIZO has iommu ctx flushing. */ |
1759 | iommu->iommu_control = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL; | 1759 | iommu->iommu_control = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL; |
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index 26d3ec41da1c..a0cd2b2494d6 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c | |||
@@ -62,9 +62,6 @@ void default_idle(void) | |||
62 | */ | 62 | */ |
63 | void cpu_idle(void) | 63 | void cpu_idle(void) |
64 | { | 64 | { |
65 | if (current->pid != 0) | ||
66 | return; | ||
67 | |||
68 | /* endless idle loop with no priority at all */ | 65 | /* endless idle loop with no priority at all */ |
69 | for (;;) { | 66 | for (;;) { |
70 | /* If current->work.need_resched is zero we should really | 67 | /* If current->work.need_resched is zero we should really |
@@ -80,7 +77,6 @@ void cpu_idle(void) | |||
80 | schedule(); | 77 | schedule(); |
81 | check_pgt_cache(); | 78 | check_pgt_cache(); |
82 | } | 79 | } |
83 | return; | ||
84 | } | 80 | } |
85 | 81 | ||
86 | #else | 82 | #else |
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c index 14d9c3a21b9a..89f5e019f24c 100644 --- a/arch/sparc64/kernel/sbus.c +++ b/arch/sparc64/kernel/sbus.c | |||
@@ -117,19 +117,42 @@ static void iommu_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages | |||
117 | 117 | ||
118 | #define STRBUF_TAG_VALID 0x02UL | 118 | #define STRBUF_TAG_VALID 0x02UL |
119 | 119 | ||
120 | static void strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages) | 120 | static void sbus_strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages, int direction) |
121 | { | 121 | { |
122 | iommu->strbuf_flushflag = 0UL; | 122 | unsigned long n; |
123 | while (npages--) | 123 | int limit; |
124 | upa_writeq(base + (npages << IO_PAGE_SHIFT), | 124 | |
125 | n = npages; | ||
126 | while (n--) | ||
127 | upa_writeq(base + (n << IO_PAGE_SHIFT), | ||
125 | iommu->strbuf_regs + STRBUF_PFLUSH); | 128 | iommu->strbuf_regs + STRBUF_PFLUSH); |
126 | 129 | ||
130 | /* If the device could not have possibly put dirty data into | ||
131 | * the streaming cache, no flush-flag synchronization needs | ||
132 | * to be performed. | ||
133 | */ | ||
134 | if (direction == SBUS_DMA_TODEVICE) | ||
135 | return; | ||
136 | |||
137 | iommu->strbuf_flushflag = 0UL; | ||
138 | |||
127 | /* Whoopee cushion! */ | 139 | /* Whoopee cushion! */ |
128 | upa_writeq(__pa(&iommu->strbuf_flushflag), | 140 | upa_writeq(__pa(&iommu->strbuf_flushflag), |
129 | iommu->strbuf_regs + STRBUF_FSYNC); | 141 | iommu->strbuf_regs + STRBUF_FSYNC); |
130 | upa_readq(iommu->sbus_control_reg); | 142 | upa_readq(iommu->sbus_control_reg); |
131 | while (iommu->strbuf_flushflag == 0UL) | 143 | |
144 | limit = 100000; | ||
145 | while (iommu->strbuf_flushflag == 0UL) { | ||
146 | limit--; | ||
147 | if (!limit) | ||
148 | break; | ||
149 | udelay(1); | ||
132 | membar("#LoadLoad"); | 150 | membar("#LoadLoad"); |
151 | } | ||
152 | if (!limit) | ||
153 | printk(KERN_WARNING "sbus_strbuf_flush: flushflag timeout " | ||
154 | "vaddr[%08x] npages[%ld]\n", | ||
155 | base, npages); | ||
133 | } | 156 | } |
134 | 157 | ||
135 | static iopte_t *alloc_streaming_cluster(struct sbus_iommu *iommu, unsigned long npages) | 158 | static iopte_t *alloc_streaming_cluster(struct sbus_iommu *iommu, unsigned long npages) |
@@ -406,7 +429,7 @@ void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t dma_addr, size_t size, | |||
406 | 429 | ||
407 | spin_lock_irqsave(&iommu->lock, flags); | 430 | spin_lock_irqsave(&iommu->lock, flags); |
408 | free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT); | 431 | free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT); |
409 | strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT); | 432 | sbus_strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT, direction); |
410 | spin_unlock_irqrestore(&iommu->lock, flags); | 433 | spin_unlock_irqrestore(&iommu->lock, flags); |
411 | } | 434 | } |
412 | 435 | ||
@@ -569,7 +592,7 @@ void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int | |||
569 | iommu = sdev->bus->iommu; | 592 | iommu = sdev->bus->iommu; |
570 | spin_lock_irqsave(&iommu->lock, flags); | 593 | spin_lock_irqsave(&iommu->lock, flags); |
571 | free_streaming_cluster(iommu, dvma_base, size >> IO_PAGE_SHIFT); | 594 | free_streaming_cluster(iommu, dvma_base, size >> IO_PAGE_SHIFT); |
572 | strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT); | 595 | sbus_strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT, direction); |
573 | spin_unlock_irqrestore(&iommu->lock, flags); | 596 | spin_unlock_irqrestore(&iommu->lock, flags); |
574 | } | 597 | } |
575 | 598 | ||
@@ -581,7 +604,7 @@ void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t base, size_t | |||
581 | size = (IO_PAGE_ALIGN(base + size) - (base & IO_PAGE_MASK)); | 604 | size = (IO_PAGE_ALIGN(base + size) - (base & IO_PAGE_MASK)); |
582 | 605 | ||
583 | spin_lock_irqsave(&iommu->lock, flags); | 606 | spin_lock_irqsave(&iommu->lock, flags); |
584 | strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT); | 607 | sbus_strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT, direction); |
585 | spin_unlock_irqrestore(&iommu->lock, flags); | 608 | spin_unlock_irqrestore(&iommu->lock, flags); |
586 | } | 609 | } |
587 | 610 | ||
@@ -605,7 +628,7 @@ void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sg, int | |||
605 | size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - base; | 628 | size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - base; |
606 | 629 | ||
607 | spin_lock_irqsave(&iommu->lock, flags); | 630 | spin_lock_irqsave(&iommu->lock, flags); |
608 | strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT); | 631 | sbus_strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT, direction); |
609 | spin_unlock_irqrestore(&iommu->lock, flags); | 632 | spin_unlock_irqrestore(&iommu->lock, flags); |
610 | } | 633 | } |
611 | 634 | ||
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index 12c3d84b7460..b7e6a91952b2 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c | |||
@@ -383,6 +383,17 @@ static void __init process_switch(char c) | |||
383 | /* Use PROM debug console. */ | 383 | /* Use PROM debug console. */ |
384 | register_console(&prom_debug_console); | 384 | register_console(&prom_debug_console); |
385 | break; | 385 | break; |
386 | case 'P': | ||
387 | /* Force UltraSPARC-III P-Cache on. */ | ||
388 | if (tlb_type != cheetah) { | ||
389 | printk("BOOT: Ignoring P-Cache force option.\n"); | ||
390 | break; | ||
391 | } | ||
392 | cheetah_pcache_forced_on = 1; | ||
393 | add_taint(TAINT_MACHINE_CHECK); | ||
394 | cheetah_enable_pcache(); | ||
395 | break; | ||
396 | |||
386 | default: | 397 | default: |
387 | printk("Unknown boot switch (-%c)\n", c); | 398 | printk("Unknown boot switch (-%c)\n", c); |
388 | break; | 399 | break; |
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 6dff06a44e76..e5b9c7a27789 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c | |||
@@ -123,6 +123,9 @@ void __init smp_callin(void) | |||
123 | 123 | ||
124 | smp_setup_percpu_timer(); | 124 | smp_setup_percpu_timer(); |
125 | 125 | ||
126 | if (cheetah_pcache_forced_on) | ||
127 | cheetah_enable_pcache(); | ||
128 | |||
126 | local_irq_enable(); | 129 | local_irq_enable(); |
127 | 130 | ||
128 | calibrate_delay(); | 131 | calibrate_delay(); |
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index cad5a1122800..e78cc53594fa 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c | |||
@@ -278,7 +278,7 @@ EXPORT_SYMBOL(verify_compat_iovec); | |||
278 | 278 | ||
279 | EXPORT_SYMBOL(dump_thread); | 279 | EXPORT_SYMBOL(dump_thread); |
280 | EXPORT_SYMBOL(dump_fpu); | 280 | EXPORT_SYMBOL(dump_fpu); |
281 | EXPORT_SYMBOL(__pte_alloc_one_kernel); | 281 | EXPORT_SYMBOL(pte_alloc_one_kernel); |
282 | #ifndef CONFIG_SMP | 282 | #ifndef CONFIG_SMP |
283 | EXPORT_SYMBOL(pgt_quicklists); | 283 | EXPORT_SYMBOL(pgt_quicklists); |
284 | #endif | 284 | #endif |
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index 56b203a2af69..a9f4596d7c2b 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c | |||
@@ -421,6 +421,25 @@ asmlinkage void cee_log(unsigned long ce_status, | |||
421 | } | 421 | } |
422 | } | 422 | } |
423 | 423 | ||
424 | int cheetah_pcache_forced_on; | ||
425 | |||
426 | void cheetah_enable_pcache(void) | ||
427 | { | ||
428 | unsigned long dcr; | ||
429 | |||
430 | printk("CHEETAH: Enabling P-Cache on cpu %d.\n", | ||
431 | smp_processor_id()); | ||
432 | |||
433 | __asm__ __volatile__("ldxa [%%g0] %1, %0" | ||
434 | : "=r" (dcr) | ||
435 | : "i" (ASI_DCU_CONTROL_REG)); | ||
436 | dcr |= (DCU_PE | DCU_HPE | DCU_SPE | DCU_SL); | ||
437 | __asm__ __volatile__("stxa %0, [%%g0] %1\n\t" | ||
438 | "membar #Sync" | ||
439 | : /* no outputs */ | ||
440 | : "r" (dcr), "i" (ASI_DCU_CONTROL_REG)); | ||
441 | } | ||
442 | |||
424 | /* Cheetah error trap handling. */ | 443 | /* Cheetah error trap handling. */ |
425 | static unsigned long ecache_flush_physbase; | 444 | static unsigned long ecache_flush_physbase; |
426 | static unsigned long ecache_flush_linesize; | 445 | static unsigned long ecache_flush_linesize; |
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index db6fa77b4dab..9c5222075da9 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c | |||
@@ -1114,7 +1114,7 @@ struct pgtable_cache_struct pgt_quicklists; | |||
1114 | #else | 1114 | #else |
1115 | #define DC_ALIAS_SHIFT 0 | 1115 | #define DC_ALIAS_SHIFT 0 |
1116 | #endif | 1116 | #endif |
1117 | pte_t *__pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | 1117 | pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) |
1118 | { | 1118 | { |
1119 | struct page *page; | 1119 | struct page *page; |
1120 | unsigned long color; | 1120 | unsigned long color; |
diff --git a/arch/um/Kconfig.debug b/arch/um/Kconfig.debug index b89989de364d..bd41e4286d0d 100644 --- a/arch/um/Kconfig.debug +++ b/arch/um/Kconfig.debug | |||
@@ -2,10 +2,6 @@ menu "Kernel hacking" | |||
2 | 2 | ||
3 | source "lib/Kconfig.debug" | 3 | source "lib/Kconfig.debug" |
4 | 4 | ||
5 | config FRAME_POINTER | ||
6 | bool | ||
7 | default y if DEBUG_INFO | ||
8 | |||
9 | config PT_PROXY | 5 | config PT_PROXY |
10 | bool "Enable ptrace proxy" | 6 | bool "Enable ptrace proxy" |
11 | depends on XTERM_CHAN && DEBUG_INFO && MODE_TT | 7 | depends on XTERM_CHAN && DEBUG_INFO && MODE_TT |
diff --git a/arch/um/Kconfig_char b/arch/um/Kconfig_char index 3e50fdb67626..62d87b71179b 100644 --- a/arch/um/Kconfig_char +++ b/arch/um/Kconfig_char | |||
@@ -204,5 +204,11 @@ config UML_RANDOM | |||
204 | http://sourceforge.net/projects/gkernel/). rngd periodically reads | 204 | http://sourceforge.net/projects/gkernel/). rngd periodically reads |
205 | /dev/hwrng and injects the entropy into /dev/random. | 205 | /dev/hwrng and injects the entropy into /dev/random. |
206 | 206 | ||
207 | config MMAPPER | ||
208 | tristate "iomem emulation driver" | ||
209 | help | ||
210 | This driver allows a host file to be used as emulated IO memory inside | ||
211 | UML. | ||
212 | |||
207 | endmenu | 213 | endmenu |
208 | 214 | ||
diff --git a/arch/um/Kconfig_x86_64 b/arch/um/Kconfig_x86_64 index fd8d7e8982b1..f162f50f0b17 100644 --- a/arch/um/Kconfig_x86_64 +++ b/arch/um/Kconfig_x86_64 | |||
@@ -6,6 +6,10 @@ config 64BIT | |||
6 | bool | 6 | bool |
7 | default y | 7 | default y |
8 | 8 | ||
9 | config TOP_ADDR | ||
10 | hex | ||
11 | default 0x80000000 | ||
12 | |||
9 | config 3_LEVEL_PGTABLES | 13 | config 3_LEVEL_PGTABLES |
10 | bool | 14 | bool |
11 | default y | 15 | default y |
diff --git a/arch/um/Makefile b/arch/um/Makefile index 97bca6b5ca95..f2a0c40a9204 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile | |||
@@ -17,7 +17,7 @@ core-y += $(ARCH_DIR)/kernel/ \ | |||
17 | 17 | ||
18 | # Have to precede the include because the included Makefiles reference them. | 18 | # Have to precede the include because the included Makefiles reference them. |
19 | SYMLINK_HEADERS := archparam.h system.h sigcontext.h processor.h ptrace.h \ | 19 | SYMLINK_HEADERS := archparam.h system.h sigcontext.h processor.h ptrace.h \ |
20 | arch-signal.h module.h vm-flags.h | 20 | module.h vm-flags.h elf.h |
21 | SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header)) | 21 | SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header)) |
22 | 22 | ||
23 | # XXX: The "os" symlink is only used by arch/um/include/os.h, which includes | 23 | # XXX: The "os" symlink is only used by arch/um/include/os.h, which includes |
@@ -44,6 +44,11 @@ ifneq ($(MAKEFILES-INCL),) | |||
44 | endif | 44 | endif |
45 | 45 | ||
46 | ARCH_INCLUDE := -I$(ARCH_DIR)/include | 46 | ARCH_INCLUDE := -I$(ARCH_DIR)/include |
47 | ifneq ($(KBUILD_SRC),) | ||
48 | ARCH_INCLUDE += -I$(ARCH_DIR)/include2 | ||
49 | ARCH_INCLUDE += -I$(srctree)/$(ARCH_DIR)/include | ||
50 | MRPROPER_DIRS += $(ARCH_DIR)/include2 | ||
51 | endif | ||
47 | SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH) | 52 | SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH) |
48 | 53 | ||
49 | include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) | 54 | include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) |
@@ -94,17 +99,18 @@ define archhelp | |||
94 | echo ' find in the kernel root.' | 99 | echo ' find in the kernel root.' |
95 | endef | 100 | endef |
96 | 101 | ||
102 | ifneq ($(KBUILD_SRC),) | ||
103 | $(shell mkdir -p $(ARCH_DIR) && ln -fsn $(srctree)/$(ARCH_DIR)/Kconfig_$(SUBARCH) $(ARCH_DIR)/Kconfig_arch) | ||
104 | CLEAN_FILES += $(ARCH_DIR)/Kconfig_arch | ||
105 | else | ||
97 | $(shell cd $(ARCH_DIR) && ln -sf Kconfig_$(SUBARCH) Kconfig_arch) | 106 | $(shell cd $(ARCH_DIR) && ln -sf Kconfig_$(SUBARCH) Kconfig_arch) |
107 | endif | ||
98 | 108 | ||
99 | prepare: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS) \ | 109 | prepare: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS) |
100 | $(ARCH_DIR)/kernel/vmlinux.lds.S | ||
101 | 110 | ||
102 | LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static | 111 | LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static |
103 | LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib | 112 | LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib |
104 | 113 | ||
105 | LD_SCRIPT-$(CONFIG_LD_SCRIPT_STATIC) := uml.lds.S | ||
106 | LD_SCRIPT-$(CONFIG_LD_SCRIPT_DYN) := dyn.lds.S | ||
107 | |||
108 | CPP_MODE-$(CONFIG_MODE_TT) := -DMODE_TT | 114 | CPP_MODE-$(CONFIG_MODE_TT) := -DMODE_TT |
109 | CONFIG_KERNEL_STACK_ORDER ?= 2 | 115 | CONFIG_KERNEL_STACK_ORDER ?= 2 |
110 | STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] ) | 116 | STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] ) |
@@ -126,7 +132,7 @@ define cmd_vmlinux__ | |||
126 | $(CC) $(CFLAGS_vmlinux) -o $@ \ | 132 | $(CC) $(CFLAGS_vmlinux) -o $@ \ |
127 | -Wl,-T,$(vmlinux-lds) $(vmlinux-init) \ | 133 | -Wl,-T,$(vmlinux-lds) $(vmlinux-init) \ |
128 | -Wl,--start-group $(vmlinux-main) -Wl,--end-group \ | 134 | -Wl,--start-group $(vmlinux-main) -Wl,--end-group \ |
129 | -L/usr/lib -lutil \ | 135 | -lutil \ |
130 | $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) \ | 136 | $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) \ |
131 | FORCE ,$^) ; rm -f linux | 137 | FORCE ,$^) ; rm -f linux |
132 | endef | 138 | endef |
@@ -145,31 +151,42 @@ archclean: | |||
145 | @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \ | 151 | @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \ |
146 | -o -name '*.gcov' \) -type f -print | xargs rm -f | 152 | -o -name '*.gcov' \) -type f -print | xargs rm -f |
147 | 153 | ||
148 | #We need to re-preprocess this when the symlink dest changes. | ||
149 | #So we touch it when needed. | ||
150 | $(ARCH_DIR)/kernel/vmlinux.lds.S: FORCE | ||
151 | $(Q)if [ "$(shell readlink $@)" != "$(LD_SCRIPT-y)" ]; then \ | ||
152 | echo ' SYMLINK $@'; \ | ||
153 | ln -sf $(LD_SCRIPT-y) $@; \ | ||
154 | touch $@; \ | ||
155 | fi; | ||
156 | |||
157 | $(SYMLINK_HEADERS): | 154 | $(SYMLINK_HEADERS): |
158 | @echo ' SYMLINK $@' | 155 | @echo ' SYMLINK $@' |
156 | ifneq ($(KBUILD_SRC),) | ||
157 | ln -fsn $(srctree)/include/asm-um/$(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $@ | ||
158 | else | ||
159 | $(Q)cd $(TOPDIR)/$(dir $@) ; \ | 159 | $(Q)cd $(TOPDIR)/$(dir $@) ; \ |
160 | ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@) | 160 | ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@) |
161 | endif | ||
161 | 162 | ||
162 | include/asm-um/arch: | 163 | include/asm-um/arch: |
163 | @echo ' SYMLINK $@' | 164 | @echo ' SYMLINK $@' |
165 | ifneq ($(KBUILD_SRC),) | ||
166 | $(Q)mkdir -p include/asm-um | ||
167 | $(Q)ln -fsn $(srctree)/include/asm-$(SUBARCH) include/asm-um/arch | ||
168 | else | ||
164 | $(Q)cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch | 169 | $(Q)cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch |
170 | endif | ||
165 | 171 | ||
166 | $(ARCH_DIR)/include/sysdep: | 172 | $(ARCH_DIR)/include/sysdep: |
167 | @echo ' SYMLINK $@' | 173 | @echo ' SYMLINK $@' |
174 | ifneq ($(KBUILD_SRC),) | ||
175 | $(Q)mkdir -p $(ARCH_DIR)/include | ||
176 | $(Q)mkdir -p $(ARCH_DIR)/include2 | ||
177 | $(Q)ln -fsn sysdep-$(SUBARCH) $(ARCH_DIR)/include/sysdep | ||
178 | $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/include/sysdep-$(SUBARCH) $(ARCH_DIR)/include2/sysdep | ||
179 | else | ||
168 | $(Q)cd $(ARCH_DIR)/include && ln -sf sysdep-$(SUBARCH) sysdep | 180 | $(Q)cd $(ARCH_DIR)/include && ln -sf sysdep-$(SUBARCH) sysdep |
181 | endif | ||
169 | 182 | ||
170 | $(ARCH_DIR)/os: | 183 | $(ARCH_DIR)/os: |
171 | @echo ' SYMLINK $@' | 184 | @echo ' SYMLINK $@' |
185 | ifneq ($(KBUILD_SRC),) | ||
186 | $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/os-$(OS) $(ARCH_DIR)/os | ||
187 | else | ||
172 | $(Q)cd $(ARCH_DIR) && ln -sf os-$(OS) os | 188 | $(Q)cd $(ARCH_DIR) && ln -sf os-$(OS) os |
189 | endif | ||
173 | 190 | ||
174 | # Generated files | 191 | # Generated files |
175 | define filechk_umlconfig | 192 | define filechk_umlconfig |
@@ -179,10 +196,31 @@ endef | |||
179 | $(ARCH_DIR)/include/uml-config.h : include/linux/autoconf.h | 196 | $(ARCH_DIR)/include/uml-config.h : include/linux/autoconf.h |
180 | $(call filechk,umlconfig) | 197 | $(call filechk,umlconfig) |
181 | 198 | ||
199 | $(ARCH_DIR)/user-offsets.s: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.c | ||
200 | $(CC) $(USER_CFLAGS) -S -o $@ $< | ||
201 | |||
202 | $(ARCH_DIR)/user-offsets.h: $(ARCH_DIR)/user-offsets.s | ||
203 | $(call filechk,gen-asm-offsets) | ||
204 | |||
205 | CLEAN_FILES += $(ARCH_DIR)/user-offsets.s $(ARCH_DIR)/user-offsets.h | ||
206 | |||
207 | $(ARCH_DIR)/kernel-offsets.s: $(ARCH_DIR)/sys-$(SUBARCH)/kernel-offsets.c \ | ||
208 | $(ARCH_SYMLINKS) \ | ||
209 | $(SYS_DIR)/sc.h \ | ||
210 | include/asm include/linux/version.h \ | ||
211 | include/config/MARKER \ | ||
212 | $(ARCH_DIR)/include/user_constants.h | ||
213 | $(CC) $(CFLAGS) $(NOSTDINC_FLAGS) $(CPPFLAGS) -S -o $@ $< | ||
214 | |||
215 | $(ARCH_DIR)/kernel-offsets.h: $(ARCH_DIR)/kernel-offsets.s | ||
216 | $(call filechk,gen-asm-offsets) | ||
217 | |||
218 | CLEAN_FILES += $(ARCH_DIR)/kernel-offsets.s $(ARCH_DIR)/kernel-offsets.h | ||
219 | |||
182 | $(ARCH_DIR)/include/task.h: $(ARCH_DIR)/util/mk_task | 220 | $(ARCH_DIR)/include/task.h: $(ARCH_DIR)/util/mk_task |
183 | $(call filechk,gen_header) | 221 | $(call filechk,gen_header) |
184 | 222 | ||
185 | $(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/os/util/mk_user_constants | 223 | $(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/os-$(OS)/util/mk_user_constants |
186 | $(call filechk,gen_header) | 224 | $(call filechk,gen_header) |
187 | 225 | ||
188 | $(ARCH_DIR)/include/kern_constants.h: $(ARCH_DIR)/util/mk_constants | 226 | $(ARCH_DIR)/include/kern_constants.h: $(ARCH_DIR)/util/mk_constants |
@@ -191,20 +229,20 @@ $(ARCH_DIR)/include/kern_constants.h: $(ARCH_DIR)/util/mk_constants | |||
191 | $(ARCH_DIR)/include/skas_ptregs.h: $(ARCH_DIR)/kernel/skas/util/mk_ptregs | 229 | $(ARCH_DIR)/include/skas_ptregs.h: $(ARCH_DIR)/kernel/skas/util/mk_ptregs |
192 | $(call filechk,gen_header) | 230 | $(call filechk,gen_header) |
193 | 231 | ||
194 | $(ARCH_DIR)/os/util/mk_user_constants: $(ARCH_DIR)/os/util FORCE ; | 232 | $(ARCH_DIR)/os-$(OS)/util/mk_user_constants: $(ARCH_DIR)/os-$(OS)/util FORCE ; |
195 | 233 | ||
196 | $(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants: $(ARCH_DIR)/include/user_constants.h $(ARCH_DIR)/util \ | 234 | $(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants: $(ARCH_DIR)/include/user_constants.h $(ARCH_DIR)/util \ |
197 | FORCE ; | 235 | FORCE ; |
198 | 236 | ||
199 | $(ARCH_DIR)/kernel/skas/util/mk_ptregs: $(ARCH_DIR)/kernel/skas/util FORCE ; | 237 | $(ARCH_DIR)/kernel/skas/util/mk_ptregs: $(ARCH_DIR)/kernel/skas/util FORCE ; |
200 | 238 | ||
201 | $(ARCH_DIR)/util: scripts_basic $(SYS_DIR)/sc.h FORCE | 239 | $(ARCH_DIR)/util: scripts_basic $(SYS_DIR)/sc.h $(ARCH_DIR)/kernel-offsets.h FORCE |
202 | $(Q)$(MAKE) $(build)=$@ | 240 | $(Q)$(MAKE) $(build)=$@ |
203 | 241 | ||
204 | $(ARCH_DIR)/kernel/skas/util: scripts_basic FORCE | 242 | $(ARCH_DIR)/kernel/skas/util: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE |
205 | $(Q)$(MAKE) $(build)=$@ | 243 | $(Q)$(MAKE) $(build)=$@ |
206 | 244 | ||
207 | $(ARCH_DIR)/os/util: scripts_basic FORCE | 245 | $(ARCH_DIR)/os-$(OS)/util: scripts_basic FORCE |
208 | $(Q)$(MAKE) $(build)=$@ | 246 | $(Q)$(MAKE) $(build)=$@ |
209 | 247 | ||
210 | export SUBARCH USER_CFLAGS OS | 248 | export SUBARCH USER_CFLAGS OS |
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386 index f9e3c0f06541..29e182d5a83a 100644 --- a/arch/um/Makefile-i386 +++ b/arch/um/Makefile-i386 | |||
@@ -32,10 +32,10 @@ $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc | |||
32 | $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread | 32 | $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread |
33 | $(call filechk,gen_header) | 33 | $(call filechk,gen_header) |
34 | 34 | ||
35 | $(SYS_UTIL_DIR)/mk_sc: scripts_basic FORCE | 35 | $(SYS_UTIL_DIR)/mk_sc: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE |
36 | $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ | 36 | $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ |
37 | 37 | ||
38 | $(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE | 38 | $(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_DIR)/kernel-offsets.h FORCE |
39 | $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ | 39 | $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ |
40 | 40 | ||
41 | $(SYS_UTIL_DIR): scripts_basic include/asm FORCE | 41 | $(SYS_UTIL_DIR): scripts_basic include/asm FORCE |
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64 index a77971133e91..32144562c279 100644 --- a/arch/um/Makefile-x86_64 +++ b/arch/um/Makefile-x86_64 | |||
@@ -23,10 +23,10 @@ $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc | |||
23 | $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread | 23 | $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread |
24 | $(call filechk,gen_header) | 24 | $(call filechk,gen_header) |
25 | 25 | ||
26 | $(SYS_UTIL_DIR)/mk_sc: scripts_basic FORCE | 26 | $(SYS_UTIL_DIR)/mk_sc: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE |
27 | $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ | 27 | $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ |
28 | 28 | ||
29 | $(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE | 29 | $(SYS_UTIL_DIR)/mk_thread: scripts_basic $(GEN_HEADERS) $(ARCH_DIR)/kernel-offsets.h FORCE |
30 | $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ | 30 | $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ |
31 | 31 | ||
32 | CLEAN_FILES += $(SYS_HEADERS) | 32 | CLEAN_FILES += $(SYS_HEADERS) |
diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile index 323f72c64cd2..b2de9916c32c 100644 --- a/arch/um/drivers/Makefile +++ b/arch/um/drivers/Makefile | |||
@@ -22,8 +22,8 @@ obj-y := stdio_console.o fd.o chan_kern.o chan_user.o line.o | |||
22 | obj-$(CONFIG_SSL) += ssl.o | 22 | obj-$(CONFIG_SSL) += ssl.o |
23 | obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o | 23 | obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o |
24 | 24 | ||
25 | obj-$(CONFIG_UML_NET_SLIP) += slip.o | 25 | obj-$(CONFIG_UML_NET_SLIP) += slip.o slip_common.o |
26 | obj-$(CONFIG_UML_NET_SLIRP) += slirp.o | 26 | obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o |
27 | obj-$(CONFIG_UML_NET_DAEMON) += daemon.o | 27 | obj-$(CONFIG_UML_NET_DAEMON) += daemon.o |
28 | obj-$(CONFIG_UML_NET_MCAST) += mcast.o | 28 | obj-$(CONFIG_UML_NET_MCAST) += mcast.o |
29 | #obj-$(CONFIG_UML_NET_PCAP) += pcap.o $(PCAP) | 29 | #obj-$(CONFIG_UML_NET_PCAP) += pcap.o $(PCAP) |
@@ -41,6 +41,6 @@ obj-$(CONFIG_UML_WATCHDOG) += harddog.o | |||
41 | obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o | 41 | obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o |
42 | obj-$(CONFIG_UML_RANDOM) += random.o | 42 | obj-$(CONFIG_UML_RANDOM) += random.o |
43 | 43 | ||
44 | USER_OBJS := fd.o null.o pty.o tty.o xterm.o | 44 | USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o |
45 | 45 | ||
46 | include arch/um/scripts/Makefile.rules | 46 | include arch/um/scripts/Makefile.rules |
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 0150038af795..14a12d6b3df6 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c | |||
@@ -20,9 +20,17 @@ | |||
20 | #include "os.h" | 20 | #include "os.h" |
21 | 21 | ||
22 | #ifdef CONFIG_NOCONFIG_CHAN | 22 | #ifdef CONFIG_NOCONFIG_CHAN |
23 | |||
24 | /* The printk's here are wrong because we are complaining that there is no | ||
25 | * output device, but printk is printing to that output device. The user will | ||
26 | * never see the error. printf would be better, except it can't run on a | ||
27 | * kernel stack because it will overflow it. | ||
28 | * Use printk for now since that will avoid crashing. | ||
29 | */ | ||
30 | |||
23 | static void *not_configged_init(char *str, int device, struct chan_opts *opts) | 31 | static void *not_configged_init(char *str, int device, struct chan_opts *opts) |
24 | { | 32 | { |
25 | printf(KERN_ERR "Using a channel type which is configured out of " | 33 | printk(KERN_ERR "Using a channel type which is configured out of " |
26 | "UML\n"); | 34 | "UML\n"); |
27 | return(NULL); | 35 | return(NULL); |
28 | } | 36 | } |
@@ -30,27 +38,27 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts) | |||
30 | static int not_configged_open(int input, int output, int primary, void *data, | 38 | static int not_configged_open(int input, int output, int primary, void *data, |
31 | char **dev_out) | 39 | char **dev_out) |
32 | { | 40 | { |
33 | printf(KERN_ERR "Using a channel type which is configured out of " | 41 | printk(KERN_ERR "Using a channel type which is configured out of " |
34 | "UML\n"); | 42 | "UML\n"); |
35 | return(-ENODEV); | 43 | return(-ENODEV); |
36 | } | 44 | } |
37 | 45 | ||
38 | static void not_configged_close(int fd, void *data) | 46 | static void not_configged_close(int fd, void *data) |
39 | { | 47 | { |
40 | printf(KERN_ERR "Using a channel type which is configured out of " | 48 | printk(KERN_ERR "Using a channel type which is configured out of " |
41 | "UML\n"); | 49 | "UML\n"); |
42 | } | 50 | } |
43 | 51 | ||
44 | static int not_configged_read(int fd, char *c_out, void *data) | 52 | static int not_configged_read(int fd, char *c_out, void *data) |
45 | { | 53 | { |
46 | printf(KERN_ERR "Using a channel type which is configured out of " | 54 | printk(KERN_ERR "Using a channel type which is configured out of " |
47 | "UML\n"); | 55 | "UML\n"); |
48 | return(-EIO); | 56 | return(-EIO); |
49 | } | 57 | } |
50 | 58 | ||
51 | static int not_configged_write(int fd, const char *buf, int len, void *data) | 59 | static int not_configged_write(int fd, const char *buf, int len, void *data) |
52 | { | 60 | { |
53 | printf(KERN_ERR "Using a channel type which is configured out of " | 61 | printk(KERN_ERR "Using a channel type which is configured out of " |
54 | "UML\n"); | 62 | "UML\n"); |
55 | return(-EIO); | 63 | return(-EIO); |
56 | } | 64 | } |
@@ -58,7 +66,7 @@ static int not_configged_write(int fd, const char *buf, int len, void *data) | |||
58 | static int not_configged_console_write(int fd, const char *buf, int len, | 66 | static int not_configged_console_write(int fd, const char *buf, int len, |
59 | void *data) | 67 | void *data) |
60 | { | 68 | { |
61 | printf(KERN_ERR "Using a channel type which is configured out of " | 69 | printk(KERN_ERR "Using a channel type which is configured out of " |
62 | "UML\n"); | 70 | "UML\n"); |
63 | return(-EIO); | 71 | return(-EIO); |
64 | } | 72 | } |
@@ -66,7 +74,7 @@ static int not_configged_console_write(int fd, const char *buf, int len, | |||
66 | static int not_configged_window_size(int fd, void *data, unsigned short *rows, | 74 | static int not_configged_window_size(int fd, void *data, unsigned short *rows, |
67 | unsigned short *cols) | 75 | unsigned short *cols) |
68 | { | 76 | { |
69 | printf(KERN_ERR "Using a channel type which is configured out of " | 77 | printk(KERN_ERR "Using a channel type which is configured out of " |
70 | "UML\n"); | 78 | "UML\n"); |
71 | return(-ENODEV); | 79 | return(-ENODEV); |
72 | } | 80 | } |
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 583b8e137c33..5d3768156c92 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c | |||
@@ -143,22 +143,22 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) | |||
143 | { | 143 | { |
144 | struct winch_data data; | 144 | struct winch_data data; |
145 | unsigned long stack; | 145 | unsigned long stack; |
146 | int fds[2], pid, n, err; | 146 | int fds[2], n, err; |
147 | char c; | 147 | char c; |
148 | 148 | ||
149 | err = os_pipe(fds, 1, 1); | 149 | err = os_pipe(fds, 1, 1); |
150 | if(err < 0){ | 150 | if(err < 0){ |
151 | printk("winch_tramp : os_pipe failed, err = %d\n", -err); | 151 | printk("winch_tramp : os_pipe failed, err = %d\n", -err); |
152 | return(err); | 152 | goto out; |
153 | } | 153 | } |
154 | 154 | ||
155 | data = ((struct winch_data) { .pty_fd = fd, | 155 | data = ((struct winch_data) { .pty_fd = fd, |
156 | .pipe_fd = fds[1], | 156 | .pipe_fd = fds[1], |
157 | .close_me = fds[0] } ); | 157 | .close_me = fds[0] } ); |
158 | pid = run_helper_thread(winch_thread, &data, 0, &stack, 0); | 158 | err = run_helper_thread(winch_thread, &data, 0, &stack, 0); |
159 | if(pid < 0){ | 159 | if(err < 0){ |
160 | printk("fork of winch_thread failed - errno = %d\n", errno); | 160 | printk("fork of winch_thread failed - errno = %d\n", errno); |
161 | return(pid); | 161 | goto out_close; |
162 | } | 162 | } |
163 | 163 | ||
164 | os_close_file(fds[1]); | 164 | os_close_file(fds[1]); |
@@ -168,14 +168,22 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) | |||
168 | printk("winch_tramp : failed to read synchronization byte\n"); | 168 | printk("winch_tramp : failed to read synchronization byte\n"); |
169 | printk("read failed, err = %d\n", -n); | 169 | printk("read failed, err = %d\n", -n); |
170 | printk("fd %d will not support SIGWINCH\n", fd); | 170 | printk("fd %d will not support SIGWINCH\n", fd); |
171 | *fd_out = -1; | 171 | err = -EINVAL; |
172 | goto out_close1; | ||
172 | } | 173 | } |
173 | return(pid); | 174 | return err ; |
175 | |||
176 | out_close: | ||
177 | os_close_file(fds[1]); | ||
178 | out_close1: | ||
179 | os_close_file(fds[0]); | ||
180 | out: | ||
181 | return err; | ||
174 | } | 182 | } |
175 | 183 | ||
176 | void register_winch(int fd, struct tty_struct *tty) | 184 | void register_winch(int fd, struct tty_struct *tty) |
177 | { | 185 | { |
178 | int pid, thread, thread_fd; | 186 | int pid, thread, thread_fd = -1; |
179 | int count; | 187 | int count; |
180 | char c = 1; | 188 | char c = 1; |
181 | 189 | ||
@@ -186,7 +194,7 @@ void register_winch(int fd, struct tty_struct *tty) | |||
186 | if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, | 194 | if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, |
187 | tty) && (pid == -1)){ | 195 | tty) && (pid == -1)){ |
188 | thread = winch_tramp(fd, tty, &thread_fd); | 196 | thread = winch_tramp(fd, tty, &thread_fd); |
189 | if(fd != -1){ | 197 | if(thread > 0){ |
190 | register_winch_irq(thread_fd, fd, thread, tty); | 198 | register_winch_irq(thread_fd, fd, thread, tty); |
191 | 199 | ||
192 | count = os_write_file(thread_fd, &c, sizeof(c)); | 200 | count = os_write_file(thread_fd, &c, sizeof(c)); |
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index d0f97127adf6..025d3be8aca4 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
@@ -462,12 +462,15 @@ out: | |||
462 | return err; | 462 | return err; |
463 | } | 463 | } |
464 | 464 | ||
465 | static void unregister_winch(struct tty_struct *tty); | ||
466 | |||
465 | void line_close(struct tty_struct *tty, struct file * filp) | 467 | void line_close(struct tty_struct *tty, struct file * filp) |
466 | { | 468 | { |
467 | struct line *line = tty->driver_data; | 469 | struct line *line = tty->driver_data; |
468 | 470 | ||
469 | /* XXX: I assume this should be called in process context, not with interrupt | 471 | /* XXX: I assume this should be called in process context, not with |
470 | * disabled!*/ | 472 | * interrupts disabled! |
473 | */ | ||
471 | spin_lock_irq(&line->lock); | 474 | spin_lock_irq(&line->lock); |
472 | 475 | ||
473 | /* We ignore the error anyway! */ | 476 | /* We ignore the error anyway! */ |
@@ -478,6 +481,12 @@ void line_close(struct tty_struct *tty, struct file * filp) | |||
478 | line_disable(tty, -1); | 481 | line_disable(tty, -1); |
479 | tty->driver_data = NULL; | 482 | tty->driver_data = NULL; |
480 | } | 483 | } |
484 | |||
485 | if((line->count == 0) && line->sigio){ | ||
486 | unregister_winch(tty); | ||
487 | line->sigio = 0; | ||
488 | } | ||
489 | |||
481 | spin_unlock_irq(&line->lock); | 490 | spin_unlock_irq(&line->lock); |
482 | } | 491 | } |
483 | 492 | ||
@@ -729,6 +738,34 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty) | |||
729 | up(&winch_handler_sem); | 738 | up(&winch_handler_sem); |
730 | } | 739 | } |
731 | 740 | ||
741 | static void unregister_winch(struct tty_struct *tty) | ||
742 | { | ||
743 | struct list_head *ele; | ||
744 | struct winch *winch, *found = NULL; | ||
745 | |||
746 | down(&winch_handler_sem); | ||
747 | list_for_each(ele, &winch_handlers){ | ||
748 | winch = list_entry(ele, struct winch, list); | ||
749 | if(winch->tty == tty){ | ||
750 | found = winch; | ||
751 | break; | ||
752 | } | ||
753 | } | ||
754 | |||
755 | if(found == NULL) | ||
756 | goto out; | ||
757 | |||
758 | if(winch->pid != -1) | ||
759 | os_kill_process(winch->pid, 1); | ||
760 | |||
761 | free_irq_by_irq_and_dev(WINCH_IRQ, winch); | ||
762 | free_irq(WINCH_IRQ, winch); | ||
763 | list_del(&winch->list); | ||
764 | kfree(winch); | ||
765 | out: | ||
766 | up(&winch_handler_sem); | ||
767 | } | ||
768 | |||
732 | static void winch_cleanup(void) | 769 | static void winch_cleanup(void) |
733 | { | 770 | { |
734 | struct list_head *ele; | 771 | struct list_head *ele; |
diff --git a/arch/um/drivers/mcast_kern.c b/arch/um/drivers/mcast_kern.c index faf714e87b5b..217438cdef33 100644 --- a/arch/um/drivers/mcast_kern.c +++ b/arch/um/drivers/mcast_kern.c | |||
@@ -73,7 +73,6 @@ int mcast_setup(char *str, char **mac_out, void *data) | |||
73 | struct mcast_init *init = data; | 73 | struct mcast_init *init = data; |
74 | char *port_str = NULL, *ttl_str = NULL, *remain; | 74 | char *port_str = NULL, *ttl_str = NULL, *remain; |
75 | char *last; | 75 | char *last; |
76 | int n; | ||
77 | 76 | ||
78 | *init = ((struct mcast_init) | 77 | *init = ((struct mcast_init) |
79 | { .addr = "239.192.168.1", | 78 | { .addr = "239.192.168.1", |
@@ -89,13 +88,12 @@ int mcast_setup(char *str, char **mac_out, void *data) | |||
89 | } | 88 | } |
90 | 89 | ||
91 | if(port_str != NULL){ | 90 | if(port_str != NULL){ |
92 | n = simple_strtoul(port_str, &last, 10); | 91 | init->port = simple_strtoul(port_str, &last, 10); |
93 | if((*last != '\0') || (last == port_str)){ | 92 | if((*last != '\0') || (last == port_str)){ |
94 | printk(KERN_ERR "mcast_setup - Bad port : '%s'\n", | 93 | printk(KERN_ERR "mcast_setup - Bad port : '%s'\n", |
95 | port_str); | 94 | port_str); |
96 | return(0); | 95 | return(0); |
97 | } | 96 | } |
98 | init->port = htons(n); | ||
99 | } | 97 | } |
100 | 98 | ||
101 | if(ttl_str != NULL){ | 99 | if(ttl_str != NULL){ |
diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c index 0fe1d9fa9139..7a0d115b29d0 100644 --- a/arch/um/drivers/mcast_user.c +++ b/arch/um/drivers/mcast_user.c | |||
@@ -38,7 +38,7 @@ static struct sockaddr_in *new_addr(char *addr, unsigned short port) | |||
38 | } | 38 | } |
39 | sin->sin_family = AF_INET; | 39 | sin->sin_family = AF_INET; |
40 | sin->sin_addr.s_addr = in_aton(addr); | 40 | sin->sin_addr.s_addr = in_aton(addr); |
41 | sin->sin_port = port; | 41 | sin->sin_port = htons(port); |
42 | return(sin); | 42 | return(sin); |
43 | } | 43 | } |
44 | 44 | ||
@@ -55,28 +55,25 @@ static int mcast_open(void *data) | |||
55 | struct mcast_data *pri = data; | 55 | struct mcast_data *pri = data; |
56 | struct sockaddr_in *sin = pri->mcast_addr; | 56 | struct sockaddr_in *sin = pri->mcast_addr; |
57 | struct ip_mreq mreq; | 57 | struct ip_mreq mreq; |
58 | int fd, yes = 1; | 58 | int fd = -EINVAL, yes = 1, err = -EINVAL;; |
59 | 59 | ||
60 | 60 | ||
61 | if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0)) { | 61 | if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0)) |
62 | fd = -EINVAL; | ||
63 | goto out; | 62 | goto out; |
64 | } | ||
65 | 63 | ||
66 | fd = socket(AF_INET, SOCK_DGRAM, 0); | 64 | fd = socket(AF_INET, SOCK_DGRAM, 0); |
65 | |||
67 | if (fd < 0){ | 66 | if (fd < 0){ |
68 | printk("mcast_open : data socket failed, errno = %d\n", | 67 | printk("mcast_open : data socket failed, errno = %d\n", |
69 | errno); | 68 | errno); |
70 | fd = -ENOMEM; | 69 | fd = -errno; |
71 | goto out; | 70 | goto out; |
72 | } | 71 | } |
73 | 72 | ||
74 | if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) { | 73 | if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) { |
75 | printk("mcast_open: SO_REUSEADDR failed, errno = %d\n", | 74 | printk("mcast_open: SO_REUSEADDR failed, errno = %d\n", |
76 | errno); | 75 | errno); |
77 | os_close_file(fd); | 76 | goto out_close; |
78 | fd = -EINVAL; | ||
79 | goto out; | ||
80 | } | 77 | } |
81 | 78 | ||
82 | /* set ttl according to config */ | 79 | /* set ttl according to config */ |
@@ -84,26 +81,20 @@ static int mcast_open(void *data) | |||
84 | sizeof(pri->ttl)) < 0) { | 81 | sizeof(pri->ttl)) < 0) { |
85 | printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n", | 82 | printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n", |
86 | errno); | 83 | errno); |
87 | os_close_file(fd); | 84 | goto out_close; |
88 | fd = -EINVAL; | ||
89 | goto out; | ||
90 | } | 85 | } |
91 | 86 | ||
92 | /* set LOOP, so data does get fed back to local sockets */ | 87 | /* set LOOP, so data does get fed back to local sockets */ |
93 | if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) { | 88 | if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) { |
94 | printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n", | 89 | printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n", |
95 | errno); | 90 | errno); |
96 | os_close_file(fd); | 91 | goto out_close; |
97 | fd = -EINVAL; | ||
98 | goto out; | ||
99 | } | 92 | } |
100 | 93 | ||
101 | /* bind socket to mcast address */ | 94 | /* bind socket to mcast address */ |
102 | if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) { | 95 | if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) { |
103 | printk("mcast_open : data bind failed, errno = %d\n", errno); | 96 | printk("mcast_open : data bind failed, errno = %d\n", errno); |
104 | os_close_file(fd); | 97 | goto out_close; |
105 | fd = -EINVAL; | ||
106 | goto out; | ||
107 | } | 98 | } |
108 | 99 | ||
109 | /* subscribe to the multicast group */ | 100 | /* subscribe to the multicast group */ |
@@ -117,12 +108,15 @@ static int mcast_open(void *data) | |||
117 | "interface on the host.\n"); | 108 | "interface on the host.\n"); |
118 | printk("eth0 should be configured in order to use the " | 109 | printk("eth0 should be configured in order to use the " |
119 | "multicast transport.\n"); | 110 | "multicast transport.\n"); |
120 | os_close_file(fd); | 111 | goto out_close; |
121 | fd = -EINVAL; | ||
122 | } | 112 | } |
123 | 113 | ||
124 | out: | 114 | out: |
125 | return(fd); | 115 | return fd; |
116 | |||
117 | out_close: | ||
118 | os_close_file(fd); | ||
119 | return err; | ||
126 | } | 120 | } |
127 | 121 | ||
128 | static void mcast_close(int fd, void *data) | 122 | static void mcast_close(int fd, void *data) |
@@ -164,14 +158,3 @@ struct net_user_info mcast_user_info = { | |||
164 | .delete_address = NULL, | 158 | .delete_address = NULL, |
165 | .max_packet = MAX_PACKET - ETH_HEADER_OTHER | 159 | .max_packet = MAX_PACKET - ETH_HEADER_OTHER |
166 | }; | 160 | }; |
167 | |||
168 | /* | ||
169 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
170 | * Emacs will notice this stuff at the end of the file and automatically | ||
171 | * adjust the settings for this buffer only. This must remain at the end | ||
172 | * of the file. | ||
173 | * --------------------------------------------------------------------------- | ||
174 | * Local variables: | ||
175 | * c-file-style: "linux" | ||
176 | * End: | ||
177 | */ | ||
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c index a63231dffe05..a37a5ac13c22 100644 --- a/arch/um/drivers/mmapper_kern.c +++ b/arch/um/drivers/mmapper_kern.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/smp_lock.h> | 20 | #include <linux/smp_lock.h> |
21 | #include <linux/miscdevice.h> | ||
21 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
22 | #include <asm/irq.h> | 23 | #include <asm/irq.h> |
23 | #include <asm/pgtable.h> | 24 | #include <asm/pgtable.h> |
@@ -117,24 +118,39 @@ static struct file_operations mmapper_fops = { | |||
117 | .release = mmapper_release, | 118 | .release = mmapper_release, |
118 | }; | 119 | }; |
119 | 120 | ||
121 | static struct miscdevice mmapper_dev = { | ||
122 | .minor = MISC_DYNAMIC_MINOR, | ||
123 | .name = "mmapper", | ||
124 | .fops = &mmapper_fops | ||
125 | }; | ||
126 | |||
120 | static int __init mmapper_init(void) | 127 | static int __init mmapper_init(void) |
121 | { | 128 | { |
129 | int err; | ||
130 | |||
122 | printk(KERN_INFO "Mapper v0.1\n"); | 131 | printk(KERN_INFO "Mapper v0.1\n"); |
123 | 132 | ||
124 | v_buf = (char *) find_iomem("mmapper", &mmapper_size); | 133 | v_buf = (char *) find_iomem("mmapper", &mmapper_size); |
125 | if(mmapper_size == 0){ | 134 | if(mmapper_size == 0){ |
126 | printk(KERN_ERR "mmapper_init - find_iomem failed\n"); | 135 | printk(KERN_ERR "mmapper_init - find_iomem failed\n"); |
127 | return(0); | 136 | goto out; |
128 | } | 137 | } |
129 | 138 | ||
130 | p_buf = __pa(v_buf); | 139 | err = misc_register(&mmapper_dev); |
140 | if(err){ | ||
141 | printk(KERN_ERR "mmapper - misc_register failed, err = %d\n", | ||
142 | err); | ||
143 | goto out; | ||
144 | } | ||
131 | 145 | ||
132 | devfs_mk_cdev(MKDEV(30, 0), S_IFCHR|S_IRUGO|S_IWUGO, "mmapper"); | 146 | p_buf = __pa(v_buf); |
133 | return(0); | 147 | out: |
148 | return 0; | ||
134 | } | 149 | } |
135 | 150 | ||
136 | static void mmapper_exit(void) | 151 | static void mmapper_exit(void) |
137 | { | 152 | { |
153 | misc_deregister(&mmapper_dev); | ||
138 | } | 154 | } |
139 | 155 | ||
140 | module_init(mmapper_init); | 156 | module_init(mmapper_init); |
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index 47229fe4a813..3730d4f12713 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c | |||
@@ -32,7 +32,7 @@ int tap_open_common(void *dev, char *gate_addr) | |||
32 | return(0); | 32 | return(0); |
33 | } | 33 | } |
34 | 34 | ||
35 | void tap_check_ips(char *gate_addr, char *eth_addr) | 35 | void tap_check_ips(char *gate_addr, unsigned char *eth_addr) |
36 | { | 36 | { |
37 | int tap_addr[4]; | 37 | int tap_addr[4]; |
38 | 38 | ||
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c index d43e9fab05a7..f9e22198e011 100644 --- a/arch/um/drivers/random.c +++ b/arch/um/drivers/random.c | |||
@@ -1,5 +1,10 @@ | |||
1 | /* Much of this ripped from hw_random.c */ | 1 | /* Copyright (C) 2005 Jeff Dike <jdike@addtoit.com> */ |
2 | 2 | /* Much of this ripped from drivers/char/hw_random.c, see there for other | |
3 | * copyright. | ||
4 | * | ||
5 | * This software may be used and distributed according to the terms | ||
6 | * of the GNU General Public License, incorporated herein by reference. | ||
7 | */ | ||
3 | #include <linux/module.h> | 8 | #include <linux/module.h> |
4 | #include <linux/fs.h> | 9 | #include <linux/fs.h> |
5 | #include <linux/miscdevice.h> | 10 | #include <linux/miscdevice.h> |
@@ -12,8 +17,6 @@ | |||
12 | */ | 17 | */ |
13 | #define RNG_VERSION "1.0.0" | 18 | #define RNG_VERSION "1.0.0" |
14 | #define RNG_MODULE_NAME "random" | 19 | #define RNG_MODULE_NAME "random" |
15 | #define RNG_DRIVER_NAME RNG_MODULE_NAME " virtual driver " RNG_VERSION | ||
16 | #define PFX RNG_MODULE_NAME ": " | ||
17 | 20 | ||
18 | #define RNG_MISCDEV_MINOR 183 /* official */ | 21 | #define RNG_MISCDEV_MINOR 183 /* official */ |
19 | 22 | ||
@@ -98,7 +101,7 @@ static int __init rng_init (void) | |||
98 | 101 | ||
99 | err = misc_register (&rng_miscdev); | 102 | err = misc_register (&rng_miscdev); |
100 | if (err) { | 103 | if (err) { |
101 | printk (KERN_ERR PFX "misc device register failed\n"); | 104 | printk (KERN_ERR RNG_MODULE_NAME ": misc device register failed\n"); |
102 | goto err_out_cleanup_hw; | 105 | goto err_out_cleanup_hw; |
103 | } | 106 | } |
104 | 107 | ||
@@ -120,3 +123,6 @@ static void __exit rng_cleanup (void) | |||
120 | 123 | ||
121 | module_init (rng_init); | 124 | module_init (rng_init); |
122 | module_exit (rng_cleanup); | 125 | module_exit (rng_cleanup); |
126 | |||
127 | MODULE_DESCRIPTION("UML Host Random Number Generator (RNG) driver"); | ||
128 | MODULE_LICENSE("GPL"); | ||
diff --git a/arch/um/drivers/slip.h b/arch/um/drivers/slip.h index 495f2f1b1420..bb0dab41c2e4 100644 --- a/arch/um/drivers/slip.h +++ b/arch/um/drivers/slip.h | |||
@@ -1,10 +1,7 @@ | |||
1 | #ifndef __UM_SLIP_H | 1 | #ifndef __UM_SLIP_H |
2 | #define __UM_SLIP_H | 2 | #define __UM_SLIP_H |
3 | 3 | ||
4 | #define BUF_SIZE 1500 | 4 | #include "slip_common.h" |
5 | /* two bytes each for a (pathological) max packet of escaped chars + * | ||
6 | * terminating END char + initial END char */ | ||
7 | #define ENC_BUF_SIZE (2 * BUF_SIZE + 2) | ||
8 | 5 | ||
9 | struct slip_data { | 6 | struct slip_data { |
10 | void *dev; | 7 | void *dev; |
@@ -12,28 +9,12 @@ struct slip_data { | |||
12 | char *addr; | 9 | char *addr; |
13 | char *gate_addr; | 10 | char *gate_addr; |
14 | int slave; | 11 | int slave; |
15 | char ibuf[ENC_BUF_SIZE]; | 12 | struct slip_proto slip; |
16 | char obuf[ENC_BUF_SIZE]; | ||
17 | int more; /* more data: do not read fd until ibuf has been drained */ | ||
18 | int pos; | ||
19 | int esc; | ||
20 | }; | 13 | }; |
21 | 14 | ||
22 | extern struct net_user_info slip_user_info; | 15 | extern struct net_user_info slip_user_info; |
23 | 16 | ||
24 | extern int set_umn_addr(int fd, char *addr, char *ptp_addr); | ||
25 | extern int slip_user_read(int fd, void *buf, int len, struct slip_data *pri); | 17 | extern int slip_user_read(int fd, void *buf, int len, struct slip_data *pri); |
26 | extern int slip_user_write(int fd, void *buf, int len, struct slip_data *pri); | 18 | extern int slip_user_write(int fd, void *buf, int len, struct slip_data *pri); |
27 | 19 | ||
28 | #endif | 20 | #endif |
29 | |||
30 | /* | ||
31 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
32 | * Emacs will notice this stuff at the end of the file and automatically | ||
33 | * adjust the settings for this buffer only. This must remain at the end | ||
34 | * of the file. | ||
35 | * --------------------------------------------------------------------------- | ||
36 | * Local variables: | ||
37 | * c-file-style: "linux" | ||
38 | * End: | ||
39 | */ | ||
diff --git a/arch/um/drivers/slip_common.c b/arch/um/drivers/slip_common.c new file mode 100644 index 000000000000..e89cfc68fc3e --- /dev/null +++ b/arch/um/drivers/slip_common.c | |||
@@ -0,0 +1,54 @@ | |||
1 | #include <string.h> | ||
2 | #include "slip_common.h" | ||
3 | #include "net_user.h" | ||
4 | |||
5 | int slip_proto_read(int fd, void *buf, int len, struct slip_proto *slip) | ||
6 | { | ||
7 | int i, n, size, start; | ||
8 | |||
9 | if(slip->more > 0){ | ||
10 | i = 0; | ||
11 | while(i < slip->more){ | ||
12 | size = slip_unesc(slip->ibuf[i++], slip->ibuf, | ||
13 | &slip->pos, &slip->esc); | ||
14 | if(size){ | ||
15 | memcpy(buf, slip->ibuf, size); | ||
16 | memmove(slip->ibuf, &slip->ibuf[i], | ||
17 | slip->more - i); | ||
18 | slip->more = slip->more - i; | ||
19 | return size; | ||
20 | } | ||
21 | } | ||
22 | slip->more = 0; | ||
23 | } | ||
24 | |||
25 | n = net_read(fd, &slip->ibuf[slip->pos], | ||
26 | sizeof(slip->ibuf) - slip->pos); | ||
27 | if(n <= 0) | ||
28 | return n; | ||
29 | |||
30 | start = slip->pos; | ||
31 | for(i = 0; i < n; i++){ | ||
32 | size = slip_unesc(slip->ibuf[start + i], slip->ibuf,&slip->pos, | ||
33 | &slip->esc); | ||
34 | if(size){ | ||
35 | memcpy(buf, slip->ibuf, size); | ||
36 | memmove(slip->ibuf, &slip->ibuf[start+i+1], | ||
37 | n - (i + 1)); | ||
38 | slip->more = n - (i + 1); | ||
39 | return size; | ||
40 | } | ||
41 | } | ||
42 | return 0; | ||
43 | } | ||
44 | |||
45 | int slip_proto_write(int fd, void *buf, int len, struct slip_proto *slip) | ||
46 | { | ||
47 | int actual, n; | ||
48 | |||
49 | actual = slip_esc(buf, slip->obuf, len); | ||
50 | n = net_write(fd, slip->obuf, actual); | ||
51 | if(n < 0) | ||
52 | return n; | ||
53 | else return len; | ||
54 | } | ||
diff --git a/arch/um/drivers/slip_proto.h b/arch/um/drivers/slip_common.h index 7206361ace45..2ae76d8f1be1 100644 --- a/arch/um/drivers/slip_proto.h +++ b/arch/um/drivers/slip_common.h | |||
@@ -1,10 +1,10 @@ | |||
1 | /* | 1 | #ifndef __UM_SLIP_COMMON_H |
2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) | 2 | #define __UM_SLIP_COMMON_H |
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | 3 | ||
6 | #ifndef __UM_SLIP_PROTO_H__ | 4 | #define BUF_SIZE 1500 |
7 | #define __UM_SLIP_PROTO_H__ | 5 | /* two bytes each for a (pathological) max packet of escaped chars + * |
6 | * terminating END char + initial END char */ | ||
7 | #define ENC_BUF_SIZE (2 * BUF_SIZE + 2) | ||
8 | 8 | ||
9 | /* SLIP protocol characters. */ | 9 | /* SLIP protocol characters. */ |
10 | #define SLIP_END 0300 /* indicates end of frame */ | 10 | #define SLIP_END 0300 /* indicates end of frame */ |
@@ -12,7 +12,8 @@ | |||
12 | #define SLIP_ESC_END 0334 /* ESC ESC_END means END 'data' */ | 12 | #define SLIP_ESC_END 0334 /* ESC ESC_END means END 'data' */ |
13 | #define SLIP_ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */ | 13 | #define SLIP_ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */ |
14 | 14 | ||
15 | static inline int slip_unesc(unsigned char c,char *buf,int *pos, int *esc) | 15 | static inline int slip_unesc(unsigned char c, unsigned char *buf, int *pos, |
16 | int *esc) | ||
16 | { | 17 | { |
17 | int ret; | 18 | int ret; |
18 | 19 | ||
@@ -79,15 +80,25 @@ static inline int slip_esc(unsigned char *s, unsigned char *d, int len) | |||
79 | return (ptr - d); | 80 | return (ptr - d); |
80 | } | 81 | } |
81 | 82 | ||
82 | #endif | 83 | struct slip_proto { |
84 | unsigned char ibuf[ENC_BUF_SIZE]; | ||
85 | unsigned char obuf[ENC_BUF_SIZE]; | ||
86 | int more; /* more data: do not read fd until ibuf has been drained */ | ||
87 | int pos; | ||
88 | int esc; | ||
89 | }; | ||
90 | |||
91 | #define SLIP_PROTO_INIT { \ | ||
92 | .ibuf = { '\0' }, \ | ||
93 | .obuf = { '\0' }, \ | ||
94 | .more = 0, \ | ||
95 | .pos = 0, \ | ||
96 | .esc = 0 \ | ||
97 | } | ||
83 | 98 | ||
84 | /* | 99 | extern int slip_proto_read(int fd, void *buf, int len, |
85 | * Overrides for Emacs so that we follow Linus's tabbing style. | 100 | struct slip_proto *slip); |
86 | * Emacs will notice this stuff at the end of the file and automatically | 101 | extern int slip_proto_write(int fd, void *buf, int len, |
87 | * adjust the settings for this buffer only. This must remain at the end | 102 | struct slip_proto *slip); |
88 | * of the file. | 103 | |
89 | * --------------------------------------------------------------------------- | 104 | #endif |
90 | * Local variables: | ||
91 | * c-file-style: "linux" | ||
92 | * End: | ||
93 | */ | ||
diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c index 0886eedba213..9a6f5c85f902 100644 --- a/arch/um/drivers/slip_kern.c +++ b/arch/um/drivers/slip_kern.c | |||
@@ -26,16 +26,16 @@ void slip_init(struct net_device *dev, void *data) | |||
26 | .addr = NULL, | 26 | .addr = NULL, |
27 | .gate_addr = init->gate_addr, | 27 | .gate_addr = init->gate_addr, |
28 | .slave = -1, | 28 | .slave = -1, |
29 | .ibuf = { '\0' }, | 29 | .slip = SLIP_PROTO_INIT, |
30 | .obuf = { '\0' }, | ||
31 | .pos = 0, | ||
32 | .esc = 0, | ||
33 | .dev = dev }); | 30 | .dev = dev }); |
34 | 31 | ||
35 | dev->init = NULL; | 32 | dev->init = NULL; |
33 | dev->header_cache_update = NULL; | ||
34 | dev->hard_header_cache = NULL; | ||
35 | dev->hard_header = NULL; | ||
36 | dev->hard_header_len = 0; | 36 | dev->hard_header_len = 0; |
37 | dev->addr_len = 4; | 37 | dev->addr_len = 0; |
38 | dev->type = ARPHRD_ETHER; | 38 | dev->type = ARPHRD_SLIP; |
39 | dev->tx_queue_len = 256; | 39 | dev->tx_queue_len = 256; |
40 | dev->flags = IFF_NOARP; | 40 | dev->flags = IFF_NOARP; |
41 | printk("SLIP backend - SLIP IP = %s\n", spri->gate_addr); | 41 | printk("SLIP backend - SLIP IP = %s\n", spri->gate_addr); |
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c index d94846b1b4cf..71af444e591f 100644 --- a/arch/um/drivers/slip_user.c +++ b/arch/um/drivers/slip_user.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include "user.h" | 13 | #include "user.h" |
14 | #include "net_user.h" | 14 | #include "net_user.h" |
15 | #include "slip.h" | 15 | #include "slip.h" |
16 | #include "slip_proto.h" | 16 | #include "slip_common.h" |
17 | #include "helper.h" | 17 | #include "helper.h" |
18 | #include "os.h" | 18 | #include "os.h" |
19 | 19 | ||
@@ -77,41 +77,51 @@ static int slip_tramp(char **argv, int fd) | |||
77 | err = os_pipe(fds, 1, 0); | 77 | err = os_pipe(fds, 1, 0); |
78 | if(err < 0){ | 78 | if(err < 0){ |
79 | printk("slip_tramp : pipe failed, err = %d\n", -err); | 79 | printk("slip_tramp : pipe failed, err = %d\n", -err); |
80 | return(err); | 80 | goto out; |
81 | } | 81 | } |
82 | 82 | ||
83 | err = 0; | 83 | err = 0; |
84 | pe_data.stdin = fd; | 84 | pe_data.stdin = fd; |
85 | pe_data.stdout = fds[1]; | 85 | pe_data.stdout = fds[1]; |
86 | pe_data.close_me = fds[0]; | 86 | pe_data.close_me = fds[0]; |
87 | pid = run_helper(slip_pre_exec, &pe_data, argv, NULL); | 87 | err = run_helper(slip_pre_exec, &pe_data, argv, NULL); |
88 | if(err < 0) | ||
89 | goto out_close; | ||
90 | pid = err; | ||
91 | |||
92 | output_len = page_size(); | ||
93 | output = um_kmalloc(output_len); | ||
94 | if(output == NULL){ | ||
95 | printk("slip_tramp : failed to allocate output buffer\n"); | ||
96 | os_kill_process(pid, 1); | ||
97 | err = -ENOMEM; | ||
98 | goto out_free; | ||
99 | } | ||
88 | 100 | ||
89 | if(pid < 0) err = pid; | 101 | os_close_file(fds[1]); |
90 | else { | 102 | read_output(fds[0], output, output_len); |
91 | output_len = page_size(); | 103 | printk("%s", output); |
92 | output = um_kmalloc(output_len); | 104 | |
93 | if(output == NULL) | 105 | CATCH_EINTR(err = waitpid(pid, &status, 0)); |
94 | printk("slip_tramp : failed to allocate output " | 106 | if(err < 0) |
95 | "buffer\n"); | 107 | err = errno; |
96 | 108 | else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){ | |
97 | os_close_file(fds[1]); | 109 | printk("'%s' didn't exit with status 0\n", argv[0]); |
98 | read_output(fds[0], output, output_len); | 110 | err = -EINVAL; |
99 | if(output != NULL){ | ||
100 | printk("%s", output); | ||
101 | kfree(output); | ||
102 | } | ||
103 | CATCH_EINTR(err = waitpid(pid, &status, 0)); | ||
104 | if(err < 0) | ||
105 | err = errno; | ||
106 | else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){ | ||
107 | printk("'%s' didn't exit with status 0\n", argv[0]); | ||
108 | err = -EINVAL; | ||
109 | } | ||
110 | } | 111 | } |
112 | else err = 0; | ||
111 | 113 | ||
112 | os_close_file(fds[0]); | 114 | os_close_file(fds[0]); |
113 | 115 | ||
114 | return(err); | 116 | out_free: |
117 | kfree(output); | ||
118 | return err; | ||
119 | |||
120 | out_close: | ||
121 | os_close_file(fds[0]); | ||
122 | os_close_file(fds[1]); | ||
123 | out: | ||
124 | return err; | ||
115 | } | 125 | } |
116 | 126 | ||
117 | static int slip_open(void *data) | 127 | static int slip_open(void *data) |
@@ -123,21 +133,26 @@ static int slip_open(void *data) | |||
123 | NULL }; | 133 | NULL }; |
124 | int sfd, mfd, err; | 134 | int sfd, mfd, err; |
125 | 135 | ||
126 | mfd = get_pty(); | 136 | err = get_pty(); |
127 | if(mfd < 0){ | 137 | if(err < 0){ |
128 | printk("umn : Failed to open pty, err = %d\n", -mfd); | 138 | printk("slip-open : Failed to open pty, err = %d\n", -err); |
129 | return(mfd); | 139 | goto out; |
130 | } | 140 | } |
131 | sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0); | 141 | mfd = err; |
132 | if(sfd < 0){ | 142 | |
133 | printk("Couldn't open tty for slip line, err = %d\n", -sfd); | 143 | err = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0); |
134 | os_close_file(mfd); | 144 | if(err < 0){ |
135 | return(sfd); | 145 | printk("Couldn't open tty for slip line, err = %d\n", -err); |
146 | goto out_close; | ||
136 | } | 147 | } |
137 | if(set_up_tty(sfd)) return(-1); | 148 | sfd = err; |
149 | |||
150 | if(set_up_tty(sfd)) | ||
151 | goto out_close2; | ||
152 | |||
138 | pri->slave = sfd; | 153 | pri->slave = sfd; |
139 | pri->pos = 0; | 154 | pri->slip.pos = 0; |
140 | pri->esc = 0; | 155 | pri->slip.esc = 0; |
141 | if(pri->gate_addr != NULL){ | 156 | if(pri->gate_addr != NULL){ |
142 | sprintf(version_buf, "%d", UML_NET_VERSION); | 157 | sprintf(version_buf, "%d", UML_NET_VERSION); |
143 | strcpy(gate_buf, pri->gate_addr); | 158 | strcpy(gate_buf, pri->gate_addr); |
@@ -146,12 +161,12 @@ static int slip_open(void *data) | |||
146 | 161 | ||
147 | if(err < 0){ | 162 | if(err < 0){ |
148 | printk("slip_tramp failed - err = %d\n", -err); | 163 | printk("slip_tramp failed - err = %d\n", -err); |
149 | return(err); | 164 | goto out_close2; |
150 | } | 165 | } |
151 | err = os_get_ifname(pri->slave, pri->name); | 166 | err = os_get_ifname(pri->slave, pri->name); |
152 | if(err < 0){ | 167 | if(err < 0){ |
153 | printk("get_ifname failed, err = %d\n", -err); | 168 | printk("get_ifname failed, err = %d\n", -err); |
154 | return(err); | 169 | goto out_close2; |
155 | } | 170 | } |
156 | iter_addresses(pri->dev, open_addr, pri->name); | 171 | iter_addresses(pri->dev, open_addr, pri->name); |
157 | } | 172 | } |
@@ -160,10 +175,16 @@ static int slip_open(void *data) | |||
160 | if(err < 0){ | 175 | if(err < 0){ |
161 | printk("Failed to set slip discipline encapsulation - " | 176 | printk("Failed to set slip discipline encapsulation - " |
162 | "err = %d\n", -err); | 177 | "err = %d\n", -err); |
163 | return(err); | 178 | goto out_close2; |
164 | } | 179 | } |
165 | } | 180 | } |
166 | return(mfd); | 181 | return(mfd); |
182 | out_close2: | ||
183 | os_close_file(sfd); | ||
184 | out_close: | ||
185 | os_close_file(mfd); | ||
186 | out: | ||
187 | return err; | ||
167 | } | 188 | } |
168 | 189 | ||
169 | static void slip_close(int fd, void *data) | 190 | static void slip_close(int fd, void *data) |
@@ -190,48 +211,12 @@ static void slip_close(int fd, void *data) | |||
190 | 211 | ||
191 | int slip_user_read(int fd, void *buf, int len, struct slip_data *pri) | 212 | int slip_user_read(int fd, void *buf, int len, struct slip_data *pri) |
192 | { | 213 | { |
193 | int i, n, size, start; | 214 | return slip_proto_read(fd, buf, len, &pri->slip); |
194 | |||
195 | if(pri->more>0) { | ||
196 | i = 0; | ||
197 | while(i < pri->more) { | ||
198 | size = slip_unesc(pri->ibuf[i++], | ||
199 | pri->ibuf, &pri->pos, &pri->esc); | ||
200 | if(size){ | ||
201 | memcpy(buf, pri->ibuf, size); | ||
202 | memmove(pri->ibuf, &pri->ibuf[i], pri->more-i); | ||
203 | pri->more=pri->more-i; | ||
204 | return(size); | ||
205 | } | ||
206 | } | ||
207 | pri->more=0; | ||
208 | } | ||
209 | |||
210 | n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos); | ||
211 | if(n <= 0) return(n); | ||
212 | |||
213 | start = pri->pos; | ||
214 | for(i = 0; i < n; i++){ | ||
215 | size = slip_unesc(pri->ibuf[start + i], | ||
216 | pri->ibuf, &pri->pos, &pri->esc); | ||
217 | if(size){ | ||
218 | memcpy(buf, pri->ibuf, size); | ||
219 | memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1)); | ||
220 | pri->more=n-(i+1); | ||
221 | return(size); | ||
222 | } | ||
223 | } | ||
224 | return(0); | ||
225 | } | 215 | } |
226 | 216 | ||
227 | int slip_user_write(int fd, void *buf, int len, struct slip_data *pri) | 217 | int slip_user_write(int fd, void *buf, int len, struct slip_data *pri) |
228 | { | 218 | { |
229 | int actual, n; | 219 | return slip_proto_write(fd, buf, len, &pri->slip); |
230 | |||
231 | actual = slip_esc(buf, pri->obuf, len); | ||
232 | n = net_write(fd, pri->obuf, actual); | ||
233 | if(n < 0) return(n); | ||
234 | else return(len); | ||
235 | } | 220 | } |
236 | 221 | ||
237 | static int slip_set_mtu(int mtu, void *data) | 222 | static int slip_set_mtu(int mtu, void *data) |
@@ -267,14 +252,3 @@ struct net_user_info slip_user_info = { | |||
267 | .delete_address = slip_del_addr, | 252 | .delete_address = slip_del_addr, |
268 | .max_packet = BUF_SIZE | 253 | .max_packet = BUF_SIZE |
269 | }; | 254 | }; |
270 | |||
271 | /* | ||
272 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
273 | * Emacs will notice this stuff at the end of the file and automatically | ||
274 | * adjust the settings for this buffer only. This must remain at the end | ||
275 | * of the file. | ||
276 | * --------------------------------------------------------------------------- | ||
277 | * Local variables: | ||
278 | * c-file-style: "linux" | ||
279 | * End: | ||
280 | */ | ||
diff --git a/arch/um/drivers/slirp.h b/arch/um/drivers/slirp.h index 04e407d1e44a..6cf88ab580c9 100644 --- a/arch/um/drivers/slirp.h +++ b/arch/um/drivers/slirp.h | |||
@@ -1,10 +1,7 @@ | |||
1 | #ifndef __UM_SLIRP_H | 1 | #ifndef __UM_SLIRP_H |
2 | #define __UM_SLIRP_H | 2 | #define __UM_SLIRP_H |
3 | 3 | ||
4 | #define BUF_SIZE 1500 | 4 | #include "slip_common.h" |
5 | /* two bytes each for a (pathological) max packet of escaped chars + * | ||
6 | * terminating END char + initial END char */ | ||
7 | #define ENC_BUF_SIZE (2 * BUF_SIZE + 2) | ||
8 | 5 | ||
9 | #define SLIRP_MAX_ARGS 100 | 6 | #define SLIRP_MAX_ARGS 100 |
10 | /* | 7 | /* |
@@ -24,28 +21,13 @@ struct slirp_data { | |||
24 | struct arg_list_dummy_wrapper argw; | 21 | struct arg_list_dummy_wrapper argw; |
25 | int pid; | 22 | int pid; |
26 | int slave; | 23 | int slave; |
27 | char ibuf[ENC_BUF_SIZE]; | 24 | struct slip_proto slip; |
28 | char obuf[ENC_BUF_SIZE]; | ||
29 | int more; /* more data: do not read fd until ibuf has been drained */ | ||
30 | int pos; | ||
31 | int esc; | ||
32 | }; | 25 | }; |
33 | 26 | ||
34 | extern struct net_user_info slirp_user_info; | 27 | extern struct net_user_info slirp_user_info; |
35 | 28 | ||
36 | extern int set_umn_addr(int fd, char *addr, char *ptp_addr); | ||
37 | extern int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri); | 29 | extern int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri); |
38 | extern int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri); | 30 | extern int slirp_user_write(int fd, void *buf, int len, |
31 | struct slirp_data *pri); | ||
39 | 32 | ||
40 | #endif | 33 | #endif |
41 | |||
42 | /* | ||
43 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
44 | * Emacs will notice this stuff at the end of the file and automatically | ||
45 | * adjust the settings for this buffer only. This must remain at the end | ||
46 | * of the file. | ||
47 | * --------------------------------------------------------------------------- | ||
48 | * Local variables: | ||
49 | * c-file-style: "linux" | ||
50 | * End: | ||
51 | */ | ||
diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c index c9d6b52a831d..9864d27afdbe 100644 --- a/arch/um/drivers/slirp_kern.c +++ b/arch/um/drivers/slirp_kern.c | |||
@@ -25,10 +25,7 @@ void slirp_init(struct net_device *dev, void *data) | |||
25 | { .argw = init->argw, | 25 | { .argw = init->argw, |
26 | .pid = -1, | 26 | .pid = -1, |
27 | .slave = -1, | 27 | .slave = -1, |
28 | .ibuf = { '\0' }, | 28 | .slip = SLIP_PROTO_INIT, |
29 | .obuf = { '\0' }, | ||
30 | .pos = 0, | ||
31 | .esc = 0, | ||
32 | .dev = dev }); | 29 | .dev = dev }); |
33 | 30 | ||
34 | dev->init = NULL; | 31 | dev->init = NULL; |
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c index c322515c71cc..8d91f663d82c 100644 --- a/arch/um/drivers/slirp_user.c +++ b/arch/um/drivers/slirp_user.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include "user.h" | 12 | #include "user.h" |
13 | #include "net_user.h" | 13 | #include "net_user.h" |
14 | #include "slirp.h" | 14 | #include "slirp.h" |
15 | #include "slip_proto.h" | 15 | #include "slip_common.h" |
16 | #include "helper.h" | 16 | #include "helper.h" |
17 | #include "os.h" | 17 | #include "os.h" |
18 | 18 | ||
@@ -48,47 +48,32 @@ static int slirp_tramp(char **argv, int fd) | |||
48 | return(pid); | 48 | return(pid); |
49 | } | 49 | } |
50 | 50 | ||
51 | /* XXX This is just a trivial wrapper around os_pipe */ | ||
52 | static int slirp_datachan(int *mfd, int *sfd) | ||
53 | { | ||
54 | int fds[2], err; | ||
55 | |||
56 | err = os_pipe(fds, 1, 1); | ||
57 | if(err < 0){ | ||
58 | printk("slirp_datachan: Failed to open pipe, err = %d\n", -err); | ||
59 | return(err); | ||
60 | } | ||
61 | |||
62 | *mfd = fds[0]; | ||
63 | *sfd = fds[1]; | ||
64 | return(0); | ||
65 | } | ||
66 | |||
67 | static int slirp_open(void *data) | 51 | static int slirp_open(void *data) |
68 | { | 52 | { |
69 | struct slirp_data *pri = data; | 53 | struct slirp_data *pri = data; |
70 | int sfd, mfd, pid, err; | 54 | int fds[2], pid, err; |
71 | 55 | ||
72 | err = slirp_datachan(&mfd, &sfd); | 56 | err = os_pipe(fds, 1, 1); |
73 | if(err) | 57 | if(err) |
74 | return(err); | 58 | return(err); |
75 | 59 | ||
76 | pid = slirp_tramp(pri->argw.argv, sfd); | 60 | err = slirp_tramp(pri->argw.argv, fds[1]); |
77 | 61 | if(err < 0){ | |
78 | if(pid < 0){ | 62 | printk("slirp_tramp failed - errno = %d\n", -err); |
79 | printk("slirp_tramp failed - errno = %d\n", -pid); | 63 | goto out; |
80 | os_close_file(sfd); | ||
81 | os_close_file(mfd); | ||
82 | return(pid); | ||
83 | } | 64 | } |
84 | 65 | pid = err; | |
85 | pri->slave = sfd; | 66 | |
86 | pri->pos = 0; | 67 | pri->slave = fds[1]; |
87 | pri->esc = 0; | 68 | pri->slip.pos = 0; |
88 | 69 | pri->slip.esc = 0; | |
89 | pri->pid = pid; | 70 | pri->pid = err; |
90 | 71 | ||
91 | return(mfd); | 72 | return(fds[0]); |
73 | out: | ||
74 | os_close_file(fds[0]); | ||
75 | os_close_file(fds[1]); | ||
76 | return err; | ||
92 | } | 77 | } |
93 | 78 | ||
94 | static void slirp_close(int fd, void *data) | 79 | static void slirp_close(int fd, void *data) |
@@ -129,48 +114,12 @@ static void slirp_close(int fd, void *data) | |||
129 | 114 | ||
130 | int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri) | 115 | int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri) |
131 | { | 116 | { |
132 | int i, n, size, start; | 117 | return slip_proto_read(fd, buf, len, &pri->slip); |
133 | |||
134 | if(pri->more>0) { | ||
135 | i = 0; | ||
136 | while(i < pri->more) { | ||
137 | size = slip_unesc(pri->ibuf[i++], | ||
138 | pri->ibuf,&pri->pos,&pri->esc); | ||
139 | if(size){ | ||
140 | memcpy(buf, pri->ibuf, size); | ||
141 | memmove(pri->ibuf, &pri->ibuf[i], pri->more-i); | ||
142 | pri->more=pri->more-i; | ||
143 | return(size); | ||
144 | } | ||
145 | } | ||
146 | pri->more=0; | ||
147 | } | ||
148 | |||
149 | n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos); | ||
150 | if(n <= 0) return(n); | ||
151 | |||
152 | start = pri->pos; | ||
153 | for(i = 0; i < n; i++){ | ||
154 | size = slip_unesc(pri->ibuf[start + i], | ||
155 | pri->ibuf,&pri->pos,&pri->esc); | ||
156 | if(size){ | ||
157 | memcpy(buf, pri->ibuf, size); | ||
158 | memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1)); | ||
159 | pri->more=n-(i+1); | ||
160 | return(size); | ||
161 | } | ||
162 | } | ||
163 | return(0); | ||
164 | } | 118 | } |
165 | 119 | ||
166 | int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri) | 120 | int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri) |
167 | { | 121 | { |
168 | int actual, n; | 122 | return slip_proto_write(fd, buf, len, &pri->slip); |
169 | |||
170 | actual = slip_esc(buf, pri->obuf, len); | ||
171 | n = net_write(fd, pri->obuf, actual); | ||
172 | if(n < 0) return(n); | ||
173 | else return(len); | ||
174 | } | 123 | } |
175 | 124 | ||
176 | static int slirp_set_mtu(int mtu, void *data) | 125 | static int slirp_set_mtu(int mtu, void *data) |
@@ -188,14 +137,3 @@ struct net_user_info slirp_user_info = { | |||
188 | .delete_address = NULL, | 137 | .delete_address = NULL, |
189 | .max_packet = BUF_SIZE | 138 | .max_packet = BUF_SIZE |
190 | }; | 139 | }; |
191 | |||
192 | /* | ||
193 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
194 | * Emacs will notice this stuff at the end of the file and automatically | ||
195 | * adjust the settings for this buffer only. This must remain at the end | ||
196 | * of the file. | ||
197 | * --------------------------------------------------------------------------- | ||
198 | * Local variables: | ||
199 | * c-file-style: "linux" | ||
200 | * End: | ||
201 | */ | ||
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index a2bac429f3d4..b32a77010fbe 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include "init.h" | 22 | #include "init.h" |
23 | #include "irq_user.h" | 23 | #include "irq_user.h" |
24 | #include "mconsole_kern.h" | 24 | #include "mconsole_kern.h" |
25 | #include "2_5compat.h" | ||
26 | 25 | ||
27 | static int ssl_version = 1; | 26 | static int ssl_version = 1; |
28 | 27 | ||
diff --git a/arch/um/drivers/stderr_console.c b/arch/um/drivers/stderr_console.c index 98565b53d170..429ae8e6c7e5 100644 --- a/arch/um/drivers/stderr_console.c +++ b/arch/um/drivers/stderr_console.c | |||
@@ -22,9 +22,9 @@ static void stderr_console_write(struct console *console, const char *string, | |||
22 | } | 22 | } |
23 | 23 | ||
24 | static struct console stderr_console = { | 24 | static struct console stderr_console = { |
25 | .name "stderr", | 25 | .name = "stderr", |
26 | .write stderr_console_write, | 26 | .write = stderr_console_write, |
27 | .flags CON_PRINTBUFFER, | 27 | .flags = CON_PRINTBUFFER, |
28 | }; | 28 | }; |
29 | 29 | ||
30 | static int __init stderr_console_init(void) | 30 | static int __init stderr_console_init(void) |
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index 361d0be342b3..afbe1e71ed83 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include "irq_user.h" | 28 | #include "irq_user.h" |
29 | #include "mconsole_kern.h" | 29 | #include "mconsole_kern.h" |
30 | #include "init.h" | 30 | #include "init.h" |
31 | #include "2_5compat.h" | ||
32 | 31 | ||
33 | #define MAX_TTYS (16) | 32 | #define MAX_TTYS (16) |
34 | 33 | ||
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 9a56ff94308d..2a7f6892c55c 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c | |||
@@ -49,13 +49,12 @@ | |||
49 | #include "irq_user.h" | 49 | #include "irq_user.h" |
50 | #include "irq_kern.h" | 50 | #include "irq_kern.h" |
51 | #include "ubd_user.h" | 51 | #include "ubd_user.h" |
52 | #include "2_5compat.h" | ||
53 | #include "os.h" | 52 | #include "os.h" |
54 | #include "mem.h" | 53 | #include "mem.h" |
55 | #include "mem_kern.h" | 54 | #include "mem_kern.h" |
56 | #include "cow.h" | 55 | #include "cow.h" |
57 | 56 | ||
58 | enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP }; | 57 | enum ubd_req { UBD_READ, UBD_WRITE }; |
59 | 58 | ||
60 | struct io_thread_req { | 59 | struct io_thread_req { |
61 | enum ubd_req op; | 60 | enum ubd_req op; |
@@ -68,8 +67,6 @@ struct io_thread_req { | |||
68 | unsigned long sector_mask; | 67 | unsigned long sector_mask; |
69 | unsigned long long cow_offset; | 68 | unsigned long long cow_offset; |
70 | unsigned long bitmap_words[2]; | 69 | unsigned long bitmap_words[2]; |
71 | int map_fd; | ||
72 | unsigned long long map_offset; | ||
73 | int error; | 70 | int error; |
74 | }; | 71 | }; |
75 | 72 | ||
@@ -122,10 +119,6 @@ static int ubd_ioctl(struct inode * inode, struct file * file, | |||
122 | 119 | ||
123 | #define MAX_DEV (8) | 120 | #define MAX_DEV (8) |
124 | 121 | ||
125 | /* Changed in early boot */ | ||
126 | static int ubd_do_mmap = 0; | ||
127 | #define UBD_MMAP_BLOCK_SIZE PAGE_SIZE | ||
128 | |||
129 | static struct block_device_operations ubd_blops = { | 122 | static struct block_device_operations ubd_blops = { |
130 | .owner = THIS_MODULE, | 123 | .owner = THIS_MODULE, |
131 | .open = ubd_open, | 124 | .open = ubd_open, |
@@ -175,12 +168,6 @@ struct ubd { | |||
175 | int no_cow; | 168 | int no_cow; |
176 | struct cow cow; | 169 | struct cow cow; |
177 | struct platform_device pdev; | 170 | struct platform_device pdev; |
178 | |||
179 | int map_writes; | ||
180 | int map_reads; | ||
181 | int nomap_writes; | ||
182 | int nomap_reads; | ||
183 | int write_maps; | ||
184 | }; | 171 | }; |
185 | 172 | ||
186 | #define DEFAULT_COW { \ | 173 | #define DEFAULT_COW { \ |
@@ -200,11 +187,6 @@ struct ubd { | |||
200 | .openflags = OPEN_FLAGS, \ | 187 | .openflags = OPEN_FLAGS, \ |
201 | .no_cow = 0, \ | 188 | .no_cow = 0, \ |
202 | .cow = DEFAULT_COW, \ | 189 | .cow = DEFAULT_COW, \ |
203 | .map_writes = 0, \ | ||
204 | .map_reads = 0, \ | ||
205 | .nomap_writes = 0, \ | ||
206 | .nomap_reads = 0, \ | ||
207 | .write_maps = 0, \ | ||
208 | } | 190 | } |
209 | 191 | ||
210 | struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD }; | 192 | struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD }; |
@@ -314,13 +296,6 @@ static int ubd_setup_common(char *str, int *index_out) | |||
314 | int major; | 296 | int major; |
315 | 297 | ||
316 | str++; | 298 | str++; |
317 | if(!strcmp(str, "mmap")){ | ||
318 | CHOOSE_MODE(printk("mmap not supported by the ubd " | ||
319 | "driver in tt mode\n"), | ||
320 | ubd_do_mmap = 1); | ||
321 | return(0); | ||
322 | } | ||
323 | |||
324 | if(!strcmp(str, "sync")){ | 299 | if(!strcmp(str, "sync")){ |
325 | global_openflags = of_sync(global_openflags); | 300 | global_openflags = of_sync(global_openflags); |
326 | return(0); | 301 | return(0); |
@@ -464,9 +439,9 @@ static int udb_setup(char *str) | |||
464 | __setup("udb", udb_setup); | 439 | __setup("udb", udb_setup); |
465 | __uml_help(udb_setup, | 440 | __uml_help(udb_setup, |
466 | "udb\n" | 441 | "udb\n" |
467 | " This option is here solely to catch ubd -> udb typos, which can be\n\n" | 442 | " This option is here solely to catch ubd -> udb typos, which can be\n" |
468 | " to impossible to catch visually unless you specifically look for\n\n" | 443 | " to impossible to catch visually unless you specifically look for\n" |
469 | " them. The only result of any option starting with 'udb' is an error\n\n" | 444 | " them. The only result of any option starting with 'udb' is an error\n" |
470 | " in the boot output.\n\n" | 445 | " in the boot output.\n\n" |
471 | ); | 446 | ); |
472 | 447 | ||
@@ -524,7 +499,7 @@ static void ubd_handler(void) | |||
524 | { | 499 | { |
525 | struct io_thread_req req; | 500 | struct io_thread_req req; |
526 | struct request *rq = elv_next_request(ubd_queue); | 501 | struct request *rq = elv_next_request(ubd_queue); |
527 | int n, err; | 502 | int n; |
528 | 503 | ||
529 | do_ubd = NULL; | 504 | do_ubd = NULL; |
530 | intr_count++; | 505 | intr_count++; |
@@ -538,19 +513,6 @@ static void ubd_handler(void) | |||
538 | return; | 513 | return; |
539 | } | 514 | } |
540 | 515 | ||
541 | if((req.op != UBD_MMAP) && | ||
542 | ((req.offset != ((__u64) (rq->sector)) << 9) || | ||
543 | (req.length != (rq->current_nr_sectors) << 9))) | ||
544 | panic("I/O op mismatch"); | ||
545 | |||
546 | if(req.map_fd != -1){ | ||
547 | err = physmem_subst_mapping(req.buffer, req.map_fd, | ||
548 | req.map_offset, 1); | ||
549 | if(err) | ||
550 | printk("ubd_handler - physmem_subst_mapping failed, " | ||
551 | "err = %d\n", -err); | ||
552 | } | ||
553 | |||
554 | ubd_finish(rq, req.error); | 516 | ubd_finish(rq, req.error); |
555 | reactivate_fd(thread_fd, UBD_IRQ); | 517 | reactivate_fd(thread_fd, UBD_IRQ); |
556 | do_ubd_request(ubd_queue); | 518 | do_ubd_request(ubd_queue); |
@@ -583,14 +545,10 @@ static int ubd_file_size(struct ubd *dev, __u64 *size_out) | |||
583 | 545 | ||
584 | static void ubd_close(struct ubd *dev) | 546 | static void ubd_close(struct ubd *dev) |
585 | { | 547 | { |
586 | if(ubd_do_mmap) | ||
587 | physmem_forget_descriptor(dev->fd); | ||
588 | os_close_file(dev->fd); | 548 | os_close_file(dev->fd); |
589 | if(dev->cow.file == NULL) | 549 | if(dev->cow.file == NULL) |
590 | return; | 550 | return; |
591 | 551 | ||
592 | if(ubd_do_mmap) | ||
593 | physmem_forget_descriptor(dev->cow.fd); | ||
594 | os_close_file(dev->cow.fd); | 552 | os_close_file(dev->cow.fd); |
595 | vfree(dev->cow.bitmap); | 553 | vfree(dev->cow.bitmap); |
596 | dev->cow.bitmap = NULL; | 554 | dev->cow.bitmap = NULL; |
@@ -1010,94 +968,13 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap, | |||
1010 | req->bitmap_words, bitmap_len); | 968 | req->bitmap_words, bitmap_len); |
1011 | } | 969 | } |
1012 | 970 | ||
1013 | static int mmap_fd(struct request *req, struct ubd *dev, __u64 offset) | ||
1014 | { | ||
1015 | __u64 sector; | ||
1016 | unsigned char *bitmap; | ||
1017 | int bit, i; | ||
1018 | |||
1019 | /* mmap must have been requested on the command line */ | ||
1020 | if(!ubd_do_mmap) | ||
1021 | return(-1); | ||
1022 | |||
1023 | /* The buffer must be page aligned */ | ||
1024 | if(((unsigned long) req->buffer % UBD_MMAP_BLOCK_SIZE) != 0) | ||
1025 | return(-1); | ||
1026 | |||
1027 | /* The request must be a page long */ | ||
1028 | if((req->current_nr_sectors << 9) != PAGE_SIZE) | ||
1029 | return(-1); | ||
1030 | |||
1031 | if(dev->cow.file == NULL) | ||
1032 | return(dev->fd); | ||
1033 | |||
1034 | sector = offset >> 9; | ||
1035 | bitmap = (unsigned char *) dev->cow.bitmap; | ||
1036 | bit = ubd_test_bit(sector, bitmap); | ||
1037 | |||
1038 | for(i = 1; i < req->current_nr_sectors; i++){ | ||
1039 | if(ubd_test_bit(sector + i, bitmap) != bit) | ||
1040 | return(-1); | ||
1041 | } | ||
1042 | |||
1043 | if(bit || (rq_data_dir(req) == WRITE)) | ||
1044 | offset += dev->cow.data_offset; | ||
1045 | |||
1046 | /* The data on disk must be page aligned */ | ||
1047 | if((offset % UBD_MMAP_BLOCK_SIZE) != 0) | ||
1048 | return(-1); | ||
1049 | |||
1050 | return(bit ? dev->fd : dev->cow.fd); | ||
1051 | } | ||
1052 | |||
1053 | static int prepare_mmap_request(struct ubd *dev, int fd, __u64 offset, | ||
1054 | struct request *req, | ||
1055 | struct io_thread_req *io_req) | ||
1056 | { | ||
1057 | int err; | ||
1058 | |||
1059 | if(rq_data_dir(req) == WRITE){ | ||
1060 | /* Writes are almost no-ops since the new data is already in the | ||
1061 | * host page cache | ||
1062 | */ | ||
1063 | dev->map_writes++; | ||
1064 | if(dev->cow.file != NULL) | ||
1065 | cowify_bitmap(io_req->offset, io_req->length, | ||
1066 | &io_req->sector_mask, &io_req->cow_offset, | ||
1067 | dev->cow.bitmap, dev->cow.bitmap_offset, | ||
1068 | io_req->bitmap_words, | ||
1069 | dev->cow.bitmap_len); | ||
1070 | } | ||
1071 | else { | ||
1072 | int w; | ||
1073 | |||
1074 | if((dev->cow.file != NULL) && (fd == dev->cow.fd)) | ||
1075 | w = 0; | ||
1076 | else w = dev->openflags.w; | ||
1077 | |||
1078 | if((dev->cow.file != NULL) && (fd == dev->fd)) | ||
1079 | offset += dev->cow.data_offset; | ||
1080 | |||
1081 | err = physmem_subst_mapping(req->buffer, fd, offset, w); | ||
1082 | if(err){ | ||
1083 | printk("physmem_subst_mapping failed, err = %d\n", | ||
1084 | -err); | ||
1085 | return(1); | ||
1086 | } | ||
1087 | dev->map_reads++; | ||
1088 | } | ||
1089 | io_req->op = UBD_MMAP; | ||
1090 | io_req->buffer = req->buffer; | ||
1091 | return(0); | ||
1092 | } | ||
1093 | |||
1094 | /* Called with ubd_io_lock held */ | 971 | /* Called with ubd_io_lock held */ |
1095 | static int prepare_request(struct request *req, struct io_thread_req *io_req) | 972 | static int prepare_request(struct request *req, struct io_thread_req *io_req) |
1096 | { | 973 | { |
1097 | struct gendisk *disk = req->rq_disk; | 974 | struct gendisk *disk = req->rq_disk; |
1098 | struct ubd *dev = disk->private_data; | 975 | struct ubd *dev = disk->private_data; |
1099 | __u64 offset; | 976 | __u64 offset; |
1100 | int len, fd; | 977 | int len; |
1101 | 978 | ||
1102 | if(req->rq_status == RQ_INACTIVE) return(1); | 979 | if(req->rq_status == RQ_INACTIVE) return(1); |
1103 | 980 | ||
@@ -1114,34 +991,12 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req) | |||
1114 | 991 | ||
1115 | io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd; | 992 | io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd; |
1116 | io_req->fds[1] = dev->fd; | 993 | io_req->fds[1] = dev->fd; |
1117 | io_req->map_fd = -1; | ||
1118 | io_req->cow_offset = -1; | 994 | io_req->cow_offset = -1; |
1119 | io_req->offset = offset; | 995 | io_req->offset = offset; |
1120 | io_req->length = len; | 996 | io_req->length = len; |
1121 | io_req->error = 0; | 997 | io_req->error = 0; |
1122 | io_req->sector_mask = 0; | 998 | io_req->sector_mask = 0; |
1123 | 999 | ||
1124 | fd = mmap_fd(req, dev, io_req->offset); | ||
1125 | if(fd > 0){ | ||
1126 | /* If mmapping is otherwise OK, but the first access to the | ||
1127 | * page is a write, then it's not mapped in yet. So we have | ||
1128 | * to write the data to disk first, then we can map the disk | ||
1129 | * page in and continue normally from there. | ||
1130 | */ | ||
1131 | if((rq_data_dir(req) == WRITE) && !is_remapped(req->buffer)){ | ||
1132 | io_req->map_fd = dev->fd; | ||
1133 | io_req->map_offset = io_req->offset + | ||
1134 | dev->cow.data_offset; | ||
1135 | dev->write_maps++; | ||
1136 | } | ||
1137 | else return(prepare_mmap_request(dev, fd, io_req->offset, req, | ||
1138 | io_req)); | ||
1139 | } | ||
1140 | |||
1141 | if(rq_data_dir(req) == READ) | ||
1142 | dev->nomap_reads++; | ||
1143 | else dev->nomap_writes++; | ||
1144 | |||
1145 | io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE; | 1000 | io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE; |
1146 | io_req->offsets[0] = 0; | 1001 | io_req->offsets[0] = 0; |
1147 | io_req->offsets[1] = dev->cow.data_offset; | 1002 | io_req->offsets[1] = dev->cow.data_offset; |
@@ -1229,143 +1084,6 @@ static int ubd_ioctl(struct inode * inode, struct file * file, | |||
1229 | return(-EINVAL); | 1084 | return(-EINVAL); |
1230 | } | 1085 | } |
1231 | 1086 | ||
1232 | static int ubd_check_remapped(int fd, unsigned long address, int is_write, | ||
1233 | __u64 offset) | ||
1234 | { | ||
1235 | __u64 bitmap_offset; | ||
1236 | unsigned long new_bitmap[2]; | ||
1237 | int i, err, n; | ||
1238 | |||
1239 | /* If it's not a write access, we can't do anything about it */ | ||
1240 | if(!is_write) | ||
1241 | return(0); | ||
1242 | |||
1243 | /* We have a write */ | ||
1244 | for(i = 0; i < sizeof(ubd_dev) / sizeof(ubd_dev[0]); i++){ | ||
1245 | struct ubd *dev = &ubd_dev[i]; | ||
1246 | |||
1247 | if((dev->fd != fd) && (dev->cow.fd != fd)) | ||
1248 | continue; | ||
1249 | |||
1250 | /* It's a write to a ubd device */ | ||
1251 | |||
1252 | /* This should be impossible now */ | ||
1253 | if(!dev->openflags.w){ | ||
1254 | /* It's a write access on a read-only device - probably | ||
1255 | * shouldn't happen. If the kernel is trying to change | ||
1256 | * something with no intention of writing it back out, | ||
1257 | * then this message will clue us in that this needs | ||
1258 | * fixing | ||
1259 | */ | ||
1260 | printk("Write access to mapped page from readonly ubd " | ||
1261 | "device %d\n", i); | ||
1262 | return(0); | ||
1263 | } | ||
1264 | |||
1265 | /* It's a write to a writeable ubd device - it must be COWed | ||
1266 | * because, otherwise, the page would have been mapped in | ||
1267 | * writeable | ||
1268 | */ | ||
1269 | |||
1270 | if(!dev->cow.file) | ||
1271 | panic("Write fault on writeable non-COW ubd device %d", | ||
1272 | i); | ||
1273 | |||
1274 | /* It should also be an access to the backing file since the | ||
1275 | * COW pages should be mapped in read-write | ||
1276 | */ | ||
1277 | |||
1278 | if(fd == dev->fd) | ||
1279 | panic("Write fault on a backing page of ubd " | ||
1280 | "device %d\n", i); | ||
1281 | |||
1282 | /* So, we do the write, copying the backing data to the COW | ||
1283 | * file... | ||
1284 | */ | ||
1285 | |||
1286 | err = os_seek_file(dev->fd, offset + dev->cow.data_offset); | ||
1287 | if(err < 0) | ||
1288 | panic("Couldn't seek to %lld in COW file of ubd " | ||
1289 | "device %d, err = %d", | ||
1290 | offset + dev->cow.data_offset, i, -err); | ||
1291 | |||
1292 | n = os_write_file(dev->fd, (void *) address, PAGE_SIZE); | ||
1293 | if(n != PAGE_SIZE) | ||
1294 | panic("Couldn't copy data to COW file of ubd " | ||
1295 | "device %d, err = %d", i, -n); | ||
1296 | |||
1297 | /* ... updating the COW bitmap... */ | ||
1298 | |||
1299 | cowify_bitmap(offset, PAGE_SIZE, NULL, &bitmap_offset, | ||
1300 | dev->cow.bitmap, dev->cow.bitmap_offset, | ||
1301 | new_bitmap, dev->cow.bitmap_len); | ||
1302 | |||
1303 | err = os_seek_file(dev->fd, bitmap_offset); | ||
1304 | if(err < 0) | ||
1305 | panic("Couldn't seek to %lld in COW file of ubd " | ||
1306 | "device %d, err = %d", bitmap_offset, i, -err); | ||
1307 | |||
1308 | n = os_write_file(dev->fd, new_bitmap, sizeof(new_bitmap)); | ||
1309 | if(n != sizeof(new_bitmap)) | ||
1310 | panic("Couldn't update bitmap of ubd device %d, " | ||
1311 | "err = %d", i, -n); | ||
1312 | |||
1313 | /* Maybe we can map the COW page in, and maybe we can't. If | ||
1314 | * it is a pre-V3 COW file, we can't, since the alignment will | ||
1315 | * be wrong. If it is a V3 or later COW file which has been | ||
1316 | * moved to a system with a larger page size, then maybe we | ||
1317 | * can't, depending on the exact location of the page. | ||
1318 | */ | ||
1319 | |||
1320 | offset += dev->cow.data_offset; | ||
1321 | |||
1322 | /* Remove the remapping, putting the original anonymous page | ||
1323 | * back. If the COW file can be mapped in, that is done. | ||
1324 | * Otherwise, the COW page is read in. | ||
1325 | */ | ||
1326 | |||
1327 | if(!physmem_remove_mapping((void *) address)) | ||
1328 | panic("Address 0x%lx not remapped by ubd device %d", | ||
1329 | address, i); | ||
1330 | if((offset % UBD_MMAP_BLOCK_SIZE) == 0) | ||
1331 | physmem_subst_mapping((void *) address, dev->fd, | ||
1332 | offset, 1); | ||
1333 | else { | ||
1334 | err = os_seek_file(dev->fd, offset); | ||
1335 | if(err < 0) | ||
1336 | panic("Couldn't seek to %lld in COW file of " | ||
1337 | "ubd device %d, err = %d", offset, i, | ||
1338 | -err); | ||
1339 | |||
1340 | n = os_read_file(dev->fd, (void *) address, PAGE_SIZE); | ||
1341 | if(n != PAGE_SIZE) | ||
1342 | panic("Failed to read page from offset %llx of " | ||
1343 | "COW file of ubd device %d, err = %d", | ||
1344 | offset, i, -n); | ||
1345 | } | ||
1346 | |||
1347 | return(1); | ||
1348 | } | ||
1349 | |||
1350 | /* It's not a write on a ubd device */ | ||
1351 | return(0); | ||
1352 | } | ||
1353 | |||
1354 | static struct remapper ubd_remapper = { | ||
1355 | .list = LIST_HEAD_INIT(ubd_remapper.list), | ||
1356 | .proc = ubd_check_remapped, | ||
1357 | }; | ||
1358 | |||
1359 | static int ubd_remapper_setup(void) | ||
1360 | { | ||
1361 | if(ubd_do_mmap) | ||
1362 | register_remapper(&ubd_remapper); | ||
1363 | |||
1364 | return(0); | ||
1365 | } | ||
1366 | |||
1367 | __initcall(ubd_remapper_setup); | ||
1368 | |||
1369 | static int same_backing_files(char *from_cmdline, char *from_cow, char *cow) | 1087 | static int same_backing_files(char *from_cmdline, char *from_cow, char *cow) |
1370 | { | 1088 | { |
1371 | struct uml_stat buf1, buf2; | 1089 | struct uml_stat buf1, buf2; |
@@ -1568,15 +1286,6 @@ void do_io(struct io_thread_req *req) | |||
1568 | int err; | 1286 | int err; |
1569 | __u64 off; | 1287 | __u64 off; |
1570 | 1288 | ||
1571 | if(req->op == UBD_MMAP){ | ||
1572 | /* Touch the page to force the host to do any necessary IO to | ||
1573 | * get it into memory | ||
1574 | */ | ||
1575 | n = *((volatile int *) req->buffer); | ||
1576 | req->error = update_bitmap(req); | ||
1577 | return; | ||
1578 | } | ||
1579 | |||
1580 | nsectors = req->length / req->sectorsize; | 1289 | nsectors = req->length / req->sectorsize; |
1581 | start = 0; | 1290 | start = 0; |
1582 | do { | 1291 | do { |
diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c index 7917b9d1cec8..a4fdf3584ad2 100644 --- a/arch/um/drivers/xterm_kern.c +++ b/arch/um/drivers/xterm_kern.c | |||
@@ -7,7 +7,6 @@ | |||
7 | #include "linux/slab.h" | 7 | #include "linux/slab.h" |
8 | #include "linux/signal.h" | 8 | #include "linux/signal.h" |
9 | #include "linux/interrupt.h" | 9 | #include "linux/interrupt.h" |
10 | #include "asm/semaphore.h" | ||
11 | #include "asm/irq.h" | 10 | #include "asm/irq.h" |
12 | #include "irq_user.h" | 11 | #include "irq_user.h" |
13 | #include "irq_kern.h" | 12 | #include "irq_kern.h" |
diff --git a/arch/um/include/2_5compat.h b/arch/um/include/2_5compat.h deleted file mode 100644 index abdb015a4d71..000000000000 --- a/arch/um/include/2_5compat.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #ifndef __2_5_COMPAT_H__ | ||
7 | #define __2_5_COMPAT_H__ | ||
8 | |||
9 | #define INIT_HARDSECT(arr, maj, sizes) | ||
10 | |||
11 | #define SET_PRI(task) do ; while(0) | ||
12 | |||
13 | #endif | ||
14 | |||
15 | /* | ||
16 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
17 | * Emacs will notice this stuff at the end of the file and automatically | ||
18 | * adjust the settings for this buffer only. This must remain at the end | ||
19 | * of the file. | ||
20 | * --------------------------------------------------------------------------- | ||
21 | * Local variables: | ||
22 | * c-file-style: "linux" | ||
23 | * End: | ||
24 | */ | ||
diff --git a/arch/um/include/common-offsets.h b/arch/um/include/common-offsets.h new file mode 100644 index 000000000000..d705daa2d854 --- /dev/null +++ b/arch/um/include/common-offsets.h | |||
@@ -0,0 +1,14 @@ | |||
1 | /* for use by sys-$SUBARCH/kernel-offsets.c */ | ||
2 | |||
3 | OFFSET(TASK_REGS, task_struct, thread.regs); | ||
4 | OFFSET(TASK_PID, task_struct, pid); | ||
5 | DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE); | ||
6 | DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC); | ||
7 | DEFINE_STR(UM_KERN_EMERG, KERN_EMERG); | ||
8 | DEFINE_STR(UM_KERN_ALERT, KERN_ALERT); | ||
9 | DEFINE_STR(UM_KERN_CRIT, KERN_CRIT); | ||
10 | DEFINE_STR(UM_KERN_ERR, KERN_ERR); | ||
11 | DEFINE_STR(UM_KERN_WARNING, KERN_WARNING); | ||
12 | DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE); | ||
13 | DEFINE_STR(UM_KERN_INFO, KERN_INFO); | ||
14 | DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG); | ||
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h index 15389c886b41..e5fec5570199 100644 --- a/arch/um/include/kern_util.h +++ b/arch/um/include/kern_util.h | |||
@@ -8,6 +8,7 @@ | |||
8 | 8 | ||
9 | #include "linux/threads.h" | 9 | #include "linux/threads.h" |
10 | #include "sysdep/ptrace.h" | 10 | #include "sysdep/ptrace.h" |
11 | #include "sysdep/faultinfo.h" | ||
11 | 12 | ||
12 | extern int ncpus; | 13 | extern int ncpus; |
13 | extern char *linux_prog; | 14 | extern char *linux_prog; |
@@ -31,8 +32,8 @@ extern int current_pid(void); | |||
31 | extern unsigned long alloc_stack(int order, int atomic); | 32 | extern unsigned long alloc_stack(int order, int atomic); |
32 | extern int do_signal(void); | 33 | extern int do_signal(void); |
33 | extern int is_stack_fault(unsigned long sp); | 34 | extern int is_stack_fault(unsigned long sp); |
34 | extern unsigned long segv(unsigned long address, unsigned long ip, | 35 | extern unsigned long segv(struct faultinfo fi, unsigned long ip, |
35 | int is_write, int is_user, void *sc); | 36 | int is_user, void *sc); |
36 | extern int handle_page_fault(unsigned long address, unsigned long ip, | 37 | extern int handle_page_fault(unsigned long address, unsigned long ip, |
37 | int is_write, int is_user, int *code_out); | 38 | int is_write, int is_user, int *code_out); |
38 | extern void syscall_ready(void); | 39 | extern void syscall_ready(void); |
@@ -82,7 +83,7 @@ extern void timer_irq(union uml_pt_regs *regs); | |||
82 | extern void unprotect_stack(unsigned long stack); | 83 | extern void unprotect_stack(unsigned long stack); |
83 | extern void do_uml_exitcalls(void); | 84 | extern void do_uml_exitcalls(void); |
84 | extern int attach_debugger(int idle_pid, int pid, int stop); | 85 | extern int attach_debugger(int idle_pid, int pid, int stop); |
85 | extern void bad_segv(unsigned long address, unsigned long ip, int is_write); | 86 | extern void bad_segv(struct faultinfo fi, unsigned long ip); |
86 | extern int config_gdb(char *str); | 87 | extern int config_gdb(char *str); |
87 | extern int remove_gdb(void); | 88 | extern int remove_gdb(void); |
88 | extern char *uml_strdup(char *string); | 89 | extern char *uml_strdup(char *string); |
diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h index 9fbe3083fdd8..cfa368e045a5 100644 --- a/arch/um/include/mconsole.h +++ b/arch/um/include/mconsole.h | |||
@@ -56,7 +56,7 @@ struct mc_request | |||
56 | int as_interrupt; | 56 | int as_interrupt; |
57 | 57 | ||
58 | int originating_fd; | 58 | int originating_fd; |
59 | int originlen; | 59 | unsigned int originlen; |
60 | unsigned char origin[128]; /* sockaddr_un */ | 60 | unsigned char origin[128]; /* sockaddr_un */ |
61 | 61 | ||
62 | struct mconsole_request request; | 62 | struct mconsole_request request; |
diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h index 36807b796e9f..89885a77a771 100644 --- a/arch/um/include/net_user.h +++ b/arch/um/include/net_user.h | |||
@@ -35,7 +35,7 @@ extern void *get_output_buffer(int *len_out); | |||
35 | extern void free_output_buffer(void *buffer); | 35 | extern void free_output_buffer(void *buffer); |
36 | 36 | ||
37 | extern int tap_open_common(void *dev, char *gate_addr); | 37 | extern int tap_open_common(void *dev, char *gate_addr); |
38 | extern void tap_check_ips(char *gate_addr, char *eth_addr); | 38 | extern void tap_check_ips(char *gate_addr, unsigned char *eth_addr); |
39 | 39 | ||
40 | extern void read_output(int fd, char *output_out, int len); | 40 | extern void read_output(int fd, char *output_out, int len); |
41 | 41 | ||
diff --git a/arch/um/include/os.h b/arch/um/include/os.h index 07340c8cf203..881d2988d2d8 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h | |||
@@ -136,7 +136,7 @@ extern int os_seek_file(int fd, __u64 offset); | |||
136 | extern int os_open_file(char *file, struct openflags flags, int mode); | 136 | extern int os_open_file(char *file, struct openflags flags, int mode); |
137 | extern int os_read_file(int fd, void *buf, int len); | 137 | extern int os_read_file(int fd, void *buf, int len); |
138 | extern int os_write_file(int fd, const void *buf, int count); | 138 | extern int os_write_file(int fd, const void *buf, int count); |
139 | extern int os_file_size(char *file, long long *size_out); | 139 | extern int os_file_size(char *file, unsigned long long *size_out); |
140 | extern int os_file_modtime(char *file, unsigned long *modtime); | 140 | extern int os_file_modtime(char *file, unsigned long *modtime); |
141 | extern int os_pipe(int *fd, int stream, int close_on_exec); | 141 | extern int os_pipe(int *fd, int stream, int close_on_exec); |
142 | extern int os_set_fd_async(int fd, int owner); | 142 | extern int os_set_fd_async(int fd, int owner); |
@@ -160,6 +160,7 @@ extern void os_kill_process(int pid, int reap_child); | |||
160 | extern void os_kill_ptraced_process(int pid, int reap_child); | 160 | extern void os_kill_ptraced_process(int pid, int reap_child); |
161 | extern void os_usr1_process(int pid); | 161 | extern void os_usr1_process(int pid); |
162 | extern int os_getpid(void); | 162 | extern int os_getpid(void); |
163 | extern int os_getpgrp(void); | ||
163 | 164 | ||
164 | extern int os_map_memory(void *virt, int fd, unsigned long long off, | 165 | extern int os_map_memory(void *virt, int fd, unsigned long long off, |
165 | unsigned long len, int r, int w, int x); | 166 | unsigned long len, int r, int w, int x); |
diff --git a/arch/um/include/skas_ptrace.h b/arch/um/include/skas_ptrace.h index cfb5fb4f5b91..cd2327d09c8d 100644 --- a/arch/um/include/skas_ptrace.h +++ b/arch/um/include/skas_ptrace.h | |||
@@ -6,22 +6,11 @@ | |||
6 | #ifndef __SKAS_PTRACE_H | 6 | #ifndef __SKAS_PTRACE_H |
7 | #define __SKAS_PTRACE_H | 7 | #define __SKAS_PTRACE_H |
8 | 8 | ||
9 | struct ptrace_faultinfo { | ||
10 | int is_write; | ||
11 | unsigned long addr; | ||
12 | }; | ||
13 | |||
14 | struct ptrace_ldt { | ||
15 | int func; | ||
16 | void *ptr; | ||
17 | unsigned long bytecount; | ||
18 | }; | ||
19 | |||
20 | #define PTRACE_FAULTINFO 52 | 9 | #define PTRACE_FAULTINFO 52 |
21 | #define PTRACE_SIGPENDING 53 | ||
22 | #define PTRACE_LDT 54 | ||
23 | #define PTRACE_SWITCH_MM 55 | 10 | #define PTRACE_SWITCH_MM 55 |
24 | 11 | ||
12 | #include "sysdep/skas_ptrace.h" | ||
13 | |||
25 | #endif | 14 | #endif |
26 | 15 | ||
27 | /* | 16 | /* |
diff --git a/arch/um/include/sysdep-i386/checksum.h b/arch/um/include/sysdep-i386/checksum.h index 3a2a45811aa3..764ba4db4788 100644 --- a/arch/um/include/sysdep-i386/checksum.h +++ b/arch/um/include/sysdep-i386/checksum.h | |||
@@ -24,19 +24,6 @@ unsigned int csum_partial(const unsigned char * buff, int len, | |||
24 | unsigned int sum); | 24 | unsigned int sum); |
25 | 25 | ||
26 | /* | 26 | /* |
27 | * the same as csum_partial, but copies from src while it | ||
28 | * checksums, and handles user-space pointer exceptions correctly, when needed. | ||
29 | * | ||
30 | * here even more important to align src and dst on a 32-bit (or even | ||
31 | * better 64-bit) boundary | ||
32 | */ | ||
33 | |||
34 | unsigned int csum_partial_copy_to(const unsigned char *src, unsigned char *dst, | ||
35 | int len, int sum, int *err_ptr); | ||
36 | unsigned int csum_partial_copy_from(const unsigned char *src, unsigned char *dst, | ||
37 | int len, int sum, int *err_ptr); | ||
38 | |||
39 | /* | ||
40 | * Note: when you get a NULL pointer exception here this means someone | 27 | * Note: when you get a NULL pointer exception here this means someone |
41 | * passed in an incorrect kernel address to one of these functions. | 28 | * passed in an incorrect kernel address to one of these functions. |
42 | * | 29 | * |
@@ -52,11 +39,24 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char * | |||
52 | return(csum_partial(dst, len, sum)); | 39 | return(csum_partial(dst, len, sum)); |
53 | } | 40 | } |
54 | 41 | ||
42 | /* | ||
43 | * the same as csum_partial, but copies from src while it | ||
44 | * checksums, and handles user-space pointer exceptions correctly, when needed. | ||
45 | * | ||
46 | * here even more important to align src and dst on a 32-bit (or even | ||
47 | * better 64-bit) boundary | ||
48 | */ | ||
49 | |||
55 | static __inline__ | 50 | static __inline__ |
56 | unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, | 51 | unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, |
57 | int len, int sum, int *err_ptr) | 52 | int len, int sum, int *err_ptr) |
58 | { | 53 | { |
59 | return csum_partial_copy_from(src, dst, len, sum, err_ptr); | 54 | if(copy_from_user(dst, src, len)){ |
55 | *err_ptr = -EFAULT; | ||
56 | return(-1); | ||
57 | } | ||
58 | |||
59 | return csum_partial(dst, len, sum); | ||
60 | } | 60 | } |
61 | 61 | ||
62 | /* | 62 | /* |
@@ -67,7 +67,6 @@ unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char | |||
67 | */ | 67 | */ |
68 | 68 | ||
69 | #define csum_partial_copy_fromuser csum_partial_copy_from_user | 69 | #define csum_partial_copy_fromuser csum_partial_copy_from_user |
70 | unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst, int len, int sum); | ||
71 | 70 | ||
72 | /* | 71 | /* |
73 | * This is a version of ip_compute_csum() optimized for IP headers, | 72 | * This is a version of ip_compute_csum() optimized for IP headers, |
@@ -196,8 +195,14 @@ static __inline__ unsigned int csum_and_copy_to_user(const unsigned char *src, | |||
196 | unsigned char *dst, | 195 | unsigned char *dst, |
197 | int len, int sum, int *err_ptr) | 196 | int len, int sum, int *err_ptr) |
198 | { | 197 | { |
199 | if (access_ok(VERIFY_WRITE, dst, len)) | 198 | if (access_ok(VERIFY_WRITE, dst, len)){ |
200 | return(csum_partial_copy_to(src, dst, len, sum, err_ptr)); | 199 | if(copy_to_user(dst, src, len)){ |
200 | *err_ptr = -EFAULT; | ||
201 | return(-1); | ||
202 | } | ||
203 | |||
204 | return csum_partial(src, len, sum); | ||
205 | } | ||
201 | 206 | ||
202 | if (len) | 207 | if (len) |
203 | *err_ptr = -EFAULT; | 208 | *err_ptr = -EFAULT; |
diff --git a/arch/um/include/sysdep-i386/faultinfo.h b/arch/um/include/sysdep-i386/faultinfo.h new file mode 100644 index 000000000000..db437cc373bc --- /dev/null +++ b/arch/um/include/sysdep-i386/faultinfo.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004 Fujitsu Siemens Computers GmbH | ||
3 | * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com> | ||
4 | * Licensed under the GPL | ||
5 | */ | ||
6 | |||
7 | #ifndef __FAULTINFO_I386_H | ||
8 | #define __FAULTINFO_I386_H | ||
9 | |||
10 | /* this structure contains the full arch-specific faultinfo | ||
11 | * from the traps. | ||
12 | * On i386, ptrace_faultinfo unfortunately doesn't provide | ||
13 | * all the info, since trap_no is missing. | ||
14 | * All common elements are defined at the same position in | ||
15 | * both structures, thus making it easy to copy the | ||
16 | * contents without knowledge about the structure elements. | ||
17 | */ | ||
18 | struct faultinfo { | ||
19 | int error_code; /* in ptrace_faultinfo misleadingly called is_write */ | ||
20 | unsigned long cr2; /* in ptrace_faultinfo called addr */ | ||
21 | int trap_no; /* missing in ptrace_faultinfo */ | ||
22 | }; | ||
23 | |||
24 | #define FAULT_WRITE(fi) ((fi).error_code & 2) | ||
25 | #define FAULT_ADDRESS(fi) ((fi).cr2) | ||
26 | |||
27 | #define PTRACE_FULL_FAULTINFO 0 | ||
28 | |||
29 | #endif | ||
diff --git a/arch/um/include/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h index 661d495e2044..c8ee9559f3ab 100644 --- a/arch/um/include/sysdep-i386/ptrace.h +++ b/arch/um/include/sysdep-i386/ptrace.h | |||
@@ -8,6 +8,8 @@ | |||
8 | 8 | ||
9 | #include "uml-config.h" | 9 | #include "uml-config.h" |
10 | #include "user_constants.h" | 10 | #include "user_constants.h" |
11 | #include "sysdep/faultinfo.h" | ||
12 | #include "choose-mode.h" | ||
11 | 13 | ||
12 | #define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long)) | 14 | #define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long)) |
13 | #define MAX_REG_OFFSET (UM_FRAME_SIZE) | 15 | #define MAX_REG_OFFSET (UM_FRAME_SIZE) |
@@ -53,24 +55,17 @@ extern int sysemu_supported; | |||
53 | 55 | ||
54 | #define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) | 56 | #define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) |
55 | 57 | ||
56 | #define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type) | ||
57 | |||
58 | #define REGS_FAULT_ADDR(r) ((r)->fault_addr) | ||
59 | |||
60 | #define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type) | ||
61 | |||
62 | #endif | 58 | #endif |
63 | #ifndef PTRACE_SYSEMU_SINGLESTEP | 59 | #ifndef PTRACE_SYSEMU_SINGLESTEP |
64 | #define PTRACE_SYSEMU_SINGLESTEP 32 | 60 | #define PTRACE_SYSEMU_SINGLESTEP 32 |
65 | #endif | 61 | #endif |
66 | 62 | ||
67 | #include "choose-mode.h" | ||
68 | |||
69 | union uml_pt_regs { | 63 | union uml_pt_regs { |
70 | #ifdef UML_CONFIG_MODE_TT | 64 | #ifdef UML_CONFIG_MODE_TT |
71 | struct tt_regs { | 65 | struct tt_regs { |
72 | long syscall; | 66 | long syscall; |
73 | void *sc; | 67 | void *sc; |
68 | struct faultinfo faultinfo; | ||
74 | } tt; | 69 | } tt; |
75 | #endif | 70 | #endif |
76 | #ifdef UML_CONFIG_MODE_SKAS | 71 | #ifdef UML_CONFIG_MODE_SKAS |
@@ -78,9 +73,7 @@ union uml_pt_regs { | |||
78 | unsigned long regs[HOST_FRAME_SIZE]; | 73 | unsigned long regs[HOST_FRAME_SIZE]; |
79 | unsigned long fp[HOST_FP_SIZE]; | 74 | unsigned long fp[HOST_FP_SIZE]; |
80 | unsigned long xfp[HOST_XFP_SIZE]; | 75 | unsigned long xfp[HOST_XFP_SIZE]; |
81 | unsigned long fault_addr; | 76 | struct faultinfo faultinfo; |
82 | unsigned long fault_type; | ||
83 | unsigned long trap_type; | ||
84 | long syscall; | 77 | long syscall; |
85 | int is_user; | 78 | int is_user; |
86 | } skas; | 79 | } skas; |
@@ -217,15 +210,8 @@ struct syscall_args { | |||
217 | #define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r) | 210 | #define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r) |
218 | #define UPT_SYSCALL_RET(r) UPT_EAX(r) | 211 | #define UPT_SYSCALL_RET(r) UPT_EAX(r) |
219 | 212 | ||
220 | #define UPT_SEGV_IS_FIXABLE(r) \ | 213 | #define UPT_FAULTINFO(r) \ |
221 | CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \ | 214 | CHOOSE_MODE((&(r)->tt.faultinfo), (&(r)->skas.faultinfo)) |
222 | REGS_SEGV_IS_FIXABLE(&r->skas)) | ||
223 | |||
224 | #define UPT_FAULT_ADDR(r) \ | ||
225 | __CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas)) | ||
226 | |||
227 | #define UPT_FAULT_WRITE(r) \ | ||
228 | CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas)) | ||
229 | 215 | ||
230 | #endif | 216 | #endif |
231 | 217 | ||
diff --git a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h index dfee589de360..1fe729265167 100644 --- a/arch/um/include/sysdep-i386/sigcontext.h +++ b/arch/um/include/sysdep-i386/sigcontext.h | |||
@@ -13,15 +13,12 @@ | |||
13 | #define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc)) | 13 | #define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc)) |
14 | #define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result) | 14 | #define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result) |
15 | 15 | ||
16 | #define SC_FAULT_ADDR(sc) SC_CR2(sc) | 16 | #define GET_FAULTINFO_FROM_SC(fi,sc) \ |
17 | #define SC_FAULT_TYPE(sc) SC_ERR(sc) | 17 | { \ |
18 | 18 | (fi).cr2 = SC_CR2(sc); \ | |
19 | #define FAULT_WRITE(err) (err & 2) | 19 | (fi).error_code = SC_ERR(sc); \ |
20 | #define TO_SC_ERR(is_write) ((is_write) ? 2 : 0) | 20 | (fi).trap_no = SC_TRAPNO(sc); \ |
21 | 21 | } | |
22 | #define SC_FAULT_WRITE(sc) (FAULT_WRITE(SC_ERR(sc))) | ||
23 | |||
24 | #define SC_TRAP_TYPE(sc) SC_TRAPNO(sc) | ||
25 | 22 | ||
26 | /* ptrace expects that, at the start of a system call, %eax contains | 23 | /* ptrace expects that, at the start of a system call, %eax contains |
27 | * -ENOSYS, so this makes it so. | 24 | * -ENOSYS, so this makes it so. |
@@ -29,9 +26,7 @@ | |||
29 | #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0) | 26 | #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0) |
30 | 27 | ||
31 | /* This is Page Fault */ | 28 | /* This is Page Fault */ |
32 | #define SEGV_IS_FIXABLE(trap) (trap == 14) | 29 | #define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) |
33 | |||
34 | #define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc))) | ||
35 | 30 | ||
36 | extern unsigned long *sc_sigmask(void *sc_ptr); | 31 | extern unsigned long *sc_sigmask(void *sc_ptr); |
37 | extern int sc_get_fpregs(unsigned long buf, void *sc_ptr); | 32 | extern int sc_get_fpregs(unsigned long buf, void *sc_ptr); |
diff --git a/arch/um/include/sysdep-i386/signal.h b/arch/um/include/sysdep-i386/signal.h index b1e1f7a77499..07518b162136 100644 --- a/arch/um/include/sysdep-i386/signal.h +++ b/arch/um/include/sysdep-i386/signal.h | |||
@@ -8,6 +8,8 @@ | |||
8 | 8 | ||
9 | #include <signal.h> | 9 | #include <signal.h> |
10 | 10 | ||
11 | #define ARCH_SIGHDLR_PARAM int sig | ||
12 | |||
11 | #define ARCH_GET_SIGCONTEXT(sc, sig) \ | 13 | #define ARCH_GET_SIGCONTEXT(sc, sig) \ |
12 | do sc = (struct sigcontext *) (&sig + 1); while(0) | 14 | do sc = (struct sigcontext *) (&sig + 1); while(0) |
13 | 15 | ||
diff --git a/arch/um/include/sysdep-i386/skas_ptrace.h b/arch/um/include/sysdep-i386/skas_ptrace.h new file mode 100644 index 000000000000..e27b8a791773 --- /dev/null +++ b/arch/um/include/sysdep-i386/skas_ptrace.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #ifndef __SYSDEP_I386_SKAS_PTRACE_H | ||
7 | #define __SYSDEP_I386_SKAS_PTRACE_H | ||
8 | |||
9 | struct ptrace_faultinfo { | ||
10 | int is_write; | ||
11 | unsigned long addr; | ||
12 | }; | ||
13 | |||
14 | struct ptrace_ldt { | ||
15 | int func; | ||
16 | void *ptr; | ||
17 | unsigned long bytecount; | ||
18 | }; | ||
19 | |||
20 | #define PTRACE_LDT 54 | ||
21 | |||
22 | #endif | ||
diff --git a/arch/um/include/sysdep-ia64/skas_ptrace.h b/arch/um/include/sysdep-ia64/skas_ptrace.h new file mode 100644 index 000000000000..25a38e715702 --- /dev/null +++ b/arch/um/include/sysdep-ia64/skas_ptrace.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #ifndef __SYSDEP_IA64_SKAS_PTRACE_H | ||
7 | #define __SYSDEP_IA64_SKAS_PTRACE_H | ||
8 | |||
9 | struct ptrace_faultinfo { | ||
10 | int is_write; | ||
11 | unsigned long addr; | ||
12 | }; | ||
13 | |||
14 | struct ptrace_ldt { | ||
15 | int func; | ||
16 | void *ptr; | ||
17 | unsigned long bytecount; | ||
18 | }; | ||
19 | |||
20 | #define PTRACE_LDT 54 | ||
21 | |||
22 | #endif | ||
diff --git a/arch/um/include/sysdep-ppc/skas_ptrace.h b/arch/um/include/sysdep-ppc/skas_ptrace.h new file mode 100644 index 000000000000..d9fbbac10de0 --- /dev/null +++ b/arch/um/include/sysdep-ppc/skas_ptrace.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #ifndef __SYSDEP_PPC_SKAS_PTRACE_H | ||
7 | #define __SYSDEP_PPC_SKAS_PTRACE_H | ||
8 | |||
9 | struct ptrace_faultinfo { | ||
10 | int is_write; | ||
11 | unsigned long addr; | ||
12 | }; | ||
13 | |||
14 | struct ptrace_ldt { | ||
15 | int func; | ||
16 | void *ptr; | ||
17 | unsigned long bytecount; | ||
18 | }; | ||
19 | |||
20 | #define PTRACE_LDT 54 | ||
21 | |||
22 | #endif | ||
diff --git a/arch/um/include/sysdep-x86_64/checksum.h b/arch/um/include/sysdep-x86_64/checksum.h index 572c6c19be33..ea97005af694 100644 --- a/arch/um/include/sysdep-x86_64/checksum.h +++ b/arch/um/include/sysdep-x86_64/checksum.h | |||
@@ -9,8 +9,6 @@ | |||
9 | #include "linux/in6.h" | 9 | #include "linux/in6.h" |
10 | #include "asm/uaccess.h" | 10 | #include "asm/uaccess.h" |
11 | 11 | ||
12 | extern unsigned int csum_partial_copy_from(const unsigned char *src, unsigned char *dst, int len, | ||
13 | int sum, int *err_ptr); | ||
14 | extern unsigned csum_partial(const unsigned char *buff, unsigned len, | 12 | extern unsigned csum_partial(const unsigned char *buff, unsigned len, |
15 | unsigned sum); | 13 | unsigned sum); |
16 | 14 | ||
@@ -31,10 +29,15 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char * | |||
31 | } | 29 | } |
32 | 30 | ||
33 | static __inline__ | 31 | static __inline__ |
34 | unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, | 32 | unsigned int csum_partial_copy_from_user(const unsigned char *src, |
35 | int len, int sum, int *err_ptr) | 33 | unsigned char *dst, int len, int sum, |
34 | int *err_ptr) | ||
36 | { | 35 | { |
37 | return csum_partial_copy_from(src, dst, len, sum, err_ptr); | 36 | if(copy_from_user(dst, src, len)){ |
37 | *err_ptr = -EFAULT; | ||
38 | return(-1); | ||
39 | } | ||
40 | return csum_partial(dst, len, sum); | ||
38 | } | 41 | } |
39 | 42 | ||
40 | /** | 43 | /** |
@@ -137,15 +140,6 @@ static inline unsigned add32_with_carry(unsigned a, unsigned b) | |||
137 | return a; | 140 | return a; |
138 | } | 141 | } |
139 | 142 | ||
140 | #endif | 143 | extern unsigned short ip_compute_csum(unsigned char * buff, int len); |
141 | 144 | ||
142 | /* | 145 | #endif |
143 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
144 | * Emacs will notice this stuff at the end of the file and automatically | ||
145 | * adjust the settings for this buffer only. This must remain at the end | ||
146 | * of the file. | ||
147 | * --------------------------------------------------------------------------- | ||
148 | * Local variables: | ||
149 | * c-file-style: "linux" | ||
150 | * End: | ||
151 | */ | ||
diff --git a/arch/um/include/sysdep-x86_64/faultinfo.h b/arch/um/include/sysdep-x86_64/faultinfo.h new file mode 100644 index 000000000000..cb917b0d5660 --- /dev/null +++ b/arch/um/include/sysdep-x86_64/faultinfo.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004 Fujitsu Siemens Computers GmbH | ||
3 | * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com> | ||
4 | * Licensed under the GPL | ||
5 | */ | ||
6 | |||
7 | #ifndef __FAULTINFO_X86_64_H | ||
8 | #define __FAULTINFO_X86_64_H | ||
9 | |||
10 | /* this structure contains the full arch-specific faultinfo | ||
11 | * from the traps. | ||
12 | * On i386, ptrace_faultinfo unfortunately doesn't provide | ||
13 | * all the info, since trap_no is missing. | ||
14 | * All common elements are defined at the same position in | ||
15 | * both structures, thus making it easy to copy the | ||
16 | * contents without knowledge about the structure elements. | ||
17 | */ | ||
18 | struct faultinfo { | ||
19 | int error_code; /* in ptrace_faultinfo misleadingly called is_write */ | ||
20 | unsigned long cr2; /* in ptrace_faultinfo called addr */ | ||
21 | int trap_no; /* missing in ptrace_faultinfo */ | ||
22 | }; | ||
23 | |||
24 | #define FAULT_WRITE(fi) ((fi).error_code & 2) | ||
25 | #define FAULT_ADDRESS(fi) ((fi).cr2) | ||
26 | |||
27 | #define PTRACE_FULL_FAULTINFO 1 | ||
28 | |||
29 | #endif | ||
diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h index 915c82daffbd..be8acd5efd97 100644 --- a/arch/um/include/sysdep-x86_64/ptrace.h +++ b/arch/um/include/sysdep-x86_64/ptrace.h | |||
@@ -9,6 +9,7 @@ | |||
9 | 9 | ||
10 | #include "uml-config.h" | 10 | #include "uml-config.h" |
11 | #include "user_constants.h" | 11 | #include "user_constants.h" |
12 | #include "sysdep/faultinfo.h" | ||
12 | 13 | ||
13 | #define MAX_REG_OFFSET (UM_FRAME_SIZE) | 14 | #define MAX_REG_OFFSET (UM_FRAME_SIZE) |
14 | #define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long)) | 15 | #define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long)) |
@@ -83,6 +84,7 @@ union uml_pt_regs { | |||
83 | long syscall; | 84 | long syscall; |
84 | unsigned long orig_rax; | 85 | unsigned long orig_rax; |
85 | void *sc; | 86 | void *sc; |
87 | struct faultinfo faultinfo; | ||
86 | } tt; | 88 | } tt; |
87 | #endif | 89 | #endif |
88 | #ifdef UML_CONFIG_MODE_SKAS | 90 | #ifdef UML_CONFIG_MODE_SKAS |
@@ -90,9 +92,7 @@ union uml_pt_regs { | |||
90 | /* XXX */ | 92 | /* XXX */ |
91 | unsigned long regs[27]; | 93 | unsigned long regs[27]; |
92 | unsigned long fp[65]; | 94 | unsigned long fp[65]; |
93 | unsigned long fault_addr; | 95 | struct faultinfo faultinfo; |
94 | unsigned long fault_type; | ||
95 | unsigned long trap_type; | ||
96 | long syscall; | 96 | long syscall; |
97 | int is_user; | 97 | int is_user; |
98 | } skas; | 98 | } skas; |
@@ -135,6 +135,7 @@ extern int mode_tt; | |||
135 | __CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs)) | 135 | __CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs)) |
136 | #define UPT_SC(r) ((r)->tt.sc) | 136 | #define UPT_SC(r) ((r)->tt.sc) |
137 | #define UPT_SYSCALL_NR(r) __CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall) | 137 | #define UPT_SYSCALL_NR(r) __CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall) |
138 | #define UPT_SYSCALL_RET(r) UPT_RAX(r) | ||
138 | 139 | ||
139 | extern int user_context(unsigned long sp); | 140 | extern int user_context(unsigned long sp); |
140 | 141 | ||
@@ -196,32 +197,32 @@ struct syscall_args { | |||
196 | 197 | ||
197 | 198 | ||
198 | #define UPT_SET(regs, reg, val) \ | 199 | #define UPT_SET(regs, reg, val) \ |
199 | ({ unsigned long val; \ | 200 | ({ unsigned long __upt_val = val; \ |
200 | switch(reg){ \ | 201 | switch(reg){ \ |
201 | case R8: UPT_R8(regs) = val; break; \ | 202 | case R8: UPT_R8(regs) = __upt_val; break; \ |
202 | case R9: UPT_R9(regs) = val; break; \ | 203 | case R9: UPT_R9(regs) = __upt_val; break; \ |
203 | case R10: UPT_R10(regs) = val; break; \ | 204 | case R10: UPT_R10(regs) = __upt_val; break; \ |
204 | case R11: UPT_R11(regs) = val; break; \ | 205 | case R11: UPT_R11(regs) = __upt_val; break; \ |
205 | case R12: UPT_R12(regs) = val; break; \ | 206 | case R12: UPT_R12(regs) = __upt_val; break; \ |
206 | case R13: UPT_R13(regs) = val; break; \ | 207 | case R13: UPT_R13(regs) = __upt_val; break; \ |
207 | case R14: UPT_R14(regs) = val; break; \ | 208 | case R14: UPT_R14(regs) = __upt_val; break; \ |
208 | case R15: UPT_R15(regs) = val; break; \ | 209 | case R15: UPT_R15(regs) = __upt_val; break; \ |
209 | case RIP: UPT_IP(regs) = val; break; \ | 210 | case RIP: UPT_IP(regs) = __upt_val; break; \ |
210 | case RSP: UPT_SP(regs) = val; break; \ | 211 | case RSP: UPT_SP(regs) = __upt_val; break; \ |
211 | case RAX: UPT_RAX(regs) = val; break; \ | 212 | case RAX: UPT_RAX(regs) = __upt_val; break; \ |
212 | case RBX: UPT_RBX(regs) = val; break; \ | 213 | case RBX: UPT_RBX(regs) = __upt_val; break; \ |
213 | case RCX: UPT_RCX(regs) = val; break; \ | 214 | case RCX: UPT_RCX(regs) = __upt_val; break; \ |
214 | case RDX: UPT_RDX(regs) = val; break; \ | 215 | case RDX: UPT_RDX(regs) = __upt_val; break; \ |
215 | case RSI: UPT_RSI(regs) = val; break; \ | 216 | case RSI: UPT_RSI(regs) = __upt_val; break; \ |
216 | case RDI: UPT_RDI(regs) = val; break; \ | 217 | case RDI: UPT_RDI(regs) = __upt_val; break; \ |
217 | case RBP: UPT_RBP(regs) = val; break; \ | 218 | case RBP: UPT_RBP(regs) = __upt_val; break; \ |
218 | case ORIG_RAX: UPT_ORIG_RAX(regs) = val; break; \ | 219 | case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \ |
219 | case CS: UPT_CS(regs) = val; break; \ | 220 | case CS: UPT_CS(regs) = __upt_val; break; \ |
220 | case DS: UPT_DS(regs) = val; break; \ | 221 | case DS: UPT_DS(regs) = __upt_val; break; \ |
221 | case ES: UPT_ES(regs) = val; break; \ | 222 | case ES: UPT_ES(regs) = __upt_val; break; \ |
222 | case FS: UPT_FS(regs) = val; break; \ | 223 | case FS: UPT_FS(regs) = __upt_val; break; \ |
223 | case GS: UPT_GS(regs) = val; break; \ | 224 | case GS: UPT_GS(regs) = __upt_val; break; \ |
224 | case EFLAGS: UPT_EFLAGS(regs) = val; break; \ | 225 | case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \ |
225 | default : \ | 226 | default : \ |
226 | panic("Bad register in UPT_SET : %d\n", reg); \ | 227 | panic("Bad register in UPT_SET : %d\n", reg); \ |
227 | break; \ | 228 | break; \ |
@@ -241,24 +242,7 @@ struct syscall_args { | |||
241 | CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \ | 242 | CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \ |
242 | REGS_SEGV_IS_FIXABLE(&r->skas)) | 243 | REGS_SEGV_IS_FIXABLE(&r->skas)) |
243 | 244 | ||
244 | #define UPT_FAULT_ADDR(r) \ | 245 | #define UPT_FAULTINFO(r) \ |
245 | __CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas)) | 246 | CHOOSE_MODE((&(r)->tt.faultinfo), (&(r)->skas.faultinfo)) |
246 | |||
247 | #define UPT_FAULT_WRITE(r) \ | ||
248 | CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas)) | ||
249 | |||
250 | #define UPT_TRAP(r) __CHOOSE_MODE(SC_TRAP_TYPE(UPT_SC(r)), REGS_TRAP(&r->skas)) | ||
251 | #define UPT_ERR(r) __CHOOSE_MODE(SC_FAULT_TYPE(UPT_SC(r)), REGS_ERR(&r->skas)) | ||
252 | 247 | ||
253 | #endif | 248 | #endif |
254 | |||
255 | /* | ||
256 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
257 | * Emacs will notice this stuff at the end of the file and automatically | ||
258 | * adjust the settings for this buffer only. This must remain at the end | ||
259 | * of the file. | ||
260 | * --------------------------------------------------------------------------- | ||
261 | * Local variables: | ||
262 | * c-file-style: "linux" | ||
263 | * End: | ||
264 | */ | ||
diff --git a/arch/um/include/sysdep-x86_64/sigcontext.h b/arch/um/include/sysdep-x86_64/sigcontext.h index 1e38a54ff4cf..2a78260d15a0 100644 --- a/arch/um/include/sysdep-x86_64/sigcontext.h +++ b/arch/um/include/sysdep-x86_64/sigcontext.h | |||
@@ -17,11 +17,12 @@ | |||
17 | #define SC_FAULT_ADDR(sc) SC_CR2(sc) | 17 | #define SC_FAULT_ADDR(sc) SC_CR2(sc) |
18 | #define SC_FAULT_TYPE(sc) SC_ERR(sc) | 18 | #define SC_FAULT_TYPE(sc) SC_ERR(sc) |
19 | 19 | ||
20 | #define FAULT_WRITE(err) ((err) & 2) | 20 | #define GET_FAULTINFO_FROM_SC(fi,sc) \ |
21 | 21 | { \ | |
22 | #define SC_FAULT_WRITE(sc) FAULT_WRITE(SC_FAULT_TYPE(sc)) | 22 | (fi).cr2 = SC_CR2(sc); \ |
23 | 23 | (fi).error_code = SC_ERR(sc); \ | |
24 | #define SC_TRAP_TYPE(sc) SC_TRAPNO(sc) | 24 | (fi).trap_no = SC_TRAPNO(sc); \ |
25 | } | ||
25 | 26 | ||
26 | /* ptrace expects that, at the start of a system call, %eax contains | 27 | /* ptrace expects that, at the start of a system call, %eax contains |
27 | * -ENOSYS, so this makes it so. | 28 | * -ENOSYS, so this makes it so. |
@@ -29,8 +30,8 @@ | |||
29 | 30 | ||
30 | #define SC_START_SYSCALL(sc) do SC_RAX(sc) = -ENOSYS; while(0) | 31 | #define SC_START_SYSCALL(sc) do SC_RAX(sc) = -ENOSYS; while(0) |
31 | 32 | ||
32 | #define SEGV_IS_FIXABLE(trap) ((trap) == 14) | 33 | /* This is Page Fault */ |
33 | #define SC_SEGV_IS_FIXABLE(sc) SEGV_IS_FIXABLE(SC_TRAP_TYPE(sc)) | 34 | #define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) |
34 | 35 | ||
35 | extern unsigned long *sc_sigmask(void *sc_ptr); | 36 | extern unsigned long *sc_sigmask(void *sc_ptr); |
36 | 37 | ||
diff --git a/arch/um/include/sysdep-x86_64/signal.h b/arch/um/include/sysdep-x86_64/signal.h index e5e52756fab4..6142897af3d1 100644 --- a/arch/um/include/sysdep-x86_64/signal.h +++ b/arch/um/include/sysdep-x86_64/signal.h | |||
@@ -6,6 +6,8 @@ | |||
6 | #ifndef __X86_64_SIGNAL_H_ | 6 | #ifndef __X86_64_SIGNAL_H_ |
7 | #define __X86_64_SIGNAL_H_ | 7 | #define __X86_64_SIGNAL_H_ |
8 | 8 | ||
9 | #define ARCH_SIGHDLR_PARAM int sig | ||
10 | |||
9 | #define ARCH_GET_SIGCONTEXT(sc, sig_addr) \ | 11 | #define ARCH_GET_SIGCONTEXT(sc, sig_addr) \ |
10 | do { \ | 12 | do { \ |
11 | struct ucontext *__uc; \ | 13 | struct ucontext *__uc; \ |
diff --git a/arch/um/include/sysdep-x86_64/skas_ptrace.h b/arch/um/include/sysdep-x86_64/skas_ptrace.h new file mode 100644 index 000000000000..95db4be786e4 --- /dev/null +++ b/arch/um/include/sysdep-x86_64/skas_ptrace.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #ifndef __SYSDEP_X86_64_SKAS_PTRACE_H | ||
7 | #define __SYSDEP_X86_64_SKAS_PTRACE_H | ||
8 | |||
9 | struct ptrace_faultinfo { | ||
10 | int is_write; | ||
11 | unsigned long addr; | ||
12 | }; | ||
13 | |||
14 | struct ptrace_ldt { | ||
15 | int func; | ||
16 | void *ptr; | ||
17 | unsigned long bytecount; | ||
18 | }; | ||
19 | |||
20 | #define PTRACE_LDT 54 | ||
21 | |||
22 | #endif | ||
diff --git a/arch/um/include/sysrq.h b/arch/um/include/sysrq.h index 2ce9423460b3..c8d332b56b98 100644 --- a/arch/um/include/sysrq.h +++ b/arch/um/include/sysrq.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef __UM_SYSRQ_H | 1 | #ifndef __UM_SYSRQ_H |
2 | #define __UM_SYSRQ_H | 2 | #define __UM_SYSRQ_H |
3 | 3 | ||
4 | extern void show_trace(unsigned long *stack); | 4 | struct task_struct; |
5 | extern void show_trace(struct task_struct* task, unsigned long *stack); | ||
5 | 6 | ||
6 | #endif | 7 | #endif |
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index 103cd320386c..7b6a24dfd302 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h | |||
@@ -41,9 +41,6 @@ extern unsigned long highmem; | |||
41 | extern char host_info[]; | 41 | extern char host_info[]; |
42 | 42 | ||
43 | extern char saved_command_line[]; | 43 | extern char saved_command_line[]; |
44 | extern char command_line[]; | ||
45 | |||
46 | extern char *tempdir; | ||
47 | 44 | ||
48 | extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end; | 45 | extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end; |
49 | extern unsigned long _unprotected_end; | 46 | extern unsigned long _unprotected_end; |
@@ -67,7 +64,6 @@ extern void *um_kmalloc(int size); | |||
67 | extern int switcheroo(int fd, int prot, void *from, void *to, int size); | 64 | extern int switcheroo(int fd, int prot, void *from, void *to, int size); |
68 | extern void setup_machinename(char *machine_out); | 65 | extern void setup_machinename(char *machine_out); |
69 | extern void setup_hostinfo(void); | 66 | extern void setup_hostinfo(void); |
70 | extern void add_arg(char *arg); | ||
71 | extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)); | 67 | extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)); |
72 | extern void init_new_thread_signals(int altstack); | 68 | extern void init_new_thread_signals(int altstack); |
73 | extern void do_exec(int old_pid, int new_pid); | 69 | extern void do_exec(int old_pid, int new_pid); |
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile index 246f0e7fb4cc..a8918e80df96 100644 --- a/arch/um/kernel/Makefile +++ b/arch/um/kernel/Makefile | |||
@@ -4,9 +4,9 @@ | |||
4 | # | 4 | # |
5 | 5 | ||
6 | extra-y := vmlinux.lds | 6 | extra-y := vmlinux.lds |
7 | clean-files := vmlinux.lds.S config.tmp | 7 | clean-files := |
8 | 8 | ||
9 | obj-y = checksum.o config.o exec_kern.o exitcode.o \ | 9 | obj-y = config.o exec_kern.o exitcode.o \ |
10 | helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o mem_user.o \ | 10 | helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o mem_user.o \ |
11 | physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \ | 11 | physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \ |
12 | sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \ | 12 | sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \ |
@@ -14,7 +14,7 @@ obj-y = checksum.o config.o exec_kern.o exitcode.o \ | |||
14 | tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o umid.o \ | 14 | tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o umid.o \ |
15 | user_util.o | 15 | user_util.o |
16 | 16 | ||
17 | obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o | 17 | obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o |
18 | obj-$(CONFIG_GPROF) += gprof_syms.o | 18 | obj-$(CONFIG_GPROF) += gprof_syms.o |
19 | obj-$(CONFIG_GCOV) += gmon_syms.o | 19 | obj-$(CONFIG_GCOV) += gmon_syms.o |
20 | obj-$(CONFIG_TTY_LOG) += tty_log.o | 20 | obj-$(CONFIG_TTY_LOG) += tty_log.o |
@@ -23,18 +23,14 @@ obj-$(CONFIG_SYSCALL_DEBUG) += syscall_user.o | |||
23 | obj-$(CONFIG_MODE_TT) += tt/ | 23 | obj-$(CONFIG_MODE_TT) += tt/ |
24 | obj-$(CONFIG_MODE_SKAS) += skas/ | 24 | obj-$(CONFIG_MODE_SKAS) += skas/ |
25 | 25 | ||
26 | # This needs be compiled with frame pointers regardless of how the rest of the | ||
27 | # kernel is built. | ||
28 | CFLAGS_frame.o := -fno-omit-frame-pointer | ||
29 | |||
30 | user-objs-$(CONFIG_TTY_LOG) += tty_log.o | 26 | user-objs-$(CONFIG_TTY_LOG) += tty_log.o |
31 | 27 | ||
32 | USER_OBJS := $(user-objs-y) config.o helper.o main.o process.o tempfile.o \ | 28 | USER_OBJS := $(user-objs-y) config.o helper.o main.o process.o tempfile.o \ |
33 | time.o tty_log.o umid.o user_util.o frame.o | 29 | time.o tty_log.o umid.o user_util.o |
34 | 30 | ||
35 | include arch/um/scripts/Makefile.rules | 31 | include arch/um/scripts/Makefile.rules |
36 | 32 | ||
37 | targets += config.c | 33 | targets := config.c config.tmp |
38 | 34 | ||
39 | # Be careful with the below Sed code - sed is pitfall-rich! | 35 | # Be careful with the below Sed code - sed is pitfall-rich! |
40 | # We use sed to lower build requirements, for "embedded" builders for instance. | 36 | # We use sed to lower build requirements, for "embedded" builders for instance. |
diff --git a/arch/um/kernel/checksum.c b/arch/um/kernel/checksum.c deleted file mode 100644 index e69b2be951d1..000000000000 --- a/arch/um/kernel/checksum.c +++ /dev/null | |||
@@ -1,36 +0,0 @@ | |||
1 | #include "asm/uaccess.h" | ||
2 | #include "linux/errno.h" | ||
3 | #include "linux/module.h" | ||
4 | |||
5 | unsigned int arch_csum_partial(const unsigned char *buff, int len, int sum); | ||
6 | |||
7 | unsigned int csum_partial(unsigned char *buff, int len, int sum) | ||
8 | { | ||
9 | return arch_csum_partial(buff, len, sum); | ||
10 | } | ||
11 | |||
12 | EXPORT_SYMBOL(csum_partial); | ||
13 | |||
14 | unsigned int csum_partial_copy_to(const unsigned char *src, | ||
15 | unsigned char __user *dst, int len, int sum, | ||
16 | int *err_ptr) | ||
17 | { | ||
18 | if(copy_to_user(dst, src, len)){ | ||
19 | *err_ptr = -EFAULT; | ||
20 | return(-1); | ||
21 | } | ||
22 | |||
23 | return(arch_csum_partial(src, len, sum)); | ||
24 | } | ||
25 | |||
26 | unsigned int csum_partial_copy_from(const unsigned char __user *src, | ||
27 | unsigned char *dst, int len, int sum, | ||
28 | int *err_ptr) | ||
29 | { | ||
30 | if(copy_from_user(dst, src, len)){ | ||
31 | *err_ptr = -EFAULT; | ||
32 | return(-1); | ||
33 | } | ||
34 | |||
35 | return arch_csum_partial(dst, len, sum); | ||
36 | } | ||
diff --git a/arch/um/kernel/exec_kern.c b/arch/um/kernel/exec_kern.c index 49ddabe69be7..efd222ffe20e 100644 --- a/arch/um/kernel/exec_kern.c +++ b/arch/um/kernel/exec_kern.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include "kern.h" | 16 | #include "kern.h" |
17 | #include "irq_user.h" | 17 | #include "irq_user.h" |
18 | #include "tlb.h" | 18 | #include "tlb.h" |
19 | #include "2_5compat.h" | ||
20 | #include "os.h" | 19 | #include "os.h" |
21 | #include "time_user.h" | 20 | #include "time_user.h" |
22 | #include "choose-mode.h" | 21 | #include "choose-mode.h" |
diff --git a/arch/um/kernel/initrd_kern.c b/arch/um/kernel/initrd.c index fc568af468b9..82ecf904b09c 100644 --- a/arch/um/kernel/initrd_kern.c +++ b/arch/um/kernel/initrd.c | |||
@@ -41,12 +41,31 @@ static int __init uml_initrd_setup(char *line, int *add) | |||
41 | return 0; | 41 | return 0; |
42 | } | 42 | } |
43 | 43 | ||
44 | __uml_setup("initrd=", uml_initrd_setup, | 44 | __uml_setup("initrd=", uml_initrd_setup, |
45 | "initrd=<initrd image>\n" | 45 | "initrd=<initrd image>\n" |
46 | " This is used to boot UML from an initrd image. The argument is the\n" | 46 | " This is used to boot UML from an initrd image. The argument is the\n" |
47 | " name of the file containing the image.\n\n" | 47 | " name of the file containing the image.\n\n" |
48 | ); | 48 | ); |
49 | 49 | ||
50 | int load_initrd(char *filename, void *buf, int size) | ||
51 | { | ||
52 | int fd, n; | ||
53 | |||
54 | fd = os_open_file(filename, of_read(OPENFLAGS()), 0); | ||
55 | if(fd < 0){ | ||
56 | printk("Opening '%s' failed - err = %d\n", filename, -fd); | ||
57 | return(-1); | ||
58 | } | ||
59 | n = os_read_file(fd, buf, size); | ||
60 | if(n != size){ | ||
61 | printk("Read of %d bytes from '%s' failed, err = %d\n", size, | ||
62 | filename, -n); | ||
63 | return(-1); | ||
64 | } | ||
65 | |||
66 | os_close_file(fd); | ||
67 | return(0); | ||
68 | } | ||
50 | /* | 69 | /* |
51 | * Overrides for Emacs so that we follow Linus's tabbing style. | 70 | * Overrides for Emacs so that we follow Linus's tabbing style. |
52 | * Emacs will notice this stuff at the end of the file and automatically | 71 | * Emacs will notice this stuff at the end of the file and automatically |
diff --git a/arch/um/kernel/initrd_user.c b/arch/um/kernel/initrd_user.c deleted file mode 100644 index cb90681e151c..000000000000 --- a/arch/um/kernel/initrd_user.c +++ /dev/null | |||
@@ -1,46 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #include <unistd.h> | ||
7 | #include <sys/types.h> | ||
8 | #include <sys/stat.h> | ||
9 | #include <errno.h> | ||
10 | |||
11 | #include "user_util.h" | ||
12 | #include "kern_util.h" | ||
13 | #include "user.h" | ||
14 | #include "initrd.h" | ||
15 | #include "os.h" | ||
16 | |||
17 | int load_initrd(char *filename, void *buf, int size) | ||
18 | { | ||
19 | int fd, n; | ||
20 | |||
21 | fd = os_open_file(filename, of_read(OPENFLAGS()), 0); | ||
22 | if(fd < 0){ | ||
23 | printk("Opening '%s' failed - err = %d\n", filename, -fd); | ||
24 | return(-1); | ||
25 | } | ||
26 | n = os_read_file(fd, buf, size); | ||
27 | if(n != size){ | ||
28 | printk("Read of %d bytes from '%s' failed, err = %d\n", size, | ||
29 | filename, -n); | ||
30 | return(-1); | ||
31 | } | ||
32 | |||
33 | os_close_file(fd); | ||
34 | return(0); | ||
35 | } | ||
36 | |||
37 | /* | ||
38 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
39 | * Emacs will notice this stuff at the end of the file and automatically | ||
40 | * adjust the settings for this buffer only. This must remain at the end | ||
41 | * of the file. | ||
42 | * --------------------------------------------------------------------------- | ||
43 | * Local variables: | ||
44 | * c-file-style: "linux" | ||
45 | * End: | ||
46 | */ | ||
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index d71e8f00810f..d44fb5282547 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c | |||
@@ -163,7 +163,6 @@ void __init init_IRQ(void) | |||
163 | irq_desc[i].handler = &SIGIO_irq_type; | 163 | irq_desc[i].handler = &SIGIO_irq_type; |
164 | enable_irq(i); | 164 | enable_irq(i); |
165 | } | 165 | } |
166 | init_irq_signals(0); | ||
167 | } | 166 | } |
168 | 167 | ||
169 | /* | 168 | /* |
diff --git a/arch/um/kernel/irq_user.c b/arch/um/kernel/irq_user.c index 6d6f9484b884..b3074cbaa479 100644 --- a/arch/um/kernel/irq_user.c +++ b/arch/um/kernel/irq_user.c | |||
@@ -236,9 +236,15 @@ static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg) | |||
236 | (*prev)->fd, pollfds[i].fd); | 236 | (*prev)->fd, pollfds[i].fd); |
237 | goto out; | 237 | goto out; |
238 | } | 238 | } |
239 | memcpy(&pollfds[i], &pollfds[i + 1], | 239 | |
240 | (pollfds_num - i - 1) * sizeof(pollfds[0])); | ||
241 | pollfds_num--; | 240 | pollfds_num--; |
241 | |||
242 | /* This moves the *whole* array after pollfds[i] (though | ||
243 | * it doesn't spot as such)! */ | ||
244 | |||
245 | memmove(&pollfds[i], &pollfds[i + 1], | ||
246 | (pollfds_num - i) * sizeof(pollfds[0])); | ||
247 | |||
242 | if(last_irq_ptr == &old_fd->next) | 248 | if(last_irq_ptr == &old_fd->next) |
243 | last_irq_ptr = prev; | 249 | last_irq_ptr = prev; |
244 | *prev = (*prev)->next; | 250 | *prev = (*prev)->next; |
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c index b41d3397d07b..99439fa15ef4 100644 --- a/arch/um/kernel/ksyms.c +++ b/arch/um/kernel/ksyms.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include "linux/spinlock.h" | 10 | #include "linux/spinlock.h" |
11 | #include "linux/highmem.h" | 11 | #include "linux/highmem.h" |
12 | #include "asm/current.h" | 12 | #include "asm/current.h" |
13 | #include "asm/delay.h" | ||
14 | #include "asm/processor.h" | 13 | #include "asm/processor.h" |
15 | #include "asm/unistd.h" | 14 | #include "asm/unistd.h" |
16 | #include "asm/pgalloc.h" | 15 | #include "asm/pgalloc.h" |
@@ -28,8 +27,6 @@ EXPORT_SYMBOL(uml_physmem); | |||
28 | EXPORT_SYMBOL(set_signals); | 27 | EXPORT_SYMBOL(set_signals); |
29 | EXPORT_SYMBOL(get_signals); | 28 | EXPORT_SYMBOL(get_signals); |
30 | EXPORT_SYMBOL(kernel_thread); | 29 | EXPORT_SYMBOL(kernel_thread); |
31 | EXPORT_SYMBOL(__const_udelay); | ||
32 | EXPORT_SYMBOL(__udelay); | ||
33 | EXPORT_SYMBOL(sys_waitpid); | 30 | EXPORT_SYMBOL(sys_waitpid); |
34 | EXPORT_SYMBOL(task_size); | 31 | EXPORT_SYMBOL(task_size); |
35 | EXPORT_SYMBOL(flush_tlb_range); | 32 | EXPORT_SYMBOL(flush_tlb_range); |
@@ -60,6 +57,7 @@ EXPORT_SYMBOL(copy_to_user_tt); | |||
60 | EXPORT_SYMBOL(strncpy_from_user_skas); | 57 | EXPORT_SYMBOL(strncpy_from_user_skas); |
61 | EXPORT_SYMBOL(copy_to_user_skas); | 58 | EXPORT_SYMBOL(copy_to_user_skas); |
62 | EXPORT_SYMBOL(copy_from_user_skas); | 59 | EXPORT_SYMBOL(copy_from_user_skas); |
60 | EXPORT_SYMBOL(clear_user_skas); | ||
63 | #endif | 61 | #endif |
64 | EXPORT_SYMBOL(uml_strdup); | 62 | EXPORT_SYMBOL(uml_strdup); |
65 | 63 | ||
diff --git a/arch/um/kernel/main.c b/arch/um/kernel/main.c index a17c49703f9b..e59f58152678 100644 --- a/arch/um/kernel/main.c +++ b/arch/um/kernel/main.c | |||
@@ -24,8 +24,6 @@ | |||
24 | #include "mode.h" | 24 | #include "mode.h" |
25 | #include "choose-mode.h" | 25 | #include "choose-mode.h" |
26 | #include "uml-config.h" | 26 | #include "uml-config.h" |
27 | #include "irq_user.h" | ||
28 | #include "time_user.h" | ||
29 | #include "os.h" | 27 | #include "os.h" |
30 | 28 | ||
31 | /* Set in set_stklim, which is called from main and __wrap_malloc. | 29 | /* Set in set_stklim, which is called from main and __wrap_malloc. |
@@ -71,7 +69,7 @@ static __init void do_uml_initcalls(void) | |||
71 | 69 | ||
72 | static void last_ditch_exit(int sig) | 70 | static void last_ditch_exit(int sig) |
73 | { | 71 | { |
74 | CHOOSE_MODE(kmalloc_ok = 0, (void) 0); | 72 | kmalloc_ok = 0; |
75 | signal(SIGINT, SIG_DFL); | 73 | signal(SIGINT, SIG_DFL); |
76 | signal(SIGTERM, SIG_DFL); | 74 | signal(SIGTERM, SIG_DFL); |
77 | signal(SIGHUP, SIG_DFL); | 75 | signal(SIGHUP, SIG_DFL); |
@@ -87,7 +85,7 @@ int main(int argc, char **argv, char **envp) | |||
87 | { | 85 | { |
88 | char **new_argv; | 86 | char **new_argv; |
89 | sigset_t mask; | 87 | sigset_t mask; |
90 | int ret, i; | 88 | int ret, i, err; |
91 | 89 | ||
92 | /* Enable all signals except SIGIO - in some environments, we can | 90 | /* Enable all signals except SIGIO - in some environments, we can |
93 | * enter with some signals blocked | 91 | * enter with some signals blocked |
@@ -160,27 +158,29 @@ int main(int argc, char **argv, char **envp) | |||
160 | */ | 158 | */ |
161 | change_sig(SIGPROF, 0); | 159 | change_sig(SIGPROF, 0); |
162 | 160 | ||
163 | /* Reboot */ | 161 | /* This signal stuff used to be in the reboot case. However, |
164 | if(ret){ | 162 | * sometimes a SIGVTALRM can come in when we're halting (reproducably |
165 | int err; | 163 | * when writing out gcov information, presumably because that takes |
164 | * some time) and cause a segfault. | ||
165 | */ | ||
166 | 166 | ||
167 | printf("\n"); | 167 | /* stop timers and set SIG*ALRM to be ignored */ |
168 | disable_timer(); | ||
168 | 169 | ||
169 | /* stop timers and set SIG*ALRM to be ignored */ | 170 | /* disable SIGIO for the fds and set SIGIO to be ignored */ |
170 | disable_timer(); | 171 | err = deactivate_all_fds(); |
172 | if(err) | ||
173 | printf("deactivate_all_fds failed, errno = %d\n", -err); | ||
171 | 174 | ||
172 | /* disable SIGIO for the fds and set SIGIO to be ignored */ | 175 | /* Let any pending signals fire now. This ensures |
173 | err = deactivate_all_fds(); | 176 | * that they won't be delivered after the exec, when |
174 | if(err) | 177 | * they are definitely not expected. |
175 | printf("deactivate_all_fds failed, errno = %d\n", | 178 | */ |
176 | -err); | 179 | unblock_signals(); |
177 | |||
178 | /* Let any pending signals fire now. This ensures | ||
179 | * that they won't be delivered after the exec, when | ||
180 | * they are definitely not expected. | ||
181 | */ | ||
182 | unblock_signals(); | ||
183 | 180 | ||
181 | /* Reboot */ | ||
182 | if(ret){ | ||
183 | printf("\n"); | ||
184 | execvp(new_argv[0], new_argv); | 184 | execvp(new_argv[0], new_argv); |
185 | perror("Failed to exec kernel"); | 185 | perror("Failed to exec kernel"); |
186 | ret = 1; | 186 | ret = 1; |
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index f156661781cb..c22825f13e40 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c | |||
@@ -100,12 +100,37 @@ void mem_init(void) | |||
100 | #endif | 100 | #endif |
101 | } | 101 | } |
102 | 102 | ||
103 | /* | ||
104 | * Create a page table and place a pointer to it in a middle page | ||
105 | * directory entry. | ||
106 | */ | ||
107 | static void __init one_page_table_init(pmd_t *pmd) | ||
108 | { | ||
109 | if (pmd_none(*pmd)) { | ||
110 | pte_t *pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); | ||
111 | set_pmd(pmd, __pmd(_KERNPG_TABLE + | ||
112 | (unsigned long) __pa(pte))); | ||
113 | if (pte != pte_offset_kernel(pmd, 0)) | ||
114 | BUG(); | ||
115 | } | ||
116 | } | ||
117 | |||
118 | static void __init one_md_table_init(pud_t *pud) | ||
119 | { | ||
120 | #ifdef CONFIG_3_LEVEL_PGTABLES | ||
121 | pmd_t *pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); | ||
122 | set_pud(pud, __pud(_KERNPG_TABLE + (unsigned long) __pa(pmd_table))); | ||
123 | if (pmd_table != pmd_offset(pud, 0)) | ||
124 | BUG(); | ||
125 | #endif | ||
126 | } | ||
127 | |||
103 | static void __init fixrange_init(unsigned long start, unsigned long end, | 128 | static void __init fixrange_init(unsigned long start, unsigned long end, |
104 | pgd_t *pgd_base) | 129 | pgd_t *pgd_base) |
105 | { | 130 | { |
106 | pgd_t *pgd; | 131 | pgd_t *pgd; |
132 | pud_t *pud; | ||
107 | pmd_t *pmd; | 133 | pmd_t *pmd; |
108 | pte_t *pte; | ||
109 | int i, j; | 134 | int i, j; |
110 | unsigned long vaddr; | 135 | unsigned long vaddr; |
111 | 136 | ||
@@ -115,15 +140,12 @@ static void __init fixrange_init(unsigned long start, unsigned long end, | |||
115 | pgd = pgd_base + i; | 140 | pgd = pgd_base + i; |
116 | 141 | ||
117 | for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) { | 142 | for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) { |
118 | pmd = (pmd_t *)pgd; | 143 | pud = pud_offset(pgd, vaddr); |
144 | if (pud_none(*pud)) | ||
145 | one_md_table_init(pud); | ||
146 | pmd = pmd_offset(pud, vaddr); | ||
119 | for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) { | 147 | for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) { |
120 | if (pmd_none(*pmd)) { | 148 | one_page_table_init(pmd); |
121 | pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); | ||
122 | set_pmd(pmd, __pmd(_KERNPG_TABLE + | ||
123 | (unsigned long) __pa(pte))); | ||
124 | if (pte != pte_offset_kernel(pmd, 0)) | ||
125 | BUG(); | ||
126 | } | ||
127 | vaddr += PMD_SIZE; | 149 | vaddr += PMD_SIZE; |
128 | } | 150 | } |
129 | j = 0; | 151 | j = 0; |
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index f76a2692adca..1b5ef3e96c71 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include "init.h" | 30 | #include "init.h" |
31 | #include "os.h" | 31 | #include "os.h" |
32 | #include "uml-config.h" | 32 | #include "uml-config.h" |
33 | #include "ptrace_user.h" | ||
34 | #include "choose-mode.h" | 33 | #include "choose-mode.h" |
35 | #include "mode.h" | 34 | #include "mode.h" |
36 | #ifdef UML_CONFIG_MODE_SKAS | 35 | #ifdef UML_CONFIG_MODE_SKAS |
@@ -65,8 +64,6 @@ void init_new_thread_signals(int altstack) | |||
65 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); | 64 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); |
66 | set_handler(SIGBUS, (__sighandler_t) sig_handler, flags, | 65 | set_handler(SIGBUS, (__sighandler_t) sig_handler, flags, |
67 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); | 66 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); |
68 | set_handler(SIGWINCH, (__sighandler_t) sig_handler, flags, | ||
69 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); | ||
70 | set_handler(SIGUSR2, (__sighandler_t) sig_handler, | 67 | set_handler(SIGUSR2, (__sighandler_t) sig_handler, |
71 | flags, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); | 68 | flags, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); |
72 | signal(SIGHUP, SIG_IGN); | 69 | signal(SIGHUP, SIG_IGN); |
@@ -133,7 +130,7 @@ int start_fork_tramp(void *thread_arg, unsigned long temp_stack, | |||
133 | return(arg.pid); | 130 | return(arg.pid); |
134 | } | 131 | } |
135 | 132 | ||
136 | static int ptrace_child(void *arg) | 133 | static int ptrace_child(void) |
137 | { | 134 | { |
138 | int ret; | 135 | int ret; |
139 | int pid = os_getpid(), ppid = getppid(); | 136 | int pid = os_getpid(), ppid = getppid(); |
@@ -162,20 +159,16 @@ static int ptrace_child(void *arg) | |||
162 | _exit(ret); | 159 | _exit(ret); |
163 | } | 160 | } |
164 | 161 | ||
165 | static int start_ptraced_child(void **stack_out) | 162 | static int start_ptraced_child(void) |
166 | { | 163 | { |
167 | void *stack; | ||
168 | unsigned long sp; | ||
169 | int pid, n, status; | 164 | int pid, n, status; |
170 | 165 | ||
171 | stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, | 166 | pid = fork(); |
172 | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | 167 | if(pid == 0) |
173 | if(stack == MAP_FAILED) | 168 | ptrace_child(); |
174 | panic("check_ptrace : mmap failed, errno = %d", errno); | 169 | |
175 | sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *); | ||
176 | pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL); | ||
177 | if(pid < 0) | 170 | if(pid < 0) |
178 | panic("check_ptrace : clone failed, errno = %d", errno); | 171 | panic("check_ptrace : fork failed, errno = %d", errno); |
179 | CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); | 172 | CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); |
180 | if(n < 0) | 173 | if(n < 0) |
181 | panic("check_ptrace : wait failed, errno = %d", errno); | 174 | panic("check_ptrace : wait failed, errno = %d", errno); |
@@ -183,7 +176,6 @@ static int start_ptraced_child(void **stack_out) | |||
183 | panic("check_ptrace : expected SIGSTOP, got status = %d", | 176 | panic("check_ptrace : expected SIGSTOP, got status = %d", |
184 | status); | 177 | status); |
185 | 178 | ||
186 | *stack_out = stack; | ||
187 | return(pid); | 179 | return(pid); |
188 | } | 180 | } |
189 | 181 | ||
@@ -191,12 +183,12 @@ static int start_ptraced_child(void **stack_out) | |||
191 | * just avoid using sysemu, not panic, but only if SYSEMU features are broken. | 183 | * just avoid using sysemu, not panic, but only if SYSEMU features are broken. |
192 | * So only for SYSEMU features we test mustpanic, while normal host features | 184 | * So only for SYSEMU features we test mustpanic, while normal host features |
193 | * must work anyway!*/ | 185 | * must work anyway!*/ |
194 | static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic) | 186 | static int stop_ptraced_child(int pid, int exitcode, int mustexit) |
195 | { | 187 | { |
196 | int status, n, ret = 0; | 188 | int status, n, ret = 0; |
197 | 189 | ||
198 | if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) | 190 | if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) |
199 | panic("check_ptrace : ptrace failed, errno = %d", errno); | 191 | panic("stop_ptraced_child : ptrace failed, errno = %d", errno); |
200 | CATCH_EINTR(n = waitpid(pid, &status, 0)); | 192 | CATCH_EINTR(n = waitpid(pid, &status, 0)); |
201 | if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { | 193 | if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { |
202 | int exit_with = WEXITSTATUS(status); | 194 | int exit_with = WEXITSTATUS(status); |
@@ -207,15 +199,13 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic) | |||
207 | printk("check_ptrace : child exited with exitcode %d, while " | 199 | printk("check_ptrace : child exited with exitcode %d, while " |
208 | "expecting %d; status 0x%x", exit_with, | 200 | "expecting %d; status 0x%x", exit_with, |
209 | exitcode, status); | 201 | exitcode, status); |
210 | if (mustpanic) | 202 | if (mustexit) |
211 | panic("\n"); | 203 | panic("\n"); |
212 | else | 204 | else |
213 | printk("\n"); | 205 | printk("\n"); |
214 | ret = -1; | 206 | ret = -1; |
215 | } | 207 | } |
216 | 208 | ||
217 | if(munmap(stack, PAGE_SIZE) < 0) | ||
218 | panic("check_ptrace : munmap failed, errno = %d", errno); | ||
219 | return ret; | 209 | return ret; |
220 | } | 210 | } |
221 | 211 | ||
@@ -237,12 +227,11 @@ __uml_setup("nosysemu", nosysemu_cmd_param, | |||
237 | 227 | ||
238 | static void __init check_sysemu(void) | 228 | static void __init check_sysemu(void) |
239 | { | 229 | { |
240 | void *stack; | ||
241 | int pid, syscall, n, status, count=0; | 230 | int pid, syscall, n, status, count=0; |
242 | 231 | ||
243 | printk("Checking syscall emulation patch for ptrace..."); | 232 | printk("Checking syscall emulation patch for ptrace..."); |
244 | sysemu_supported = 0; | 233 | sysemu_supported = 0; |
245 | pid = start_ptraced_child(&stack); | 234 | pid = start_ptraced_child(); |
246 | 235 | ||
247 | if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) | 236 | if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) |
248 | goto fail; | 237 | goto fail; |
@@ -260,7 +249,7 @@ static void __init check_sysemu(void) | |||
260 | panic("check_sysemu : failed to modify system " | 249 | panic("check_sysemu : failed to modify system " |
261 | "call return, errno = %d", errno); | 250 | "call return, errno = %d", errno); |
262 | 251 | ||
263 | if (stop_ptraced_child(pid, stack, 0, 0) < 0) | 252 | if (stop_ptraced_child(pid, 0, 0) < 0) |
264 | goto fail_stopped; | 253 | goto fail_stopped; |
265 | 254 | ||
266 | sysemu_supported = 1; | 255 | sysemu_supported = 1; |
@@ -268,7 +257,7 @@ static void __init check_sysemu(void) | |||
268 | set_using_sysemu(!force_sysemu_disabled); | 257 | set_using_sysemu(!force_sysemu_disabled); |
269 | 258 | ||
270 | printk("Checking advanced syscall emulation patch for ptrace..."); | 259 | printk("Checking advanced syscall emulation patch for ptrace..."); |
271 | pid = start_ptraced_child(&stack); | 260 | pid = start_ptraced_child(); |
272 | while(1){ | 261 | while(1){ |
273 | count++; | 262 | count++; |
274 | if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) | 263 | if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) |
@@ -293,7 +282,7 @@ static void __init check_sysemu(void) | |||
293 | break; | 282 | break; |
294 | } | 283 | } |
295 | } | 284 | } |
296 | if (stop_ptraced_child(pid, stack, 0, 0) < 0) | 285 | if (stop_ptraced_child(pid, 0, 0) < 0) |
297 | goto fail_stopped; | 286 | goto fail_stopped; |
298 | 287 | ||
299 | sysemu_supported = 2; | 288 | sysemu_supported = 2; |
@@ -304,18 +293,17 @@ static void __init check_sysemu(void) | |||
304 | return; | 293 | return; |
305 | 294 | ||
306 | fail: | 295 | fail: |
307 | stop_ptraced_child(pid, stack, 1, 0); | 296 | stop_ptraced_child(pid, 1, 0); |
308 | fail_stopped: | 297 | fail_stopped: |
309 | printk("missing\n"); | 298 | printk("missing\n"); |
310 | } | 299 | } |
311 | 300 | ||
312 | void __init check_ptrace(void) | 301 | void __init check_ptrace(void) |
313 | { | 302 | { |
314 | void *stack; | ||
315 | int pid, syscall, n, status; | 303 | int pid, syscall, n, status; |
316 | 304 | ||
317 | printk("Checking that ptrace can change system call numbers..."); | 305 | printk("Checking that ptrace can change system call numbers..."); |
318 | pid = start_ptraced_child(&stack); | 306 | pid = start_ptraced_child(); |
319 | 307 | ||
320 | if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) | 308 | if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) |
321 | panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno); | 309 | panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno); |
@@ -342,7 +330,7 @@ void __init check_ptrace(void) | |||
342 | break; | 330 | break; |
343 | } | 331 | } |
344 | } | 332 | } |
345 | stop_ptraced_child(pid, stack, 0, 1); | 333 | stop_ptraced_child(pid, 0, 1); |
346 | printk("OK\n"); | 334 | printk("OK\n"); |
347 | check_sysemu(); | 335 | check_sysemu(); |
348 | } | 336 | } |
@@ -374,11 +362,10 @@ void forward_pending_sigio(int target) | |||
374 | static inline int check_skas3_ptrace_support(void) | 362 | static inline int check_skas3_ptrace_support(void) |
375 | { | 363 | { |
376 | struct ptrace_faultinfo fi; | 364 | struct ptrace_faultinfo fi; |
377 | void *stack; | ||
378 | int pid, n, ret = 1; | 365 | int pid, n, ret = 1; |
379 | 366 | ||
380 | printf("Checking for the skas3 patch in the host..."); | 367 | printf("Checking for the skas3 patch in the host..."); |
381 | pid = start_ptraced_child(&stack); | 368 | pid = start_ptraced_child(); |
382 | 369 | ||
383 | n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); | 370 | n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); |
384 | if (n < 0) { | 371 | if (n < 0) { |
@@ -393,7 +380,7 @@ static inline int check_skas3_ptrace_support(void) | |||
393 | } | 380 | } |
394 | 381 | ||
395 | init_registers(pid); | 382 | init_registers(pid); |
396 | stop_ptraced_child(pid, stack, 1, 1); | 383 | stop_ptraced_child(pid, 1, 1); |
397 | 384 | ||
398 | return(ret); | 385 | return(ret); |
399 | } | 386 | } |
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c index 7a943696f950..804c6bbdf67c 100644 --- a/arch/um/kernel/process_kern.c +++ b/arch/um/kernel/process_kern.c | |||
@@ -43,7 +43,6 @@ | |||
43 | #include "tlb.h" | 43 | #include "tlb.h" |
44 | #include "frame_kern.h" | 44 | #include "frame_kern.h" |
45 | #include "sigcontext.h" | 45 | #include "sigcontext.h" |
46 | #include "2_5compat.h" | ||
47 | #include "os.h" | 46 | #include "os.h" |
48 | #include "mode.h" | 47 | #include "mode.h" |
49 | #include "mode_kern.h" | 48 | #include "mode_kern.h" |
@@ -55,18 +54,6 @@ | |||
55 | */ | 54 | */ |
56 | struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } }; | 55 | struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } }; |
57 | 56 | ||
58 | struct task_struct *get_task(int pid, int require) | ||
59 | { | ||
60 | struct task_struct *ret; | ||
61 | |||
62 | read_lock(&tasklist_lock); | ||
63 | ret = find_task_by_pid(pid); | ||
64 | read_unlock(&tasklist_lock); | ||
65 | |||
66 | if(require && (ret == NULL)) panic("get_task couldn't find a task\n"); | ||
67 | return(ret); | ||
68 | } | ||
69 | |||
70 | int external_pid(void *t) | 57 | int external_pid(void *t) |
71 | { | 58 | { |
72 | struct task_struct *task = t ? t : current; | 59 | struct task_struct *task = t ? t : current; |
@@ -115,16 +102,6 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | |||
115 | return(pid); | 102 | return(pid); |
116 | } | 103 | } |
117 | 104 | ||
118 | void switch_mm(struct mm_struct *prev, struct mm_struct *next, | ||
119 | struct task_struct *tsk) | ||
120 | { | ||
121 | int cpu = smp_processor_id(); | ||
122 | |||
123 | if (prev != next) | ||
124 | cpu_clear(cpu, prev->cpu_vm_mask); | ||
125 | cpu_set(cpu, next->cpu_vm_mask); | ||
126 | } | ||
127 | |||
128 | void set_current(void *t) | 105 | void set_current(void *t) |
129 | { | 106 | { |
130 | struct task_struct *task = t; | 107 | struct task_struct *task = t; |
@@ -152,7 +129,6 @@ void release_thread(struct task_struct *task) | |||
152 | 129 | ||
153 | void exit_thread(void) | 130 | void exit_thread(void) |
154 | { | 131 | { |
155 | CHOOSE_MODE(exit_thread_tt(), exit_thread_skas()); | ||
156 | unprotect_stack((unsigned long) current_thread); | 132 | unprotect_stack((unsigned long) current_thread); |
157 | } | 133 | } |
158 | 134 | ||
@@ -200,7 +176,6 @@ void default_idle(void) | |||
200 | 176 | ||
201 | while(1){ | 177 | while(1){ |
202 | /* endless idle loop with no priority at all */ | 178 | /* endless idle loop with no priority at all */ |
203 | SET_PRI(current); | ||
204 | 179 | ||
205 | /* | 180 | /* |
206 | * although we are an idle CPU, we do not want to | 181 | * although we are an idle CPU, we do not want to |
@@ -223,11 +198,6 @@ int page_size(void) | |||
223 | return(PAGE_SIZE); | 198 | return(PAGE_SIZE); |
224 | } | 199 | } |
225 | 200 | ||
226 | unsigned long page_mask(void) | ||
227 | { | ||
228 | return(PAGE_MASK); | ||
229 | } | ||
230 | |||
231 | void *um_virt_to_phys(struct task_struct *task, unsigned long addr, | 201 | void *um_virt_to_phys(struct task_struct *task, unsigned long addr, |
232 | pte_t *pte_out) | 202 | pte_t *pte_out) |
233 | { | 203 | { |
@@ -360,11 +330,6 @@ char *uml_strdup(char *string) | |||
360 | return(new); | 330 | return(new); |
361 | } | 331 | } |
362 | 332 | ||
363 | void *get_init_task(void) | ||
364 | { | ||
365 | return(&init_thread_union.thread_info.task); | ||
366 | } | ||
367 | |||
368 | int copy_to_user_proc(void __user *to, void *from, int size) | 333 | int copy_to_user_proc(void __user *to, void *from, int size) |
369 | { | 334 | { |
370 | return(copy_to_user(to, from, size)); | 335 | return(copy_to_user(to, from, size)); |
@@ -476,21 +441,18 @@ int singlestepping(void * t) | |||
476 | return 2; | 441 | return 2; |
477 | } | 442 | } |
478 | 443 | ||
444 | /* | ||
445 | * Only x86 and x86_64 have an arch_align_stack(). | ||
446 | * All other arches have "#define arch_align_stack(x) (x)" | ||
447 | * in their asm/system.h | ||
448 | * As this is included in UML from asm-um/system-generic.h, | ||
449 | * we can use it to behave as the subarch does. | ||
450 | */ | ||
451 | #ifndef arch_align_stack | ||
479 | unsigned long arch_align_stack(unsigned long sp) | 452 | unsigned long arch_align_stack(unsigned long sp) |
480 | { | 453 | { |
481 | if (randomize_va_space) | 454 | if (randomize_va_space) |
482 | sp -= get_random_int() % 8192; | 455 | sp -= get_random_int() % 8192; |
483 | return sp & ~0xf; | 456 | return sp & ~0xf; |
484 | } | 457 | } |
485 | 458 | #endif | |
486 | |||
487 | /* | ||
488 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
489 | * Emacs will notice this stuff at the end of the file and automatically | ||
490 | * adjust the settings for this buffer only. This must remain at the end | ||
491 | * of the file. | ||
492 | * --------------------------------------------------------------------------- | ||
493 | * Local variables: | ||
494 | * c-file-style: "linux" | ||
495 | * End: | ||
496 | */ | ||
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index e50e60ff5d27..71af4d503899 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c | |||
@@ -19,15 +19,30 @@ | |||
19 | #include "skas_ptrace.h" | 19 | #include "skas_ptrace.h" |
20 | #include "sysdep/ptrace.h" | 20 | #include "sysdep/ptrace.h" |
21 | 21 | ||
22 | static inline void set_singlestepping(struct task_struct *child, int on) | ||
23 | { | ||
24 | if (on) | ||
25 | child->ptrace |= PT_DTRACE; | ||
26 | else | ||
27 | child->ptrace &= ~PT_DTRACE; | ||
28 | child->thread.singlestep_syscall = 0; | ||
29 | |||
30 | #ifdef SUBARCH_SET_SINGLESTEPPING | ||
31 | SUBARCH_SET_SINGLESTEPPING(child, on); | ||
32 | #endif | ||
33 | } | ||
34 | |||
22 | /* | 35 | /* |
23 | * Called by kernel/ptrace.c when detaching.. | 36 | * Called by kernel/ptrace.c when detaching.. |
24 | */ | 37 | */ |
25 | void ptrace_disable(struct task_struct *child) | 38 | void ptrace_disable(struct task_struct *child) |
26 | { | 39 | { |
27 | child->ptrace &= ~PT_DTRACE; | 40 | set_singlestepping(child,0); |
28 | child->thread.singlestep_syscall = 0; | ||
29 | } | 41 | } |
30 | 42 | ||
43 | extern int peek_user(struct task_struct * child, long addr, long data); | ||
44 | extern int poke_user(struct task_struct * child, long addr, long data); | ||
45 | |||
31 | long sys_ptrace(long request, long pid, long addr, long data) | 46 | long sys_ptrace(long request, long pid, long addr, long data) |
32 | { | 47 | { |
33 | struct task_struct *child; | 48 | struct task_struct *child; |
@@ -67,6 +82,10 @@ long sys_ptrace(long request, long pid, long addr, long data) | |||
67 | goto out_tsk; | 82 | goto out_tsk; |
68 | } | 83 | } |
69 | 84 | ||
85 | #ifdef SUBACH_PTRACE_SPECIAL | ||
86 | SUBARCH_PTRACE_SPECIAL(child,request,addr,data); | ||
87 | #endif | ||
88 | |||
70 | ret = ptrace_check_attach(child, request == PTRACE_KILL); | 89 | ret = ptrace_check_attach(child, request == PTRACE_KILL); |
71 | if (ret < 0) | 90 | if (ret < 0) |
72 | goto out_tsk; | 91 | goto out_tsk; |
@@ -87,26 +106,9 @@ long sys_ptrace(long request, long pid, long addr, long data) | |||
87 | } | 106 | } |
88 | 107 | ||
89 | /* read the word at location addr in the USER area. */ | 108 | /* read the word at location addr in the USER area. */ |
90 | case PTRACE_PEEKUSR: { | 109 | case PTRACE_PEEKUSR: |
91 | unsigned long tmp; | 110 | ret = peek_user(child, addr, data); |
92 | 111 | break; | |
93 | ret = -EIO; | ||
94 | if ((addr & 3) || addr < 0) | ||
95 | break; | ||
96 | |||
97 | tmp = 0; /* Default return condition */ | ||
98 | if(addr < MAX_REG_OFFSET){ | ||
99 | tmp = getreg(child, addr); | ||
100 | } | ||
101 | else if((addr >= offsetof(struct user, u_debugreg[0])) && | ||
102 | (addr <= offsetof(struct user, u_debugreg[7]))){ | ||
103 | addr -= offsetof(struct user, u_debugreg[0]); | ||
104 | addr = addr >> 2; | ||
105 | tmp = child->thread.arch.debugregs[addr]; | ||
106 | } | ||
107 | ret = put_user(tmp, (unsigned long __user *) data); | ||
108 | break; | ||
109 | } | ||
110 | 112 | ||
111 | /* when I and D space are separate, this will have to be fixed. */ | 113 | /* when I and D space are separate, this will have to be fixed. */ |
112 | case PTRACE_POKETEXT: /* write the word at location addr. */ | 114 | case PTRACE_POKETEXT: /* write the word at location addr. */ |
@@ -119,26 +121,8 @@ long sys_ptrace(long request, long pid, long addr, long data) | |||
119 | break; | 121 | break; |
120 | 122 | ||
121 | case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ | 123 | case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ |
122 | ret = -EIO; | 124 | ret = poke_user(child, addr, data); |
123 | if ((addr & 3) || addr < 0) | 125 | break; |
124 | break; | ||
125 | |||
126 | if (addr < MAX_REG_OFFSET) { | ||
127 | ret = putreg(child, addr, data); | ||
128 | break; | ||
129 | } | ||
130 | #if 0 /* XXX x86_64 */ | ||
131 | else if((addr >= offsetof(struct user, u_debugreg[0])) && | ||
132 | (addr <= offsetof(struct user, u_debugreg[7]))){ | ||
133 | addr -= offsetof(struct user, u_debugreg[0]); | ||
134 | addr = addr >> 2; | ||
135 | if((addr == 4) || (addr == 5)) break; | ||
136 | child->thread.arch.debugregs[addr] = data; | ||
137 | ret = 0; | ||
138 | } | ||
139 | #endif | ||
140 | |||
141 | break; | ||
142 | 126 | ||
143 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ | 127 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ |
144 | case PTRACE_CONT: { /* restart after signal. */ | 128 | case PTRACE_CONT: { /* restart after signal. */ |
@@ -146,8 +130,7 @@ long sys_ptrace(long request, long pid, long addr, long data) | |||
146 | if (!valid_signal(data)) | 130 | if (!valid_signal(data)) |
147 | break; | 131 | break; |
148 | 132 | ||
149 | child->ptrace &= ~PT_DTRACE; | 133 | set_singlestepping(child, 0); |
150 | child->thread.singlestep_syscall = 0; | ||
151 | if (request == PTRACE_SYSCALL) { | 134 | if (request == PTRACE_SYSCALL) { |
152 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 135 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
153 | } | 136 | } |
@@ -170,8 +153,7 @@ long sys_ptrace(long request, long pid, long addr, long data) | |||
170 | if (child->exit_state == EXIT_ZOMBIE) /* already dead */ | 153 | if (child->exit_state == EXIT_ZOMBIE) /* already dead */ |
171 | break; | 154 | break; |
172 | 155 | ||
173 | child->ptrace &= ~PT_DTRACE; | 156 | set_singlestepping(child, 0); |
174 | child->thread.singlestep_syscall = 0; | ||
175 | child->exit_code = SIGKILL; | 157 | child->exit_code = SIGKILL; |
176 | wake_up_process(child); | 158 | wake_up_process(child); |
177 | break; | 159 | break; |
@@ -182,8 +164,7 @@ long sys_ptrace(long request, long pid, long addr, long data) | |||
182 | if (!valid_signal(data)) | 164 | if (!valid_signal(data)) |
183 | break; | 165 | break; |
184 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 166 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
185 | child->ptrace |= PT_DTRACE; | 167 | set_singlestepping(child, 1); |
186 | child->thread.singlestep_syscall = 0; | ||
187 | child->exit_code = data; | 168 | child->exit_code = data; |
188 | /* give it a chance to run. */ | 169 | /* give it a chance to run. */ |
189 | wake_up_process(child); | 170 | wake_up_process(child); |
@@ -250,23 +231,19 @@ long sys_ptrace(long request, long pid, long addr, long data) | |||
250 | break; | 231 | break; |
251 | #endif | 232 | #endif |
252 | case PTRACE_FAULTINFO: { | 233 | case PTRACE_FAULTINFO: { |
253 | struct ptrace_faultinfo fault; | 234 | /* Take the info from thread->arch->faultinfo, |
254 | 235 | * but transfer max. sizeof(struct ptrace_faultinfo). | |
255 | fault = ((struct ptrace_faultinfo) | 236 | * On i386, ptrace_faultinfo is smaller! |
256 | { .is_write = child->thread.err, | 237 | */ |
257 | .addr = child->thread.cr2 }); | 238 | ret = copy_to_user((unsigned long __user *) data, |
258 | ret = copy_to_user((unsigned long __user *) data, &fault, | 239 | &child->thread.arch.faultinfo, |
259 | sizeof(fault)); | 240 | sizeof(struct ptrace_faultinfo)); |
260 | if(ret) | 241 | if(ret) |
261 | break; | 242 | break; |
262 | break; | 243 | break; |
263 | } | 244 | } |
264 | case PTRACE_SIGPENDING: | ||
265 | ret = copy_to_user((unsigned long __user *) data, | ||
266 | &child->pending.signal, | ||
267 | sizeof(child->pending.signal)); | ||
268 | break; | ||
269 | 245 | ||
246 | #ifdef PTRACE_LDT | ||
270 | case PTRACE_LDT: { | 247 | case PTRACE_LDT: { |
271 | struct ptrace_ldt ldt; | 248 | struct ptrace_ldt ldt; |
272 | 249 | ||
@@ -282,6 +259,7 @@ long sys_ptrace(long request, long pid, long addr, long data) | |||
282 | ret = -EIO; | 259 | ret = -EIO; |
283 | break; | 260 | break; |
284 | } | 261 | } |
262 | #endif | ||
285 | #ifdef CONFIG_PROC_MM | 263 | #ifdef CONFIG_PROC_MM |
286 | case PTRACE_SWITCH_MM: { | 264 | case PTRACE_SWITCH_MM: { |
287 | struct mm_struct *old = child->mm; | 265 | struct mm_struct *old = child->mm; |
@@ -337,15 +315,16 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit) | |||
337 | 315 | ||
338 | if (unlikely(current->audit_context)) { | 316 | if (unlikely(current->audit_context)) { |
339 | if (!entryexit) | 317 | if (!entryexit) |
340 | audit_syscall_entry(current, | 318 | audit_syscall_entry(current, |
341 | UPT_SYSCALL_NR(®s->regs), | 319 | HOST_AUDIT_ARCH, |
342 | UPT_SYSCALL_ARG1(®s->regs), | 320 | UPT_SYSCALL_NR(regs), |
343 | UPT_SYSCALL_ARG2(®s->regs), | 321 | UPT_SYSCALL_ARG1(regs), |
344 | UPT_SYSCALL_ARG3(®s->regs), | 322 | UPT_SYSCALL_ARG2(regs), |
345 | UPT_SYSCALL_ARG4(®s->regs)); | 323 | UPT_SYSCALL_ARG3(regs), |
346 | else | 324 | UPT_SYSCALL_ARG4(regs)); |
347 | audit_syscall_exit(current, | 325 | else audit_syscall_exit(current, |
348 | UPT_SYSCALL_RET(®s->regs)); | 326 | AUDITSC_RESULT(UPT_SYSCALL_RET(regs)), |
327 | UPT_SYSCALL_RET(regs)); | ||
349 | } | 328 | } |
350 | 329 | ||
351 | /* Fake a debug trap */ | 330 | /* Fake a debug trap */ |
@@ -375,14 +354,3 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit) | |||
375 | current->exit_code = 0; | 354 | current->exit_code = 0; |
376 | } | 355 | } |
377 | } | 356 | } |
378 | |||
379 | /* | ||
380 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
381 | * Emacs will notice this stuff at the end of the file and automatically | ||
382 | * adjust the settings for this buffer only. This must remain at the end | ||
383 | * of the file. | ||
384 | * --------------------------------------------------------------------------- | ||
385 | * Local variables: | ||
386 | * c-file-style: "linux" | ||
387 | * End: | ||
388 | */ | ||
diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c index 668df13d8c9d..e89218958f38 100644 --- a/arch/um/kernel/sigio_user.c +++ b/arch/um/kernel/sigio_user.c | |||
@@ -182,6 +182,7 @@ static int write_sigio_thread(void *unused) | |||
182 | int i, n, respond_fd; | 182 | int i, n, respond_fd; |
183 | char c; | 183 | char c; |
184 | 184 | ||
185 | signal(SIGWINCH, SIG_IGN); | ||
185 | fds = ¤t_poll; | 186 | fds = ¤t_poll; |
186 | while(1){ | 187 | while(1){ |
187 | n = poll(fds->poll, fds->used, -1); | 188 | n = poll(fds->poll, fds->used, -1); |
diff --git a/arch/um/kernel/skas/include/mode_kern-skas.h b/arch/um/kernel/skas/include/mode_kern-skas.h index 94c564962378..e48490028111 100644 --- a/arch/um/kernel/skas/include/mode_kern-skas.h +++ b/arch/um/kernel/skas/include/mode_kern-skas.h | |||
@@ -18,7 +18,6 @@ extern int copy_thread_skas(int nr, unsigned long clone_flags, | |||
18 | unsigned long sp, unsigned long stack_top, | 18 | unsigned long sp, unsigned long stack_top, |
19 | struct task_struct *p, struct pt_regs *regs); | 19 | struct task_struct *p, struct pt_regs *regs); |
20 | extern void release_thread_skas(struct task_struct *task); | 20 | extern void release_thread_skas(struct task_struct *task); |
21 | extern void exit_thread_skas(void); | ||
22 | extern void initial_thread_cb_skas(void (*proc)(void *), void *arg); | 21 | extern void initial_thread_cb_skas(void (*proc)(void *), void *arg); |
23 | extern void init_idle_skas(void); | 22 | extern void init_idle_skas(void); |
24 | extern void flush_tlb_kernel_range_skas(unsigned long start, | 23 | extern void flush_tlb_kernel_range_skas(unsigned long start, |
diff --git a/arch/um/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h index f0702c2c7204..96b51dba3471 100644 --- a/arch/um/kernel/skas/include/skas.h +++ b/arch/um/kernel/skas/include/skas.h | |||
@@ -27,9 +27,10 @@ extern void map(int fd, unsigned long virt, unsigned long len, int r, int w, | |||
27 | extern int unmap(int fd, void *addr, unsigned long len); | 27 | extern int unmap(int fd, void *addr, unsigned long len); |
28 | extern int protect(int fd, unsigned long addr, unsigned long len, | 28 | extern int protect(int fd, unsigned long addr, unsigned long len, |
29 | int r, int w, int x); | 29 | int r, int w, int x); |
30 | extern void user_signal(int sig, union uml_pt_regs *regs); | 30 | extern void user_signal(int sig, union uml_pt_regs *regs, int pid); |
31 | extern int new_mm(int from); | 31 | extern int new_mm(int from); |
32 | extern void start_userspace(int cpu); | 32 | extern void start_userspace(int cpu); |
33 | extern void get_skas_faultinfo(int pid, struct faultinfo * fi); | ||
33 | extern long execute_syscall_skas(void *r); | 34 | extern long execute_syscall_skas(void *r); |
34 | 35 | ||
35 | #endif | 36 | #endif |
diff --git a/arch/um/kernel/skas/include/uaccess-skas.h b/arch/um/kernel/skas/include/uaccess-skas.h index c35620385da0..cd6c280482cb 100644 --- a/arch/um/kernel/skas/include/uaccess-skas.h +++ b/arch/um/kernel/skas/include/uaccess-skas.h | |||
@@ -18,8 +18,8 @@ | |||
18 | ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \ | 18 | ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \ |
19 | ((unsigned long) (addr) + (size) >= (unsigned long)(addr)))) | 19 | ((unsigned long) (addr) + (size) >= (unsigned long)(addr)))) |
20 | 20 | ||
21 | static inline int __deprecated verify_area_skas(int type, const void * addr, | 21 | static inline int verify_area_skas(int type, const void * addr, |
22 | unsigned long size) | 22 | unsigned long size) |
23 | { | 23 | { |
24 | return(access_ok_skas(type, addr, size) ? 0 : -EFAULT); | 24 | return(access_ok_skas(type, addr, size) ? 0 : -EFAULT); |
25 | } | 25 | } |
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index b4ffaaa81241..773cd2b525fc 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c | |||
@@ -4,6 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <stdlib.h> | 6 | #include <stdlib.h> |
7 | #include <string.h> | ||
7 | #include <unistd.h> | 8 | #include <unistd.h> |
8 | #include <errno.h> | 9 | #include <errno.h> |
9 | #include <signal.h> | 10 | #include <signal.h> |
@@ -27,27 +28,37 @@ | |||
27 | #include "chan_user.h" | 28 | #include "chan_user.h" |
28 | #include "signal_user.h" | 29 | #include "signal_user.h" |
29 | #include "registers.h" | 30 | #include "registers.h" |
31 | #include "process.h" | ||
30 | 32 | ||
31 | int is_skas_winch(int pid, int fd, void *data) | 33 | int is_skas_winch(int pid, int fd, void *data) |
32 | { | 34 | { |
33 | if(pid != os_getpid()) | 35 | if(pid != os_getpgrp()) |
34 | return(0); | 36 | return(0); |
35 | 37 | ||
36 | register_winch_irq(-1, fd, -1, data); | 38 | register_winch_irq(-1, fd, -1, data); |
37 | return(1); | 39 | return(1); |
38 | } | 40 | } |
39 | 41 | ||
40 | static void handle_segv(int pid) | 42 | void get_skas_faultinfo(int pid, struct faultinfo * fi) |
41 | { | 43 | { |
42 | struct ptrace_faultinfo fault; | ||
43 | int err; | 44 | int err; |
44 | 45 | ||
45 | err = ptrace(PTRACE_FAULTINFO, pid, 0, &fault); | 46 | err = ptrace(PTRACE_FAULTINFO, pid, 0, fi); |
46 | if(err) | 47 | if(err) |
47 | panic("handle_segv - PTRACE_FAULTINFO failed, errno = %d\n", | 48 | panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, " |
48 | errno); | 49 | "errno = %d\n", errno); |
50 | |||
51 | /* Special handling for i386, which has different structs */ | ||
52 | if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo)) | ||
53 | memset((char *)fi + sizeof(struct ptrace_faultinfo), 0, | ||
54 | sizeof(struct faultinfo) - | ||
55 | sizeof(struct ptrace_faultinfo)); | ||
56 | } | ||
49 | 57 | ||
50 | segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL); | 58 | static void handle_segv(int pid, union uml_pt_regs * regs) |
59 | { | ||
60 | get_skas_faultinfo(pid, ®s->skas.faultinfo); | ||
61 | segv(regs->skas.faultinfo, 0, 1, NULL); | ||
51 | } | 62 | } |
52 | 63 | ||
53 | /*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/ | 64 | /*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/ |
@@ -163,7 +174,7 @@ void userspace(union uml_pt_regs *regs) | |||
163 | if(WIFSTOPPED(status)){ | 174 | if(WIFSTOPPED(status)){ |
164 | switch(WSTOPSIG(status)){ | 175 | switch(WSTOPSIG(status)){ |
165 | case SIGSEGV: | 176 | case SIGSEGV: |
166 | handle_segv(pid); | 177 | handle_segv(pid, regs); |
167 | break; | 178 | break; |
168 | case SIGTRAP + 0x80: | 179 | case SIGTRAP + 0x80: |
169 | handle_trap(pid, regs, local_using_sysemu); | 180 | handle_trap(pid, regs, local_using_sysemu); |
@@ -177,7 +188,7 @@ void userspace(union uml_pt_regs *regs) | |||
177 | case SIGBUS: | 188 | case SIGBUS: |
178 | case SIGFPE: | 189 | case SIGFPE: |
179 | case SIGWINCH: | 190 | case SIGWINCH: |
180 | user_signal(WSTOPSIG(status), regs); | 191 | user_signal(WSTOPSIG(status), regs, pid); |
181 | break; | 192 | break; |
182 | default: | 193 | default: |
183 | printk("userspace - child stopped with signal " | 194 | printk("userspace - child stopped with signal " |
@@ -190,6 +201,11 @@ void userspace(union uml_pt_regs *regs) | |||
190 | } | 201 | } |
191 | } | 202 | } |
192 | } | 203 | } |
204 | #define INIT_JMP_NEW_THREAD 0 | ||
205 | #define INIT_JMP_REMOVE_SIGSTACK 1 | ||
206 | #define INIT_JMP_CALLBACK 2 | ||
207 | #define INIT_JMP_HALT 3 | ||
208 | #define INIT_JMP_REBOOT 4 | ||
193 | 209 | ||
194 | void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | 210 | void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, |
195 | void (*handler)(int)) | 211 | void (*handler)(int)) |
@@ -225,7 +241,7 @@ void thread_wait(void *sw, void *fb) | |||
225 | *switch_buf = &buf; | 241 | *switch_buf = &buf; |
226 | fork_buf = fb; | 242 | fork_buf = fb; |
227 | if(sigsetjmp(buf, 1) == 0) | 243 | if(sigsetjmp(buf, 1) == 0) |
228 | siglongjmp(*fork_buf, 1); | 244 | siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK); |
229 | } | 245 | } |
230 | 246 | ||
231 | void switch_threads(void *me, void *next) | 247 | void switch_threads(void *me, void *next) |
@@ -249,23 +265,31 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | |||
249 | sigjmp_buf **switch_buf = switch_buf_ptr; | 265 | sigjmp_buf **switch_buf = switch_buf_ptr; |
250 | int n; | 266 | int n; |
251 | 267 | ||
268 | set_handler(SIGWINCH, (__sighandler_t) sig_handler, | ||
269 | SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM, | ||
270 | SIGVTALRM, -1); | ||
271 | |||
252 | *fork_buf_ptr = &initial_jmpbuf; | 272 | *fork_buf_ptr = &initial_jmpbuf; |
253 | n = sigsetjmp(initial_jmpbuf, 1); | 273 | n = sigsetjmp(initial_jmpbuf, 1); |
254 | if(n == 0) | 274 | switch(n){ |
255 | new_thread_proc((void *) stack, new_thread_handler); | 275 | case INIT_JMP_NEW_THREAD: |
256 | else if(n == 1) | 276 | new_thread_proc((void *) stack, new_thread_handler); |
257 | remove_sigstack(); | 277 | break; |
258 | else if(n == 2){ | 278 | case INIT_JMP_REMOVE_SIGSTACK: |
279 | remove_sigstack(); | ||
280 | break; | ||
281 | case INIT_JMP_CALLBACK: | ||
259 | (*cb_proc)(cb_arg); | 282 | (*cb_proc)(cb_arg); |
260 | siglongjmp(*cb_back, 1); | 283 | siglongjmp(*cb_back, 1); |
261 | } | 284 | break; |
262 | else if(n == 3){ | 285 | case INIT_JMP_HALT: |
263 | kmalloc_ok = 0; | 286 | kmalloc_ok = 0; |
264 | return(0); | 287 | return(0); |
265 | } | 288 | case INIT_JMP_REBOOT: |
266 | else if(n == 4){ | ||
267 | kmalloc_ok = 0; | 289 | kmalloc_ok = 0; |
268 | return(1); | 290 | return(1); |
291 | default: | ||
292 | panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); | ||
269 | } | 293 | } |
270 | siglongjmp(**switch_buf, 1); | 294 | siglongjmp(**switch_buf, 1); |
271 | } | 295 | } |
@@ -290,7 +314,7 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg) | |||
290 | 314 | ||
291 | block_signals(); | 315 | block_signals(); |
292 | if(sigsetjmp(here, 1) == 0) | 316 | if(sigsetjmp(here, 1) == 0) |
293 | siglongjmp(initial_jmpbuf, 2); | 317 | siglongjmp(initial_jmpbuf, INIT_JMP_CALLBACK); |
294 | unblock_signals(); | 318 | unblock_signals(); |
295 | 319 | ||
296 | cb_proc = NULL; | 320 | cb_proc = NULL; |
@@ -301,13 +325,13 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg) | |||
301 | void halt_skas(void) | 325 | void halt_skas(void) |
302 | { | 326 | { |
303 | block_signals(); | 327 | block_signals(); |
304 | siglongjmp(initial_jmpbuf, 3); | 328 | siglongjmp(initial_jmpbuf, INIT_JMP_HALT); |
305 | } | 329 | } |
306 | 330 | ||
307 | void reboot_skas(void) | 331 | void reboot_skas(void) |
308 | { | 332 | { |
309 | block_signals(); | 333 | block_signals(); |
310 | siglongjmp(initial_jmpbuf, 4); | 334 | siglongjmp(initial_jmpbuf, INIT_JMP_REBOOT); |
311 | } | 335 | } |
312 | 336 | ||
313 | void switch_mm_skas(int mm_fd) | 337 | void switch_mm_skas(int mm_fd) |
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c index 5d096ea63b97..fc71ef295782 100644 --- a/arch/um/kernel/skas/process_kern.c +++ b/arch/um/kernel/skas/process_kern.c | |||
@@ -68,8 +68,11 @@ void new_thread_handler(int sig) | |||
68 | * 0 if it just exits | 68 | * 0 if it just exits |
69 | */ | 69 | */ |
70 | n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf); | 70 | n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf); |
71 | if(n == 1) | 71 | if(n == 1){ |
72 | /* Handle any immediate reschedules or signals */ | ||
73 | interrupt_end(); | ||
72 | userspace(¤t->thread.regs.regs); | 74 | userspace(¤t->thread.regs.regs); |
75 | } | ||
73 | else do_exit(0); | 76 | else do_exit(0); |
74 | } | 77 | } |
75 | 78 | ||
@@ -83,10 +86,6 @@ void release_thread_skas(struct task_struct *task) | |||
83 | { | 86 | { |
84 | } | 87 | } |
85 | 88 | ||
86 | void exit_thread_skas(void) | ||
87 | { | ||
88 | } | ||
89 | |||
90 | void fork_handler(int sig) | 89 | void fork_handler(int sig) |
91 | { | 90 | { |
92 | change_sig(SIGUSR1, 1); | 91 | change_sig(SIGUSR1, 1); |
@@ -100,6 +99,8 @@ void fork_handler(int sig) | |||
100 | schedule_tail(current->thread.prev_sched); | 99 | schedule_tail(current->thread.prev_sched); |
101 | current->thread.prev_sched = NULL; | 100 | current->thread.prev_sched = NULL; |
102 | 101 | ||
102 | /* Handle any immediate reschedules or signals */ | ||
103 | interrupt_end(); | ||
103 | userspace(¤t->thread.regs.regs); | 104 | userspace(¤t->thread.regs.regs); |
104 | } | 105 | } |
105 | 106 | ||
diff --git a/arch/um/kernel/skas/trap_user.c b/arch/um/kernel/skas/trap_user.c index 8e9b46d4702e..0dee1d95c806 100644 --- a/arch/um/kernel/skas/trap_user.c +++ b/arch/um/kernel/skas/trap_user.c | |||
@@ -5,12 +5,15 @@ | |||
5 | 5 | ||
6 | #include <signal.h> | 6 | #include <signal.h> |
7 | #include <errno.h> | 7 | #include <errno.h> |
8 | #include "sysdep/ptrace.h" | ||
9 | #include "signal_user.h" | 8 | #include "signal_user.h" |
10 | #include "user_util.h" | 9 | #include "user_util.h" |
11 | #include "kern_util.h" | 10 | #include "kern_util.h" |
12 | #include "task.h" | 11 | #include "task.h" |
13 | #include "sigcontext.h" | 12 | #include "sigcontext.h" |
13 | #include "skas.h" | ||
14 | #include "ptrace_user.h" | ||
15 | #include "sysdep/ptrace.h" | ||
16 | #include "sysdep/ptrace_user.h" | ||
14 | 17 | ||
15 | void sig_handler_common_skas(int sig, void *sc_ptr) | 18 | void sig_handler_common_skas(int sig, void *sc_ptr) |
16 | { | 19 | { |
@@ -31,9 +34,11 @@ void sig_handler_common_skas(int sig, void *sc_ptr) | |||
31 | r = &TASK_REGS(get_current())->skas; | 34 | r = &TASK_REGS(get_current())->skas; |
32 | save_user = r->is_user; | 35 | save_user = r->is_user; |
33 | r->is_user = 0; | 36 | r->is_user = 0; |
34 | r->fault_addr = SC_FAULT_ADDR(sc); | 37 | if ( sig == SIGFPE || sig == SIGSEGV || |
35 | r->fault_type = SC_FAULT_TYPE(sc); | 38 | sig == SIGBUS || sig == SIGILL || |
36 | r->trap_type = SC_TRAP_TYPE(sc); | 39 | sig == SIGTRAP ) { |
40 | GET_FAULTINFO_FROM_SC(r->faultinfo, sc); | ||
41 | } | ||
37 | 42 | ||
38 | change_sig(SIGUSR1, 1); | 43 | change_sig(SIGUSR1, 1); |
39 | info = &sig_info[sig]; | 44 | info = &sig_info[sig]; |
@@ -45,14 +50,17 @@ void sig_handler_common_skas(int sig, void *sc_ptr) | |||
45 | r->is_user = save_user; | 50 | r->is_user = save_user; |
46 | } | 51 | } |
47 | 52 | ||
48 | void user_signal(int sig, union uml_pt_regs *regs) | 53 | extern int ptrace_faultinfo; |
54 | |||
55 | void user_signal(int sig, union uml_pt_regs *regs, int pid) | ||
49 | { | 56 | { |
50 | struct signal_info *info; | 57 | struct signal_info *info; |
58 | int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) || | ||
59 | (sig == SIGILL) || (sig == SIGTRAP)); | ||
51 | 60 | ||
52 | regs->skas.is_user = 1; | 61 | regs->skas.is_user = 1; |
53 | regs->skas.fault_addr = 0; | 62 | if (segv) |
54 | regs->skas.fault_type = 0; | 63 | get_skas_faultinfo(pid, ®s->skas.faultinfo); |
55 | regs->skas.trap_type = 0; | ||
56 | info = &sig_info[sig]; | 64 | info = &sig_info[sig]; |
57 | (*info->handler)(sig, regs); | 65 | (*info->handler)(sig, regs); |
58 | 66 | ||
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c index f7da9d027672..75195281081e 100644 --- a/arch/um/kernel/skas/uaccess.c +++ b/arch/um/kernel/skas/uaccess.c | |||
@@ -29,9 +29,12 @@ static unsigned long maybe_map(unsigned long virt, int is_write) | |||
29 | if(IS_ERR(phys) || (is_write && !pte_write(pte))){ | 29 | if(IS_ERR(phys) || (is_write && !pte_write(pte))){ |
30 | err = handle_page_fault(virt, 0, is_write, 1, &dummy_code); | 30 | err = handle_page_fault(virt, 0, is_write, 1, &dummy_code); |
31 | if(err) | 31 | if(err) |
32 | return(0); | 32 | return(-1UL); |
33 | phys = um_virt_to_phys(current, virt, NULL); | 33 | phys = um_virt_to_phys(current, virt, NULL); |
34 | } | 34 | } |
35 | if(IS_ERR(phys)) | ||
36 | phys = (void *) -1; | ||
37 | |||
35 | return((unsigned long) phys); | 38 | return((unsigned long) phys); |
36 | } | 39 | } |
37 | 40 | ||
@@ -42,7 +45,7 @@ static int do_op(unsigned long addr, int len, int is_write, | |||
42 | int n; | 45 | int n; |
43 | 46 | ||
44 | addr = maybe_map(addr, is_write); | 47 | addr = maybe_map(addr, is_write); |
45 | if(addr == -1) | 48 | if(addr == -1UL) |
46 | return(-1); | 49 | return(-1); |
47 | 50 | ||
48 | page = phys_to_page(addr); | 51 | page = phys_to_page(addr); |
diff --git a/arch/um/kernel/skas/util/Makefile b/arch/um/kernel/skas/util/Makefile index 17f5909d60f7..f7b7eba83340 100644 --- a/arch/um/kernel/skas/util/Makefile +++ b/arch/um/kernel/skas/util/Makefile | |||
@@ -2,3 +2,4 @@ hostprogs-y := mk_ptregs | |||
2 | always := $(hostprogs-y) | 2 | always := $(hostprogs-y) |
3 | 3 | ||
4 | mk_ptregs-objs := mk_ptregs-$(SUBARCH).o | 4 | mk_ptregs-objs := mk_ptregs-$(SUBARCH).o |
5 | HOSTCFLAGS_mk_ptregs-$(SUBARCH).o := -I$(objtree)/arch/um | ||
diff --git a/arch/um/kernel/skas/util/mk_ptregs-i386.c b/arch/um/kernel/skas/util/mk_ptregs-i386.c index 0788dd05bcac..1f96e1eeb8a7 100644 --- a/arch/um/kernel/skas/util/mk_ptregs-i386.c +++ b/arch/um/kernel/skas/util/mk_ptregs-i386.c | |||
@@ -1,8 +1,7 @@ | |||
1 | #include <stdio.h> | 1 | #include <stdio.h> |
2 | #include <asm/ptrace.h> | 2 | #include <user-offsets.h> |
3 | #include <asm/user.h> | ||
4 | 3 | ||
5 | #define PRINT_REG(name, val) printf("#define HOST_%s %d\n", (name), (val)) | 4 | #define SHOW(name) printf("#define %s %d\n", #name, name) |
6 | 5 | ||
7 | int main(int argc, char **argv) | 6 | int main(int argc, char **argv) |
8 | { | 7 | { |
@@ -12,28 +11,27 @@ int main(int argc, char **argv) | |||
12 | printf("#ifndef __SKAS_PT_REGS_\n"); | 11 | printf("#ifndef __SKAS_PT_REGS_\n"); |
13 | printf("#define __SKAS_PT_REGS_\n"); | 12 | printf("#define __SKAS_PT_REGS_\n"); |
14 | printf("\n"); | 13 | printf("\n"); |
15 | printf("#define HOST_FRAME_SIZE %d\n", FRAME_SIZE); | 14 | SHOW(HOST_FRAME_SIZE); |
16 | printf("#define HOST_FP_SIZE %d\n", | 15 | SHOW(HOST_FP_SIZE); |
17 | sizeof(struct user_i387_struct) / sizeof(unsigned long)); | 16 | SHOW(HOST_XFP_SIZE); |
18 | printf("#define HOST_XFP_SIZE %d\n", | 17 | |
19 | sizeof(struct user_fxsr_struct) / sizeof(unsigned long)); | 18 | SHOW(HOST_IP); |
19 | SHOW(HOST_SP); | ||
20 | SHOW(HOST_EFLAGS); | ||
21 | SHOW(HOST_EAX); | ||
22 | SHOW(HOST_EBX); | ||
23 | SHOW(HOST_ECX); | ||
24 | SHOW(HOST_EDX); | ||
25 | SHOW(HOST_ESI); | ||
26 | SHOW(HOST_EDI); | ||
27 | SHOW(HOST_EBP); | ||
28 | SHOW(HOST_CS); | ||
29 | SHOW(HOST_SS); | ||
30 | SHOW(HOST_DS); | ||
31 | SHOW(HOST_FS); | ||
32 | SHOW(HOST_ES); | ||
33 | SHOW(HOST_GS); | ||
20 | 34 | ||
21 | PRINT_REG("IP", EIP); | ||
22 | PRINT_REG("SP", UESP); | ||
23 | PRINT_REG("EFLAGS", EFL); | ||
24 | PRINT_REG("EAX", EAX); | ||
25 | PRINT_REG("EBX", EBX); | ||
26 | PRINT_REG("ECX", ECX); | ||
27 | PRINT_REG("EDX", EDX); | ||
28 | PRINT_REG("ESI", ESI); | ||
29 | PRINT_REG("EDI", EDI); | ||
30 | PRINT_REG("EBP", EBP); | ||
31 | PRINT_REG("CS", CS); | ||
32 | PRINT_REG("SS", SS); | ||
33 | PRINT_REG("DS", DS); | ||
34 | PRINT_REG("FS", FS); | ||
35 | PRINT_REG("ES", ES); | ||
36 | PRINT_REG("GS", GS); | ||
37 | printf("\n"); | 35 | printf("\n"); |
38 | printf("#endif\n"); | 36 | printf("#endif\n"); |
39 | return(0); | 37 | return(0); |
diff --git a/arch/um/kernel/skas/util/mk_ptregs-x86_64.c b/arch/um/kernel/skas/util/mk_ptregs-x86_64.c index 67aee92a70ef..5fccbfe35f78 100644 --- a/arch/um/kernel/skas/util/mk_ptregs-x86_64.c +++ b/arch/um/kernel/skas/util/mk_ptregs-x86_64.c | |||
@@ -5,11 +5,10 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <stdio.h> | 7 | #include <stdio.h> |
8 | #define __FRAME_OFFSETS | 8 | #include <user-offsets.h> |
9 | #include <asm/ptrace.h> | ||
10 | 9 | ||
11 | #define PRINT_REG(name, val) \ | 10 | #define SHOW(name) \ |
12 | printf("#define HOST_%s (%d / sizeof(unsigned long))\n", (name), (val)) | 11 | printf("#define %s (%d / sizeof(unsigned long))\n", #name, name) |
13 | 12 | ||
14 | int main(int argc, char **argv) | 13 | int main(int argc, char **argv) |
15 | { | 14 | { |
@@ -18,36 +17,35 @@ int main(int argc, char **argv) | |||
18 | printf("\n"); | 17 | printf("\n"); |
19 | printf("#ifndef __SKAS_PT_REGS_\n"); | 18 | printf("#ifndef __SKAS_PT_REGS_\n"); |
20 | printf("#define __SKAS_PT_REGS_\n"); | 19 | printf("#define __SKAS_PT_REGS_\n"); |
21 | printf("#define HOST_FRAME_SIZE (%d / sizeof(unsigned long))\n", | 20 | SHOW(HOST_FRAME_SIZE); |
22 | FRAME_SIZE); | 21 | SHOW(HOST_RBX); |
23 | PRINT_REG("RBX", RBX); | 22 | SHOW(HOST_RCX); |
24 | PRINT_REG("RCX", RCX); | 23 | SHOW(HOST_RDI); |
25 | PRINT_REG("RDI", RDI); | 24 | SHOW(HOST_RSI); |
26 | PRINT_REG("RSI", RSI); | 25 | SHOW(HOST_RDX); |
27 | PRINT_REG("RDX", RDX); | 26 | SHOW(HOST_RBP); |
28 | PRINT_REG("RBP", RBP); | 27 | SHOW(HOST_RAX); |
29 | PRINT_REG("RAX", RAX); | 28 | SHOW(HOST_R8); |
30 | PRINT_REG("R8", R8); | 29 | SHOW(HOST_R9); |
31 | PRINT_REG("R9", R9); | 30 | SHOW(HOST_R10); |
32 | PRINT_REG("R10", R10); | 31 | SHOW(HOST_R11); |
33 | PRINT_REG("R11", R11); | 32 | SHOW(HOST_R12); |
34 | PRINT_REG("R12", R12); | 33 | SHOW(HOST_R13); |
35 | PRINT_REG("R13", R13); | 34 | SHOW(HOST_R14); |
36 | PRINT_REG("R14", R14); | 35 | SHOW(HOST_R15); |
37 | PRINT_REG("R15", R15); | 36 | SHOW(HOST_ORIG_RAX); |
38 | PRINT_REG("ORIG_RAX", ORIG_RAX); | 37 | SHOW(HOST_CS); |
39 | PRINT_REG("CS", CS); | 38 | SHOW(HOST_SS); |
40 | PRINT_REG("SS", SS); | 39 | SHOW(HOST_EFLAGS); |
41 | PRINT_REG("EFLAGS", EFLAGS); | ||
42 | #if 0 | 40 | #if 0 |
43 | PRINT_REG("FS", FS); | 41 | SHOW(HOST_FS); |
44 | PRINT_REG("GS", GS); | 42 | SHOW(HOST_GS); |
45 | PRINT_REG("DS", DS); | 43 | SHOW(HOST_DS); |
46 | PRINT_REG("ES", ES); | 44 | SHOW(HOST_ES); |
47 | #endif | 45 | #endif |
48 | 46 | ||
49 | PRINT_REG("IP", RIP); | 47 | SHOW(HOST_IP); |
50 | PRINT_REG("SP", RSP); | 48 | SHOW(HOST_SP); |
51 | printf("#define HOST_FP_SIZE 0\n"); | 49 | printf("#define HOST_FP_SIZE 0\n"); |
52 | printf("#define HOST_XFP_SIZE 0\n"); | 50 | printf("#define HOST_XFP_SIZE 0\n"); |
53 | printf("\n"); | 51 | printf("\n"); |
diff --git a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c index 42731e04f50f..b7a55251e897 100644 --- a/arch/um/kernel/syscall_kern.c +++ b/arch/um/kernel/syscall_kern.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include "linux/utime.h" | 17 | #include "linux/utime.h" |
18 | #include "asm/mman.h" | 18 | #include "asm/mman.h" |
19 | #include "asm/uaccess.h" | 19 | #include "asm/uaccess.h" |
20 | #include "asm/ipc.h" | ||
21 | #include "kern_util.h" | 20 | #include "kern_util.h" |
22 | #include "user_util.h" | 21 | #include "user_util.h" |
23 | #include "sysdep/syscalls.h" | 22 | #include "sysdep/syscalls.h" |
diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c index e630438f9e73..f80850091e79 100644 --- a/arch/um/kernel/sysrq.c +++ b/arch/um/kernel/sysrq.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/config.h" | ||
6 | #include "linux/sched.h" | 7 | #include "linux/sched.h" |
7 | #include "linux/kernel.h" | 8 | #include "linux/kernel.h" |
8 | #include "linux/module.h" | 9 | #include "linux/module.h" |
@@ -12,14 +13,14 @@ | |||
12 | #include "sysrq.h" | 13 | #include "sysrq.h" |
13 | #include "user_util.h" | 14 | #include "user_util.h" |
14 | 15 | ||
15 | void show_trace(unsigned long * stack) | 16 | /* Catch non-i386 SUBARCH's. */ |
17 | #if !defined(CONFIG_UML_X86) || defined(CONFIG_64BIT) | ||
18 | void show_trace(struct task_struct *task, unsigned long * stack) | ||
16 | { | 19 | { |
17 | /* XXX: Copy the CONFIG_FRAME_POINTER stack-walking backtrace from | ||
18 | * arch/i386/kernel/traps.c, and then move this to sys-i386/sysrq.c.*/ | ||
19 | unsigned long addr; | 20 | unsigned long addr; |
20 | 21 | ||
21 | if (!stack) { | 22 | if (!stack) { |
22 | stack = (unsigned long*) &stack; | 23 | stack = (unsigned long*) &stack; |
23 | WARN_ON(1); | 24 | WARN_ON(1); |
24 | } | 25 | } |
25 | 26 | ||
@@ -35,6 +36,7 @@ void show_trace(unsigned long * stack) | |||
35 | } | 36 | } |
36 | printk("\n"); | 37 | printk("\n"); |
37 | } | 38 | } |
39 | #endif | ||
38 | 40 | ||
39 | /* | 41 | /* |
40 | * stack dumps generator - this is used by arch-independent code. | 42 | * stack dumps generator - this is used by arch-independent code. |
@@ -44,7 +46,7 @@ void dump_stack(void) | |||
44 | { | 46 | { |
45 | unsigned long stack; | 47 | unsigned long stack; |
46 | 48 | ||
47 | show_trace(&stack); | 49 | show_trace(current, &stack); |
48 | } | 50 | } |
49 | EXPORT_SYMBOL(dump_stack); | 51 | EXPORT_SYMBOL(dump_stack); |
50 | 52 | ||
@@ -59,7 +61,11 @@ void show_stack(struct task_struct *task, unsigned long *esp) | |||
59 | int i; | 61 | int i; |
60 | 62 | ||
61 | if (esp == NULL) { | 63 | if (esp == NULL) { |
62 | if (task != current) { | 64 | if (task != current && task != NULL) { |
65 | /* XXX: Isn't this bogus? I.e. isn't this the | ||
66 | * *userspace* stack of this task? If not so, use this | ||
67 | * even when task == current (as in i386). | ||
68 | */ | ||
63 | esp = (unsigned long *) KSTK_ESP(task); | 69 | esp = (unsigned long *) KSTK_ESP(task); |
64 | /* Which one? No actual difference - just coding style.*/ | 70 | /* Which one? No actual difference - just coding style.*/ |
65 | //esp = (unsigned long *) PT_REGS_IP(&task->thread.regs); | 71 | //esp = (unsigned long *) PT_REGS_IP(&task->thread.regs); |
@@ -77,5 +83,6 @@ void show_stack(struct task_struct *task, unsigned long *esp) | |||
77 | printk("%08lx ", *stack++); | 83 | printk("%08lx ", *stack++); |
78 | } | 84 | } |
79 | 85 | ||
80 | show_trace(esp); | 86 | printk("Call Trace: \n"); |
87 | show_trace(current, esp); | ||
81 | } | 88 | } |
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c index 2461cd73ca87..6516fc52afe0 100644 --- a/arch/um/kernel/time_kern.c +++ b/arch/um/kernel/time_kern.c | |||
@@ -48,8 +48,6 @@ static unsigned long long prev_usecs; | |||
48 | static long long delta; /* Deviation per interval */ | 48 | static long long delta; /* Deviation per interval */ |
49 | #endif | 49 | #endif |
50 | 50 | ||
51 | #define MILLION 1000000 | ||
52 | |||
53 | void timer_irq(union uml_pt_regs *regs) | 51 | void timer_irq(union uml_pt_regs *regs) |
54 | { | 52 | { |
55 | unsigned long long ticks = 0; | 53 | unsigned long long ticks = 0; |
@@ -136,22 +134,6 @@ long um_stime(int __user *tptr) | |||
136 | return 0; | 134 | return 0; |
137 | } | 135 | } |
138 | 136 | ||
139 | void __udelay(unsigned long usecs) | ||
140 | { | ||
141 | int i, n; | ||
142 | |||
143 | n = (loops_per_jiffy * HZ * usecs) / MILLION; | ||
144 | for(i=0;i<n;i++) ; | ||
145 | } | ||
146 | |||
147 | void __const_udelay(unsigned long usecs) | ||
148 | { | ||
149 | int i, n; | ||
150 | |||
151 | n = (loops_per_jiffy * HZ * usecs) / MILLION; | ||
152 | for(i=0;i<n;i++) ; | ||
153 | } | ||
154 | |||
155 | void timer_handler(int sig, union uml_pt_regs *regs) | 137 | void timer_handler(int sig, union uml_pt_regs *regs) |
156 | { | 138 | { |
157 | local_irq_disable(); | 139 | local_irq_disable(); |
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c index 47e766e6ba10..c20aef120598 100644 --- a/arch/um/kernel/trap_kern.c +++ b/arch/um/kernel/trap_kern.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include "kern.h" | 23 | #include "kern.h" |
24 | #include "chan_kern.h" | 24 | #include "chan_kern.h" |
25 | #include "mconsole_kern.h" | 25 | #include "mconsole_kern.h" |
26 | #include "2_5compat.h" | ||
27 | #include "mem.h" | 26 | #include "mem.h" |
28 | #include "mem_kern.h" | 27 | #include "mem_kern.h" |
29 | 28 | ||
@@ -48,7 +47,7 @@ int handle_page_fault(unsigned long address, unsigned long ip, | |||
48 | goto good_area; | 47 | goto good_area; |
49 | else if(!(vma->vm_flags & VM_GROWSDOWN)) | 48 | else if(!(vma->vm_flags & VM_GROWSDOWN)) |
50 | goto out; | 49 | goto out; |
51 | else if(!ARCH_IS_STACKGROW(address)) | 50 | else if(is_user && !ARCH_IS_STACKGROW(address)) |
52 | goto out; | 51 | goto out; |
53 | else if(expand_stack(vma, address)) | 52 | else if(expand_stack(vma, address)) |
54 | goto out; | 53 | goto out; |
@@ -57,10 +56,11 @@ int handle_page_fault(unsigned long address, unsigned long ip, | |||
57 | *code_out = SEGV_ACCERR; | 56 | *code_out = SEGV_ACCERR; |
58 | if(is_write && !(vma->vm_flags & VM_WRITE)) | 57 | if(is_write && !(vma->vm_flags & VM_WRITE)) |
59 | goto out; | 58 | goto out; |
59 | |||
60 | if(!(vma->vm_flags & (VM_READ | VM_EXEC))) | ||
61 | goto out; | ||
62 | |||
60 | page = address & PAGE_MASK; | 63 | page = address & PAGE_MASK; |
61 | pgd = pgd_offset(mm, page); | ||
62 | pud = pud_offset(pgd, page); | ||
63 | pmd = pmd_offset(pud, page); | ||
64 | do { | 64 | do { |
65 | survive: | 65 | survive: |
66 | switch (handle_mm_fault(mm, vma, address, is_write)){ | 66 | switch (handle_mm_fault(mm, vma, address, is_write)){ |
@@ -106,46 +106,24 @@ out_of_memory: | |||
106 | goto out; | 106 | goto out; |
107 | } | 107 | } |
108 | 108 | ||
109 | LIST_HEAD(physmem_remappers); | 109 | /* |
110 | 110 | * We give a *copy* of the faultinfo in the regs to segv. | |
111 | void register_remapper(struct remapper *info) | 111 | * This must be done, since nesting SEGVs could overwrite |
112 | { | 112 | * the info in the regs. A pointer to the info then would |
113 | list_add(&info->list, &physmem_remappers); | 113 | * give us bad data! |
114 | } | 114 | */ |
115 | 115 | unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc) | |
116 | static int check_remapped_addr(unsigned long address, int is_write) | ||
117 | { | ||
118 | struct remapper *remapper; | ||
119 | struct list_head *ele; | ||
120 | __u64 offset; | ||
121 | int fd; | ||
122 | |||
123 | fd = phys_mapping(__pa(address), &offset); | ||
124 | if(fd == -1) | ||
125 | return(0); | ||
126 | |||
127 | list_for_each(ele, &physmem_remappers){ | ||
128 | remapper = list_entry(ele, struct remapper, list); | ||
129 | if((*remapper->proc)(fd, address, is_write, offset)) | ||
130 | return(1); | ||
131 | } | ||
132 | |||
133 | return(0); | ||
134 | } | ||
135 | |||
136 | unsigned long segv(unsigned long address, unsigned long ip, int is_write, | ||
137 | int is_user, void *sc) | ||
138 | { | 116 | { |
139 | struct siginfo si; | 117 | struct siginfo si; |
140 | void *catcher; | 118 | void *catcher; |
141 | int err; | 119 | int err; |
120 | int is_write = FAULT_WRITE(fi); | ||
121 | unsigned long address = FAULT_ADDRESS(fi); | ||
142 | 122 | ||
143 | if(!is_user && (address >= start_vm) && (address < end_vm)){ | 123 | if(!is_user && (address >= start_vm) && (address < end_vm)){ |
144 | flush_tlb_kernel_vm(); | 124 | flush_tlb_kernel_vm(); |
145 | return(0); | 125 | return(0); |
146 | } | 126 | } |
147 | else if(check_remapped_addr(address & PAGE_MASK, is_write)) | ||
148 | return(0); | ||
149 | else if(current->mm == NULL) | 127 | else if(current->mm == NULL) |
150 | panic("Segfault with no mm"); | 128 | panic("Segfault with no mm"); |
151 | err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); | 129 | err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); |
@@ -159,7 +137,7 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write, | |||
159 | } | 137 | } |
160 | else if(current->thread.fault_addr != NULL) | 138 | else if(current->thread.fault_addr != NULL) |
161 | panic("fault_addr set but no fault catcher"); | 139 | panic("fault_addr set but no fault catcher"); |
162 | else if(arch_fixup(ip, sc)) | 140 | else if(!is_user && arch_fixup(ip, sc)) |
163 | return(0); | 141 | return(0); |
164 | 142 | ||
165 | if(!is_user) | 143 | if(!is_user) |
@@ -171,6 +149,7 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write, | |||
171 | si.si_errno = 0; | 149 | si.si_errno = 0; |
172 | si.si_code = BUS_ADRERR; | 150 | si.si_code = BUS_ADRERR; |
173 | si.si_addr = (void *)address; | 151 | si.si_addr = (void *)address; |
152 | current->thread.arch.faultinfo = fi; | ||
174 | force_sig_info(SIGBUS, &si, current); | 153 | force_sig_info(SIGBUS, &si, current); |
175 | } | 154 | } |
176 | else if(err == -ENOMEM){ | 155 | else if(err == -ENOMEM){ |
@@ -180,22 +159,20 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write, | |||
180 | else { | 159 | else { |
181 | si.si_signo = SIGSEGV; | 160 | si.si_signo = SIGSEGV; |
182 | si.si_addr = (void *) address; | 161 | si.si_addr = (void *) address; |
183 | current->thread.cr2 = address; | 162 | current->thread.arch.faultinfo = fi; |
184 | current->thread.err = is_write; | ||
185 | force_sig_info(SIGSEGV, &si, current); | 163 | force_sig_info(SIGSEGV, &si, current); |
186 | } | 164 | } |
187 | return(0); | 165 | return(0); |
188 | } | 166 | } |
189 | 167 | ||
190 | void bad_segv(unsigned long address, unsigned long ip, int is_write) | 168 | void bad_segv(struct faultinfo fi, unsigned long ip) |
191 | { | 169 | { |
192 | struct siginfo si; | 170 | struct siginfo si; |
193 | 171 | ||
194 | si.si_signo = SIGSEGV; | 172 | si.si_signo = SIGSEGV; |
195 | si.si_code = SEGV_ACCERR; | 173 | si.si_code = SEGV_ACCERR; |
196 | si.si_addr = (void *) address; | 174 | si.si_addr = (void *) FAULT_ADDRESS(fi); |
197 | current->thread.cr2 = address; | 175 | current->thread.arch.faultinfo = fi; |
198 | current->thread.err = is_write; | ||
199 | force_sig_info(SIGSEGV, &si, current); | 176 | force_sig_info(SIGSEGV, &si, current); |
200 | } | 177 | } |
201 | 178 | ||
@@ -204,6 +181,7 @@ void relay_signal(int sig, union uml_pt_regs *regs) | |||
204 | if(arch_handle_signal(sig, regs)) return; | 181 | if(arch_handle_signal(sig, regs)) return; |
205 | if(!UPT_IS_USER(regs)) | 182 | if(!UPT_IS_USER(regs)) |
206 | panic("Kernel mode signal %d", sig); | 183 | panic("Kernel mode signal %d", sig); |
184 | current->thread.arch.faultinfo = *UPT_FAULTINFO(regs); | ||
207 | force_sig(sig, current); | 185 | force_sig(sig, current); |
208 | } | 186 | } |
209 | 187 | ||
diff --git a/arch/um/kernel/trap_user.c b/arch/um/kernel/trap_user.c index 50a4042a509f..f825a6eda3f5 100644 --- a/arch/um/kernel/trap_user.c +++ b/arch/um/kernel/trap_user.c | |||
@@ -54,23 +54,22 @@ struct { | |||
54 | void segv_handler(int sig, union uml_pt_regs *regs) | 54 | void segv_handler(int sig, union uml_pt_regs *regs) |
55 | { | 55 | { |
56 | int index, max; | 56 | int index, max; |
57 | struct faultinfo * fi = UPT_FAULTINFO(regs); | ||
57 | 58 | ||
58 | if(UPT_IS_USER(regs) && !UPT_SEGV_IS_FIXABLE(regs)){ | 59 | if(UPT_IS_USER(regs) && !SEGV_IS_FIXABLE(fi)){ |
59 | bad_segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), | 60 | bad_segv(*fi, UPT_IP(regs)); |
60 | UPT_FAULT_WRITE(regs)); | ||
61 | return; | 61 | return; |
62 | } | 62 | } |
63 | max = sizeof(segfault_record)/sizeof(segfault_record[0]); | 63 | max = sizeof(segfault_record)/sizeof(segfault_record[0]); |
64 | index = next_trap_index(max); | 64 | index = next_trap_index(max); |
65 | 65 | ||
66 | nsegfaults++; | 66 | nsegfaults++; |
67 | segfault_record[index].address = UPT_FAULT_ADDR(regs); | 67 | segfault_record[index].address = FAULT_ADDRESS(*fi); |
68 | segfault_record[index].pid = os_getpid(); | 68 | segfault_record[index].pid = os_getpid(); |
69 | segfault_record[index].is_write = UPT_FAULT_WRITE(regs); | 69 | segfault_record[index].is_write = FAULT_WRITE(*fi); |
70 | segfault_record[index].sp = UPT_SP(regs); | 70 | segfault_record[index].sp = UPT_SP(regs); |
71 | segfault_record[index].is_user = UPT_IS_USER(regs); | 71 | segfault_record[index].is_user = UPT_IS_USER(regs); |
72 | segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), UPT_FAULT_WRITE(regs), | 72 | segv(*fi, UPT_IP(regs), UPT_IS_USER(regs), regs); |
73 | UPT_IS_USER(regs), regs); | ||
74 | } | 73 | } |
75 | 74 | ||
76 | void usr2_handler(int sig, union uml_pt_regs *regs) | 75 | void usr2_handler(int sig, union uml_pt_regs *regs) |
diff --git a/arch/um/kernel/tt/Makefile b/arch/um/kernel/tt/Makefile index 3d5177df3504..c3faea21a996 100644 --- a/arch/um/kernel/tt/Makefile +++ b/arch/um/kernel/tt/Makefile | |||
@@ -4,6 +4,7 @@ | |||
4 | # | 4 | # |
5 | 5 | ||
6 | extra-y := unmap_fin.o | 6 | extra-y := unmap_fin.o |
7 | targets := unmap.o | ||
7 | clean-files := unmap_tmp.o | 8 | clean-files := unmap_tmp.o |
8 | 9 | ||
9 | obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \ | 10 | obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \ |
diff --git a/arch/um/kernel/tt/include/mode_kern-tt.h b/arch/um/kernel/tt/include/mode_kern-tt.h index 28aaab3448fa..e0ca0e0b2516 100644 --- a/arch/um/kernel/tt/include/mode_kern-tt.h +++ b/arch/um/kernel/tt/include/mode_kern-tt.h | |||
@@ -19,7 +19,6 @@ extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp, | |||
19 | unsigned long stack_top, struct task_struct *p, | 19 | unsigned long stack_top, struct task_struct *p, |
20 | struct pt_regs *regs); | 20 | struct pt_regs *regs); |
21 | extern void release_thread_tt(struct task_struct *task); | 21 | extern void release_thread_tt(struct task_struct *task); |
22 | extern void exit_thread_tt(void); | ||
23 | extern void initial_thread_cb_tt(void (*proc)(void *), void *arg); | 22 | extern void initial_thread_cb_tt(void (*proc)(void *), void *arg); |
24 | extern void init_idle_tt(void); | 23 | extern void init_idle_tt(void); |
25 | extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end); | 24 | extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end); |
diff --git a/arch/um/kernel/tt/include/uaccess-tt.h b/arch/um/kernel/tt/include/uaccess-tt.h index bb69d6b7d022..3fbb5fe26f49 100644 --- a/arch/um/kernel/tt/include/uaccess-tt.h +++ b/arch/um/kernel/tt/include/uaccess-tt.h | |||
@@ -33,8 +33,8 @@ extern unsigned long uml_physmem; | |||
33 | (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \ | 33 | (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \ |
34 | (under_task_size(addr, size) || is_stack(addr, size)))) | 34 | (under_task_size(addr, size) || is_stack(addr, size)))) |
35 | 35 | ||
36 | static inline int __deprecated verify_area_tt(int type, const void * addr, | 36 | static inline int verify_area_tt(int type, const void * addr, |
37 | unsigned long size) | 37 | unsigned long size) |
38 | { | 38 | { |
39 | return(access_ok_tt(type, addr, size) ? 0 : -EFAULT); | 39 | return(access_ok_tt(type, addr, size) ? 0 : -EFAULT); |
40 | } | 40 | } |
diff --git a/arch/um/kernel/tt/ksyms.c b/arch/um/kernel/tt/ksyms.c index 92ec85d67c7c..84a9385a8fef 100644 --- a/arch/um/kernel/tt/ksyms.c +++ b/arch/um/kernel/tt/ksyms.c | |||
@@ -12,6 +12,7 @@ EXPORT_SYMBOL(__do_copy_to_user); | |||
12 | EXPORT_SYMBOL(__do_strncpy_from_user); | 12 | EXPORT_SYMBOL(__do_strncpy_from_user); |
13 | EXPORT_SYMBOL(__do_strnlen_user); | 13 | EXPORT_SYMBOL(__do_strnlen_user); |
14 | EXPORT_SYMBOL(__do_clear_user); | 14 | EXPORT_SYMBOL(__do_clear_user); |
15 | EXPORT_SYMBOL(clear_user_tt); | ||
15 | 16 | ||
16 | EXPORT_SYMBOL(tracing_pid); | 17 | EXPORT_SYMBOL(tracing_pid); |
17 | EXPORT_SYMBOL(honeypot); | 18 | EXPORT_SYMBOL(honeypot); |
diff --git a/arch/um/kernel/tt/mem.c b/arch/um/kernel/tt/mem.c index 74346a04a2b2..bcb8796c3cb1 100644 --- a/arch/um/kernel/tt/mem.c +++ b/arch/um/kernel/tt/mem.c | |||
@@ -21,14 +21,8 @@ void before_mem_tt(unsigned long brk_start) | |||
21 | remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(&_end), 1); | 21 | remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(&_end), 1); |
22 | } | 22 | } |
23 | 23 | ||
24 | #ifdef CONFIG_HOST_2G_2G | ||
25 | #define TOP 0x80000000 | ||
26 | #else | ||
27 | #define TOP 0xc0000000 | ||
28 | #endif | ||
29 | |||
30 | #define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000) | 24 | #define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000) |
31 | #define START (TOP - SIZE) | 25 | #define START (CONFIG_TOP_ADDR - SIZE) |
32 | 26 | ||
33 | unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, | 27 | unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, |
34 | unsigned long *task_size_out) | 28 | unsigned long *task_size_out) |
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c index f19f7c18febe..776310fd5b8b 100644 --- a/arch/um/kernel/tt/process_kern.c +++ b/arch/um/kernel/tt/process_kern.c | |||
@@ -32,10 +32,6 @@ void *switch_to_tt(void *prev, void *next, void *last) | |||
32 | unsigned long flags; | 32 | unsigned long flags; |
33 | int err, vtalrm, alrm, prof, cpu; | 33 | int err, vtalrm, alrm, prof, cpu; |
34 | char c; | 34 | char c; |
35 | /* jailing and SMP are incompatible, so this doesn't need to be | ||
36 | * made per-cpu | ||
37 | */ | ||
38 | static int reading; | ||
39 | 35 | ||
40 | from = prev; | 36 | from = prev; |
41 | to = next; | 37 | to = next; |
@@ -59,14 +55,11 @@ void *switch_to_tt(void *prev, void *next, void *last) | |||
59 | c = 0; | 55 | c = 0; |
60 | set_current(to); | 56 | set_current(to); |
61 | 57 | ||
62 | reading = 0; | ||
63 | err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); | 58 | err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); |
64 | if(err != sizeof(c)) | 59 | if(err != sizeof(c)) |
65 | panic("write of switch_pipe failed, err = %d", -err); | 60 | panic("write of switch_pipe failed, err = %d", -err); |
66 | 61 | ||
67 | reading = 1; | 62 | if(from->thread.mode.tt.switch_pipe[0] == -1) |
68 | if((from->exit_state == EXIT_ZOMBIE) || | ||
69 | (from->exit_state == EXIT_DEAD)) | ||
70 | os_kill_process(os_getpid(), 0); | 63 | os_kill_process(os_getpid(), 0); |
71 | 64 | ||
72 | err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c)); | 65 | err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c)); |
@@ -81,8 +74,7 @@ void *switch_to_tt(void *prev, void *next, void *last) | |||
81 | * in case it has not already killed itself. | 74 | * in case it has not already killed itself. |
82 | */ | 75 | */ |
83 | prev_sched = current->thread.prev_sched; | 76 | prev_sched = current->thread.prev_sched; |
84 | if((prev_sched->exit_state == EXIT_ZOMBIE) || | 77 | if(prev_sched->thread.mode.tt.switch_pipe[0] == -1) |
85 | (prev_sched->exit_state == EXIT_DEAD)) | ||
86 | os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1); | 78 | os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1); |
87 | 79 | ||
88 | change_sig(SIGVTALRM, vtalrm); | 80 | change_sig(SIGVTALRM, vtalrm); |
@@ -101,14 +93,18 @@ void release_thread_tt(struct task_struct *task) | |||
101 | { | 93 | { |
102 | int pid = task->thread.mode.tt.extern_pid; | 94 | int pid = task->thread.mode.tt.extern_pid; |
103 | 95 | ||
96 | /* | ||
97 | * We first have to kill the other process, before | ||
98 | * closing its switch_pipe. Else it might wake up | ||
99 | * and receive "EOF" before we could kill it. | ||
100 | */ | ||
104 | if(os_getpid() != pid) | 101 | if(os_getpid() != pid) |
105 | os_kill_process(pid, 0); | 102 | os_kill_process(pid, 0); |
106 | } | ||
107 | 103 | ||
108 | void exit_thread_tt(void) | 104 | os_close_file(task->thread.mode.tt.switch_pipe[0]); |
109 | { | 105 | os_close_file(task->thread.mode.tt.switch_pipe[1]); |
110 | os_close_file(current->thread.mode.tt.switch_pipe[0]); | 106 | /* use switch_pipe as flag: thread is released */ |
111 | os_close_file(current->thread.mode.tt.switch_pipe[1]); | 107 | task->thread.mode.tt.switch_pipe[0] = -1; |
112 | } | 108 | } |
113 | 109 | ||
114 | void suspend_new_thread(int fd) | 110 | void suspend_new_thread(int fd) |
diff --git a/arch/um/kernel/tt/syscall_user.c b/arch/um/kernel/tt/syscall_user.c index e4e7e9c2224c..b218316cfdb2 100644 --- a/arch/um/kernel/tt/syscall_user.c +++ b/arch/um/kernel/tt/syscall_user.c | |||
@@ -63,6 +63,10 @@ void do_syscall(void *task, int pid, int local_using_sysemu) | |||
63 | 63 | ||
64 | UPT_SYSCALL_NR(TASK_REGS(task)) = PT_SYSCALL_NR(proc_regs); | 64 | UPT_SYSCALL_NR(TASK_REGS(task)) = PT_SYSCALL_NR(proc_regs); |
65 | 65 | ||
66 | #ifdef UPT_ORIGGPR2 | ||
67 | UPT_ORIGGPR2(TASK_REGS(task)) = REGS_ORIGGPR2(proc_regs); | ||
68 | #endif | ||
69 | |||
66 | if(((unsigned long *) PT_IP(proc_regs) >= &_stext) && | 70 | if(((unsigned long *) PT_IP(proc_regs) >= &_stext) && |
67 | ((unsigned long *) PT_IP(proc_regs) <= &_etext)) | 71 | ((unsigned long *) PT_IP(proc_regs) <= &_etext)) |
68 | tracer_panic("I'm tracing myself and I can't get out"); | 72 | tracer_panic("I'm tracing myself and I can't get out"); |
diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c index 7b5d937e5955..d11e7399d7a1 100644 --- a/arch/um/kernel/tt/tracer.c +++ b/arch/um/kernel/tt/tracer.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "kern_util.h" | 26 | #include "kern_util.h" |
27 | #include "chan_user.h" | 27 | #include "chan_user.h" |
28 | #include "ptrace_user.h" | 28 | #include "ptrace_user.h" |
29 | #include "irq_user.h" | ||
29 | #include "mode.h" | 30 | #include "mode.h" |
30 | #include "tt.h" | 31 | #include "tt.h" |
31 | 32 | ||
@@ -33,7 +34,7 @@ static int tracer_winch[2]; | |||
33 | 34 | ||
34 | int is_tracer_winch(int pid, int fd, void *data) | 35 | int is_tracer_winch(int pid, int fd, void *data) |
35 | { | 36 | { |
36 | if(pid != tracing_pid) | 37 | if(pid != os_getpgrp()) |
37 | return(0); | 38 | return(0); |
38 | 39 | ||
39 | register_winch_irq(tracer_winch[0], fd, -1, data); | 40 | register_winch_irq(tracer_winch[0], fd, -1, data); |
@@ -89,8 +90,10 @@ void tracer_panic(char *format, ...) | |||
89 | 90 | ||
90 | static void tracer_segv(int sig, struct sigcontext sc) | 91 | static void tracer_segv(int sig, struct sigcontext sc) |
91 | { | 92 | { |
93 | struct faultinfo fi; | ||
94 | GET_FAULTINFO_FROM_SC(fi, &sc); | ||
92 | printf("Tracing thread segfault at address 0x%lx, ip 0x%lx\n", | 95 | printf("Tracing thread segfault at address 0x%lx, ip 0x%lx\n", |
93 | SC_FAULT_ADDR(&sc), SC_IP(&sc)); | 96 | FAULT_ADDRESS(fi), SC_IP(&sc)); |
94 | while(1) | 97 | while(1) |
95 | pause(); | 98 | pause(); |
96 | } | 99 | } |
@@ -117,6 +120,7 @@ static int signal_tramp(void *arg) | |||
117 | signal(SIGSEGV, (__sighandler_t) sig_handler); | 120 | signal(SIGSEGV, (__sighandler_t) sig_handler); |
118 | set_cmdline("(idle thread)"); | 121 | set_cmdline("(idle thread)"); |
119 | set_init_pid(os_getpid()); | 122 | set_init_pid(os_getpid()); |
123 | init_irq_signals(0); | ||
120 | proc = arg; | 124 | proc = arg; |
121 | return((*proc)(NULL)); | 125 | return((*proc)(NULL)); |
122 | } | 126 | } |
diff --git a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c index 92a3820ca543..fc108615beaf 100644 --- a/arch/um/kernel/tt/trap_user.c +++ b/arch/um/kernel/tt/trap_user.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <errno.h> | 7 | #include <errno.h> |
8 | #include <signal.h> | 8 | #include <signal.h> |
9 | #include "sysdep/ptrace.h" | 9 | #include "sysdep/ptrace.h" |
10 | #include "sysdep/sigcontext.h" | ||
10 | #include "signal_user.h" | 11 | #include "signal_user.h" |
11 | #include "user_util.h" | 12 | #include "user_util.h" |
12 | #include "kern_util.h" | 13 | #include "kern_util.h" |
@@ -28,6 +29,11 @@ void sig_handler_common_tt(int sig, void *sc_ptr) | |||
28 | change_sig(SIGSEGV, 1); | 29 | change_sig(SIGSEGV, 1); |
29 | 30 | ||
30 | r = &TASK_REGS(get_current())->tt; | 31 | r = &TASK_REGS(get_current())->tt; |
32 | if ( sig == SIGFPE || sig == SIGSEGV || | ||
33 | sig == SIGBUS || sig == SIGILL || | ||
34 | sig == SIGTRAP ) { | ||
35 | GET_FAULTINFO_FROM_SC(r->faultinfo, sc); | ||
36 | } | ||
31 | save_regs = *r; | 37 | save_regs = *r; |
32 | is_user = user_context(SC_SP(sc)); | 38 | is_user = user_context(SC_SP(sc)); |
33 | r->sc = sc; | 39 | r->sc = sc; |
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 5c49d88eed3d..8736d098f0ee 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c | |||
@@ -23,9 +23,9 @@ | |||
23 | #include "asm/ptrace.h" | 23 | #include "asm/ptrace.h" |
24 | #include "asm/elf.h" | 24 | #include "asm/elf.h" |
25 | #include "asm/user.h" | 25 | #include "asm/user.h" |
26 | #include "asm/setup.h" | ||
26 | #include "ubd_user.h" | 27 | #include "ubd_user.h" |
27 | #include "asm/current.h" | 28 | #include "asm/current.h" |
28 | #include "asm/setup.h" | ||
29 | #include "user_util.h" | 29 | #include "user_util.h" |
30 | #include "kern_util.h" | 30 | #include "kern_util.h" |
31 | #include "kern.h" | 31 | #include "kern.h" |
@@ -42,9 +42,9 @@ | |||
42 | #define DEFAULT_COMMAND_LINE "root=98:0" | 42 | #define DEFAULT_COMMAND_LINE "root=98:0" |
43 | 43 | ||
44 | /* Changed in linux_main and setup_arch, which run before SMP is started */ | 44 | /* Changed in linux_main and setup_arch, which run before SMP is started */ |
45 | char command_line[COMMAND_LINE_SIZE] = { 0 }; | 45 | static char command_line[COMMAND_LINE_SIZE] = { 0 }; |
46 | 46 | ||
47 | void add_arg(char *arg) | 47 | static void add_arg(char *arg) |
48 | { | 48 | { |
49 | if (strlen(command_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) { | 49 | if (strlen(command_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) { |
50 | printf("add_arg: Too many command line arguments!\n"); | 50 | printf("add_arg: Too many command line arguments!\n"); |
@@ -110,12 +110,6 @@ struct seq_operations cpuinfo_op = { | |||
110 | .show = show_cpuinfo, | 110 | .show = show_cpuinfo, |
111 | }; | 111 | }; |
112 | 112 | ||
113 | pte_t * __bad_pagetable(void) | ||
114 | { | ||
115 | panic("Someone should implement __bad_pagetable"); | ||
116 | return(NULL); | ||
117 | } | ||
118 | |||
119 | /* Set in linux_main */ | 113 | /* Set in linux_main */ |
120 | unsigned long host_task_size; | 114 | unsigned long host_task_size; |
121 | unsigned long task_size; | 115 | unsigned long task_size; |
@@ -449,7 +443,7 @@ void __init setup_arch(char **cmdline_p) | |||
449 | { | 443 | { |
450 | notifier_chain_register(&panic_notifier_list, &panic_exit_notifier); | 444 | notifier_chain_register(&panic_notifier_list, &panic_exit_notifier); |
451 | paging_init(); | 445 | paging_init(); |
452 | strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE); | 446 | strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE); |
453 | *cmdline_p = command_line; | 447 | *cmdline_p = command_line; |
454 | setup_hostinfo(); | 448 | setup_hostinfo(); |
455 | } | 449 | } |
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S index 76eadb309189..dd5355500bdc 100644 --- a/arch/um/kernel/uml.lds.S +++ b/arch/um/kernel/uml.lds.S | |||
@@ -73,6 +73,8 @@ SECTIONS | |||
73 | 73 | ||
74 | .got : { *(.got.plt) *(.got) } | 74 | .got : { *(.got.plt) *(.got) } |
75 | .dynamic : { *(.dynamic) } | 75 | .dynamic : { *(.dynamic) } |
76 | .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } | ||
77 | .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } | ||
76 | /* We want the small data sections together, so single-instruction offsets | 78 | /* We want the small data sections together, so single-instruction offsets |
77 | can access them all, and initialized data all before uninitialized, so | 79 | can access them all, and initialized data all before uninitialized, so |
78 | we can shorten the on-disk segment size. */ | 80 | we can shorten the on-disk segment size. */ |
diff --git a/arch/um/kernel/vmlinux.lds.S b/arch/um/kernel/vmlinux.lds.S new file mode 100644 index 000000000000..1660a769674b --- /dev/null +++ b/arch/um/kernel/vmlinux.lds.S | |||
@@ -0,0 +1,6 @@ | |||
1 | #include <linux/config.h> | ||
2 | #ifdef CONFIG_LD_SCRIPT_STATIC | ||
3 | #include "uml.lds.S" | ||
4 | #else | ||
5 | #include "dyn.lds.S" | ||
6 | #endif | ||
diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c index 9aee0b62ebca..f0d6060e3e57 100644 --- a/arch/um/os-Linux/elf_aux.c +++ b/arch/um/os-Linux/elf_aux.c | |||
@@ -45,7 +45,11 @@ __init void scan_elf_aux( char **envp) | |||
45 | elf_aux_hwcap = auxv->a_un.a_val; | 45 | elf_aux_hwcap = auxv->a_un.a_val; |
46 | break; | 46 | break; |
47 | case AT_PLATFORM: | 47 | case AT_PLATFORM: |
48 | elf_aux_platform = auxv->a_un.a_ptr; | 48 | /* elf.h removed the pointer elements from |
49 | * a_un, so we have to use a_val, which is | ||
50 | * all that's left. | ||
51 | */ | ||
52 | elf_aux_platform = (char *) auxv->a_un.a_val; | ||
49 | break; | 53 | break; |
50 | case AT_PAGESZ: | 54 | case AT_PAGESZ: |
51 | page_size = auxv->a_un.a_val; | 55 | page_size = auxv->a_un.a_val; |
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index 77d4066d1af8..fd45bb260907 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c | |||
@@ -363,7 +363,7 @@ int os_write_file(int fd, const void *buf, int len) | |||
363 | (int (*)(int, void *, int)) write, copy_to_user_proc)); | 363 | (int (*)(int, void *, int)) write, copy_to_user_proc)); |
364 | } | 364 | } |
365 | 365 | ||
366 | int os_file_size(char *file, long long *size_out) | 366 | int os_file_size(char *file, unsigned long long *size_out) |
367 | { | 367 | { |
368 | struct uml_stat buf; | 368 | struct uml_stat buf; |
369 | int err; | 369 | int err; |
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index ba9ca1cc790a..1e126bfd31a7 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c | |||
@@ -123,6 +123,11 @@ int os_getpid(void) | |||
123 | return(getpid()); | 123 | return(getpid()); |
124 | } | 124 | } |
125 | 125 | ||
126 | int os_getpgrp(void) | ||
127 | { | ||
128 | return getpgrp(); | ||
129 | } | ||
130 | |||
126 | int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len, | 131 | int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len, |
127 | int r, int w, int x) | 132 | int r, int w, int x) |
128 | { | 133 | { |
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 7eac1baf5975..c7bfd5ee3925 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c | |||
@@ -8,7 +8,7 @@ | |||
8 | #include "mode.h" | 8 | #include "mode.h" |
9 | #include "sysdep/signal.h" | 9 | #include "sysdep/signal.h" |
10 | 10 | ||
11 | void sig_handler(int sig) | 11 | void sig_handler(ARCH_SIGHDLR_PARAM) |
12 | { | 12 | { |
13 | struct sigcontext *sc; | 13 | struct sigcontext *sc; |
14 | 14 | ||
@@ -19,7 +19,7 @@ void sig_handler(int sig) | |||
19 | 19 | ||
20 | extern int timer_irq_inited; | 20 | extern int timer_irq_inited; |
21 | 21 | ||
22 | void alarm_handler(int sig) | 22 | void alarm_handler(ARCH_SIGHDLR_PARAM) |
23 | { | 23 | { |
24 | struct sigcontext *sc; | 24 | struct sigcontext *sc; |
25 | 25 | ||
diff --git a/arch/um/os-Linux/util/Makefile b/arch/um/os-Linux/util/Makefile index fb00ddf969bd..9778aed0c314 100644 --- a/arch/um/os-Linux/util/Makefile +++ b/arch/um/os-Linux/util/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | hostprogs-y := mk_user_constants | 1 | hostprogs-y := mk_user_constants |
2 | always := $(hostprogs-y) | 2 | always := $(hostprogs-y) |
3 | 3 | ||
4 | mk_user_constants-objs := mk_user_constants.o | 4 | HOSTCFLAGS_mk_user_constants.o := -I$(objtree)/arch/um |
diff --git a/arch/um/os-Linux/util/mk_user_constants.c b/arch/um/os-Linux/util/mk_user_constants.c index 0933518aa8bd..4838f30eecf0 100644 --- a/arch/um/os-Linux/util/mk_user_constants.c +++ b/arch/um/os-Linux/util/mk_user_constants.c | |||
@@ -1,11 +1,5 @@ | |||
1 | #include <stdio.h> | 1 | #include <stdio.h> |
2 | #include <asm/types.h> | 2 | #include <user-offsets.h> |
3 | /* For some reason, x86_64 nowhere defines u64 and u32, even though they're | ||
4 | * used throughout the headers. | ||
5 | */ | ||
6 | typedef __u64 u64; | ||
7 | typedef __u32 u32; | ||
8 | #include <asm/user.h> | ||
9 | 3 | ||
10 | int main(int argc, char **argv) | 4 | int main(int argc, char **argv) |
11 | { | 5 | { |
@@ -20,7 +14,7 @@ int main(int argc, char **argv) | |||
20 | * x86_64 (216 vs 168 bytes). user_regs_struct is the correct size on | 14 | * x86_64 (216 vs 168 bytes). user_regs_struct is the correct size on |
21 | * both x86_64 and i386. | 15 | * both x86_64 and i386. |
22 | */ | 16 | */ |
23 | printf("#define UM_FRAME_SIZE %d\n", (int) sizeof(struct user_regs_struct)); | 17 | printf("#define UM_FRAME_SIZE %d\n", __UM_FRAME_SIZE); |
24 | 18 | ||
25 | printf("\n"); | 19 | printf("\n"); |
26 | printf("#endif\n"); | 20 | printf("#endif\n"); |
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules index 143f6fea0763..98346c711493 100644 --- a/arch/um/scripts/Makefile.rules +++ b/arch/um/scripts/Makefile.rules | |||
@@ -2,12 +2,27 @@ | |||
2 | # arch/um: Generic definitions | 2 | # arch/um: Generic definitions |
3 | # =========================================================================== | 3 | # =========================================================================== |
4 | 4 | ||
5 | USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs)) | 5 | USER_SINGLE_OBJS := \ |
6 | USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) | 6 | $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs)) |
7 | 7 | USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) | |
8 | USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) | 8 | USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) |
9 | 9 | ||
10 | $(USER_OBJS): c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(notdir $@)) | 10 | $(USER_OBJS) : c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) \ |
11 | $(CFLAGS_$(notdir $@)) | ||
11 | 12 | ||
12 | quiet_cmd_make_link = SYMLINK $@ | 13 | quiet_cmd_make_link = SYMLINK $@ |
13 | cmd_make_link = rm -f $@; ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@ | 14 | cmd_make_link = ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@ |
15 | |||
16 | # this needs to be before the foreach, because targets does not accept | ||
17 | # complete paths like $(obj)/$(f). To make sure this works, use a := assignment | ||
18 | # or we will get $(obj)/$(f) in the "targets" value. | ||
19 | # Also, this forces you to use the := syntax when assigning to targets. | ||
20 | # Otherwise the line below will cause an infinite loop (if you don't know why, | ||
21 | # just do it). | ||
22 | |||
23 | targets := $(targets) $(SYMLINKS) | ||
24 | |||
25 | SYMLINKS := $(foreach f,$(SYMLINKS),$(obj)/$(f)) | ||
26 | |||
27 | $(SYMLINKS): FORCE | ||
28 | $(call if_changed,make_link) | ||
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile index 950781e354de..4351e5605506 100644 --- a/arch/um/sys-i386/Makefile +++ b/arch/um/sys-i386/Makefile | |||
@@ -7,24 +7,13 @@ obj-$(CONFIG_MODULES) += module.o | |||
7 | 7 | ||
8 | USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o | 8 | USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o |
9 | 9 | ||
10 | include arch/um/scripts/Makefile.rules | ||
11 | |||
12 | SYMLINKS = bitops.c semaphore.c highmem.c module.c | 10 | SYMLINKS = bitops.c semaphore.c highmem.c module.c |
13 | 11 | ||
14 | # this needs to be before the foreach, because clean-files does not accept | 12 | include arch/um/scripts/Makefile.rules |
15 | # complete paths like $(src)/$f. | ||
16 | clean-files := $(SYMLINKS) | ||
17 | |||
18 | targets += $(SYMLINKS) | ||
19 | |||
20 | SYMLINKS := $(foreach f,$(SYMLINKS),$(obj)/$f) | ||
21 | 13 | ||
22 | bitops.c-dir = lib | 14 | bitops.c-dir = lib |
23 | semaphore.c-dir = kernel | 15 | semaphore.c-dir = kernel |
24 | highmem.c-dir = mm | 16 | highmem.c-dir = mm |
25 | module.c-dir = kernel | 17 | module.c-dir = kernel |
26 | 18 | ||
27 | $(SYMLINKS): FORCE | ||
28 | $(call if_changed,make_link) | ||
29 | |||
30 | subdir- := util | 19 | subdir- := util |
diff --git a/arch/um/sys-i386/checksum.S b/arch/um/sys-i386/checksum.S index a11171fb6223..d98b2fff3d08 100644 --- a/arch/um/sys-i386/checksum.S +++ b/arch/um/sys-i386/checksum.S | |||
@@ -38,7 +38,7 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) | |||
38 | 38 | ||
39 | .text | 39 | .text |
40 | .align 4 | 40 | .align 4 |
41 | .globl arch_csum_partial | 41 | .globl csum_partial |
42 | 42 | ||
43 | #ifndef CONFIG_X86_USE_PPRO_CHECKSUM | 43 | #ifndef CONFIG_X86_USE_PPRO_CHECKSUM |
44 | 44 | ||
@@ -49,7 +49,7 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) | |||
49 | * Fortunately, it is easy to convert 2-byte alignment to 4-byte | 49 | * Fortunately, it is easy to convert 2-byte alignment to 4-byte |
50 | * alignment for the unrolled loop. | 50 | * alignment for the unrolled loop. |
51 | */ | 51 | */ |
52 | arch_csum_partial: | 52 | csum_partial: |
53 | pushl %esi | 53 | pushl %esi |
54 | pushl %ebx | 54 | pushl %ebx |
55 | movl 20(%esp),%eax # Function arg: unsigned int sum | 55 | movl 20(%esp),%eax # Function arg: unsigned int sum |
@@ -119,7 +119,7 @@ arch_csum_partial: | |||
119 | 119 | ||
120 | /* Version for PentiumII/PPro */ | 120 | /* Version for PentiumII/PPro */ |
121 | 121 | ||
122 | arch_csum_partial: | 122 | csum_partial: |
123 | pushl %esi | 123 | pushl %esi |
124 | pushl %ebx | 124 | pushl %ebx |
125 | movl 20(%esp),%eax # Function arg: unsigned int sum | 125 | movl 20(%esp),%eax # Function arg: unsigned int sum |
diff --git a/arch/um/sys-i386/delay.c b/arch/um/sys-i386/delay.c index 20d37dbbaf08..2c11b9770e8b 100644 --- a/arch/um/sys-i386/delay.c +++ b/arch/um/sys-i386/delay.c | |||
@@ -1,3 +1,8 @@ | |||
1 | #include <linux/module.h> | ||
2 | #include <linux/kernel.h> | ||
3 | #include <linux/delay.h> | ||
4 | #include <asm/param.h> | ||
5 | |||
1 | void __delay(unsigned long time) | 6 | void __delay(unsigned long time) |
2 | { | 7 | { |
3 | /* Stolen from the i386 __loop_delay */ | 8 | /* Stolen from the i386 __loop_delay */ |
@@ -12,3 +17,24 @@ void __delay(unsigned long time) | |||
12 | :"0" (time)); | 17 | :"0" (time)); |
13 | } | 18 | } |
14 | 19 | ||
20 | void __udelay(unsigned long usecs) | ||
21 | { | ||
22 | int i, n; | ||
23 | |||
24 | n = (loops_per_jiffy * HZ * usecs) / MILLION; | ||
25 | for(i=0;i<n;i++) | ||
26 | cpu_relax(); | ||
27 | } | ||
28 | |||
29 | EXPORT_SYMBOL(__udelay); | ||
30 | |||
31 | void __const_udelay(unsigned long usecs) | ||
32 | { | ||
33 | int i, n; | ||
34 | |||
35 | n = (loops_per_jiffy * HZ * usecs) / MILLION; | ||
36 | for(i=0;i<n;i++) | ||
37 | cpu_relax(); | ||
38 | } | ||
39 | |||
40 | EXPORT_SYMBOL(__const_udelay); | ||
diff --git a/arch/um/sys-i386/kernel-offsets.c b/arch/um/sys-i386/kernel-offsets.c new file mode 100644 index 000000000000..9f8ecd1fdd96 --- /dev/null +++ b/arch/um/sys-i386/kernel-offsets.c | |||
@@ -0,0 +1,25 @@ | |||
1 | #include <linux/config.h> | ||
2 | #include <linux/stddef.h> | ||
3 | #include <linux/sched.h> | ||
4 | #include <linux/time.h> | ||
5 | #include <asm/page.h> | ||
6 | |||
7 | #define DEFINE(sym, val) \ | ||
8 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) | ||
9 | |||
10 | #define STR(x) #x | ||
11 | #define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " STR(val) " " #val: : ) | ||
12 | |||
13 | #define BLANK() asm volatile("\n->" : : ) | ||
14 | |||
15 | #define OFFSET(sym, str, mem) \ | ||
16 | DEFINE(sym, offsetof(struct str, mem)); | ||
17 | |||
18 | void foo(void) | ||
19 | { | ||
20 | OFFSET(TASK_DEBUGREGS, task_struct, thread.arch.debugregs); | ||
21 | #ifdef CONFIG_MODE_TT | ||
22 | OFFSET(TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); | ||
23 | #endif | ||
24 | #include <common-offsets.h> | ||
25 | } | ||
diff --git a/arch/um/sys-i386/ksyms.c b/arch/um/sys-i386/ksyms.c index 74f70a120458..db524ab3f743 100644 --- a/arch/um/sys-i386/ksyms.c +++ b/arch/um/sys-i386/ksyms.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include "linux/in6.h" | 2 | #include "linux/in6.h" |
3 | #include "linux/rwsem.h" | 3 | #include "linux/rwsem.h" |
4 | #include "asm/byteorder.h" | 4 | #include "asm/byteorder.h" |
5 | #include "asm/delay.h" | ||
5 | #include "asm/semaphore.h" | 6 | #include "asm/semaphore.h" |
6 | #include "asm/uaccess.h" | 7 | #include "asm/uaccess.h" |
7 | #include "asm/checksum.h" | 8 | #include "asm/checksum.h" |
@@ -13,5 +14,8 @@ EXPORT_SYMBOL(__down_failed_trylock); | |||
13 | EXPORT_SYMBOL(__up_wakeup); | 14 | EXPORT_SYMBOL(__up_wakeup); |
14 | 15 | ||
15 | /* Networking helper routines. */ | 16 | /* Networking helper routines. */ |
16 | EXPORT_SYMBOL(csum_partial_copy_from); | 17 | EXPORT_SYMBOL(csum_partial); |
17 | EXPORT_SYMBOL(csum_partial_copy_to); | 18 | |
19 | /* delay core functions */ | ||
20 | EXPORT_SYMBOL(__const_udelay); | ||
21 | EXPORT_SYMBOL(__udelay); | ||
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c index 31bcb2f997d4..dc755b0b9db8 100644 --- a/arch/um/sys-i386/ldt.c +++ b/arch/um/sys-i386/ldt.c | |||
@@ -25,7 +25,7 @@ int sys_modify_ldt_tt(int func, void __user *ptr, unsigned long bytecount) | |||
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | #ifdef CONFIG_MODE_SKAS | 27 | #ifdef CONFIG_MODE_SKAS |
28 | extern int userspace_pid; | 28 | extern int userspace_pid[]; |
29 | 29 | ||
30 | #include "skas_ptrace.h" | 30 | #include "skas_ptrace.h" |
31 | 31 | ||
@@ -56,7 +56,8 @@ int sys_modify_ldt_skas(int func, void __user *ptr, unsigned long bytecount) | |||
56 | ldt = ((struct ptrace_ldt) { .func = func, | 56 | ldt = ((struct ptrace_ldt) { .func = func, |
57 | .ptr = buf, | 57 | .ptr = buf, |
58 | .bytecount = bytecount }); | 58 | .bytecount = bytecount }); |
59 | res = ptrace(PTRACE_LDT, userspace_pid, 0, (unsigned long) &ldt); | 59 | #warning Need to look up userspace_pid by cpu |
60 | res = ptrace(PTRACE_LDT, userspace_pid[0], 0, (unsigned long) &ldt); | ||
60 | if(res < 0) | 61 | if(res < 0) |
61 | goto out; | 62 | goto out; |
62 | 63 | ||
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c index e470d28cdf84..e839ce65ad28 100644 --- a/arch/um/sys-i386/ptrace.c +++ b/arch/um/sys-i386/ptrace.c | |||
@@ -73,6 +73,25 @@ int putreg(struct task_struct *child, int regno, unsigned long value) | |||
73 | return 0; | 73 | return 0; |
74 | } | 74 | } |
75 | 75 | ||
76 | int poke_user(struct task_struct *child, long addr, long data) | ||
77 | { | ||
78 | if ((addr & 3) || addr < 0) | ||
79 | return -EIO; | ||
80 | |||
81 | if (addr < MAX_REG_OFFSET) | ||
82 | return putreg(child, addr, data); | ||
83 | |||
84 | else if((addr >= offsetof(struct user, u_debugreg[0])) && | ||
85 | (addr <= offsetof(struct user, u_debugreg[7]))){ | ||
86 | addr -= offsetof(struct user, u_debugreg[0]); | ||
87 | addr = addr >> 2; | ||
88 | if((addr == 4) || (addr == 5)) return -EIO; | ||
89 | child->thread.arch.debugregs[addr] = data; | ||
90 | return 0; | ||
91 | } | ||
92 | return -EIO; | ||
93 | } | ||
94 | |||
76 | unsigned long getreg(struct task_struct *child, int regno) | 95 | unsigned long getreg(struct task_struct *child, int regno) |
77 | { | 96 | { |
78 | unsigned long retval = ~0UL; | 97 | unsigned long retval = ~0UL; |
@@ -93,6 +112,27 @@ unsigned long getreg(struct task_struct *child, int regno) | |||
93 | return retval; | 112 | return retval; |
94 | } | 113 | } |
95 | 114 | ||
115 | int peek_user(struct task_struct *child, long addr, long data) | ||
116 | { | ||
117 | /* read the word at location addr in the USER area. */ | ||
118 | unsigned long tmp; | ||
119 | |||
120 | if ((addr & 3) || addr < 0) | ||
121 | return -EIO; | ||
122 | |||
123 | tmp = 0; /* Default return condition */ | ||
124 | if(addr < MAX_REG_OFFSET){ | ||
125 | tmp = getreg(child, addr); | ||
126 | } | ||
127 | else if((addr >= offsetof(struct user, u_debugreg[0])) && | ||
128 | (addr <= offsetof(struct user, u_debugreg[7]))){ | ||
129 | addr -= offsetof(struct user, u_debugreg[0]); | ||
130 | addr = addr >> 2; | ||
131 | tmp = child->thread.arch.debugregs[addr]; | ||
132 | } | ||
133 | return put_user(tmp, (unsigned long *) data); | ||
134 | } | ||
135 | |||
96 | struct i387_fxsave_struct { | 136 | struct i387_fxsave_struct { |
97 | unsigned short cwd; | 137 | unsigned short cwd; |
98 | unsigned short swd; | 138 | unsigned short swd; |
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c index 76ba87254b25..03913ca5d256 100644 --- a/arch/um/sys-i386/signal.c +++ b/arch/um/sys-i386/signal.c | |||
@@ -47,9 +47,6 @@ static int copy_sc_from_user_skas(struct pt_regs *regs, | |||
47 | REGS_CS(regs->regs.skas.regs) = sc.cs; | 47 | REGS_CS(regs->regs.skas.regs) = sc.cs; |
48 | REGS_EFLAGS(regs->regs.skas.regs) = sc.eflags; | 48 | REGS_EFLAGS(regs->regs.skas.regs) = sc.eflags; |
49 | REGS_SS(regs->regs.skas.regs) = sc.ss; | 49 | REGS_SS(regs->regs.skas.regs) = sc.ss; |
50 | regs->regs.skas.fault_addr = sc.cr2; | ||
51 | regs->regs.skas.fault_type = FAULT_WRITE(sc.err); | ||
52 | regs->regs.skas.trap_type = sc.trapno; | ||
53 | 50 | ||
54 | err = restore_fp_registers(userspace_pid[0], fpregs); | 51 | err = restore_fp_registers(userspace_pid[0], fpregs); |
55 | if(err < 0){ | 52 | if(err < 0){ |
@@ -62,11 +59,11 @@ static int copy_sc_from_user_skas(struct pt_regs *regs, | |||
62 | } | 59 | } |
63 | 60 | ||
64 | int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, | 61 | int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, |
65 | struct pt_regs *regs, unsigned long fault_addr, | 62 | struct pt_regs *regs) |
66 | int fault_type) | ||
67 | { | 63 | { |
68 | struct sigcontext sc; | 64 | struct sigcontext sc; |
69 | unsigned long fpregs[HOST_FP_SIZE]; | 65 | unsigned long fpregs[HOST_FP_SIZE]; |
66 | struct faultinfo * fi = ¤t->thread.arch.faultinfo; | ||
70 | int err; | 67 | int err; |
71 | 68 | ||
72 | sc.gs = REGS_GS(regs->regs.skas.regs); | 69 | sc.gs = REGS_GS(regs->regs.skas.regs); |
@@ -86,9 +83,9 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, | |||
86 | sc.eflags = REGS_EFLAGS(regs->regs.skas.regs); | 83 | sc.eflags = REGS_EFLAGS(regs->regs.skas.regs); |
87 | sc.esp_at_signal = regs->regs.skas.regs[UESP]; | 84 | sc.esp_at_signal = regs->regs.skas.regs[UESP]; |
88 | sc.ss = regs->regs.skas.regs[SS]; | 85 | sc.ss = regs->regs.skas.regs[SS]; |
89 | sc.cr2 = fault_addr; | 86 | sc.cr2 = fi->cr2; |
90 | sc.err = TO_SC_ERR(fault_type); | 87 | sc.err = fi->error_code; |
91 | sc.trapno = regs->regs.skas.trap_type; | 88 | sc.trapno = fi->trap_no; |
92 | 89 | ||
93 | err = save_fp_registers(userspace_pid[0], fpregs); | 90 | err = save_fp_registers(userspace_pid[0], fpregs); |
94 | if(err < 0){ | 91 | if(err < 0){ |
@@ -167,9 +164,7 @@ static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp, | |||
167 | { | 164 | { |
168 | return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), | 165 | return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), |
169 | sizeof(*fp)), | 166 | sizeof(*fp)), |
170 | copy_sc_to_user_skas(to, fp, from, | 167 | copy_sc_to_user_skas(to, fp, from))); |
171 | current->thread.cr2, | ||
172 | current->thread.err))); | ||
173 | } | 168 | } |
174 | 169 | ||
175 | static int copy_ucontext_to_user(struct ucontext *uc, struct _fpstate *fp, | 170 | static int copy_ucontext_to_user(struct ucontext *uc, struct _fpstate *fp, |
diff --git a/arch/um/sys-i386/sysrq.c b/arch/um/sys-i386/sysrq.c index 281fc7b8ca00..e3706d15c4f5 100644 --- a/arch/um/sys-i386/sysrq.c +++ b/arch/um/sys-i386/sysrq.c | |||
@@ -3,12 +3,15 @@ | |||
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/config.h" | ||
6 | #include "linux/kernel.h" | 7 | #include "linux/kernel.h" |
7 | #include "linux/smp.h" | 8 | #include "linux/smp.h" |
8 | #include "linux/sched.h" | 9 | #include "linux/sched.h" |
10 | #include "linux/kallsyms.h" | ||
9 | #include "asm/ptrace.h" | 11 | #include "asm/ptrace.h" |
10 | #include "sysrq.h" | 12 | #include "sysrq.h" |
11 | 13 | ||
14 | /* This is declared by <linux/sched.h> */ | ||
12 | void show_regs(struct pt_regs *regs) | 15 | void show_regs(struct pt_regs *regs) |
13 | { | 16 | { |
14 | printk("\n"); | 17 | printk("\n"); |
@@ -31,5 +34,80 @@ void show_regs(struct pt_regs *regs) | |||
31 | 0xffff & PT_REGS_DS(regs), | 34 | 0xffff & PT_REGS_DS(regs), |
32 | 0xffff & PT_REGS_ES(regs)); | 35 | 0xffff & PT_REGS_ES(regs)); |
33 | 36 | ||
34 | show_trace((unsigned long *) ®s); | 37 | show_trace(NULL, (unsigned long *) ®s); |
35 | } | 38 | } |
39 | |||
40 | /* Copied from i386. */ | ||
41 | static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) | ||
42 | { | ||
43 | return p > (void *)tinfo && | ||
44 | p < (void *)tinfo + THREAD_SIZE - 3; | ||
45 | } | ||
46 | |||
47 | /* Adapted from i386 (we also print the address we read from). */ | ||
48 | static inline unsigned long print_context_stack(struct thread_info *tinfo, | ||
49 | unsigned long *stack, unsigned long ebp) | ||
50 | { | ||
51 | unsigned long addr; | ||
52 | |||
53 | #ifdef CONFIG_FRAME_POINTER | ||
54 | while (valid_stack_ptr(tinfo, (void *)ebp)) { | ||
55 | addr = *(unsigned long *)(ebp + 4); | ||
56 | printk("%08lx: [<%08lx>]", ebp + 4, addr); | ||
57 | print_symbol(" %s", addr); | ||
58 | printk("\n"); | ||
59 | ebp = *(unsigned long *)ebp; | ||
60 | } | ||
61 | #else | ||
62 | while (valid_stack_ptr(tinfo, stack)) { | ||
63 | addr = *stack; | ||
64 | if (__kernel_text_address(addr)) { | ||
65 | printk("%08lx: [<%08lx>]", (unsigned long) stack, addr); | ||
66 | print_symbol(" %s", addr); | ||
67 | printk("\n"); | ||
68 | } | ||
69 | stack++; | ||
70 | } | ||
71 | #endif | ||
72 | return ebp; | ||
73 | } | ||
74 | |||
75 | void show_trace(struct task_struct* task, unsigned long * stack) | ||
76 | { | ||
77 | unsigned long ebp; | ||
78 | struct thread_info *context; | ||
79 | |||
80 | /* Turn this into BUG_ON if possible. */ | ||
81 | if (!stack) { | ||
82 | stack = (unsigned long*) &stack; | ||
83 | printk("show_trace: got NULL stack, implicit assumption task == current"); | ||
84 | WARN_ON(1); | ||
85 | } | ||
86 | |||
87 | if (!task) | ||
88 | task = current; | ||
89 | |||
90 | if (task != current) { | ||
91 | //ebp = (unsigned long) KSTK_EBP(task); | ||
92 | /* Which one? No actual difference - just coding style.*/ | ||
93 | ebp = (unsigned long) PT_REGS_EBP(&task->thread.regs); | ||
94 | } else { | ||
95 | asm ("movl %%ebp, %0" : "=r" (ebp) : ); | ||
96 | } | ||
97 | |||
98 | context = (struct thread_info *) | ||
99 | ((unsigned long)stack & (~(THREAD_SIZE - 1))); | ||
100 | print_context_stack(context, stack, ebp); | ||
101 | |||
102 | /*while (((long) stack & (THREAD_SIZE-1)) != 0) { | ||
103 | addr = *stack; | ||
104 | if (__kernel_text_address(addr)) { | ||
105 | printk("%08lx: [<%08lx>]", (unsigned long) stack, addr); | ||
106 | print_symbol(" %s", addr); | ||
107 | printk("\n"); | ||
108 | } | ||
109 | stack++; | ||
110 | }*/ | ||
111 | printk("\n"); | ||
112 | } | ||
113 | |||
diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c new file mode 100644 index 000000000000..3ceaabceb3d7 --- /dev/null +++ b/arch/um/sys-i386/user-offsets.c | |||
@@ -0,0 +1,69 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <signal.h> | ||
3 | #include <asm/ptrace.h> | ||
4 | #include <asm/user.h> | ||
5 | #include <linux/stddef.h> | ||
6 | |||
7 | #define DEFINE(sym, val) \ | ||
8 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) | ||
9 | |||
10 | #define OFFSET(sym, str, mem) \ | ||
11 | DEFINE(sym, offsetof(struct str, mem)); | ||
12 | |||
13 | void foo(void) | ||
14 | { | ||
15 | OFFSET(SC_IP, sigcontext, eip); | ||
16 | OFFSET(SC_SP, sigcontext, esp); | ||
17 | OFFSET(SC_FS, sigcontext, fs); | ||
18 | OFFSET(SC_GS, sigcontext, gs); | ||
19 | OFFSET(SC_DS, sigcontext, ds); | ||
20 | OFFSET(SC_ES, sigcontext, es); | ||
21 | OFFSET(SC_SS, sigcontext, ss); | ||
22 | OFFSET(SC_CS, sigcontext, cs); | ||
23 | OFFSET(SC_EFLAGS, sigcontext, eflags); | ||
24 | OFFSET(SC_EAX, sigcontext, eax); | ||
25 | OFFSET(SC_EBX, sigcontext, ebx); | ||
26 | OFFSET(SC_ECX, sigcontext, ecx); | ||
27 | OFFSET(SC_EDX, sigcontext, edx); | ||
28 | OFFSET(SC_EDI, sigcontext, edi); | ||
29 | OFFSET(SC_ESI, sigcontext, esi); | ||
30 | OFFSET(SC_EBP, sigcontext, ebp); | ||
31 | OFFSET(SC_TRAPNO, sigcontext, trapno); | ||
32 | OFFSET(SC_ERR, sigcontext, err); | ||
33 | OFFSET(SC_CR2, sigcontext, cr2); | ||
34 | OFFSET(SC_FPSTATE, sigcontext, fpstate); | ||
35 | OFFSET(SC_SIGMASK, sigcontext, oldmask); | ||
36 | OFFSET(SC_FP_CW, _fpstate, cw); | ||
37 | OFFSET(SC_FP_SW, _fpstate, sw); | ||
38 | OFFSET(SC_FP_TAG, _fpstate, tag); | ||
39 | OFFSET(SC_FP_IPOFF, _fpstate, ipoff); | ||
40 | OFFSET(SC_FP_CSSEL, _fpstate, cssel); | ||
41 | OFFSET(SC_FP_DATAOFF, _fpstate, dataoff); | ||
42 | OFFSET(SC_FP_DATASEL, _fpstate, datasel); | ||
43 | OFFSET(SC_FP_ST, _fpstate, _st); | ||
44 | OFFSET(SC_FXSR_ENV, _fpstate, _fxsr_env); | ||
45 | |||
46 | DEFINE(HOST_FRAME_SIZE, FRAME_SIZE); | ||
47 | DEFINE(HOST_FP_SIZE, | ||
48 | sizeof(struct user_i387_struct) / sizeof(unsigned long)); | ||
49 | DEFINE(HOST_XFP_SIZE, | ||
50 | sizeof(struct user_fxsr_struct) / sizeof(unsigned long)); | ||
51 | |||
52 | DEFINE(HOST_IP, EIP); | ||
53 | DEFINE(HOST_SP, UESP); | ||
54 | DEFINE(HOST_EFLAGS, EFL); | ||
55 | DEFINE(HOST_EAX, EAX); | ||
56 | DEFINE(HOST_EBX, EBX); | ||
57 | DEFINE(HOST_ECX, ECX); | ||
58 | DEFINE(HOST_EDX, EDX); | ||
59 | DEFINE(HOST_ESI, ESI); | ||
60 | DEFINE(HOST_EDI, EDI); | ||
61 | DEFINE(HOST_EBP, EBP); | ||
62 | DEFINE(HOST_CS, CS); | ||
63 | DEFINE(HOST_SS, SS); | ||
64 | DEFINE(HOST_DS, DS); | ||
65 | DEFINE(HOST_FS, FS); | ||
66 | DEFINE(HOST_ES, ES); | ||
67 | DEFINE(HOST_GS, GS); | ||
68 | DEFINE(__UM_FRAME_SIZE, sizeof(struct user_regs_struct)); | ||
69 | } | ||
diff --git a/arch/um/sys-i386/util/Makefile b/arch/um/sys-i386/util/Makefile index 34860f9ca7b0..bf61afd0b045 100644 --- a/arch/um/sys-i386/util/Makefile +++ b/arch/um/sys-i386/util/Makefile | |||
@@ -1,8 +1,5 @@ | |||
1 | |||
2 | hostprogs-y := mk_sc mk_thread | 1 | hostprogs-y := mk_sc mk_thread |
3 | always := $(hostprogs-y) | 2 | always := $(hostprogs-y) |
4 | 3 | ||
5 | mk_thread-objs := mk_thread_kern.o mk_thread_user.o | 4 | HOSTCFLAGS_mk_sc.o := -I$(objtree)/arch/um |
6 | 5 | HOSTCFLAGS_mk_thread.o := -I$(objtree)/arch/um | |
7 | HOSTCFLAGS_mk_thread_kern.o := $(CFLAGS) $(CPPFLAGS) | ||
8 | HOSTCFLAGS_mk_thread_user.o := $(USER_CFLAGS) | ||
diff --git a/arch/um/sys-i386/util/mk_sc.c b/arch/um/sys-i386/util/mk_sc.c index 85cbd30396f7..04c0d73433aa 100644 --- a/arch/um/sys-i386/util/mk_sc.c +++ b/arch/um/sys-i386/util/mk_sc.c | |||
@@ -1,52 +1,51 @@ | |||
1 | #include <stdio.h> | 1 | #include <stdio.h> |
2 | #include <signal.h> | 2 | #include <user-offsets.h> |
3 | #include <linux/stddef.h> | ||
4 | 3 | ||
5 | #define SC_OFFSET(name, field) \ | 4 | #define SC_OFFSET(name, field) \ |
6 | printf("#define " name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\ | 5 | printf("#define " #name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\ |
7 | offsetof(struct sigcontext, field)) | 6 | name) |
8 | 7 | ||
9 | #define SC_FP_OFFSET(name, field) \ | 8 | #define SC_FP_OFFSET(name, field) \ |
10 | printf("#define " name \ | 9 | printf("#define " #name \ |
11 | "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\ | 10 | "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\ |
12 | offsetof(struct _fpstate, field)) | 11 | name) |
13 | 12 | ||
14 | #define SC_FP_OFFSET_PTR(name, field, type) \ | 13 | #define SC_FP_OFFSET_PTR(name, field, type) \ |
15 | printf("#define " name \ | 14 | printf("#define " #name \ |
16 | "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\ | 15 | "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\ |
17 | offsetof(struct _fpstate, field)) | 16 | name) |
18 | 17 | ||
19 | int main(int argc, char **argv) | 18 | int main(int argc, char **argv) |
20 | { | 19 | { |
21 | SC_OFFSET("SC_IP", eip); | 20 | SC_OFFSET(SC_IP, eip); |
22 | SC_OFFSET("SC_SP", esp); | 21 | SC_OFFSET(SC_SP, esp); |
23 | SC_OFFSET("SC_FS", fs); | 22 | SC_OFFSET(SC_FS, fs); |
24 | SC_OFFSET("SC_GS", gs); | 23 | SC_OFFSET(SC_GS, gs); |
25 | SC_OFFSET("SC_DS", ds); | 24 | SC_OFFSET(SC_DS, ds); |
26 | SC_OFFSET("SC_ES", es); | 25 | SC_OFFSET(SC_ES, es); |
27 | SC_OFFSET("SC_SS", ss); | 26 | SC_OFFSET(SC_SS, ss); |
28 | SC_OFFSET("SC_CS", cs); | 27 | SC_OFFSET(SC_CS, cs); |
29 | SC_OFFSET("SC_EFLAGS", eflags); | 28 | SC_OFFSET(SC_EFLAGS, eflags); |
30 | SC_OFFSET("SC_EAX", eax); | 29 | SC_OFFSET(SC_EAX, eax); |
31 | SC_OFFSET("SC_EBX", ebx); | 30 | SC_OFFSET(SC_EBX, ebx); |
32 | SC_OFFSET("SC_ECX", ecx); | 31 | SC_OFFSET(SC_ECX, ecx); |
33 | SC_OFFSET("SC_EDX", edx); | 32 | SC_OFFSET(SC_EDX, edx); |
34 | SC_OFFSET("SC_EDI", edi); | 33 | SC_OFFSET(SC_EDI, edi); |
35 | SC_OFFSET("SC_ESI", esi); | 34 | SC_OFFSET(SC_ESI, esi); |
36 | SC_OFFSET("SC_EBP", ebp); | 35 | SC_OFFSET(SC_EBP, ebp); |
37 | SC_OFFSET("SC_TRAPNO", trapno); | 36 | SC_OFFSET(SC_TRAPNO, trapno); |
38 | SC_OFFSET("SC_ERR", err); | 37 | SC_OFFSET(SC_ERR, err); |
39 | SC_OFFSET("SC_CR2", cr2); | 38 | SC_OFFSET(SC_CR2, cr2); |
40 | SC_OFFSET("SC_FPSTATE", fpstate); | 39 | SC_OFFSET(SC_FPSTATE, fpstate); |
41 | SC_OFFSET("SC_SIGMASK", oldmask); | 40 | SC_OFFSET(SC_SIGMASK, oldmask); |
42 | SC_FP_OFFSET("SC_FP_CW", cw); | 41 | SC_FP_OFFSET(SC_FP_CW, cw); |
43 | SC_FP_OFFSET("SC_FP_SW", sw); | 42 | SC_FP_OFFSET(SC_FP_SW, sw); |
44 | SC_FP_OFFSET("SC_FP_TAG", tag); | 43 | SC_FP_OFFSET(SC_FP_TAG, tag); |
45 | SC_FP_OFFSET("SC_FP_IPOFF", ipoff); | 44 | SC_FP_OFFSET(SC_FP_IPOFF, ipoff); |
46 | SC_FP_OFFSET("SC_FP_CSSEL", cssel); | 45 | SC_FP_OFFSET(SC_FP_CSSEL, cssel); |
47 | SC_FP_OFFSET("SC_FP_DATAOFF", dataoff); | 46 | SC_FP_OFFSET(SC_FP_DATAOFF, dataoff); |
48 | SC_FP_OFFSET("SC_FP_DATASEL", datasel); | 47 | SC_FP_OFFSET(SC_FP_DATASEL, datasel); |
49 | SC_FP_OFFSET_PTR("SC_FP_ST", _st, "struct _fpstate"); | 48 | SC_FP_OFFSET_PTR(SC_FP_ST, _st, "struct _fpstate"); |
50 | SC_FP_OFFSET_PTR("SC_FXSR_ENV", _fxsr_env, "void"); | 49 | SC_FP_OFFSET_PTR(SC_FXSR_ENV, _fxsr_env, "void"); |
51 | return(0); | 50 | return(0); |
52 | } | 51 | } |
diff --git a/arch/um/sys-i386/util/mk_thread.c b/arch/um/sys-i386/util/mk_thread.c new file mode 100644 index 000000000000..7470d0dda67e --- /dev/null +++ b/arch/um/sys-i386/util/mk_thread.c | |||
@@ -0,0 +1,22 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <kernel-offsets.h> | ||
3 | |||
4 | int main(int argc, char **argv) | ||
5 | { | ||
6 | printf("/*\n"); | ||
7 | printf(" * Generated by mk_thread\n"); | ||
8 | printf(" */\n"); | ||
9 | printf("\n"); | ||
10 | printf("#ifndef __UM_THREAD_H\n"); | ||
11 | printf("#define __UM_THREAD_H\n"); | ||
12 | printf("\n"); | ||
13 | printf("#define TASK_DEBUGREGS(task) ((unsigned long *) " | ||
14 | "&(((char *) (task))[%d]))\n", TASK_DEBUGREGS); | ||
15 | #ifdef TASK_EXTERN_PID | ||
16 | printf("#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[%d]))\n", | ||
17 | TASK_EXTERN_PID); | ||
18 | #endif | ||
19 | printf("\n"); | ||
20 | printf("#endif\n"); | ||
21 | return(0); | ||
22 | } | ||
diff --git a/arch/um/sys-i386/util/mk_thread_kern.c b/arch/um/sys-i386/util/mk_thread_kern.c deleted file mode 100644 index 948b1ce85230..000000000000 --- a/arch/um/sys-i386/util/mk_thread_kern.c +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | #include "linux/config.h" | ||
2 | #include "linux/stddef.h" | ||
3 | #include "linux/sched.h" | ||
4 | |||
5 | extern void print_head(void); | ||
6 | extern void print_constant_ptr(char *name, int value); | ||
7 | extern void print_constant(char *name, char *type, int value); | ||
8 | extern void print_tail(void); | ||
9 | |||
10 | #define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field) | ||
11 | |||
12 | int main(int argc, char **argv) | ||
13 | { | ||
14 | print_head(); | ||
15 | print_constant_ptr("TASK_DEBUGREGS", THREAD_OFFSET(arch.debugregs)); | ||
16 | #ifdef CONFIG_MODE_TT | ||
17 | print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid)); | ||
18 | #endif | ||
19 | print_tail(); | ||
20 | return(0); | ||
21 | } | ||
22 | |||
diff --git a/arch/um/sys-i386/util/mk_thread_user.c b/arch/um/sys-i386/util/mk_thread_user.c deleted file mode 100644 index 2620cd6aa1f1..000000000000 --- a/arch/um/sys-i386/util/mk_thread_user.c +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | #include <stdio.h> | ||
2 | |||
3 | void print_head(void) | ||
4 | { | ||
5 | printf("/*\n"); | ||
6 | printf(" * Generated by mk_thread\n"); | ||
7 | printf(" */\n"); | ||
8 | printf("\n"); | ||
9 | printf("#ifndef __UM_THREAD_H\n"); | ||
10 | printf("#define __UM_THREAD_H\n"); | ||
11 | printf("\n"); | ||
12 | } | ||
13 | |||
14 | void print_constant_ptr(char *name, int value) | ||
15 | { | ||
16 | printf("#define %s(task) ((unsigned long *) " | ||
17 | "&(((char *) (task))[%d]))\n", name, value); | ||
18 | } | ||
19 | |||
20 | void print_constant(char *name, char *type, int value) | ||
21 | { | ||
22 | printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type, | ||
23 | value); | ||
24 | } | ||
25 | |||
26 | void print_tail(void) | ||
27 | { | ||
28 | printf("\n"); | ||
29 | printf("#endif\n"); | ||
30 | } | ||
diff --git a/arch/um/sys-ppc/ptrace.c b/arch/um/sys-ppc/ptrace.c index a971366d3277..8e71b47f2b8e 100644 --- a/arch/um/sys-ppc/ptrace.c +++ b/arch/um/sys-ppc/ptrace.c | |||
@@ -8,6 +8,25 @@ int putreg(struct task_struct *child, unsigned long regno, | |||
8 | return 0; | 8 | return 0; |
9 | } | 9 | } |
10 | 10 | ||
11 | int poke_user(struct task_struct *child, long addr, long data) | ||
12 | { | ||
13 | if ((addr & 3) || addr < 0) | ||
14 | return -EIO; | ||
15 | |||
16 | if (addr < MAX_REG_OFFSET) | ||
17 | return putreg(child, addr, data); | ||
18 | |||
19 | else if((addr >= offsetof(struct user, u_debugreg[0])) && | ||
20 | (addr <= offsetof(struct user, u_debugreg[7]))){ | ||
21 | addr -= offsetof(struct user, u_debugreg[0]); | ||
22 | addr = addr >> 2; | ||
23 | if((addr == 4) || (addr == 5)) return -EIO; | ||
24 | child->thread.arch.debugregs[addr] = data; | ||
25 | return 0; | ||
26 | } | ||
27 | return -EIO; | ||
28 | } | ||
29 | |||
11 | unsigned long getreg(struct task_struct *child, unsigned long regno) | 30 | unsigned long getreg(struct task_struct *child, unsigned long regno) |
12 | { | 31 | { |
13 | unsigned long retval = ~0UL; | 32 | unsigned long retval = ~0UL; |
@@ -16,6 +35,27 @@ unsigned long getreg(struct task_struct *child, unsigned long regno) | |||
16 | return retval; | 35 | return retval; |
17 | } | 36 | } |
18 | 37 | ||
38 | int peek_user(struct task_struct *child, long addr, long data) | ||
39 | { | ||
40 | /* read the word at location addr in the USER area. */ | ||
41 | unsigned long tmp; | ||
42 | |||
43 | if ((addr & 3) || addr < 0) | ||
44 | return -EIO; | ||
45 | |||
46 | tmp = 0; /* Default return condition */ | ||
47 | if(addr < MAX_REG_OFFSET){ | ||
48 | tmp = getreg(child, addr); | ||
49 | } | ||
50 | else if((addr >= offsetof(struct user, u_debugreg[0])) && | ||
51 | (addr <= offsetof(struct user, u_debugreg[7]))){ | ||
52 | addr -= offsetof(struct user, u_debugreg[0]); | ||
53 | addr = addr >> 2; | ||
54 | tmp = child->thread.arch.debugregs[addr]; | ||
55 | } | ||
56 | return put_user(tmp, (unsigned long *) data); | ||
57 | } | ||
58 | |||
19 | /* | 59 | /* |
20 | * Overrides for Emacs so that we follow Linus's tabbing style. | 60 | * 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 | 61 | * Emacs will notice this stuff at the end of the file and automatically |
diff --git a/arch/um/sys-ppc/sysrq.c b/arch/um/sys-ppc/sysrq.c index 82d6e9335bb6..2f816f1a0ff4 100644 --- a/arch/um/sys-ppc/sysrq.c +++ b/arch/um/sys-ppc/sysrq.c | |||
@@ -27,17 +27,5 @@ void show_regs(struct pt_regs_subarch *regs) | |||
27 | 0xffff & regs->xds, 0xffff & regs->xes); | 27 | 0xffff & regs->xds, 0xffff & regs->xes); |
28 | #endif | 28 | #endif |
29 | 29 | ||
30 | show_trace(®s->gpr[1]); | 30 | show_trace(current, ®s->gpr[1]); |
31 | } | 31 | } |
32 | |||
33 | |||
34 | /* | ||
35 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
36 | * Emacs will notice this stuff at the end of the file and automatically | ||
37 | * adjust the settings for this buffer only. This must remain at the end | ||
38 | * of the file. | ||
39 | * --------------------------------------------------------------------------- | ||
40 | * Local variables: | ||
41 | * c-file-style: "linux" | ||
42 | * End: | ||
43 | */ | ||
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile index d7ed2f7908df..608466ad6b22 100644 --- a/arch/um/sys-x86_64/Makefile +++ b/arch/um/sys-x86_64/Makefile | |||
@@ -4,24 +4,20 @@ | |||
4 | # Licensed under the GPL | 4 | # Licensed under the GPL |
5 | # | 5 | # |
6 | 6 | ||
7 | #XXX: why into lib-y? | ||
7 | lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \ | 8 | lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \ |
8 | ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o \ | 9 | ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o \ |
9 | syscalls.o sysrq.o thunk.o syscall_table.o | 10 | syscalls.o sysrq.o thunk.o syscall_table.o |
10 | 11 | ||
11 | USER_OBJS := ptrace_user.o sigcontext.o | 12 | obj-y := ksyms.o |
13 | obj-$(CONFIG_MODULES) += module.o um_module.o | ||
12 | 14 | ||
13 | include arch/um/scripts/Makefile.rules | 15 | USER_OBJS := ptrace_user.o sigcontext.o |
14 | 16 | ||
15 | SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c memcpy.S \ | 17 | SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c memcpy.S \ |
16 | semaphore.c thunk.S | 18 | semaphore.c thunk.S module.c |
17 | |||
18 | # this needs to be before the foreach, because clean-files does not accept | ||
19 | # complete paths like $(src)/$f. | ||
20 | clean-files := $(SYMLINKS) | ||
21 | 19 | ||
22 | targets += $(SYMLINKS) | 20 | include arch/um/scripts/Makefile.rules |
23 | |||
24 | SYMLINKS := $(foreach f,$(SYMLINKS),$(obj)/$f) | ||
25 | 21 | ||
26 | bitops.c-dir = lib | 22 | bitops.c-dir = lib |
27 | csum-copy.S-dir = lib | 23 | csum-copy.S-dir = lib |
@@ -30,8 +26,6 @@ csum-wrappers.c-dir = lib | |||
30 | memcpy.S-dir = lib | 26 | memcpy.S-dir = lib |
31 | semaphore.c-dir = kernel | 27 | semaphore.c-dir = kernel |
32 | thunk.S-dir = lib | 28 | thunk.S-dir = lib |
29 | module.c-dir = kernel | ||
33 | 30 | ||
34 | $(SYMLINKS): FORCE | 31 | subdir- := util |
35 | $(call if_changed,make_link) | ||
36 | |||
37 | CFLAGS_csum-partial.o := -Dcsum_partial=arch_csum_partial | ||
diff --git a/arch/um/sys-x86_64/delay.c b/arch/um/sys-x86_64/delay.c index f3b5187942b4..137f4446b439 100644 --- a/arch/um/sys-x86_64/delay.c +++ b/arch/um/sys-x86_64/delay.c | |||
@@ -5,22 +5,37 @@ | |||
5 | * Licensed under the GPL | 5 | * Licensed under the GPL |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include "asm/processor.h" | 8 | #include <linux/module.h> |
9 | #include <linux/delay.h> | ||
10 | #include <asm/processor.h> | ||
11 | #include <asm/param.h> | ||
9 | 12 | ||
10 | void __delay(unsigned long loops) | 13 | void __delay(unsigned long loops) |
11 | { | 14 | { |
12 | unsigned long i; | 15 | unsigned long i; |
13 | 16 | ||
14 | for(i = 0; i < loops; i++) ; | 17 | for(i = 0; i < loops; i++) |
18 | cpu_relax(); | ||
15 | } | 19 | } |
16 | 20 | ||
17 | /* | 21 | void __udelay(unsigned long usecs) |
18 | * Overrides for Emacs so that we follow Linus's tabbing style. | 22 | { |
19 | * Emacs will notice this stuff at the end of the file and automatically | 23 | unsigned long i, n; |
20 | * adjust the settings for this buffer only. This must remain at the end | 24 | |
21 | * of the file. | 25 | n = (loops_per_jiffy * HZ * usecs) / MILLION; |
22 | * --------------------------------------------------------------------------- | 26 | for(i=0;i<n;i++) |
23 | * Local variables: | 27 | cpu_relax(); |
24 | * c-file-style: "linux" | 28 | } |
25 | * End: | 29 | |
26 | */ | 30 | EXPORT_SYMBOL(__udelay); |
31 | |||
32 | void __const_udelay(unsigned long usecs) | ||
33 | { | ||
34 | unsigned long i, n; | ||
35 | |||
36 | n = (loops_per_jiffy * HZ * usecs) / MILLION; | ||
37 | for(i=0;i<n;i++) | ||
38 | cpu_relax(); | ||
39 | } | ||
40 | |||
41 | EXPORT_SYMBOL(__const_udelay); | ||
diff --git a/arch/um/sys-x86_64/kernel-offsets.c b/arch/um/sys-x86_64/kernel-offsets.c new file mode 100644 index 000000000000..220e875cbe29 --- /dev/null +++ b/arch/um/sys-x86_64/kernel-offsets.c | |||
@@ -0,0 +1,24 @@ | |||
1 | #include <linux/config.h> | ||
2 | #include <linux/stddef.h> | ||
3 | #include <linux/sched.h> | ||
4 | #include <linux/time.h> | ||
5 | #include <asm/page.h> | ||
6 | |||
7 | #define DEFINE(sym, val) \ | ||
8 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) | ||
9 | |||
10 | #define DEFINE_STR1(x) #x | ||
11 | #define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " DEFINE_STR1(val) " " #val: : ) | ||
12 | |||
13 | #define BLANK() asm volatile("\n->" : : ) | ||
14 | |||
15 | #define OFFSET(sym, str, mem) \ | ||
16 | DEFINE(sym, offsetof(struct str, mem)); | ||
17 | |||
18 | void foo(void) | ||
19 | { | ||
20 | #ifdef CONFIG_MODE_TT | ||
21 | OFFSET(TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); | ||
22 | #endif | ||
23 | #include <common-offsets.h> | ||
24 | } | ||
diff --git a/arch/um/sys-x86_64/ksyms.c b/arch/um/sys-x86_64/ksyms.c new file mode 100644 index 000000000000..859273808203 --- /dev/null +++ b/arch/um/sys-x86_64/ksyms.c | |||
@@ -0,0 +1,19 @@ | |||
1 | #include "linux/module.h" | ||
2 | #include "linux/in6.h" | ||
3 | #include "linux/rwsem.h" | ||
4 | #include "asm/byteorder.h" | ||
5 | #include "asm/semaphore.h" | ||
6 | #include "asm/uaccess.h" | ||
7 | #include "asm/checksum.h" | ||
8 | #include "asm/errno.h" | ||
9 | |||
10 | EXPORT_SYMBOL(__down_failed); | ||
11 | EXPORT_SYMBOL(__down_failed_interruptible); | ||
12 | EXPORT_SYMBOL(__down_failed_trylock); | ||
13 | EXPORT_SYMBOL(__up_wakeup); | ||
14 | |||
15 | /*XXX: we need them because they would be exported by x86_64 */ | ||
16 | EXPORT_SYMBOL(__memcpy); | ||
17 | |||
18 | /* Networking helper routines. */ | ||
19 | EXPORT_SYMBOL(ip_compute_csum); | ||
diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c index 8c146b2a1e00..74eee5c7c6dd 100644 --- a/arch/um/sys-x86_64/ptrace.c +++ b/arch/um/sys-x86_64/ptrace.c | |||
@@ -5,10 +5,11 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | #define __FRAME_OFFSETS | 7 | #define __FRAME_OFFSETS |
8 | #include "asm/ptrace.h" | 8 | #include <asm/ptrace.h> |
9 | #include "linux/sched.h" | 9 | #include <linux/sched.h> |
10 | #include "linux/errno.h" | 10 | #include <linux/errno.h> |
11 | #include "asm/elf.h" | 11 | #include <asm/uaccess.h> |
12 | #include <asm/elf.h> | ||
12 | 13 | ||
13 | /* XXX x86_64 */ | 14 | /* XXX x86_64 */ |
14 | unsigned long not_ss; | 15 | unsigned long not_ss; |
@@ -62,6 +63,27 @@ int putreg(struct task_struct *child, int regno, unsigned long value) | |||
62 | return 0; | 63 | return 0; |
63 | } | 64 | } |
64 | 65 | ||
66 | int poke_user(struct task_struct *child, long addr, long data) | ||
67 | { | ||
68 | if ((addr & 3) || addr < 0) | ||
69 | return -EIO; | ||
70 | |||
71 | if (addr < MAX_REG_OFFSET) | ||
72 | return putreg(child, addr, data); | ||
73 | |||
74 | #if 0 /* Need x86_64 debugregs handling */ | ||
75 | else if((addr >= offsetof(struct user, u_debugreg[0])) && | ||
76 | (addr <= offsetof(struct user, u_debugreg[7]))){ | ||
77 | addr -= offsetof(struct user, u_debugreg[0]); | ||
78 | addr = addr >> 2; | ||
79 | if((addr == 4) || (addr == 5)) return -EIO; | ||
80 | child->thread.arch.debugregs[addr] = data; | ||
81 | return 0; | ||
82 | } | ||
83 | #endif | ||
84 | return -EIO; | ||
85 | } | ||
86 | |||
65 | unsigned long getreg(struct task_struct *child, int regno) | 87 | unsigned long getreg(struct task_struct *child, int regno) |
66 | { | 88 | { |
67 | unsigned long retval = ~0UL; | 89 | unsigned long retval = ~0UL; |
@@ -84,6 +106,29 @@ unsigned long getreg(struct task_struct *child, int regno) | |||
84 | return retval; | 106 | return retval; |
85 | } | 107 | } |
86 | 108 | ||
109 | int peek_user(struct task_struct *child, long addr, long data) | ||
110 | { | ||
111 | /* read the word at location addr in the USER area. */ | ||
112 | unsigned long tmp; | ||
113 | |||
114 | if ((addr & 3) || addr < 0) | ||
115 | return -EIO; | ||
116 | |||
117 | tmp = 0; /* Default return condition */ | ||
118 | if(addr < MAX_REG_OFFSET){ | ||
119 | tmp = getreg(child, addr); | ||
120 | } | ||
121 | #if 0 /* Need x86_64 debugregs handling */ | ||
122 | else if((addr >= offsetof(struct user, u_debugreg[0])) && | ||
123 | (addr <= offsetof(struct user, u_debugreg[7]))){ | ||
124 | addr -= offsetof(struct user, u_debugreg[0]); | ||
125 | addr = addr >> 2; | ||
126 | tmp = child->thread.arch.debugregs[addr]; | ||
127 | } | ||
128 | #endif | ||
129 | return put_user(tmp, (unsigned long *) data); | ||
130 | } | ||
131 | |||
87 | void arch_switch(void) | 132 | void arch_switch(void) |
88 | { | 133 | { |
89 | /* XXX | 134 | /* XXX |
diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c index 5bc5a0d796e5..73a7926f7370 100644 --- a/arch/um/sys-x86_64/signal.c +++ b/arch/um/sys-x86_64/signal.c | |||
@@ -57,7 +57,7 @@ static int copy_sc_from_user_skas(struct pt_regs *regs, | |||
57 | int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, | 57 | int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, |
58 | struct pt_regs *regs, unsigned long mask) | 58 | struct pt_regs *regs, unsigned long mask) |
59 | { | 59 | { |
60 | unsigned long eflags; | 60 | struct faultinfo * fi = ¤t->thread.arch.faultinfo; |
61 | int err = 0; | 61 | int err = 0; |
62 | 62 | ||
63 | err |= __put_user(0, &to->gs); | 63 | err |= __put_user(0, &to->gs); |
@@ -84,14 +84,16 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, | |||
84 | err |= PUTREG(regs, R14, to, r14); | 84 | err |= PUTREG(regs, R14, to, r14); |
85 | err |= PUTREG(regs, R15, to, r15); | 85 | err |= PUTREG(regs, R15, to, r15); |
86 | err |= PUTREG(regs, CS, to, cs); /* XXX x86_64 doesn't do this */ | 86 | err |= PUTREG(regs, CS, to, cs); /* XXX x86_64 doesn't do this */ |
87 | err |= __put_user(current->thread.err, &to->err); | 87 | |
88 | err |= __put_user(current->thread.trap_no, &to->trapno); | 88 | err |= __put_user(fi->cr2, &to->cr2); |
89 | err |= __put_user(fi->error_code, &to->err); | ||
90 | err |= __put_user(fi->trap_no, &to->trapno); | ||
91 | |||
89 | err |= PUTREG(regs, RIP, to, rip); | 92 | err |= PUTREG(regs, RIP, to, rip); |
90 | err |= PUTREG(regs, EFLAGS, to, eflags); | 93 | err |= PUTREG(regs, EFLAGS, to, eflags); |
91 | #undef PUTREG | 94 | #undef PUTREG |
92 | 95 | ||
93 | err |= __put_user(mask, &to->oldmask); | 96 | err |= __put_user(mask, &to->oldmask); |
94 | err |= __put_user(current->thread.cr2, &to->cr2); | ||
95 | 97 | ||
96 | return(err); | 98 | return(err); |
97 | } | 99 | } |
@@ -166,7 +168,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, | |||
166 | 168 | ||
167 | frame = (struct rt_sigframe __user *) | 169 | frame = (struct rt_sigframe __user *) |
168 | round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8; | 170 | round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8; |
169 | frame -= 128; | 171 | ((unsigned char *) frame) -= 128; |
170 | 172 | ||
171 | if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) | 173 | if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) |
172 | goto out; | 174 | goto out; |
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c index ab4b0abf8af3..6f44f40204ed 100644 --- a/arch/um/sys-x86_64/syscalls.c +++ b/arch/um/sys-x86_64/syscalls.c | |||
@@ -7,12 +7,15 @@ | |||
7 | #include "linux/linkage.h" | 7 | #include "linux/linkage.h" |
8 | #include "linux/slab.h" | 8 | #include "linux/slab.h" |
9 | #include "linux/shm.h" | 9 | #include "linux/shm.h" |
10 | #include "linux/utsname.h" | ||
11 | #include "linux/personality.h" | ||
10 | #include "asm/uaccess.h" | 12 | #include "asm/uaccess.h" |
11 | #define __FRAME_OFFSETS | 13 | #define __FRAME_OFFSETS |
12 | #include "asm/ptrace.h" | 14 | #include "asm/ptrace.h" |
13 | #include "asm/unistd.h" | 15 | #include "asm/unistd.h" |
14 | #include "asm/prctl.h" /* XXX This should get the constants from libc */ | 16 | #include "asm/prctl.h" /* XXX This should get the constants from libc */ |
15 | #include "choose-mode.h" | 17 | #include "choose-mode.h" |
18 | #include "kern.h" | ||
16 | 19 | ||
17 | asmlinkage long sys_uname64(struct new_utsname __user * name) | 20 | asmlinkage long sys_uname64(struct new_utsname __user * name) |
18 | { | 21 | { |
@@ -42,6 +45,8 @@ long sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount) | |||
42 | #ifdef CONFIG_MODE_SKAS | 45 | #ifdef CONFIG_MODE_SKAS |
43 | extern int userspace_pid[]; | 46 | extern int userspace_pid[]; |
44 | 47 | ||
48 | #include "skas_ptrace.h" | ||
49 | |||
45 | long sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount) | 50 | long sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount) |
46 | { | 51 | { |
47 | struct ptrace_ldt ldt; | 52 | struct ptrace_ldt ldt; |
@@ -128,23 +133,27 @@ static long arch_prctl_tt(int code, unsigned long addr) | |||
128 | 133 | ||
129 | #ifdef CONFIG_MODE_SKAS | 134 | #ifdef CONFIG_MODE_SKAS |
130 | 135 | ||
136 | /* XXX: Must also call arch_prctl in the host, beside saving the segment bases! */ | ||
131 | static long arch_prctl_skas(int code, unsigned long addr) | 137 | static long arch_prctl_skas(int code, unsigned long addr) |
132 | { | 138 | { |
133 | long ret = 0; | 139 | long ret = 0; |
134 | 140 | ||
135 | switch(code){ | 141 | switch(code){ |
136 | case ARCH_SET_GS: | ||
137 | current->thread.regs.regs.skas.regs[GS_BASE / sizeof(unsigned long)] = addr; | ||
138 | break; | ||
139 | case ARCH_SET_FS: | 142 | case ARCH_SET_FS: |
140 | current->thread.regs.regs.skas.regs[FS_BASE / sizeof(unsigned long)] = addr; | 143 | current->thread.regs.regs.skas.regs[FS_BASE / sizeof(unsigned long)] = addr; |
141 | break; | 144 | break; |
145 | case ARCH_SET_GS: | ||
146 | current->thread.regs.regs.skas.regs[GS_BASE / sizeof(unsigned long)] = addr; | ||
147 | break; | ||
142 | case ARCH_GET_FS: | 148 | case ARCH_GET_FS: |
143 | ret = put_user(current->thread.regs.regs.skas.regs[GS / sizeof(unsigned long)], &addr); | 149 | ret = put_user(current->thread.regs.regs.skas. |
150 | regs[FS_BASE / sizeof(unsigned long)], | ||
151 | (unsigned long __user *)addr); | ||
144 | break; | 152 | break; |
145 | case ARCH_GET_GS: | 153 | case ARCH_GET_GS: |
146 | ret = put_user(current->thread.regs.regs.skas.regs[FS / sizeof(unsigned \ | 154 | ret = put_user(current->thread.regs.regs.skas. |
147 | long)], &addr); | 155 | regs[GS_BASE / sizeof(unsigned long)], |
156 | (unsigned long __user *)addr); | ||
148 | break; | 157 | break; |
149 | default: | 158 | default: |
150 | ret = -EINVAL; | 159 | ret = -EINVAL; |
diff --git a/arch/um/sys-x86_64/sysrq.c b/arch/um/sys-x86_64/sysrq.c index ddf74691a610..d0a25af19a5b 100644 --- a/arch/um/sys-x86_64/sysrq.c +++ b/arch/um/sys-x86_64/sysrq.c | |||
@@ -36,14 +36,5 @@ void __show_regs(struct pt_regs * regs) | |||
36 | void show_regs(struct pt_regs *regs) | 36 | void show_regs(struct pt_regs *regs) |
37 | { | 37 | { |
38 | __show_regs(regs); | 38 | __show_regs(regs); |
39 | show_trace((unsigned long *) ®s); | 39 | show_trace(current, (unsigned long *) ®s); |
40 | } | 40 | } |
41 | |||
42 | /* Emacs will notice this stuff at the end of the file and automatically | ||
43 | * adjust the settings for this buffer only. This must remain at the end | ||
44 | * of the file. | ||
45 | * --------------------------------------------------------------------------- | ||
46 | * Local variables: | ||
47 | * c-file-style: "linux" | ||
48 | * End: | ||
49 | */ | ||
diff --git a/arch/um/sys-x86_64/um_module.c b/arch/um/sys-x86_64/um_module.c new file mode 100644 index 000000000000..8b8eff1bd977 --- /dev/null +++ b/arch/um/sys-x86_64/um_module.c | |||
@@ -0,0 +1,19 @@ | |||
1 | #include <linux/vmalloc.h> | ||
2 | #include <linux/moduleloader.h> | ||
3 | |||
4 | /*Copied from i386 arch/i386/kernel/module.c */ | ||
5 | void *module_alloc(unsigned long size) | ||
6 | { | ||
7 | if (size == 0) | ||
8 | return NULL; | ||
9 | return vmalloc_exec(size); | ||
10 | } | ||
11 | |||
12 | /* Free memory returned from module_alloc */ | ||
13 | void module_free(struct module *mod, void *module_region) | ||
14 | { | ||
15 | vfree(module_region); | ||
16 | /* FIXME: If module_region == mod->init_region, trim exception | ||
17 | table entries. */ | ||
18 | } | ||
19 | |||
diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c new file mode 100644 index 000000000000..513d17ceafd4 --- /dev/null +++ b/arch/um/sys-x86_64/user-offsets.c | |||
@@ -0,0 +1,86 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stddef.h> | ||
3 | #include <signal.h> | ||
4 | #define __FRAME_OFFSETS | ||
5 | #include <asm/ptrace.h> | ||
6 | #include <asm/types.h> | ||
7 | /* For some reason, x86_64 defines u64 and u32 only in <pci/types.h>, which I | ||
8 | * refuse to include here, even though they're used throughout the headers. | ||
9 | * These are used in asm/user.h, and that include can't be avoided because of | ||
10 | * the sizeof(struct user_regs_struct) below. | ||
11 | */ | ||
12 | typedef __u64 u64; | ||
13 | typedef __u32 u32; | ||
14 | #include <asm/user.h> | ||
15 | |||
16 | #define DEFINE(sym, val) \ | ||
17 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) | ||
18 | |||
19 | #define OFFSET(sym, str, mem) \ | ||
20 | DEFINE(sym, offsetof(struct str, mem)); | ||
21 | |||
22 | void foo(void) | ||
23 | { | ||
24 | OFFSET(SC_RBX, sigcontext, rbx); | ||
25 | OFFSET(SC_RCX, sigcontext, rcx); | ||
26 | OFFSET(SC_RDX, sigcontext, rdx); | ||
27 | OFFSET(SC_RSI, sigcontext, rsi); | ||
28 | OFFSET(SC_RDI, sigcontext, rdi); | ||
29 | OFFSET(SC_RBP, sigcontext, rbp); | ||
30 | OFFSET(SC_RAX, sigcontext, rax); | ||
31 | OFFSET(SC_R8, sigcontext, r8); | ||
32 | OFFSET(SC_R9, sigcontext, r9); | ||
33 | OFFSET(SC_R10, sigcontext, r10); | ||
34 | OFFSET(SC_R11, sigcontext, r11); | ||
35 | OFFSET(SC_R12, sigcontext, r12); | ||
36 | OFFSET(SC_R13, sigcontext, r13); | ||
37 | OFFSET(SC_R14, sigcontext, r14); | ||
38 | OFFSET(SC_R15, sigcontext, r15); | ||
39 | OFFSET(SC_IP, sigcontext, rip); | ||
40 | OFFSET(SC_SP, sigcontext, rsp); | ||
41 | OFFSET(SC_CR2, sigcontext, cr2); | ||
42 | OFFSET(SC_ERR, sigcontext, err); | ||
43 | OFFSET(SC_TRAPNO, sigcontext, trapno); | ||
44 | OFFSET(SC_CS, sigcontext, cs); | ||
45 | OFFSET(SC_FS, sigcontext, fs); | ||
46 | OFFSET(SC_GS, sigcontext, gs); | ||
47 | OFFSET(SC_EFLAGS, sigcontext, eflags); | ||
48 | OFFSET(SC_SIGMASK, sigcontext, oldmask); | ||
49 | #if 0 | ||
50 | OFFSET(SC_ORIG_RAX, sigcontext, orig_rax); | ||
51 | OFFSET(SC_DS, sigcontext, ds); | ||
52 | OFFSET(SC_ES, sigcontext, es); | ||
53 | OFFSET(SC_SS, sigcontext, ss); | ||
54 | #endif | ||
55 | |||
56 | DEFINE(HOST_FRAME_SIZE, FRAME_SIZE); | ||
57 | DEFINE(HOST_RBX, RBX); | ||
58 | DEFINE(HOST_RCX, RCX); | ||
59 | DEFINE(HOST_RDI, RDI); | ||
60 | DEFINE(HOST_RSI, RSI); | ||
61 | DEFINE(HOST_RDX, RDX); | ||
62 | DEFINE(HOST_RBP, RBP); | ||
63 | DEFINE(HOST_RAX, RAX); | ||
64 | DEFINE(HOST_R8, R8); | ||
65 | DEFINE(HOST_R9, R9); | ||
66 | DEFINE(HOST_R10, R10); | ||
67 | DEFINE(HOST_R11, R11); | ||
68 | DEFINE(HOST_R12, R12); | ||
69 | DEFINE(HOST_R13, R13); | ||
70 | DEFINE(HOST_R14, R14); | ||
71 | DEFINE(HOST_R15, R15); | ||
72 | DEFINE(HOST_ORIG_RAX, ORIG_RAX); | ||
73 | DEFINE(HOST_CS, CS); | ||
74 | DEFINE(HOST_SS, SS); | ||
75 | DEFINE(HOST_EFLAGS, EFLAGS); | ||
76 | #if 0 | ||
77 | DEFINE(HOST_FS, FS); | ||
78 | DEFINE(HOST_GS, GS); | ||
79 | DEFINE(HOST_DS, DS); | ||
80 | DEFINE(HOST_ES, ES); | ||
81 | #endif | ||
82 | |||
83 | DEFINE(HOST_IP, RIP); | ||
84 | DEFINE(HOST_SP, RSP); | ||
85 | DEFINE(__UM_FRAME_SIZE, sizeof(struct user_regs_struct)); | ||
86 | } | ||
diff --git a/arch/um/sys-x86_64/util/Makefile b/arch/um/sys-x86_64/util/Makefile index 002607980864..75b052cfc206 100644 --- a/arch/um/sys-x86_64/util/Makefile +++ b/arch/um/sys-x86_64/util/Makefile | |||
@@ -4,7 +4,5 @@ | |||
4 | hostprogs-y := mk_sc mk_thread | 4 | hostprogs-y := mk_sc mk_thread |
5 | always := $(hostprogs-y) | 5 | always := $(hostprogs-y) |
6 | 6 | ||
7 | mk_thread-objs := mk_thread_kern.o mk_thread_user.o | 7 | HOSTCFLAGS_mk_sc.o := -I$(objtree)/arch/um |
8 | 8 | HOSTCFLAGS_mk_thread.o := -I$(objtree)/arch/um | |
9 | HOSTCFLAGS_mk_thread_kern.o := $(CFLAGS) $(CPPFLAGS) | ||
10 | HOSTCFLAGS_mk_thread_user.o := $(USER_CFLAGS) | ||
diff --git a/arch/um/sys-x86_64/util/mk_sc.c b/arch/um/sys-x86_64/util/mk_sc.c index c236e213918d..7619bc377c1f 100644 --- a/arch/um/sys-x86_64/util/mk_sc.c +++ b/arch/um/sys-x86_64/util/mk_sc.c | |||
@@ -3,56 +3,45 @@ | |||
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <stdio.h> | 5 | #include <stdio.h> |
6 | #include <signal.h> | 6 | #include <user-offsets.h> |
7 | #include <linux/stddef.h> | ||
8 | 7 | ||
9 | #define SC_OFFSET(name, field) \ | 8 | #define SC_OFFSET(name) \ |
10 | printf("#define " name \ | 9 | printf("#define " #name \ |
11 | "(sc) *((unsigned long *) &(((char *) (sc))[%ld]))\n",\ | 10 | "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\ |
12 | offsetof(struct sigcontext, field)) | 11 | name) |
13 | |||
14 | #define SC_FP_OFFSET(name, field) \ | ||
15 | printf("#define " name \ | ||
16 | "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%ld]))\n",\ | ||
17 | offsetof(struct _fpstate, field)) | ||
18 | |||
19 | #define SC_FP_OFFSET_PTR(name, field, type) \ | ||
20 | printf("#define " name \ | ||
21 | "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\ | ||
22 | offsetof(struct _fpstate, field)) | ||
23 | 12 | ||
24 | int main(int argc, char **argv) | 13 | int main(int argc, char **argv) |
25 | { | 14 | { |
26 | SC_OFFSET("SC_RBX", rbx); | 15 | SC_OFFSET(SC_RBX); |
27 | SC_OFFSET("SC_RCX", rcx); | 16 | SC_OFFSET(SC_RCX); |
28 | SC_OFFSET("SC_RDX", rdx); | 17 | SC_OFFSET(SC_RDX); |
29 | SC_OFFSET("SC_RSI", rsi); | 18 | SC_OFFSET(SC_RSI); |
30 | SC_OFFSET("SC_RDI", rdi); | 19 | SC_OFFSET(SC_RDI); |
31 | SC_OFFSET("SC_RBP", rbp); | 20 | SC_OFFSET(SC_RBP); |
32 | SC_OFFSET("SC_RAX", rax); | 21 | SC_OFFSET(SC_RAX); |
33 | SC_OFFSET("SC_R8", r8); | 22 | SC_OFFSET(SC_R8); |
34 | SC_OFFSET("SC_R9", r9); | 23 | SC_OFFSET(SC_R9); |
35 | SC_OFFSET("SC_R10", r10); | 24 | SC_OFFSET(SC_R10); |
36 | SC_OFFSET("SC_R11", r11); | 25 | SC_OFFSET(SC_R11); |
37 | SC_OFFSET("SC_R12", r12); | 26 | SC_OFFSET(SC_R12); |
38 | SC_OFFSET("SC_R13", r13); | 27 | SC_OFFSET(SC_R13); |
39 | SC_OFFSET("SC_R14", r14); | 28 | SC_OFFSET(SC_R14); |
40 | SC_OFFSET("SC_R15", r15); | 29 | SC_OFFSET(SC_R15); |
41 | SC_OFFSET("SC_IP", rip); | 30 | SC_OFFSET(SC_IP); |
42 | SC_OFFSET("SC_SP", rsp); | 31 | SC_OFFSET(SC_SP); |
43 | SC_OFFSET("SC_CR2", cr2); | 32 | SC_OFFSET(SC_CR2); |
44 | SC_OFFSET("SC_ERR", err); | 33 | SC_OFFSET(SC_ERR); |
45 | SC_OFFSET("SC_TRAPNO", trapno); | 34 | SC_OFFSET(SC_TRAPNO); |
46 | SC_OFFSET("SC_CS", cs); | 35 | SC_OFFSET(SC_CS); |
47 | SC_OFFSET("SC_FS", fs); | 36 | SC_OFFSET(SC_FS); |
48 | SC_OFFSET("SC_GS", gs); | 37 | SC_OFFSET(SC_GS); |
49 | SC_OFFSET("SC_EFLAGS", eflags); | 38 | SC_OFFSET(SC_EFLAGS); |
50 | SC_OFFSET("SC_SIGMASK", oldmask); | 39 | SC_OFFSET(SC_SIGMASK); |
51 | #if 0 | 40 | #if 0 |
52 | SC_OFFSET("SC_ORIG_RAX", orig_rax); | 41 | SC_OFFSET(SC_ORIG_RAX); |
53 | SC_OFFSET("SC_DS", ds); | 42 | SC_OFFSET(SC_DS); |
54 | SC_OFFSET("SC_ES", es); | 43 | SC_OFFSET(SC_ES); |
55 | SC_OFFSET("SC_SS", ss); | 44 | SC_OFFSET(SC_SS); |
56 | #endif | 45 | #endif |
57 | return(0); | 46 | return(0); |
58 | } | 47 | } |
diff --git a/arch/um/sys-x86_64/util/mk_thread.c b/arch/um/sys-x86_64/util/mk_thread.c new file mode 100644 index 000000000000..15517396e9cf --- /dev/null +++ b/arch/um/sys-x86_64/util/mk_thread.c | |||
@@ -0,0 +1,20 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <kernel-offsets.h> | ||
3 | |||
4 | int main(int argc, char **argv) | ||
5 | { | ||
6 | printf("/*\n"); | ||
7 | printf(" * Generated by mk_thread\n"); | ||
8 | printf(" */\n"); | ||
9 | printf("\n"); | ||
10 | printf("#ifndef __UM_THREAD_H\n"); | ||
11 | printf("#define __UM_THREAD_H\n"); | ||
12 | printf("\n"); | ||
13 | #ifdef TASK_EXTERN_PID | ||
14 | printf("#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[%d]))\n", | ||
15 | TASK_EXTERN_PID); | ||
16 | #endif | ||
17 | printf("\n"); | ||
18 | printf("#endif\n"); | ||
19 | return(0); | ||
20 | } | ||
diff --git a/arch/um/sys-x86_64/util/mk_thread_kern.c b/arch/um/sys-x86_64/util/mk_thread_kern.c deleted file mode 100644 index a281673f02b2..000000000000 --- a/arch/um/sys-x86_64/util/mk_thread_kern.c +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | #include "linux/config.h" | ||
2 | #include "linux/stddef.h" | ||
3 | #include "linux/sched.h" | ||
4 | |||
5 | extern void print_head(void); | ||
6 | extern void print_constant_ptr(char *name, int value); | ||
7 | extern void print_constant(char *name, char *type, int value); | ||
8 | extern void print_tail(void); | ||
9 | |||
10 | #define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field) | ||
11 | |||
12 | int main(int argc, char **argv) | ||
13 | { | ||
14 | print_head(); | ||
15 | #ifdef CONFIG_MODE_TT | ||
16 | print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid)); | ||
17 | #endif | ||
18 | print_tail(); | ||
19 | return(0); | ||
20 | } | ||
21 | |||
diff --git a/arch/um/sys-x86_64/util/mk_thread_user.c b/arch/um/sys-x86_64/util/mk_thread_user.c deleted file mode 100644 index 7989725568b8..000000000000 --- a/arch/um/sys-x86_64/util/mk_thread_user.c +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | #include <stdio.h> | ||
2 | |||
3 | void print_head(void) | ||
4 | { | ||
5 | printf("/*\n"); | ||
6 | printf(" * Generated by mk_thread\n"); | ||
7 | printf(" */\n"); | ||
8 | printf("\n"); | ||
9 | printf("#ifndef __UM_THREAD_H\n"); | ||
10 | printf("#define __UM_THREAD_H\n"); | ||
11 | printf("\n"); | ||
12 | } | ||
13 | |||
14 | void print_constant_ptr(char *name, int value) | ||
15 | { | ||
16 | printf("#define %s(task) ((unsigned long *) " | ||
17 | "&(((char *) (task))[%d]))\n", name, value); | ||
18 | } | ||
19 | |||
20 | void print_constant(char *name, char *type, int value) | ||
21 | { | ||
22 | printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type, | ||
23 | value); | ||
24 | } | ||
25 | |||
26 | void print_tail(void) | ||
27 | { | ||
28 | printf("\n"); | ||
29 | printf("#endif\n"); | ||
30 | } | ||
diff --git a/arch/um/util/Makefile b/arch/um/util/Makefile index e2ab71209f3f..4c7551c28033 100644 --- a/arch/um/util/Makefile +++ b/arch/um/util/Makefile | |||
@@ -1,8 +1,5 @@ | |||
1 | hostprogs-y := mk_task mk_constants | 1 | hostprogs-y := mk_task mk_constants |
2 | always := $(hostprogs-y) | 2 | always := $(hostprogs-y) |
3 | 3 | ||
4 | mk_task-objs := mk_task_user.o mk_task_kern.o | 4 | HOSTCFLAGS_mk_task.o := -I$(objtree)/arch/um |
5 | mk_constants-objs := mk_constants_user.o mk_constants_kern.o | 5 | HOSTCFLAGS_mk_constants.o := -I$(objtree)/arch/um |
6 | |||
7 | HOSTCFLAGS_mk_task_kern.o := $(CFLAGS) $(CPPFLAGS) | ||
8 | HOSTCFLAGS_mk_constants_kern.o := $(CFLAGS) $(CPPFLAGS) | ||
diff --git a/arch/um/util/mk_constants.c b/arch/um/util/mk_constants.c new file mode 100644 index 000000000000..ab217becc36a --- /dev/null +++ b/arch/um/util/mk_constants.c | |||
@@ -0,0 +1,32 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <kernel-offsets.h> | ||
3 | |||
4 | #define SHOW_INT(sym) printf("#define %s %d\n", #sym, sym) | ||
5 | #define SHOW_STR(sym) printf("#define %s %s\n", #sym, sym) | ||
6 | |||
7 | int main(int argc, char **argv) | ||
8 | { | ||
9 | printf("/*\n"); | ||
10 | printf(" * Generated by mk_constants\n"); | ||
11 | printf(" */\n"); | ||
12 | printf("\n"); | ||
13 | printf("#ifndef __UM_CONSTANTS_H\n"); | ||
14 | printf("#define __UM_CONSTANTS_H\n"); | ||
15 | printf("\n"); | ||
16 | |||
17 | SHOW_INT(UM_KERN_PAGE_SIZE); | ||
18 | |||
19 | SHOW_STR(UM_KERN_EMERG); | ||
20 | SHOW_STR(UM_KERN_ALERT); | ||
21 | SHOW_STR(UM_KERN_CRIT); | ||
22 | SHOW_STR(UM_KERN_ERR); | ||
23 | SHOW_STR(UM_KERN_WARNING); | ||
24 | SHOW_STR(UM_KERN_NOTICE); | ||
25 | SHOW_STR(UM_KERN_INFO); | ||
26 | SHOW_STR(UM_KERN_DEBUG); | ||
27 | |||
28 | SHOW_INT(UM_NSEC_PER_SEC); | ||
29 | printf("\n"); | ||
30 | printf("#endif\n"); | ||
31 | return(0); | ||
32 | } | ||
diff --git a/arch/um/util/mk_constants_kern.c b/arch/um/util/mk_constants_kern.c deleted file mode 100644 index cdcb1232a1ea..000000000000 --- a/arch/um/util/mk_constants_kern.c +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | #include "linux/kernel.h" | ||
2 | #include "linux/stringify.h" | ||
3 | #include "linux/time.h" | ||
4 | #include "asm/page.h" | ||
5 | |||
6 | extern void print_head(void); | ||
7 | extern void print_constant_str(char *name, char *value); | ||
8 | extern void print_constant_int(char *name, int value); | ||
9 | extern void print_tail(void); | ||
10 | |||
11 | int main(int argc, char **argv) | ||
12 | { | ||
13 | print_head(); | ||
14 | print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE); | ||
15 | |||
16 | print_constant_str("UM_KERN_EMERG", KERN_EMERG); | ||
17 | print_constant_str("UM_KERN_ALERT", KERN_ALERT); | ||
18 | print_constant_str("UM_KERN_CRIT", KERN_CRIT); | ||
19 | print_constant_str("UM_KERN_ERR", KERN_ERR); | ||
20 | print_constant_str("UM_KERN_WARNING", KERN_WARNING); | ||
21 | print_constant_str("UM_KERN_NOTICE", KERN_NOTICE); | ||
22 | print_constant_str("UM_KERN_INFO", KERN_INFO); | ||
23 | print_constant_str("UM_KERN_DEBUG", KERN_DEBUG); | ||
24 | |||
25 | print_constant_int("UM_NSEC_PER_SEC", NSEC_PER_SEC); | ||
26 | print_tail(); | ||
27 | return(0); | ||
28 | } | ||
diff --git a/arch/um/util/mk_constants_user.c b/arch/um/util/mk_constants_user.c deleted file mode 100644 index 8f4d7e50be7c..000000000000 --- a/arch/um/util/mk_constants_user.c +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | #include <stdio.h> | ||
2 | |||
3 | void print_head(void) | ||
4 | { | ||
5 | printf("/*\n"); | ||
6 | printf(" * Generated by mk_constants\n"); | ||
7 | printf(" */\n"); | ||
8 | printf("\n"); | ||
9 | printf("#ifndef __UM_CONSTANTS_H\n"); | ||
10 | printf("#define __UM_CONSTANTS_H\n"); | ||
11 | printf("\n"); | ||
12 | } | ||
13 | |||
14 | void print_constant_str(char *name, char *value) | ||
15 | { | ||
16 | printf("#define %s \"%s\"\n", name, value); | ||
17 | } | ||
18 | |||
19 | void print_constant_int(char *name, int value) | ||
20 | { | ||
21 | printf("#define %s %d\n", name, value); | ||
22 | } | ||
23 | |||
24 | void print_tail(void) | ||
25 | { | ||
26 | printf("\n"); | ||
27 | printf("#endif\n"); | ||
28 | } | ||
diff --git a/arch/um/util/mk_task_user.c b/arch/um/util/mk_task.c index 9db849f3f3ac..36c9606505e2 100644 --- a/arch/um/util/mk_task_user.c +++ b/arch/um/util/mk_task.c | |||
@@ -1,18 +1,19 @@ | |||
1 | #include <stdio.h> | 1 | #include <stdio.h> |
2 | #include <kernel-offsets.h> | ||
2 | 3 | ||
3 | void print(char *name, char *type, int offset) | 4 | void print_ptr(char *name, char *type, int offset) |
4 | { | 5 | { |
5 | printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type, | 6 | printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type, |
6 | offset); | 7 | offset); |
7 | } | 8 | } |
8 | 9 | ||
9 | void print_ptr(char *name, char *type, int offset) | 10 | void print(char *name, char *type, int offset) |
10 | { | 11 | { |
11 | printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type, | 12 | printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type, |
12 | offset); | 13 | offset); |
13 | } | 14 | } |
14 | 15 | ||
15 | void print_head(void) | 16 | int main(int argc, char **argv) |
16 | { | 17 | { |
17 | printf("/*\n"); | 18 | printf("/*\n"); |
18 | printf(" * Generated by mk_task\n"); | 19 | printf(" * Generated by mk_task\n"); |
@@ -21,10 +22,9 @@ void print_head(void) | |||
21 | printf("#ifndef __TASK_H\n"); | 22 | printf("#ifndef __TASK_H\n"); |
22 | printf("#define __TASK_H\n"); | 23 | printf("#define __TASK_H\n"); |
23 | printf("\n"); | 24 | printf("\n"); |
24 | } | 25 | print_ptr("TASK_REGS", "union uml_pt_regs", TASK_REGS); |
25 | 26 | print("TASK_PID", "int", TASK_PID); | |
26 | void print_tail(void) | ||
27 | { | ||
28 | printf("\n"); | 27 | printf("\n"); |
29 | printf("#endif\n"); | 28 | printf("#endif\n"); |
29 | return(0); | ||
30 | } | 30 | } |
diff --git a/arch/um/util/mk_task_kern.c b/arch/um/util/mk_task_kern.c deleted file mode 100644 index c218103315ed..000000000000 --- a/arch/um/util/mk_task_kern.c +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | #include "linux/sched.h" | ||
2 | #include "linux/stddef.h" | ||
3 | |||
4 | extern void print(char *name, char *type, int offset); | ||
5 | extern void print_ptr(char *name, char *type, int offset); | ||
6 | extern void print_head(void); | ||
7 | extern void print_tail(void); | ||
8 | |||
9 | int main(int argc, char **argv) | ||
10 | { | ||
11 | print_head(); | ||
12 | print_ptr("TASK_REGS", "union uml_pt_regs", | ||
13 | offsetof(struct task_struct, thread.regs)); | ||
14 | print("TASK_PID", "int", offsetof(struct task_struct, pid)); | ||
15 | print_tail(); | ||
16 | return(0); | ||
17 | } | ||
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 80c38c5d71fe..289f448ac89c 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig | |||
@@ -303,6 +303,21 @@ config HPET_TIMER | |||
303 | as it is off-chip. You can find the HPET spec at | 303 | as it is off-chip. You can find the HPET spec at |
304 | <http://www.intel.com/labs/platcomp/hpet/hpetspec.htm>. | 304 | <http://www.intel.com/labs/platcomp/hpet/hpetspec.htm>. |
305 | 305 | ||
306 | config X86_PM_TIMER | ||
307 | bool "PM timer" | ||
308 | depends on ACPI | ||
309 | default y | ||
310 | help | ||
311 | Support the ACPI PM timer for time keeping. This is slow, | ||
312 | but is useful on some chipsets without HPET on systems with more | ||
313 | than one CPU. On a single processor or single socket multi core | ||
314 | system it is normally not required. | ||
315 | When the PM timer is active 64bit vsyscalls are disabled | ||
316 | and should not be enabled (/proc/sys/kernel/vsyscall64 should | ||
317 | not be changed). | ||
318 | The kernel selects the PM timer only as a last resort, so it is | ||
319 | useful to enable just in case. | ||
320 | |||
306 | config HPET_EMULATE_RTC | 321 | config HPET_EMULATE_RTC |
307 | bool "Provide RTC interrupt" | 322 | bool "Provide RTC interrupt" |
308 | depends on HPET_TIMER && RTC=y | 323 | depends on HPET_TIMER && RTC=y |
@@ -379,6 +394,11 @@ config GENERIC_IRQ_PROBE | |||
379 | bool | 394 | bool |
380 | default y | 395 | default y |
381 | 396 | ||
397 | # we have no ISA slots, but we do have ISA-style DMA. | ||
398 | config ISA_DMA_API | ||
399 | bool | ||
400 | default y | ||
401 | |||
382 | menu "Power management options" | 402 | menu "Power management options" |
383 | 403 | ||
384 | source kernel/power/Kconfig | 404 | source kernel/power/Kconfig |
@@ -402,7 +422,7 @@ config PCI_DIRECT | |||
402 | 422 | ||
403 | config PCI_MMCONFIG | 423 | config PCI_MMCONFIG |
404 | bool "Support mmconfig PCI config space access" | 424 | bool "Support mmconfig PCI config space access" |
405 | depends on PCI | 425 | depends on PCI && ACPI |
406 | select ACPI_BOOT | 426 | select ACPI_BOOT |
407 | 427 | ||
408 | config UNORDERED_IO | 428 | config UNORDERED_IO |
diff --git a/arch/x86_64/boot/bootsect.S b/arch/x86_64/boot/bootsect.S index bb15d406ee95..011b7a4993d4 100644 --- a/arch/x86_64/boot/bootsect.S +++ b/arch/x86_64/boot/bootsect.S | |||
@@ -63,7 +63,7 @@ msg_loop: | |||
63 | jz die | 63 | jz die |
64 | movb $0xe, %ah | 64 | movb $0xe, %ah |
65 | movw $7, %bx | 65 | movw $7, %bx |
66 | int $0x10 | 66 | int $0x10 |
67 | jmp msg_loop | 67 | jmp msg_loop |
68 | 68 | ||
69 | die: | 69 | die: |
@@ -71,7 +71,7 @@ die: | |||
71 | xorw %ax, %ax | 71 | xorw %ax, %ax |
72 | int $0x16 | 72 | int $0x16 |
73 | int $0x19 | 73 | int $0x19 |
74 | 74 | ||
75 | # int 0x19 should never return. In case it does anyway, | 75 | # int 0x19 should never return. In case it does anyway, |
76 | # invoke the BIOS reset code... | 76 | # invoke the BIOS reset code... |
77 | ljmp $0xf000,$0xfff0 | 77 | ljmp $0xf000,$0xfff0 |
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig index 9ce51dee30b3..569595b74c7c 100644 --- a/arch/x86_64/defconfig +++ b/arch/x86_64/defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.11-bk7 | 3 | # Linux kernel version: 2.6.12-rc4 |
4 | # Sat Mar 12 23:43:44 2005 | 4 | # Fri May 13 06:39:11 2005 |
5 | # | 5 | # |
6 | CONFIG_X86_64=y | 6 | CONFIG_X86_64=y |
7 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
@@ -11,8 +11,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y | |||
11 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 11 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
12 | CONFIG_X86_CMPXCHG=y | 12 | CONFIG_X86_CMPXCHG=y |
13 | CONFIG_EARLY_PRINTK=y | 13 | CONFIG_EARLY_PRINTK=y |
14 | CONFIG_HPET_TIMER=y | ||
15 | CONFIG_HPET_EMULATE_RTC=y | ||
16 | CONFIG_GENERIC_ISA_DMA=y | 14 | CONFIG_GENERIC_ISA_DMA=y |
17 | CONFIG_GENERIC_IOMAP=y | 15 | CONFIG_GENERIC_IOMAP=y |
18 | 16 | ||
@@ -22,6 +20,7 @@ CONFIG_GENERIC_IOMAP=y | |||
22 | CONFIG_EXPERIMENTAL=y | 20 | CONFIG_EXPERIMENTAL=y |
23 | CONFIG_CLEAN_COMPILE=y | 21 | CONFIG_CLEAN_COMPILE=y |
24 | CONFIG_LOCK_KERNEL=y | 22 | CONFIG_LOCK_KERNEL=y |
23 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
25 | 24 | ||
26 | # | 25 | # |
27 | # General setup | 26 | # General setup |
@@ -33,7 +32,6 @@ CONFIG_POSIX_MQUEUE=y | |||
33 | # CONFIG_BSD_PROCESS_ACCT is not set | 32 | # CONFIG_BSD_PROCESS_ACCT is not set |
34 | CONFIG_SYSCTL=y | 33 | CONFIG_SYSCTL=y |
35 | # CONFIG_AUDIT is not set | 34 | # CONFIG_AUDIT is not set |
36 | CONFIG_LOG_BUF_SHIFT=18 | ||
37 | # CONFIG_HOTPLUG is not set | 35 | # CONFIG_HOTPLUG is not set |
38 | CONFIG_KOBJECT_UEVENT=y | 36 | CONFIG_KOBJECT_UEVENT=y |
39 | CONFIG_IKCONFIG=y | 37 | CONFIG_IKCONFIG=y |
@@ -43,10 +41,11 @@ CONFIG_IKCONFIG_PROC=y | |||
43 | CONFIG_KALLSYMS=y | 41 | CONFIG_KALLSYMS=y |
44 | CONFIG_KALLSYMS_ALL=y | 42 | CONFIG_KALLSYMS_ALL=y |
45 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 43 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
44 | CONFIG_PRINTK=y | ||
45 | CONFIG_BUG=y | ||
46 | CONFIG_BASE_FULL=y | 46 | CONFIG_BASE_FULL=y |
47 | CONFIG_FUTEX=y | 47 | CONFIG_FUTEX=y |
48 | CONFIG_EPOLL=y | 48 | CONFIG_EPOLL=y |
49 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
50 | CONFIG_SHMEM=y | 49 | CONFIG_SHMEM=y |
51 | CONFIG_CC_ALIGN_FUNCTIONS=0 | 50 | CONFIG_CC_ALIGN_FUNCTIONS=0 |
52 | CONFIG_CC_ALIGN_LABELS=0 | 51 | CONFIG_CC_ALIGN_LABELS=0 |
@@ -93,6 +92,9 @@ CONFIG_DISCONTIGMEM=y | |||
93 | CONFIG_NUMA=y | 92 | CONFIG_NUMA=y |
94 | CONFIG_HAVE_DEC_LOCK=y | 93 | CONFIG_HAVE_DEC_LOCK=y |
95 | CONFIG_NR_CPUS=8 | 94 | CONFIG_NR_CPUS=8 |
95 | CONFIG_HPET_TIMER=y | ||
96 | CONFIG_X86_PM_TIMER=y | ||
97 | CONFIG_HPET_EMULATE_RTC=y | ||
96 | CONFIG_GART_IOMMU=y | 98 | CONFIG_GART_IOMMU=y |
97 | CONFIG_SWIOTLB=y | 99 | CONFIG_SWIOTLB=y |
98 | CONFIG_X86_MCE=y | 100 | CONFIG_X86_MCE=y |
@@ -100,6 +102,7 @@ CONFIG_X86_MCE_INTEL=y | |||
100 | CONFIG_SECCOMP=y | 102 | CONFIG_SECCOMP=y |
101 | CONFIG_GENERIC_HARDIRQS=y | 103 | CONFIG_GENERIC_HARDIRQS=y |
102 | CONFIG_GENERIC_IRQ_PROBE=y | 104 | CONFIG_GENERIC_IRQ_PROBE=y |
105 | CONFIG_ISA_DMA_API=y | ||
103 | 106 | ||
104 | # | 107 | # |
105 | # Power management options | 108 | # Power management options |
@@ -129,7 +132,7 @@ CONFIG_ACPI_NUMA=y | |||
129 | # CONFIG_ACPI_IBM is not set | 132 | # CONFIG_ACPI_IBM is not set |
130 | CONFIG_ACPI_TOSHIBA=y | 133 | CONFIG_ACPI_TOSHIBA=y |
131 | CONFIG_ACPI_BLACKLIST_YEAR=2001 | 134 | CONFIG_ACPI_BLACKLIST_YEAR=2001 |
132 | CONFIG_ACPI_DEBUG=y | 135 | # CONFIG_ACPI_DEBUG is not set |
133 | CONFIG_ACPI_BUS=y | 136 | CONFIG_ACPI_BUS=y |
134 | CONFIG_ACPI_EC=y | 137 | CONFIG_ACPI_EC=y |
135 | CONFIG_ACPI_POWER=y | 138 | CONFIG_ACPI_POWER=y |
@@ -141,6 +144,7 @@ CONFIG_ACPI_SYSTEM=y | |||
141 | # CPU Frequency scaling | 144 | # CPU Frequency scaling |
142 | # | 145 | # |
143 | CONFIG_CPU_FREQ=y | 146 | CONFIG_CPU_FREQ=y |
147 | CONFIG_CPU_FREQ_TABLE=y | ||
144 | # CONFIG_CPU_FREQ_DEBUG is not set | 148 | # CONFIG_CPU_FREQ_DEBUG is not set |
145 | CONFIG_CPU_FREQ_STAT=y | 149 | CONFIG_CPU_FREQ_STAT=y |
146 | # CONFIG_CPU_FREQ_STAT_DETAILS is not set | 150 | # CONFIG_CPU_FREQ_STAT_DETAILS is not set |
@@ -150,7 +154,6 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y | |||
150 | # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set | 154 | # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set |
151 | CONFIG_CPU_FREQ_GOV_USERSPACE=y | 155 | CONFIG_CPU_FREQ_GOV_USERSPACE=y |
152 | CONFIG_CPU_FREQ_GOV_ONDEMAND=y | 156 | CONFIG_CPU_FREQ_GOV_ONDEMAND=y |
153 | CONFIG_CPU_FREQ_TABLE=y | ||
154 | 157 | ||
155 | # | 158 | # |
156 | # CPUFreq processor drivers | 159 | # CPUFreq processor drivers |
@@ -164,6 +167,7 @@ CONFIG_X86_ACPI_CPUFREQ=y | |||
164 | # shared options | 167 | # shared options |
165 | # | 168 | # |
166 | CONFIG_X86_ACPI_CPUFREQ_PROC_INTF=y | 169 | CONFIG_X86_ACPI_CPUFREQ_PROC_INTF=y |
170 | # CONFIG_X86_SPEEDSTEP_LIB is not set | ||
167 | 171 | ||
168 | # | 172 | # |
169 | # Bus options (PCI etc.) | 173 | # Bus options (PCI etc.) |
@@ -172,9 +176,11 @@ CONFIG_PCI=y | |||
172 | CONFIG_PCI_DIRECT=y | 176 | CONFIG_PCI_DIRECT=y |
173 | CONFIG_PCI_MMCONFIG=y | 177 | CONFIG_PCI_MMCONFIG=y |
174 | CONFIG_UNORDERED_IO=y | 178 | CONFIG_UNORDERED_IO=y |
179 | # CONFIG_PCIEPORTBUS is not set | ||
175 | CONFIG_PCI_MSI=y | 180 | CONFIG_PCI_MSI=y |
176 | # CONFIG_PCI_LEGACY_PROC is not set | 181 | # CONFIG_PCI_LEGACY_PROC is not set |
177 | # CONFIG_PCI_NAMES is not set | 182 | # CONFIG_PCI_NAMES is not set |
183 | # CONFIG_PCI_DEBUG is not set | ||
178 | 184 | ||
179 | # | 185 | # |
180 | # PCCARD (PCMCIA/CardBus) support | 186 | # PCCARD (PCMCIA/CardBus) support |
@@ -182,10 +188,6 @@ CONFIG_PCI_MSI=y | |||
182 | # CONFIG_PCCARD is not set | 188 | # CONFIG_PCCARD is not set |
183 | 189 | ||
184 | # | 190 | # |
185 | # PC-card bridges | ||
186 | # | ||
187 | |||
188 | # | ||
189 | # PCI Hotplug Support | 191 | # PCI Hotplug Support |
190 | # | 192 | # |
191 | # CONFIG_HOTPLUG_PCI is not set | 193 | # CONFIG_HOTPLUG_PCI is not set |
@@ -254,7 +256,7 @@ CONFIG_LBD=y | |||
254 | # IO Schedulers | 256 | # IO Schedulers |
255 | # | 257 | # |
256 | CONFIG_IOSCHED_NOOP=y | 258 | CONFIG_IOSCHED_NOOP=y |
257 | CONFIG_IOSCHED_AS=y | 259 | # CONFIG_IOSCHED_AS is not set |
258 | CONFIG_IOSCHED_DEADLINE=y | 260 | CONFIG_IOSCHED_DEADLINE=y |
259 | CONFIG_IOSCHED_CFQ=y | 261 | CONFIG_IOSCHED_CFQ=y |
260 | # CONFIG_ATA_OVER_ETH is not set | 262 | # CONFIG_ATA_OVER_ETH is not set |
@@ -308,7 +310,8 @@ CONFIG_BLK_DEV_AMD74XX=y | |||
308 | CONFIG_BLK_DEV_PIIX=y | 310 | CONFIG_BLK_DEV_PIIX=y |
309 | # CONFIG_BLK_DEV_NS87415 is not set | 311 | # CONFIG_BLK_DEV_NS87415 is not set |
310 | # CONFIG_BLK_DEV_PDC202XX_OLD is not set | 312 | # CONFIG_BLK_DEV_PDC202XX_OLD is not set |
311 | # CONFIG_BLK_DEV_PDC202XX_NEW is not set | 313 | CONFIG_BLK_DEV_PDC202XX_NEW=y |
314 | # CONFIG_PDC202XX_FORCE is not set | ||
312 | # CONFIG_BLK_DEV_SVWKS is not set | 315 | # CONFIG_BLK_DEV_SVWKS is not set |
313 | # CONFIG_BLK_DEV_SIIMAGE is not set | 316 | # CONFIG_BLK_DEV_SIIMAGE is not set |
314 | # CONFIG_BLK_DEV_SIS5513 is not set | 317 | # CONFIG_BLK_DEV_SIS5513 is not set |
@@ -353,7 +356,7 @@ CONFIG_BLK_DEV_SD=y | |||
353 | # | 356 | # |
354 | # SCSI low-level drivers | 357 | # SCSI low-level drivers |
355 | # | 358 | # |
356 | CONFIG_BLK_DEV_3W_XXXX_RAID=y | 359 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set |
357 | # CONFIG_SCSI_3W_9XXX is not set | 360 | # CONFIG_SCSI_3W_9XXX is not set |
358 | # CONFIG_SCSI_ACARD is not set | 361 | # CONFIG_SCSI_ACARD is not set |
359 | # CONFIG_SCSI_AACRAID is not set | 362 | # CONFIG_SCSI_AACRAID is not set |
@@ -384,7 +387,6 @@ CONFIG_SCSI_SATA_VIA=y | |||
384 | # CONFIG_SCSI_BUSLOGIC is not set | 387 | # CONFIG_SCSI_BUSLOGIC is not set |
385 | # CONFIG_SCSI_DMX3191D is not set | 388 | # CONFIG_SCSI_DMX3191D is not set |
386 | # CONFIG_SCSI_EATA is not set | 389 | # CONFIG_SCSI_EATA is not set |
387 | # CONFIG_SCSI_EATA_PIO is not set | ||
388 | # CONFIG_SCSI_FUTURE_DOMAIN is not set | 390 | # CONFIG_SCSI_FUTURE_DOMAIN is not set |
389 | # CONFIG_SCSI_GDTH is not set | 391 | # CONFIG_SCSI_GDTH is not set |
390 | # CONFIG_SCSI_IPS is not set | 392 | # CONFIG_SCSI_IPS is not set |
@@ -392,7 +394,6 @@ CONFIG_SCSI_SATA_VIA=y | |||
392 | # CONFIG_SCSI_INIA100 is not set | 394 | # CONFIG_SCSI_INIA100 is not set |
393 | # CONFIG_SCSI_SYM53C8XX_2 is not set | 395 | # CONFIG_SCSI_SYM53C8XX_2 is not set |
394 | # CONFIG_SCSI_IPR is not set | 396 | # CONFIG_SCSI_IPR is not set |
395 | # CONFIG_SCSI_QLOGIC_ISP is not set | ||
396 | # CONFIG_SCSI_QLOGIC_FC is not set | 397 | # CONFIG_SCSI_QLOGIC_FC is not set |
397 | # CONFIG_SCSI_QLOGIC_1280 is not set | 398 | # CONFIG_SCSI_QLOGIC_1280 is not set |
398 | CONFIG_SCSI_QLA2XXX=y | 399 | CONFIG_SCSI_QLA2XXX=y |
@@ -401,6 +402,7 @@ CONFIG_SCSI_QLA2XXX=y | |||
401 | # CONFIG_SCSI_QLA2300 is not set | 402 | # CONFIG_SCSI_QLA2300 is not set |
402 | # CONFIG_SCSI_QLA2322 is not set | 403 | # CONFIG_SCSI_QLA2322 is not set |
403 | # CONFIG_SCSI_QLA6312 is not set | 404 | # CONFIG_SCSI_QLA6312 is not set |
405 | # CONFIG_SCSI_LPFC is not set | ||
404 | # CONFIG_SCSI_DC395x is not set | 406 | # CONFIG_SCSI_DC395x is not set |
405 | # CONFIG_SCSI_DC390T is not set | 407 | # CONFIG_SCSI_DC390T is not set |
406 | # CONFIG_SCSI_DEBUG is not set | 408 | # CONFIG_SCSI_DEBUG is not set |
@@ -437,7 +439,6 @@ CONFIG_NET=y | |||
437 | # | 439 | # |
438 | CONFIG_PACKET=y | 440 | CONFIG_PACKET=y |
439 | # CONFIG_PACKET_MMAP is not set | 441 | # CONFIG_PACKET_MMAP is not set |
440 | # CONFIG_NETLINK_DEV is not set | ||
441 | CONFIG_UNIX=y | 442 | CONFIG_UNIX=y |
442 | # CONFIG_NET_KEY is not set | 443 | # CONFIG_NET_KEY is not set |
443 | CONFIG_INET=y | 444 | CONFIG_INET=y |
@@ -502,7 +503,7 @@ CONFIG_NETDEVICES=y | |||
502 | # CONFIG_DUMMY is not set | 503 | # CONFIG_DUMMY is not set |
503 | # CONFIG_BONDING is not set | 504 | # CONFIG_BONDING is not set |
504 | # CONFIG_EQUALIZER is not set | 505 | # CONFIG_EQUALIZER is not set |
505 | # CONFIG_TUN is not set | 506 | CONFIG_TUN=y |
506 | 507 | ||
507 | # | 508 | # |
508 | # ARCnet devices | 509 | # ARCnet devices |
@@ -525,8 +526,7 @@ CONFIG_MII=y | |||
525 | # CONFIG_HP100 is not set | 526 | # CONFIG_HP100 is not set |
526 | CONFIG_NET_PCI=y | 527 | CONFIG_NET_PCI=y |
527 | # CONFIG_PCNET32 is not set | 528 | # CONFIG_PCNET32 is not set |
528 | CONFIG_AMD8111_ETH=y | 529 | # CONFIG_AMD8111_ETH is not set |
529 | # CONFIG_AMD8111E_NAPI is not set | ||
530 | # CONFIG_ADAPTEC_STARFIRE is not set | 530 | # CONFIG_ADAPTEC_STARFIRE is not set |
531 | # CONFIG_B44 is not set | 531 | # CONFIG_B44 is not set |
532 | CONFIG_FORCEDETH=y | 532 | CONFIG_FORCEDETH=y |
@@ -536,7 +536,7 @@ CONFIG_FORCEDETH=y | |||
536 | # CONFIG_FEALNX is not set | 536 | # CONFIG_FEALNX is not set |
537 | # CONFIG_NATSEMI is not set | 537 | # CONFIG_NATSEMI is not set |
538 | # CONFIG_NE2K_PCI is not set | 538 | # CONFIG_NE2K_PCI is not set |
539 | CONFIG_8139CP=m | 539 | CONFIG_8139CP=y |
540 | CONFIG_8139TOO=y | 540 | CONFIG_8139TOO=y |
541 | # CONFIG_8139TOO_PIO is not set | 541 | # CONFIG_8139TOO_PIO is not set |
542 | # CONFIG_8139TOO_TUNE_TWISTER is not set | 542 | # CONFIG_8139TOO_TUNE_TWISTER is not set |
@@ -671,6 +671,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4 | |||
671 | # | 671 | # |
672 | CONFIG_SERIAL_CORE=y | 672 | CONFIG_SERIAL_CORE=y |
673 | CONFIG_SERIAL_CORE_CONSOLE=y | 673 | CONFIG_SERIAL_CORE_CONSOLE=y |
674 | # CONFIG_SERIAL_JSM is not set | ||
674 | CONFIG_UNIX98_PTYS=y | 675 | CONFIG_UNIX98_PTYS=y |
675 | CONFIG_LEGACY_PTYS=y | 676 | CONFIG_LEGACY_PTYS=y |
676 | CONFIG_LEGACY_PTY_COUNT=256 | 677 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -696,6 +697,7 @@ CONFIG_RTC=y | |||
696 | # | 697 | # |
697 | CONFIG_AGP=y | 698 | CONFIG_AGP=y |
698 | CONFIG_AGP_AMD64=y | 699 | CONFIG_AGP_AMD64=y |
700 | CONFIG_AGP_INTEL=y | ||
699 | # CONFIG_DRM is not set | 701 | # CONFIG_DRM is not set |
700 | # CONFIG_MWAVE is not set | 702 | # CONFIG_MWAVE is not set |
701 | CONFIG_RAW_DRIVER=y | 703 | CONFIG_RAW_DRIVER=y |
@@ -703,7 +705,7 @@ CONFIG_HPET=y | |||
703 | # CONFIG_HPET_RTC_IRQ is not set | 705 | # CONFIG_HPET_RTC_IRQ is not set |
704 | CONFIG_HPET_MMAP=y | 706 | CONFIG_HPET_MMAP=y |
705 | CONFIG_MAX_RAW_DEVS=256 | 707 | CONFIG_MAX_RAW_DEVS=256 |
706 | CONFIG_HANGCHECK_TIMER=y | 708 | # CONFIG_HANGCHECK_TIMER is not set |
707 | 709 | ||
708 | # | 710 | # |
709 | # TPM devices | 711 | # TPM devices |
@@ -786,6 +788,8 @@ CONFIG_SOUND_ICH=y | |||
786 | # | 788 | # |
787 | # USB support | 789 | # USB support |
788 | # | 790 | # |
791 | CONFIG_USB_ARCH_HAS_HCD=y | ||
792 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
789 | CONFIG_USB=y | 793 | CONFIG_USB=y |
790 | # CONFIG_USB_DEBUG is not set | 794 | # CONFIG_USB_DEBUG is not set |
791 | 795 | ||
@@ -797,8 +801,6 @@ CONFIG_USB_DEVICEFS=y | |||
797 | # CONFIG_USB_DYNAMIC_MINORS is not set | 801 | # CONFIG_USB_DYNAMIC_MINORS is not set |
798 | # CONFIG_USB_SUSPEND is not set | 802 | # CONFIG_USB_SUSPEND is not set |
799 | # CONFIG_USB_OTG is not set | 803 | # CONFIG_USB_OTG is not set |
800 | CONFIG_USB_ARCH_HAS_HCD=y | ||
801 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
802 | 804 | ||
803 | # | 805 | # |
804 | # USB Host Controller Drivers | 806 | # USB Host Controller Drivers |
@@ -826,7 +828,6 @@ CONFIG_USB_PRINTER=y | |||
826 | # | 828 | # |
827 | CONFIG_USB_STORAGE=y | 829 | CONFIG_USB_STORAGE=y |
828 | # CONFIG_USB_STORAGE_DEBUG is not set | 830 | # CONFIG_USB_STORAGE_DEBUG is not set |
829 | # CONFIG_USB_STORAGE_RW_DETECT is not set | ||
830 | # CONFIG_USB_STORAGE_DATAFAB is not set | 831 | # CONFIG_USB_STORAGE_DATAFAB is not set |
831 | # CONFIG_USB_STORAGE_FREECOM is not set | 832 | # CONFIG_USB_STORAGE_FREECOM is not set |
832 | # CONFIG_USB_STORAGE_ISD200 is not set | 833 | # CONFIG_USB_STORAGE_ISD200 is not set |
@@ -965,7 +966,7 @@ CONFIG_AUTOFS_FS=y | |||
965 | # CD-ROM/DVD Filesystems | 966 | # CD-ROM/DVD Filesystems |
966 | # | 967 | # |
967 | CONFIG_ISO9660_FS=y | 968 | CONFIG_ISO9660_FS=y |
968 | # CONFIG_JOLIET is not set | 969 | CONFIG_JOLIET=y |
969 | # CONFIG_ZISOFS is not set | 970 | # CONFIG_ZISOFS is not set |
970 | # CONFIG_UDF_FS is not set | 971 | # CONFIG_UDF_FS is not set |
971 | 972 | ||
@@ -1092,9 +1093,10 @@ CONFIG_OPROFILE=y | |||
1092 | # | 1093 | # |
1093 | # Kernel hacking | 1094 | # Kernel hacking |
1094 | # | 1095 | # |
1096 | # CONFIG_PRINTK_TIME is not set | ||
1095 | CONFIG_DEBUG_KERNEL=y | 1097 | CONFIG_DEBUG_KERNEL=y |
1096 | CONFIG_MAGIC_SYSRQ=y | 1098 | CONFIG_MAGIC_SYSRQ=y |
1097 | # CONFIG_PRINTK_TIME is not set | 1099 | CONFIG_LOG_BUF_SHIFT=18 |
1098 | # CONFIG_SCHEDSTATS is not set | 1100 | # CONFIG_SCHEDSTATS is not set |
1099 | # CONFIG_DEBUG_SLAB is not set | 1101 | # CONFIG_DEBUG_SLAB is not set |
1100 | # CONFIG_DEBUG_SPINLOCK is not set | 1102 | # CONFIG_DEBUG_SPINLOCK is not set |
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile index 0a3318e08ab6..5ca4a4598fda 100644 --- a/arch/x86_64/kernel/Makefile +++ b/arch/x86_64/kernel/Makefile | |||
@@ -28,6 +28,7 @@ obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o | |||
28 | obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o pci-dma.o | 28 | obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o pci-dma.o |
29 | obj-$(CONFIG_SWIOTLB) += swiotlb.o | 29 | obj-$(CONFIG_SWIOTLB) += swiotlb.o |
30 | obj-$(CONFIG_KPROBES) += kprobes.o | 30 | obj-$(CONFIG_KPROBES) += kprobes.o |
31 | obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o | ||
31 | 32 | ||
32 | obj-$(CONFIG_MODULES) += module.o | 33 | obj-$(CONFIG_MODULES) += module.o |
33 | 34 | ||
diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c index a491f72cc966..504e63474993 100644 --- a/arch/x86_64/kernel/aperture.c +++ b/arch/x86_64/kernel/aperture.c | |||
@@ -33,12 +33,10 @@ int fallback_aper_force __initdata = 0; | |||
33 | 33 | ||
34 | int fix_aperture __initdata = 1; | 34 | int fix_aperture __initdata = 1; |
35 | 35 | ||
36 | #define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16)) | 36 | /* This code runs before the PCI subsystem is initialized, so just |
37 | access the northbridge directly. */ | ||
37 | 38 | ||
38 | static struct resource aper_res = { | 39 | #define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16)) |
39 | .name = "Aperture", | ||
40 | .flags = IORESOURCE_MEM, | ||
41 | }; | ||
42 | 40 | ||
43 | static u32 __init allocate_aperture(void) | 41 | static u32 __init allocate_aperture(void) |
44 | { | 42 | { |
@@ -55,24 +53,11 @@ static u32 __init allocate_aperture(void) | |||
55 | aper_size = (32 * 1024 * 1024) << fallback_aper_order; | 53 | aper_size = (32 * 1024 * 1024) << fallback_aper_order; |
56 | 54 | ||
57 | /* | 55 | /* |
58 | * Aperture has to be naturally aligned. This means an 2GB | 56 | * Aperture has to be naturally aligned. This means an 2GB aperture won't |
59 | * aperture won't have much chances to find a place in the | 57 | * have much chances to find a place in the lower 4GB of memory. |
60 | * lower 4GB of memory. Unfortunately we cannot move it up | 58 | * Unfortunately we cannot move it up because that would make the |
61 | * because that would make the IOMMU useless. | 59 | * IOMMU useless. |
62 | */ | 60 | */ |
63 | |||
64 | /* First try to find some free unused space */ | ||
65 | if (!allocate_resource(&iomem_resource, &aper_res, | ||
66 | aper_size, | ||
67 | 0, 0xffffffff, | ||
68 | aper_size, | ||
69 | NULL, NULL)) { | ||
70 | printk(KERN_INFO "Putting aperture at %lx-%lx\n", | ||
71 | aper_res.start, aper_res.end); | ||
72 | return aper_res.start; | ||
73 | } | ||
74 | |||
75 | /* No free space found. Go on to waste some memory... */ | ||
76 | p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0); | 61 | p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0); |
77 | if (!p || __pa(p)+aper_size > 0xffffffff) { | 62 | if (!p || __pa(p)+aper_size > 0xffffffff) { |
78 | printk("Cannot allocate aperture memory hole (%p,%uK)\n", | 63 | printk("Cannot allocate aperture memory hole (%p,%uK)\n", |
@@ -81,7 +66,7 @@ static u32 __init allocate_aperture(void) | |||
81 | free_bootmem_node(nd0, (unsigned long)p, aper_size); | 66 | free_bootmem_node(nd0, (unsigned long)p, aper_size); |
82 | return 0; | 67 | return 0; |
83 | } | 68 | } |
84 | printk("Mapping aperture over %d KB of precious RAM @ %lx\n", | 69 | printk("Mapping aperture over %d KB of RAM @ %lx\n", |
85 | aper_size >> 10, __pa(p)); | 70 | aper_size >> 10, __pa(p)); |
86 | return (u32)__pa(p); | 71 | return (u32)__pa(p); |
87 | } | 72 | } |
@@ -102,16 +87,10 @@ static int __init aperture_valid(char *name, u64 aper_base, u32 aper_size) | |||
102 | printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name); | 87 | printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name); |
103 | return 0; | 88 | return 0; |
104 | } | 89 | } |
105 | /* Don't check the resource here because the aperture is usually | ||
106 | in an e820 reserved area, and we allocated these earlier. */ | ||
107 | return 1; | 90 | return 1; |
108 | } | 91 | } |
109 | 92 | ||
110 | /* | 93 | /* Find a PCI capability */ |
111 | * Find a PCI capability. | ||
112 | * This code runs before the PCI subsystem is initialized, so just | ||
113 | * access the northbridge directly. | ||
114 | */ | ||
115 | static __u32 __init find_cap(int num, int slot, int func, int cap) | 94 | static __u32 __init find_cap(int num, int slot, int func, int cap) |
116 | { | 95 | { |
117 | u8 pos; | 96 | u8 pos; |
@@ -276,6 +255,8 @@ void __init iommu_hole_init(void) | |||
276 | fallback_aper_force) { | 255 | fallback_aper_force) { |
277 | printk("Your BIOS doesn't leave a aperture memory hole\n"); | 256 | printk("Your BIOS doesn't leave a aperture memory hole\n"); |
278 | printk("Please enable the IOMMU option in the BIOS setup\n"); | 257 | printk("Please enable the IOMMU option in the BIOS setup\n"); |
258 | printk("This costs you %d MB of RAM\n", | ||
259 | 32 << fallback_aper_order); | ||
279 | 260 | ||
280 | aper_order = fallback_aper_order; | 261 | aper_order = fallback_aper_order; |
281 | aper_alloc = allocate_aperture(); | 262 | aper_alloc = allocate_aperture(); |
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c index 7e13545748e0..f8e6cc4fecd4 100644 --- a/arch/x86_64/kernel/apic.c +++ b/arch/x86_64/kernel/apic.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <asm/mpspec.h> | 33 | #include <asm/mpspec.h> |
34 | #include <asm/pgalloc.h> | 34 | #include <asm/pgalloc.h> |
35 | #include <asm/mach_apic.h> | 35 | #include <asm/mach_apic.h> |
36 | #include <asm/nmi.h> | ||
36 | 37 | ||
37 | int apic_verbosity; | 38 | int apic_verbosity; |
38 | 39 | ||
@@ -925,7 +926,7 @@ __init int oem_force_hpet_timer(void) | |||
925 | unsigned id; | 926 | unsigned id; |
926 | DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS); | 927 | DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS); |
927 | 928 | ||
928 | bitmap_empty(clustermap, NUM_APIC_CLUSTERS); | 929 | bitmap_zero(clustermap, NUM_APIC_CLUSTERS); |
929 | 930 | ||
930 | for (i = 0; i < NR_CPUS; i++) { | 931 | for (i = 0; i < NR_CPUS; i++) { |
931 | id = bios_cpu_apicid[i]; | 932 | id = bios_cpu_apicid[i]; |
@@ -1056,7 +1057,7 @@ int __init APIC_init_uniprocessor (void) | |||
1056 | nr_ioapics = 0; | 1057 | nr_ioapics = 0; |
1057 | #endif | 1058 | #endif |
1058 | setup_boot_APIC_clock(); | 1059 | setup_boot_APIC_clock(); |
1059 | 1060 | check_nmi_watchdog(); | |
1060 | return 0; | 1061 | return 0; |
1061 | } | 1062 | } |
1062 | 1063 | ||
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index 1086b5fcac21..28817490fdc6 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S | |||
@@ -220,13 +220,18 @@ sysret_careful: | |||
220 | jmp sysret_check | 220 | jmp sysret_check |
221 | 221 | ||
222 | /* Handle a signal */ | 222 | /* Handle a signal */ |
223 | /* edx: work flags (arg3) */ | ||
224 | sysret_signal: | 223 | sysret_signal: |
225 | sti | 224 | sti |
225 | testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx | ||
226 | jz 1f | ||
227 | |||
228 | /* Really a signal */ | ||
229 | /* edx: work flags (arg3) */ | ||
226 | leaq do_notify_resume(%rip),%rax | 230 | leaq do_notify_resume(%rip),%rax |
227 | leaq -ARGOFFSET(%rsp),%rdi # &pt_regs -> arg1 | 231 | leaq -ARGOFFSET(%rsp),%rdi # &pt_regs -> arg1 |
228 | xorl %esi,%esi # oldset -> arg2 | 232 | xorl %esi,%esi # oldset -> arg2 |
229 | call ptregscall_common | 233 | call ptregscall_common |
234 | 1: movl $_TIF_NEED_RESCHED,%edi | ||
230 | jmp sysret_check | 235 | jmp sysret_check |
231 | 236 | ||
232 | /* Do syscall tracing */ | 237 | /* Do syscall tracing */ |
@@ -484,6 +489,8 @@ retint_careful: | |||
484 | jmp retint_check | 489 | jmp retint_check |
485 | 490 | ||
486 | retint_signal: | 491 | retint_signal: |
492 | testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx | ||
493 | jz retint_swapgs | ||
487 | sti | 494 | sti |
488 | SAVE_REST | 495 | SAVE_REST |
489 | movq $-1,ORIG_RAX(%rsp) | 496 | movq $-1,ORIG_RAX(%rsp) |
@@ -492,8 +499,8 @@ retint_signal: | |||
492 | call do_notify_resume | 499 | call do_notify_resume |
493 | RESTORE_REST | 500 | RESTORE_REST |
494 | cli | 501 | cli |
502 | movl $_TIF_NEED_RESCHED,%edi | ||
495 | GET_THREAD_INFO(%rcx) | 503 | GET_THREAD_INFO(%rcx) |
496 | movl $_TIF_WORK_MASK,%edi | ||
497 | jmp retint_check | 504 | jmp retint_check |
498 | 505 | ||
499 | #ifdef CONFIG_PREEMPT | 506 | #ifdef CONFIG_PREEMPT |
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 60be58617eb9..afd87e64d0a8 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c | |||
@@ -37,11 +37,14 @@ | |||
37 | #include <asm/desc.h> | 37 | #include <asm/desc.h> |
38 | #include <asm/proto.h> | 38 | #include <asm/proto.h> |
39 | #include <asm/mach_apic.h> | 39 | #include <asm/mach_apic.h> |
40 | #include <asm/acpi.h> | ||
40 | 41 | ||
41 | #define __apicdebuginit __init | 42 | #define __apicdebuginit __init |
42 | 43 | ||
43 | int sis_apic_bug; /* not actually supported, dummy for compile */ | 44 | int sis_apic_bug; /* not actually supported, dummy for compile */ |
44 | 45 | ||
46 | static int no_timer_check; | ||
47 | |||
45 | static DEFINE_SPINLOCK(ioapic_lock); | 48 | static DEFINE_SPINLOCK(ioapic_lock); |
46 | 49 | ||
47 | /* | 50 | /* |
@@ -1601,7 +1604,7 @@ static inline void check_timer(void) | |||
1601 | * Ok, does IRQ0 through the IOAPIC work? | 1604 | * Ok, does IRQ0 through the IOAPIC work? |
1602 | */ | 1605 | */ |
1603 | unmask_IO_APIC_irq(0); | 1606 | unmask_IO_APIC_irq(0); |
1604 | if (timer_irq_works()) { | 1607 | if (!no_timer_check && timer_irq_works()) { |
1605 | nmi_watchdog_default(); | 1608 | nmi_watchdog_default(); |
1606 | if (nmi_watchdog == NMI_IO_APIC) { | 1609 | if (nmi_watchdog == NMI_IO_APIC) { |
1607 | disable_8259A_irq(0); | 1610 | disable_8259A_irq(0); |
@@ -1671,6 +1674,13 @@ static inline void check_timer(void) | |||
1671 | panic("IO-APIC + timer doesn't work! Try using the 'noapic' kernel parameter\n"); | 1674 | panic("IO-APIC + timer doesn't work! Try using the 'noapic' kernel parameter\n"); |
1672 | } | 1675 | } |
1673 | 1676 | ||
1677 | static int __init notimercheck(char *s) | ||
1678 | { | ||
1679 | no_timer_check = 1; | ||
1680 | return 1; | ||
1681 | } | ||
1682 | __setup("no_timer_check", notimercheck); | ||
1683 | |||
1674 | /* | 1684 | /* |
1675 | * | 1685 | * |
1676 | * IRQ's that are handled by the PIC in the MPS IOAPIC case. | 1686 | * IRQ's that are handled by the PIC in the MPS IOAPIC case. |
@@ -1804,76 +1814,6 @@ device_initcall(ioapic_init_sysfs); | |||
1804 | 1814 | ||
1805 | #define IO_APIC_MAX_ID 0xFE | 1815 | #define IO_APIC_MAX_ID 0xFE |
1806 | 1816 | ||
1807 | int __init io_apic_get_unique_id (int ioapic, int apic_id) | ||
1808 | { | ||
1809 | union IO_APIC_reg_00 reg_00; | ||
1810 | static physid_mask_t apic_id_map; | ||
1811 | unsigned long flags; | ||
1812 | int i = 0; | ||
1813 | |||
1814 | /* | ||
1815 | * The P4 platform supports up to 256 APIC IDs on two separate APIC | ||
1816 | * buses (one for LAPICs, one for IOAPICs), where predecessors only | ||
1817 | * supports up to 16 on one shared APIC bus. | ||
1818 | * | ||
1819 | * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full | ||
1820 | * advantage of new APIC bus architecture. | ||
1821 | */ | ||
1822 | |||
1823 | if (physids_empty(apic_id_map)) | ||
1824 | apic_id_map = phys_cpu_present_map; | ||
1825 | |||
1826 | spin_lock_irqsave(&ioapic_lock, flags); | ||
1827 | reg_00.raw = io_apic_read(ioapic, 0); | ||
1828 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
1829 | |||
1830 | if (apic_id >= IO_APIC_MAX_ID) { | ||
1831 | apic_printk(APIC_QUIET, KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying " | ||
1832 | "%d\n", ioapic, apic_id, reg_00.bits.ID); | ||
1833 | apic_id = reg_00.bits.ID; | ||
1834 | } | ||
1835 | |||
1836 | /* | ||
1837 | * Every APIC in a system must have a unique ID or we get lots of nice | ||
1838 | * 'stuck on smp_invalidate_needed IPI wait' messages. | ||
1839 | */ | ||
1840 | if (physid_isset(apic_id, apic_id_map)) { | ||
1841 | |||
1842 | for (i = 0; i < IO_APIC_MAX_ID; i++) { | ||
1843 | if (!physid_isset(i, apic_id_map)) | ||
1844 | break; | ||
1845 | } | ||
1846 | |||
1847 | if (i == IO_APIC_MAX_ID) | ||
1848 | panic("Max apic_id exceeded!\n"); | ||
1849 | |||
1850 | apic_printk(APIC_VERBOSE, KERN_WARNING "IOAPIC[%d]: apic_id %d already used, " | ||
1851 | "trying %d\n", ioapic, apic_id, i); | ||
1852 | |||
1853 | apic_id = i; | ||
1854 | } | ||
1855 | |||
1856 | physid_set(apic_id, apic_id_map); | ||
1857 | |||
1858 | if (reg_00.bits.ID != apic_id) { | ||
1859 | reg_00.bits.ID = apic_id; | ||
1860 | |||
1861 | spin_lock_irqsave(&ioapic_lock, flags); | ||
1862 | io_apic_write(ioapic, 0, reg_00.raw); | ||
1863 | reg_00.raw = io_apic_read(ioapic, 0); | ||
1864 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
1865 | |||
1866 | /* Sanity check */ | ||
1867 | if (reg_00.bits.ID != apic_id) | ||
1868 | panic("IOAPIC[%d]: Unable change apic_id!\n", ioapic); | ||
1869 | } | ||
1870 | |||
1871 | apic_printk(APIC_VERBOSE,KERN_INFO "IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id); | ||
1872 | |||
1873 | return apic_id; | ||
1874 | } | ||
1875 | |||
1876 | |||
1877 | int __init io_apic_get_version (int ioapic) | 1817 | int __init io_apic_get_version (int ioapic) |
1878 | { | 1818 | { |
1879 | union IO_APIC_reg_01 reg_01; | 1819 | union IO_APIC_reg_01 reg_01; |
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c index 4f2a852299b6..f77f8a0ff187 100644 --- a/arch/x86_64/kernel/kprobes.c +++ b/arch/x86_64/kernel/kprobes.c | |||
@@ -355,6 +355,13 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs) | |||
355 | *tos &= ~(TF_MASK | IF_MASK); | 355 | *tos &= ~(TF_MASK | IF_MASK); |
356 | *tos |= kprobe_old_rflags; | 356 | *tos |= kprobe_old_rflags; |
357 | break; | 357 | break; |
358 | case 0xc3: /* ret/lret */ | ||
359 | case 0xcb: | ||
360 | case 0xc2: | ||
361 | case 0xca: | ||
362 | regs->eflags &= ~TF_MASK; | ||
363 | /* rip is already adjusted, no more changes required*/ | ||
364 | return; | ||
358 | case 0xe8: /* call relative - Fix return addr */ | 365 | case 0xe8: /* call relative - Fix return addr */ |
359 | *tos = orig_rip + (*tos - copy_rip); | 366 | *tos = orig_rip + (*tos - copy_rip); |
360 | break; | 367 | break; |
diff --git a/arch/x86_64/kernel/module.c b/arch/x86_64/kernel/module.c index c2ffea8845ed..bac195c74bcc 100644 --- a/arch/x86_64/kernel/module.c +++ b/arch/x86_64/kernel/module.c | |||
@@ -30,9 +30,12 @@ | |||
30 | 30 | ||
31 | #define DEBUGP(fmt...) | 31 | #define DEBUGP(fmt...) |
32 | 32 | ||
33 | #ifndef CONFIG_UML | ||
33 | void module_free(struct module *mod, void *module_region) | 34 | void module_free(struct module *mod, void *module_region) |
34 | { | 35 | { |
35 | vfree(module_region); | 36 | vfree(module_region); |
37 | /* FIXME: If module_region == mod->init_region, trim exception | ||
38 | table entries. */ | ||
36 | } | 39 | } |
37 | 40 | ||
38 | void *module_alloc(unsigned long size) | 41 | void *module_alloc(unsigned long size) |
@@ -51,6 +54,7 @@ void *module_alloc(unsigned long size) | |||
51 | 54 | ||
52 | return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC); | 55 | return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC); |
53 | } | 56 | } |
57 | #endif | ||
54 | 58 | ||
55 | /* We don't need anything special. */ | 59 | /* We don't need anything special. */ |
56 | int module_frob_arch_sections(Elf_Ehdr *hdr, | 60 | int module_frob_arch_sections(Elf_Ehdr *hdr, |
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c index 7ec031c6ca10..61a63be6b294 100644 --- a/arch/x86_64/kernel/mpparse.c +++ b/arch/x86_64/kernel/mpparse.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <asm/pgalloc.h> | 30 | #include <asm/pgalloc.h> |
31 | #include <asm/io_apic.h> | 31 | #include <asm/io_apic.h> |
32 | #include <asm/proto.h> | 32 | #include <asm/proto.h> |
33 | #include <asm/acpi.h> | ||
33 | 34 | ||
34 | /* Have we found an MP table */ | 35 | /* Have we found an MP table */ |
35 | int smp_found_config; | 36 | int smp_found_config; |
@@ -107,6 +108,7 @@ static int __init mpf_checksum(unsigned char *mp, int len) | |||
107 | static void __init MP_processor_info (struct mpc_config_processor *m) | 108 | static void __init MP_processor_info (struct mpc_config_processor *m) |
108 | { | 109 | { |
109 | int ver; | 110 | int ver; |
111 | static int found_bsp=0; | ||
110 | 112 | ||
111 | if (!(m->mpc_cpuflag & CPU_ENABLED)) | 113 | if (!(m->mpc_cpuflag & CPU_ENABLED)) |
112 | return; | 114 | return; |
@@ -126,11 +128,6 @@ static void __init MP_processor_info (struct mpc_config_processor *m) | |||
126 | " Processor ignored.\n", NR_CPUS); | 128 | " Processor ignored.\n", NR_CPUS); |
127 | return; | 129 | return; |
128 | } | 130 | } |
129 | if (num_processors >= maxcpus) { | ||
130 | printk(KERN_WARNING "WARNING: maxcpus limit of %i reached." | ||
131 | " Processor ignored.\n", maxcpus); | ||
132 | return; | ||
133 | } | ||
134 | 131 | ||
135 | num_processors++; | 132 | num_processors++; |
136 | 133 | ||
@@ -150,7 +147,19 @@ static void __init MP_processor_info (struct mpc_config_processor *m) | |||
150 | ver = 0x10; | 147 | ver = 0x10; |
151 | } | 148 | } |
152 | apic_version[m->mpc_apicid] = ver; | 149 | apic_version[m->mpc_apicid] = ver; |
153 | bios_cpu_apicid[num_processors - 1] = m->mpc_apicid; | 150 | if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { |
151 | /* | ||
152 | * bios_cpu_apicid is required to have processors listed | ||
153 | * in same order as logical cpu numbers. Hence the first | ||
154 | * entry is BSP, and so on. | ||
155 | */ | ||
156 | bios_cpu_apicid[0] = m->mpc_apicid; | ||
157 | x86_cpu_to_apicid[0] = m->mpc_apicid; | ||
158 | found_bsp = 1; | ||
159 | } else { | ||
160 | bios_cpu_apicid[num_processors - found_bsp] = m->mpc_apicid; | ||
161 | x86_cpu_to_apicid[num_processors - found_bsp] = m->mpc_apicid; | ||
162 | } | ||
154 | } | 163 | } |
155 | 164 | ||
156 | static void __init MP_bus_info (struct mpc_config_bus *m) | 165 | static void __init MP_bus_info (struct mpc_config_bus *m) |
@@ -759,7 +768,7 @@ void __init mp_register_ioapic ( | |||
759 | mp_ioapics[idx].mpc_apicaddr = address; | 768 | mp_ioapics[idx].mpc_apicaddr = address; |
760 | 769 | ||
761 | set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); | 770 | set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); |
762 | mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id); | 771 | mp_ioapics[idx].mpc_apicid = id; |
763 | mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx); | 772 | mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx); |
764 | 773 | ||
765 | /* | 774 | /* |
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index 61de0b34a01e..31c0f2e6ac91 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <asm/msr.h> | 33 | #include <asm/msr.h> |
34 | #include <asm/proto.h> | 34 | #include <asm/proto.h> |
35 | #include <asm/kdebug.h> | 35 | #include <asm/kdebug.h> |
36 | #include <asm/local.h> | ||
36 | 37 | ||
37 | /* | 38 | /* |
38 | * lapic_nmi_owner tracks the ownership of the lapic NMI hardware: | 39 | * lapic_nmi_owner tracks the ownership of the lapic NMI hardware: |
@@ -59,7 +60,8 @@ int panic_on_timeout; | |||
59 | 60 | ||
60 | unsigned int nmi_watchdog = NMI_DEFAULT; | 61 | unsigned int nmi_watchdog = NMI_DEFAULT; |
61 | static unsigned int nmi_hz = HZ; | 62 | static unsigned int nmi_hz = HZ; |
62 | unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */ | 63 | static unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */ |
64 | static unsigned int nmi_p4_cccr_val; | ||
63 | 65 | ||
64 | /* Note that these events don't tick when the CPU idles. This means | 66 | /* Note that these events don't tick when the CPU idles. This means |
65 | the frequency varies with CPU load. */ | 67 | the frequency varies with CPU load. */ |
@@ -71,61 +73,87 @@ unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */ | |||
71 | #define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76 | 73 | #define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76 |
72 | #define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING | 74 | #define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING |
73 | 75 | ||
74 | #define P6_EVNTSEL0_ENABLE (1 << 22) | 76 | #define MSR_P4_MISC_ENABLE 0x1A0 |
75 | #define P6_EVNTSEL_INT (1 << 20) | 77 | #define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7) |
76 | #define P6_EVNTSEL_OS (1 << 17) | 78 | #define MSR_P4_MISC_ENABLE_PEBS_UNAVAIL (1<<12) |
77 | #define P6_EVNTSEL_USR (1 << 16) | 79 | #define MSR_P4_PERFCTR0 0x300 |
78 | #define P6_EVENT_CPU_CLOCKS_NOT_HALTED 0x79 | 80 | #define MSR_P4_CCCR0 0x360 |
79 | #define P6_NMI_EVENT P6_EVENT_CPU_CLOCKS_NOT_HALTED | 81 | #define P4_ESCR_EVENT_SELECT(N) ((N)<<25) |
82 | #define P4_ESCR_OS (1<<3) | ||
83 | #define P4_ESCR_USR (1<<2) | ||
84 | #define P4_CCCR_OVF_PMI0 (1<<26) | ||
85 | #define P4_CCCR_OVF_PMI1 (1<<27) | ||
86 | #define P4_CCCR_THRESHOLD(N) ((N)<<20) | ||
87 | #define P4_CCCR_COMPLEMENT (1<<19) | ||
88 | #define P4_CCCR_COMPARE (1<<18) | ||
89 | #define P4_CCCR_REQUIRED (3<<16) | ||
90 | #define P4_CCCR_ESCR_SELECT(N) ((N)<<13) | ||
91 | #define P4_CCCR_ENABLE (1<<12) | ||
92 | /* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter | ||
93 | CRU_ESCR0 (with any non-null event selector) through a complemented | ||
94 | max threshold. [IA32-Vol3, Section 14.9.9] */ | ||
95 | #define MSR_P4_IQ_COUNTER0 0x30C | ||
96 | #define P4_NMI_CRU_ESCR0 (P4_ESCR_EVENT_SELECT(0x3F)|P4_ESCR_OS|P4_ESCR_USR) | ||
97 | #define P4_NMI_IQ_CCCR0 \ | ||
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) | ||
100 | |||
101 | static __init inline int nmi_known_cpu(void) | ||
102 | { | ||
103 | switch (boot_cpu_data.x86_vendor) { | ||
104 | case X86_VENDOR_AMD: | ||
105 | return boot_cpu_data.x86 == 15; | ||
106 | case X86_VENDOR_INTEL: | ||
107 | return boot_cpu_data.x86 == 15; | ||
108 | } | ||
109 | return 0; | ||
110 | } | ||
80 | 111 | ||
81 | /* 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 */ |
82 | void __init nmi_watchdog_default(void) | 113 | void __init nmi_watchdog_default(void) |
83 | { | 114 | { |
84 | if (nmi_watchdog != NMI_DEFAULT) | 115 | if (nmi_watchdog != NMI_DEFAULT) |
85 | return; | 116 | return; |
86 | 117 | if (nmi_known_cpu()) | |
87 | /* For some reason the IO APIC watchdog doesn't work on the AMD | 118 | nmi_watchdog = NMI_LOCAL_APIC; |
88 | 8111 chipset. For now switch to local APIC mode using | 119 | else |
89 | perfctr0 there. On Intel CPUs we don't have code to handle | ||
90 | the perfctr and the IO-APIC seems to work, so use that. */ | ||
91 | |||
92 | if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { | ||
93 | nmi_watchdog = NMI_LOCAL_APIC; | ||
94 | printk(KERN_INFO | ||
95 | "Using local APIC NMI watchdog using perfctr0\n"); | ||
96 | } else { | ||
97 | printk(KERN_INFO "Using IO APIC NMI watchdog\n"); | ||
98 | nmi_watchdog = NMI_IO_APIC; | 120 | nmi_watchdog = NMI_IO_APIC; |
99 | } | ||
100 | } | 121 | } |
101 | 122 | ||
102 | /* Why is there no CPUID flag for this? */ | 123 | #ifdef CONFIG_SMP |
103 | static __init int cpu_has_lapic(void) | 124 | /* The performance counters used by NMI_LOCAL_APIC don't trigger when |
125 | * the CPU is idle. To make sure the NMI watchdog really ticks on all | ||
126 | * CPUs during the test make them busy. | ||
127 | */ | ||
128 | static __init void nmi_cpu_busy(void *data) | ||
104 | { | 129 | { |
105 | switch (boot_cpu_data.x86_vendor) { | 130 | volatile int *endflag = data; |
106 | case X86_VENDOR_INTEL: | 131 | local_irq_enable(); |
107 | case X86_VENDOR_AMD: | 132 | /* Intentionally don't use cpu_relax here. This is |
108 | return boot_cpu_data.x86 >= 6; | 133 | to make sure that the performance counter really ticks, |
109 | /* .... add more cpus here or find a different way to figure this out. */ | 134 | even if there is a simulator or similar that catches the |
110 | default: | 135 | pause instruction. On a real HT machine this is fine because |
111 | return 0; | 136 | all other CPUs are busy with "useless" delay loops and don't |
112 | } | 137 | care if they get somewhat less cycles. */ |
138 | while (*endflag == 0) | ||
139 | barrier(); | ||
113 | } | 140 | } |
141 | #endif | ||
114 | 142 | ||
115 | static int __init check_nmi_watchdog (void) | 143 | int __init check_nmi_watchdog (void) |
116 | { | 144 | { |
117 | int counts[NR_CPUS]; | 145 | volatile int endflag = 0; |
146 | int *counts; | ||
118 | int cpu; | 147 | int cpu; |
119 | 148 | ||
120 | if (nmi_watchdog == NMI_NONE) | 149 | counts = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL); |
121 | return 0; | 150 | if (!counts) |
151 | return -1; | ||
122 | 152 | ||
123 | if (nmi_watchdog == NMI_LOCAL_APIC && !cpu_has_lapic()) { | 153 | printk(KERN_INFO "testing NMI watchdog ... "); |
124 | nmi_watchdog = NMI_NONE; | ||
125 | return -1; | ||
126 | } | ||
127 | 154 | ||
128 | printk(KERN_INFO "Testing NMI watchdog ... "); | 155 | if (nmi_watchdog == NMI_LOCAL_APIC) |
156 | smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0); | ||
129 | 157 | ||
130 | for (cpu = 0; cpu < NR_CPUS; cpu++) | 158 | for (cpu = 0; cpu < NR_CPUS; cpu++) |
131 | counts[cpu] = cpu_pda[cpu].__nmi_count; | 159 | counts[cpu] = cpu_pda[cpu].__nmi_count; |
@@ -133,15 +161,22 @@ static int __init check_nmi_watchdog (void) | |||
133 | mdelay((10*1000)/nmi_hz); // wait 10 ticks | 161 | mdelay((10*1000)/nmi_hz); // wait 10 ticks |
134 | 162 | ||
135 | for (cpu = 0; cpu < NR_CPUS; cpu++) { | 163 | for (cpu = 0; cpu < NR_CPUS; cpu++) { |
164 | if (!cpu_online(cpu)) | ||
165 | continue; | ||
136 | if (cpu_pda[cpu].__nmi_count - counts[cpu] <= 5) { | 166 | if (cpu_pda[cpu].__nmi_count - counts[cpu] <= 5) { |
137 | printk("CPU#%d: NMI appears to be stuck (%d)!\n", | 167 | endflag = 1; |
168 | printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n", | ||
138 | cpu, | 169 | cpu, |
170 | counts[cpu], | ||
139 | cpu_pda[cpu].__nmi_count); | 171 | cpu_pda[cpu].__nmi_count); |
140 | nmi_active = 0; | 172 | nmi_active = 0; |
141 | lapic_nmi_owner &= ~LAPIC_NMI_WATCHDOG; | 173 | lapic_nmi_owner &= ~LAPIC_NMI_WATCHDOG; |
174 | nmi_perfctr_msr = 0; | ||
175 | kfree(counts); | ||
142 | return -1; | 176 | return -1; |
143 | } | 177 | } |
144 | } | 178 | } |
179 | endflag = 1; | ||
145 | printk("OK.\n"); | 180 | printk("OK.\n"); |
146 | 181 | ||
147 | /* now that we know it works we can reduce NMI frequency to | 182 | /* now that we know it works we can reduce NMI frequency to |
@@ -149,10 +184,9 @@ static int __init check_nmi_watchdog (void) | |||
149 | if (nmi_watchdog == NMI_LOCAL_APIC) | 184 | if (nmi_watchdog == NMI_LOCAL_APIC) |
150 | nmi_hz = 1; | 185 | nmi_hz = 1; |
151 | 186 | ||
187 | kfree(counts); | ||
152 | return 0; | 188 | return 0; |
153 | } | 189 | } |
154 | /* Have this called later during boot so counters are updating */ | ||
155 | late_initcall(check_nmi_watchdog); | ||
156 | 190 | ||
157 | int __init setup_nmi_watchdog(char *str) | 191 | int __init setup_nmi_watchdog(char *str) |
158 | { | 192 | { |
@@ -170,7 +204,7 @@ int __init setup_nmi_watchdog(char *str) | |||
170 | 204 | ||
171 | if (nmi >= NMI_INVALID) | 205 | if (nmi >= NMI_INVALID) |
172 | return 0; | 206 | return 0; |
173 | nmi_watchdog = nmi; | 207 | nmi_watchdog = nmi; |
174 | return 1; | 208 | return 1; |
175 | } | 209 | } |
176 | 210 | ||
@@ -185,7 +219,10 @@ static void disable_lapic_nmi_watchdog(void) | |||
185 | wrmsr(MSR_K7_EVNTSEL0, 0, 0); | 219 | wrmsr(MSR_K7_EVNTSEL0, 0, 0); |
186 | break; | 220 | break; |
187 | case X86_VENDOR_INTEL: | 221 | case X86_VENDOR_INTEL: |
188 | wrmsr(MSR_IA32_EVNTSEL0, 0, 0); | 222 | if (boot_cpu_data.x86 == 15) { |
223 | wrmsr(MSR_P4_IQ_CCCR0, 0, 0); | ||
224 | wrmsr(MSR_P4_CRU_ESCR0, 0, 0); | ||
225 | } | ||
189 | break; | 226 | break; |
190 | } | 227 | } |
191 | nmi_active = -1; | 228 | nmi_active = -1; |
@@ -253,7 +290,7 @@ void enable_timer_nmi_watchdog(void) | |||
253 | 290 | ||
254 | static int nmi_pm_active; /* nmi_active before suspend */ | 291 | static int nmi_pm_active; /* nmi_active before suspend */ |
255 | 292 | ||
256 | static int lapic_nmi_suspend(struct sys_device *dev, pm_message_t state) | 293 | static int lapic_nmi_suspend(struct sys_device *dev, u32 state) |
257 | { | 294 | { |
258 | nmi_pm_active = nmi_active; | 295 | nmi_pm_active = nmi_active; |
259 | disable_lapic_nmi_watchdog(); | 296 | disable_lapic_nmi_watchdog(); |
@@ -300,22 +337,27 @@ late_initcall(init_lapic_nmi_sysfs); | |||
300 | * Original code written by Keith Owens. | 337 | * Original code written by Keith Owens. |
301 | */ | 338 | */ |
302 | 339 | ||
340 | static void clear_msr_range(unsigned int base, unsigned int n) | ||
341 | { | ||
342 | unsigned int i; | ||
343 | |||
344 | for(i = 0; i < n; ++i) | ||
345 | wrmsr(base+i, 0, 0); | ||
346 | } | ||
347 | |||
303 | static void setup_k7_watchdog(void) | 348 | static void setup_k7_watchdog(void) |
304 | { | 349 | { |
305 | int i; | 350 | int i; |
306 | unsigned int evntsel; | 351 | unsigned int evntsel; |
307 | 352 | ||
308 | /* No check, so can start with slow frequency */ | ||
309 | nmi_hz = 1; | ||
310 | |||
311 | /* XXX should check these in EFER */ | ||
312 | |||
313 | nmi_perfctr_msr = MSR_K7_PERFCTR0; | 353 | nmi_perfctr_msr = MSR_K7_PERFCTR0; |
314 | 354 | ||
315 | for(i = 0; i < 4; ++i) { | 355 | for(i = 0; i < 4; ++i) { |
316 | /* Simulator may not support it */ | 356 | /* Simulator may not support it */ |
317 | if (checking_wrmsrl(MSR_K7_EVNTSEL0+i, 0UL)) | 357 | if (checking_wrmsrl(MSR_K7_EVNTSEL0+i, 0UL)) { |
358 | nmi_perfctr_msr = 0; | ||
318 | return; | 359 | return; |
360 | } | ||
319 | wrmsrl(MSR_K7_PERFCTR0+i, 0UL); | 361 | wrmsrl(MSR_K7_PERFCTR0+i, 0UL); |
320 | } | 362 | } |
321 | 363 | ||
@@ -325,12 +367,54 @@ static void setup_k7_watchdog(void) | |||
325 | | K7_NMI_EVENT; | 367 | | K7_NMI_EVENT; |
326 | 368 | ||
327 | wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); | 369 | wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); |
328 | wrmsrl(MSR_K7_PERFCTR0, -((u64)cpu_khz*1000) / nmi_hz); | 370 | wrmsr(MSR_K7_PERFCTR0, -(cpu_khz/nmi_hz*1000), -1); |
329 | apic_write(APIC_LVTPC, APIC_DM_NMI); | 371 | apic_write(APIC_LVTPC, APIC_DM_NMI); |
330 | evntsel |= K7_EVNTSEL_ENABLE; | 372 | evntsel |= K7_EVNTSEL_ENABLE; |
331 | wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); | 373 | wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); |
332 | } | 374 | } |
333 | 375 | ||
376 | |||
377 | static int setup_p4_watchdog(void) | ||
378 | { | ||
379 | unsigned int misc_enable, dummy; | ||
380 | |||
381 | rdmsr(MSR_P4_MISC_ENABLE, misc_enable, dummy); | ||
382 | if (!(misc_enable & MSR_P4_MISC_ENABLE_PERF_AVAIL)) | ||
383 | return 0; | ||
384 | |||
385 | nmi_perfctr_msr = MSR_P4_IQ_COUNTER0; | ||
386 | nmi_p4_cccr_val = P4_NMI_IQ_CCCR0; | ||
387 | #ifdef CONFIG_SMP | ||
388 | if (smp_num_siblings == 2) | ||
389 | nmi_p4_cccr_val |= P4_CCCR_OVF_PMI1; | ||
390 | #endif | ||
391 | |||
392 | if (!(misc_enable & MSR_P4_MISC_ENABLE_PEBS_UNAVAIL)) | ||
393 | clear_msr_range(0x3F1, 2); | ||
394 | /* MSR 0x3F0 seems to have a default value of 0xFC00, but current | ||
395 | docs doesn't fully define it, so leave it alone for now. */ | ||
396 | if (boot_cpu_data.x86_model >= 0x3) { | ||
397 | /* MSR_P4_IQ_ESCR0/1 (0x3ba/0x3bb) removed */ | ||
398 | clear_msr_range(0x3A0, 26); | ||
399 | clear_msr_range(0x3BC, 3); | ||
400 | } else { | ||
401 | clear_msr_range(0x3A0, 31); | ||
402 | } | ||
403 | clear_msr_range(0x3C0, 6); | ||
404 | clear_msr_range(0x3C8, 6); | ||
405 | clear_msr_range(0x3E0, 2); | ||
406 | clear_msr_range(MSR_P4_CCCR0, 18); | ||
407 | clear_msr_range(MSR_P4_PERFCTR0, 18); | ||
408 | |||
409 | wrmsr(MSR_P4_CRU_ESCR0, P4_NMI_CRU_ESCR0, 0); | ||
410 | wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0 & ~P4_CCCR_ENABLE, 0); | ||
411 | Dprintk("setting P4_IQ_COUNTER0 to 0x%08lx\n", -(cpu_khz/nmi_hz*1000)); | ||
412 | wrmsr(MSR_P4_IQ_COUNTER0, -(cpu_khz/nmi_hz*1000), -1); | ||
413 | apic_write(APIC_LVTPC, APIC_DM_NMI); | ||
414 | wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); | ||
415 | return 1; | ||
416 | } | ||
417 | |||
334 | void setup_apic_nmi_watchdog(void) | 418 | void setup_apic_nmi_watchdog(void) |
335 | { | 419 | { |
336 | switch (boot_cpu_data.x86_vendor) { | 420 | switch (boot_cpu_data.x86_vendor) { |
@@ -341,6 +425,13 @@ void setup_apic_nmi_watchdog(void) | |||
341 | return; | 425 | return; |
342 | setup_k7_watchdog(); | 426 | setup_k7_watchdog(); |
343 | break; | 427 | break; |
428 | case X86_VENDOR_INTEL: | ||
429 | if (boot_cpu_data.x86 != 15) | ||
430 | return; | ||
431 | if (!setup_p4_watchdog()) | ||
432 | return; | ||
433 | break; | ||
434 | |||
344 | default: | 435 | default: |
345 | return; | 436 | return; |
346 | } | 437 | } |
@@ -355,56 +446,67 @@ void setup_apic_nmi_watchdog(void) | |||
355 | * | 446 | * |
356 | * as these watchdog NMI IRQs are generated on every CPU, we only | 447 | * as these watchdog NMI IRQs are generated on every CPU, we only |
357 | * have to check the current processor. | 448 | * have to check the current processor. |
358 | * | ||
359 | * since NMIs don't listen to _any_ locks, we have to be extremely | ||
360 | * careful not to rely on unsafe variables. The printk might lock | ||
361 | * up though, so we have to break up any console locks first ... | ||
362 | * [when there will be more tty-related locks, break them up | ||
363 | * here too!] | ||
364 | */ | 449 | */ |
365 | 450 | ||
366 | static unsigned int | 451 | static DEFINE_PER_CPU(unsigned, last_irq_sum); |
367 | last_irq_sums [NR_CPUS], | 452 | static DEFINE_PER_CPU(local_t, alert_counter); |
368 | alert_counter [NR_CPUS]; | 453 | static DEFINE_PER_CPU(int, nmi_touch); |
369 | 454 | ||
370 | void touch_nmi_watchdog (void) | 455 | void touch_nmi_watchdog (void) |
371 | { | 456 | { |
372 | int i; | 457 | int i; |
373 | 458 | ||
374 | /* | 459 | /* |
375 | * Just reset the alert counters, (other CPUs might be | 460 | * Tell other CPUs to reset their alert counters. We cannot |
376 | * spinning on locks we hold): | 461 | * do it ourselves because the alert count increase is not |
462 | * atomic. | ||
377 | */ | 463 | */ |
378 | for (i = 0; i < NR_CPUS; i++) | 464 | for (i = 0; i < NR_CPUS; i++) |
379 | alert_counter[i] = 0; | 465 | per_cpu(nmi_touch, i) = 1; |
380 | } | 466 | } |
381 | 467 | ||
382 | void nmi_watchdog_tick (struct pt_regs * regs, unsigned reason) | 468 | void nmi_watchdog_tick (struct pt_regs * regs, unsigned reason) |
383 | { | 469 | { |
384 | int sum, cpu; | 470 | int sum; |
471 | int touched = 0; | ||
385 | 472 | ||
386 | cpu = safe_smp_processor_id(); | ||
387 | sum = read_pda(apic_timer_irqs); | 473 | sum = read_pda(apic_timer_irqs); |
388 | if (last_irq_sums[cpu] == sum) { | 474 | if (__get_cpu_var(nmi_touch)) { |
475 | __get_cpu_var(nmi_touch) = 0; | ||
476 | touched = 1; | ||
477 | } | ||
478 | if (!touched && __get_cpu_var(last_irq_sum) == sum) { | ||
389 | /* | 479 | /* |
390 | * Ayiee, looks like this CPU is stuck ... | 480 | * Ayiee, looks like this CPU is stuck ... |
391 | * wait a few IRQs (5 seconds) before doing the oops ... | 481 | * wait a few IRQs (5 seconds) before doing the oops ... |
392 | */ | 482 | */ |
393 | alert_counter[cpu]++; | 483 | local_inc(&__get_cpu_var(alert_counter)); |
394 | if (alert_counter[cpu] == 5*nmi_hz) { | 484 | if (local_read(&__get_cpu_var(alert_counter)) == 5*nmi_hz) { |
395 | if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) | 485 | if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) |
396 | == NOTIFY_STOP) { | 486 | == NOTIFY_STOP) { |
397 | alert_counter[cpu] = 0; | 487 | local_set(&__get_cpu_var(alert_counter), 0); |
398 | return; | 488 | return; |
399 | } | 489 | } |
400 | die_nmi("NMI Watchdog detected LOCKUP on CPU%d", regs); | 490 | die_nmi("NMI Watchdog detected LOCKUP on CPU%d", regs); |
401 | } | 491 | } |
402 | } else { | 492 | } else { |
403 | last_irq_sums[cpu] = sum; | 493 | __get_cpu_var(last_irq_sum) = sum; |
404 | alert_counter[cpu] = 0; | 494 | local_set(&__get_cpu_var(alert_counter), 0); |
405 | } | 495 | } |
406 | if (nmi_perfctr_msr) | 496 | if (nmi_perfctr_msr) { |
497 | if (nmi_perfctr_msr == MSR_P4_IQ_COUNTER0) { | ||
498 | /* | ||
499 | * P4 quirks: | ||
500 | * - An overflown perfctr will assert its interrupt | ||
501 | * until the OVF flag in its CCCR is cleared. | ||
502 | * - LVTPC is masked on interrupt and must be | ||
503 | * unmasked by the LVTPC handler. | ||
504 | */ | ||
505 | wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); | ||
506 | apic_write(APIC_LVTPC, APIC_DM_NMI); | ||
507 | } | ||
407 | wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1); | 508 | wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1); |
509 | } | ||
408 | } | 510 | } |
409 | 511 | ||
410 | static int dummy_nmi_callback(struct pt_regs * regs, int cpu) | 512 | static int dummy_nmi_callback(struct pt_regs * regs, int cpu) |
diff --git a/arch/x86_64/kernel/pmtimer.c b/arch/x86_64/kernel/pmtimer.c new file mode 100644 index 000000000000..feb5f108dd26 --- /dev/null +++ b/arch/x86_64/kernel/pmtimer.c | |||
@@ -0,0 +1,101 @@ | |||
1 | /* Ported over from i386 by AK, original copyright was: | ||
2 | * | ||
3 | * (C) Dominik Brodowski <linux@brodo.de> 2003 | ||
4 | * | ||
5 | * Driver to use the Power Management Timer (PMTMR) available in some | ||
6 | * southbridges as primary timing source for the Linux kernel. | ||
7 | * | ||
8 | * Based on parts of linux/drivers/acpi/hardware/hwtimer.c, timer_pit.c, | ||
9 | * timer_hpet.c, and on Arjan van de Ven's implementation for 2.4. | ||
10 | * | ||
11 | * This file is licensed under the GPL v2. | ||
12 | * | ||
13 | * Dropped all the hardware bug workarounds for now. Hopefully they | ||
14 | * are not needed on 64bit chipsets. | ||
15 | */ | ||
16 | |||
17 | #include <linux/jiffies.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/time.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/cpumask.h> | ||
22 | #include <asm/io.h> | ||
23 | #include <asm/proto.h> | ||
24 | #include <asm/msr.h> | ||
25 | #include <asm/vsyscall.h> | ||
26 | |||
27 | /* The I/O port the PMTMR resides at. | ||
28 | * The location is detected during setup_arch(), | ||
29 | * in arch/i386/kernel/acpi/boot.c */ | ||
30 | u32 pmtmr_ioport; | ||
31 | |||
32 | /* value of the Power timer at last timer interrupt */ | ||
33 | static u32 offset_delay; | ||
34 | static u32 last_pmtmr_tick; | ||
35 | |||
36 | #define ACPI_PM_MASK 0xFFFFFF /* limit it to 24 bits */ | ||
37 | |||
38 | static inline u32 cyc2us(u32 cycles) | ||
39 | { | ||
40 | /* The Power Management Timer ticks at 3.579545 ticks per microsecond. | ||
41 | * 1 / PM_TIMER_FREQUENCY == 0.27936511 =~ 286/1024 [error: 0.024%] | ||
42 | * | ||
43 | * Even with HZ = 100, delta is at maximum 35796 ticks, so it can | ||
44 | * easily be multiplied with 286 (=0x11E) without having to fear | ||
45 | * u32 overflows. | ||
46 | */ | ||
47 | cycles *= 286; | ||
48 | return (cycles >> 10); | ||
49 | } | ||
50 | |||
51 | int pmtimer_mark_offset(void) | ||
52 | { | ||
53 | static int first_run = 1; | ||
54 | unsigned long tsc; | ||
55 | u32 lost; | ||
56 | |||
57 | u32 tick = inl(pmtmr_ioport); | ||
58 | u32 delta; | ||
59 | |||
60 | delta = cyc2us((tick - last_pmtmr_tick) & ACPI_PM_MASK); | ||
61 | |||
62 | last_pmtmr_tick = tick; | ||
63 | monotonic_base += delta * NSEC_PER_USEC; | ||
64 | |||
65 | delta += offset_delay; | ||
66 | |||
67 | lost = delta / (USEC_PER_SEC / HZ); | ||
68 | offset_delay = delta % (USEC_PER_SEC / HZ); | ||
69 | |||
70 | rdtscll(tsc); | ||
71 | vxtime.last_tsc = tsc - offset_delay * cpu_khz; | ||
72 | |||
73 | /* don't calculate delay for first run, | ||
74 | or if we've got less then a tick */ | ||
75 | if (first_run || (lost < 1)) { | ||
76 | first_run = 0; | ||
77 | offset_delay = 0; | ||
78 | } | ||
79 | |||
80 | return lost - 1; | ||
81 | } | ||
82 | |||
83 | unsigned int do_gettimeoffset_pm(void) | ||
84 | { | ||
85 | u32 now, offset, delta = 0; | ||
86 | |||
87 | offset = last_pmtmr_tick; | ||
88 | now = inl(pmtmr_ioport); | ||
89 | delta = (now - offset) & ACPI_PM_MASK; | ||
90 | |||
91 | return offset_delay + cyc2us(delta); | ||
92 | } | ||
93 | |||
94 | |||
95 | static int __init nopmtimer_setup(char *s) | ||
96 | { | ||
97 | pmtmr_ioport = 0; | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | __setup("nopmtimer", nopmtimer_setup); | ||
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c index c64b9c97c745..525f6a128a27 100644 --- a/arch/x86_64/kernel/ptrace.c +++ b/arch/x86_64/kernel/ptrace.c | |||
@@ -257,13 +257,13 @@ static int putreg(struct task_struct *child, | |||
257 | value &= 0xffff; | 257 | value &= 0xffff; |
258 | return 0; | 258 | return 0; |
259 | case offsetof(struct user_regs_struct,fs_base): | 259 | case offsetof(struct user_regs_struct,fs_base): |
260 | if (!((value >> 48) == 0 || (value >> 48) == 0xffff)) | 260 | if (value >= TASK_SIZE) |
261 | return -EIO; | 261 | return -EIO; |
262 | child->thread.fs = value; | 262 | child->thread.fs = value; |
263 | return 0; | 263 | return 0; |
264 | case offsetof(struct user_regs_struct,gs_base): | 264 | case offsetof(struct user_regs_struct,gs_base): |
265 | if (!((value >> 48) == 0 || (value >> 48) == 0xffff)) | 265 | if (value >= TASK_SIZE) |
266 | return -EIO; | 266 | return -EIO; |
267 | child->thread.gs = value; | 267 | child->thread.gs = value; |
268 | return 0; | 268 | return 0; |
269 | case offsetof(struct user_regs_struct, eflags): | 269 | case offsetof(struct user_regs_struct, eflags): |
@@ -277,6 +277,11 @@ static int putreg(struct task_struct *child, | |||
277 | return -EIO; | 277 | return -EIO; |
278 | value &= 0xffff; | 278 | value &= 0xffff; |
279 | break; | 279 | break; |
280 | case offsetof(struct user_regs_struct, rip): | ||
281 | /* Check if the new RIP address is canonical */ | ||
282 | if (value >= TASK_SIZE) | ||
283 | return -EIO; | ||
284 | break; | ||
280 | } | 285 | } |
281 | put_stack_long(child, regno - sizeof(struct pt_regs), value); | 286 | put_stack_long(child, regno - sizeof(struct pt_regs), value); |
282 | return 0; | 287 | return 0; |
@@ -375,7 +380,7 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data | |||
375 | break; | 380 | break; |
376 | 381 | ||
377 | switch (addr) { | 382 | switch (addr) { |
378 | case 0 ... sizeof(struct user_regs_struct): | 383 | case 0 ... sizeof(struct user_regs_struct) - sizeof(long): |
379 | tmp = getreg(child, addr); | 384 | tmp = getreg(child, addr); |
380 | break; | 385 | break; |
381 | case offsetof(struct user, u_debugreg[0]): | 386 | case offsetof(struct user, u_debugreg[0]): |
@@ -420,7 +425,7 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data | |||
420 | break; | 425 | break; |
421 | 426 | ||
422 | switch (addr) { | 427 | switch (addr) { |
423 | case 0 ... sizeof(struct user_regs_struct): | 428 | case 0 ... sizeof(struct user_regs_struct) - sizeof(long): |
424 | ret = putreg(child, addr, data); | 429 | ret = putreg(child, addr, data); |
425 | break; | 430 | break; |
426 | /* Disallows to set a breakpoint into the vsyscall */ | 431 | /* Disallows to set a breakpoint into the vsyscall */ |
@@ -635,20 +640,29 @@ asmlinkage void syscall_trace_enter(struct pt_regs *regs) | |||
635 | /* do the secure computing check first */ | 640 | /* do the secure computing check first */ |
636 | secure_computing(regs->orig_rax); | 641 | secure_computing(regs->orig_rax); |
637 | 642 | ||
638 | if (unlikely(current->audit_context)) | ||
639 | audit_syscall_entry(current, regs->orig_rax, | ||
640 | regs->rdi, regs->rsi, | ||
641 | regs->rdx, regs->r10); | ||
642 | |||
643 | if (test_thread_flag(TIF_SYSCALL_TRACE) | 643 | if (test_thread_flag(TIF_SYSCALL_TRACE) |
644 | && (current->ptrace & PT_PTRACED)) | 644 | && (current->ptrace & PT_PTRACED)) |
645 | syscall_trace(regs); | 645 | syscall_trace(regs); |
646 | |||
647 | if (unlikely(current->audit_context)) { | ||
648 | if (test_thread_flag(TIF_IA32)) { | ||
649 | audit_syscall_entry(current, AUDIT_ARCH_I386, | ||
650 | regs->orig_rax, | ||
651 | regs->rbx, regs->rcx, | ||
652 | regs->rdx, regs->rsi); | ||
653 | } else { | ||
654 | audit_syscall_entry(current, AUDIT_ARCH_X86_64, | ||
655 | regs->orig_rax, | ||
656 | regs->rdi, regs->rsi, | ||
657 | regs->rdx, regs->r10); | ||
658 | } | ||
659 | } | ||
646 | } | 660 | } |
647 | 661 | ||
648 | asmlinkage void syscall_trace_leave(struct pt_regs *regs) | 662 | asmlinkage void syscall_trace_leave(struct pt_regs *regs) |
649 | { | 663 | { |
650 | if (unlikely(current->audit_context)) | 664 | if (unlikely(current->audit_context)) |
651 | audit_syscall_exit(current, regs->rax); | 665 | audit_syscall_exit(current, AUDITSC_RESULT(regs->rax), regs->rax); |
652 | 666 | ||
653 | if ((test_thread_flag(TIF_SYSCALL_TRACE) | 667 | if ((test_thread_flag(TIF_SYSCALL_TRACE) |
654 | || test_thread_flag(TIF_SINGLESTEP)) | 668 | || test_thread_flag(TIF_SINGLESTEP)) |
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 2129cf9ba6b2..99f038ede23c 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c | |||
@@ -719,7 +719,6 @@ static void __init display_cacheinfo(struct cpuinfo_x86 *c) | |||
719 | } | 719 | } |
720 | } | 720 | } |
721 | 721 | ||
722 | #ifdef CONFIG_SMP | ||
723 | /* | 722 | /* |
724 | * On a AMD dual core setup the lower bits of the APIC id distingush the cores. | 723 | * On a AMD dual core setup the lower bits of the APIC id distingush the cores. |
725 | * Assumes number of cores is a power of two. | 724 | * Assumes number of cores is a power of two. |
@@ -727,17 +726,26 @@ static void __init display_cacheinfo(struct cpuinfo_x86 *c) | |||
727 | static void __init amd_detect_cmp(struct cpuinfo_x86 *c) | 726 | static void __init amd_detect_cmp(struct cpuinfo_x86 *c) |
728 | { | 727 | { |
729 | #ifdef CONFIG_SMP | 728 | #ifdef CONFIG_SMP |
730 | int cpu = c->x86_apicid; | 729 | int cpu = smp_processor_id(); |
731 | int node = 0; | 730 | int node = 0; |
731 | unsigned bits; | ||
732 | if (c->x86_num_cores == 1) | 732 | if (c->x86_num_cores == 1) |
733 | return; | 733 | return; |
734 | cpu_core_id[cpu] = cpu >> hweight32(c->x86_num_cores - 1); | 734 | |
735 | bits = 0; | ||
736 | while ((1 << bits) < c->x86_num_cores) | ||
737 | bits++; | ||
738 | |||
739 | /* Low order bits define the core id (index of core in socket) */ | ||
740 | cpu_core_id[cpu] = phys_proc_id[cpu] & ((1 << bits)-1); | ||
741 | /* Convert the APIC ID into the socket ID */ | ||
742 | phys_proc_id[cpu] >>= bits; | ||
735 | 743 | ||
736 | #ifdef CONFIG_NUMA | 744 | #ifdef CONFIG_NUMA |
737 | /* When an ACPI SRAT table is available use the mappings from SRAT | 745 | /* When an ACPI SRAT table is available use the mappings from SRAT |
738 | instead. */ | 746 | instead. */ |
739 | if (acpi_numa <= 0) { | 747 | if (acpi_numa <= 0) { |
740 | node = cpu_core_id[cpu]; | 748 | node = phys_proc_id[cpu]; |
741 | if (!node_online(node)) | 749 | if (!node_online(node)) |
742 | node = first_node(node_online_map); | 750 | node = first_node(node_online_map); |
743 | cpu_to_node[cpu] = node; | 751 | cpu_to_node[cpu] = node; |
@@ -745,15 +753,11 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c) | |||
745 | node = cpu_to_node[cpu]; | 753 | node = cpu_to_node[cpu]; |
746 | } | 754 | } |
747 | #endif | 755 | #endif |
756 | |||
748 | printk(KERN_INFO "CPU %d(%d) -> Node %d -> Core %d\n", | 757 | printk(KERN_INFO "CPU %d(%d) -> Node %d -> Core %d\n", |
749 | cpu, c->x86_num_cores, node, cpu_core_id[cpu]); | 758 | cpu, c->x86_num_cores, node, cpu_core_id[cpu]); |
750 | #endif | 759 | #endif |
751 | } | 760 | } |
752 | #else | ||
753 | static void __init amd_detect_cmp(struct cpuinfo_x86 *c) | ||
754 | { | ||
755 | } | ||
756 | #endif | ||
757 | 761 | ||
758 | static int __init init_amd(struct cpuinfo_x86 *c) | 762 | static int __init init_amd(struct cpuinfo_x86 *c) |
759 | { | 763 | { |
@@ -925,7 +929,6 @@ void __init early_identify_cpu(struct cpuinfo_x86 *c) | |||
925 | c->x86_clflush_size = 64; | 929 | c->x86_clflush_size = 64; |
926 | c->x86_cache_alignment = c->x86_clflush_size; | 930 | c->x86_cache_alignment = c->x86_clflush_size; |
927 | c->x86_num_cores = 1; | 931 | c->x86_num_cores = 1; |
928 | c->x86_apicid = c == &boot_cpu_data ? 0 : c - cpu_data; | ||
929 | c->extended_cpuid_level = 0; | 932 | c->extended_cpuid_level = 0; |
930 | memset(&c->x86_capability, 0, sizeof c->x86_capability); | 933 | memset(&c->x86_capability, 0, sizeof c->x86_capability); |
931 | 934 | ||
@@ -954,11 +957,14 @@ void __init early_identify_cpu(struct cpuinfo_x86 *c) | |||
954 | } | 957 | } |
955 | if (c->x86_capability[0] & (1<<19)) | 958 | if (c->x86_capability[0] & (1<<19)) |
956 | c->x86_clflush_size = ((misc >> 8) & 0xff) * 8; | 959 | c->x86_clflush_size = ((misc >> 8) & 0xff) * 8; |
957 | c->x86_apicid = misc >> 24; | ||
958 | } else { | 960 | } else { |
959 | /* Have CPUID level 0 only - unheard of */ | 961 | /* Have CPUID level 0 only - unheard of */ |
960 | c->x86 = 4; | 962 | c->x86 = 4; |
961 | } | 963 | } |
964 | |||
965 | #ifdef CONFIG_SMP | ||
966 | phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff; | ||
967 | #endif | ||
962 | } | 968 | } |
963 | 969 | ||
964 | /* | 970 | /* |
@@ -1088,7 +1094,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
1088 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 1094 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
1089 | 1095 | ||
1090 | /* Other (Linux-defined) */ | 1096 | /* Other (Linux-defined) */ |
1091 | "cxmmx", NULL, "cyrix_arr", "centaur_mcr", "k8c+", | 1097 | "cxmmx", NULL, "cyrix_arr", "centaur_mcr", NULL, |
1092 | "constant_tsc", NULL, NULL, | 1098 | "constant_tsc", NULL, NULL, |
1093 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 1099 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
1094 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 1100 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c index d439ced150c6..429c0269dc4e 100644 --- a/arch/x86_64/kernel/signal.c +++ b/arch/x86_64/kernel/signal.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
29 | #include <asm/i387.h> | 29 | #include <asm/i387.h> |
30 | #include <asm/proto.h> | 30 | #include <asm/proto.h> |
31 | #include <asm/ia32_unistd.h> | ||
31 | 32 | ||
32 | /* #define DEBUG_SIG 1 */ | 33 | /* #define DEBUG_SIG 1 */ |
33 | 34 | ||
@@ -452,7 +453,9 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
452 | regs->rip -= 2; | 453 | regs->rip -= 2; |
453 | } | 454 | } |
454 | if (regs->rax == (unsigned long)-ERESTART_RESTARTBLOCK) { | 455 | if (regs->rax == (unsigned long)-ERESTART_RESTARTBLOCK) { |
455 | regs->rax = __NR_restart_syscall; | 456 | regs->rax = test_thread_flag(TIF_IA32) ? |
457 | __NR_ia32_restart_syscall : | ||
458 | __NR_restart_syscall; | ||
456 | regs->rip -= 2; | 459 | regs->rip -= 2; |
457 | } | 460 | } |
458 | } | 461 | } |
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index 73f7e8b9543a..f1ec0f345941 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include <asm/kdebug.h> | 56 | #include <asm/kdebug.h> |
57 | #include <asm/tlbflush.h> | 57 | #include <asm/tlbflush.h> |
58 | #include <asm/proto.h> | 58 | #include <asm/proto.h> |
59 | #include <asm/nmi.h> | ||
59 | 60 | ||
60 | /* Change for real CPU hotplug. Note other files need to be fixed | 61 | /* Change for real CPU hotplug. Note other files need to be fixed |
61 | first too. */ | 62 | first too. */ |
@@ -93,6 +94,7 @@ int smp_threads_ready; | |||
93 | 94 | ||
94 | cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; | 95 | cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; |
95 | cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; | 96 | cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; |
97 | EXPORT_SYMBOL(cpu_core_map); | ||
96 | 98 | ||
97 | /* | 99 | /* |
98 | * Trampoline 80x86 program as an array. | 100 | * Trampoline 80x86 program as an array. |
@@ -125,96 +127,210 @@ static void __cpuinit smp_store_cpu_info(int id) | |||
125 | 127 | ||
126 | *c = boot_cpu_data; | 128 | *c = boot_cpu_data; |
127 | identify_cpu(c); | 129 | identify_cpu(c); |
130 | print_cpu_info(c); | ||
128 | } | 131 | } |
129 | 132 | ||
130 | /* | 133 | /* |
131 | * Synchronize TSCs of CPUs | 134 | * New Funky TSC sync algorithm borrowed from IA64. |
135 | * Main advantage is that it doesn't reset the TSCs fully and | ||
136 | * in general looks more robust and it works better than my earlier | ||
137 | * attempts. I believe it was written by David Mosberger. Some minor | ||
138 | * adjustments for x86-64 by me -AK | ||
132 | * | 139 | * |
133 | * This new algorithm is less accurate than the old "zero TSCs" | 140 | * Original comment reproduced below. |
134 | * one, but we cannot zero TSCs anymore in the new hotplug CPU | 141 | * |
135 | * model. | 142 | * Synchronize TSC of the current (slave) CPU with the TSC of the |
143 | * MASTER CPU (normally the time-keeper CPU). We use a closed loop to | ||
144 | * eliminate the possibility of unaccounted-for errors (such as | ||
145 | * getting a machine check in the middle of a calibration step). The | ||
146 | * basic idea is for the slave to ask the master what itc value it has | ||
147 | * and to read its own itc before and after the master responds. Each | ||
148 | * iteration gives us three timestamps: | ||
149 | * | ||
150 | * slave master | ||
151 | * | ||
152 | * t0 ---\ | ||
153 | * ---\ | ||
154 | * ---> | ||
155 | * tm | ||
156 | * /--- | ||
157 | * /--- | ||
158 | * t1 <--- | ||
159 | * | ||
160 | * | ||
161 | * The goal is to adjust the slave's TSC such that tm falls exactly | ||
162 | * half-way between t0 and t1. If we achieve this, the clocks are | ||
163 | * synchronized provided the interconnect between the slave and the | ||
164 | * master is symmetric. Even if the interconnect were asymmetric, we | ||
165 | * would still know that the synchronization error is smaller than the | ||
166 | * roundtrip latency (t0 - t1). | ||
167 | * | ||
168 | * When the interconnect is quiet and symmetric, this lets us | ||
169 | * synchronize the TSC to within one or two cycles. However, we can | ||
170 | * only *guarantee* that the synchronization is accurate to within a | ||
171 | * round-trip time, which is typically in the range of several hundred | ||
172 | * cycles (e.g., ~500 cycles). In practice, this means that the TSCs | ||
173 | * are usually almost perfectly synchronized, but we shouldn't assume | ||
174 | * that the accuracy is much better than half a micro second or so. | ||
175 | * | ||
176 | * [there are other errors like the latency of RDTSC and of the | ||
177 | * WRMSR. These can also account to hundreds of cycles. So it's | ||
178 | * probably worse. It claims 153 cycles error on a dual Opteron, | ||
179 | * but I suspect the numbers are actually somewhat worse -AK] | ||
136 | */ | 180 | */ |
137 | 181 | ||
138 | static atomic_t __cpuinitdata tsc_flag; | 182 | #define MASTER 0 |
183 | #define SLAVE (SMP_CACHE_BYTES/8) | ||
184 | |||
185 | /* Intentionally don't use cpu_relax() while TSC synchronization | ||
186 | because we don't want to go into funky power save modi or cause | ||
187 | hypervisors to schedule us away. Going to sleep would likely affect | ||
188 | latency and low latency is the primary objective here. -AK */ | ||
189 | #define no_cpu_relax() barrier() | ||
190 | |||
139 | static __cpuinitdata DEFINE_SPINLOCK(tsc_sync_lock); | 191 | static __cpuinitdata DEFINE_SPINLOCK(tsc_sync_lock); |
140 | static unsigned long long __cpuinitdata bp_tsc, ap_tsc; | 192 | static volatile __cpuinitdata unsigned long go[SLAVE + 1]; |
193 | static int notscsync __cpuinitdata; | ||
194 | |||
195 | #undef DEBUG_TSC_SYNC | ||
141 | 196 | ||
142 | #define NR_LOOPS 5 | 197 | #define NUM_ROUNDS 64 /* magic value */ |
198 | #define NUM_ITERS 5 /* likewise */ | ||
143 | 199 | ||
144 | static void __cpuinit sync_tsc_bp_init(int init) | 200 | /* Callback on boot CPU */ |
201 | static __cpuinit void sync_master(void *arg) | ||
145 | { | 202 | { |
146 | if (init) | 203 | unsigned long flags, i; |
147 | _raw_spin_lock(&tsc_sync_lock); | 204 | |
148 | else | 205 | if (smp_processor_id() != boot_cpu_id) |
149 | _raw_spin_unlock(&tsc_sync_lock); | 206 | return; |
150 | atomic_set(&tsc_flag, 0); | 207 | |
208 | go[MASTER] = 0; | ||
209 | |||
210 | local_irq_save(flags); | ||
211 | { | ||
212 | for (i = 0; i < NUM_ROUNDS*NUM_ITERS; ++i) { | ||
213 | while (!go[MASTER]) | ||
214 | no_cpu_relax(); | ||
215 | go[MASTER] = 0; | ||
216 | rdtscll(go[SLAVE]); | ||
217 | } | ||
218 | } | ||
219 | local_irq_restore(flags); | ||
151 | } | 220 | } |
152 | 221 | ||
153 | /* | 222 | /* |
154 | * Synchronize TSC on AP with BP. | 223 | * Return the number of cycles by which our tsc differs from the tsc |
224 | * on the master (time-keeper) CPU. A positive number indicates our | ||
225 | * tsc is ahead of the master, negative that it is behind. | ||
155 | */ | 226 | */ |
156 | static void __cpuinit __sync_tsc_ap(void) | 227 | static inline long |
228 | get_delta(long *rt, long *master) | ||
157 | { | 229 | { |
158 | if (!cpu_has_tsc) | 230 | unsigned long best_t0 = 0, best_t1 = ~0UL, best_tm = 0; |
159 | return; | 231 | unsigned long tcenter, t0, t1, tm; |
160 | Dprintk("AP %d syncing TSC\n", smp_processor_id()); | 232 | int i; |
161 | 233 | ||
162 | while (atomic_read(&tsc_flag) != 0) | 234 | for (i = 0; i < NUM_ITERS; ++i) { |
163 | cpu_relax(); | 235 | rdtscll(t0); |
164 | atomic_inc(&tsc_flag); | 236 | go[MASTER] = 1; |
165 | mb(); | 237 | while (!(tm = go[SLAVE])) |
166 | _raw_spin_lock(&tsc_sync_lock); | 238 | no_cpu_relax(); |
167 | wrmsrl(MSR_IA32_TSC, bp_tsc); | 239 | go[SLAVE] = 0; |
168 | _raw_spin_unlock(&tsc_sync_lock); | 240 | rdtscll(t1); |
169 | rdtscll(ap_tsc); | 241 | |
170 | mb(); | 242 | if (t1 - t0 < best_t1 - best_t0) |
171 | atomic_inc(&tsc_flag); | 243 | best_t0 = t0, best_t1 = t1, best_tm = tm; |
172 | mb(); | 244 | } |
245 | |||
246 | *rt = best_t1 - best_t0; | ||
247 | *master = best_tm - best_t0; | ||
248 | |||
249 | /* average best_t0 and best_t1 without overflow: */ | ||
250 | tcenter = (best_t0/2 + best_t1/2); | ||
251 | if (best_t0 % 2 + best_t1 % 2 == 2) | ||
252 | ++tcenter; | ||
253 | return tcenter - best_tm; | ||
173 | } | 254 | } |
174 | 255 | ||
175 | static void __cpuinit sync_tsc_ap(void) | 256 | static __cpuinit void sync_tsc(void) |
176 | { | 257 | { |
177 | int i; | 258 | int i, done = 0; |
178 | for (i = 0; i < NR_LOOPS; i++) | 259 | long delta, adj, adjust_latency = 0; |
179 | __sync_tsc_ap(); | 260 | unsigned long flags, rt, master_time_stamp, bound; |
261 | #if DEBUG_TSC_SYNC | ||
262 | static struct syncdebug { | ||
263 | long rt; /* roundtrip time */ | ||
264 | long master; /* master's timestamp */ | ||
265 | long diff; /* difference between midpoint and master's timestamp */ | ||
266 | long lat; /* estimate of tsc adjustment latency */ | ||
267 | } t[NUM_ROUNDS] __cpuinitdata; | ||
268 | #endif | ||
269 | |||
270 | go[MASTER] = 1; | ||
271 | |||
272 | smp_call_function(sync_master, NULL, 1, 0); | ||
273 | |||
274 | while (go[MASTER]) /* wait for master to be ready */ | ||
275 | no_cpu_relax(); | ||
276 | |||
277 | spin_lock_irqsave(&tsc_sync_lock, flags); | ||
278 | { | ||
279 | for (i = 0; i < NUM_ROUNDS; ++i) { | ||
280 | delta = get_delta(&rt, &master_time_stamp); | ||
281 | if (delta == 0) { | ||
282 | done = 1; /* let's lock on to this... */ | ||
283 | bound = rt; | ||
284 | } | ||
285 | |||
286 | if (!done) { | ||
287 | unsigned long t; | ||
288 | if (i > 0) { | ||
289 | adjust_latency += -delta; | ||
290 | adj = -delta + adjust_latency/4; | ||
291 | } else | ||
292 | adj = -delta; | ||
293 | |||
294 | rdtscll(t); | ||
295 | wrmsrl(MSR_IA32_TSC, t + adj); | ||
296 | } | ||
297 | #if DEBUG_TSC_SYNC | ||
298 | t[i].rt = rt; | ||
299 | t[i].master = master_time_stamp; | ||
300 | t[i].diff = delta; | ||
301 | t[i].lat = adjust_latency/4; | ||
302 | #endif | ||
303 | } | ||
304 | } | ||
305 | spin_unlock_irqrestore(&tsc_sync_lock, flags); | ||
306 | |||
307 | #if DEBUG_TSC_SYNC | ||
308 | for (i = 0; i < NUM_ROUNDS; ++i) | ||
309 | printk("rt=%5ld master=%5ld diff=%5ld adjlat=%5ld\n", | ||
310 | t[i].rt, t[i].master, t[i].diff, t[i].lat); | ||
311 | #endif | ||
312 | |||
313 | printk(KERN_INFO | ||
314 | "CPU %d: synchronized TSC with CPU %u (last diff %ld cycles, " | ||
315 | "maxerr %lu cycles)\n", | ||
316 | smp_processor_id(), boot_cpu_id, delta, rt); | ||
180 | } | 317 | } |
181 | 318 | ||
182 | /* | 319 | static void __cpuinit tsc_sync_wait(void) |
183 | * Synchronize TSC from BP to AP. | ||
184 | */ | ||
185 | static void __cpuinit __sync_tsc_bp(int cpu) | ||
186 | { | 320 | { |
187 | if (!cpu_has_tsc) | 321 | if (notscsync || !cpu_has_tsc) |
188 | return; | 322 | return; |
189 | 323 | printk(KERN_INFO "CPU %d: Syncing TSC to CPU %u.\n", smp_processor_id(), | |
190 | /* Wait for AP */ | 324 | boot_cpu_id); |
191 | while (atomic_read(&tsc_flag) == 0) | 325 | sync_tsc(); |
192 | cpu_relax(); | ||
193 | /* Save BPs TSC */ | ||
194 | sync_core(); | ||
195 | rdtscll(bp_tsc); | ||
196 | /* Don't do the sync core here to avoid too much latency. */ | ||
197 | mb(); | ||
198 | /* Start the AP */ | ||
199 | _raw_spin_unlock(&tsc_sync_lock); | ||
200 | /* Wait for AP again */ | ||
201 | while (atomic_read(&tsc_flag) < 2) | ||
202 | cpu_relax(); | ||
203 | rdtscl(bp_tsc); | ||
204 | barrier(); | ||
205 | } | 326 | } |
206 | 327 | ||
207 | static void __cpuinit sync_tsc_bp(int cpu) | 328 | static __init int notscsync_setup(char *s) |
208 | { | 329 | { |
209 | int i; | 330 | notscsync = 1; |
210 | for (i = 0; i < NR_LOOPS - 1; i++) { | 331 | return 0; |
211 | __sync_tsc_bp(cpu); | ||
212 | sync_tsc_bp_init(1); | ||
213 | } | ||
214 | __sync_tsc_bp(cpu); | ||
215 | printk(KERN_INFO "Synced TSC of CPU %d difference %Ld\n", | ||
216 | cpu, ap_tsc - bp_tsc); | ||
217 | } | 332 | } |
333 | __setup("notscsync", notscsync_setup); | ||
218 | 334 | ||
219 | static atomic_t init_deasserted __cpuinitdata; | 335 | static atomic_t init_deasserted __cpuinitdata; |
220 | 336 | ||
@@ -315,11 +431,6 @@ void __cpuinit start_secondary(void) | |||
315 | cpu_init(); | 431 | cpu_init(); |
316 | smp_callin(); | 432 | smp_callin(); |
317 | 433 | ||
318 | /* | ||
319 | * Synchronize the TSC with the BP | ||
320 | */ | ||
321 | sync_tsc_ap(); | ||
322 | |||
323 | /* otherwise gcc will move up the smp_processor_id before the cpu_init */ | 434 | /* otherwise gcc will move up the smp_processor_id before the cpu_init */ |
324 | barrier(); | 435 | barrier(); |
325 | 436 | ||
@@ -334,7 +445,6 @@ void __cpuinit start_secondary(void) | |||
334 | enable_8259A_irq(0); | 445 | enable_8259A_irq(0); |
335 | } | 446 | } |
336 | 447 | ||
337 | |||
338 | enable_APIC_timer(); | 448 | enable_APIC_timer(); |
339 | 449 | ||
340 | /* | 450 | /* |
@@ -343,6 +453,11 @@ void __cpuinit start_secondary(void) | |||
343 | cpu_set(smp_processor_id(), cpu_online_map); | 453 | cpu_set(smp_processor_id(), cpu_online_map); |
344 | mb(); | 454 | mb(); |
345 | 455 | ||
456 | /* Wait for TSC sync to not schedule things before. | ||
457 | We still process interrupts, which could see an inconsistent | ||
458 | time in that window unfortunately. */ | ||
459 | tsc_sync_wait(); | ||
460 | |||
346 | cpu_idle(); | 461 | cpu_idle(); |
347 | } | 462 | } |
348 | 463 | ||
@@ -531,7 +646,6 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid) | |||
531 | printk("failed fork for CPU %d\n", cpu); | 646 | printk("failed fork for CPU %d\n", cpu); |
532 | return PTR_ERR(idle); | 647 | return PTR_ERR(idle); |
533 | } | 648 | } |
534 | x86_cpu_to_apicid[cpu] = apicid; | ||
535 | 649 | ||
536 | cpu_pda[cpu].pcurrent = idle; | 650 | cpu_pda[cpu].pcurrent = idle; |
537 | 651 | ||
@@ -600,8 +714,6 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid) | |||
600 | 714 | ||
601 | if (cpu_isset(cpu, cpu_callin_map)) { | 715 | if (cpu_isset(cpu, cpu_callin_map)) { |
602 | /* number CPUs logically, starting from 1 (BSP is 0) */ | 716 | /* number CPUs logically, starting from 1 (BSP is 0) */ |
603 | Dprintk("OK.\n"); | ||
604 | print_cpu_info(&cpu_data[cpu]); | ||
605 | Dprintk("CPU has booted.\n"); | 717 | Dprintk("CPU has booted.\n"); |
606 | } else { | 718 | } else { |
607 | boot_error = 1; | 719 | boot_error = 1; |
@@ -842,7 +954,6 @@ void __cpuinit smp_prepare_cpus(unsigned int max_cpus) | |||
842 | GET_APIC_ID(apic_read(APIC_ID)), boot_cpu_id); | 954 | GET_APIC_ID(apic_read(APIC_ID)), boot_cpu_id); |
843 | /* Or can we switch back to PIC here? */ | 955 | /* Or can we switch back to PIC here? */ |
844 | } | 956 | } |
845 | x86_cpu_to_apicid[0] = boot_cpu_id; | ||
846 | 957 | ||
847 | /* | 958 | /* |
848 | * Now start the IO-APICs | 959 | * Now start the IO-APICs |
@@ -889,18 +1000,14 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
889 | printk("__cpu_up: bad cpu %d\n", cpu); | 1000 | printk("__cpu_up: bad cpu %d\n", cpu); |
890 | return -EINVAL; | 1001 | return -EINVAL; |
891 | } | 1002 | } |
892 | sync_tsc_bp_init(1); | ||
893 | 1003 | ||
894 | /* Boot it! */ | 1004 | /* Boot it! */ |
895 | err = do_boot_cpu(cpu, apicid); | 1005 | err = do_boot_cpu(cpu, apicid); |
896 | if (err < 0) { | 1006 | if (err < 0) { |
897 | sync_tsc_bp_init(0); | ||
898 | Dprintk("do_boot_cpu failed %d\n", err); | 1007 | Dprintk("do_boot_cpu failed %d\n", err); |
899 | return err; | 1008 | return err; |
900 | } | 1009 | } |
901 | 1010 | ||
902 | sync_tsc_bp(cpu); | ||
903 | |||
904 | /* Unleash the CPU! */ | 1011 | /* Unleash the CPU! */ |
905 | Dprintk("waiting for cpu %d\n", cpu); | 1012 | Dprintk("waiting for cpu %d\n", cpu); |
906 | 1013 | ||
@@ -923,4 +1030,6 @@ void __cpuinit smp_cpus_done(unsigned int max_cpus) | |||
923 | 1030 | ||
924 | detect_siblings(); | 1031 | detect_siblings(); |
925 | time_init_gtod(); | 1032 | time_init_gtod(); |
1033 | |||
1034 | check_nmi_watchdog(); | ||
926 | } | 1035 | } |
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index 0e3b60e1ac5b..fb8c809b4cd9 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c | |||
@@ -26,6 +26,10 @@ | |||
26 | #include <linux/sysdev.h> | 26 | #include <linux/sysdev.h> |
27 | #include <linux/bcd.h> | 27 | #include <linux/bcd.h> |
28 | #include <linux/kallsyms.h> | 28 | #include <linux/kallsyms.h> |
29 | #include <linux/acpi.h> | ||
30 | #ifdef CONFIG_ACPI | ||
31 | #include <acpi/achware.h> /* for PM timer frequency */ | ||
32 | #endif | ||
29 | #include <asm/8253pit.h> | 33 | #include <asm/8253pit.h> |
30 | #include <asm/pgtable.h> | 34 | #include <asm/pgtable.h> |
31 | #include <asm/vsyscall.h> | 35 | #include <asm/vsyscall.h> |
@@ -396,6 +400,10 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
396 | (offset - vxtime.last)*(NSEC_PER_SEC/HZ) / hpet_tick; | 400 | (offset - vxtime.last)*(NSEC_PER_SEC/HZ) / hpet_tick; |
397 | 401 | ||
398 | vxtime.last = offset; | 402 | vxtime.last = offset; |
403 | #ifdef CONFIG_X86_PM_TIMER | ||
404 | } else if (vxtime.mode == VXTIME_PMTMR) { | ||
405 | lost = pmtimer_mark_offset(); | ||
406 | #endif | ||
399 | } else { | 407 | } else { |
400 | offset = (((tsc - vxtime.last_tsc) * | 408 | offset = (((tsc - vxtime.last_tsc) * |
401 | vxtime.tsc_quot) >> 32) - (USEC_PER_SEC / HZ); | 409 | vxtime.tsc_quot) >> 32) - (USEC_PER_SEC / HZ); |
@@ -898,6 +906,13 @@ void __init time_init(void) | |||
898 | hpet_period; | 906 | hpet_period; |
899 | cpu_khz = hpet_calibrate_tsc(); | 907 | cpu_khz = hpet_calibrate_tsc(); |
900 | timename = "HPET"; | 908 | timename = "HPET"; |
909 | #ifdef CONFIG_X86_PM_TIMER | ||
910 | } else if (pmtmr_ioport) { | ||
911 | vxtime_hz = PM_TIMER_FREQUENCY; | ||
912 | timename = "PM"; | ||
913 | pit_init(); | ||
914 | cpu_khz = pit_calibrate_tsc(); | ||
915 | #endif | ||
901 | } else { | 916 | } else { |
902 | pit_init(); | 917 | pit_init(); |
903 | cpu_khz = pit_calibrate_tsc(); | 918 | cpu_khz = pit_calibrate_tsc(); |
@@ -923,35 +938,50 @@ void __init time_init(void) | |||
923 | } | 938 | } |
924 | 939 | ||
925 | /* | 940 | /* |
941 | * Make an educated guess if the TSC is trustworthy and synchronized | ||
942 | * over all CPUs. | ||
943 | */ | ||
944 | static __init int unsynchronized_tsc(void) | ||
945 | { | ||
946 | #ifdef CONFIG_SMP | ||
947 | if (oem_force_hpet_timer()) | ||
948 | return 1; | ||
949 | /* Intel systems are normally all synchronized. Exceptions | ||
950 | are handled in the OEM check above. */ | ||
951 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) | ||
952 | return 0; | ||
953 | /* All in a single socket - should be synchronized */ | ||
954 | if (cpus_weight(cpu_core_map[0]) == num_online_cpus()) | ||
955 | return 0; | ||
956 | #endif | ||
957 | /* Assume multi socket systems are not synchronized */ | ||
958 | return num_online_cpus() > 1; | ||
959 | } | ||
960 | |||
961 | /* | ||
926 | * Decide after all CPUs are booted what mode gettimeofday should use. | 962 | * Decide after all CPUs are booted what mode gettimeofday should use. |
927 | */ | 963 | */ |
928 | void __init time_init_gtod(void) | 964 | void __init time_init_gtod(void) |
929 | { | 965 | { |
930 | char *timetype; | 966 | char *timetype; |
931 | 967 | ||
932 | /* | 968 | if (unsynchronized_tsc()) |
933 | * AMD systems with more than one CPU don't have fully synchronized | ||
934 | * TSCs. Always use HPET gettimeofday for these, although it is slower. | ||
935 | * Intel SMP systems usually have synchronized TSCs, so use always | ||
936 | * the TSC. | ||
937 | * | ||
938 | * Exceptions: | ||
939 | * IBM Summit2 checked by oem_force_hpet_timer(). | ||
940 | * AMD dual core may also not need HPET. Check me. | ||
941 | * | ||
942 | * Can be turned off with "notsc". | ||
943 | */ | ||
944 | if (num_online_cpus() > 1 && | ||
945 | boot_cpu_data.x86_vendor == X86_VENDOR_AMD) | ||
946 | notsc = 1; | ||
947 | /* Some systems will want to disable TSC and use HPET. */ | ||
948 | if (oem_force_hpet_timer()) | ||
949 | notsc = 1; | 969 | notsc = 1; |
950 | if (vxtime.hpet_address && notsc) { | 970 | if (vxtime.hpet_address && notsc) { |
951 | timetype = "HPET"; | 971 | timetype = "HPET"; |
952 | vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick; | 972 | vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick; |
953 | vxtime.mode = VXTIME_HPET; | 973 | vxtime.mode = VXTIME_HPET; |
954 | do_gettimeoffset = do_gettimeoffset_hpet; | 974 | do_gettimeoffset = do_gettimeoffset_hpet; |
975 | #ifdef CONFIG_X86_PM_TIMER | ||
976 | /* Using PM for gettimeofday is quite slow, but we have no other | ||
977 | choice because the TSC is too unreliable on some systems. */ | ||
978 | } else if (pmtmr_ioport && !vxtime.hpet_address && notsc) { | ||
979 | timetype = "PM"; | ||
980 | do_gettimeoffset = do_gettimeoffset_pm; | ||
981 | vxtime.mode = VXTIME_PMTMR; | ||
982 | sysctl_vsyscall = 0; | ||
983 | printk(KERN_INFO "Disabling vsyscall due to use of PM timer\n"); | ||
984 | #endif | ||
955 | } else { | 985 | } else { |
956 | timetype = vxtime.hpet_address ? "HPET/TSC" : "PIT/TSC"; | 986 | timetype = vxtime.hpet_address ? "HPET/TSC" : "PIT/TSC"; |
957 | vxtime.mode = VXTIME_TSC; | 987 | vxtime.mode = VXTIME_TSC; |
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 65a37f52c56e..3dfec8fdabcd 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c | |||
@@ -332,10 +332,12 @@ void handle_BUG(struct pt_regs *regs) | |||
332 | printk(KERN_ALERT "Kernel BUG at %.50s:%d\n", f.filename, f.line); | 332 | printk(KERN_ALERT "Kernel BUG at %.50s:%d\n", f.filename, f.line); |
333 | } | 333 | } |
334 | 334 | ||
335 | #ifdef CONFIG_BUG | ||
335 | void out_of_line_bug(void) | 336 | void out_of_line_bug(void) |
336 | { | 337 | { |
337 | BUG(); | 338 | BUG(); |
338 | } | 339 | } |
340 | #endif | ||
339 | 341 | ||
340 | static DEFINE_SPINLOCK(die_lock); | 342 | static DEFINE_SPINLOCK(die_lock); |
341 | static int die_owner = -1; | 343 | static int die_owner = -1; |
diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c index b4b8dc59663a..2e5734425949 100644 --- a/arch/x86_64/kernel/vsyscall.c +++ b/arch/x86_64/kernel/vsyscall.c | |||
@@ -65,7 +65,7 @@ static force_inline void do_vgettimeofday(struct timeval * tv) | |||
65 | usec = (__xtime.tv_nsec / 1000) + | 65 | usec = (__xtime.tv_nsec / 1000) + |
66 | (__jiffies - __wall_jiffies) * (1000000 / HZ); | 66 | (__jiffies - __wall_jiffies) * (1000000 / HZ); |
67 | 67 | ||
68 | if (__vxtime.mode == VXTIME_TSC) { | 68 | if (__vxtime.mode != VXTIME_HPET) { |
69 | sync_core(); | 69 | sync_core(); |
70 | rdtscll(t); | 70 | rdtscll(t); |
71 | if (t < __vxtime.last_tsc) | 71 | if (t < __vxtime.last_tsc) |
@@ -217,8 +217,9 @@ static int __init vsyscall_init(void) | |||
217 | BUG_ON((unsigned long) &vtime != VSYSCALL_ADDR(__NR_vtime)); | 217 | BUG_ON((unsigned long) &vtime != VSYSCALL_ADDR(__NR_vtime)); |
218 | BUG_ON((VSYSCALL_ADDR(0) != __fix_to_virt(VSYSCALL_FIRST_PAGE))); | 218 | BUG_ON((VSYSCALL_ADDR(0) != __fix_to_virt(VSYSCALL_FIRST_PAGE))); |
219 | map_vsyscall(); | 219 | map_vsyscall(); |
220 | sysctl_vsyscall = 1; | 220 | #ifdef CONFIG_SYSCTL |
221 | register_sysctl_table(kernel_root_table2, 0); | 221 | register_sysctl_table(kernel_root_table2, 0); |
222 | #endif | ||
222 | return 0; | 223 | return 0; |
223 | } | 224 | } |
224 | 225 | ||
diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c index 88626e626886..68ec03070e5a 100644 --- a/arch/x86_64/kernel/x8664_ksyms.c +++ b/arch/x86_64/kernel/x8664_ksyms.c | |||
@@ -139,35 +139,23 @@ EXPORT_SYMBOL_GPL(unset_nmi_callback); | |||
139 | #undef memmove | 139 | #undef memmove |
140 | #undef memchr | 140 | #undef memchr |
141 | #undef strlen | 141 | #undef strlen |
142 | #undef strcpy | ||
143 | #undef strncmp | 142 | #undef strncmp |
144 | #undef strncpy | 143 | #undef strncpy |
145 | #undef strchr | 144 | #undef strchr |
146 | #undef strcmp | ||
147 | #undef strcpy | ||
148 | #undef strcat | ||
149 | #undef memcmp | ||
150 | 145 | ||
151 | extern void * memset(void *,int,__kernel_size_t); | 146 | extern void * memset(void *,int,__kernel_size_t); |
152 | extern size_t strlen(const char *); | 147 | extern size_t strlen(const char *); |
153 | extern void * memmove(void * dest,const void *src,size_t count); | 148 | extern void * memmove(void * dest,const void *src,size_t count); |
154 | extern char * strcpy(char * dest,const char *src); | ||
155 | extern int strcmp(const char * cs,const char * ct); | ||
156 | extern void *memchr(const void *s, int c, size_t n); | 149 | extern void *memchr(const void *s, int c, size_t n); |
157 | extern void * memcpy(void *,const void *,__kernel_size_t); | 150 | extern void * memcpy(void *,const void *,__kernel_size_t); |
158 | extern void * __memcpy(void *,const void *,__kernel_size_t); | 151 | extern void * __memcpy(void *,const void *,__kernel_size_t); |
159 | extern char * strcat(char *, const char *); | ||
160 | extern int memcmp(const void * cs,const void * ct,size_t count); | ||
161 | 152 | ||
162 | EXPORT_SYMBOL(memset); | 153 | EXPORT_SYMBOL(memset); |
163 | EXPORT_SYMBOL(strlen); | 154 | EXPORT_SYMBOL(strlen); |
164 | EXPORT_SYMBOL(memmove); | 155 | EXPORT_SYMBOL(memmove); |
165 | EXPORT_SYMBOL(strcpy); | ||
166 | EXPORT_SYMBOL(strncmp); | 156 | EXPORT_SYMBOL(strncmp); |
167 | EXPORT_SYMBOL(strncpy); | 157 | EXPORT_SYMBOL(strncpy); |
168 | EXPORT_SYMBOL(strchr); | 158 | EXPORT_SYMBOL(strchr); |
169 | EXPORT_SYMBOL(strcmp); | ||
170 | EXPORT_SYMBOL(strcat); | ||
171 | EXPORT_SYMBOL(strncat); | 159 | EXPORT_SYMBOL(strncat); |
172 | EXPORT_SYMBOL(memchr); | 160 | EXPORT_SYMBOL(memchr); |
173 | EXPORT_SYMBOL(strrchr); | 161 | EXPORT_SYMBOL(strrchr); |
@@ -175,7 +163,6 @@ EXPORT_SYMBOL(strnlen); | |||
175 | EXPORT_SYMBOL(memscan); | 163 | EXPORT_SYMBOL(memscan); |
176 | EXPORT_SYMBOL(memcpy); | 164 | EXPORT_SYMBOL(memcpy); |
177 | EXPORT_SYMBOL(__memcpy); | 165 | EXPORT_SYMBOL(__memcpy); |
178 | EXPORT_SYMBOL(memcmp); | ||
179 | 166 | ||
180 | #ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM | 167 | #ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM |
181 | /* prototypes are wrong, these are assembly with custom calling functions */ | 168 | /* prototypes are wrong, these are assembly with custom calling functions */ |
@@ -206,8 +193,9 @@ EXPORT_SYMBOL(smp_num_siblings); | |||
206 | extern void do_softirq_thunk(void); | 193 | extern void do_softirq_thunk(void); |
207 | EXPORT_SYMBOL(do_softirq_thunk); | 194 | EXPORT_SYMBOL(do_softirq_thunk); |
208 | 195 | ||
209 | void out_of_line_bug(void); | 196 | #ifdef CONFIG_BUG |
210 | EXPORT_SYMBOL(out_of_line_bug); | 197 | EXPORT_SYMBOL(out_of_line_bug); |
198 | #endif | ||
211 | 199 | ||
212 | EXPORT_SYMBOL(init_level4_pgt); | 200 | EXPORT_SYMBOL(init_level4_pgt); |
213 | 201 | ||
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c index e03309216764..5d6b2114cc9a 100644 --- a/arch/x86_64/mm/fault.c +++ b/arch/x86_64/mm/fault.c | |||
@@ -234,6 +234,8 @@ static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs, | |||
234 | 234 | ||
235 | /* | 235 | /* |
236 | * Handle a fault on the vmalloc or module mapping area | 236 | * Handle a fault on the vmalloc or module mapping area |
237 | * | ||
238 | * This assumes no large pages in there. | ||
237 | */ | 239 | */ |
238 | static int vmalloc_fault(unsigned long address) | 240 | static int vmalloc_fault(unsigned long address) |
239 | { | 241 | { |
@@ -272,7 +274,10 @@ static int vmalloc_fault(unsigned long address) | |||
272 | if (!pte_present(*pte_ref)) | 274 | if (!pte_present(*pte_ref)) |
273 | return -1; | 275 | return -1; |
274 | pte = pte_offset_kernel(pmd, address); | 276 | pte = pte_offset_kernel(pmd, address); |
275 | if (!pte_present(*pte) || pte_page(*pte) != pte_page(*pte_ref)) | 277 | /* Don't use pte_page here, because the mappings can point |
278 | outside mem_map, and the NUMA hash lookup cannot handle | ||
279 | that. */ | ||
280 | if (!pte_present(*pte) || pte_pfn(*pte) != pte_pfn(*pte_ref)) | ||
276 | BUG(); | 281 | BUG(); |
277 | __flush_tlb_all(); | 282 | __flush_tlb_all(); |
278 | return 0; | 283 | return 0; |
@@ -346,7 +351,9 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) | |||
346 | * protection error (error_code & 1) == 0. | 351 | * protection error (error_code & 1) == 0. |
347 | */ | 352 | */ |
348 | if (unlikely(address >= TASK_SIZE)) { | 353 | if (unlikely(address >= TASK_SIZE)) { |
349 | if (!(error_code & 5)) { | 354 | if (!(error_code & 5) && |
355 | ((address >= VMALLOC_START && address < VMALLOC_END) || | ||
356 | (address >= MODULES_VADDR && address < MODULES_END))) { | ||
350 | if (vmalloc_fault(address) < 0) | 357 | if (vmalloc_fault(address) < 0) |
351 | goto bad_area_nosemaphore; | 358 | goto bad_area_nosemaphore; |
352 | return; | 359 | return; |
diff --git a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c index 74ec8554b195..58aac23760ef 100644 --- a/arch/x86_64/mm/ioremap.c +++ b/arch/x86_64/mm/ioremap.c | |||
@@ -133,7 +133,7 @@ ioremap_change_attr(unsigned long phys_addr, unsigned long size, | |||
133 | unsigned long flags) | 133 | unsigned long flags) |
134 | { | 134 | { |
135 | int err = 0; | 135 | int err = 0; |
136 | if (flags && phys_addr + size - 1 < (end_pfn_map << PAGE_SHIFT)) { | 136 | if (phys_addr + size - 1 < (end_pfn_map << PAGE_SHIFT)) { |
137 | unsigned long npages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; | 137 | unsigned long npages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; |
138 | unsigned long vaddr = (unsigned long) __va(phys_addr); | 138 | unsigned long vaddr = (unsigned long) __va(phys_addr); |
139 | 139 | ||
@@ -214,7 +214,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l | |||
214 | remove_vm_area((void *)(PAGE_MASK & (unsigned long) addr)); | 214 | remove_vm_area((void *)(PAGE_MASK & (unsigned long) addr)); |
215 | return NULL; | 215 | return NULL; |
216 | } | 216 | } |
217 | if (ioremap_change_attr(phys_addr, size, flags) < 0) { | 217 | if (flags && ioremap_change_attr(phys_addr, size, flags) < 0) { |
218 | area->flags &= 0xffffff; | 218 | area->flags &= 0xffffff; |
219 | vunmap(addr); | 219 | vunmap(addr); |
220 | return NULL; | 220 | return NULL; |
@@ -251,7 +251,7 @@ void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size) | |||
251 | 251 | ||
252 | void iounmap(volatile void __iomem *addr) | 252 | void iounmap(volatile void __iomem *addr) |
253 | { | 253 | { |
254 | struct vm_struct *p, **pprev; | 254 | struct vm_struct *p; |
255 | 255 | ||
256 | if (addr <= high_memory) | 256 | if (addr <= high_memory) |
257 | return; | 257 | return; |
@@ -260,24 +260,11 @@ void iounmap(volatile void __iomem *addr) | |||
260 | return; | 260 | return; |
261 | 261 | ||
262 | write_lock(&vmlist_lock); | 262 | write_lock(&vmlist_lock); |
263 | for (p = vmlist, pprev = &vmlist; p != NULL; pprev = &p->next, p = *pprev) | 263 | p = __remove_vm_area((void *)((unsigned long)addr & PAGE_MASK)); |
264 | if (p->addr == (void *)(PAGE_MASK & (unsigned long)addr)) | 264 | if (!p) |
265 | break; | 265 | printk("iounmap: bad address %p\n", addr); |
266 | if (!p) { | 266 | else if (p->flags >> 20) |
267 | printk("__iounmap: bad address %p\n", addr); | 267 | ioremap_change_attr(p->phys_addr, p->size, 0); |
268 | goto out_unlock; | ||
269 | } | ||
270 | *pprev = p->next; | ||
271 | unmap_vm_area(p); | ||
272 | if ((p->flags >> 20) && | ||
273 | p->phys_addr + p->size - 1 < virt_to_phys(high_memory)) { | ||
274 | /* p->size includes the guard page, but cpa doesn't like that */ | ||
275 | change_page_attr(virt_to_page(__va(p->phys_addr)), | ||
276 | p->size >> PAGE_SHIFT, | ||
277 | PAGE_KERNEL); | ||
278 | global_flush_tlb(); | ||
279 | } | ||
280 | out_unlock: | ||
281 | write_unlock(&vmlist_lock); | 268 | write_unlock(&vmlist_lock); |
282 | kfree(p); | 269 | kfree(p); |
283 | } | 270 | } |