aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-09 14:15:23 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-09 14:15:23 -0500
commit531021f2ca681faf58f926771f85bb5c76f13eba (patch)
treeb730cd35a1bde5f2ddd85e080a6269df96c50074
parent451688ba0b488faf274e13dc591734b1e695642c (diff)
parent6252d702c5311ce916caf75ed82e5c8245171c92 (diff)
Merge branch 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6: [S390] dynamic page tables. [S390] Add four level page tables for CONFIG_64BIT=y. [S390] 1K/2K page table pages. [S390] Remove a.out header file. [S390] sclp_vt220: Fix vt220 initialization [S390] qdio: avoid hang when establishing qdio queues [S390] VMEM_MAX_PHYS overflow on 31 bit. [S390] zcrypt: Do not start ap poll thread per default [S390] Fix __ffs_word_loop/__ffz_word_loop inlnie assembly. [S390] Wire up new timerfd syscalls. [S390] Update default configuration.
-rw-r--r--arch/s390/defconfig87
-rw-r--r--arch/s390/kernel/binfmt_elf32.c11
-rw-r--r--arch/s390/kernel/compat_wrapper.S20
-rw-r--r--arch/s390/kernel/process.c1
-rw-r--r--arch/s390/kernel/setup.c1
-rw-r--r--arch/s390/kernel/syscalls.S3
-rw-r--r--arch/s390/kernel/traps.c3
-rw-r--r--arch/s390/mm/fault.c40
-rw-r--r--arch/s390/mm/init.c3
-rw-r--r--arch/s390/mm/mmap.c65
-rw-r--r--arch/s390/mm/pgtable.c176
-rw-r--r--arch/s390/mm/vmem.c28
-rw-r--r--drivers/s390/char/sclp_vt220.c31
-rw-r--r--drivers/s390/cio/qdio.c18
-rw-r--r--drivers/s390/crypto/ap_bus.c4
-rw-r--r--include/asm-s390/a.out.h32
-rw-r--r--include/asm-s390/bitops.h4
-rw-r--r--include/asm-s390/elf.h22
-rw-r--r--include/asm-s390/mmu.h9
-rw-r--r--include/asm-s390/mmu_context.h20
-rw-r--r--include/asm-s390/page.h36
-rw-r--r--include/asm-s390/pgalloc.h116
-rw-r--r--include/asm-s390/pgtable.h191
-rw-r--r--include/asm-s390/processor.h45
-rw-r--r--include/asm-s390/tlb.h49
-rw-r--r--include/asm-s390/tlbflush.h11
-rw-r--r--include/asm-s390/unistd.h5
27 files changed, 689 insertions, 342 deletions
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index ece7b99da895..39921f3a9685 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -1,12 +1,13 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.23 3# Linux kernel version: 2.6.24
4# Mon Oct 22 12:10:44 2007 4# Sat Feb 9 12:13:01 2008
5# 5#
6CONFIG_MMU=y 6CONFIG_MMU=y
7CONFIG_ZONE_DMA=y 7CONFIG_ZONE_DMA=y
8CONFIG_LOCKDEP_SUPPORT=y 8CONFIG_LOCKDEP_SUPPORT=y
9CONFIG_STACKTRACE_SUPPORT=y 9CONFIG_STACKTRACE_SUPPORT=y
10CONFIG_HAVE_LATENCYTOP_SUPPORT=y
10CONFIG_RWSEM_XCHGADD_ALGORITHM=y 11CONFIG_RWSEM_XCHGADD_ALGORITHM=y
11# CONFIG_ARCH_HAS_ILOG2_U32 is not set 12# CONFIG_ARCH_HAS_ILOG2_U32 is not set
12# CONFIG_ARCH_HAS_ILOG2_U64 is not set 13# CONFIG_ARCH_HAS_ILOG2_U64 is not set
@@ -15,6 +16,7 @@ CONFIG_GENERIC_TIME=y
15CONFIG_GENERIC_BUG=y 16CONFIG_GENERIC_BUG=y
16CONFIG_NO_IOMEM=y 17CONFIG_NO_IOMEM=y
17CONFIG_NO_DMA=y 18CONFIG_NO_DMA=y
19CONFIG_GENERIC_LOCKBREAK=y
18CONFIG_S390=y 20CONFIG_S390=y
19CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" 21CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
20 22
@@ -32,7 +34,6 @@ CONFIG_SYSVIPC_SYSCTL=y
32CONFIG_POSIX_MQUEUE=y 34CONFIG_POSIX_MQUEUE=y
33# CONFIG_BSD_PROCESS_ACCT is not set 35# CONFIG_BSD_PROCESS_ACCT is not set
34# CONFIG_TASKSTATS is not set 36# CONFIG_TASKSTATS is not set
35# CONFIG_USER_NS is not set
36CONFIG_AUDIT=y 37CONFIG_AUDIT=y
37# CONFIG_AUDITSYSCALL is not set 38# CONFIG_AUDITSYSCALL is not set
38CONFIG_IKCONFIG=y 39CONFIG_IKCONFIG=y
@@ -41,13 +42,19 @@ CONFIG_LOG_BUF_SHIFT=17
41CONFIG_CGROUPS=y 42CONFIG_CGROUPS=y
42# CONFIG_CGROUP_DEBUG is not set 43# CONFIG_CGROUP_DEBUG is not set
43CONFIG_CGROUP_NS=y 44CONFIG_CGROUP_NS=y
44CONFIG_CGROUP_CPUACCT=y
45# CONFIG_CPUSETS is not set 45# CONFIG_CPUSETS is not set
46CONFIG_FAIR_GROUP_SCHED=y 46CONFIG_FAIR_GROUP_SCHED=y
47CONFIG_FAIR_USER_SCHED=y 47CONFIG_FAIR_USER_SCHED=y
48# CONFIG_FAIR_CGROUP_SCHED is not set 48# CONFIG_FAIR_CGROUP_SCHED is not set
49# CONFIG_CGROUP_CPUACCT is not set
50# CONFIG_RESOURCE_COUNTERS is not set
49CONFIG_SYSFS_DEPRECATED=y 51CONFIG_SYSFS_DEPRECATED=y
50# CONFIG_RELAY is not set 52# CONFIG_RELAY is not set
53CONFIG_NAMESPACES=y
54CONFIG_UTS_NS=y
55CONFIG_IPC_NS=y
56# CONFIG_USER_NS is not set
57# CONFIG_PID_NS is not set
51CONFIG_BLK_DEV_INITRD=y 58CONFIG_BLK_DEV_INITRD=y
52CONFIG_INITRAMFS_SOURCE="" 59CONFIG_INITRAMFS_SOURCE=""
53# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set 60# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -61,17 +68,26 @@ CONFIG_HOTPLUG=y
61CONFIG_PRINTK=y 68CONFIG_PRINTK=y
62CONFIG_BUG=y 69CONFIG_BUG=y
63CONFIG_ELF_CORE=y 70CONFIG_ELF_CORE=y
71# CONFIG_COMPAT_BRK is not set
64CONFIG_BASE_FULL=y 72CONFIG_BASE_FULL=y
65CONFIG_FUTEX=y 73CONFIG_FUTEX=y
66CONFIG_ANON_INODES=y 74CONFIG_ANON_INODES=y
67CONFIG_EPOLL=y 75CONFIG_EPOLL=y
68CONFIG_SIGNALFD=y 76CONFIG_SIGNALFD=y
77CONFIG_TIMERFD=y
69CONFIG_EVENTFD=y 78CONFIG_EVENTFD=y
70CONFIG_SHMEM=y 79CONFIG_SHMEM=y
71CONFIG_VM_EVENT_COUNTERS=y 80CONFIG_VM_EVENT_COUNTERS=y
72CONFIG_SLAB=y 81CONFIG_SLAB=y
73# CONFIG_SLUB is not set 82# CONFIG_SLUB is not set
74# CONFIG_SLOB is not set 83# CONFIG_SLOB is not set
84# CONFIG_PROFILING is not set
85# CONFIG_MARKERS is not set
86CONFIG_HAVE_OPROFILE=y
87CONFIG_KPROBES=y
88CONFIG_HAVE_KPROBES=y
89CONFIG_PROC_PAGE_MONITOR=y
90CONFIG_SLABINFO=y
75CONFIG_RT_MUTEXES=y 91CONFIG_RT_MUTEXES=y
76# CONFIG_TINY_SHMEM is not set 92# CONFIG_TINY_SHMEM is not set
77CONFIG_BASE_SMALL=0 93CONFIG_BASE_SMALL=0
@@ -99,6 +115,8 @@ CONFIG_DEFAULT_DEADLINE=y
99# CONFIG_DEFAULT_CFQ is not set 115# CONFIG_DEFAULT_CFQ is not set
100# CONFIG_DEFAULT_NOOP is not set 116# CONFIG_DEFAULT_NOOP is not set
101CONFIG_DEFAULT_IOSCHED="deadline" 117CONFIG_DEFAULT_IOSCHED="deadline"
118CONFIG_CLASSIC_RCU=y
119# CONFIG_PREEMPT_RCU is not set
102 120
103# 121#
104# Base setup 122# Base setup
@@ -137,7 +155,7 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y
137# CONFIG_PREEMPT_NONE is not set 155# CONFIG_PREEMPT_NONE is not set
138# CONFIG_PREEMPT_VOLUNTARY is not set 156# CONFIG_PREEMPT_VOLUNTARY is not set
139CONFIG_PREEMPT=y 157CONFIG_PREEMPT=y
140CONFIG_PREEMPT_BKL=y 158# CONFIG_RCU_TRACE is not set
141CONFIG_SELECT_MEMORY_MODEL=y 159CONFIG_SELECT_MEMORY_MODEL=y
142CONFIG_FLATMEM_MANUAL=y 160CONFIG_FLATMEM_MANUAL=y
143# CONFIG_DISCONTIGMEM_MANUAL is not set 161# CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -151,7 +169,6 @@ CONFIG_RESOURCES_64BIT=y
151CONFIG_ZONE_DMA_FLAG=1 169CONFIG_ZONE_DMA_FLAG=1
152CONFIG_BOUNCE=y 170CONFIG_BOUNCE=y
153CONFIG_VIRT_TO_BUS=y 171CONFIG_VIRT_TO_BUS=y
154CONFIG_HOLES_IN_ZONE=y
155 172
156# 173#
157# I/O subsystem configuration 174# I/O subsystem configuration
@@ -180,6 +197,7 @@ CONFIG_HZ_100=y
180# CONFIG_HZ_300 is not set 197# CONFIG_HZ_300 is not set
181# CONFIG_HZ_1000 is not set 198# CONFIG_HZ_1000 is not set
182CONFIG_HZ=100 199CONFIG_HZ=100
200# CONFIG_SCHED_HRTICK is not set
183CONFIG_NO_IDLE_HZ=y 201CONFIG_NO_IDLE_HZ=y
184CONFIG_NO_IDLE_HZ_INIT=y 202CONFIG_NO_IDLE_HZ_INIT=y
185CONFIG_S390_HYPFS_FS=y 203CONFIG_S390_HYPFS_FS=y
@@ -201,6 +219,7 @@ CONFIG_XFRM=y
201# CONFIG_XFRM_USER is not set 219# CONFIG_XFRM_USER is not set
202# CONFIG_XFRM_SUB_POLICY is not set 220# CONFIG_XFRM_SUB_POLICY is not set
203# CONFIG_XFRM_MIGRATE is not set 221# CONFIG_XFRM_MIGRATE is not set
222# CONFIG_XFRM_STATISTICS is not set
204CONFIG_NET_KEY=y 223CONFIG_NET_KEY=y
205# CONFIG_NET_KEY_MIGRATE is not set 224# CONFIG_NET_KEY_MIGRATE is not set
206CONFIG_IUCV=m 225CONFIG_IUCV=m
@@ -251,6 +270,7 @@ CONFIG_IPV6_SIT=y
251# CONFIG_NETWORK_SECMARK is not set 270# CONFIG_NETWORK_SECMARK is not set
252CONFIG_NETFILTER=y 271CONFIG_NETFILTER=y
253# CONFIG_NETFILTER_DEBUG is not set 272# CONFIG_NETFILTER_DEBUG is not set
273CONFIG_NETFILTER_ADVANCED=y
254 274
255# 275#
256# Core Netfilter Configuration 276# Core Netfilter Configuration
@@ -258,7 +278,6 @@ CONFIG_NETFILTER=y
258CONFIG_NETFILTER_NETLINK=m 278CONFIG_NETFILTER_NETLINK=m
259CONFIG_NETFILTER_NETLINK_QUEUE=m 279CONFIG_NETFILTER_NETLINK_QUEUE=m
260CONFIG_NETFILTER_NETLINK_LOG=m 280CONFIG_NETFILTER_NETLINK_LOG=m
261CONFIG_NF_CONNTRACK_ENABLED=m
262CONFIG_NF_CONNTRACK=m 281CONFIG_NF_CONNTRACK=m
263# CONFIG_NF_CT_ACCT is not set 282# CONFIG_NF_CT_ACCT is not set
264# CONFIG_NF_CONNTRACK_MARK is not set 283# CONFIG_NF_CONNTRACK_MARK is not set
@@ -286,7 +305,7 @@ CONFIG_NF_CONNTRACK=m
286# CONFIG_IP_NF_ARPTABLES is not set 305# CONFIG_IP_NF_ARPTABLES is not set
287 306
288# 307#
289# IPv6: Netfilter Configuration (EXPERIMENTAL) 308# IPv6: Netfilter Configuration
290# 309#
291# CONFIG_NF_CONNTRACK_IPV6 is not set 310# CONFIG_NF_CONNTRACK_IPV6 is not set
292# CONFIG_IP6_NF_QUEUE is not set 311# CONFIG_IP6_NF_QUEUE is not set
@@ -343,6 +362,7 @@ CONFIG_NET_CLS_U32=m
343CONFIG_CLS_U32_MARK=y 362CONFIG_CLS_U32_MARK=y
344CONFIG_NET_CLS_RSVP=m 363CONFIG_NET_CLS_RSVP=m
345CONFIG_NET_CLS_RSVP6=m 364CONFIG_NET_CLS_RSVP6=m
365CONFIG_NET_CLS_FLOW=m
346# CONFIG_NET_EMATCH is not set 366# CONFIG_NET_EMATCH is not set
347CONFIG_NET_CLS_ACT=y 367CONFIG_NET_CLS_ACT=y
348CONFIG_NET_ACT_POLICE=y 368CONFIG_NET_ACT_POLICE=y
@@ -351,7 +371,6 @@ CONFIG_NET_ACT_POLICE=y
351CONFIG_NET_ACT_NAT=m 371CONFIG_NET_ACT_NAT=m
352# CONFIG_NET_ACT_PEDIT is not set 372# CONFIG_NET_ACT_PEDIT is not set
353# CONFIG_NET_ACT_SIMP is not set 373# CONFIG_NET_ACT_SIMP is not set
354CONFIG_NET_CLS_POLICE=y
355# CONFIG_NET_CLS_IND is not set 374# CONFIG_NET_CLS_IND is not set
356CONFIG_NET_SCH_FIFO=y 375CONFIG_NET_SCH_FIFO=y
357 376
@@ -360,6 +379,15 @@ CONFIG_NET_SCH_FIFO=y
360# 379#
361# CONFIG_NET_PKTGEN is not set 380# CONFIG_NET_PKTGEN is not set
362# CONFIG_NET_TCPPROBE is not set 381# CONFIG_NET_TCPPROBE is not set
382CONFIG_CAN=m
383CONFIG_CAN_RAW=m
384CONFIG_CAN_BCM=m
385
386#
387# CAN Device Drivers
388#
389CONFIG_CAN_VCAN=m
390# CONFIG_CAN_DEBUG_DEVICES is not set
363# CONFIG_AF_RXRPC is not set 391# CONFIG_AF_RXRPC is not set
364# CONFIG_RFKILL is not set 392# CONFIG_RFKILL is not set
365# CONFIG_NET_9P is not set 393# CONFIG_NET_9P is not set
@@ -389,7 +417,7 @@ CONFIG_BLK_DEV_NBD=m
389CONFIG_BLK_DEV_RAM=y 417CONFIG_BLK_DEV_RAM=y
390CONFIG_BLK_DEV_RAM_COUNT=16 418CONFIG_BLK_DEV_RAM_COUNT=16
391CONFIG_BLK_DEV_RAM_SIZE=4096 419CONFIG_BLK_DEV_RAM_SIZE=4096
392CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 420CONFIG_BLK_DEV_XIP=y
393# CONFIG_CDROM_PKTCDVD is not set 421# CONFIG_CDROM_PKTCDVD is not set
394# CONFIG_ATA_OVER_ETH is not set 422# CONFIG_ATA_OVER_ETH is not set
395 423
@@ -406,6 +434,7 @@ CONFIG_DASD_DIAG=y
406CONFIG_DASD_EER=y 434CONFIG_DASD_EER=y
407CONFIG_MISC_DEVICES=y 435CONFIG_MISC_DEVICES=y
408# CONFIG_EEPROM_93CX6 is not set 436# CONFIG_EEPROM_93CX6 is not set
437# CONFIG_ENCLOSURE_SERVICES is not set
409 438
410# 439#
411# SCSI device support 440# SCSI device support
@@ -487,6 +516,7 @@ CONFIG_NET_ETHERNET=y
487# CONFIG_IBM_NEW_EMAC_TAH is not set 516# CONFIG_IBM_NEW_EMAC_TAH is not set
488# CONFIG_IBM_NEW_EMAC_EMAC4 is not set 517# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
489CONFIG_NETDEV_1000=y 518CONFIG_NETDEV_1000=y
519# CONFIG_E1000E_ENABLED is not set
490CONFIG_NETDEV_10000=y 520CONFIG_NETDEV_10000=y
491# CONFIG_TR is not set 521# CONFIG_TR is not set
492# CONFIG_WAN is not set 522# CONFIG_WAN is not set
@@ -508,7 +538,6 @@ CONFIG_QETH=y
508CONFIG_CCWGROUP=y 538CONFIG_CCWGROUP=y
509# CONFIG_PPP is not set 539# CONFIG_PPP is not set
510# CONFIG_SLIP is not set 540# CONFIG_SLIP is not set
511# CONFIG_SHAPER is not set
512# CONFIG_NETCONSOLE is not set 541# CONFIG_NETCONSOLE is not set
513# CONFIG_NETPOLL is not set 542# CONFIG_NETPOLL is not set
514# CONFIG_NET_POLL_CONTROLLER is not set 543# CONFIG_NET_POLL_CONTROLLER is not set
@@ -558,6 +587,7 @@ CONFIG_S390_TAPE_34XX=m
558CONFIG_MONWRITER=m 587CONFIG_MONWRITER=m
559CONFIG_S390_VMUR=m 588CONFIG_S390_VMUR=m
560# CONFIG_POWER_SUPPLY is not set 589# CONFIG_POWER_SUPPLY is not set
590# CONFIG_THERMAL is not set
561# CONFIG_WATCHDOG is not set 591# CONFIG_WATCHDOG is not set
562 592
563# 593#
@@ -584,12 +614,10 @@ CONFIG_FS_POSIX_ACL=y
584# CONFIG_XFS_FS is not set 614# CONFIG_XFS_FS is not set
585# CONFIG_GFS2_FS is not set 615# CONFIG_GFS2_FS is not set
586# CONFIG_OCFS2_FS is not set 616# CONFIG_OCFS2_FS is not set
587# CONFIG_MINIX_FS is not set 617CONFIG_DNOTIFY=y
588# CONFIG_ROMFS_FS is not set
589CONFIG_INOTIFY=y 618CONFIG_INOTIFY=y
590CONFIG_INOTIFY_USER=y 619CONFIG_INOTIFY_USER=y
591# CONFIG_QUOTA is not set 620# CONFIG_QUOTA is not set
592CONFIG_DNOTIFY=y
593# CONFIG_AUTOFS_FS is not set 621# CONFIG_AUTOFS_FS is not set
594# CONFIG_AUTOFS4_FS is not set 622# CONFIG_AUTOFS4_FS is not set
595# CONFIG_FUSE_FS is not set 623# CONFIG_FUSE_FS is not set
@@ -632,8 +660,10 @@ CONFIG_CONFIGFS_FS=m
632# CONFIG_EFS_FS is not set 660# CONFIG_EFS_FS is not set
633# CONFIG_CRAMFS is not set 661# CONFIG_CRAMFS is not set
634# CONFIG_VXFS_FS is not set 662# CONFIG_VXFS_FS is not set
663# CONFIG_MINIX_FS is not set
635# CONFIG_HPFS_FS is not set 664# CONFIG_HPFS_FS is not set
636# CONFIG_QNX4FS_FS is not set 665# CONFIG_QNX4FS_FS is not set
666# CONFIG_ROMFS_FS is not set
637# CONFIG_SYSV_FS is not set 667# CONFIG_SYSV_FS is not set
638# CONFIG_UFS_FS is not set 668# CONFIG_UFS_FS is not set
639CONFIG_NETWORK_FILESYSTEMS=y 669CONFIG_NETWORK_FILESYSTEMS=y
@@ -686,16 +716,13 @@ CONFIG_MSDOS_PARTITION=y
686# CONFIG_NLS is not set 716# CONFIG_NLS is not set
687CONFIG_DLM=m 717CONFIG_DLM=m
688# CONFIG_DLM_DEBUG is not set 718# CONFIG_DLM_DEBUG is not set
689CONFIG_INSTRUMENTATION=y
690# CONFIG_PROFILING is not set
691CONFIG_KPROBES=y
692# CONFIG_MARKERS is not set
693 719
694# 720#
695# Kernel hacking 721# Kernel hacking
696# 722#
697CONFIG_TRACE_IRQFLAGS_SUPPORT=y 723CONFIG_TRACE_IRQFLAGS_SUPPORT=y
698# CONFIG_PRINTK_TIME is not set 724# CONFIG_PRINTK_TIME is not set
725CONFIG_ENABLE_WARN_DEPRECATED=y
699CONFIG_ENABLE_MUST_CHECK=y 726CONFIG_ENABLE_MUST_CHECK=y
700CONFIG_MAGIC_SYSRQ=y 727CONFIG_MAGIC_SYSRQ=y
701# CONFIG_UNUSED_SYMBOLS is not set 728# CONFIG_UNUSED_SYMBOLS is not set
@@ -721,12 +748,18 @@ CONFIG_DEBUG_BUGVERBOSE=y
721# CONFIG_DEBUG_INFO is not set 748# CONFIG_DEBUG_INFO is not set
722# CONFIG_DEBUG_VM is not set 749# CONFIG_DEBUG_VM is not set
723# CONFIG_DEBUG_LIST is not set 750# CONFIG_DEBUG_LIST is not set
751# CONFIG_DEBUG_SG is not set
724# CONFIG_FRAME_POINTER is not set 752# CONFIG_FRAME_POINTER is not set
725CONFIG_FORCED_INLINING=y 753CONFIG_FORCED_INLINING=y
726# CONFIG_RCU_TORTURE_TEST is not set 754# CONFIG_RCU_TORTURE_TEST is not set
755# CONFIG_KPROBES_SANITY_TEST is not set
756# CONFIG_BACKTRACE_SELF_TEST is not set
727# CONFIG_LKDTM is not set 757# CONFIG_LKDTM is not set
728# CONFIG_FAULT_INJECTION is not set 758# CONFIG_FAULT_INJECTION is not set
759# CONFIG_LATENCYTOP is not set
729CONFIG_SAMPLES=y 760CONFIG_SAMPLES=y
761# CONFIG_SAMPLE_KOBJECT is not set
762# CONFIG_DEBUG_PAGEALLOC is not set
730 763
731# 764#
732# Security options 765# Security options
@@ -738,6 +771,7 @@ CONFIG_CRYPTO=y
738CONFIG_CRYPTO_ALGAPI=y 771CONFIG_CRYPTO_ALGAPI=y
739CONFIG_CRYPTO_AEAD=m 772CONFIG_CRYPTO_AEAD=m
740CONFIG_CRYPTO_BLKCIPHER=y 773CONFIG_CRYPTO_BLKCIPHER=y
774CONFIG_CRYPTO_SEQIV=m
741CONFIG_CRYPTO_HASH=m 775CONFIG_CRYPTO_HASH=m
742CONFIG_CRYPTO_MANAGER=y 776CONFIG_CRYPTO_MANAGER=y
743CONFIG_CRYPTO_HMAC=m 777CONFIG_CRYPTO_HMAC=m
@@ -745,17 +779,20 @@ CONFIG_CRYPTO_HMAC=m
745# CONFIG_CRYPTO_NULL is not set 779# CONFIG_CRYPTO_NULL is not set
746# CONFIG_CRYPTO_MD4 is not set 780# CONFIG_CRYPTO_MD4 is not set
747CONFIG_CRYPTO_MD5=m 781CONFIG_CRYPTO_MD5=m
748# CONFIG_CRYPTO_SHA1 is not set 782CONFIG_CRYPTO_SHA1=m
749# CONFIG_CRYPTO_SHA256 is not set 783# CONFIG_CRYPTO_SHA256 is not set
750# CONFIG_CRYPTO_SHA512 is not set 784# CONFIG_CRYPTO_SHA512 is not set
751# CONFIG_CRYPTO_WP512 is not set 785# CONFIG_CRYPTO_WP512 is not set
752# CONFIG_CRYPTO_TGR192 is not set 786# CONFIG_CRYPTO_TGR192 is not set
753# CONFIG_CRYPTO_GF128MUL is not set 787CONFIG_CRYPTO_GF128MUL=m
754CONFIG_CRYPTO_ECB=m 788CONFIG_CRYPTO_ECB=m
755CONFIG_CRYPTO_CBC=y 789CONFIG_CRYPTO_CBC=y
756CONFIG_CRYPTO_PCBC=m 790CONFIG_CRYPTO_PCBC=m
757# CONFIG_CRYPTO_LRW is not set 791# CONFIG_CRYPTO_LRW is not set
758# CONFIG_CRYPTO_XTS is not set 792# CONFIG_CRYPTO_XTS is not set
793CONFIG_CRYPTO_CTR=m
794CONFIG_CRYPTO_GCM=m
795CONFIG_CRYPTO_CCM=m
759# CONFIG_CRYPTO_CRYPTD is not set 796# CONFIG_CRYPTO_CRYPTD is not set
760# CONFIG_CRYPTO_DES is not set 797# CONFIG_CRYPTO_DES is not set
761CONFIG_CRYPTO_FCRYPT=m 798CONFIG_CRYPTO_FCRYPT=m
@@ -770,20 +807,22 @@ CONFIG_CRYPTO_FCRYPT=m
770# CONFIG_CRYPTO_KHAZAD is not set 807# CONFIG_CRYPTO_KHAZAD is not set
771# CONFIG_CRYPTO_ANUBIS is not set 808# CONFIG_CRYPTO_ANUBIS is not set
772CONFIG_CRYPTO_SEED=m 809CONFIG_CRYPTO_SEED=m
810CONFIG_CRYPTO_SALSA20=m
773# CONFIG_CRYPTO_DEFLATE is not set 811# CONFIG_CRYPTO_DEFLATE is not set
774# CONFIG_CRYPTO_MICHAEL_MIC is not set 812# CONFIG_CRYPTO_MICHAEL_MIC is not set
775# CONFIG_CRYPTO_CRC32C is not set 813# CONFIG_CRYPTO_CRC32C is not set
776CONFIG_CRYPTO_CAMELLIA=m 814CONFIG_CRYPTO_CAMELLIA=m
777# CONFIG_CRYPTO_TEST is not set 815# CONFIG_CRYPTO_TEST is not set
778CONFIG_CRYPTO_AUTHENC=m 816CONFIG_CRYPTO_AUTHENC=m
817CONFIG_CRYPTO_LZO=m
779CONFIG_CRYPTO_HW=y 818CONFIG_CRYPTO_HW=y
819CONFIG_ZCRYPT=m
820# CONFIG_ZCRYPT_MONOLITHIC is not set
780# CONFIG_CRYPTO_SHA1_S390 is not set 821# CONFIG_CRYPTO_SHA1_S390 is not set
781# CONFIG_CRYPTO_SHA256_S390 is not set 822# CONFIG_CRYPTO_SHA256_S390 is not set
782# CONFIG_CRYPTO_DES_S390 is not set 823# CONFIG_CRYPTO_DES_S390 is not set
783# CONFIG_CRYPTO_AES_S390 is not set 824# CONFIG_CRYPTO_AES_S390 is not set
784CONFIG_S390_PRNG=m 825CONFIG_S390_PRNG=m
785CONFIG_ZCRYPT=m
786# CONFIG_ZCRYPT_MONOLITHIC is not set
787 826
788# 827#
789# Library routines 828# Library routines
@@ -794,5 +833,7 @@ CONFIG_BITREVERSE=m
794# CONFIG_CRC_ITU_T is not set 833# CONFIG_CRC_ITU_T is not set
795CONFIG_CRC32=m 834CONFIG_CRC32=m
796CONFIG_CRC7=m 835CONFIG_CRC7=m
797# CONFIG_LIBCRC32C is not set 836CONFIG_LIBCRC32C=m
837CONFIG_LZO_COMPRESS=m
838CONFIG_LZO_DECOMPRESS=m
798CONFIG_PLIST=y 839CONFIG_PLIST=y
diff --git a/arch/s390/kernel/binfmt_elf32.c b/arch/s390/kernel/binfmt_elf32.c
index f1e40ca00d8d..3e1c315b736d 100644
--- a/arch/s390/kernel/binfmt_elf32.c
+++ b/arch/s390/kernel/binfmt_elf32.c
@@ -134,6 +134,7 @@ static inline int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
134} 134}
135 135
136#include <asm/processor.h> 136#include <asm/processor.h>
137#include <asm/pgalloc.h>
137#include <linux/module.h> 138#include <linux/module.h>
138#include <linux/elfcore.h> 139#include <linux/elfcore.h>
139#include <linux/binfmts.h> 140#include <linux/binfmts.h>
@@ -183,6 +184,16 @@ struct elf_prpsinfo32
183#undef start_thread 184#undef start_thread
184#define start_thread start_thread31 185#define start_thread start_thread31
185 186
187static inline void start_thread31(struct pt_regs *regs, unsigned long new_psw,
188 unsigned long new_stackp)
189{
190 set_fs(USER_DS);
191 regs->psw.mask = psw_user32_bits;
192 regs->psw.addr = new_psw;
193 regs->gprs[15] = new_stackp;
194 crst_table_downgrade(current->mm, 1UL << 31);
195}
196
186MODULE_DESCRIPTION("Binary format loader for compatibility with 32bit Linux for S390 binaries," 197MODULE_DESCRIPTION("Binary format loader for compatibility with 32bit Linux for S390 binaries,"
187 " Copyright 2000 IBM Corporation"); 198 " Copyright 2000 IBM Corporation");
188MODULE_AUTHOR("Gerhard Tonn <ton@de.ibm.com>"); 199MODULE_AUTHOR("Gerhard Tonn <ton@de.ibm.com>");
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index 062c3d4c0394..743d54f0b8db 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -1712,3 +1712,23 @@ sys_fallocate_wrapper:
1712 sllg %r5,%r6,32 # get high word of 64bit loff_t 1712 sllg %r5,%r6,32 # get high word of 64bit loff_t
1713 l %r5,164(%r15) # get low word of 64bit loff_t 1713 l %r5,164(%r15) # get low word of 64bit loff_t
1714 jg sys_fallocate 1714 jg sys_fallocate
1715
1716 .globl sys_timerfd_create_wrapper
1717sys_timerfd_create_wrapper:
1718 lgfr %r2,%r2 # int
1719 lgfr %r3,%r3 # int
1720 jg sys_timerfd_create
1721
1722 .globl compat_sys_timerfd_settime_wrapper
1723compat_sys_timerfd_settime_wrapper:
1724 lgfr %r2,%r2 # int
1725 lgfr %r3,%r3 # int
1726 llgtr %r4,%r4 # struct compat_itimerspec *
1727 llgtr %r5,%r5 # struct compat_itimerspec *
1728 jg compat_sys_timerfd_settime
1729
1730 .globl compat_sys_timerfd_gettime_wrapper
1731compat_sys_timerfd_gettime_wrapper:
1732 lgfr %r2,%r2 # int
1733 llgtr %r3,%r3 # struct compat_itimerspec *
1734 jg compat_sys_timerfd_gettime
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 0e7aca039307..a6a4729e0e94 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -29,7 +29,6 @@
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/vmalloc.h> 30#include <linux/vmalloc.h>
31#include <linux/user.h> 31#include <linux/user.h>
32#include <linux/a.out.h>
33#include <linux/interrupt.h> 32#include <linux/interrupt.h>
34#include <linux/delay.h> 33#include <linux/delay.h>
35#include <linux/reboot.h> 34#include <linux/reboot.h>
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index f9f8779022a0..290e504061a3 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -24,7 +24,6 @@
24#include <linux/ptrace.h> 24#include <linux/ptrace.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/user.h> 26#include <linux/user.h>
27#include <linux/a.out.h>
28#include <linux/tty.h> 27#include <linux/tty.h>
29#include <linux/ioport.h> 28#include <linux/ioport.h>
30#include <linux/delay.h> 29#include <linux/delay.h>
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
index 25eac7802fc4..c87ec687d4c6 100644
--- a/arch/s390/kernel/syscalls.S
+++ b/arch/s390/kernel/syscalls.S
@@ -327,3 +327,6 @@ SYSCALL(sys_utimensat,sys_utimensat,compat_sys_utimensat_wrapper) /* 315 */
327SYSCALL(sys_signalfd,sys_signalfd,compat_sys_signalfd_wrapper) 327SYSCALL(sys_signalfd,sys_signalfd,compat_sys_signalfd_wrapper)
328NI_SYSCALL /* 317 old sys_timer_fd */ 328NI_SYSCALL /* 317 old sys_timer_fd */
329SYSCALL(sys_eventfd,sys_eventfd,sys_eventfd_wrapper) 329SYSCALL(sys_eventfd,sys_eventfd,sys_eventfd_wrapper)
330SYSCALL(sys_timerfd_create,sys_timerfd_create,sys_timerfd_create_wrapper)
331SYSCALL(sys_timerfd_settime,sys_timerfd_settime,compat_sys_timerfd_settime_wrapper) /* 320 */
332SYSCALL(sys_timerfd_gettime,sys_timerfd_gettime,compat_sys_timerfd_gettime_wrapper)
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index a4d29025ddbd..60f728aeaf12 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -60,6 +60,7 @@ int sysctl_userprocess_debug = 0;
60extern pgm_check_handler_t do_protection_exception; 60extern pgm_check_handler_t do_protection_exception;
61extern pgm_check_handler_t do_dat_exception; 61extern pgm_check_handler_t do_dat_exception;
62extern pgm_check_handler_t do_monitor_call; 62extern pgm_check_handler_t do_monitor_call;
63extern pgm_check_handler_t do_asce_exception;
63 64
64#define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; }) 65#define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; })
65 66
@@ -730,7 +731,7 @@ void __init trap_init(void)
730 pgm_check_table[0x12] = &translation_exception; 731 pgm_check_table[0x12] = &translation_exception;
731 pgm_check_table[0x13] = &special_op_exception; 732 pgm_check_table[0x13] = &special_op_exception;
732#ifdef CONFIG_64BIT 733#ifdef CONFIG_64BIT
733 pgm_check_table[0x38] = &do_dat_exception; 734 pgm_check_table[0x38] = &do_asce_exception;
734 pgm_check_table[0x39] = &do_dat_exception; 735 pgm_check_table[0x39] = &do_dat_exception;
735 pgm_check_table[0x3A] = &do_dat_exception; 736 pgm_check_table[0x3A] = &do_dat_exception;
736 pgm_check_table[0x3B] = &do_dat_exception; 737 pgm_check_table[0x3B] = &do_dat_exception;
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 2456b52ed068..ed13d429a487 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -32,6 +32,7 @@
32#include <asm/system.h> 32#include <asm/system.h>
33#include <asm/pgtable.h> 33#include <asm/pgtable.h>
34#include <asm/s390_ext.h> 34#include <asm/s390_ext.h>
35#include <asm/mmu_context.h>
35 36
36#ifndef CONFIG_64BIT 37#ifndef CONFIG_64BIT
37#define __FAIL_ADDR_MASK 0x7ffff000 38#define __FAIL_ADDR_MASK 0x7ffff000
@@ -444,6 +445,45 @@ void __kprobes do_dat_exception(struct pt_regs *regs, unsigned long error_code)
444 do_exception(regs, error_code & 0xff, 0); 445 do_exception(regs, error_code & 0xff, 0);
445} 446}
446 447
448#ifdef CONFIG_64BIT
449void __kprobes do_asce_exception(struct pt_regs *regs, unsigned long error_code)
450{
451 struct mm_struct *mm;
452 struct vm_area_struct *vma;
453 unsigned long address;
454 int space;
455
456 mm = current->mm;
457 address = S390_lowcore.trans_exc_code & __FAIL_ADDR_MASK;
458 space = check_space(current);
459
460 if (unlikely(space == 0 || in_atomic() || !mm))
461 goto no_context;
462
463 local_irq_enable();
464
465 down_read(&mm->mmap_sem);
466 vma = find_vma(mm, address);
467 up_read(&mm->mmap_sem);
468
469 if (vma) {
470 update_mm(mm, current);
471 return;
472 }
473
474 /* User mode accesses just cause a SIGSEGV */
475 if (regs->psw.mask & PSW_MASK_PSTATE) {
476 current->thread.prot_addr = address;
477 current->thread.trap_no = error_code;
478 do_sigsegv(regs, error_code, SEGV_MAPERR, address);
479 return;
480 }
481
482no_context:
483 do_no_context(regs, error_code, address);
484}
485#endif
486
447#ifdef CONFIG_PFAULT 487#ifdef CONFIG_PFAULT
448/* 488/*
449 * 'pfault' pseudo page faults routines. 489 * 'pfault' pseudo page faults routines.
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 983ec6ec0e7c..8053245fe259 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -112,6 +112,7 @@ void __init paging_init(void)
112 init_mm.pgd = swapper_pg_dir; 112 init_mm.pgd = swapper_pg_dir;
113 S390_lowcore.kernel_asce = __pa(init_mm.pgd) & PAGE_MASK; 113 S390_lowcore.kernel_asce = __pa(init_mm.pgd) & PAGE_MASK;
114#ifdef CONFIG_64BIT 114#ifdef CONFIG_64BIT
115 /* A three level page table (4TB) is enough for the kernel space. */
115 S390_lowcore.kernel_asce |= _ASCE_TYPE_REGION3 | _ASCE_TABLE_LENGTH; 116 S390_lowcore.kernel_asce |= _ASCE_TYPE_REGION3 | _ASCE_TABLE_LENGTH;
116 pgd_type = _REGION3_ENTRY_EMPTY; 117 pgd_type = _REGION3_ENTRY_EMPTY;
117#else 118#else
@@ -184,7 +185,7 @@ void kernel_map_pages(struct page *page, int numpages, int enable)
184 pmd = pmd_offset(pud, address); 185 pmd = pmd_offset(pud, address);
185 pte = pte_offset_kernel(pmd, address); 186 pte = pte_offset_kernel(pmd, address);
186 if (!enable) { 187 if (!enable) {
187 ptep_invalidate(address, pte); 188 ptep_invalidate(&init_mm, address, pte);
188 continue; 189 continue;
189 } 190 }
190 *pte = mk_pte_phys(address, __pgprot(_PAGE_TYPE_RW)); 191 *pte = mk_pte_phys(address, __pgprot(_PAGE_TYPE_RW));
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
index 356257c171de..5932a824547a 100644
--- a/arch/s390/mm/mmap.c
+++ b/arch/s390/mm/mmap.c
@@ -27,6 +27,7 @@
27#include <linux/personality.h> 27#include <linux/personality.h>
28#include <linux/mm.h> 28#include <linux/mm.h>
29#include <linux/module.h> 29#include <linux/module.h>
30#include <asm/pgalloc.h>
30 31
31/* 32/*
32 * Top of mmap area (just below the process stack). 33 * Top of mmap area (just below the process stack).
@@ -62,6 +63,8 @@ static inline int mmap_is_legacy(void)
62 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY; 63 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY;
63} 64}
64 65
66#ifndef CONFIG_64BIT
67
65/* 68/*
66 * This function, called very early during the creation of a new 69 * This function, called very early during the creation of a new
67 * process VM image, sets up which VM layout function to use: 70 * process VM image, sets up which VM layout function to use:
@@ -84,3 +87,65 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
84} 87}
85EXPORT_SYMBOL_GPL(arch_pick_mmap_layout); 88EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
86 89
90#else
91
92static unsigned long
93s390_get_unmapped_area(struct file *filp, unsigned long addr,
94 unsigned long len, unsigned long pgoff, unsigned long flags)
95{
96 struct mm_struct *mm = current->mm;
97 int rc;
98
99 addr = arch_get_unmapped_area(filp, addr, len, pgoff, flags);
100 if (addr & ~PAGE_MASK)
101 return addr;
102 if (unlikely(mm->context.asce_limit < addr + len)) {
103 rc = crst_table_upgrade(mm, addr + len);
104 if (rc)
105 return (unsigned long) rc;
106 }
107 return addr;
108}
109
110static unsigned long
111s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
112 const unsigned long len, const unsigned long pgoff,
113 const unsigned long flags)
114{
115 struct mm_struct *mm = current->mm;
116 unsigned long addr = addr0;
117 int rc;
118
119 addr = arch_get_unmapped_area_topdown(filp, addr, len, pgoff, flags);
120 if (addr & ~PAGE_MASK)
121 return addr;
122 if (unlikely(mm->context.asce_limit < addr + len)) {
123 rc = crst_table_upgrade(mm, addr + len);
124 if (rc)
125 return (unsigned long) rc;
126 }
127 return addr;
128}
129/*
130 * This function, called very early during the creation of a new
131 * process VM image, sets up which VM layout function to use:
132 */
133void arch_pick_mmap_layout(struct mm_struct *mm)
134{
135 /*
136 * Fall back to the standard layout if the personality
137 * bit is set, or if the expected stack growth is unlimited:
138 */
139 if (mmap_is_legacy()) {
140 mm->mmap_base = TASK_UNMAPPED_BASE;
141 mm->get_unmapped_area = s390_get_unmapped_area;
142 mm->unmap_area = arch_unmap_area;
143 } else {
144 mm->mmap_base = mmap_base();
145 mm->get_unmapped_area = s390_get_unmapped_area_topdown;
146 mm->unmap_area = arch_unmap_area_topdown;
147 }
148}
149EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
150
151#endif
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 019f518cd5a0..fd072013f88c 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -23,11 +23,18 @@
23#include <asm/pgalloc.h> 23#include <asm/pgalloc.h>
24#include <asm/tlb.h> 24#include <asm/tlb.h>
25#include <asm/tlbflush.h> 25#include <asm/tlbflush.h>
26#include <asm/mmu_context.h>
26 27
27#ifndef CONFIG_64BIT 28#ifndef CONFIG_64BIT
28#define ALLOC_ORDER 1 29#define ALLOC_ORDER 1
30#define TABLES_PER_PAGE 4
31#define FRAG_MASK 15UL
32#define SECOND_HALVES 10UL
29#else 33#else
30#define ALLOC_ORDER 2 34#define ALLOC_ORDER 2
35#define TABLES_PER_PAGE 2
36#define FRAG_MASK 3UL
37#define SECOND_HALVES 2UL
31#endif 38#endif
32 39
33unsigned long *crst_table_alloc(struct mm_struct *mm, int noexec) 40unsigned long *crst_table_alloc(struct mm_struct *mm, int noexec)
@@ -45,52 +52,179 @@ unsigned long *crst_table_alloc(struct mm_struct *mm, int noexec)
45 } 52 }
46 page->index = page_to_phys(shadow); 53 page->index = page_to_phys(shadow);
47 } 54 }
55 spin_lock(&mm->page_table_lock);
56 list_add(&page->lru, &mm->context.crst_list);
57 spin_unlock(&mm->page_table_lock);
48 return (unsigned long *) page_to_phys(page); 58 return (unsigned long *) page_to_phys(page);
49} 59}
50 60
51void crst_table_free(unsigned long *table) 61void crst_table_free(struct mm_struct *mm, unsigned long *table)
52{ 62{
53 unsigned long *shadow = get_shadow_table(table); 63 unsigned long *shadow = get_shadow_table(table);
64 struct page *page = virt_to_page(table);
54 65
66 spin_lock(&mm->page_table_lock);
67 list_del(&page->lru);
68 spin_unlock(&mm->page_table_lock);
55 if (shadow) 69 if (shadow)
56 free_pages((unsigned long) shadow, ALLOC_ORDER); 70 free_pages((unsigned long) shadow, ALLOC_ORDER);
57 free_pages((unsigned long) table, ALLOC_ORDER); 71 free_pages((unsigned long) table, ALLOC_ORDER);
58} 72}
59 73
74#ifdef CONFIG_64BIT
75int crst_table_upgrade(struct mm_struct *mm, unsigned long limit)
76{
77 unsigned long *table, *pgd;
78 unsigned long entry;
79
80 BUG_ON(limit > (1UL << 53));
81repeat:
82 table = crst_table_alloc(mm, mm->context.noexec);
83 if (!table)
84 return -ENOMEM;
85 spin_lock(&mm->page_table_lock);
86 if (mm->context.asce_limit < limit) {
87 pgd = (unsigned long *) mm->pgd;
88 if (mm->context.asce_limit <= (1UL << 31)) {
89 entry = _REGION3_ENTRY_EMPTY;
90 mm->context.asce_limit = 1UL << 42;
91 mm->context.asce_bits = _ASCE_TABLE_LENGTH |
92 _ASCE_USER_BITS |
93 _ASCE_TYPE_REGION3;
94 } else {
95 entry = _REGION2_ENTRY_EMPTY;
96 mm->context.asce_limit = 1UL << 53;
97 mm->context.asce_bits = _ASCE_TABLE_LENGTH |
98 _ASCE_USER_BITS |
99 _ASCE_TYPE_REGION2;
100 }
101 crst_table_init(table, entry);
102 pgd_populate(mm, (pgd_t *) table, (pud_t *) pgd);
103 mm->pgd = (pgd_t *) table;
104 table = NULL;
105 }
106 spin_unlock(&mm->page_table_lock);
107 if (table)
108 crst_table_free(mm, table);
109 if (mm->context.asce_limit < limit)
110 goto repeat;
111 update_mm(mm, current);
112 return 0;
113}
114
115void crst_table_downgrade(struct mm_struct *mm, unsigned long limit)
116{
117 pgd_t *pgd;
118
119 if (mm->context.asce_limit <= limit)
120 return;
121 __tlb_flush_mm(mm);
122 while (mm->context.asce_limit > limit) {
123 pgd = mm->pgd;
124 switch (pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) {
125 case _REGION_ENTRY_TYPE_R2:
126 mm->context.asce_limit = 1UL << 42;
127 mm->context.asce_bits = _ASCE_TABLE_LENGTH |
128 _ASCE_USER_BITS |
129 _ASCE_TYPE_REGION3;
130 break;
131 case _REGION_ENTRY_TYPE_R3:
132 mm->context.asce_limit = 1UL << 31;
133 mm->context.asce_bits = _ASCE_TABLE_LENGTH |
134 _ASCE_USER_BITS |
135 _ASCE_TYPE_SEGMENT;
136 break;
137 default:
138 BUG();
139 }
140 mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN);
141 crst_table_free(mm, (unsigned long *) pgd);
142 }
143 update_mm(mm, current);
144}
145#endif
146
60/* 147/*
61 * page table entry allocation/free routines. 148 * page table entry allocation/free routines.
62 */ 149 */
63unsigned long *page_table_alloc(int noexec) 150unsigned long *page_table_alloc(struct mm_struct *mm)
64{ 151{
65 struct page *page = alloc_page(GFP_KERNEL); 152 struct page *page;
66 unsigned long *table; 153 unsigned long *table;
154 unsigned long bits;
67 155
68 if (!page) 156 bits = mm->context.noexec ? 3UL : 1UL;
69 return NULL; 157 spin_lock(&mm->page_table_lock);
70 page->index = 0; 158 page = NULL;
71 if (noexec) { 159 if (!list_empty(&mm->context.pgtable_list)) {
72 struct page *shadow = alloc_page(GFP_KERNEL); 160 page = list_first_entry(&mm->context.pgtable_list,
73 if (!shadow) { 161 struct page, lru);
74 __free_page(page); 162 if ((page->flags & FRAG_MASK) == ((1UL << TABLES_PER_PAGE) - 1))
163 page = NULL;
164 }
165 if (!page) {
166 spin_unlock(&mm->page_table_lock);
167 page = alloc_page(GFP_KERNEL|__GFP_REPEAT);
168 if (!page)
75 return NULL; 169 return NULL;
76 } 170 pgtable_page_ctor(page);
77 table = (unsigned long *) page_to_phys(shadow); 171 page->flags &= ~FRAG_MASK;
172 table = (unsigned long *) page_to_phys(page);
78 clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE); 173 clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE);
79 page->index = (addr_t) table; 174 spin_lock(&mm->page_table_lock);
175 list_add(&page->lru, &mm->context.pgtable_list);
80 } 176 }
81 pgtable_page_ctor(page);
82 table = (unsigned long *) page_to_phys(page); 177 table = (unsigned long *) page_to_phys(page);
83 clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE); 178 while (page->flags & bits) {
179 table += 256;
180 bits <<= 1;
181 }
182 page->flags |= bits;
183 if ((page->flags & FRAG_MASK) == ((1UL << TABLES_PER_PAGE) - 1))
184 list_move_tail(&page->lru, &mm->context.pgtable_list);
185 spin_unlock(&mm->page_table_lock);
84 return table; 186 return table;
85} 187}
86 188
87void page_table_free(unsigned long *table) 189void page_table_free(struct mm_struct *mm, unsigned long *table)
88{ 190{
89 unsigned long *shadow = get_shadow_pte(table); 191 struct page *page;
192 unsigned long bits;
90 193
91 pgtable_page_dtor(virt_to_page(table)); 194 bits = mm->context.noexec ? 3UL : 1UL;
92 if (shadow) 195 bits <<= (__pa(table) & (PAGE_SIZE - 1)) / 256 / sizeof(unsigned long);
93 free_page((unsigned long) shadow); 196 page = pfn_to_page(__pa(table) >> PAGE_SHIFT);
94 free_page((unsigned long) table); 197 spin_lock(&mm->page_table_lock);
198 page->flags ^= bits;
199 if (page->flags & FRAG_MASK) {
200 /* Page now has some free pgtable fragments. */
201 list_move(&page->lru, &mm->context.pgtable_list);
202 page = NULL;
203 } else
204 /* All fragments of the 4K page have been freed. */
205 list_del(&page->lru);
206 spin_unlock(&mm->page_table_lock);
207 if (page) {
208 pgtable_page_dtor(page);
209 __free_page(page);
210 }
211}
95 212
213void disable_noexec(struct mm_struct *mm, struct task_struct *tsk)
214{
215 struct page *page;
216
217 spin_lock(&mm->page_table_lock);
218 /* Free shadow region and segment tables. */
219 list_for_each_entry(page, &mm->context.crst_list, lru)
220 if (page->index) {
221 free_pages((unsigned long) page->index, ALLOC_ORDER);
222 page->index = 0;
223 }
224 /* "Free" second halves of page tables. */
225 list_for_each_entry(page, &mm->context.pgtable_list, lru)
226 page->flags &= ~SECOND_HALVES;
227 spin_unlock(&mm->page_table_lock);
228 mm->context.noexec = 0;
229 update_mm(mm, tsk);
96} 230}
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
index 7c1287ccf788..35d90a4720fd 100644
--- a/arch/s390/mm/vmem.c
+++ b/arch/s390/mm/vmem.c
@@ -69,7 +69,19 @@ static void __ref *vmem_alloc_pages(unsigned int order)
69 return alloc_bootmem_pages((1 << order) * PAGE_SIZE); 69 return alloc_bootmem_pages((1 << order) * PAGE_SIZE);
70} 70}
71 71
72#define vmem_pud_alloc() ({ BUG(); ((pud_t *) NULL); }) 72static inline pud_t *vmem_pud_alloc(void)
73{
74 pud_t *pud = NULL;
75
76#ifdef CONFIG_64BIT
77 pud = vmem_alloc_pages(2);
78 if (!pud)
79 return NULL;
80 pud_val(*pud) = _REGION3_ENTRY_EMPTY;
81 memcpy(pud + 1, pud, (PTRS_PER_PUD - 1)*sizeof(pud_t));
82#endif
83 return pud;
84}
73 85
74static inline pmd_t *vmem_pmd_alloc(void) 86static inline pmd_t *vmem_pmd_alloc(void)
75{ 87{
@@ -84,13 +96,18 @@ static inline pmd_t *vmem_pmd_alloc(void)
84 return pmd; 96 return pmd;
85} 97}
86 98
87static inline pte_t *vmem_pte_alloc(void) 99static pte_t __init_refok *vmem_pte_alloc(void)
88{ 100{
89 pte_t *pte = vmem_alloc_pages(0); 101 pte_t *pte;
90 102
103 if (slab_is_available())
104 pte = (pte_t *) page_table_alloc(&init_mm);
105 else
106 pte = alloc_bootmem(PTRS_PER_PTE * sizeof(pte_t));
91 if (!pte) 107 if (!pte)
92 return NULL; 108 return NULL;
93 clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY, PAGE_SIZE); 109 clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY,
110 PTRS_PER_PTE * sizeof(pte_t));
94 return pte; 111 return pte;
95} 112}
96 113
@@ -360,6 +377,9 @@ void __init vmem_map_init(void)
360{ 377{
361 int i; 378 int i;
362 379
380 INIT_LIST_HEAD(&init_mm.context.crst_list);
381 INIT_LIST_HEAD(&init_mm.context.pgtable_list);
382 init_mm.context.noexec = 0;
363 NODE_DATA(0)->node_mem_map = VMEM_MAP; 383 NODE_DATA(0)->node_mem_map = VMEM_MAP;
364 for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) 384 for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++)
365 vmem_add_mem(memory_chunk[i].addr, memory_chunk[i].size); 385 vmem_add_mem(memory_chunk[i].addr, memory_chunk[i].size);
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index 68071622d4bb..f47f4a768be5 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -3,7 +3,7 @@
3 * SCLP VT220 terminal driver. 3 * SCLP VT220 terminal driver.
4 * 4 *
5 * S390 version 5 * S390 version
6 * Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation 6 * Copyright IBM Corp. 2003,2008
7 * Author(s): Peter Oberparleiter <Peter.Oberparleiter@de.ibm.com> 7 * Author(s): Peter Oberparleiter <Peter.Oberparleiter@de.ibm.com>
8 */ 8 */
9 9
@@ -632,6 +632,9 @@ static void __init __sclp_vt220_cleanup(void)
632 else 632 else
633 free_bootmem((unsigned long) page, PAGE_SIZE); 633 free_bootmem((unsigned long) page, PAGE_SIZE);
634 } 634 }
635 if (!list_empty(&sclp_vt220_register.list))
636 sclp_unregister(&sclp_vt220_register);
637 sclp_vt220_initialized = 0;
635} 638}
636 639
637static int __init __sclp_vt220_init(void) 640static int __init __sclp_vt220_init(void)
@@ -639,6 +642,7 @@ static int __init __sclp_vt220_init(void)
639 void *page; 642 void *page;
640 int i; 643 int i;
641 int num_pages; 644 int num_pages;
645 int rc;
642 646
643 if (sclp_vt220_initialized) 647 if (sclp_vt220_initialized)
644 return 0; 648 return 0;
@@ -667,7 +671,14 @@ static int __init __sclp_vt220_init(void)
667 } 671 }
668 list_add_tail((struct list_head *) page, &sclp_vt220_empty); 672 list_add_tail((struct list_head *) page, &sclp_vt220_empty);
669 } 673 }
670 return 0; 674 rc = sclp_register(&sclp_vt220_register);
675 if (rc) {
676 printk(KERN_ERR SCLP_VT220_PRINT_HEADER
677 "could not register vt220 - "
678 "sclp_register returned %d\n", rc);
679 __sclp_vt220_cleanup();
680 }
681 return rc;
671} 682}
672 683
673static const struct tty_operations sclp_vt220_ops = { 684static const struct tty_operations sclp_vt220_ops = {
@@ -688,22 +699,17 @@ static int __init sclp_vt220_tty_init(void)
688{ 699{
689 struct tty_driver *driver; 700 struct tty_driver *driver;
690 int rc; 701 int rc;
702 int cleanup;
691 703
692 /* Note: we're not testing for CONSOLE_IS_SCLP here to preserve 704 /* Note: we're not testing for CONSOLE_IS_SCLP here to preserve
693 * symmetry between VM and LPAR systems regarding ttyS1. */ 705 * symmetry between VM and LPAR systems regarding ttyS1. */
694 driver = alloc_tty_driver(1); 706 driver = alloc_tty_driver(1);
695 if (!driver) 707 if (!driver)
696 return -ENOMEM; 708 return -ENOMEM;
709 cleanup = !sclp_vt220_initialized;
697 rc = __sclp_vt220_init(); 710 rc = __sclp_vt220_init();
698 if (rc) 711 if (rc)
699 goto out_driver; 712 goto out_driver;
700 rc = sclp_register(&sclp_vt220_register);
701 if (rc) {
702 printk(KERN_ERR SCLP_VT220_PRINT_HEADER
703 "could not register tty - "
704 "sclp_register returned %d\n", rc);
705 goto out_init;
706 }
707 713
708 driver->owner = THIS_MODULE; 714 driver->owner = THIS_MODULE;
709 driver->driver_name = SCLP_VT220_DRIVER_NAME; 715 driver->driver_name = SCLP_VT220_DRIVER_NAME;
@@ -721,15 +727,14 @@ static int __init sclp_vt220_tty_init(void)
721 printk(KERN_ERR SCLP_VT220_PRINT_HEADER 727 printk(KERN_ERR SCLP_VT220_PRINT_HEADER
722 "could not register tty - " 728 "could not register tty - "
723 "tty_register_driver returned %d\n", rc); 729 "tty_register_driver returned %d\n", rc);
724 goto out_sclp; 730 goto out_init;
725 } 731 }
726 sclp_vt220_driver = driver; 732 sclp_vt220_driver = driver;
727 return 0; 733 return 0;
728 734
729out_sclp:
730 sclp_unregister(&sclp_vt220_register);
731out_init: 735out_init:
732 __sclp_vt220_cleanup(); 736 if (cleanup)
737 __sclp_vt220_cleanup();
733out_driver: 738out_driver:
734 put_tty_driver(driver); 739 put_tty_driver(driver);
735 return rc; 740 return rc;
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index e2a781b6b21d..097fc0967e9d 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -3189,13 +3189,11 @@ qdio_establish(struct qdio_initialize *init_data)
3189 spin_lock_irqsave(get_ccwdev_lock(cdev),saveflags); 3189 spin_lock_irqsave(get_ccwdev_lock(cdev),saveflags);
3190 3190
3191 ccw_device_set_options_mask(cdev, 0); 3191 ccw_device_set_options_mask(cdev, 0);
3192 result=ccw_device_start_timeout(cdev,&irq_ptr->ccw, 3192 result = ccw_device_start(cdev, &irq_ptr->ccw,
3193 QDIO_DOING_ESTABLISH,0, 0, 3193 QDIO_DOING_ESTABLISH, 0, 0);
3194 QDIO_ESTABLISH_TIMEOUT);
3195 if (result) { 3194 if (result) {
3196 result2=ccw_device_start_timeout(cdev,&irq_ptr->ccw, 3195 result2 = ccw_device_start(cdev, &irq_ptr->ccw,
3197 QDIO_DOING_ESTABLISH,0,0, 3196 QDIO_DOING_ESTABLISH, 0, 0);
3198 QDIO_ESTABLISH_TIMEOUT);
3199 sprintf(dbf_text,"eq:io%4x",result); 3197 sprintf(dbf_text,"eq:io%4x",result);
3200 QDIO_DBF_TEXT2(1,setup,dbf_text); 3198 QDIO_DBF_TEXT2(1,setup,dbf_text);
3201 if (result2) { 3199 if (result2) {
@@ -3219,10 +3217,10 @@ qdio_establish(struct qdio_initialize *init_data)
3219 return result; 3217 return result;
3220 } 3218 }
3221 3219
3222 /* Timeout is cared for already by using ccw_device_start_timeout(). */ 3220 wait_event_interruptible_timeout(cdev->private->wait_q,
3223 wait_event_interruptible(cdev->private->wait_q, 3221 irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED ||
3224 irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED || 3222 irq_ptr->state == QDIO_IRQ_STATE_ERR,
3225 irq_ptr->state == QDIO_IRQ_STATE_ERR); 3223 QDIO_ESTABLISH_TIMEOUT);
3226 3224
3227 if (irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED) 3225 if (irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED)
3228 result = 0; 3226 result = 0;
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 67aaff3e668d..d0c6fd3b1c19 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -61,9 +61,9 @@ module_param_named(domain, ap_domain_index, int, 0000);
61MODULE_PARM_DESC(domain, "domain index for ap devices"); 61MODULE_PARM_DESC(domain, "domain index for ap devices");
62EXPORT_SYMBOL(ap_domain_index); 62EXPORT_SYMBOL(ap_domain_index);
63 63
64static int ap_thread_flag = 1; 64static int ap_thread_flag = 0;
65module_param_named(poll_thread, ap_thread_flag, int, 0000); 65module_param_named(poll_thread, ap_thread_flag, int, 0000);
66MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 1 (on)."); 66MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 0 (off).");
67 67
68static struct device *ap_root_device = NULL; 68static struct device *ap_root_device = NULL;
69static DEFINE_SPINLOCK(ap_device_lock); 69static DEFINE_SPINLOCK(ap_device_lock);
diff --git a/include/asm-s390/a.out.h b/include/asm-s390/a.out.h
deleted file mode 100644
index 8d6bd9c2952e..000000000000
--- a/include/asm-s390/a.out.h
+++ /dev/null
@@ -1,32 +0,0 @@
1/*
2 * include/asm-s390/a.out.h
3 *
4 * S390 version
5 * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
6 *
7 * Derived from "include/asm-i386/a.out.h"
8 * Copyright (C) 1992, Linus Torvalds
9 *
10 * I don't think we'll ever need a.out ...
11 */
12
13#ifndef __S390_A_OUT_H__
14#define __S390_A_OUT_H__
15
16struct exec
17{
18 unsigned long a_info; /* Use macros N_MAGIC, etc for access */
19 unsigned a_text; /* length of text, in bytes */
20 unsigned a_data; /* length of data, in bytes */
21 unsigned a_bss; /* length of uninitialized data area for file, in bytes */
22 unsigned a_syms; /* length of symbol table data in file, in bytes */
23 unsigned a_entry; /* start address */
24 unsigned a_trsize; /* length of relocation info for text, in bytes */
25 unsigned a_drsize; /* length of relocation info for data, in bytes */
26};
27
28#define N_TRSIZE(a) ((a).a_trsize)
29#define N_DRSIZE(a) ((a).a_drsize)
30#define N_SYMSIZE(a) ((a).a_syms)
31
32#endif /* __A_OUT_GNU_H__ */
diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h
index 882db054110c..ab83c844d04c 100644
--- a/include/asm-s390/bitops.h
+++ b/include/asm-s390/bitops.h
@@ -472,7 +472,7 @@ static inline unsigned long __ffz_word_loop(const unsigned long *addr,
472 " brct %1,0b\n" 472 " brct %1,0b\n"
473 "1:\n" 473 "1:\n"
474#endif 474#endif
475 : "+a" (bytes), "+d" (size) 475 : "+&a" (bytes), "+&d" (size)
476 : "d" (-1UL), "a" (addr), "m" (*(addrtype *) addr) 476 : "d" (-1UL), "a" (addr), "m" (*(addrtype *) addr)
477 : "cc" ); 477 : "cc" );
478 return bytes; 478 return bytes;
@@ -507,7 +507,7 @@ static inline unsigned long __ffs_word_loop(const unsigned long *addr,
507 " brct %1,0b\n" 507 " brct %1,0b\n"
508 "1:\n" 508 "1:\n"
509#endif 509#endif
510 : "+a" (bytes), "+a" (size) 510 : "+&a" (bytes), "+&a" (size)
511 : "d" (0UL), "a" (addr), "m" (*(addrtype *) addr) 511 : "d" (0UL), "a" (addr), "m" (*(addrtype *) addr)
512 : "cc" ); 512 : "cc" );
513 return bytes; 513 return bytes;
diff --git a/include/asm-s390/elf.h b/include/asm-s390/elf.h
index b73a424d0f97..b3ac262c4582 100644
--- a/include/asm-s390/elf.h
+++ b/include/asm-s390/elf.h
@@ -115,6 +115,7 @@ typedef s390_regs elf_gregset_t;
115 115
116#include <linux/sched.h> /* for task_struct */ 116#include <linux/sched.h> /* for task_struct */
117#include <asm/system.h> /* for save_access_regs */ 117#include <asm/system.h> /* for save_access_regs */
118#include <asm/mmu_context.h>
118 119
119/* 120/*
120 * This is used to ensure we don't load something for the wrong architecture. 121 * This is used to ensure we don't load something for the wrong architecture.
@@ -137,14 +138,7 @@ typedef s390_regs elf_gregset_t;
137 use of this is to invoke "./ld.so someprog" to test out a new version of 138 use of this is to invoke "./ld.so someprog" to test out a new version of
138 the loader. We need to make sure that it is out of the way of the program 139 the loader. We need to make sure that it is out of the way of the program
139 that it will "exec", and that there is sufficient room for the brk. */ 140 that it will "exec", and that there is sufficient room for the brk. */
140 141#define ELF_ET_DYN_BASE (STACK_TOP / 3 * 2)
141#ifndef __s390x__
142#define ELF_ET_DYN_BASE ((TASK_SIZE & 0x80000000) \
143 ? TASK_SIZE / 3 * 2 \
144 : 2 * TASK_SIZE / 3)
145#else /* __s390x__ */
146#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
147#endif /* __s390x__ */
148 142
149/* Wow, the "main" arch needs arch dependent functions too.. :) */ 143/* Wow, the "main" arch needs arch dependent functions too.. :) */
150 144
@@ -214,4 +208,16 @@ do { \
214} while (0) 208} while (0)
215#endif /* __s390x__ */ 209#endif /* __s390x__ */
216 210
211/*
212 * An executable for which elf_read_implies_exec() returns TRUE will
213 * have the READ_IMPLIES_EXEC personality flag set automatically.
214 */
215#define elf_read_implies_exec(ex, executable_stack) \
216({ \
217 if (current->mm->context.noexec && \
218 executable_stack != EXSTACK_DISABLE_X) \
219 disable_noexec(current->mm, current); \
220 current->mm->context.noexec == 0; \
221})
222
217#endif 223#endif
diff --git a/include/asm-s390/mmu.h b/include/asm-s390/mmu.h
index ccd36d26615a..1698e29c5b20 100644
--- a/include/asm-s390/mmu.h
+++ b/include/asm-s390/mmu.h
@@ -1,7 +1,12 @@
1#ifndef __MMU_H 1#ifndef __MMU_H
2#define __MMU_H 2#define __MMU_H
3 3
4/* Default "unsigned long" context */ 4typedef struct {
5typedef unsigned long mm_context_t; 5 struct list_head crst_list;
6 struct list_head pgtable_list;
7 unsigned long asce_bits;
8 unsigned long asce_limit;
9 int noexec;
10} mm_context_t;
6 11
7#endif 12#endif
diff --git a/include/asm-s390/mmu_context.h b/include/asm-s390/mmu_context.h
index a77d4ba3c8eb..b5a34c6f91a9 100644
--- a/include/asm-s390/mmu_context.h
+++ b/include/asm-s390/mmu_context.h
@@ -10,15 +10,19 @@
10#define __S390_MMU_CONTEXT_H 10#define __S390_MMU_CONTEXT_H
11 11
12#include <asm/pgalloc.h> 12#include <asm/pgalloc.h>
13#include <asm/uaccess.h>
13#include <asm-generic/mm_hooks.h> 14#include <asm-generic/mm_hooks.h>
14 15
15static inline int init_new_context(struct task_struct *tsk, 16static inline int init_new_context(struct task_struct *tsk,
16 struct mm_struct *mm) 17 struct mm_struct *mm)
17{ 18{
18 mm->context = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS; 19 mm->context.asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS;
19#ifdef CONFIG_64BIT 20#ifdef CONFIG_64BIT
20 mm->context |= _ASCE_TYPE_REGION3; 21 mm->context.asce_bits |= _ASCE_TYPE_REGION3;
21#endif 22#endif
23 mm->context.noexec = s390_noexec;
24 mm->context.asce_limit = STACK_TOP_MAX;
25 crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm));
22 return 0; 26 return 0;
23} 27}
24 28
@@ -32,24 +36,25 @@ static inline int init_new_context(struct task_struct *tsk,
32 36
33static inline void update_mm(struct mm_struct *mm, struct task_struct *tsk) 37static inline void update_mm(struct mm_struct *mm, struct task_struct *tsk)
34{ 38{
35 S390_lowcore.user_asce = mm->context | __pa(mm->pgd); 39 pgd_t *pgd = mm->pgd;
40
41 S390_lowcore.user_asce = mm->context.asce_bits | __pa(pgd);
36 if (switch_amode) { 42 if (switch_amode) {
37 /* Load primary space page table origin. */ 43 /* Load primary space page table origin. */
38 pgd_t *shadow_pgd = get_shadow_table(mm->pgd) ? : mm->pgd; 44 pgd = mm->context.noexec ? get_shadow_table(pgd) : pgd;
39 S390_lowcore.user_exec_asce = mm->context | __pa(shadow_pgd); 45 S390_lowcore.user_exec_asce = mm->context.asce_bits | __pa(pgd);
40 asm volatile(LCTL_OPCODE" 1,1,%0\n" 46 asm volatile(LCTL_OPCODE" 1,1,%0\n"
41 : : "m" (S390_lowcore.user_exec_asce) ); 47 : : "m" (S390_lowcore.user_exec_asce) );
42 } else 48 } else
43 /* Load home space page table origin. */ 49 /* Load home space page table origin. */
44 asm volatile(LCTL_OPCODE" 13,13,%0" 50 asm volatile(LCTL_OPCODE" 13,13,%0"
45 : : "m" (S390_lowcore.user_asce) ); 51 : : "m" (S390_lowcore.user_asce) );
52 set_fs(current->thread.mm_segment);
46} 53}
47 54
48static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, 55static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
49 struct task_struct *tsk) 56 struct task_struct *tsk)
50{ 57{
51 if (unlikely(prev == next))
52 return;
53 cpu_set(smp_processor_id(), next->cpu_vm_mask); 58 cpu_set(smp_processor_id(), next->cpu_vm_mask);
54 update_mm(next, tsk); 59 update_mm(next, tsk);
55} 60}
@@ -61,7 +66,6 @@ static inline void activate_mm(struct mm_struct *prev,
61 struct mm_struct *next) 66 struct mm_struct *next)
62{ 67{
63 switch_mm(prev, next, current); 68 switch_mm(prev, next, current);
64 set_fs(current->thread.mm_segment);
65} 69}
66 70
67#endif /* __S390_MMU_CONTEXT_H */ 71#endif /* __S390_MMU_CONTEXT_H */
diff --git a/include/asm-s390/page.h b/include/asm-s390/page.h
index 7f29a981f48c..fe7f92b6ae6d 100644
--- a/include/asm-s390/page.h
+++ b/include/asm-s390/page.h
@@ -74,43 +74,17 @@ static inline void copy_page(void *to, void *from)
74 74
75typedef struct { unsigned long pgprot; } pgprot_t; 75typedef struct { unsigned long pgprot; } pgprot_t;
76typedef struct { unsigned long pte; } pte_t; 76typedef struct { unsigned long pte; } pte_t;
77
78#define pte_val(x) ((x).pte)
79#define pgprot_val(x) ((x).pgprot)
80
81#ifndef __s390x__
82
83typedef struct { unsigned long pmd; } pmd_t; 77typedef struct { unsigned long pmd; } pmd_t;
84typedef struct { unsigned long pud; } pud_t; 78typedef struct { unsigned long pud; } pud_t;
85typedef struct {
86 unsigned long pgd0;
87 unsigned long pgd1;
88 unsigned long pgd2;
89 unsigned long pgd3;
90 } pgd_t;
91
92#define pmd_val(x) ((x).pmd)
93#define pud_val(x) ((x).pud)
94#define pgd_val(x) ((x).pgd0)
95
96#else /* __s390x__ */
97
98typedef struct {
99 unsigned long pmd0;
100 unsigned long pmd1;
101 } pmd_t;
102typedef struct { unsigned long pud; } pud_t;
103typedef struct { unsigned long pgd; } pgd_t; 79typedef struct { unsigned long pgd; } pgd_t;
80typedef pte_t *pgtable_t;
104 81
105#define pmd_val(x) ((x).pmd0) 82#define pgprot_val(x) ((x).pgprot)
106#define pmd_val1(x) ((x).pmd1) 83#define pte_val(x) ((x).pte)
84#define pmd_val(x) ((x).pmd)
107#define pud_val(x) ((x).pud) 85#define pud_val(x) ((x).pud)
108#define pgd_val(x) ((x).pgd) 86#define pgd_val(x) ((x).pgd)
109 87
110#endif /* __s390x__ */
111
112typedef struct page *pgtable_t;
113
114#define __pte(x) ((pte_t) { (x) } ) 88#define __pte(x) ((pte_t) { (x) } )
115#define __pmd(x) ((pmd_t) { (x) } ) 89#define __pmd(x) ((pmd_t) { (x) } )
116#define __pgd(x) ((pgd_t) { (x) } ) 90#define __pgd(x) ((pgd_t) { (x) } )
@@ -167,7 +141,7 @@ static inline int pfn_valid(unsigned long pfn)
167#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) 141#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
168#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) 142#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
169 143
170#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ 144#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \
171 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) 145 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
172 146
173#include <asm-generic/memory_model.h> 147#include <asm-generic/memory_model.h>
diff --git a/include/asm-s390/pgalloc.h b/include/asm-s390/pgalloc.h
index 900d44807e10..f5b2bf3d7c1d 100644
--- a/include/asm-s390/pgalloc.h
+++ b/include/asm-s390/pgalloc.h
@@ -20,10 +20,11 @@
20#define check_pgt_cache() do {} while (0) 20#define check_pgt_cache() do {} while (0)
21 21
22unsigned long *crst_table_alloc(struct mm_struct *, int); 22unsigned long *crst_table_alloc(struct mm_struct *, int);
23void crst_table_free(unsigned long *); 23void crst_table_free(struct mm_struct *, unsigned long *);
24 24
25unsigned long *page_table_alloc(int); 25unsigned long *page_table_alloc(struct mm_struct *);
26void page_table_free(unsigned long *); 26void page_table_free(struct mm_struct *, unsigned long *);
27void disable_noexec(struct mm_struct *, struct task_struct *);
27 28
28static inline void clear_table(unsigned long *s, unsigned long val, size_t n) 29static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
29{ 30{
@@ -72,23 +73,49 @@ static inline unsigned long pgd_entry_type(struct mm_struct *mm)
72 73
73static inline unsigned long pgd_entry_type(struct mm_struct *mm) 74static inline unsigned long pgd_entry_type(struct mm_struct *mm)
74{ 75{
75 return _REGION3_ENTRY_EMPTY; 76 if (mm->context.asce_limit <= (1UL << 31))
77 return _SEGMENT_ENTRY_EMPTY;
78 if (mm->context.asce_limit <= (1UL << 42))
79 return _REGION3_ENTRY_EMPTY;
80 return _REGION2_ENTRY_EMPTY;
76} 81}
77 82
78#define pud_alloc_one(mm,address) ({ BUG(); ((pud_t *)2); }) 83int crst_table_upgrade(struct mm_struct *, unsigned long limit);
79#define pud_free(mm, x) do { } while (0) 84void crst_table_downgrade(struct mm_struct *, unsigned long limit);
85
86static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address)
87{
88 unsigned long *table = crst_table_alloc(mm, mm->context.noexec);
89 if (table)
90 crst_table_init(table, _REGION3_ENTRY_EMPTY);
91 return (pud_t *) table;
92}
93#define pud_free(mm, pud) crst_table_free(mm, (unsigned long *) pud)
80 94
81static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr) 95static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
82{ 96{
83 unsigned long *crst = crst_table_alloc(mm, s390_noexec); 97 unsigned long *table = crst_table_alloc(mm, mm->context.noexec);
84 if (crst) 98 if (table)
85 crst_table_init(crst, _SEGMENT_ENTRY_EMPTY); 99 crst_table_init(table, _SEGMENT_ENTRY_EMPTY);
86 return (pmd_t *) crst; 100 return (pmd_t *) table;
87} 101}
88#define pmd_free(mm, pmd) crst_table_free((unsigned long *)pmd) 102#define pmd_free(mm, pmd) crst_table_free(mm, (unsigned long *) pmd)
89 103
90#define pgd_populate(mm, pgd, pud) BUG() 104static inline void pgd_populate_kernel(struct mm_struct *mm,
91#define pgd_populate_kernel(mm, pgd, pud) BUG() 105 pgd_t *pgd, pud_t *pud)
106{
107 pgd_val(*pgd) = _REGION2_ENTRY | __pa(pud);
108}
109
110static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
111{
112 pgd_populate_kernel(mm, pgd, pud);
113 if (mm->context.noexec) {
114 pgd = get_shadow_table(pgd);
115 pud = get_shadow_table(pud);
116 pgd_populate_kernel(mm, pgd, pud);
117 }
118}
92 119
93static inline void pud_populate_kernel(struct mm_struct *mm, 120static inline void pud_populate_kernel(struct mm_struct *mm,
94 pud_t *pud, pmd_t *pmd) 121 pud_t *pud, pmd_t *pmd)
@@ -98,63 +125,50 @@ static inline void pud_populate_kernel(struct mm_struct *mm,
98 125
99static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) 126static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
100{ 127{
101 pud_t *shadow_pud = get_shadow_table(pud);
102 pmd_t *shadow_pmd = get_shadow_table(pmd);
103
104 if (shadow_pud && shadow_pmd)
105 pud_populate_kernel(mm, shadow_pud, shadow_pmd);
106 pud_populate_kernel(mm, pud, pmd); 128 pud_populate_kernel(mm, pud, pmd);
129 if (mm->context.noexec) {
130 pud = get_shadow_table(pud);
131 pmd = get_shadow_table(pmd);
132 pud_populate_kernel(mm, pud, pmd);
133 }
107} 134}
108 135
109#endif /* __s390x__ */ 136#endif /* __s390x__ */
110 137
111static inline pgd_t *pgd_alloc(struct mm_struct *mm) 138static inline pgd_t *pgd_alloc(struct mm_struct *mm)
112{ 139{
113 unsigned long *crst = crst_table_alloc(mm, s390_noexec); 140 INIT_LIST_HEAD(&mm->context.crst_list);
114 if (crst) 141 INIT_LIST_HEAD(&mm->context.pgtable_list);
115 crst_table_init(crst, pgd_entry_type(mm)); 142 return (pgd_t *) crst_table_alloc(mm, s390_noexec);
116 return (pgd_t *) crst;
117} 143}
118#define pgd_free(mm, pgd) crst_table_free((unsigned long *) pgd) 144#define pgd_free(mm, pgd) crst_table_free(mm, (unsigned long *) pgd)
119 145
120static inline void 146static inline void pmd_populate_kernel(struct mm_struct *mm,
121pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) 147 pmd_t *pmd, pte_t *pte)
122{ 148{
123#ifndef __s390x__
124 pmd_val(pmd[0]) = _SEGMENT_ENTRY + __pa(pte);
125 pmd_val(pmd[1]) = _SEGMENT_ENTRY + __pa(pte+256);
126 pmd_val(pmd[2]) = _SEGMENT_ENTRY + __pa(pte+512);
127 pmd_val(pmd[3]) = _SEGMENT_ENTRY + __pa(pte+768);
128#else /* __s390x__ */
129 pmd_val(*pmd) = _SEGMENT_ENTRY + __pa(pte); 149 pmd_val(*pmd) = _SEGMENT_ENTRY + __pa(pte);
130 pmd_val1(*pmd) = _SEGMENT_ENTRY + __pa(pte+256);
131#endif /* __s390x__ */
132} 150}
133 151
134static inline void 152static inline void pmd_populate(struct mm_struct *mm,
135pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t page) 153 pmd_t *pmd, pgtable_t pte)
136{ 154{
137 pte_t *pte = (pte_t *)page_to_phys(page);
138 pmd_t *shadow_pmd = get_shadow_table(pmd);
139 pte_t *shadow_pte = get_shadow_pte(pte);
140
141 pmd_populate_kernel(mm, pmd, pte); 155 pmd_populate_kernel(mm, pmd, pte);
142 if (shadow_pmd && shadow_pte) 156 if (mm->context.noexec) {
143 pmd_populate_kernel(mm, shadow_pmd, shadow_pte); 157 pmd = get_shadow_table(pmd);
158 pmd_populate_kernel(mm, pmd, pte + PTRS_PER_PTE);
159 }
144} 160}
145#define pmd_pgtable(pmd) pmd_page(pmd) 161
162#define pmd_pgtable(pmd) \
163 (pgtable_t)(pmd_val(pmd) & -sizeof(pte_t)*PTRS_PER_PTE)
146 164
147/* 165/*
148 * page table entry allocation/free routines. 166 * page table entry allocation/free routines.
149 */ 167 */
150#define pte_alloc_one_kernel(mm, vmaddr) \ 168#define pte_alloc_one_kernel(mm, vmaddr) ((pte_t *) page_table_alloc(mm))
151 ((pte_t *) page_table_alloc(s390_noexec)) 169#define pte_alloc_one(mm, vmaddr) ((pte_t *) page_table_alloc(mm))
152#define pte_alloc_one(mm, vmaddr) \ 170
153 virt_to_page(page_table_alloc(s390_noexec)) 171#define pte_free_kernel(mm, pte) page_table_free(mm, (unsigned long *) pte)
154 172#define pte_free(mm, pte) page_table_free(mm, (unsigned long *) pte)
155#define pte_free_kernel(mm, pte) \
156 page_table_free((unsigned long *) pte)
157#define pte_free(mm, pte) \
158 page_table_free((unsigned long *) page_to_phys((struct page *) pte))
159 173
160#endif /* _S390_PGALLOC_H */ 174#endif /* _S390_PGALLOC_H */
diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h
index 3f520754e71c..65154dc9a9e5 100644
--- a/include/asm-s390/pgtable.h
+++ b/include/asm-s390/pgtable.h
@@ -57,21 +57,21 @@ extern char empty_zero_page[PAGE_SIZE];
57 * PGDIR_SHIFT determines what a third-level page table entry can map 57 * PGDIR_SHIFT determines what a third-level page table entry can map
58 */ 58 */
59#ifndef __s390x__ 59#ifndef __s390x__
60# define PMD_SHIFT 22 60# define PMD_SHIFT 20
61# define PUD_SHIFT 22 61# define PUD_SHIFT 20
62# define PGDIR_SHIFT 22 62# define PGDIR_SHIFT 20
63#else /* __s390x__ */ 63#else /* __s390x__ */
64# define PMD_SHIFT 21 64# define PMD_SHIFT 20
65# define PUD_SHIFT 31 65# define PUD_SHIFT 31
66# define PGDIR_SHIFT 31 66# define PGDIR_SHIFT 42
67#endif /* __s390x__ */ 67#endif /* __s390x__ */
68 68
69#define PMD_SIZE (1UL << PMD_SHIFT) 69#define PMD_SIZE (1UL << PMD_SHIFT)
70#define PMD_MASK (~(PMD_SIZE-1)) 70#define PMD_MASK (~(PMD_SIZE-1))
71#define PUD_SIZE (1UL << PUD_SHIFT) 71#define PUD_SIZE (1UL << PUD_SHIFT)
72#define PUD_MASK (~(PUD_SIZE-1)) 72#define PUD_MASK (~(PUD_SIZE-1))
73#define PGDIR_SIZE (1UL << PGDIR_SHIFT) 73#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
74#define PGDIR_MASK (~(PGDIR_SIZE-1)) 74#define PGDIR_MASK (~(PGDIR_SIZE-1))
75 75
76/* 76/*
77 * entries per page directory level: the S390 is two-level, so 77 * entries per page directory level: the S390 is two-level, so
@@ -79,17 +79,15 @@ extern char empty_zero_page[PAGE_SIZE];
79 * for S390 segment-table entries are combined to one PGD 79 * for S390 segment-table entries are combined to one PGD
80 * that leads to 1024 pte per pgd 80 * that leads to 1024 pte per pgd
81 */ 81 */
82#define PTRS_PER_PTE 256
82#ifndef __s390x__ 83#ifndef __s390x__
83# define PTRS_PER_PTE 1024 84#define PTRS_PER_PMD 1
84# define PTRS_PER_PMD 1 85#define PTRS_PER_PUD 1
85# define PTRS_PER_PUD 1
86# define PTRS_PER_PGD 512
87#else /* __s390x__ */ 86#else /* __s390x__ */
88# define PTRS_PER_PTE 512 87#define PTRS_PER_PMD 2048
89# define PTRS_PER_PMD 1024 88#define PTRS_PER_PUD 2048
90# define PTRS_PER_PUD 1
91# define PTRS_PER_PGD 2048
92#endif /* __s390x__ */ 89#endif /* __s390x__ */
90#define PTRS_PER_PGD 2048
93 91
94#define FIRST_USER_ADDRESS 0 92#define FIRST_USER_ADDRESS 0
95 93
@@ -127,8 +125,9 @@ extern char empty_zero_page[PAGE_SIZE];
127 * mapping. This needs to be calculated at compile time since the size of the 125 * mapping. This needs to be calculated at compile time since the size of the
128 * VMEM_MAP is static but the size of struct page can change. 126 * VMEM_MAP is static but the size of struct page can change.
129 */ 127 */
130#define VMEM_MAX_PHYS min(VMALLOC_START, ((VMEM_MAP_END - VMALLOC_END) / \ 128#define VMEM_MAX_PAGES ((VMEM_MAP_END - VMALLOC_END) / sizeof(struct page))
131 sizeof(struct page) * PAGE_SIZE) & ~((16 << 20) - 1)) 129#define VMEM_MAX_PFN min(VMALLOC_START >> PAGE_SHIFT, VMEM_MAX_PAGES)
130#define VMEM_MAX_PHYS ((VMEM_MAX_PFN << PAGE_SHIFT) & ~((16 << 20) - 1))
132#define VMEM_MAP ((struct page *) VMALLOC_END) 131#define VMEM_MAP ((struct page *) VMALLOC_END)
133 132
134/* 133/*
@@ -375,24 +374,6 @@ extern char empty_zero_page[PAGE_SIZE];
375# define PxD_SHADOW_SHIFT 2 374# define PxD_SHADOW_SHIFT 2
376#endif /* __s390x__ */ 375#endif /* __s390x__ */
377 376
378static inline struct page *get_shadow_page(struct page *page)
379{
380 if (s390_noexec && page->index)
381 return virt_to_page((void *)(addr_t) page->index);
382 return NULL;
383}
384
385static inline void *get_shadow_pte(void *table)
386{
387 unsigned long addr, offset;
388 struct page *page;
389
390 addr = (unsigned long) table;
391 offset = addr & (PAGE_SIZE - 1);
392 page = virt_to_page((void *)(addr ^ offset));
393 return (void *)(addr_t)(page->index ? (page->index | offset) : 0UL);
394}
395
396static inline void *get_shadow_table(void *table) 377static inline void *get_shadow_table(void *table)
397{ 378{
398 unsigned long addr, offset; 379 unsigned long addr, offset;
@@ -410,17 +391,16 @@ static inline void *get_shadow_table(void *table)
410 * hook is made available. 391 * hook is made available.
411 */ 392 */
412static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, 393static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
413 pte_t *pteptr, pte_t pteval) 394 pte_t *ptep, pte_t entry)
414{ 395{
415 pte_t *shadow_pte = get_shadow_pte(pteptr); 396 *ptep = entry;
416 397 if (mm->context.noexec) {
417 *pteptr = pteval; 398 if (!(pte_val(entry) & _PAGE_INVALID) &&
418 if (shadow_pte) { 399 (pte_val(entry) & _PAGE_SWX))
419 if (!(pte_val(pteval) & _PAGE_INVALID) && 400 pte_val(entry) |= _PAGE_RO;
420 (pte_val(pteval) & _PAGE_SWX))
421 pte_val(*shadow_pte) = pte_val(pteval) | _PAGE_RO;
422 else 401 else
423 pte_val(*shadow_pte) = _PAGE_TYPE_EMPTY; 402 pte_val(entry) = _PAGE_TYPE_EMPTY;
403 ptep[PTRS_PER_PTE] = entry;
424 } 404 }
425} 405}
426 406
@@ -439,24 +419,58 @@ static inline int pud_bad(pud_t pud) { return 0; }
439 419
440#else /* __s390x__ */ 420#else /* __s390x__ */
441 421
442static inline int pgd_present(pgd_t pgd) { return 1; } 422static inline int pgd_present(pgd_t pgd)
443static inline int pgd_none(pgd_t pgd) { return 0; } 423{
444static inline int pgd_bad(pgd_t pgd) { return 0; } 424 if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R2)
425 return 1;
426 return (pgd_val(pgd) & _REGION_ENTRY_ORIGIN) != 0UL;
427}
428
429static inline int pgd_none(pgd_t pgd)
430{
431 if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R2)
432 return 0;
433 return (pgd_val(pgd) & _REGION_ENTRY_INV) != 0UL;
434}
435
436static inline int pgd_bad(pgd_t pgd)
437{
438 /*
439 * With dynamic page table levels the pgd can be a region table
440 * entry or a segment table entry. Check for the bit that are
441 * invalid for either table entry.
442 */
443 unsigned long mask =
444 ~_SEGMENT_ENTRY_ORIGIN & ~_REGION_ENTRY_INV &
445 ~_REGION_ENTRY_TYPE_MASK & ~_REGION_ENTRY_LENGTH;
446 return (pgd_val(pgd) & mask) != 0;
447}
445 448
446static inline int pud_present(pud_t pud) 449static inline int pud_present(pud_t pud)
447{ 450{
451 if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R3)
452 return 1;
448 return (pud_val(pud) & _REGION_ENTRY_ORIGIN) != 0UL; 453 return (pud_val(pud) & _REGION_ENTRY_ORIGIN) != 0UL;
449} 454}
450 455
451static inline int pud_none(pud_t pud) 456static inline int pud_none(pud_t pud)
452{ 457{
458 if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R3)
459 return 0;
453 return (pud_val(pud) & _REGION_ENTRY_INV) != 0UL; 460 return (pud_val(pud) & _REGION_ENTRY_INV) != 0UL;
454} 461}
455 462
456static inline int pud_bad(pud_t pud) 463static inline int pud_bad(pud_t pud)
457{ 464{
458 unsigned long mask = ~_REGION_ENTRY_ORIGIN & ~_REGION_ENTRY_INV; 465 /*
459 return (pud_val(pud) & mask) != _REGION3_ENTRY; 466 * With dynamic page table levels the pud can be a region table
467 * entry or a segment table entry. Check for the bit that are
468 * invalid for either table entry.
469 */
470 unsigned long mask =
471 ~_SEGMENT_ENTRY_ORIGIN & ~_REGION_ENTRY_INV &
472 ~_REGION_ENTRY_TYPE_MASK & ~_REGION_ENTRY_LENGTH;
473 return (pud_val(pud) & mask) != 0;
460} 474}
461 475
462#endif /* __s390x__ */ 476#endif /* __s390x__ */
@@ -535,24 +549,30 @@ static inline int pte_young(pte_t pte)
535#define pgd_clear(pgd) do { } while (0) 549#define pgd_clear(pgd) do { } while (0)
536#define pud_clear(pud) do { } while (0) 550#define pud_clear(pud) do { } while (0)
537 551
538static inline void pmd_clear_kernel(pmd_t * pmdp) 552#else /* __s390x__ */
553
554static inline void pgd_clear_kernel(pgd_t * pgd)
539{ 555{
540 pmd_val(pmdp[0]) = _SEGMENT_ENTRY_EMPTY; 556 if ((pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R2)
541 pmd_val(pmdp[1]) = _SEGMENT_ENTRY_EMPTY; 557 pgd_val(*pgd) = _REGION2_ENTRY_EMPTY;
542 pmd_val(pmdp[2]) = _SEGMENT_ENTRY_EMPTY;
543 pmd_val(pmdp[3]) = _SEGMENT_ENTRY_EMPTY;
544} 558}
545 559
546#else /* __s390x__ */ 560static inline void pgd_clear(pgd_t * pgd)
561{
562 pgd_t *shadow = get_shadow_table(pgd);
547 563
548#define pgd_clear(pgd) do { } while (0) 564 pgd_clear_kernel(pgd);
565 if (shadow)
566 pgd_clear_kernel(shadow);
567}
549 568
550static inline void pud_clear_kernel(pud_t *pud) 569static inline void pud_clear_kernel(pud_t *pud)
551{ 570{
552 pud_val(*pud) = _REGION3_ENTRY_EMPTY; 571 if ((pud_val(*pud) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3)
572 pud_val(*pud) = _REGION3_ENTRY_EMPTY;
553} 573}
554 574
555static inline void pud_clear(pud_t * pud) 575static inline void pud_clear(pud_t *pud)
556{ 576{
557 pud_t *shadow = get_shadow_table(pud); 577 pud_t *shadow = get_shadow_table(pud);
558 578
@@ -561,30 +581,27 @@ static inline void pud_clear(pud_t * pud)
561 pud_clear_kernel(shadow); 581 pud_clear_kernel(shadow);
562} 582}
563 583
584#endif /* __s390x__ */
585
564static inline void pmd_clear_kernel(pmd_t * pmdp) 586static inline void pmd_clear_kernel(pmd_t * pmdp)
565{ 587{
566 pmd_val(*pmdp) = _SEGMENT_ENTRY_EMPTY; 588 pmd_val(*pmdp) = _SEGMENT_ENTRY_EMPTY;
567 pmd_val1(*pmdp) = _SEGMENT_ENTRY_EMPTY;
568} 589}
569 590
570#endif /* __s390x__ */ 591static inline void pmd_clear(pmd_t *pmd)
571
572static inline void pmd_clear(pmd_t * pmdp)
573{ 592{
574 pmd_t *shadow_pmd = get_shadow_table(pmdp); 593 pmd_t *shadow = get_shadow_table(pmd);
575 594
576 pmd_clear_kernel(pmdp); 595 pmd_clear_kernel(pmd);
577 if (shadow_pmd) 596 if (shadow)
578 pmd_clear_kernel(shadow_pmd); 597 pmd_clear_kernel(shadow);
579} 598}
580 599
581static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) 600static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
582{ 601{
583 pte_t *shadow_pte = get_shadow_pte(ptep);
584
585 pte_val(*ptep) = _PAGE_TYPE_EMPTY; 602 pte_val(*ptep) = _PAGE_TYPE_EMPTY;
586 if (shadow_pte) 603 if (mm->context.noexec)
587 pte_val(*shadow_pte) = _PAGE_TYPE_EMPTY; 604 pte_val(ptep[PTRS_PER_PTE]) = _PAGE_TYPE_EMPTY;
588} 605}
589 606
590/* 607/*
@@ -665,7 +682,7 @@ static inline void __ptep_ipte(unsigned long address, pte_t *ptep)
665{ 682{
666 if (!(pte_val(*ptep) & _PAGE_INVALID)) { 683 if (!(pte_val(*ptep) & _PAGE_INVALID)) {
667#ifndef __s390x__ 684#ifndef __s390x__
668 /* S390 has 1mb segments, we are emulating 4MB segments */ 685 /* pto must point to the start of the segment table */
669 pte_t *pto = (pte_t *) (((unsigned long) ptep) & 0x7ffffc00); 686 pte_t *pto = (pte_t *) (((unsigned long) ptep) & 0x7ffffc00);
670#else 687#else
671 /* ipte in zarch mode can do the math */ 688 /* ipte in zarch mode can do the math */
@@ -679,12 +696,12 @@ static inline void __ptep_ipte(unsigned long address, pte_t *ptep)
679 pte_val(*ptep) = _PAGE_TYPE_EMPTY; 696 pte_val(*ptep) = _PAGE_TYPE_EMPTY;
680} 697}
681 698
682static inline void ptep_invalidate(unsigned long address, pte_t *ptep) 699static inline void ptep_invalidate(struct mm_struct *mm,
700 unsigned long address, pte_t *ptep)
683{ 701{
684 __ptep_ipte(address, ptep); 702 __ptep_ipte(address, ptep);
685 ptep = get_shadow_pte(ptep); 703 if (mm->context.noexec)
686 if (ptep) 704 __ptep_ipte(address, ptep + PTRS_PER_PTE);
687 __ptep_ipte(address, ptep);
688} 705}
689 706
690/* 707/*
@@ -706,7 +723,7 @@ static inline void ptep_invalidate(unsigned long address, pte_t *ptep)
706 pte_t __pte = *(__ptep); \ 723 pte_t __pte = *(__ptep); \
707 if (atomic_read(&(__mm)->mm_users) > 1 || \ 724 if (atomic_read(&(__mm)->mm_users) > 1 || \
708 (__mm) != current->active_mm) \ 725 (__mm) != current->active_mm) \
709 ptep_invalidate(__address, __ptep); \ 726 ptep_invalidate(__mm, __address, __ptep); \
710 else \ 727 else \
711 pte_clear((__mm), (__address), (__ptep)); \ 728 pte_clear((__mm), (__address), (__ptep)); \
712 __pte; \ 729 __pte; \
@@ -717,7 +734,7 @@ static inline pte_t ptep_clear_flush(struct vm_area_struct *vma,
717 unsigned long address, pte_t *ptep) 734 unsigned long address, pte_t *ptep)
718{ 735{
719 pte_t pte = *ptep; 736 pte_t pte = *ptep;
720 ptep_invalidate(address, ptep); 737 ptep_invalidate(vma->vm_mm, address, ptep);
721 return pte; 738 return pte;
722} 739}
723 740
@@ -738,7 +755,7 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm,
738 if (full) 755 if (full)
739 pte_clear(mm, addr, ptep); 756 pte_clear(mm, addr, ptep);
740 else 757 else
741 ptep_invalidate(addr, ptep); 758 ptep_invalidate(mm, addr, ptep);
742 return pte; 759 return pte;
743} 760}
744 761
@@ -749,7 +766,7 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm,
749 if (pte_write(__pte)) { \ 766 if (pte_write(__pte)) { \
750 if (atomic_read(&(__mm)->mm_users) > 1 || \ 767 if (atomic_read(&(__mm)->mm_users) > 1 || \
751 (__mm) != current->active_mm) \ 768 (__mm) != current->active_mm) \
752 ptep_invalidate(__addr, __ptep); \ 769 ptep_invalidate(__mm, __addr, __ptep); \
753 set_pte_at(__mm, __addr, __ptep, pte_wrprotect(__pte)); \ 770 set_pte_at(__mm, __addr, __ptep, pte_wrprotect(__pte)); \
754 } \ 771 } \
755}) 772})
@@ -759,7 +776,7 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm,
759({ \ 776({ \
760 int __changed = !pte_same(*(__ptep), __entry); \ 777 int __changed = !pte_same(*(__ptep), __entry); \
761 if (__changed) { \ 778 if (__changed) { \
762 ptep_invalidate(__addr, __ptep); \ 779 ptep_invalidate((__vma)->vm_mm, __addr, __ptep); \
763 set_pte_at((__vma)->vm_mm, __addr, __ptep, __entry); \ 780 set_pte_at((__vma)->vm_mm, __addr, __ptep, __entry); \
764 } \ 781 } \
765 __changed; \ 782 __changed; \
@@ -840,13 +857,21 @@ static inline pte_t mk_pte(struct page *page, pgprot_t pgprot)
840 857
841#define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) 858#define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN)
842#define pud_deref(pud) (pud_val(pud) & _REGION_ENTRY_ORIGIN) 859#define pud_deref(pud) (pud_val(pud) & _REGION_ENTRY_ORIGIN)
843#define pgd_deref(pgd) ({ BUG(); 0UL; }) 860#define pgd_deref(pgd) (pgd_val(pgd) & _REGION_ENTRY_ORIGIN)
844 861
845#define pud_offset(pgd, address) ((pud_t *) pgd) 862static inline pud_t *pud_offset(pgd_t *pgd, unsigned long address)
863{
864 pud_t *pud = (pud_t *) pgd;
865 if ((pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R2)
866 pud = (pud_t *) pgd_deref(*pgd);
867 return pud + pud_index(address);
868}
846 869
847static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address) 870static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
848{ 871{
849 pmd_t *pmd = (pmd_t *) pud_deref(*pud); 872 pmd_t *pmd = (pmd_t *) pud;
873 if ((pud_val(*pud) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3)
874 pmd = (pmd_t *) pud_deref(*pud);
850 return pmd + pmd_index(address); 875 return pmd + pmd_index(address);
851} 876}
852 877
diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h
index e8785634cbdb..51d88912aa20 100644
--- a/include/asm-s390/processor.h
+++ b/include/asm-s390/processor.h
@@ -64,24 +64,29 @@ extern int get_cpu_capability(unsigned int *);
64 */ 64 */
65#ifndef __s390x__ 65#ifndef __s390x__
66 66
67# define TASK_SIZE (0x80000000UL) 67#define TASK_SIZE (1UL << 31)
68# define TASK_UNMAPPED_BASE (TASK_SIZE / 2) 68#define TASK_UNMAPPED_BASE (1UL << 30)
69# define DEFAULT_TASK_SIZE (0x80000000UL)
70 69
71#else /* __s390x__ */ 70#else /* __s390x__ */
72 71
73# define TASK_SIZE_OF(tsk) (test_tsk_thread_flag(tsk, TIF_31BIT) ? \ 72#define TASK_SIZE_OF(tsk) (test_tsk_thread_flag(tsk,TIF_31BIT) ? \
74 (0x80000000UL) : (0x40000000000UL)) 73 (1UL << 31) : (1UL << 53))
75# define TASK_SIZE TASK_SIZE_OF(current) 74#define TASK_UNMAPPED_BASE (test_thread_flag(TIF_31BIT) ? \
76# define TASK_UNMAPPED_BASE (TASK_SIZE / 2) 75 (1UL << 30) : (1UL << 41))
77# define DEFAULT_TASK_SIZE (0x40000000000UL) 76#define TASK_SIZE TASK_SIZE_OF(current)
78 77
79#endif /* __s390x__ */ 78#endif /* __s390x__ */
80 79
81#ifdef __KERNEL__ 80#ifdef __KERNEL__
82 81
83#define STACK_TOP TASK_SIZE 82#ifndef __s390x__
84#define STACK_TOP_MAX DEFAULT_TASK_SIZE 83#define STACK_TOP (1UL << 31)
84#define STACK_TOP_MAX (1UL << 31)
85#else /* __s390x__ */
86#define STACK_TOP (1UL << (test_thread_flag(TIF_31BIT) ? 31:42))
87#define STACK_TOP_MAX (1UL << 42)
88#endif /* __s390x__ */
89
85 90
86#endif 91#endif
87 92
@@ -138,8 +143,6 @@ struct stack_frame {
138/* 143/*
139 * Do necessary setup to start up a new thread. 144 * Do necessary setup to start up a new thread.
140 */ 145 */
141#ifndef __s390x__
142
143#define start_thread(regs, new_psw, new_stackp) do { \ 146#define start_thread(regs, new_psw, new_stackp) do { \
144 set_fs(USER_DS); \ 147 set_fs(USER_DS); \
145 regs->psw.mask = psw_user_bits; \ 148 regs->psw.mask = psw_user_bits; \
@@ -147,24 +150,6 @@ struct stack_frame {
147 regs->gprs[15] = new_stackp ; \ 150 regs->gprs[15] = new_stackp ; \
148} while (0) 151} while (0)
149 152
150#else /* __s390x__ */
151
152#define start_thread(regs, new_psw, new_stackp) do { \
153 set_fs(USER_DS); \
154 regs->psw.mask = psw_user_bits; \
155 regs->psw.addr = new_psw; \
156 regs->gprs[15] = new_stackp; \
157} while (0)
158
159#define start_thread31(regs, new_psw, new_stackp) do { \
160 set_fs(USER_DS); \
161 regs->psw.mask = psw_user32_bits; \
162 regs->psw.addr = new_psw; \
163 regs->gprs[15] = new_stackp; \
164} while (0)
165
166#endif /* __s390x__ */
167
168/* Forward declaration, a strange C thing */ 153/* Forward declaration, a strange C thing */
169struct task_struct; 154struct task_struct;
170struct mm_struct; 155struct mm_struct;
diff --git a/include/asm-s390/tlb.h b/include/asm-s390/tlb.h
index 3c8177fa9e06..3d8a96d39d9d 100644
--- a/include/asm-s390/tlb.h
+++ b/include/asm-s390/tlb.h
@@ -38,7 +38,7 @@ struct mmu_gather {
38 struct mm_struct *mm; 38 struct mm_struct *mm;
39 unsigned int fullmm; 39 unsigned int fullmm;
40 unsigned int nr_ptes; 40 unsigned int nr_ptes;
41 unsigned int nr_pmds; 41 unsigned int nr_pxds;
42 void *array[TLB_NR_PTRS]; 42 void *array[TLB_NR_PTRS];
43}; 43};
44 44
@@ -53,7 +53,7 @@ static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm,
53 tlb->fullmm = full_mm_flush || (num_online_cpus() == 1) || 53 tlb->fullmm = full_mm_flush || (num_online_cpus() == 1) ||
54 (atomic_read(&mm->mm_users) <= 1 && mm == current->active_mm); 54 (atomic_read(&mm->mm_users) <= 1 && mm == current->active_mm);
55 tlb->nr_ptes = 0; 55 tlb->nr_ptes = 0;
56 tlb->nr_pmds = TLB_NR_PTRS; 56 tlb->nr_pxds = TLB_NR_PTRS;
57 if (tlb->fullmm) 57 if (tlb->fullmm)
58 __tlb_flush_mm(mm); 58 __tlb_flush_mm(mm);
59 return tlb; 59 return tlb;
@@ -62,12 +62,13 @@ static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm,
62static inline void tlb_flush_mmu(struct mmu_gather *tlb, 62static inline void tlb_flush_mmu(struct mmu_gather *tlb,
63 unsigned long start, unsigned long end) 63 unsigned long start, unsigned long end)
64{ 64{
65 if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pmds < TLB_NR_PTRS)) 65 if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pxds < TLB_NR_PTRS))
66 __tlb_flush_mm(tlb->mm); 66 __tlb_flush_mm(tlb->mm);
67 while (tlb->nr_ptes > 0) 67 while (tlb->nr_ptes > 0)
68 pte_free(tlb->mm, tlb->array[--tlb->nr_ptes]); 68 pte_free(tlb->mm, tlb->array[--tlb->nr_ptes]);
69 while (tlb->nr_pmds < TLB_NR_PTRS) 69 while (tlb->nr_pxds < TLB_NR_PTRS)
70 pmd_free(tlb->mm, (pmd_t *) tlb->array[tlb->nr_pmds++]); 70 /* pgd_free frees the pointer as region or segment table */
71 pgd_free(tlb->mm, tlb->array[tlb->nr_pxds++]);
71} 72}
72 73
73static inline void tlb_finish_mmu(struct mmu_gather *tlb, 74static inline void tlb_finish_mmu(struct mmu_gather *tlb,
@@ -95,33 +96,57 @@ static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
95 * pte_free_tlb frees a pte table and clears the CRSTE for the 96 * pte_free_tlb frees a pte table and clears the CRSTE for the
96 * page table from the tlb. 97 * page table from the tlb.
97 */ 98 */
98static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t page) 99static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte)
99{ 100{
100 if (!tlb->fullmm) { 101 if (!tlb->fullmm) {
101 tlb->array[tlb->nr_ptes++] = page; 102 tlb->array[tlb->nr_ptes++] = pte;
102 if (tlb->nr_ptes >= tlb->nr_pmds) 103 if (tlb->nr_ptes >= tlb->nr_pxds)
103 tlb_flush_mmu(tlb, 0, 0); 104 tlb_flush_mmu(tlb, 0, 0);
104 } else 105 } else
105 pte_free(tlb->mm, page); 106 pte_free(tlb->mm, pte);
106} 107}
107 108
108/* 109/*
109 * pmd_free_tlb frees a pmd table and clears the CRSTE for the 110 * pmd_free_tlb frees a pmd table and clears the CRSTE for the
110 * segment table entry from the tlb. 111 * segment table entry from the tlb.
112 * If the mm uses a two level page table the single pmd is freed
113 * as the pgd. pmd_free_tlb checks the asce_limit against 2GB
114 * to avoid the double free of the pmd in this case.
111 */ 115 */
112static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) 116static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
113{ 117{
114#ifdef __s390x__ 118#ifdef __s390x__
119 if (tlb->mm->context.asce_limit <= (1UL << 31))
120 return;
115 if (!tlb->fullmm) { 121 if (!tlb->fullmm) {
116 tlb->array[--tlb->nr_pmds] = (struct page *) pmd; 122 tlb->array[--tlb->nr_pxds] = pmd;
117 if (tlb->nr_ptes >= tlb->nr_pmds) 123 if (tlb->nr_ptes >= tlb->nr_pxds)
118 tlb_flush_mmu(tlb, 0, 0); 124 tlb_flush_mmu(tlb, 0, 0);
119 } else 125 } else
120 pmd_free(tlb->mm, pmd); 126 pmd_free(tlb->mm, pmd);
121#endif 127#endif
122} 128}
123 129
124#define pud_free_tlb(tlb, pud) do { } while (0) 130/*
131 * pud_free_tlb frees a pud table and clears the CRSTE for the
132 * region third table entry from the tlb.
133 * If the mm uses a three level page table the single pud is freed
134 * as the pgd. pud_free_tlb checks the asce_limit against 4TB
135 * to avoid the double free of the pud in this case.
136 */
137static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud)
138{
139#ifdef __s390x__
140 if (tlb->mm->context.asce_limit <= (1UL << 42))
141 return;
142 if (!tlb->fullmm) {
143 tlb->array[--tlb->nr_pxds] = pud;
144 if (tlb->nr_ptes >= tlb->nr_pxds)
145 tlb_flush_mmu(tlb, 0, 0);
146 } else
147 pud_free(tlb->mm, pud);
148#endif
149}
125 150
126#define tlb_start_vma(tlb, vma) do { } while (0) 151#define tlb_start_vma(tlb, vma) do { } while (0)
127#define tlb_end_vma(tlb, vma) do { } while (0) 152#define tlb_end_vma(tlb, vma) do { } while (0)
diff --git a/include/asm-s390/tlbflush.h b/include/asm-s390/tlbflush.h
index 70fa5ae58180..35fb4f9127b2 100644
--- a/include/asm-s390/tlbflush.h
+++ b/include/asm-s390/tlbflush.h
@@ -61,11 +61,12 @@ static inline void __tlb_flush_mm(struct mm_struct * mm)
61 * only ran on the local cpu. 61 * only ran on the local cpu.
62 */ 62 */
63 if (MACHINE_HAS_IDTE) { 63 if (MACHINE_HAS_IDTE) {
64 pgd_t *shadow = get_shadow_table(mm->pgd); 64 if (mm->context.noexec)
65 65 __tlb_flush_idte((unsigned long)
66 if (shadow) 66 get_shadow_table(mm->pgd) |
67 __tlb_flush_idte((unsigned long) shadow | mm->context); 67 mm->context.asce_bits);
68 __tlb_flush_idte((unsigned long) mm->pgd | mm->context); 68 __tlb_flush_idte((unsigned long) mm->pgd |
69 mm->context.asce_bits);
69 return; 70 return;
70 } 71 }
71 preempt_disable(); 72 preempt_disable();
diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h
index f04acb2670a8..583da807ea97 100644
--- a/include/asm-s390/unistd.h
+++ b/include/asm-s390/unistd.h
@@ -256,7 +256,10 @@
256#define __NR_signalfd 316 256#define __NR_signalfd 316
257#define __NR_timerfd 317 257#define __NR_timerfd 317
258#define __NR_eventfd 318 258#define __NR_eventfd 318
259#define NR_syscalls 319 259#define __NR_timerfd_create 319
260#define __NR_timerfd_settime 320
261#define __NR_timerfd_gettime 321
262#define NR_syscalls 322
260 263
261/* 264/*
262 * There are some system calls that are not present on 64 bit, some 265 * There are some system calls that are not present on 64 bit, some