diff options
Diffstat (limited to 'arch/s390')
| -rw-r--r-- | arch/s390/Kconfig | 4 | ||||
| -rw-r--r-- | arch/s390/Makefile | 12 | ||||
| -rw-r--r-- | arch/s390/defconfig | 21 | ||||
| -rw-r--r-- | arch/s390/kernel/early.c | 5 | ||||
| -rw-r--r-- | arch/s390/kernel/head31.S | 15 | ||||
| -rw-r--r-- | arch/s390/kernel/head64.S | 16 | ||||
| -rw-r--r-- | arch/s390/kernel/ipl.c | 33 | ||||
| -rw-r--r-- | arch/s390/kernel/setup.c | 10 | ||||
| -rw-r--r-- | arch/s390/kernel/smp.c | 182 | ||||
| -rw-r--r-- | arch/s390/kernel/time.c | 10 | ||||
| -rw-r--r-- | arch/s390/lib/delay.c | 7 | ||||
| -rw-r--r-- | arch/s390/mm/init.c | 2 |
12 files changed, 144 insertions, 173 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index eaaac3788110..d9425f59be91 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
| @@ -8,8 +8,8 @@ config MMU | |||
| 8 | default y | 8 | default y |
| 9 | 9 | ||
| 10 | config ZONE_DMA | 10 | config ZONE_DMA |
| 11 | bool | 11 | def_bool y |
| 12 | default y | 12 | depends on 64BIT |
| 13 | 13 | ||
| 14 | config LOCKDEP_SUPPORT | 14 | config LOCKDEP_SUPPORT |
| 15 | bool | 15 | bool |
diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 6598e5268573..b1e558496469 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile | |||
| @@ -82,18 +82,18 @@ AFLAGS += $(aflags-y) | |||
| 82 | OBJCOPYFLAGS := -O binary | 82 | OBJCOPYFLAGS := -O binary |
| 83 | LDFLAGS_vmlinux := -e start | 83 | LDFLAGS_vmlinux := -e start |
| 84 | 84 | ||
| 85 | head-y := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o | 85 | head-y := arch/s390/kernel/head.o arch/s390/kernel/init_task.o |
| 86 | 86 | ||
| 87 | core-y += arch/$(ARCH)/mm/ arch/$(ARCH)/kernel/ arch/$(ARCH)/crypto/ \ | 87 | core-y += arch/s390/mm/ arch/s390/kernel/ arch/s390/crypto/ \ |
| 88 | arch/$(ARCH)/appldata/ arch/$(ARCH)/hypfs/ | 88 | arch/s390/appldata/ arch/s390/hypfs/ |
| 89 | libs-y += arch/$(ARCH)/lib/ | 89 | libs-y += arch/s390/lib/ |
| 90 | drivers-y += drivers/s390/ | 90 | drivers-y += drivers/s390/ |
| 91 | drivers-$(CONFIG_MATHEMU) += arch/$(ARCH)/math-emu/ | 91 | drivers-$(CONFIG_MATHEMU) += arch/s390/math-emu/ |
| 92 | 92 | ||
| 93 | # must be linked after kernel | 93 | # must be linked after kernel |
| 94 | drivers-$(CONFIG_OPROFILE) += arch/s390/oprofile/ | 94 | drivers-$(CONFIG_OPROFILE) += arch/s390/oprofile/ |
| 95 | 95 | ||
| 96 | boot := arch/$(ARCH)/boot | 96 | boot := arch/s390/boot |
| 97 | 97 | ||
| 98 | all: image | 98 | all: image |
| 99 | 99 | ||
diff --git a/arch/s390/defconfig b/arch/s390/defconfig index 1406400bf3ea..741d2bbb2b37 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | # | 1 | # |
| 2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
| 3 | # Linux kernel version: 2.6.20-rc1 | 3 | # Linux kernel version: 2.6.21-rc1 |
| 4 | # Fri Dec 15 16:52:28 2006 | 4 | # Wed Feb 21 10:44:30 2007 |
| 5 | # | 5 | # |
| 6 | CONFIG_MMU=y | 6 | CONFIG_MMU=y |
| 7 | CONFIG_ZONE_DMA=y | ||
| 7 | CONFIG_LOCKDEP_SUPPORT=y | 8 | CONFIG_LOCKDEP_SUPPORT=y |
| 8 | CONFIG_STACKTRACE_SUPPORT=y | 9 | CONFIG_STACKTRACE_SUPPORT=y |
| 9 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | 10 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y |
| @@ -11,6 +12,7 @@ CONFIG_RWSEM_XCHGADD_ALGORITHM=y | |||
| 11 | # CONFIG_ARCH_HAS_ILOG2_U64 is not set | 12 | # CONFIG_ARCH_HAS_ILOG2_U64 is not set |
| 12 | CONFIG_GENERIC_HWEIGHT=y | 13 | CONFIG_GENERIC_HWEIGHT=y |
| 13 | CONFIG_GENERIC_TIME=y | 14 | CONFIG_GENERIC_TIME=y |
| 15 | CONFIG_NO_IOMEM=y | ||
| 14 | CONFIG_S390=y | 16 | CONFIG_S390=y |
| 15 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | 17 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" |
| 16 | 18 | ||
| @@ -29,6 +31,7 @@ CONFIG_LOCALVERSION_AUTO=y | |||
| 29 | CONFIG_SWAP=y | 31 | CONFIG_SWAP=y |
| 30 | CONFIG_SYSVIPC=y | 32 | CONFIG_SYSVIPC=y |
| 31 | # CONFIG_IPC_NS is not set | 33 | # CONFIG_IPC_NS is not set |
| 34 | CONFIG_SYSVIPC_SYSCTL=y | ||
| 32 | CONFIG_POSIX_MQUEUE=y | 35 | CONFIG_POSIX_MQUEUE=y |
| 33 | # CONFIG_BSD_PROCESS_ACCT is not set | 36 | # CONFIG_BSD_PROCESS_ACCT is not set |
| 34 | # CONFIG_TASKSTATS is not set | 37 | # CONFIG_TASKSTATS is not set |
| @@ -133,6 +136,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y | |||
| 133 | # CONFIG_SPARSEMEM_STATIC is not set | 136 | # CONFIG_SPARSEMEM_STATIC is not set |
| 134 | CONFIG_SPLIT_PTLOCK_CPUS=4 | 137 | CONFIG_SPLIT_PTLOCK_CPUS=4 |
| 135 | CONFIG_RESOURCES_64BIT=y | 138 | CONFIG_RESOURCES_64BIT=y |
| 139 | CONFIG_ZONE_DMA_FLAG=1 | ||
| 136 | CONFIG_HOLES_IN_ZONE=y | 140 | CONFIG_HOLES_IN_ZONE=y |
| 137 | 141 | ||
| 138 | # | 142 | # |
| @@ -178,7 +182,9 @@ CONFIG_UNIX=y | |||
| 178 | CONFIG_XFRM=y | 182 | CONFIG_XFRM=y |
| 179 | # CONFIG_XFRM_USER is not set | 183 | # CONFIG_XFRM_USER is not set |
| 180 | # CONFIG_XFRM_SUB_POLICY is not set | 184 | # CONFIG_XFRM_SUB_POLICY is not set |
| 185 | # CONFIG_XFRM_MIGRATE is not set | ||
| 181 | CONFIG_NET_KEY=y | 186 | CONFIG_NET_KEY=y |
| 187 | # CONFIG_NET_KEY_MIGRATE is not set | ||
| 182 | CONFIG_IUCV=m | 188 | CONFIG_IUCV=m |
| 183 | CONFIG_AFIUCV=m | 189 | CONFIG_AFIUCV=m |
| 184 | CONFIG_INET=y | 190 | CONFIG_INET=y |
| @@ -195,7 +201,7 @@ CONFIG_IP_FIB_HASH=y | |||
| 195 | # CONFIG_INET_ESP is not set | 201 | # CONFIG_INET_ESP is not set |
| 196 | # CONFIG_INET_IPCOMP is not set | 202 | # CONFIG_INET_IPCOMP is not set |
| 197 | # CONFIG_INET_XFRM_TUNNEL is not set | 203 | # CONFIG_INET_XFRM_TUNNEL is not set |
| 198 | # CONFIG_INET_TUNNEL is not set | 204 | CONFIG_INET_TUNNEL=y |
| 199 | CONFIG_INET_XFRM_MODE_TRANSPORT=y | 205 | CONFIG_INET_XFRM_MODE_TRANSPORT=y |
| 200 | CONFIG_INET_XFRM_MODE_TUNNEL=y | 206 | CONFIG_INET_XFRM_MODE_TUNNEL=y |
| 201 | CONFIG_INET_XFRM_MODE_BEET=y | 207 | CONFIG_INET_XFRM_MODE_BEET=y |
| @@ -313,6 +319,7 @@ CONFIG_STANDALONE=y | |||
| 313 | CONFIG_PREVENT_FIRMWARE_BUILD=y | 319 | CONFIG_PREVENT_FIRMWARE_BUILD=y |
| 314 | # CONFIG_FW_LOADER is not set | 320 | # CONFIG_FW_LOADER is not set |
| 315 | # CONFIG_DEBUG_DRIVER is not set | 321 | # CONFIG_DEBUG_DRIVER is not set |
| 322 | # CONFIG_DEBUG_DEVRES is not set | ||
| 316 | CONFIG_SYS_HYPERVISOR=y | 323 | CONFIG_SYS_HYPERVISOR=y |
| 317 | 324 | ||
| 318 | # | 325 | # |
| @@ -686,13 +693,13 @@ CONFIG_HEADERS_CHECK=y | |||
| 686 | CONFIG_DEBUG_KERNEL=y | 693 | CONFIG_DEBUG_KERNEL=y |
| 687 | CONFIG_LOG_BUF_SHIFT=17 | 694 | CONFIG_LOG_BUF_SHIFT=17 |
| 688 | # CONFIG_SCHEDSTATS is not set | 695 | # CONFIG_SCHEDSTATS is not set |
| 696 | # CONFIG_TIMER_STATS is not set | ||
| 689 | # CONFIG_DEBUG_SLAB is not set | 697 | # CONFIG_DEBUG_SLAB is not set |
| 690 | CONFIG_DEBUG_PREEMPT=y | 698 | CONFIG_DEBUG_PREEMPT=y |
| 691 | # CONFIG_DEBUG_RT_MUTEXES is not set | 699 | # CONFIG_DEBUG_RT_MUTEXES is not set |
| 692 | # CONFIG_RT_MUTEX_TESTER is not set | 700 | # CONFIG_RT_MUTEX_TESTER is not set |
| 693 | CONFIG_DEBUG_SPINLOCK=y | 701 | CONFIG_DEBUG_SPINLOCK=y |
| 694 | CONFIG_DEBUG_MUTEXES=y | 702 | CONFIG_DEBUG_MUTEXES=y |
| 695 | # CONFIG_DEBUG_RWSEMS is not set | ||
| 696 | # CONFIG_DEBUG_LOCK_ALLOC is not set | 703 | # CONFIG_DEBUG_LOCK_ALLOC is not set |
| 697 | # CONFIG_PROVE_LOCKING is not set | 704 | # CONFIG_PROVE_LOCKING is not set |
| 698 | CONFIG_DEBUG_SPINLOCK_SLEEP=y | 705 | CONFIG_DEBUG_SPINLOCK_SLEEP=y |
| @@ -702,10 +709,10 @@ CONFIG_DEBUG_SPINLOCK_SLEEP=y | |||
| 702 | # CONFIG_DEBUG_VM is not set | 709 | # CONFIG_DEBUG_VM is not set |
| 703 | # CONFIG_DEBUG_LIST is not set | 710 | # CONFIG_DEBUG_LIST is not set |
| 704 | # CONFIG_FRAME_POINTER is not set | 711 | # CONFIG_FRAME_POINTER is not set |
| 705 | # CONFIG_UNWIND_INFO is not set | ||
| 706 | CONFIG_FORCED_INLINING=y | 712 | CONFIG_FORCED_INLINING=y |
| 707 | # CONFIG_RCU_TORTURE_TEST is not set | 713 | # CONFIG_RCU_TORTURE_TEST is not set |
| 708 | # CONFIG_LKDTM is not set | 714 | # CONFIG_LKDTM is not set |
| 715 | # CONFIG_FAULT_INJECTION is not set | ||
| 709 | 716 | ||
| 710 | # | 717 | # |
| 711 | # Security options | 718 | # Security options |
| @@ -733,8 +740,10 @@ CONFIG_CRYPTO_MANAGER=y | |||
| 733 | # CONFIG_CRYPTO_GF128MUL is not set | 740 | # CONFIG_CRYPTO_GF128MUL is not set |
| 734 | CONFIG_CRYPTO_ECB=m | 741 | CONFIG_CRYPTO_ECB=m |
| 735 | CONFIG_CRYPTO_CBC=y | 742 | CONFIG_CRYPTO_CBC=y |
| 743 | CONFIG_CRYPTO_PCBC=m | ||
| 736 | # CONFIG_CRYPTO_LRW is not set | 744 | # CONFIG_CRYPTO_LRW is not set |
| 737 | # CONFIG_CRYPTO_DES is not set | 745 | # CONFIG_CRYPTO_DES is not set |
| 746 | CONFIG_CRYPTO_FCRYPT=m | ||
| 738 | # CONFIG_CRYPTO_BLOWFISH is not set | 747 | # CONFIG_CRYPTO_BLOWFISH is not set |
| 739 | # CONFIG_CRYPTO_TWOFISH is not set | 748 | # CONFIG_CRYPTO_TWOFISH is not set |
| 740 | # CONFIG_CRYPTO_SERPENT is not set | 749 | # CONFIG_CRYPTO_SERPENT is not set |
| @@ -748,6 +757,7 @@ CONFIG_CRYPTO_CBC=y | |||
| 748 | # CONFIG_CRYPTO_DEFLATE is not set | 757 | # CONFIG_CRYPTO_DEFLATE is not set |
| 749 | # CONFIG_CRYPTO_MICHAEL_MIC is not set | 758 | # CONFIG_CRYPTO_MICHAEL_MIC is not set |
| 750 | # CONFIG_CRYPTO_CRC32C is not set | 759 | # CONFIG_CRYPTO_CRC32C is not set |
| 760 | CONFIG_CRYPTO_CAMELLIA=m | ||
| 751 | # CONFIG_CRYPTO_TEST is not set | 761 | # CONFIG_CRYPTO_TEST is not set |
| 752 | 762 | ||
| 753 | # | 763 | # |
| @@ -768,4 +778,3 @@ CONFIG_BITREVERSE=m | |||
| 768 | CONFIG_CRC32=m | 778 | CONFIG_CRC32=m |
| 769 | # CONFIG_LIBCRC32C is not set | 779 | # CONFIG_LIBCRC32C is not set |
| 770 | CONFIG_PLIST=y | 780 | CONFIG_PLIST=y |
| 771 | CONFIG_IOMAP_COPY=y | ||
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index e518dd53eff5..afca1c6f4d21 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 15 | #include <linux/pfn.h> | 15 | #include <linux/pfn.h> |
| 16 | #include <linux/uaccess.h> | 16 | #include <linux/uaccess.h> |
| 17 | #include <asm/ipl.h> | ||
| 17 | #include <asm/lowcore.h> | 18 | #include <asm/lowcore.h> |
| 18 | #include <asm/processor.h> | 19 | #include <asm/processor.h> |
| 19 | #include <asm/sections.h> | 20 | #include <asm/sections.h> |
| @@ -109,7 +110,7 @@ static inline void create_kernel_nss(void) { } | |||
| 109 | */ | 110 | */ |
| 110 | static noinline __init void clear_bss_section(void) | 111 | static noinline __init void clear_bss_section(void) |
| 111 | { | 112 | { |
| 112 | memset(__bss_start, 0, _end - __bss_start); | 113 | memset(__bss_start, 0, __bss_stop - __bss_start); |
| 113 | } | 114 | } |
| 114 | 115 | ||
| 115 | /* | 116 | /* |
| @@ -129,7 +130,7 @@ static noinline __init void detect_machine_type(void) | |||
| 129 | { | 130 | { |
| 130 | struct cpuinfo_S390 *cpuinfo = &S390_lowcore.cpu_data; | 131 | struct cpuinfo_S390 *cpuinfo = &S390_lowcore.cpu_data; |
| 131 | 132 | ||
| 132 | asm volatile("stidp %0" : "=m" (S390_lowcore.cpu_data.cpu_id)); | 133 | get_cpu_id(&S390_lowcore.cpu_data.cpu_id); |
| 133 | 134 | ||
| 134 | /* Running under z/VM ? */ | 135 | /* Running under z/VM ? */ |
| 135 | if (cpuinfo->cpu_id.version == 0xff) | 136 | if (cpuinfo->cpu_id.version == 0xff) |
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S index 453fd3b4edea..da7c8bb80982 100644 --- a/arch/s390/kernel/head31.S +++ b/arch/s390/kernel/head31.S | |||
| @@ -148,20 +148,9 @@ startup_continue: | |||
| 148 | .Lstartup_init: | 148 | .Lstartup_init: |
| 149 | .long startup_init | 149 | .long startup_init |
| 150 | 150 | ||
| 151 | .globl ipl_schib | ||
| 152 | ipl_schib: | ||
| 153 | .rept 13 | ||
| 154 | .long 0 | ||
| 155 | .endr | ||
| 156 | |||
| 157 | .globl ipl_flags | ||
| 158 | ipl_flags: | ||
| 159 | .long 0 | ||
| 160 | .globl ipl_devno | ||
| 161 | ipl_devno: | ||
| 162 | .word 0 | ||
| 163 | |||
| 164 | .org 0x12000 | 151 | .org 0x12000 |
| 152 | .globl _ehead | ||
| 153 | _ehead: | ||
| 165 | #ifdef CONFIG_SHARED_KERNEL | 154 | #ifdef CONFIG_SHARED_KERNEL |
| 166 | .org 0x100000 | 155 | .org 0x100000 |
| 167 | #endif | 156 | #endif |
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index b8fec4e5c5d4..af09e18cc5d0 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S | |||
| @@ -154,21 +154,9 @@ startup_continue: | |||
| 154 | .Lparmaddr: | 154 | .Lparmaddr: |
| 155 | .quad PARMAREA | 155 | .quad PARMAREA |
| 156 | 156 | ||
| 157 | .globl ipl_schib | ||
| 158 | ipl_schib: | ||
| 159 | .rept 13 | ||
| 160 | .long 0 | ||
| 161 | .endr | ||
| 162 | |||
| 163 | .globl ipl_flags | ||
| 164 | ipl_flags: | ||
| 165 | .long 0 | ||
| 166 | .globl ipl_devno | ||
| 167 | ipl_devno: | ||
| 168 | .word 0 | ||
| 169 | |||
| 170 | .org 0x12000 | 157 | .org 0x12000 |
| 171 | 158 | .globl _ehead | |
| 159 | _ehead: | ||
| 172 | #ifdef CONFIG_SHARED_KERNEL | 160 | #ifdef CONFIG_SHARED_KERNEL |
| 173 | .org 0x100000 | 161 | .org 0x100000 |
| 174 | #endif | 162 | #endif |
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 052259530651..5a863a3bf10c 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
| 15 | #include <linux/reboot.h> | 15 | #include <linux/reboot.h> |
| 16 | #include <linux/ctype.h> | 16 | #include <linux/ctype.h> |
| 17 | #include <asm/ipl.h> | ||
| 17 | #include <asm/smp.h> | 18 | #include <asm/smp.h> |
| 18 | #include <asm/setup.h> | 19 | #include <asm/setup.h> |
| 19 | #include <asm/cpcmd.h> | 20 | #include <asm/cpcmd.h> |
| @@ -42,6 +43,13 @@ enum ipl_type { | |||
| 42 | #define IPL_FCP_STR "fcp" | 43 | #define IPL_FCP_STR "fcp" |
| 43 | #define IPL_NSS_STR "nss" | 44 | #define IPL_NSS_STR "nss" |
| 44 | 45 | ||
| 46 | /* | ||
| 47 | * Must be in data section since the bss section | ||
| 48 | * is not cleared when these are accessed. | ||
| 49 | */ | ||
| 50 | u16 ipl_devno __attribute__((__section__(".data"))) = 0; | ||
| 51 | u32 ipl_flags __attribute__((__section__(".data"))) = 0; | ||
| 52 | |||
| 45 | static char *ipl_type_str(enum ipl_type type) | 53 | static char *ipl_type_str(enum ipl_type type) |
| 46 | { | 54 | { |
| 47 | switch (type) { | 55 | switch (type) { |
| @@ -90,31 +98,10 @@ static char *shutdown_action_str(enum shutdown_action action) | |||
| 90 | case SHUTDOWN_STOP: | 98 | case SHUTDOWN_STOP: |
| 91 | return SHUTDOWN_STOP_STR; | 99 | return SHUTDOWN_STOP_STR; |
| 92 | default: | 100 | default: |
| 93 | BUG(); | 101 | return NULL; |
| 94 | } | 102 | } |
| 95 | } | 103 | } |
| 96 | 104 | ||
| 97 | enum diag308_subcode { | ||
| 98 | DIAG308_IPL = 3, | ||
| 99 | DIAG308_DUMP = 4, | ||
| 100 | DIAG308_SET = 5, | ||
| 101 | DIAG308_STORE = 6, | ||
| 102 | }; | ||
| 103 | |||
| 104 | enum diag308_ipl_type { | ||
| 105 | DIAG308_IPL_TYPE_FCP = 0, | ||
| 106 | DIAG308_IPL_TYPE_CCW = 2, | ||
| 107 | }; | ||
| 108 | |||
| 109 | enum diag308_opt { | ||
| 110 | DIAG308_IPL_OPT_IPL = 0x10, | ||
| 111 | DIAG308_IPL_OPT_DUMP = 0x20, | ||
| 112 | }; | ||
| 113 | |||
| 114 | enum diag308_rc { | ||
| 115 | DIAG308_RC_OK = 1, | ||
| 116 | }; | ||
| 117 | |||
| 118 | static int diag308_set_works = 0; | 105 | static int diag308_set_works = 0; |
| 119 | 106 | ||
| 120 | static int reipl_capabilities = IPL_TYPE_UNKNOWN; | 107 | static int reipl_capabilities = IPL_TYPE_UNKNOWN; |
| @@ -134,7 +121,7 @@ static struct ipl_parameter_block *dump_block_ccw; | |||
| 134 | 121 | ||
| 135 | static enum shutdown_action on_panic_action = SHUTDOWN_STOP; | 122 | static enum shutdown_action on_panic_action = SHUTDOWN_STOP; |
| 136 | 123 | ||
| 137 | static int diag308(unsigned long subcode, void *addr) | 124 | int diag308(unsigned long subcode, void *addr) |
| 138 | { | 125 | { |
| 139 | register unsigned long _addr asm("0") = (unsigned long) addr; | 126 | register unsigned long _addr asm("0") = (unsigned long) addr; |
| 140 | register unsigned long _rc asm("1") = 0; | 127 | register unsigned long _rc asm("1") = 0; |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 50c5210fbc64..863c8d08c026 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | #include <linux/ctype.h> | 41 | #include <linux/ctype.h> |
| 42 | #include <linux/reboot.h> | 42 | #include <linux/reboot.h> |
| 43 | 43 | ||
| 44 | #include <asm/ipl.h> | ||
| 44 | #include <asm/uaccess.h> | 45 | #include <asm/uaccess.h> |
| 45 | #include <asm/system.h> | 46 | #include <asm/system.h> |
| 46 | #include <asm/smp.h> | 47 | #include <asm/smp.h> |
| @@ -106,7 +107,7 @@ void __devinit cpu_init (void) | |||
| 106 | /* | 107 | /* |
| 107 | * Store processor id in lowcore (used e.g. in timer_interrupt) | 108 | * Store processor id in lowcore (used e.g. in timer_interrupt) |
| 108 | */ | 109 | */ |
| 109 | asm volatile("stidp %0": "=m" (S390_lowcore.cpu_data.cpu_id)); | 110 | get_cpu_id(&S390_lowcore.cpu_data.cpu_id); |
| 110 | S390_lowcore.cpu_data.cpu_addr = addr; | 111 | S390_lowcore.cpu_data.cpu_addr = addr; |
| 111 | 112 | ||
| 112 | /* | 113 | /* |
| @@ -689,9 +690,14 @@ setup_memory(void) | |||
| 689 | psw_set_key(PAGE_DEFAULT_KEY); | 690 | psw_set_key(PAGE_DEFAULT_KEY); |
| 690 | 691 | ||
| 691 | free_bootmem_with_active_regions(0, max_pfn); | 692 | free_bootmem_with_active_regions(0, max_pfn); |
| 692 | reserve_bootmem(0, PFN_PHYS(start_pfn)); | ||
| 693 | 693 | ||
| 694 | /* | 694 | /* |
| 695 | * Reserve memory used for lowcore/command line/kernel image. | ||
| 696 | */ | ||
| 697 | reserve_bootmem(0, (unsigned long)_ehead); | ||
| 698 | reserve_bootmem((unsigned long)_stext, | ||
| 699 | PFN_PHYS(start_pfn) - (unsigned long)_stext); | ||
| 700 | /* | ||
| 695 | * Reserve the bootmem bitmap itself as well. We do this in two | 701 | * Reserve the bootmem bitmap itself as well. We do this in two |
| 696 | * steps (first step was init_bootmem()) because this catches | 702 | * steps (first step was init_bootmem()) because this catches |
| 697 | * the (very unlikely) case of us accidentally initializing the | 703 | * the (very unlikely) case of us accidentally initializing the |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 83a4ea6e3d60..ecaa432a99f8 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
| 32 | #include <linux/cpu.h> | 32 | #include <linux/cpu.h> |
| 33 | #include <linux/timex.h> | 33 | #include <linux/timex.h> |
| 34 | #include <asm/ipl.h> | ||
| 34 | #include <asm/setup.h> | 35 | #include <asm/setup.h> |
| 35 | #include <asm/sigp.h> | 36 | #include <asm/sigp.h> |
| 36 | #include <asm/pgalloc.h> | 37 | #include <asm/pgalloc.h> |
| @@ -54,19 +55,18 @@ cpumask_t cpu_possible_map = CPU_MASK_NONE; | |||
| 54 | static struct task_struct *current_set[NR_CPUS]; | 55 | static struct task_struct *current_set[NR_CPUS]; |
| 55 | 56 | ||
| 56 | static void smp_ext_bitcall(int, ec_bit_sig); | 57 | static void smp_ext_bitcall(int, ec_bit_sig); |
| 57 | static void smp_ext_bitcall_others(ec_bit_sig); | ||
| 58 | 58 | ||
| 59 | /* | 59 | /* |
| 60 | * Structure and data for smp_call_function(). This is designed to minimise | 60 | * Structure and data for __smp_call_function_map(). This is designed to |
| 61 | * static memory requirements. It also looks cleaner. | 61 | * minimise static memory requirements. It also looks cleaner. |
| 62 | */ | 62 | */ |
| 63 | static DEFINE_SPINLOCK(call_lock); | 63 | static DEFINE_SPINLOCK(call_lock); |
| 64 | 64 | ||
| 65 | struct call_data_struct { | 65 | struct call_data_struct { |
| 66 | void (*func) (void *info); | 66 | void (*func) (void *info); |
| 67 | void *info; | 67 | void *info; |
| 68 | atomic_t started; | 68 | cpumask_t started; |
| 69 | atomic_t finished; | 69 | cpumask_t finished; |
| 70 | int wait; | 70 | int wait; |
| 71 | }; | 71 | }; |
| 72 | 72 | ||
| @@ -81,118 +81,113 @@ static void do_call_function(void) | |||
| 81 | void *info = call_data->info; | 81 | void *info = call_data->info; |
| 82 | int wait = call_data->wait; | 82 | int wait = call_data->wait; |
| 83 | 83 | ||
| 84 | atomic_inc(&call_data->started); | 84 | cpu_set(smp_processor_id(), call_data->started); |
| 85 | (*func)(info); | 85 | (*func)(info); |
| 86 | if (wait) | 86 | if (wait) |
| 87 | atomic_inc(&call_data->finished); | 87 | cpu_set(smp_processor_id(), call_data->finished);; |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | /* | 90 | static void __smp_call_function_map(void (*func) (void *info), void *info, |
| 91 | * this function sends a 'generic call function' IPI to all other CPUs | 91 | int nonatomic, int wait, cpumask_t map) |
| 92 | * in the system. | ||
| 93 | */ | ||
| 94 | |||
| 95 | int smp_call_function (void (*func) (void *info), void *info, int nonatomic, | ||
| 96 | int wait) | ||
| 97 | /* | ||
| 98 | * [SUMMARY] Run a function on all other CPUs. | ||
| 99 | * <func> The function to run. This must be fast and non-blocking. | ||
| 100 | * <info> An arbitrary pointer to pass to the function. | ||
| 101 | * <nonatomic> currently unused. | ||
| 102 | * <wait> If true, wait (atomically) until function has completed on other CPUs. | ||
| 103 | * [RETURNS] 0 on success, else a negative status code. Does not return until | ||
| 104 | * remote CPUs are nearly ready to execute <<func>> or are or have executed. | ||
| 105 | * | ||
| 106 | * You must not call this function with disabled interrupts or from a | ||
| 107 | * hardware interrupt handler. | ||
| 108 | */ | ||
| 109 | { | 92 | { |
| 110 | struct call_data_struct data; | 93 | struct call_data_struct data; |
| 111 | int cpus = num_online_cpus()-1; | 94 | int cpu, local = 0; |
| 112 | 95 | ||
| 113 | if (cpus <= 0) | 96 | /* |
| 114 | return 0; | 97 | * Can deadlock when interrupts are disabled or if in wrong context, |
| 98 | * caller must disable preemption | ||
| 99 | */ | ||
| 100 | WARN_ON(irqs_disabled() || in_irq() || preemptible()); | ||
| 115 | 101 | ||
| 116 | /* Can deadlock when interrupts are disabled or if in wrong context */ | 102 | /* |
| 117 | WARN_ON(irqs_disabled() || in_irq()); | 103 | * Check for local function call. We have to have the same call order |
| 104 | * as in on_each_cpu() because of machine_restart_smp(). | ||
| 105 | */ | ||
| 106 | if (cpu_isset(smp_processor_id(), map)) { | ||
| 107 | local = 1; | ||
| 108 | cpu_clear(smp_processor_id(), map); | ||
| 109 | } | ||
| 110 | |||
| 111 | cpus_and(map, map, cpu_online_map); | ||
| 112 | if (cpus_empty(map)) | ||
| 113 | goto out; | ||
| 118 | 114 | ||
| 119 | data.func = func; | 115 | data.func = func; |
| 120 | data.info = info; | 116 | data.info = info; |
| 121 | atomic_set(&data.started, 0); | 117 | data.started = CPU_MASK_NONE; |
| 122 | data.wait = wait; | 118 | data.wait = wait; |
| 123 | if (wait) | 119 | if (wait) |
| 124 | atomic_set(&data.finished, 0); | 120 | data.finished = CPU_MASK_NONE; |
| 125 | 121 | ||
| 126 | spin_lock_bh(&call_lock); | 122 | spin_lock_bh(&call_lock); |
| 127 | call_data = &data; | 123 | call_data = &data; |
| 128 | /* Send a message to all other CPUs and wait for them to respond */ | 124 | |
| 129 | smp_ext_bitcall_others(ec_call_function); | 125 | for_each_cpu_mask(cpu, map) |
| 126 | smp_ext_bitcall(cpu, ec_call_function); | ||
| 130 | 127 | ||
| 131 | /* Wait for response */ | 128 | /* Wait for response */ |
| 132 | while (atomic_read(&data.started) != cpus) | 129 | while (!cpus_equal(map, data.started)) |
| 133 | cpu_relax(); | 130 | cpu_relax(); |
| 134 | 131 | ||
| 135 | if (wait) | 132 | if (wait) |
| 136 | while (atomic_read(&data.finished) != cpus) | 133 | while (!cpus_equal(map, data.finished)) |
| 137 | cpu_relax(); | 134 | cpu_relax(); |
| 135 | |||
| 138 | spin_unlock_bh(&call_lock); | 136 | spin_unlock_bh(&call_lock); |
| 139 | 137 | ||
| 140 | return 0; | 138 | out: |
| 139 | local_irq_disable(); | ||
| 140 | if (local) | ||
| 141 | func(info); | ||
| 142 | local_irq_enable(); | ||
| 141 | } | 143 | } |
| 142 | 144 | ||
| 143 | /* | 145 | /* |
| 144 | * Call a function on one CPU | 146 | * smp_call_function: |
| 145 | * cpu : the CPU the function should be executed on | 147 | * @func: the function to run; this must be fast and non-blocking |
| 148 | * @info: an arbitrary pointer to pass to the function | ||
| 149 | * @nonatomic: unused | ||
| 150 | * @wait: if true, wait (atomically) until function has completed on other CPUs | ||
| 146 | * | 151 | * |
| 147 | * You must not call this function with disabled interrupts or from a | 152 | * Run a function on all other CPUs. |
| 148 | * hardware interrupt handler. You may call it from a bottom half. | ||
| 149 | * | 153 | * |
| 150 | * It is guaranteed that the called function runs on the specified CPU, | 154 | * You must not call this function with disabled interrupts or from a |
| 151 | * preemption is disabled. | 155 | * hardware interrupt handler. Must be called with preemption disabled. |
| 156 | * You may call it from a bottom half. | ||
| 152 | */ | 157 | */ |
| 153 | int smp_call_function_on(void (*func) (void *info), void *info, | 158 | int smp_call_function(void (*func) (void *info), void *info, int nonatomic, |
| 154 | int nonatomic, int wait, int cpu) | 159 | int wait) |
| 155 | { | 160 | { |
| 156 | struct call_data_struct data; | 161 | cpumask_t map; |
| 157 | int curr_cpu; | ||
| 158 | |||
| 159 | if (!cpu_online(cpu)) | ||
| 160 | return -EINVAL; | ||
| 161 | |||
| 162 | /* Can deadlock when interrupts are disabled or if in wrong context */ | ||
| 163 | WARN_ON(irqs_disabled() || in_irq()); | ||
| 164 | |||
| 165 | /* disable preemption for local function call */ | ||
| 166 | curr_cpu = get_cpu(); | ||
| 167 | |||
| 168 | if (curr_cpu == cpu) { | ||
| 169 | /* direct call to function */ | ||
| 170 | func(info); | ||
| 171 | put_cpu(); | ||
| 172 | return 0; | ||
| 173 | } | ||
| 174 | |||
| 175 | data.func = func; | ||
| 176 | data.info = info; | ||
| 177 | atomic_set(&data.started, 0); | ||
| 178 | data.wait = wait; | ||
| 179 | if (wait) | ||
| 180 | atomic_set(&data.finished, 0); | ||
| 181 | |||
| 182 | spin_lock_bh(&call_lock); | ||
| 183 | call_data = &data; | ||
| 184 | smp_ext_bitcall(cpu, ec_call_function); | ||
| 185 | 162 | ||
| 186 | /* Wait for response */ | 163 | map = cpu_online_map; |
| 187 | while (atomic_read(&data.started) != 1) | 164 | cpu_clear(smp_processor_id(), map); |
| 188 | cpu_relax(); | 165 | __smp_call_function_map(func, info, nonatomic, wait, map); |
| 166 | return 0; | ||
| 167 | } | ||
| 168 | EXPORT_SYMBOL(smp_call_function); | ||
| 189 | 169 | ||
| 190 | if (wait) | 170 | /* |
| 191 | while (atomic_read(&data.finished) != 1) | 171 | * smp_call_function_on: |
| 192 | cpu_relax(); | 172 | * @func: the function to run; this must be fast and non-blocking |
| 173 | * @info: an arbitrary pointer to pass to the function | ||
| 174 | * @nonatomic: unused | ||
| 175 | * @wait: if true, wait (atomically) until function has completed on other CPUs | ||
| 176 | * @cpu: the CPU where func should run | ||
| 177 | * | ||
| 178 | * Run a function on one processor. | ||
| 179 | * | ||
| 180 | * You must not call this function with disabled interrupts or from a | ||
| 181 | * hardware interrupt handler. Must be called with preemption disabled. | ||
| 182 | * You may call it from a bottom half. | ||
| 183 | */ | ||
| 184 | int smp_call_function_on(void (*func) (void *info), void *info, int nonatomic, | ||
| 185 | int wait, int cpu) | ||
| 186 | { | ||
| 187 | cpumask_t map = CPU_MASK_NONE; | ||
| 193 | 188 | ||
| 194 | spin_unlock_bh(&call_lock); | 189 | cpu_set(cpu, map); |
| 195 | put_cpu(); | 190 | __smp_call_function_map(func, info, nonatomic, wait, map); |
| 196 | return 0; | 191 | return 0; |
| 197 | } | 192 | } |
| 198 | EXPORT_SYMBOL(smp_call_function_on); | 193 | EXPORT_SYMBOL(smp_call_function_on); |
| @@ -325,26 +320,6 @@ static void smp_ext_bitcall(int cpu, ec_bit_sig sig) | |||
| 325 | udelay(10); | 320 | udelay(10); |
| 326 | } | 321 | } |
| 327 | 322 | ||
| 328 | /* | ||
| 329 | * Send an external call sigp to every other cpu in the system and | ||
| 330 | * return without waiting for its completion. | ||
| 331 | */ | ||
| 332 | static void smp_ext_bitcall_others(ec_bit_sig sig) | ||
| 333 | { | ||
| 334 | int cpu; | ||
| 335 | |||
| 336 | for_each_online_cpu(cpu) { | ||
| 337 | if (cpu == smp_processor_id()) | ||
| 338 | continue; | ||
| 339 | /* | ||
| 340 | * Set signaling bit in lowcore of target cpu and kick it | ||
| 341 | */ | ||
| 342 | set_bit(sig, (unsigned long *) &lowcore_ptr[cpu]->ext_call_fast); | ||
| 343 | while (signal_processor(cpu, sigp_emergency_signal) == sigp_busy) | ||
| 344 | udelay(10); | ||
| 345 | } | ||
| 346 | } | ||
| 347 | |||
| 348 | #ifndef CONFIG_64BIT | 323 | #ifndef CONFIG_64BIT |
| 349 | /* | 324 | /* |
| 350 | * this function sends a 'purge tlb' signal to another CPU. | 325 | * this function sends a 'purge tlb' signal to another CPU. |
| @@ -807,6 +782,5 @@ EXPORT_SYMBOL(cpu_possible_map); | |||
| 807 | EXPORT_SYMBOL(lowcore_ptr); | 782 | EXPORT_SYMBOL(lowcore_ptr); |
| 808 | EXPORT_SYMBOL(smp_ctl_set_bit); | 783 | EXPORT_SYMBOL(smp_ctl_set_bit); |
| 809 | EXPORT_SYMBOL(smp_ctl_clear_bit); | 784 | EXPORT_SYMBOL(smp_ctl_clear_bit); |
| 810 | EXPORT_SYMBOL(smp_call_function); | ||
| 811 | EXPORT_SYMBOL(smp_get_cpu); | 785 | EXPORT_SYMBOL(smp_get_cpu); |
| 812 | EXPORT_SYMBOL(smp_put_cpu); | 786 | EXPORT_SYMBOL(smp_put_cpu); |
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index ee9fd7b85928..e1ad464b6f20 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c | |||
| @@ -747,6 +747,7 @@ static void etr_adjust_time(unsigned long long clock, unsigned long long delay) | |||
| 747 | } | 747 | } |
| 748 | } | 748 | } |
| 749 | 749 | ||
| 750 | #ifdef CONFIG_SMP | ||
| 750 | static void etr_sync_cpu_start(void *dummy) | 751 | static void etr_sync_cpu_start(void *dummy) |
| 751 | { | 752 | { |
| 752 | int *in_sync = dummy; | 753 | int *in_sync = dummy; |
| @@ -758,8 +759,14 @@ static void etr_sync_cpu_start(void *dummy) | |||
| 758 | * __udelay will stop the cpu on an enabled wait psw until the | 759 | * __udelay will stop the cpu on an enabled wait psw until the |
| 759 | * TOD is running again. | 760 | * TOD is running again. |
| 760 | */ | 761 | */ |
| 761 | while (*in_sync == 0) | 762 | while (*in_sync == 0) { |
| 762 | __udelay(1); | 763 | __udelay(1); |
| 764 | /* | ||
| 765 | * A different cpu changes *in_sync. Therefore use | ||
| 766 | * barrier() to force memory access. | ||
| 767 | */ | ||
| 768 | barrier(); | ||
| 769 | } | ||
| 763 | if (*in_sync != 1) | 770 | if (*in_sync != 1) |
| 764 | /* Didn't work. Clear per-cpu in sync bit again. */ | 771 | /* Didn't work. Clear per-cpu in sync bit again. */ |
| 765 | etr_disable_sync_clock(NULL); | 772 | etr_disable_sync_clock(NULL); |
| @@ -773,6 +780,7 @@ static void etr_sync_cpu_start(void *dummy) | |||
| 773 | static void etr_sync_cpu_end(void *dummy) | 780 | static void etr_sync_cpu_end(void *dummy) |
| 774 | { | 781 | { |
| 775 | } | 782 | } |
| 783 | #endif /* CONFIG_SMP */ | ||
| 776 | 784 | ||
| 777 | /* | 785 | /* |
| 778 | * Sync the TOD clock using the port refered to by aibp. This port | 786 | * Sync the TOD clock using the port refered to by aibp. This port |
diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c index 02854449b74b..70f2a862b670 100644 --- a/arch/s390/lib/delay.c +++ b/arch/s390/lib/delay.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
| 16 | #include <linux/timex.h> | 16 | #include <linux/timex.h> |
| 17 | #include <linux/irqflags.h> | 17 | #include <linux/irqflags.h> |
| 18 | #include <linux/interrupt.h> | ||
| 18 | 19 | ||
| 19 | void __delay(unsigned long loops) | 20 | void __delay(unsigned long loops) |
| 20 | { | 21 | { |
| @@ -35,7 +36,11 @@ void __udelay(unsigned long usecs) | |||
| 35 | { | 36 | { |
| 36 | u64 end, time, jiffy_timer = 0; | 37 | u64 end, time, jiffy_timer = 0; |
| 37 | unsigned long flags, cr0, mask, dummy; | 38 | unsigned long flags, cr0, mask, dummy; |
| 39 | int irq_context; | ||
| 38 | 40 | ||
| 41 | irq_context = in_interrupt(); | ||
| 42 | if (!irq_context) | ||
| 43 | local_bh_disable(); | ||
| 39 | local_irq_save(flags); | 44 | local_irq_save(flags); |
| 40 | if (raw_irqs_disabled_flags(flags)) { | 45 | if (raw_irqs_disabled_flags(flags)) { |
| 41 | jiffy_timer = S390_lowcore.jiffy_timer; | 46 | jiffy_timer = S390_lowcore.jiffy_timer; |
| @@ -62,6 +67,8 @@ void __udelay(unsigned long usecs) | |||
| 62 | __ctl_load(cr0, 0, 0); | 67 | __ctl_load(cr0, 0, 0); |
| 63 | S390_lowcore.jiffy_timer = jiffy_timer; | 68 | S390_lowcore.jiffy_timer = jiffy_timer; |
| 64 | } | 69 | } |
| 70 | if (!irq_context) | ||
| 71 | _local_bh_enable(); | ||
| 65 | set_clock_comparator(S390_lowcore.jiffy_timer); | 72 | set_clock_comparator(S390_lowcore.jiffy_timer); |
| 66 | local_irq_restore(flags); | 73 | local_irq_restore(flags); |
| 67 | } | 74 | } |
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index b3e7c45efb63..916b72a8cde8 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c | |||
| @@ -141,7 +141,9 @@ void __init paging_init(void) | |||
| 141 | __raw_local_irq_ssm(ssm_mask); | 141 | __raw_local_irq_ssm(ssm_mask); |
| 142 | 142 | ||
| 143 | memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); | 143 | memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); |
| 144 | #ifdef CONFIG_ZONE_DMA | ||
| 144 | max_zone_pfns[ZONE_DMA] = PFN_DOWN(MAX_DMA_ADDRESS); | 145 | max_zone_pfns[ZONE_DMA] = PFN_DOWN(MAX_DMA_ADDRESS); |
| 146 | #endif | ||
| 145 | max_zone_pfns[ZONE_NORMAL] = max_low_pfn; | 147 | max_zone_pfns[ZONE_NORMAL] = max_low_pfn; |
| 146 | free_area_init_nodes(max_zone_pfns); | 148 | free_area_init_nodes(max_zone_pfns); |
| 147 | } | 149 | } |
