Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux

Pull s390 updates from Martin Schwidefsky:
 "There are two memory management related changes, the CMMA support for
  KVM to avoid swap-in of freed pages and the split page table lock for
  the PMD level.  These two come with common code changes in mm/.

  A fix for the long standing theoretical TLB flush problem, this one
  comes with a common code change in kernel/sched/.

  Another set of changes is Heikos uaccess work, included is the initial
  set of patches with more to come.

  And fixes and cleanups as usual"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (36 commits)
  s390/con3270: optionally disable auto update
  s390/mm: remove unecessary parameter from pgste_ipte_notify
  s390/mm: remove unnecessary parameter from gmap_do_ipte_notify
  s390/mm: fixing comment so that parameter name match
  s390/smp: limit number of cpus in possible cpu mask
  hypfs: Add clarification for "weight_min" attribute
  s390: update defconfigs
  s390/ptrace: add support for PTRACE_SINGLEBLOCK
  s390/perf: make print_debug_cf() static
  s390/topology: Remove call to update_cpu_masks()
  s390/compat: remove compat exec domain
  s390: select CONFIG_TTY for use of tty in unconditional keyboard driver
  s390/appldata_os: fix cpu array size calculation
  s390/checksum: remove memset() within csum_partial_copy_from_user()
  s390/uaccess: remove copy_from_user_real()
  s390/sclp_early: Return correct HSA block count also for zero
  s390: add some drivers/subsystems to the MAINTAINERS file
  s390: improve debug feature usage
  s390/airq: add support for irq ranges
  s390/mm: enable split page table lock for PMD level
  ...
This commit is contained in:
Linus Torvalds 2014-03-31 14:35:30 -07:00
commit 1f8c538ed6
61 changed files with 944 additions and 428 deletions

View file

@ -7405,10 +7405,26 @@ W: http://www.ibm.com/developerworks/linux/linux390/
S: Supported S: Supported
F: arch/s390/ F: arch/s390/
F: drivers/s390/ F: drivers/s390/
F: block/partitions/ibm.c
F: Documentation/s390/ F: Documentation/s390/
F: Documentation/DocBook/s390* F: Documentation/DocBook/s390*
S390 COMMON I/O LAYER
M: Sebastian Ott <sebott@linux.vnet.ibm.com>
M: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
L: linux-s390@vger.kernel.org
W: http://www.ibm.com/developerworks/linux/linux390/
S: Supported
F: drivers/s390/cio/
S390 DASD DRIVER
M: Stefan Weinhuber <wein@de.ibm.com>
M: Stefan Haberland <stefan.haberland@de.ibm.com>
L: linux-s390@vger.kernel.org
W: http://www.ibm.com/developerworks/linux/linux390/
S: Supported
F: drivers/s390/block/dasd*
F: block/partitions/ibm.c
S390 NETWORK DRIVERS S390 NETWORK DRIVERS
M: Ursula Braun <ursula.braun@de.ibm.com> M: Ursula Braun <ursula.braun@de.ibm.com>
M: Frank Blaschka <blaschka@linux.vnet.ibm.com> M: Frank Blaschka <blaschka@linux.vnet.ibm.com>
@ -7418,6 +7434,15 @@ W: http://www.ibm.com/developerworks/linux/linux390/
S: Supported S: Supported
F: drivers/s390/net/ F: drivers/s390/net/
S390 PCI SUBSYSTEM
M: Sebastian Ott <sebott@linux.vnet.ibm.com>
M: Gerald Schaefer <gerald.schaefer@de.ibm.com>
L: linux-s390@vger.kernel.org
W: http://www.ibm.com/developerworks/linux/linux390/
S: Supported
F: arch/s390/pci/
F: drivers/pci/hotplug/s390_pci_hpc.c
S390 ZCRYPT DRIVER S390 ZCRYPT DRIVER
M: Ingo Tuchscherer <ingo.tuchscherer@de.ibm.com> M: Ingo Tuchscherer <ingo.tuchscherer@de.ibm.com>
M: linux390@de.ibm.com M: linux390@de.ibm.com

View file

@ -141,6 +141,7 @@ config S390
select OLD_SIGACTION select OLD_SIGACTION
select OLD_SIGSUSPEND3 select OLD_SIGSUSPEND3
select SYSCTL_EXCEPTION_TRACE select SYSCTL_EXCEPTION_TRACE
select TTY
select VIRT_CPU_ACCOUNTING select VIRT_CPU_ACCOUNTING
select VIRT_TO_BUS select VIRT_TO_BUS
@ -416,6 +417,10 @@ config ARCH_ENABLE_MEMORY_HOTPLUG
config ARCH_ENABLE_MEMORY_HOTREMOVE config ARCH_ENABLE_MEMORY_HOTREMOVE
def_bool y def_bool y
config ARCH_ENABLE_SPLIT_PMD_PTLOCK
def_bool y
depends on 64BIT
config FORCE_MAX_ZONEORDER config FORCE_MAX_ZONEORDER
int int
default "9" default "9"

View file

@ -171,7 +171,7 @@ static int __init appldata_os_init(void)
int rc, max_size; int rc, max_size;
max_size = sizeof(struct appldata_os_data) + max_size = sizeof(struct appldata_os_data) +
(NR_CPUS * sizeof(struct appldata_os_per_cpu)); (num_possible_cpus() * sizeof(struct appldata_os_per_cpu));
if (max_size > APPLDATA_MAX_REC_SIZE) { if (max_size > APPLDATA_MAX_REC_SIZE) {
pr_err("Maximum OS record size %i exceeds the maximum " pr_err("Maximum OS record size %i exceeds the maximum "
"record size %i\n", max_size, APPLDATA_MAX_REC_SIZE); "record size %i\n", max_size, APPLDATA_MAX_REC_SIZE);

View file

@ -46,6 +46,7 @@ CONFIG_UNIXWARE_DISKLABEL=y
CONFIG_CFQ_GROUP_IOSCHED=y CONFIG_CFQ_GROUP_IOSCHED=y
CONFIG_DEFAULT_DEADLINE=y CONFIG_DEFAULT_DEADLINE=y
CONFIG_MARCH_Z9_109=y CONFIG_MARCH_Z9_109=y
CONFIG_NR_CPUS=256
CONFIG_PREEMPT=y CONFIG_PREEMPT=y
CONFIG_HZ_100=y CONFIG_HZ_100=y
CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTPLUG=y
@ -58,7 +59,6 @@ CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_S390=y CONFIG_HOTPLUG_PCI_S390=y
CONFIG_CHSC_SCH=y CONFIG_CHSC_SCH=y
CONFIG_CRASH_DUMP=y CONFIG_CRASH_DUMP=y
CONFIG_ZFCPDUMP=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_BINFMT_MISC=m CONFIG_BINFMT_MISC=m
CONFIG_HIBERNATION=y CONFIG_HIBERNATION=y
@ -101,7 +101,6 @@ CONFIG_TCP_CONG_VENO=m
CONFIG_TCP_CONG_YEAH=m CONFIG_TCP_CONG_YEAH=m
CONFIG_TCP_CONG_ILLINOIS=m CONFIG_TCP_CONG_ILLINOIS=m
CONFIG_IPV6=y CONFIG_IPV6=y
CONFIG_IPV6_PRIVACY=y
CONFIG_IPV6_ROUTER_PREF=y CONFIG_IPV6_ROUTER_PREF=y
CONFIG_INET6_AH=m CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m CONFIG_INET6_ESP=m
@ -111,6 +110,7 @@ CONFIG_INET6_XFRM_MODE_TRANSPORT=m
CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_TUNNEL=m
CONFIG_INET6_XFRM_MODE_BEET=m CONFIG_INET6_XFRM_MODE_BEET=m
CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
CONFIG_IPV6_VTI=m
CONFIG_IPV6_SIT=m CONFIG_IPV6_SIT=m
CONFIG_IPV6_GRE=m CONFIG_IPV6_GRE=m
CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_MULTIPLE_TABLES=y
@ -135,7 +135,17 @@ CONFIG_NF_CONNTRACK_SIP=m
CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_CONNTRACK_TFTP=m
CONFIG_NF_CT_NETLINK=m CONFIG_NF_CT_NETLINK=m
CONFIG_NF_CT_NETLINK_TIMEOUT=m CONFIG_NF_CT_NETLINK_TIMEOUT=m
CONFIG_NETFILTER_TPROXY=m CONFIG_NF_TABLES=m
CONFIG_NFT_EXTHDR=m
CONFIG_NFT_META=m
CONFIG_NFT_CT=m
CONFIG_NFT_RBTREE=m
CONFIG_NFT_HASH=m
CONFIG_NFT_COUNTER=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
CONFIG_NFT_NAT=m
CONFIG_NFT_COMPAT=m
CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_SET=m
CONFIG_NETFILTER_XT_TARGET_AUDIT=m CONFIG_NETFILTER_XT_TARGET_AUDIT=m
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
@ -204,7 +214,9 @@ CONFIG_IP_SET_HASH_IP=m
CONFIG_IP_SET_HASH_IPPORT=m CONFIG_IP_SET_HASH_IPPORT=m
CONFIG_IP_SET_HASH_IPPORTIP=m CONFIG_IP_SET_HASH_IPPORTIP=m
CONFIG_IP_SET_HASH_IPPORTNET=m CONFIG_IP_SET_HASH_IPPORTNET=m
CONFIG_IP_SET_HASH_NETPORTNET=m
CONFIG_IP_SET_HASH_NET=m CONFIG_IP_SET_HASH_NET=m
CONFIG_IP_SET_HASH_NETNET=m
CONFIG_IP_SET_HASH_NETPORT=m CONFIG_IP_SET_HASH_NETPORT=m
CONFIG_IP_SET_HASH_NETIFACE=m CONFIG_IP_SET_HASH_NETIFACE=m
CONFIG_IP_SET_LIST_SET=m CONFIG_IP_SET_LIST_SET=m
@ -227,6 +239,11 @@ CONFIG_IP_VS_FTP=m
CONFIG_IP_VS_PE_SIP=m CONFIG_IP_VS_PE_SIP=m
CONFIG_NF_CONNTRACK_IPV4=m CONFIG_NF_CONNTRACK_IPV4=m
# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set # CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
CONFIG_NF_TABLES_IPV4=m
CONFIG_NFT_REJECT_IPV4=m
CONFIG_NFT_CHAIN_ROUTE_IPV4=m
CONFIG_NFT_CHAIN_NAT_IPV4=m
CONFIG_NF_TABLES_ARP=m
CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_AH=m
CONFIG_IP_NF_MATCH_ECN=m CONFIG_IP_NF_MATCH_ECN=m
@ -249,6 +266,9 @@ CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NF_CONNTRACK_IPV6=m CONFIG_NF_CONNTRACK_IPV6=m
CONFIG_NF_TABLES_IPV6=m
CONFIG_NFT_CHAIN_ROUTE_IPV6=m
CONFIG_NFT_CHAIN_NAT_IPV6=m
CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m CONFIG_IP6_NF_MATCH_EUI64=m
@ -268,6 +288,7 @@ CONFIG_IP6_NF_SECURITY=m
CONFIG_NF_NAT_IPV6=m CONFIG_NF_NAT_IPV6=m
CONFIG_IP6_NF_TARGET_MASQUERADE=m CONFIG_IP6_NF_TARGET_MASQUERADE=m
CONFIG_IP6_NF_TARGET_NPT=m CONFIG_IP6_NF_TARGET_NPT=m
CONFIG_NF_TABLES_BRIDGE=m
CONFIG_NET_SCTPPROBE=m CONFIG_NET_SCTPPROBE=m
CONFIG_RDS=m CONFIG_RDS=m
CONFIG_RDS_RDMA=m CONFIG_RDS_RDMA=m
@ -314,6 +335,7 @@ CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m CONFIG_NET_CLS_RSVP6=m
CONFIG_NET_CLS_FLOW=m CONFIG_NET_CLS_FLOW=m
CONFIG_NET_CLS_CGROUP=y CONFIG_NET_CLS_CGROUP=y
CONFIG_NET_CLS_BPF=m
CONFIG_NET_CLS_ACT=y CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_POLICE=m CONFIG_NET_ACT_POLICE=m
CONFIG_NET_ACT_GACT=m CONFIG_NET_ACT_GACT=m
@ -381,8 +403,8 @@ CONFIG_BLK_DEV_DM=m
CONFIG_DM_CRYPT=m CONFIG_DM_CRYPT=m
CONFIG_DM_SNAPSHOT=m CONFIG_DM_SNAPSHOT=m
CONFIG_DM_MIRROR=m CONFIG_DM_MIRROR=m
CONFIG_DM_RAID=m
CONFIG_DM_LOG_USERSPACE=m CONFIG_DM_LOG_USERSPACE=m
CONFIG_DM_RAID=m
CONFIG_DM_ZERO=m CONFIG_DM_ZERO=m
CONFIG_DM_MULTIPATH=m CONFIG_DM_MULTIPATH=m
CONFIG_DM_MULTIPATH_QL=m CONFIG_DM_MULTIPATH_QL=m
@ -434,7 +456,6 @@ CONFIG_TN3270_FS=y
CONFIG_WATCHDOG=y CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_NOWAYOUT=y CONFIG_WATCHDOG_NOWAYOUT=y
CONFIG_SOFT_WATCHDOG=m CONFIG_SOFT_WATCHDOG=m
CONFIG_ZVM_WATCHDOG=m
# CONFIG_HID is not set # CONFIG_HID is not set
# CONFIG_USB_SUPPORT is not set # CONFIG_USB_SUPPORT is not set
CONFIG_INFINIBAND=m CONFIG_INFINIBAND=m
@ -534,13 +555,23 @@ CONFIG_UNUSED_SYMBOLS=y
CONFIG_MAGIC_SYSRQ=y CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_PAGEALLOC=y CONFIG_DEBUG_PAGEALLOC=y
CONFIG_DEBUG_OBJECTS=y
CONFIG_DEBUG_OBJECTS_SELFTEST=y
CONFIG_DEBUG_OBJECTS_FREE=y
CONFIG_DEBUG_OBJECTS_TIMERS=y
CONFIG_DEBUG_OBJECTS_WORK=y
CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y
CONFIG_SLUB_DEBUG_ON=y CONFIG_SLUB_DEBUG_ON=y
CONFIG_SLUB_STATS=y CONFIG_SLUB_STATS=y
CONFIG_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_STACK_USAGE=y CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_VM=y CONFIG_DEBUG_VM=y
CONFIG_DEBUG_VM_RB=y CONFIG_DEBUG_VM_RB=y
CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m
CONFIG_DEBUG_PER_CPU_MAPS=y CONFIG_DEBUG_PER_CPU_MAPS=y
CONFIG_DEBUG_SHIRQ=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_TIMER_STATS=y CONFIG_TIMER_STATS=y
CONFIG_DEBUG_RT_MUTEXES=y CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_RT_MUTEX_TESTER=y CONFIG_RT_MUTEX_TESTER=y
@ -573,9 +604,11 @@ CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y
CONFIG_BLK_DEV_IO_TRACE=y CONFIG_BLK_DEV_IO_TRACE=y
# CONFIG_KPROBE_EVENT is not set # CONFIG_KPROBE_EVENT is not set
CONFIG_LKDTM=m CONFIG_LKDTM=m
CONFIG_TEST_LIST_SORT=y
CONFIG_KPROBES_SANITY_TEST=y CONFIG_KPROBES_SANITY_TEST=y
CONFIG_RBTREE_TEST=m CONFIG_RBTREE_TEST=y
CONFIG_INTERVAL_TREE_TEST=m CONFIG_INTERVAL_TREE_TEST=m
CONFIG_PERCPU_TEST=m
CONFIG_ATOMIC64_SELFTEST=y CONFIG_ATOMIC64_SELFTEST=y
CONFIG_DMA_API_DEBUG=y CONFIG_DMA_API_DEBUG=y
# CONFIG_STRICT_DEVMEM is not set # CONFIG_STRICT_DEVMEM is not set
@ -638,7 +671,6 @@ CONFIG_CRYPTO_AES_S390=m
CONFIG_CRYPTO_GHASH_S390=m CONFIG_CRYPTO_GHASH_S390=m
CONFIG_ASYMMETRIC_KEY_TYPE=m CONFIG_ASYMMETRIC_KEY_TYPE=m
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m
CONFIG_PUBLIC_KEY_ALGO_RSA=m
CONFIG_X509_CERTIFICATE_PARSER=m CONFIG_X509_CERTIFICATE_PARSER=m
CONFIG_CRC7=m CONFIG_CRC7=m
CONFIG_CRC8=m CONFIG_CRC8=m

View file

@ -46,6 +46,7 @@ CONFIG_UNIXWARE_DISKLABEL=y
CONFIG_CFQ_GROUP_IOSCHED=y CONFIG_CFQ_GROUP_IOSCHED=y
CONFIG_DEFAULT_DEADLINE=y CONFIG_DEFAULT_DEADLINE=y
CONFIG_MARCH_Z9_109=y CONFIG_MARCH_Z9_109=y
CONFIG_NR_CPUS=256
CONFIG_HZ_100=y CONFIG_HZ_100=y
CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTREMOVE=y CONFIG_MEMORY_HOTREMOVE=y
@ -56,7 +57,6 @@ CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_S390=y CONFIG_HOTPLUG_PCI_S390=y
CONFIG_CHSC_SCH=y CONFIG_CHSC_SCH=y
CONFIG_CRASH_DUMP=y CONFIG_CRASH_DUMP=y
CONFIG_ZFCPDUMP=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_BINFMT_MISC=m CONFIG_BINFMT_MISC=m
CONFIG_HIBERNATION=y CONFIG_HIBERNATION=y
@ -99,7 +99,6 @@ CONFIG_TCP_CONG_VENO=m
CONFIG_TCP_CONG_YEAH=m CONFIG_TCP_CONG_YEAH=m
CONFIG_TCP_CONG_ILLINOIS=m CONFIG_TCP_CONG_ILLINOIS=m
CONFIG_IPV6=y CONFIG_IPV6=y
CONFIG_IPV6_PRIVACY=y
CONFIG_IPV6_ROUTER_PREF=y CONFIG_IPV6_ROUTER_PREF=y
CONFIG_INET6_AH=m CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m CONFIG_INET6_ESP=m
@ -109,6 +108,7 @@ CONFIG_INET6_XFRM_MODE_TRANSPORT=m
CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_TUNNEL=m
CONFIG_INET6_XFRM_MODE_BEET=m CONFIG_INET6_XFRM_MODE_BEET=m
CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
CONFIG_IPV6_VTI=m
CONFIG_IPV6_SIT=m CONFIG_IPV6_SIT=m
CONFIG_IPV6_GRE=m CONFIG_IPV6_GRE=m
CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_MULTIPLE_TABLES=y
@ -133,7 +133,17 @@ CONFIG_NF_CONNTRACK_SIP=m
CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_CONNTRACK_TFTP=m
CONFIG_NF_CT_NETLINK=m CONFIG_NF_CT_NETLINK=m
CONFIG_NF_CT_NETLINK_TIMEOUT=m CONFIG_NF_CT_NETLINK_TIMEOUT=m
CONFIG_NETFILTER_TPROXY=m CONFIG_NF_TABLES=m
CONFIG_NFT_EXTHDR=m
CONFIG_NFT_META=m
CONFIG_NFT_CT=m
CONFIG_NFT_RBTREE=m
CONFIG_NFT_HASH=m
CONFIG_NFT_COUNTER=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
CONFIG_NFT_NAT=m
CONFIG_NFT_COMPAT=m
CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_SET=m
CONFIG_NETFILTER_XT_TARGET_AUDIT=m CONFIG_NETFILTER_XT_TARGET_AUDIT=m
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
@ -202,7 +212,9 @@ CONFIG_IP_SET_HASH_IP=m
CONFIG_IP_SET_HASH_IPPORT=m CONFIG_IP_SET_HASH_IPPORT=m
CONFIG_IP_SET_HASH_IPPORTIP=m CONFIG_IP_SET_HASH_IPPORTIP=m
CONFIG_IP_SET_HASH_IPPORTNET=m CONFIG_IP_SET_HASH_IPPORTNET=m
CONFIG_IP_SET_HASH_NETPORTNET=m
CONFIG_IP_SET_HASH_NET=m CONFIG_IP_SET_HASH_NET=m
CONFIG_IP_SET_HASH_NETNET=m
CONFIG_IP_SET_HASH_NETPORT=m CONFIG_IP_SET_HASH_NETPORT=m
CONFIG_IP_SET_HASH_NETIFACE=m CONFIG_IP_SET_HASH_NETIFACE=m
CONFIG_IP_SET_LIST_SET=m CONFIG_IP_SET_LIST_SET=m
@ -225,6 +237,11 @@ CONFIG_IP_VS_FTP=m
CONFIG_IP_VS_PE_SIP=m CONFIG_IP_VS_PE_SIP=m
CONFIG_NF_CONNTRACK_IPV4=m CONFIG_NF_CONNTRACK_IPV4=m
# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set # CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
CONFIG_NF_TABLES_IPV4=m
CONFIG_NFT_REJECT_IPV4=m
CONFIG_NFT_CHAIN_ROUTE_IPV4=m
CONFIG_NFT_CHAIN_NAT_IPV4=m
CONFIG_NF_TABLES_ARP=m
CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_AH=m
CONFIG_IP_NF_MATCH_ECN=m CONFIG_IP_NF_MATCH_ECN=m
@ -247,6 +264,9 @@ CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NF_CONNTRACK_IPV6=m CONFIG_NF_CONNTRACK_IPV6=m
CONFIG_NF_TABLES_IPV6=m
CONFIG_NFT_CHAIN_ROUTE_IPV6=m
CONFIG_NFT_CHAIN_NAT_IPV6=m
CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m CONFIG_IP6_NF_MATCH_EUI64=m
@ -266,6 +286,7 @@ CONFIG_IP6_NF_SECURITY=m
CONFIG_NF_NAT_IPV6=m CONFIG_NF_NAT_IPV6=m
CONFIG_IP6_NF_TARGET_MASQUERADE=m CONFIG_IP6_NF_TARGET_MASQUERADE=m
CONFIG_IP6_NF_TARGET_NPT=m CONFIG_IP6_NF_TARGET_NPT=m
CONFIG_NF_TABLES_BRIDGE=m
CONFIG_NET_SCTPPROBE=m CONFIG_NET_SCTPPROBE=m
CONFIG_RDS=m CONFIG_RDS=m
CONFIG_RDS_RDMA=m CONFIG_RDS_RDMA=m
@ -311,6 +332,7 @@ CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m CONFIG_NET_CLS_RSVP6=m
CONFIG_NET_CLS_FLOW=m CONFIG_NET_CLS_FLOW=m
CONFIG_NET_CLS_CGROUP=y CONFIG_NET_CLS_CGROUP=y
CONFIG_NET_CLS_BPF=m
CONFIG_NET_CLS_ACT=y CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_POLICE=m CONFIG_NET_ACT_POLICE=m
CONFIG_NET_ACT_GACT=m CONFIG_NET_ACT_GACT=m
@ -378,8 +400,8 @@ CONFIG_BLK_DEV_DM=m
CONFIG_DM_CRYPT=m CONFIG_DM_CRYPT=m
CONFIG_DM_SNAPSHOT=m CONFIG_DM_SNAPSHOT=m
CONFIG_DM_MIRROR=m CONFIG_DM_MIRROR=m
CONFIG_DM_RAID=m
CONFIG_DM_LOG_USERSPACE=m CONFIG_DM_LOG_USERSPACE=m
CONFIG_DM_RAID=m
CONFIG_DM_ZERO=m CONFIG_DM_ZERO=m
CONFIG_DM_MULTIPATH=m CONFIG_DM_MULTIPATH=m
CONFIG_DM_MULTIPATH_QL=m CONFIG_DM_MULTIPATH_QL=m
@ -431,7 +453,6 @@ CONFIG_TN3270_FS=y
CONFIG_WATCHDOG=y CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_NOWAYOUT=y CONFIG_WATCHDOG_NOWAYOUT=y
CONFIG_SOFT_WATCHDOG=m CONFIG_SOFT_WATCHDOG=m
CONFIG_ZVM_WATCHDOG=m
# CONFIG_HID is not set # CONFIG_HID is not set
# CONFIG_USB_SUPPORT is not set # CONFIG_USB_SUPPORT is not set
CONFIG_INFINIBAND=m CONFIG_INFINIBAND=m
@ -540,6 +561,7 @@ CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_LKDTM=m CONFIG_LKDTM=m
CONFIG_RBTREE_TEST=m CONFIG_RBTREE_TEST=m
CONFIG_INTERVAL_TREE_TEST=m CONFIG_INTERVAL_TREE_TEST=m
CONFIG_PERCPU_TEST=m
CONFIG_ATOMIC64_SELFTEST=y CONFIG_ATOMIC64_SELFTEST=y
# CONFIG_STRICT_DEVMEM is not set # CONFIG_STRICT_DEVMEM is not set
CONFIG_S390_PTDUMP=y CONFIG_S390_PTDUMP=y
@ -601,7 +623,6 @@ CONFIG_CRYPTO_AES_S390=m
CONFIG_CRYPTO_GHASH_S390=m CONFIG_CRYPTO_GHASH_S390=m
CONFIG_ASYMMETRIC_KEY_TYPE=m CONFIG_ASYMMETRIC_KEY_TYPE=m
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m
CONFIG_PUBLIC_KEY_ALGO_RSA=m
CONFIG_X509_CERTIFICATE_PARSER=m CONFIG_X509_CERTIFICATE_PARSER=m
CONFIG_CRC7=m CONFIG_CRC7=m
CONFIG_CRC8=m CONFIG_CRC8=m

View file

@ -44,6 +44,7 @@ CONFIG_UNIXWARE_DISKLABEL=y
CONFIG_CFQ_GROUP_IOSCHED=y CONFIG_CFQ_GROUP_IOSCHED=y
CONFIG_DEFAULT_DEADLINE=y CONFIG_DEFAULT_DEADLINE=y
CONFIG_MARCH_Z9_109=y CONFIG_MARCH_Z9_109=y
CONFIG_NR_CPUS=256
CONFIG_HZ_100=y CONFIG_HZ_100=y
CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTREMOVE=y CONFIG_MEMORY_HOTREMOVE=y
@ -54,7 +55,6 @@ CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_S390=y CONFIG_HOTPLUG_PCI_S390=y
CONFIG_CHSC_SCH=y CONFIG_CHSC_SCH=y
CONFIG_CRASH_DUMP=y CONFIG_CRASH_DUMP=y
CONFIG_ZFCPDUMP=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_BINFMT_MISC=m CONFIG_BINFMT_MISC=m
CONFIG_HIBERNATION=y CONFIG_HIBERNATION=y
@ -97,7 +97,6 @@ CONFIG_TCP_CONG_VENO=m
CONFIG_TCP_CONG_YEAH=m CONFIG_TCP_CONG_YEAH=m
CONFIG_TCP_CONG_ILLINOIS=m CONFIG_TCP_CONG_ILLINOIS=m
CONFIG_IPV6=y CONFIG_IPV6=y
CONFIG_IPV6_PRIVACY=y
CONFIG_IPV6_ROUTER_PREF=y CONFIG_IPV6_ROUTER_PREF=y
CONFIG_INET6_AH=m CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m CONFIG_INET6_ESP=m
@ -107,6 +106,7 @@ CONFIG_INET6_XFRM_MODE_TRANSPORT=m
CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_TUNNEL=m
CONFIG_INET6_XFRM_MODE_BEET=m CONFIG_INET6_XFRM_MODE_BEET=m
CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
CONFIG_IPV6_VTI=m
CONFIG_IPV6_SIT=m CONFIG_IPV6_SIT=m
CONFIG_IPV6_GRE=m CONFIG_IPV6_GRE=m
CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_MULTIPLE_TABLES=y
@ -131,7 +131,17 @@ CONFIG_NF_CONNTRACK_SIP=m
CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_CONNTRACK_TFTP=m
CONFIG_NF_CT_NETLINK=m CONFIG_NF_CT_NETLINK=m
CONFIG_NF_CT_NETLINK_TIMEOUT=m CONFIG_NF_CT_NETLINK_TIMEOUT=m
CONFIG_NETFILTER_TPROXY=m CONFIG_NF_TABLES=m
CONFIG_NFT_EXTHDR=m
CONFIG_NFT_META=m
CONFIG_NFT_CT=m
CONFIG_NFT_RBTREE=m
CONFIG_NFT_HASH=m
CONFIG_NFT_COUNTER=m
CONFIG_NFT_LOG=m
CONFIG_NFT_LIMIT=m
CONFIG_NFT_NAT=m
CONFIG_NFT_COMPAT=m
CONFIG_NETFILTER_XT_SET=m CONFIG_NETFILTER_XT_SET=m
CONFIG_NETFILTER_XT_TARGET_AUDIT=m CONFIG_NETFILTER_XT_TARGET_AUDIT=m
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
@ -200,7 +210,9 @@ CONFIG_IP_SET_HASH_IP=m
CONFIG_IP_SET_HASH_IPPORT=m CONFIG_IP_SET_HASH_IPPORT=m
CONFIG_IP_SET_HASH_IPPORTIP=m CONFIG_IP_SET_HASH_IPPORTIP=m
CONFIG_IP_SET_HASH_IPPORTNET=m CONFIG_IP_SET_HASH_IPPORTNET=m
CONFIG_IP_SET_HASH_NETPORTNET=m
CONFIG_IP_SET_HASH_NET=m CONFIG_IP_SET_HASH_NET=m
CONFIG_IP_SET_HASH_NETNET=m
CONFIG_IP_SET_HASH_NETPORT=m CONFIG_IP_SET_HASH_NETPORT=m
CONFIG_IP_SET_HASH_NETIFACE=m CONFIG_IP_SET_HASH_NETIFACE=m
CONFIG_IP_SET_LIST_SET=m CONFIG_IP_SET_LIST_SET=m
@ -223,6 +235,11 @@ CONFIG_IP_VS_FTP=m
CONFIG_IP_VS_PE_SIP=m CONFIG_IP_VS_PE_SIP=m
CONFIG_NF_CONNTRACK_IPV4=m CONFIG_NF_CONNTRACK_IPV4=m
# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set # CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
CONFIG_NF_TABLES_IPV4=m
CONFIG_NFT_REJECT_IPV4=m
CONFIG_NFT_CHAIN_ROUTE_IPV4=m
CONFIG_NFT_CHAIN_NAT_IPV4=m
CONFIG_NF_TABLES_ARP=m
CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_AH=m
CONFIG_IP_NF_MATCH_ECN=m CONFIG_IP_NF_MATCH_ECN=m
@ -245,6 +262,9 @@ CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_NF_CONNTRACK_IPV6=m CONFIG_NF_CONNTRACK_IPV6=m
CONFIG_NF_TABLES_IPV6=m
CONFIG_NFT_CHAIN_ROUTE_IPV6=m
CONFIG_NFT_CHAIN_NAT_IPV6=m
CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m CONFIG_IP6_NF_MATCH_EUI64=m
@ -264,6 +284,7 @@ CONFIG_IP6_NF_SECURITY=m
CONFIG_NF_NAT_IPV6=m CONFIG_NF_NAT_IPV6=m
CONFIG_IP6_NF_TARGET_MASQUERADE=m CONFIG_IP6_NF_TARGET_MASQUERADE=m
CONFIG_IP6_NF_TARGET_NPT=m CONFIG_IP6_NF_TARGET_NPT=m
CONFIG_NF_TABLES_BRIDGE=m
CONFIG_NET_SCTPPROBE=m CONFIG_NET_SCTPPROBE=m
CONFIG_RDS=m CONFIG_RDS=m
CONFIG_RDS_RDMA=m CONFIG_RDS_RDMA=m
@ -309,6 +330,7 @@ CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m CONFIG_NET_CLS_RSVP6=m
CONFIG_NET_CLS_FLOW=m CONFIG_NET_CLS_FLOW=m
CONFIG_NET_CLS_CGROUP=y CONFIG_NET_CLS_CGROUP=y
CONFIG_NET_CLS_BPF=m
CONFIG_NET_CLS_ACT=y CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_POLICE=m CONFIG_NET_ACT_POLICE=m
CONFIG_NET_ACT_GACT=m CONFIG_NET_ACT_GACT=m
@ -376,8 +398,8 @@ CONFIG_BLK_DEV_DM=m
CONFIG_DM_CRYPT=m CONFIG_DM_CRYPT=m
CONFIG_DM_SNAPSHOT=m CONFIG_DM_SNAPSHOT=m
CONFIG_DM_MIRROR=m CONFIG_DM_MIRROR=m
CONFIG_DM_RAID=m
CONFIG_DM_LOG_USERSPACE=m CONFIG_DM_LOG_USERSPACE=m
CONFIG_DM_RAID=m
CONFIG_DM_ZERO=m CONFIG_DM_ZERO=m
CONFIG_DM_MULTIPATH=m CONFIG_DM_MULTIPATH=m
CONFIG_DM_MULTIPATH_QL=m CONFIG_DM_MULTIPATH_QL=m
@ -429,7 +451,6 @@ CONFIG_TN3270_FS=y
CONFIG_WATCHDOG=y CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_NOWAYOUT=y CONFIG_WATCHDOG_NOWAYOUT=y
CONFIG_SOFT_WATCHDOG=m CONFIG_SOFT_WATCHDOG=m
CONFIG_ZVM_WATCHDOG=m
# CONFIG_HID is not set # CONFIG_HID is not set
# CONFIG_USB_SUPPORT is not set # CONFIG_USB_SUPPORT is not set
CONFIG_INFINIBAND=m CONFIG_INFINIBAND=m
@ -532,6 +553,7 @@ CONFIG_LATENCYTOP=y
CONFIG_BLK_DEV_IO_TRACE=y CONFIG_BLK_DEV_IO_TRACE=y
# CONFIG_KPROBE_EVENT is not set # CONFIG_KPROBE_EVENT is not set
CONFIG_LKDTM=m CONFIG_LKDTM=m
CONFIG_PERCPU_TEST=m
CONFIG_ATOMIC64_SELFTEST=y CONFIG_ATOMIC64_SELFTEST=y
# CONFIG_STRICT_DEVMEM is not set # CONFIG_STRICT_DEVMEM is not set
CONFIG_S390_PTDUMP=y CONFIG_S390_PTDUMP=y
@ -593,7 +615,6 @@ CONFIG_CRYPTO_AES_S390=m
CONFIG_CRYPTO_GHASH_S390=m CONFIG_CRYPTO_GHASH_S390=m
CONFIG_ASYMMETRIC_KEY_TYPE=m CONFIG_ASYMMETRIC_KEY_TYPE=m
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m
CONFIG_PUBLIC_KEY_ALGO_RSA=m
CONFIG_X509_CERTIFICATE_PARSER=m CONFIG_X509_CERTIFICATE_PARSER=m
CONFIG_CRC7=m CONFIG_CRC7=m
CONFIG_CRC8=m CONFIG_CRC8=m

View file

@ -19,7 +19,6 @@ CONFIG_HZ_100=y
# CONFIG_CHSC_SCH is not set # CONFIG_CHSC_SCH is not set
# CONFIG_SCM_BUS is not set # CONFIG_SCM_BUS is not set
CONFIG_CRASH_DUMP=y CONFIG_CRASH_DUMP=y
CONFIG_ZFCPDUMP=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
# CONFIG_SECCOMP is not set # CONFIG_SECCOMP is not set
# CONFIG_IUCV is not set # CONFIG_IUCV is not set

View file

@ -40,6 +40,7 @@ CONFIG_PARTITION_ADVANCED=y
CONFIG_IBM_PARTITION=y CONFIG_IBM_PARTITION=y
CONFIG_DEFAULT_DEADLINE=y CONFIG_DEFAULT_DEADLINE=y
CONFIG_MARCH_Z196=y CONFIG_MARCH_Z196=y
CONFIG_NR_CPUS=256
CONFIG_HZ_100=y CONFIG_HZ_100=y
CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTREMOVE=y CONFIG_MEMORY_HOTREMOVE=y
@ -122,22 +123,31 @@ CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y CONFIG_TMPFS_POSIX_ACL=y
CONFIG_HUGETLBFS=y CONFIG_HUGETLBFS=y
# CONFIG_NETWORK_FILESYSTEMS is not set # CONFIG_NETWORK_FILESYSTEMS is not set
CONFIG_UNUSED_SYMBOLS=y
CONFIG_DEBUG_SECTION_MISMATCH=y
CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
CONFIG_MAGIC_SYSRQ=y CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_PAGEALLOC=y CONFIG_DEBUG_PAGEALLOC=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_TIMER_STATS=y CONFIG_TIMER_STATS=y
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_PROVE_LOCKING=y CONFIG_PROVE_LOCKING=y
CONFIG_LOCK_STAT=y CONFIG_LOCK_STAT=y
CONFIG_DEBUG_LOCKDEP=y CONFIG_DEBUG_LOCKDEP=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_DEBUG_WRITECOUNT=y
CONFIG_DEBUG_LIST=y CONFIG_DEBUG_LIST=y
CONFIG_DEBUG_SG=y
CONFIG_DEBUG_NOTIFIERS=y CONFIG_DEBUG_NOTIFIERS=y
CONFIG_PROVE_RCU=y CONFIG_PROVE_RCU=y
CONFIG_RCU_CPU_STALL_TIMEOUT=60 CONFIG_RCU_CPU_STALL_TIMEOUT=60
CONFIG_RCU_TRACE=y CONFIG_RCU_TRACE=y
CONFIG_LATENCYTOP=y CONFIG_LATENCYTOP=y
CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y
CONFIG_BLK_DEV_IO_TRACE=y CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_KPROBES_SANITY_TEST=y CONFIG_KPROBES_SANITY_TEST=y
# CONFIG_STRICT_DEVMEM is not set # CONFIG_STRICT_DEVMEM is not set
CONFIG_S390_PTDUMP=y
CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_CRYPTD=m
CONFIG_CRYPTO_AUTHENC=m CONFIG_CRYPTO_AUTHENC=m
CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_TEST=m

View file

@ -32,7 +32,7 @@ struct diag2fc_data {
__u32 pcpus; __u32 pcpus;
__u32 lcpus; __u32 lcpus;
__u32 vcpus; __u32 vcpus;
__u32 cpu_min; __u32 ocpus;
__u32 cpu_max; __u32 cpu_max;
__u32 cpu_shares; __u32 cpu_shares;
__u32 cpu_use_samp; __u32 cpu_use_samp;
@ -142,7 +142,12 @@ static int hpyfs_vm_create_guest(struct dentry *systems_dir,
ATTRIBUTE(cpus_dir, "capped", capped_value); ATTRIBUTE(cpus_dir, "capped", capped_value);
ATTRIBUTE(cpus_dir, "dedicated", dedicated_flag); ATTRIBUTE(cpus_dir, "dedicated", dedicated_flag);
ATTRIBUTE(cpus_dir, "count", data->vcpus); ATTRIBUTE(cpus_dir, "count", data->vcpus);
ATTRIBUTE(cpus_dir, "weight_min", data->cpu_min); /*
* Note: The "weight_min" attribute got the wrong name.
* The value represents the number of non-stopped (operating)
* CPUS.
*/
ATTRIBUTE(cpus_dir, "weight_min", data->ocpus);
ATTRIBUTE(cpus_dir, "weight_max", data->cpu_max); ATTRIBUTE(cpus_dir, "weight_max", data->cpu_max);
ATTRIBUTE(cpus_dir, "weight_cur", data->cpu_shares); ATTRIBUTE(cpus_dir, "weight_cur", data->cpu_shares);

View file

@ -44,11 +44,21 @@ struct airq_iv {
struct airq_iv *airq_iv_create(unsigned long bits, unsigned long flags); struct airq_iv *airq_iv_create(unsigned long bits, unsigned long flags);
void airq_iv_release(struct airq_iv *iv); void airq_iv_release(struct airq_iv *iv);
unsigned long airq_iv_alloc_bit(struct airq_iv *iv); unsigned long airq_iv_alloc(struct airq_iv *iv, unsigned long num);
void airq_iv_free_bit(struct airq_iv *iv, unsigned long bit); void airq_iv_free(struct airq_iv *iv, unsigned long bit, unsigned long num);
unsigned long airq_iv_scan(struct airq_iv *iv, unsigned long start, unsigned long airq_iv_scan(struct airq_iv *iv, unsigned long start,
unsigned long end); unsigned long end);
static inline unsigned long airq_iv_alloc_bit(struct airq_iv *iv)
{
return airq_iv_alloc(iv, 1);
}
static inline void airq_iv_free_bit(struct airq_iv *iv, unsigned long bit)
{
airq_iv_free(iv, bit, 1);
}
static inline unsigned long airq_iv_end(struct airq_iv *iv) static inline unsigned long airq_iv_end(struct airq_iv *iv)
{ {
return iv->end; return iv->end;

View file

@ -13,9 +13,9 @@
* *
* The bitop functions are defined to work on unsigned longs, so for an * The bitop functions are defined to work on unsigned longs, so for an
* s390x system the bits end up numbered: * s390x system the bits end up numbered:
* |63..............0|127............64|191...........128|255...........196| * |63..............0|127............64|191...........128|255...........192|
* and on s390: * and on s390:
* |31.....0|63....31|95....64|127...96|159..128|191..160|223..192|255..224| * |31.....0|63....32|95....64|127...96|159..128|191..160|223..192|255..224|
* *
* There are a few little-endian macros used mostly for filesystem * There are a few little-endian macros used mostly for filesystem
* bitmaps, these work on similar bit arrays layouts, but * bitmaps, these work on similar bit arrays layouts, but
@ -30,7 +30,7 @@
* on an s390x system the bits are numbered: * on an s390x system the bits are numbered:
* |0..............63|64............127|128...........191|192...........255| * |0..............63|64............127|128...........191|192...........255|
* and on s390: * and on s390:
* |0.....31|31....63|64....95|96...127|128..159|160..191|192..223|224..255| * |0.....31|32....63|64....95|96...127|128..159|160..191|192..223|224..255|
* *
* The main difference is that bit 0-63 (64b) or 0-31 (32b) in the bit * The main difference is that bit 0-63 (64b) or 0-31 (32b) in the bit
* number field needs to be reversed compared to the LSB0 encoded bit * number field needs to be reversed compared to the LSB0 encoded bit
@ -304,7 +304,7 @@ static inline int test_bit(unsigned long nr, const volatile unsigned long *ptr)
* On an s390x system the bits are numbered: * On an s390x system the bits are numbered:
* |0..............63|64............127|128...........191|192...........255| * |0..............63|64............127|128...........191|192...........255|
* and on s390: * and on s390:
* |0.....31|31....63|64....95|96...127|128..159|160..191|192..223|224..255| * |0.....31|32....63|64....95|96...127|128..159|160..191|192..223|224..255|
*/ */
unsigned long find_first_bit_inv(const unsigned long *addr, unsigned long size); unsigned long find_first_bit_inv(const unsigned long *addr, unsigned long size);
unsigned long find_next_bit_inv(const unsigned long *addr, unsigned long size, unsigned long find_next_bit_inv(const unsigned long *addr, unsigned long size,

View file

@ -219,7 +219,9 @@ extern void ccw_device_get_id(struct ccw_device *, struct ccw_dev_id *);
#define to_ccwdev(n) container_of(n, struct ccw_device, dev) #define to_ccwdev(n) container_of(n, struct ccw_device, dev)
#define to_ccwdrv(n) container_of(n, struct ccw_driver, driver) #define to_ccwdrv(n) container_of(n, struct ccw_driver, driver)
extern struct ccw_device *ccw_device_probe_console(void); extern struct ccw_device *ccw_device_create_console(struct ccw_driver *);
extern void ccw_device_destroy_console(struct ccw_device *);
extern int ccw_device_enable_console(struct ccw_device *);
extern void ccw_device_wait_idle(struct ccw_device *); extern void ccw_device_wait_idle(struct ccw_device *);
extern int ccw_device_force_console(struct ccw_device *); extern int ccw_device_force_console(struct ccw_device *);

View file

@ -44,22 +44,15 @@ csum_partial(const void *buff, int len, __wsum sum)
* here even more important to align src and dst on a 32-bit (or even * here even more important to align src and dst on a 32-bit (or even
* better 64-bit) boundary * better 64-bit) boundary
* *
* Copy from userspace and compute checksum. If we catch an exception * Copy from userspace and compute checksum.
* then zero the rest of the buffer.
*/ */
static inline __wsum static inline __wsum
csum_partial_copy_from_user(const void __user *src, void *dst, csum_partial_copy_from_user(const void __user *src, void *dst,
int len, __wsum sum, int len, __wsum sum,
int *err_ptr) int *err_ptr)
{ {
int missing; if (unlikely(copy_from_user(dst, src, len)))
missing = copy_from_user(dst, src, len);
if (missing) {
memset(dst + len - missing, 0, missing);
*err_ptr = -EFAULT; *err_ptr = -EFAULT;
}
return csum_partial(dst, len, sum); return csum_partial(dst, len, sum);
} }

View file

@ -5,7 +5,10 @@
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/errno.h> #include <asm/errno.h>
static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, u32 newval);
int __futex_atomic_op_inuser(int op, u32 __user *uaddr, int oparg, int *old);
static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
{ {
int op = (encoded_op >> 28) & 7; int op = (encoded_op >> 28) & 7;
int cmp = (encoded_op >> 24) & 15; int cmp = (encoded_op >> 24) & 15;
@ -17,7 +20,7 @@ static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
oparg = 1 << oparg; oparg = 1 << oparg;
pagefault_disable(); pagefault_disable();
ret = uaccess.futex_atomic_op(op, uaddr, oparg, &oldval); ret = __futex_atomic_op_inuser(op, uaddr, oparg, &oldval);
pagefault_enable(); pagefault_enable();
if (!ret) { if (!ret) {
@ -34,10 +37,4 @@ static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
return ret; return ret;
} }
static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
u32 oldval, u32 newval)
{
return uaccess.futex_atomic_cmpxchg(uval, uaddr, oldval, newval);
}
#endif /* _ASM_S390_FUTEX_H */ #endif /* _ASM_S390_FUTEX_H */

View file

@ -106,7 +106,9 @@ struct kvm_s390_sie_block {
__u64 gbea; /* 0x0180 */ __u64 gbea; /* 0x0180 */
__u8 reserved188[24]; /* 0x0188 */ __u8 reserved188[24]; /* 0x0188 */
__u32 fac; /* 0x01a0 */ __u32 fac; /* 0x01a0 */
__u8 reserved1a4[68]; /* 0x01a4 */ __u8 reserved1a4[20]; /* 0x01a4 */
__u64 cbrlo; /* 0x01b8 */
__u8 reserved1c0[40]; /* 0x01c0 */
__u64 itdba; /* 0x01e8 */ __u64 itdba; /* 0x01e8 */
__u8 reserved1f0[16]; /* 0x01f0 */ __u8 reserved1f0[16]; /* 0x01f0 */
} __attribute__((packed)); } __attribute__((packed));
@ -155,6 +157,7 @@ struct kvm_vcpu_stat {
u32 instruction_stsi; u32 instruction_stsi;
u32 instruction_stfl; u32 instruction_stfl;
u32 instruction_tprot; u32 instruction_tprot;
u32 instruction_essa;
u32 instruction_sigp_sense; u32 instruction_sigp_sense;
u32 instruction_sigp_sense_running; u32 instruction_sigp_sense_running;
u32 instruction_sigp_external_call; u32 instruction_sigp_external_call;

View file

@ -48,13 +48,42 @@ static inline void update_mm(struct mm_struct *mm, struct task_struct *tsk)
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
struct task_struct *tsk) struct task_struct *tsk)
{ {
cpumask_set_cpu(smp_processor_id(), mm_cpumask(next)); int cpu = smp_processor_id();
update_mm(next, tsk);
if (prev == next)
return;
if (atomic_inc_return(&next->context.attach_count) >> 16) {
/* Delay update_mm until all TLB flushes are done. */
set_tsk_thread_flag(tsk, TIF_TLB_WAIT);
} else {
cpumask_set_cpu(cpu, mm_cpumask(next));
update_mm(next, tsk);
if (next->context.flush_mm)
/* Flush pending TLBs */
__tlb_flush_mm(next);
}
atomic_dec(&prev->context.attach_count); atomic_dec(&prev->context.attach_count);
WARN_ON(atomic_read(&prev->context.attach_count) < 0); WARN_ON(atomic_read(&prev->context.attach_count) < 0);
atomic_inc(&next->context.attach_count); }
/* Check for TLBs not flushed yet */
__tlb_flush_mm_lazy(next); #define finish_arch_post_lock_switch finish_arch_post_lock_switch
static inline void finish_arch_post_lock_switch(void)
{
struct task_struct *tsk = current;
struct mm_struct *mm = tsk->mm;
if (!test_tsk_thread_flag(tsk, TIF_TLB_WAIT))
return;
preempt_disable();
clear_tsk_thread_flag(tsk, TIF_TLB_WAIT);
while (atomic_read(&mm->context.attach_count) >> 16)
cpu_relax();
cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
update_mm(mm, tsk);
if (mm->context.flush_mm)
__tlb_flush_mm(mm);
preempt_enable();
} }
#define enter_lazy_tlb(mm,tsk) do { } while (0) #define enter_lazy_tlb(mm,tsk) do { } while (0)

View file

@ -22,6 +22,7 @@ unsigned long *page_table_alloc(struct mm_struct *, unsigned long);
void page_table_free(struct mm_struct *, unsigned long *); void page_table_free(struct mm_struct *, unsigned long *);
void page_table_free_rcu(struct mmu_gather *, unsigned long *); void page_table_free_rcu(struct mmu_gather *, unsigned long *);
void page_table_reset_pgste(struct mm_struct *, unsigned long, unsigned long);
int set_guest_storage_key(struct mm_struct *mm, unsigned long addr, int set_guest_storage_key(struct mm_struct *mm, unsigned long addr,
unsigned long key, bool nq); unsigned long key, bool nq);
@ -91,11 +92,22 @@ static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address)
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr) static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
{ {
unsigned long *table = crst_table_alloc(mm); unsigned long *table = crst_table_alloc(mm);
if (table)
crst_table_init(table, _SEGMENT_ENTRY_EMPTY); if (!table)
return NULL;
crst_table_init(table, _SEGMENT_ENTRY_EMPTY);
if (!pgtable_pmd_page_ctor(virt_to_page(table))) {
crst_table_free(mm, table);
return NULL;
}
return (pmd_t *) table; return (pmd_t *) table;
} }
#define pmd_free(mm, pmd) crst_table_free(mm, (unsigned long *) pmd)
static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
{
pgtable_pmd_page_dtor(virt_to_page(pmd));
crst_table_free(mm, (unsigned long *) pmd);
}
static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud) static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
{ {

View file

@ -229,6 +229,7 @@ extern unsigned long MODULES_END;
#define _PAGE_READ 0x010 /* SW pte read bit */ #define _PAGE_READ 0x010 /* SW pte read bit */
#define _PAGE_WRITE 0x020 /* SW pte write bit */ #define _PAGE_WRITE 0x020 /* SW pte write bit */
#define _PAGE_SPECIAL 0x040 /* SW associated with special page */ #define _PAGE_SPECIAL 0x040 /* SW associated with special page */
#define _PAGE_UNUSED 0x080 /* SW bit for pgste usage state */
#define __HAVE_ARCH_PTE_SPECIAL #define __HAVE_ARCH_PTE_SPECIAL
/* Set of bits not changed in pte_modify */ /* Set of bits not changed in pte_modify */
@ -394,6 +395,12 @@ extern unsigned long MODULES_END;
#endif /* CONFIG_64BIT */ #endif /* CONFIG_64BIT */
/* Guest Page State used for virtualization */
#define _PGSTE_GPS_ZERO 0x0000000080000000UL
#define _PGSTE_GPS_USAGE_MASK 0x0000000003000000UL
#define _PGSTE_GPS_USAGE_STABLE 0x0000000000000000UL
#define _PGSTE_GPS_USAGE_UNUSED 0x0000000001000000UL
/* /*
* A user page table pointer has the space-switch-event bit, the * A user page table pointer has the space-switch-event bit, the
* private-space-control bit and the storage-alteration-event-control * private-space-control bit and the storage-alteration-event-control
@ -617,6 +624,14 @@ static inline int pte_none(pte_t pte)
return pte_val(pte) == _PAGE_INVALID; return pte_val(pte) == _PAGE_INVALID;
} }
static inline int pte_swap(pte_t pte)
{
/* Bit pattern: (pte & 0x603) == 0x402 */
return (pte_val(pte) & (_PAGE_INVALID | _PAGE_PROTECT |
_PAGE_TYPE | _PAGE_PRESENT))
== (_PAGE_INVALID | _PAGE_TYPE);
}
static inline int pte_file(pte_t pte) static inline int pte_file(pte_t pte)
{ {
/* Bit pattern: (pte & 0x601) == 0x600 */ /* Bit pattern: (pte & 0x601) == 0x600 */
@ -821,20 +836,20 @@ unsigned long gmap_translate(unsigned long address, struct gmap *);
unsigned long __gmap_fault(unsigned long address, struct gmap *); unsigned long __gmap_fault(unsigned long address, struct gmap *);
unsigned long gmap_fault(unsigned long address, struct gmap *); unsigned long gmap_fault(unsigned long address, struct gmap *);
void gmap_discard(unsigned long from, unsigned long to, struct gmap *); void gmap_discard(unsigned long from, unsigned long to, struct gmap *);
void __gmap_zap(unsigned long address, struct gmap *);
void gmap_register_ipte_notifier(struct gmap_notifier *); void gmap_register_ipte_notifier(struct gmap_notifier *);
void gmap_unregister_ipte_notifier(struct gmap_notifier *); void gmap_unregister_ipte_notifier(struct gmap_notifier *);
int gmap_ipte_notify(struct gmap *, unsigned long start, unsigned long len); int gmap_ipte_notify(struct gmap *, unsigned long start, unsigned long len);
void gmap_do_ipte_notify(struct mm_struct *, unsigned long addr, pte_t *); void gmap_do_ipte_notify(struct mm_struct *, pte_t *);
static inline pgste_t pgste_ipte_notify(struct mm_struct *mm, static inline pgste_t pgste_ipte_notify(struct mm_struct *mm,
unsigned long addr,
pte_t *ptep, pgste_t pgste) pte_t *ptep, pgste_t pgste)
{ {
#ifdef CONFIG_PGSTE #ifdef CONFIG_PGSTE
if (pgste_val(pgste) & PGSTE_IN_BIT) { if (pgste_val(pgste) & PGSTE_IN_BIT) {
pgste_val(pgste) &= ~PGSTE_IN_BIT; pgste_val(pgste) &= ~PGSTE_IN_BIT;
gmap_do_ipte_notify(mm, addr, ptep); gmap_do_ipte_notify(mm, ptep);
} }
#endif #endif
return pgste; return pgste;
@ -852,6 +867,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
if (mm_has_pgste(mm)) { if (mm_has_pgste(mm)) {
pgste = pgste_get_lock(ptep); pgste = pgste_get_lock(ptep);
pgste_val(pgste) &= ~_PGSTE_GPS_ZERO;
pgste_set_key(ptep, pgste, entry); pgste_set_key(ptep, pgste, entry);
pgste_set_pte(ptep, entry); pgste_set_pte(ptep, entry);
pgste_set_unlock(ptep, pgste); pgste_set_unlock(ptep, pgste);
@ -881,6 +897,12 @@ static inline int pte_young(pte_t pte)
return (pte_val(pte) & _PAGE_YOUNG) != 0; return (pte_val(pte) & _PAGE_YOUNG) != 0;
} }
#define __HAVE_ARCH_PTE_UNUSED
static inline int pte_unused(pte_t pte)
{
return pte_val(pte) & _PAGE_UNUSED;
}
/* /*
* pgd/pmd/pte modification functions * pgd/pmd/pte modification functions
*/ */
@ -1034,30 +1056,41 @@ static inline int ptep_test_and_clear_user_young(struct mm_struct *mm,
static inline void __ptep_ipte(unsigned long address, pte_t *ptep) static inline void __ptep_ipte(unsigned long address, pte_t *ptep)
{ {
if (!(pte_val(*ptep) & _PAGE_INVALID)) { unsigned long pto = (unsigned long) ptep;
#ifndef CONFIG_64BIT #ifndef CONFIG_64BIT
/* pto must point to the start of the segment table */ /* pto in ESA mode must point to the start of the segment table */
pte_t *pto = (pte_t *) (((unsigned long) ptep) & 0x7ffffc00); pto &= 0x7ffffc00;
#else
/* ipte in zarch mode can do the math */
pte_t *pto = ptep;
#endif #endif
asm volatile( /* Invalidation + global TLB flush for the pte */
" ipte %2,%3" asm volatile(
: "=m" (*ptep) : "m" (*ptep), " ipte %2,%3"
"a" (pto), "a" (address)); : "=m" (*ptep) : "m" (*ptep), "a" (pto), "a" (address));
} }
static inline void ptep_flush_direct(struct mm_struct *mm,
unsigned long address, pte_t *ptep)
{
if (pte_val(*ptep) & _PAGE_INVALID)
return;
__ptep_ipte(address, ptep);
} }
static inline void ptep_flush_lazy(struct mm_struct *mm, static inline void ptep_flush_lazy(struct mm_struct *mm,
unsigned long address, pte_t *ptep) unsigned long address, pte_t *ptep)
{ {
int active = (mm == current->active_mm) ? 1 : 0; int active, count;
if (atomic_read(&mm->context.attach_count) > active) if (pte_val(*ptep) & _PAGE_INVALID)
__ptep_ipte(address, ptep); return;
else active = (mm == current->active_mm) ? 1 : 0;
count = atomic_add_return(0x10000, &mm->context.attach_count);
if ((count & 0xffff) <= active) {
pte_val(*ptep) |= _PAGE_INVALID;
mm->context.flush_mm = 1; mm->context.flush_mm = 1;
} else
__ptep_ipte(address, ptep);
atomic_sub(0x10000, &mm->context.attach_count);
} }
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
@ -1070,11 +1103,11 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
if (mm_has_pgste(vma->vm_mm)) { if (mm_has_pgste(vma->vm_mm)) {
pgste = pgste_get_lock(ptep); pgste = pgste_get_lock(ptep);
pgste = pgste_ipte_notify(vma->vm_mm, addr, ptep, pgste); pgste = pgste_ipte_notify(vma->vm_mm, ptep, pgste);
} }
pte = *ptep; pte = *ptep;
__ptep_ipte(addr, ptep); ptep_flush_direct(vma->vm_mm, addr, ptep);
young = pte_young(pte); young = pte_young(pte);
pte = pte_mkold(pte); pte = pte_mkold(pte);
@ -1116,7 +1149,7 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
if (mm_has_pgste(mm)) { if (mm_has_pgste(mm)) {
pgste = pgste_get_lock(ptep); pgste = pgste_get_lock(ptep);
pgste = pgste_ipte_notify(mm, address, ptep, pgste); pgste = pgste_ipte_notify(mm, ptep, pgste);
} }
pte = *ptep; pte = *ptep;
@ -1140,12 +1173,11 @@ static inline pte_t ptep_modify_prot_start(struct mm_struct *mm,
if (mm_has_pgste(mm)) { if (mm_has_pgste(mm)) {
pgste = pgste_get_lock(ptep); pgste = pgste_get_lock(ptep);
pgste_ipte_notify(mm, address, ptep, pgste); pgste_ipte_notify(mm, ptep, pgste);
} }
pte = *ptep; pte = *ptep;
ptep_flush_lazy(mm, address, ptep); ptep_flush_lazy(mm, address, ptep);
pte_val(*ptep) |= _PAGE_INVALID;
if (mm_has_pgste(mm)) { if (mm_has_pgste(mm)) {
pgste = pgste_update_all(&pte, pgste); pgste = pgste_update_all(&pte, pgste);
@ -1178,14 +1210,17 @@ static inline pte_t ptep_clear_flush(struct vm_area_struct *vma,
if (mm_has_pgste(vma->vm_mm)) { if (mm_has_pgste(vma->vm_mm)) {
pgste = pgste_get_lock(ptep); pgste = pgste_get_lock(ptep);
pgste = pgste_ipte_notify(vma->vm_mm, address, ptep, pgste); pgste = pgste_ipte_notify(vma->vm_mm, ptep, pgste);
} }
pte = *ptep; pte = *ptep;
__ptep_ipte(address, ptep); ptep_flush_direct(vma->vm_mm, address, ptep);
pte_val(*ptep) = _PAGE_INVALID; pte_val(*ptep) = _PAGE_INVALID;
if (mm_has_pgste(vma->vm_mm)) { if (mm_has_pgste(vma->vm_mm)) {
if ((pgste_val(pgste) & _PGSTE_GPS_USAGE_MASK) ==
_PGSTE_GPS_USAGE_UNUSED)
pte_val(pte) |= _PAGE_UNUSED;
pgste = pgste_update_all(&pte, pgste); pgste = pgste_update_all(&pte, pgste);
pgste_set_unlock(ptep, pgste); pgste_set_unlock(ptep, pgste);
} }
@ -1209,7 +1244,7 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm,
if (!full && mm_has_pgste(mm)) { if (!full && mm_has_pgste(mm)) {
pgste = pgste_get_lock(ptep); pgste = pgste_get_lock(ptep);
pgste = pgste_ipte_notify(mm, address, ptep, pgste); pgste = pgste_ipte_notify(mm, ptep, pgste);
} }
pte = *ptep; pte = *ptep;
@ -1234,7 +1269,7 @@ static inline pte_t ptep_set_wrprotect(struct mm_struct *mm,
if (pte_write(pte)) { if (pte_write(pte)) {
if (mm_has_pgste(mm)) { if (mm_has_pgste(mm)) {
pgste = pgste_get_lock(ptep); pgste = pgste_get_lock(ptep);
pgste = pgste_ipte_notify(mm, address, ptep, pgste); pgste = pgste_ipte_notify(mm, ptep, pgste);
} }
ptep_flush_lazy(mm, address, ptep); ptep_flush_lazy(mm, address, ptep);
@ -1260,10 +1295,10 @@ static inline int ptep_set_access_flags(struct vm_area_struct *vma,
return 0; return 0;
if (mm_has_pgste(vma->vm_mm)) { if (mm_has_pgste(vma->vm_mm)) {
pgste = pgste_get_lock(ptep); pgste = pgste_get_lock(ptep);
pgste = pgste_ipte_notify(vma->vm_mm, address, ptep, pgste); pgste = pgste_ipte_notify(vma->vm_mm, ptep, pgste);
} }
__ptep_ipte(address, ptep); ptep_flush_direct(vma->vm_mm, address, ptep);
if (mm_has_pgste(vma->vm_mm)) { if (mm_has_pgste(vma->vm_mm)) {
pgste_set_pte(ptep, entry); pgste_set_pte(ptep, entry);
@ -1447,12 +1482,16 @@ static inline pmd_t pmd_mkwrite(pmd_t pmd)
static inline void pmdp_flush_lazy(struct mm_struct *mm, static inline void pmdp_flush_lazy(struct mm_struct *mm,
unsigned long address, pmd_t *pmdp) unsigned long address, pmd_t *pmdp)
{ {
int active = (mm == current->active_mm) ? 1 : 0; int active, count;
if ((atomic_read(&mm->context.attach_count) & 0xffff) > active) active = (mm == current->active_mm) ? 1 : 0;
__pmd_idte(address, pmdp); count = atomic_add_return(0x10000, &mm->context.attach_count);
else if ((count & 0xffff) <= active) {
pmd_val(*pmdp) |= _SEGMENT_ENTRY_INVALID;
mm->context.flush_mm = 1; mm->context.flush_mm = 1;
} else
__pmd_idte(address, pmdp);
atomic_sub(0x10000, &mm->context.attach_count);
} }
#ifdef CONFIG_TRANSPARENT_HUGEPAGE #ifdef CONFIG_TRANSPARENT_HUGEPAGE

View file

@ -83,6 +83,7 @@ struct per_struct_kernel {
* These are defined as per linux/ptrace.h, which see. * These are defined as per linux/ptrace.h, which see.
*/ */
#define arch_has_single_step() (1) #define arch_has_single_step() (1)
#define arch_has_block_step() (1)
#define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
#define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)

View file

@ -46,6 +46,7 @@ int sclp_cpu_configure(u8 cpu);
int sclp_cpu_deconfigure(u8 cpu); int sclp_cpu_deconfigure(u8 cpu);
unsigned long long sclp_get_rnmax(void); unsigned long long sclp_get_rnmax(void);
unsigned long long sclp_get_rzm(void); unsigned long long sclp_get_rzm(void);
unsigned int sclp_get_max_cpu(void);
int sclp_sdias_blk_count(void); int sclp_sdias_blk_count(void);
int sclp_sdias_copy(void *dest, int blk_num, int nr_blks); int sclp_sdias_copy(void *dest, int blk_num, int nr_blks);
int sclp_chp_configure(struct chp_id chpid); int sclp_chp_configure(struct chp_id chpid);

View file

@ -59,7 +59,6 @@ void create_mem_hole(struct mem_chunk mem_chunk[], unsigned long addr,
#define MACHINE_FLAG_DIAG44 (1UL << 4) #define MACHINE_FLAG_DIAG44 (1UL << 4)
#define MACHINE_FLAG_IDTE (1UL << 5) #define MACHINE_FLAG_IDTE (1UL << 5)
#define MACHINE_FLAG_DIAG9C (1UL << 6) #define MACHINE_FLAG_DIAG9C (1UL << 6)
#define MACHINE_FLAG_MVCOS (1UL << 7)
#define MACHINE_FLAG_KVM (1UL << 8) #define MACHINE_FLAG_KVM (1UL << 8)
#define MACHINE_FLAG_ESOP (1UL << 9) #define MACHINE_FLAG_ESOP (1UL << 9)
#define MACHINE_FLAG_EDAT1 (1UL << 10) #define MACHINE_FLAG_EDAT1 (1UL << 10)
@ -85,7 +84,6 @@ void create_mem_hole(struct mem_chunk mem_chunk[], unsigned long addr,
#define MACHINE_HAS_IDTE (0) #define MACHINE_HAS_IDTE (0)
#define MACHINE_HAS_DIAG44 (1) #define MACHINE_HAS_DIAG44 (1)
#define MACHINE_HAS_MVPG (S390_lowcore.machine_flags & MACHINE_FLAG_MVPG) #define MACHINE_HAS_MVPG (S390_lowcore.machine_flags & MACHINE_FLAG_MVPG)
#define MACHINE_HAS_MVCOS (0)
#define MACHINE_HAS_EDAT1 (0) #define MACHINE_HAS_EDAT1 (0)
#define MACHINE_HAS_EDAT2 (0) #define MACHINE_HAS_EDAT2 (0)
#define MACHINE_HAS_LPP (0) #define MACHINE_HAS_LPP (0)
@ -98,7 +96,6 @@ void create_mem_hole(struct mem_chunk mem_chunk[], unsigned long addr,
#define MACHINE_HAS_IDTE (S390_lowcore.machine_flags & MACHINE_FLAG_IDTE) #define MACHINE_HAS_IDTE (S390_lowcore.machine_flags & MACHINE_FLAG_IDTE)
#define MACHINE_HAS_DIAG44 (S390_lowcore.machine_flags & MACHINE_FLAG_DIAG44) #define MACHINE_HAS_DIAG44 (S390_lowcore.machine_flags & MACHINE_FLAG_DIAG44)
#define MACHINE_HAS_MVPG (1) #define MACHINE_HAS_MVPG (1)
#define MACHINE_HAS_MVCOS (S390_lowcore.machine_flags & MACHINE_FLAG_MVCOS)
#define MACHINE_HAS_EDAT1 (S390_lowcore.machine_flags & MACHINE_FLAG_EDAT1) #define MACHINE_HAS_EDAT1 (S390_lowcore.machine_flags & MACHINE_FLAG_EDAT1)
#define MACHINE_HAS_EDAT2 (S390_lowcore.machine_flags & MACHINE_FLAG_EDAT2) #define MACHINE_HAS_EDAT2 (S390_lowcore.machine_flags & MACHINE_FLAG_EDAT2)
#define MACHINE_HAS_LPP (S390_lowcore.machine_flags & MACHINE_FLAG_LPP) #define MACHINE_HAS_LPP (S390_lowcore.machine_flags & MACHINE_FLAG_LPP)

View file

@ -81,6 +81,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_NOTIFY_RESUME 1 /* callback before returning to user */ #define TIF_NOTIFY_RESUME 1 /* callback before returning to user */
#define TIF_SIGPENDING 2 /* signal pending */ #define TIF_SIGPENDING 2 /* signal pending */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_TLB_WAIT 4 /* wait for TLB flush completion */
#define TIF_PER_TRAP 6 /* deliver sigtrap on return to user */ #define TIF_PER_TRAP 6 /* deliver sigtrap on return to user */
#define TIF_MCCK_PENDING 7 /* machine check handling is pending */ #define TIF_MCCK_PENDING 7 /* machine check handling is pending */
#define TIF_SYSCALL_TRACE 8 /* syscall trace active */ #define TIF_SYSCALL_TRACE 8 /* syscall trace active */
@ -91,11 +92,13 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define TIF_RESTORE_SIGMASK 19 /* restore signal mask in do_signal() */ #define TIF_RESTORE_SIGMASK 19 /* restore signal mask in do_signal() */
#define TIF_SINGLE_STEP 20 /* This task is single stepped */ #define TIF_SINGLE_STEP 20 /* This task is single stepped */
#define TIF_BLOCK_STEP 21 /* This task is block stepped */
#define _TIF_SYSCALL (1<<TIF_SYSCALL) #define _TIF_SYSCALL (1<<TIF_SYSCALL)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_TLB_WAIT (1<<TIF_TLB_WAIT)
#define _TIF_PER_TRAP (1<<TIF_PER_TRAP) #define _TIF_PER_TRAP (1<<TIF_PER_TRAP)
#define _TIF_MCCK_PENDING (1<<TIF_MCCK_PENDING) #define _TIF_MCCK_PENDING (1<<TIF_MCCK_PENDING)
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)

View file

@ -92,33 +92,58 @@ static inline unsigned long extable_fixup(const struct exception_table_entry *x)
#define ARCH_HAS_SORT_EXTABLE #define ARCH_HAS_SORT_EXTABLE
#define ARCH_HAS_SEARCH_EXTABLE #define ARCH_HAS_SEARCH_EXTABLE
struct uaccess_ops { int __handle_fault(unsigned long, unsigned long, int);
size_t (*copy_from_user)(size_t, const void __user *, void *);
size_t (*copy_to_user)(size_t, void __user *, const void *);
size_t (*copy_in_user)(size_t, void __user *, const void __user *);
size_t (*clear_user)(size_t, void __user *);
size_t (*strnlen_user)(size_t, const char __user *);
size_t (*strncpy_from_user)(size_t, const char __user *, char *);
int (*futex_atomic_op)(int op, u32 __user *, int oparg, int *old);
int (*futex_atomic_cmpxchg)(u32 *, u32 __user *, u32 old, u32 new);
};
extern struct uaccess_ops uaccess; /**
extern struct uaccess_ops uaccess_mvcos; * __copy_from_user: - Copy a block of data from user space, with less checking.
extern struct uaccess_ops uaccess_pt; * @to: Destination address, in kernel space.
* @from: Source address, in user space.
* @n: Number of bytes to copy.
*
* Context: User context only. This function may sleep.
*
* Copy data from user space to kernel space. Caller must check
* the specified block with access_ok() before calling this function.
*
* Returns number of bytes that could not be copied.
* On success, this will be zero.
*
* If some data could not be copied, this function will pad the copied
* data to the requested size using zero bytes.
*/
unsigned long __must_check __copy_from_user(void *to, const void __user *from,
unsigned long n);
extern int __handle_fault(unsigned long, unsigned long, int); /**
* __copy_to_user: - Copy a block of data into user space, with less checking.
* @to: Destination address, in user space.
* @from: Source address, in kernel space.
* @n: Number of bytes to copy.
*
* Context: User context only. This function may sleep.
*
* Copy data from kernel space to user space. Caller must check
* the specified block with access_ok() before calling this function.
*
* Returns number of bytes that could not be copied.
* On success, this will be zero.
*/
unsigned long __must_check __copy_to_user(void __user *to, const void *from,
unsigned long n);
static inline int __put_user_fn(size_t size, void __user *ptr, void *x) #define __copy_to_user_inatomic __copy_to_user
#define __copy_from_user_inatomic __copy_from_user
static inline int __put_user_fn(void *x, void __user *ptr, unsigned long size)
{ {
size = uaccess.copy_to_user(size, ptr, x); size = __copy_to_user(ptr, x, size);
return size ? -EFAULT : size; return size ? -EFAULT : 0;
} }
static inline int __get_user_fn(size_t size, const void __user *ptr, void *x) static inline int __get_user_fn(void *x, const void __user *ptr, unsigned long size)
{ {
size = uaccess.copy_from_user(size, ptr, x); size = __copy_from_user(x, ptr, size);
return size ? -EFAULT : size; return size ? -EFAULT : 0;
} }
/* /*
@ -135,8 +160,8 @@ static inline int __get_user_fn(size_t size, const void __user *ptr, void *x)
case 2: \ case 2: \
case 4: \ case 4: \
case 8: \ case 8: \
__pu_err = __put_user_fn(sizeof (*(ptr)), \ __pu_err = __put_user_fn(&__x, ptr, \
ptr, &__x); \ sizeof(*(ptr))); \
break; \ break; \
default: \ default: \
__put_user_bad(); \ __put_user_bad(); \
@ -152,7 +177,7 @@ static inline int __get_user_fn(size_t size, const void __user *ptr, void *x)
}) })
extern int __put_user_bad(void) __attribute__((noreturn)); int __put_user_bad(void) __attribute__((noreturn));
#define __get_user(x, ptr) \ #define __get_user(x, ptr) \
({ \ ({ \
@ -161,29 +186,29 @@ extern int __put_user_bad(void) __attribute__((noreturn));
switch (sizeof(*(ptr))) { \ switch (sizeof(*(ptr))) { \
case 1: { \ case 1: { \
unsigned char __x; \ unsigned char __x; \
__gu_err = __get_user_fn(sizeof (*(ptr)), \ __gu_err = __get_user_fn(&__x, ptr, \
ptr, &__x); \ sizeof(*(ptr))); \
(x) = *(__force __typeof__(*(ptr)) *) &__x; \ (x) = *(__force __typeof__(*(ptr)) *) &__x; \
break; \ break; \
}; \ }; \
case 2: { \ case 2: { \
unsigned short __x; \ unsigned short __x; \
__gu_err = __get_user_fn(sizeof (*(ptr)), \ __gu_err = __get_user_fn(&__x, ptr, \
ptr, &__x); \ sizeof(*(ptr))); \
(x) = *(__force __typeof__(*(ptr)) *) &__x; \ (x) = *(__force __typeof__(*(ptr)) *) &__x; \
break; \ break; \
}; \ }; \
case 4: { \ case 4: { \
unsigned int __x; \ unsigned int __x; \
__gu_err = __get_user_fn(sizeof (*(ptr)), \ __gu_err = __get_user_fn(&__x, ptr, \
ptr, &__x); \ sizeof(*(ptr))); \
(x) = *(__force __typeof__(*(ptr)) *) &__x; \ (x) = *(__force __typeof__(*(ptr)) *) &__x; \
break; \ break; \
}; \ }; \
case 8: { \ case 8: { \
unsigned long long __x; \ unsigned long long __x; \
__gu_err = __get_user_fn(sizeof (*(ptr)), \ __gu_err = __get_user_fn(&__x, ptr, \
ptr, &__x); \ sizeof(*(ptr))); \
(x) = *(__force __typeof__(*(ptr)) *) &__x; \ (x) = *(__force __typeof__(*(ptr)) *) &__x; \
break; \ break; \
}; \ }; \
@ -200,34 +225,11 @@ extern int __put_user_bad(void) __attribute__((noreturn));
__get_user(x, ptr); \ __get_user(x, ptr); \
}) })
extern int __get_user_bad(void) __attribute__((noreturn)); int __get_user_bad(void) __attribute__((noreturn));
#define __put_user_unaligned __put_user #define __put_user_unaligned __put_user
#define __get_user_unaligned __get_user #define __get_user_unaligned __get_user
/**
* __copy_to_user: - Copy a block of data into user space, with less checking.
* @to: Destination address, in user space.
* @from: Source address, in kernel space.
* @n: Number of bytes to copy.
*
* Context: User context only. This function may sleep.
*
* Copy data from kernel space to user space. Caller must check
* the specified block with access_ok() before calling this function.
*
* Returns number of bytes that could not be copied.
* On success, this will be zero.
*/
static inline unsigned long __must_check
__copy_to_user(void __user *to, const void *from, unsigned long n)
{
return uaccess.copy_to_user(n, to, from);
}
#define __copy_to_user_inatomic __copy_to_user
#define __copy_from_user_inatomic __copy_from_user
/** /**
* copy_to_user: - Copy a block of data into user space. * copy_to_user: - Copy a block of data into user space.
* @to: Destination address, in user space. * @to: Destination address, in user space.
@ -248,30 +250,7 @@ copy_to_user(void __user *to, const void *from, unsigned long n)
return __copy_to_user(to, from, n); return __copy_to_user(to, from, n);
} }
/** void copy_from_user_overflow(void)
* __copy_from_user: - Copy a block of data from user space, with less checking.
* @to: Destination address, in kernel space.
* @from: Source address, in user space.
* @n: Number of bytes to copy.
*
* Context: User context only. This function may sleep.
*
* Copy data from user space to kernel space. Caller must check
* the specified block with access_ok() before calling this function.
*
* Returns number of bytes that could not be copied.
* On success, this will be zero.
*
* If some data could not be copied, this function will pad the copied
* data to the requested size using zero bytes.
*/
static inline unsigned long __must_check
__copy_from_user(void *to, const void __user *from, unsigned long n)
{
return uaccess.copy_from_user(n, from, to);
}
extern void copy_from_user_overflow(void)
#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS #ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
__compiletime_warning("copy_from_user() buffer size is not provably correct") __compiletime_warning("copy_from_user() buffer size is not provably correct")
#endif #endif
@ -306,11 +285,8 @@ copy_from_user(void *to, const void __user *from, unsigned long n)
return __copy_from_user(to, from, n); return __copy_from_user(to, from, n);
} }
static inline unsigned long __must_check unsigned long __must_check
__copy_in_user(void __user *to, const void __user *from, unsigned long n) __copy_in_user(void __user *to, const void __user *from, unsigned long n);
{
return uaccess.copy_in_user(n, to, from);
}
static inline unsigned long __must_check static inline unsigned long __must_check
copy_in_user(void __user *to, const void __user *from, unsigned long n) copy_in_user(void __user *to, const void __user *from, unsigned long n)
@ -322,18 +298,22 @@ copy_in_user(void __user *to, const void __user *from, unsigned long n)
/* /*
* Copy a null terminated string from userspace. * Copy a null terminated string from userspace.
*/ */
long __strncpy_from_user(char *dst, const char __user *src, long count);
static inline long __must_check static inline long __must_check
strncpy_from_user(char *dst, const char __user *src, long count) strncpy_from_user(char *dst, const char __user *src, long count)
{ {
might_fault(); might_fault();
return uaccess.strncpy_from_user(count, src, dst); return __strncpy_from_user(dst, src, count);
} }
static inline unsigned long unsigned long __must_check __strnlen_user(const char __user *src, unsigned long count);
strnlen_user(const char __user * src, unsigned long n)
static inline unsigned long strnlen_user(const char __user *src, unsigned long n)
{ {
might_fault(); might_fault();
return uaccess.strnlen_user(n, src); return __strnlen_user(src, n);
} }
/** /**
@ -355,21 +335,14 @@ strnlen_user(const char __user * src, unsigned long n)
/* /*
* Zero Userspace * Zero Userspace
*/ */
unsigned long __must_check __clear_user(void __user *to, unsigned long size);
static inline unsigned long __must_check static inline unsigned long __must_check clear_user(void __user *to, unsigned long n)
__clear_user(void __user *to, unsigned long n)
{
return uaccess.clear_user(n, to);
}
static inline unsigned long __must_check
clear_user(void __user *to, unsigned long n)
{ {
might_fault(); might_fault();
return uaccess.clear_user(n, to); return __clear_user(to, n);
} }
extern int copy_to_user_real(void __user *dest, void *src, size_t count); int copy_to_user_real(void __user *dest, void *src, unsigned long count);
extern int copy_from_user_real(void *dest, void __user *src, size_t count);
#endif /* __S390_UACCESS_H */ #endif /* __S390_UACCESS_H */

View file

@ -402,6 +402,12 @@ typedef struct
#define PTRACE_DISABLE_TE 0x5010 #define PTRACE_DISABLE_TE 0x5010
#define PTRACE_TE_ABORT_RAND 0x5011 #define PTRACE_TE_ABORT_RAND 0x5011
/*
* The numbers chosen here are somewhat arbitrary but absolutely MUST
* not overlap with any of the number assigned in <linux/ptrace.h>.
*/
#define PTRACE_SINGLEBLOCK 12 /* resume execution until next branch */
/* /*
* PT_PROT definition is loosely based on hppa bsd definition in * PT_PROT definition is loosely based on hppa bsd definition in
* gdb/hppab-nat.c * gdb/hppab-nat.c

View file

@ -47,9 +47,8 @@ obj-$(CONFIG_SCHED_BOOK) += topology.o
obj-$(CONFIG_HIBERNATION) += suspend.o swsusp_asm64.o obj-$(CONFIG_HIBERNATION) += suspend.o swsusp_asm64.o
obj-$(CONFIG_AUDIT) += audit.o obj-$(CONFIG_AUDIT) += audit.o
compat-obj-$(CONFIG_AUDIT) += compat_audit.o compat-obj-$(CONFIG_AUDIT) += compat_audit.o
obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \ obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o
compat_wrapper.o compat_exec_domain.o \ obj-$(CONFIG_COMPAT) += compat_wrapper.o $(compat-obj-y)
$(compat-obj-y)
obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_KPROBES) += kprobes.o

View file

@ -1,29 +0,0 @@
/*
* Support for 32-bit Linux for S390 personality.
*
* Copyright IBM Corp. 2000
* Author(s): Gerhard Tonn (ton@de.ibm.com)
*
*
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/personality.h>
#include <linux/sched.h>
static struct exec_domain s390_exec_domain;
static int __init s390_init (void)
{
s390_exec_domain.name = "Linux/s390";
s390_exec_domain.handler = NULL;
s390_exec_domain.pers_low = PER_LINUX32;
s390_exec_domain.pers_high = PER_LINUX32;
s390_exec_domain.signal_map = default_exec_domain.signal_map;
s390_exec_domain.signal_invmap = default_exec_domain.signal_invmap;
register_exec_domain(&s390_exec_domain);
return 0;
}
__initcall(s390_init);

View file

@ -380,8 +380,6 @@ static __init void detect_machine_facilities(void)
S390_lowcore.machine_flags |= MACHINE_FLAG_EDAT2; S390_lowcore.machine_flags |= MACHINE_FLAG_EDAT2;
if (test_facility(3)) if (test_facility(3))
S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE; S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE;
if (test_facility(27))
S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS;
if (test_facility(40)) if (test_facility(40))
S390_lowcore.machine_flags |= MACHINE_FLAG_LPP; S390_lowcore.machine_flags |= MACHINE_FLAG_LPP;
if (test_facility(50) && test_facility(73)) if (test_facility(50) && test_facility(73))

View file

@ -43,6 +43,7 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
_TIF_MCCK_PENDING) _TIF_MCCK_PENDING)
_TIF_TRACE = (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \ _TIF_TRACE = (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \
_TIF_SYSCALL_TRACEPOINT) _TIF_SYSCALL_TRACEPOINT)
_TIF_TRANSFER = (_TIF_MCCK_PENDING | _TIF_TLB_WAIT)
STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
STACK_SIZE = 1 << STACK_SHIFT STACK_SIZE = 1 << STACK_SHIFT
@ -159,10 +160,12 @@ ENTRY(__switch_to)
lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4
mvc __LC_CURRENT_PID(4,%r0),__TASK_pid(%r3) # store pid of next mvc __LC_CURRENT_PID(4,%r0),__TASK_pid(%r3) # store pid of next
l %r15,__THREAD_ksp(%r3) # load kernel stack of next l %r15,__THREAD_ksp(%r3) # load kernel stack of next
tm __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending? lhi %r6,_TIF_TRANSFER # transfer TIF bits
n %r6,__TI_flags(%r4) # isolate TIF bits
jz 0f jz 0f
ni __TI_flags+3(%r4),255-_TIF_MCCK_PENDING # clear flag in prev o %r6,__TI_flags(%r5) # set TIF bits of next
oi __TI_flags+3(%r5),_TIF_MCCK_PENDING # set it in next st %r6,__TI_flags(%r5)
ni __TI_flags+3(%r4),255-_TIF_TRANSFER # clear TIF bits of prev
0: lm %r6,%r15,__SF_GPRS(%r15) # load gprs of next task 0: lm %r6,%r15,__SF_GPRS(%r15) # load gprs of next task
br %r14 br %r14

View file

@ -48,6 +48,7 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
_TIF_MCCK_PENDING) _TIF_MCCK_PENDING)
_TIF_TRACE = (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \ _TIF_TRACE = (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \
_TIF_SYSCALL_TRACEPOINT) _TIF_SYSCALL_TRACEPOINT)
_TIF_TRANSFER = (_TIF_MCCK_PENDING | _TIF_TLB_WAIT)
#define BASED(name) name-system_call(%r13) #define BASED(name) name-system_call(%r13)
@ -189,10 +190,12 @@ ENTRY(__switch_to)
lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4
mvc __LC_CURRENT_PID+4(4,%r0),__TASK_pid(%r3) # store pid of next mvc __LC_CURRENT_PID+4(4,%r0),__TASK_pid(%r3) # store pid of next
lg %r15,__THREAD_ksp(%r3) # load kernel stack of next lg %r15,__THREAD_ksp(%r3) # load kernel stack of next
tm __TI_flags+7(%r4),_TIF_MCCK_PENDING # machine check pending? llill %r6,_TIF_TRANSFER # transfer TIF bits
ng %r6,__TI_flags(%r4) # isolate TIF bits
jz 0f jz 0f
ni __TI_flags+7(%r4),255-_TIF_MCCK_PENDING # clear flag in prev og %r6,__TI_flags(%r5) # set TIF bits of next
oi __TI_flags+7(%r5),_TIF_MCCK_PENDING # set it in next stg %r6,__TI_flags(%r5)
ni __TI_flags+7(%r4),255-_TIF_TRANSFER # clear TIF bits of prev
0: lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task 0: lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task
br %r14 br %r14

View file

@ -121,7 +121,7 @@ unsigned long perf_misc_flags(struct pt_regs *regs)
: PERF_RECORD_MISC_KERNEL; : PERF_RECORD_MISC_KERNEL;
} }
void print_debug_cf(void) static void print_debug_cf(void)
{ {
struct cpumf_ctr_info cf_info; struct cpumf_ctr_info cf_info;
int cpu = smp_processor_id(); int cpu = smp_processor_id();

View file

@ -85,7 +85,10 @@ void update_cr_regs(struct task_struct *task)
/* merge TIF_SINGLE_STEP into user specified PER registers. */ /* merge TIF_SINGLE_STEP into user specified PER registers. */
if (test_tsk_thread_flag(task, TIF_SINGLE_STEP)) { if (test_tsk_thread_flag(task, TIF_SINGLE_STEP)) {
new.control |= PER_EVENT_IFETCH; if (test_tsk_thread_flag(task, TIF_BLOCK_STEP))
new.control |= PER_EVENT_BRANCH;
else
new.control |= PER_EVENT_IFETCH;
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
new.control |= PER_CONTROL_SUSPENSION; new.control |= PER_CONTROL_SUSPENSION;
new.control |= PER_EVENT_TRANSACTION_END; new.control |= PER_EVENT_TRANSACTION_END;
@ -107,14 +110,22 @@ void update_cr_regs(struct task_struct *task)
void user_enable_single_step(struct task_struct *task) void user_enable_single_step(struct task_struct *task)
{ {
clear_tsk_thread_flag(task, TIF_BLOCK_STEP);
set_tsk_thread_flag(task, TIF_SINGLE_STEP); set_tsk_thread_flag(task, TIF_SINGLE_STEP);
} }
void user_disable_single_step(struct task_struct *task) void user_disable_single_step(struct task_struct *task)
{ {
clear_tsk_thread_flag(task, TIF_BLOCK_STEP);
clear_tsk_thread_flag(task, TIF_SINGLE_STEP); clear_tsk_thread_flag(task, TIF_SINGLE_STEP);
} }
void user_enable_block_step(struct task_struct *task)
{
set_tsk_thread_flag(task, TIF_SINGLE_STEP);
set_tsk_thread_flag(task, TIF_BLOCK_STEP);
}
/* /*
* Called by kernel/ptrace.c when detaching.. * Called by kernel/ptrace.c when detaching..
* *

View file

@ -47,7 +47,6 @@
#include <linux/compat.h> #include <linux/compat.h>
#include <asm/ipl.h> #include <asm/ipl.h>
#include <asm/uaccess.h>
#include <asm/facility.h> #include <asm/facility.h>
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/mmu_context.h> #include <asm/mmu_context.h>
@ -64,12 +63,6 @@
#include <asm/sclp.h> #include <asm/sclp.h>
#include "entry.h" #include "entry.h"
/*
* User copy operations.
*/
struct uaccess_ops uaccess;
EXPORT_SYMBOL(uaccess);
/* /*
* Machine setup.. * Machine setup..
*/ */
@ -294,14 +287,6 @@ static int __init parse_vmalloc(char *arg)
} }
early_param("vmalloc", parse_vmalloc); early_param("vmalloc", parse_vmalloc);
static int __init early_parse_user_mode(char *p)
{
if (!p || strcmp(p, "primary") == 0)
return 0;
return 1;
}
early_param("user_mode", early_parse_user_mode);
void *restart_stack __attribute__((__section__(".data"))); void *restart_stack __attribute__((__section__(".data")));
static void __init setup_lowcore(void) static void __init setup_lowcore(void)
@ -1009,8 +994,6 @@ void __init setup_arch(char **cmdline_p)
init_mm.end_data = (unsigned long) &_edata; init_mm.end_data = (unsigned long) &_edata;
init_mm.brk = (unsigned long) &_end; init_mm.brk = (unsigned long) &_end;
uaccess = MACHINE_HAS_MVCOS ? uaccess_mvcos : uaccess_pt;
parse_early_param(); parse_early_param();
detect_memory_layout(memory_chunk, memory_end); detect_memory_layout(memory_chunk, memory_end);
os_info_init(); os_info_init();

View file

@ -773,11 +773,11 @@ void __noreturn cpu_die(void)
void __init smp_fill_possible_mask(void) void __init smp_fill_possible_mask(void)
{ {
unsigned int possible, cpu; unsigned int possible, sclp, cpu;
possible = setup_possible_cpus; sclp = sclp_get_max_cpu() ?: nr_cpu_ids;
if (!possible) possible = setup_possible_cpus ?: nr_cpu_ids;
possible = MACHINE_IS_VM ? 64 : nr_cpu_ids; possible = min(possible, sclp);
for (cpu = 0; cpu < possible && cpu < nr_cpu_ids; cpu++) for (cpu = 0; cpu < possible && cpu < nr_cpu_ids; cpu++)
set_cpu_possible(cpu, true); set_cpu_possible(cpu, true);
} }

View file

@ -451,7 +451,6 @@ static int __init topology_init(void)
} }
set_topology_timer(); set_topology_timer();
out: out:
update_cpu_masks();
return device_create_file(cpu_subsys.dev_root, &dev_attr_dispatching); return device_create_file(cpu_subsys.dev_root, &dev_attr_dispatching);
} }
device_initcall(topology_init); device_initcall(topology_init);

View file

@ -13,6 +13,7 @@
#include <linux/kvm.h> #include <linux/kvm.h>
#include <linux/kvm_host.h> #include <linux/kvm_host.h>
#include <asm/pgalloc.h>
#include <asm/virtio-ccw.h> #include <asm/virtio-ccw.h>
#include "kvm-s390.h" #include "kvm-s390.h"
#include "trace.h" #include "trace.h"
@ -86,9 +87,11 @@ static int __diag_ipl_functions(struct kvm_vcpu *vcpu)
switch (subcode) { switch (subcode) {
case 3: case 3:
vcpu->run->s390_reset_flags = KVM_S390_RESET_CLEAR; vcpu->run->s390_reset_flags = KVM_S390_RESET_CLEAR;
page_table_reset_pgste(current->mm, 0, TASK_SIZE);
break; break;
case 4: case 4:
vcpu->run->s390_reset_flags = 0; vcpu->run->s390_reset_flags = 0;
page_table_reset_pgste(current->mm, 0, TASK_SIZE);
break; break;
default: default:
return -EOPNOTSUPP; return -EOPNOTSUPP;

View file

@ -68,6 +68,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
{ "instruction_storage_key", VCPU_STAT(instruction_storage_key) }, { "instruction_storage_key", VCPU_STAT(instruction_storage_key) },
{ "instruction_stsch", VCPU_STAT(instruction_stsch) }, { "instruction_stsch", VCPU_STAT(instruction_stsch) },
{ "instruction_chsc", VCPU_STAT(instruction_chsc) }, { "instruction_chsc", VCPU_STAT(instruction_chsc) },
{ "instruction_essa", VCPU_STAT(instruction_essa) },
{ "instruction_stsi", VCPU_STAT(instruction_stsi) }, { "instruction_stsi", VCPU_STAT(instruction_stsi) },
{ "instruction_stfl", VCPU_STAT(instruction_stfl) }, { "instruction_stfl", VCPU_STAT(instruction_stfl) },
{ "instruction_tprot", VCPU_STAT(instruction_tprot) }, { "instruction_tprot", VCPU_STAT(instruction_tprot) },
@ -283,7 +284,11 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
if (kvm_is_ucontrol(vcpu->kvm)) if (kvm_is_ucontrol(vcpu->kvm))
gmap_free(vcpu->arch.gmap); gmap_free(vcpu->arch.gmap);
if (vcpu->arch.sie_block->cbrlo)
__free_page(__pfn_to_page(
vcpu->arch.sie_block->cbrlo >> PAGE_SHIFT));
free_page((unsigned long)(vcpu->arch.sie_block)); free_page((unsigned long)(vcpu->arch.sie_block));
kvm_vcpu_uninit(vcpu); kvm_vcpu_uninit(vcpu);
kmem_cache_free(kvm_vcpu_cache, vcpu); kmem_cache_free(kvm_vcpu_cache, vcpu);
} }
@ -390,6 +395,8 @@ int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
{ {
struct page *cbrl;
atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH | atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH |
CPUSTAT_SM | CPUSTAT_SM |
CPUSTAT_STOPPED | CPUSTAT_STOPPED |
@ -401,6 +408,14 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
vcpu->arch.sie_block->ecb2 = 8; vcpu->arch.sie_block->ecb2 = 8;
vcpu->arch.sie_block->eca = 0xC1002001U; vcpu->arch.sie_block->eca = 0xC1002001U;
vcpu->arch.sie_block->fac = (int) (long) vfacilities; vcpu->arch.sie_block->fac = (int) (long) vfacilities;
if (kvm_enabled_cmma()) {
cbrl = alloc_page(GFP_KERNEL | __GFP_ZERO);
if (cbrl) {
vcpu->arch.sie_block->ecb2 |= 0x80;
vcpu->arch.sie_block->ecb2 &= ~0x08;
vcpu->arch.sie_block->cbrlo = page_to_phys(cbrl);
}
}
hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet, tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
(unsigned long) vcpu); (unsigned long) vcpu);
@ -761,6 +776,16 @@ static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason)
return rc; return rc;
} }
bool kvm_enabled_cmma(void)
{
if (!MACHINE_IS_LPAR)
return false;
/* only enable for z10 and later */
if (!MACHINE_HAS_EDAT1)
return false;
return true;
}
static int __vcpu_run(struct kvm_vcpu *vcpu) static int __vcpu_run(struct kvm_vcpu *vcpu)
{ {
int rc, exit_reason; int rc, exit_reason;

View file

@ -156,6 +156,8 @@ void s390_vcpu_block(struct kvm_vcpu *vcpu);
void s390_vcpu_unblock(struct kvm_vcpu *vcpu); void s390_vcpu_unblock(struct kvm_vcpu *vcpu);
void exit_sie(struct kvm_vcpu *vcpu); void exit_sie(struct kvm_vcpu *vcpu);
void exit_sie_sync(struct kvm_vcpu *vcpu); void exit_sie_sync(struct kvm_vcpu *vcpu);
/* are we going to support cmma? */
bool kvm_enabled_cmma(void);
/* implemented in diag.c */ /* implemented in diag.c */
int kvm_s390_handle_diag(struct kvm_vcpu *vcpu); int kvm_s390_handle_diag(struct kvm_vcpu *vcpu);

View file

@ -636,8 +636,49 @@ static int handle_pfmf(struct kvm_vcpu *vcpu)
return 0; return 0;
} }
static int handle_essa(struct kvm_vcpu *vcpu)
{
/* entries expected to be 1FF */
int entries = (vcpu->arch.sie_block->cbrlo & ~PAGE_MASK) >> 3;
unsigned long *cbrlo, cbrle;
struct gmap *gmap;
int i;
VCPU_EVENT(vcpu, 5, "cmma release %d pages", entries);
gmap = vcpu->arch.gmap;
vcpu->stat.instruction_essa++;
if (!kvm_enabled_cmma() || !vcpu->arch.sie_block->cbrlo)
return kvm_s390_inject_program_int(vcpu, PGM_OPERATION);
if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
if (((vcpu->arch.sie_block->ipb & 0xf0000000) >> 28) > 6)
return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
/* Rewind PSW to repeat the ESSA instruction */
vcpu->arch.sie_block->gpsw.addr =
__rewind_psw(vcpu->arch.sie_block->gpsw, 4);
vcpu->arch.sie_block->cbrlo &= PAGE_MASK; /* reset nceo */
cbrlo = phys_to_virt(vcpu->arch.sie_block->cbrlo);
down_read(&gmap->mm->mmap_sem);
for (i = 0; i < entries; ++i) {
cbrle = cbrlo[i];
if (unlikely(cbrle & ~PAGE_MASK || cbrle < 2 * PAGE_SIZE))
/* invalid entry */
break;
/* try to free backing */
__gmap_zap(cbrle, gmap);
}
up_read(&gmap->mm->mmap_sem);
if (i < entries)
return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
return 0;
}
static const intercept_handler_t b9_handlers[256] = { static const intercept_handler_t b9_handlers[256] = {
[0x8d] = handle_epsw, [0x8d] = handle_epsw,
[0xab] = handle_essa,
[0xaf] = handle_pfmf, [0xaf] = handle_pfmf,
}; };

View file

@ -2,8 +2,7 @@
# Makefile for s390-specific library files.. # Makefile for s390-specific library files..
# #
lib-y += delay.o string.o uaccess_pt.o find.o lib-y += delay.o string.o uaccess_pt.o uaccess_mvcos.o find.o
obj-$(CONFIG_32BIT) += div64.o qrnnd.o ucmpdi2.o mem32.o obj-$(CONFIG_32BIT) += div64.o qrnnd.o ucmpdi2.o mem32.o
obj-$(CONFIG_64BIT) += mem64.o obj-$(CONFIG_64BIT) += mem64.o
lib-$(CONFIG_64BIT) += uaccess_mvcos.o
lib-$(CONFIG_SMP) += spinlock.o lib-$(CONFIG_SMP) += spinlock.o

View file

@ -4,7 +4,7 @@
* On s390x the bits are numbered: * On s390x the bits are numbered:
* |0..............63|64............127|128...........191|192...........255| * |0..............63|64............127|128...........191|192...........255|
* and on s390: * and on s390:
* |0.....31|31....63|64....95|96...127|128..159|160..191|192..223|224..255| * |0.....31|32....63|64....95|96...127|128..159|160..191|192..223|224..255|
* *
* The reason for this bit numbering is the fact that the hardware sets bits * The reason for this bit numbering is the fact that the hardware sets bits
* in a bitmap starting at bit 0 (MSB) and we don't want to scan the bitmap * in a bitmap starting at bit 0 (MSB) and we don't want to scan the bitmap

View file

@ -6,7 +6,11 @@
#ifndef __ARCH_S390_LIB_UACCESS_H #ifndef __ARCH_S390_LIB_UACCESS_H
#define __ARCH_S390_LIB_UACCESS_H #define __ARCH_S390_LIB_UACCESS_H
extern int futex_atomic_op_pt(int, u32 __user *, int, int *); unsigned long copy_from_user_pt(void *to, const void __user *from, unsigned long n);
extern int futex_atomic_cmpxchg_pt(u32 *, u32 __user *, u32, u32); unsigned long copy_to_user_pt(void __user *to, const void *from, unsigned long n);
unsigned long copy_in_user_pt(void __user *to, const void __user *from, unsigned long n);
unsigned long clear_user_pt(void __user *to, unsigned long n);
unsigned long strnlen_user_pt(const char __user *src, unsigned long count);
long strncpy_from_user_pt(char *dst, const char __user *src, long count);
#endif /* __ARCH_S390_LIB_UACCESS_H */ #endif /* __ARCH_S390_LIB_UACCESS_H */

View file

@ -6,8 +6,11 @@
* Gerald Schaefer (gerald.schaefer@de.ibm.com) * Gerald Schaefer (gerald.schaefer@de.ibm.com)
*/ */
#include <linux/jump_label.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/init.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <asm/facility.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/futex.h> #include <asm/futex.h>
#include "uaccess.h" #include "uaccess.h"
@ -26,7 +29,10 @@
#define SLR "slgr" #define SLR "slgr"
#endif #endif
static size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x) static struct static_key have_mvcos = STATIC_KEY_INIT_TRUE;
static inline unsigned long copy_from_user_mvcos(void *x, const void __user *ptr,
unsigned long size)
{ {
register unsigned long reg0 asm("0") = 0x81UL; register unsigned long reg0 asm("0") = 0x81UL;
unsigned long tmp1, tmp2; unsigned long tmp1, tmp2;
@ -65,7 +71,16 @@ static size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x)
return size; return size;
} }
static size_t copy_to_user_mvcos(size_t size, void __user *ptr, const void *x) unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n)
{
if (static_key_true(&have_mvcos))
return copy_from_user_mvcos(to, from, n);
return copy_from_user_pt(to, from, n);
}
EXPORT_SYMBOL(__copy_from_user);
static inline unsigned long copy_to_user_mvcos(void __user *ptr, const void *x,
unsigned long size)
{ {
register unsigned long reg0 asm("0") = 0x810000UL; register unsigned long reg0 asm("0") = 0x810000UL;
unsigned long tmp1, tmp2; unsigned long tmp1, tmp2;
@ -94,8 +109,16 @@ static size_t copy_to_user_mvcos(size_t size, void __user *ptr, const void *x)
return size; return size;
} }
static size_t copy_in_user_mvcos(size_t size, void __user *to, unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n)
const void __user *from) {
if (static_key_true(&have_mvcos))
return copy_to_user_mvcos(to, from, n);
return copy_to_user_pt(to, from, n);
}
EXPORT_SYMBOL(__copy_to_user);
static inline unsigned long copy_in_user_mvcos(void __user *to, const void __user *from,
unsigned long size)
{ {
register unsigned long reg0 asm("0") = 0x810081UL; register unsigned long reg0 asm("0") = 0x810081UL;
unsigned long tmp1, tmp2; unsigned long tmp1, tmp2;
@ -117,7 +140,15 @@ static size_t copy_in_user_mvcos(size_t size, void __user *to,
return size; return size;
} }
static size_t clear_user_mvcos(size_t size, void __user *to) unsigned long __copy_in_user(void __user *to, const void __user *from, unsigned long n)
{
if (static_key_true(&have_mvcos))
return copy_in_user_mvcos(to, from, n);
return copy_in_user_pt(to, from, n);
}
EXPORT_SYMBOL(__copy_in_user);
static inline unsigned long clear_user_mvcos(void __user *to, unsigned long size)
{ {
register unsigned long reg0 asm("0") = 0x810000UL; register unsigned long reg0 asm("0") = 0x810000UL;
unsigned long tmp1, tmp2; unsigned long tmp1, tmp2;
@ -145,17 +176,26 @@ static size_t clear_user_mvcos(size_t size, void __user *to)
return size; return size;
} }
static size_t strnlen_user_mvcos(size_t count, const char __user *src) unsigned long __clear_user(void __user *to, unsigned long size)
{ {
size_t done, len, offset, len_str; if (static_key_true(&have_mvcos))
return clear_user_mvcos(to, size);
return clear_user_pt(to, size);
}
EXPORT_SYMBOL(__clear_user);
static inline unsigned long strnlen_user_mvcos(const char __user *src,
unsigned long count)
{
unsigned long done, len, offset, len_str;
char buf[256]; char buf[256];
done = 0; done = 0;
do { do {
offset = (size_t)src & ~PAGE_MASK; offset = (unsigned long)src & ~PAGE_MASK;
len = min(256UL, PAGE_SIZE - offset); len = min(256UL, PAGE_SIZE - offset);
len = min(count - done, len); len = min(count - done, len);
if (copy_from_user_mvcos(len, src, buf)) if (copy_from_user_mvcos(buf, src, len))
return 0; return 0;
len_str = strnlen(buf, len); len_str = strnlen(buf, len);
done += len_str; done += len_str;
@ -164,18 +204,26 @@ static size_t strnlen_user_mvcos(size_t count, const char __user *src)
return done + 1; return done + 1;
} }
static size_t strncpy_from_user_mvcos(size_t count, const char __user *src, unsigned long __strnlen_user(const char __user *src, unsigned long count)
char *dst)
{ {
size_t done, len, offset, len_str; if (static_key_true(&have_mvcos))
return strnlen_user_mvcos(src, count);
return strnlen_user_pt(src, count);
}
EXPORT_SYMBOL(__strnlen_user);
if (unlikely(!count)) static inline long strncpy_from_user_mvcos(char *dst, const char __user *src,
long count)
{
unsigned long done, len, offset, len_str;
if (unlikely(count <= 0))
return 0; return 0;
done = 0; done = 0;
do { do {
offset = (size_t)src & ~PAGE_MASK; offset = (unsigned long)src & ~PAGE_MASK;
len = min(count - done, PAGE_SIZE - offset); len = min(count - done, PAGE_SIZE - offset);
if (copy_from_user_mvcos(len, src, dst)) if (copy_from_user_mvcos(dst, src, len))
return -EFAULT; return -EFAULT;
len_str = strnlen(dst, len); len_str = strnlen(dst, len);
done += len_str; done += len_str;
@ -185,13 +233,31 @@ static size_t strncpy_from_user_mvcos(size_t count, const char __user *src,
return done; return done;
} }
struct uaccess_ops uaccess_mvcos = { long __strncpy_from_user(char *dst, const char __user *src, long count)
.copy_from_user = copy_from_user_mvcos, {
.copy_to_user = copy_to_user_mvcos, if (static_key_true(&have_mvcos))
.copy_in_user = copy_in_user_mvcos, return strncpy_from_user_mvcos(dst, src, count);
.clear_user = clear_user_mvcos, return strncpy_from_user_pt(dst, src, count);
.strnlen_user = strnlen_user_mvcos, }
.strncpy_from_user = strncpy_from_user_mvcos, EXPORT_SYMBOL(__strncpy_from_user);
.futex_atomic_op = futex_atomic_op_pt,
.futex_atomic_cmpxchg = futex_atomic_cmpxchg_pt, /*
}; * The uaccess page tabe walk variant can be enforced with the "uaccesspt"
* kernel parameter. This is mainly for debugging purposes.
*/
static int force_uaccess_pt __initdata;
static int __init parse_uaccess_pt(char *__unused)
{
force_uaccess_pt = 1;
return 0;
}
early_param("uaccesspt", parse_uaccess_pt);
static int __init uaccess_init(void)
{
if (IS_ENABLED(CONFIG_32BIT) || force_uaccess_pt || !test_facility(27))
static_key_slow_dec(&have_mvcos);
return 0;
}
early_initcall(uaccess_init);

View file

@ -22,7 +22,7 @@
#define SLR "slgr" #define SLR "slgr"
#endif #endif
static size_t strnlen_kernel(size_t count, const char __user *src) static unsigned long strnlen_kernel(const char __user *src, unsigned long count)
{ {
register unsigned long reg0 asm("0") = 0UL; register unsigned long reg0 asm("0") = 0UL;
unsigned long tmp1, tmp2; unsigned long tmp1, tmp2;
@ -42,8 +42,8 @@ static size_t strnlen_kernel(size_t count, const char __user *src)
return count; return count;
} }
static size_t copy_in_kernel(size_t count, void __user *to, static unsigned long copy_in_kernel(void __user *to, const void __user *from,
const void __user *from) unsigned long count)
{ {
unsigned long tmp1; unsigned long tmp1;
@ -146,8 +146,8 @@ static unsigned long follow_table(struct mm_struct *mm,
#endif /* CONFIG_64BIT */ #endif /* CONFIG_64BIT */
static __always_inline size_t __user_copy_pt(unsigned long uaddr, void *kptr, static inline unsigned long __user_copy_pt(unsigned long uaddr, void *kptr,
size_t n, int write_user) unsigned long n, int write_user)
{ {
struct mm_struct *mm = current->mm; struct mm_struct *mm = current->mm;
unsigned long offset, done, size, kaddr; unsigned long offset, done, size, kaddr;
@ -189,8 +189,7 @@ fault:
* Do DAT for user address by page table walk, return kernel address. * Do DAT for user address by page table walk, return kernel address.
* This function needs to be called with current->mm->page_table_lock held. * This function needs to be called with current->mm->page_table_lock held.
*/ */
static __always_inline unsigned long __dat_user_addr(unsigned long uaddr, static inline unsigned long __dat_user_addr(unsigned long uaddr, int write)
int write)
{ {
struct mm_struct *mm = current->mm; struct mm_struct *mm = current->mm;
unsigned long kaddr; unsigned long kaddr;
@ -211,29 +210,29 @@ fault:
return 0; return 0;
} }
static size_t copy_from_user_pt(size_t n, const void __user *from, void *to) unsigned long copy_from_user_pt(void *to, const void __user *from, unsigned long n)
{ {
size_t rc; unsigned long rc;
if (segment_eq(get_fs(), KERNEL_DS)) if (segment_eq(get_fs(), KERNEL_DS))
return copy_in_kernel(n, (void __user *) to, from); return copy_in_kernel((void __user *) to, from, n);
rc = __user_copy_pt((unsigned long) from, to, n, 0); rc = __user_copy_pt((unsigned long) from, to, n, 0);
if (unlikely(rc)) if (unlikely(rc))
memset(to + n - rc, 0, rc); memset(to + n - rc, 0, rc);
return rc; return rc;
} }
static size_t copy_to_user_pt(size_t n, void __user *to, const void *from) unsigned long copy_to_user_pt(void __user *to, const void *from, unsigned long n)
{ {
if (segment_eq(get_fs(), KERNEL_DS)) if (segment_eq(get_fs(), KERNEL_DS))
return copy_in_kernel(n, to, (void __user *) from); return copy_in_kernel(to, (void __user *) from, n);
return __user_copy_pt((unsigned long) to, (void *) from, n, 1); return __user_copy_pt((unsigned long) to, (void *) from, n, 1);
} }
static size_t clear_user_pt(size_t n, void __user *to) unsigned long clear_user_pt(void __user *to, unsigned long n)
{ {
void *zpage = (void *) empty_zero_page; void *zpage = (void *) empty_zero_page;
long done, size, ret; unsigned long done, size, ret;
done = 0; done = 0;
do { do {
@ -242,7 +241,7 @@ static size_t clear_user_pt(size_t n, void __user *to)
else else
size = n - done; size = n - done;
if (segment_eq(get_fs(), KERNEL_DS)) if (segment_eq(get_fs(), KERNEL_DS))
ret = copy_in_kernel(n, to, (void __user *) zpage); ret = copy_in_kernel(to, (void __user *) zpage, n);
else else
ret = __user_copy_pt((unsigned long) to, zpage, size, 1); ret = __user_copy_pt((unsigned long) to, zpage, size, 1);
done += size; done += size;
@ -253,17 +252,17 @@ static size_t clear_user_pt(size_t n, void __user *to)
return 0; return 0;
} }
static size_t strnlen_user_pt(size_t count, const char __user *src) unsigned long strnlen_user_pt(const char __user *src, unsigned long count)
{ {
unsigned long uaddr = (unsigned long) src; unsigned long uaddr = (unsigned long) src;
struct mm_struct *mm = current->mm; struct mm_struct *mm = current->mm;
unsigned long offset, done, len, kaddr; unsigned long offset, done, len, kaddr;
size_t len_str; unsigned long len_str;
if (unlikely(!count)) if (unlikely(!count))
return 0; return 0;
if (segment_eq(get_fs(), KERNEL_DS)) if (segment_eq(get_fs(), KERNEL_DS))
return strnlen_kernel(count, src); return strnlen_kernel(src, count);
if (!mm) if (!mm)
return 0; return 0;
done = 0; done = 0;
@ -289,19 +288,18 @@ fault:
goto retry; goto retry;
} }
static size_t strncpy_from_user_pt(size_t count, const char __user *src, long strncpy_from_user_pt(char *dst, const char __user *src, long count)
char *dst)
{ {
size_t done, len, offset, len_str; unsigned long done, len, offset, len_str;
if (unlikely(!count)) if (unlikely(count <= 0))
return 0; return 0;
done = 0; done = 0;
do { do {
offset = (size_t)src & ~PAGE_MASK; offset = (unsigned long)src & ~PAGE_MASK;
len = min(count - done, PAGE_SIZE - offset); len = min(count - done, PAGE_SIZE - offset);
if (segment_eq(get_fs(), KERNEL_DS)) { if (segment_eq(get_fs(), KERNEL_DS)) {
if (copy_in_kernel(len, (void __user *) dst, src)) if (copy_in_kernel((void __user *) dst, src, len))
return -EFAULT; return -EFAULT;
} else { } else {
if (__user_copy_pt((unsigned long) src, dst, len, 0)) if (__user_copy_pt((unsigned long) src, dst, len, 0))
@ -315,8 +313,8 @@ static size_t strncpy_from_user_pt(size_t count, const char __user *src,
return done; return done;
} }
static size_t copy_in_user_pt(size_t n, void __user *to, unsigned long copy_in_user_pt(void __user *to, const void __user *from,
const void __user *from) unsigned long n)
{ {
struct mm_struct *mm = current->mm; struct mm_struct *mm = current->mm;
unsigned long offset_max, uaddr, done, size, error_code; unsigned long offset_max, uaddr, done, size, error_code;
@ -326,7 +324,7 @@ static size_t copy_in_user_pt(size_t n, void __user *to,
int write_user; int write_user;
if (segment_eq(get_fs(), KERNEL_DS)) if (segment_eq(get_fs(), KERNEL_DS))
return copy_in_kernel(n, to, from); return copy_in_kernel(to, from, n);
if (!mm) if (!mm)
return n; return n;
done = 0; done = 0;
@ -411,7 +409,7 @@ static int __futex_atomic_op_pt(int op, u32 __user *uaddr, int oparg, int *old)
return ret; return ret;
} }
int futex_atomic_op_pt(int op, u32 __user *uaddr, int oparg, int *old) int __futex_atomic_op_inuser(int op, u32 __user *uaddr, int oparg, int *old)
{ {
int ret; int ret;
@ -449,8 +447,8 @@ static int __futex_atomic_cmpxchg_pt(u32 *uval, u32 __user *uaddr,
return ret; return ret;
} }
int futex_atomic_cmpxchg_pt(u32 *uval, u32 __user *uaddr, int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
u32 oldval, u32 newval) u32 oldval, u32 newval)
{ {
int ret; int ret;
@ -471,14 +469,3 @@ int futex_atomic_cmpxchg_pt(u32 *uval, u32 __user *uaddr,
put_page(virt_to_page(uaddr)); put_page(virt_to_page(uaddr));
return ret; return ret;
} }
struct uaccess_ops uaccess_pt = {
.copy_from_user = copy_from_user_pt,
.copy_to_user = copy_to_user_pt,
.copy_in_user = copy_in_user_pt,
.clear_user = clear_user_pt,
.strnlen_user = strnlen_user_pt,
.strncpy_from_user = strncpy_from_user_pt,
.futex_atomic_op = futex_atomic_op_pt,
.futex_atomic_cmpxchg = futex_atomic_cmpxchg_pt,
};

View file

@ -128,7 +128,7 @@ void memcpy_absolute(void *dest, void *src, size_t count)
/* /*
* Copy memory from kernel (real) to user (virtual) * Copy memory from kernel (real) to user (virtual)
*/ */
int copy_to_user_real(void __user *dest, void *src, size_t count) int copy_to_user_real(void __user *dest, void *src, unsigned long count)
{ {
int offs = 0, size, rc; int offs = 0, size, rc;
char *buf; char *buf;
@ -151,32 +151,6 @@ out:
return rc; return rc;
} }
/*
* Copy memory from user (virtual) to kernel (real)
*/
int copy_from_user_real(void *dest, void __user *src, size_t count)
{
int offs = 0, size, rc;
char *buf;
buf = (char *) __get_free_page(GFP_KERNEL);
if (!buf)
return -ENOMEM;
rc = -EFAULT;
while (offs < count) {
size = min(PAGE_SIZE, count - offs);
if (copy_from_user(buf, src + offs, size))
goto out;
if (memcpy_real(dest + offs, buf, size))
goto out;
offs += size;
}
rc = 0;
out:
free_page((unsigned long) buf);
return rc;
}
/* /*
* Check if physical address is within prefix or zero page * Check if physical address is within prefix or zero page
*/ */

View file

@ -17,6 +17,7 @@
#include <linux/quicklist.h> #include <linux/quicklist.h>
#include <linux/rcupdate.h> #include <linux/rcupdate.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/swapops.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
@ -594,6 +595,82 @@ unsigned long gmap_fault(unsigned long address, struct gmap *gmap)
} }
EXPORT_SYMBOL_GPL(gmap_fault); EXPORT_SYMBOL_GPL(gmap_fault);
static void gmap_zap_swap_entry(swp_entry_t entry, struct mm_struct *mm)
{
if (!non_swap_entry(entry))
dec_mm_counter(mm, MM_SWAPENTS);
else if (is_migration_entry(entry)) {
struct page *page = migration_entry_to_page(entry);
if (PageAnon(page))
dec_mm_counter(mm, MM_ANONPAGES);
else
dec_mm_counter(mm, MM_FILEPAGES);
}
free_swap_and_cache(entry);
}
/**
* The mm->mmap_sem lock must be held
*/
static void gmap_zap_unused(struct mm_struct *mm, unsigned long address)
{
unsigned long ptev, pgstev;
spinlock_t *ptl;
pgste_t pgste;
pte_t *ptep, pte;
ptep = get_locked_pte(mm, address, &ptl);
if (unlikely(!ptep))
return;
pte = *ptep;
if (!pte_swap(pte))
goto out_pte;
/* Zap unused and logically-zero pages */
pgste = pgste_get_lock(ptep);
pgstev = pgste_val(pgste);
ptev = pte_val(pte);
if (((pgstev & _PGSTE_GPS_USAGE_MASK) == _PGSTE_GPS_USAGE_UNUSED) ||
((pgstev & _PGSTE_GPS_ZERO) && (ptev & _PAGE_INVALID))) {
gmap_zap_swap_entry(pte_to_swp_entry(pte), mm);
pte_clear(mm, address, ptep);
}
pgste_set_unlock(ptep, pgste);
out_pte:
pte_unmap_unlock(*ptep, ptl);
}
/*
* this function is assumed to be called with mmap_sem held
*/
void __gmap_zap(unsigned long address, struct gmap *gmap)
{
unsigned long *table, *segment_ptr;
unsigned long segment, pgstev, ptev;
struct gmap_pgtable *mp;
struct page *page;
segment_ptr = gmap_table_walk(address, gmap);
if (IS_ERR(segment_ptr))
return;
segment = *segment_ptr;
if (segment & _SEGMENT_ENTRY_INVALID)
return;
page = pfn_to_page(segment >> PAGE_SHIFT);
mp = (struct gmap_pgtable *) page->index;
address = mp->vmaddr | (address & ~PMD_MASK);
/* Page table is present */
table = (unsigned long *)(segment & _SEGMENT_ENTRY_ORIGIN);
table = table + ((address >> 12) & 0xff);
pgstev = table[PTRS_PER_PTE];
ptev = table[0];
/* quick check, checked again with locks held */
if (((pgstev & _PGSTE_GPS_USAGE_MASK) == _PGSTE_GPS_USAGE_UNUSED) ||
((pgstev & _PGSTE_GPS_ZERO) && (ptev & _PAGE_INVALID)))
gmap_zap_unused(gmap->mm, address);
}
EXPORT_SYMBOL_GPL(__gmap_zap);
void gmap_discard(unsigned long from, unsigned long to, struct gmap *gmap) void gmap_discard(unsigned long from, unsigned long to, struct gmap *gmap)
{ {
@ -671,7 +748,7 @@ EXPORT_SYMBOL_GPL(gmap_unregister_ipte_notifier);
/** /**
* gmap_ipte_notify - mark a range of ptes for invalidation notification * gmap_ipte_notify - mark a range of ptes for invalidation notification
* @gmap: pointer to guest mapping meta data structure * @gmap: pointer to guest mapping meta data structure
* @address: virtual address in the guest address space * @start: virtual address in the guest address space
* @len: size of area * @len: size of area
* *
* Returns 0 if for each page in the given range a gmap mapping exists and * Returns 0 if for each page in the given range a gmap mapping exists and
@ -725,13 +802,12 @@ EXPORT_SYMBOL_GPL(gmap_ipte_notify);
/** /**
* gmap_do_ipte_notify - call all invalidation callbacks for a specific pte. * gmap_do_ipte_notify - call all invalidation callbacks for a specific pte.
* @mm: pointer to the process mm_struct * @mm: pointer to the process mm_struct
* @addr: virtual address in the process address space
* @pte: pointer to the page table entry * @pte: pointer to the page table entry
* *
* This function is assumed to be called with the page table lock held * This function is assumed to be called with the page table lock held
* for the pte to notify. * for the pte to notify.
*/ */
void gmap_do_ipte_notify(struct mm_struct *mm, unsigned long addr, pte_t *pte) void gmap_do_ipte_notify(struct mm_struct *mm, pte_t *pte)
{ {
unsigned long segment_offset; unsigned long segment_offset;
struct gmap_notifier *nb; struct gmap_notifier *nb;
@ -802,6 +878,78 @@ static inline void page_table_free_pgste(unsigned long *table)
__free_page(page); __free_page(page);
} }
static inline unsigned long page_table_reset_pte(struct mm_struct *mm,
pmd_t *pmd, unsigned long addr, unsigned long end)
{
pte_t *start_pte, *pte;
spinlock_t *ptl;
pgste_t pgste;
start_pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
pte = start_pte;
do {
pgste = pgste_get_lock(pte);
pgste_val(pgste) &= ~_PGSTE_GPS_USAGE_MASK;
pgste_set_unlock(pte, pgste);
} while (pte++, addr += PAGE_SIZE, addr != end);
pte_unmap_unlock(start_pte, ptl);
return addr;
}
static inline unsigned long page_table_reset_pmd(struct mm_struct *mm,
pud_t *pud, unsigned long addr, unsigned long end)
{
unsigned long next;
pmd_t *pmd;
pmd = pmd_offset(pud, addr);
do {
next = pmd_addr_end(addr, end);
if (pmd_none_or_clear_bad(pmd))
continue;
next = page_table_reset_pte(mm, pmd, addr, next);
} while (pmd++, addr = next, addr != end);
return addr;
}
static inline unsigned long page_table_reset_pud(struct mm_struct *mm,
pgd_t *pgd, unsigned long addr, unsigned long end)
{
unsigned long next;
pud_t *pud;
pud = pud_offset(pgd, addr);
do {
next = pud_addr_end(addr, end);
if (pud_none_or_clear_bad(pud))
continue;
next = page_table_reset_pmd(mm, pud, addr, next);
} while (pud++, addr = next, addr != end);
return addr;
}
void page_table_reset_pgste(struct mm_struct *mm,
unsigned long start, unsigned long end)
{
unsigned long addr, next;
pgd_t *pgd;
addr = start;
down_read(&mm->mmap_sem);
pgd = pgd_offset(mm, addr);
do {
next = pgd_addr_end(addr, end);
if (pgd_none_or_clear_bad(pgd))
continue;
next = page_table_reset_pud(mm, pgd, addr, next);
} while (pgd++, addr = next, addr != end);
up_read(&mm->mmap_sem);
}
EXPORT_SYMBOL(page_table_reset_pgste);
int set_guest_storage_key(struct mm_struct *mm, unsigned long addr, int set_guest_storage_key(struct mm_struct *mm, unsigned long addr,
unsigned long key, bool nq) unsigned long key, bool nq)
{ {
@ -1248,7 +1396,7 @@ void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
{ {
struct list_head *lh = (struct list_head *) pgtable; struct list_head *lh = (struct list_head *) pgtable;
assert_spin_locked(&mm->page_table_lock); assert_spin_locked(pmd_lockptr(mm, pmdp));
/* FIFO */ /* FIFO */
if (!pmd_huge_pte(mm, pmdp)) if (!pmd_huge_pte(mm, pmdp))
@ -1264,7 +1412,7 @@ pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp)
pgtable_t pgtable; pgtable_t pgtable;
pte_t *ptep; pte_t *ptep;
assert_spin_locked(&mm->page_table_lock); assert_spin_locked(pmd_lockptr(mm, pmdp));
/* FIFO */ /* FIFO */
pgtable = pmd_huge_pte(mm, pmdp); pgtable = pmd_huge_pte(mm, pmdp);

View file

@ -139,7 +139,7 @@ void zpci_debug_exit_device(struct zpci_dev *zdev)
int __init zpci_debug_init(void) int __init zpci_debug_init(void)
{ {
/* event trace buffer */ /* event trace buffer */
pci_debug_msg_id = debug_register("pci_msg", 16, 1, 16 * sizeof(long)); pci_debug_msg_id = debug_register("pci_msg", 8, 1, 8 * sizeof(long));
if (!pci_debug_msg_id) if (!pci_debug_msg_id)
return -EINVAL; return -EINVAL;
debug_register_view(pci_debug_msg_id, &debug_sprintf_view); debug_register_view(pci_debug_msg_id, &debug_sprintf_view);

View file

@ -922,7 +922,7 @@ static int __init con3215_init(void)
raw3215_freelist = req; raw3215_freelist = req;
} }
cdev = ccw_device_probe_console(); cdev = ccw_device_create_console(&raw3215_ccw_driver);
if (IS_ERR(cdev)) if (IS_ERR(cdev))
return -ENODEV; return -ENODEV;
@ -932,6 +932,12 @@ static int __init con3215_init(void)
cdev->handler = raw3215_irq; cdev->handler = raw3215_irq;
raw->flags |= RAW3215_FIXED; raw->flags |= RAW3215_FIXED;
if (ccw_device_enable_console(cdev)) {
ccw_device_destroy_console(cdev);
raw3215_free_info(raw);
raw3215[0] = NULL;
return -ENODEV;
}
/* Request the console irq */ /* Request the console irq */
if (raw3215_startup(raw) != 0) { if (raw3215_startup(raw) != 0) {

View file

@ -7,6 +7,7 @@
* Copyright IBM Corp. 2003, 2009 * Copyright IBM Corp. 2003, 2009
*/ */
#include <linux/module.h>
#include <linux/console.h> #include <linux/console.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
@ -30,6 +31,9 @@
static struct raw3270_fn con3270_fn; static struct raw3270_fn con3270_fn;
static bool auto_update = 1;
module_param(auto_update, bool, 0);
/* /*
* Main 3270 console view data structure. * Main 3270 console view data structure.
*/ */
@ -204,6 +208,8 @@ con3270_update(struct con3270 *cp)
struct string *s, *n; struct string *s, *n;
int rc; int rc;
if (!auto_update && !raw3270_view_active(&cp->view))
return;
if (cp->view.dev) if (cp->view.dev)
raw3270_activate_view(&cp->view); raw3270_activate_view(&cp->view);
@ -529,6 +535,7 @@ con3270_flush(void)
if (!cp->view.dev) if (!cp->view.dev)
return; return;
raw3270_pm_unfreeze(&cp->view); raw3270_pm_unfreeze(&cp->view);
raw3270_activate_view(&cp->view);
spin_lock_irqsave(&cp->view.lock, flags); spin_lock_irqsave(&cp->view.lock, flags);
con3270_wait_write(cp); con3270_wait_write(cp);
cp->nr_up = 0; cp->nr_up = 0;
@ -576,7 +583,6 @@ static struct console con3270 = {
static int __init static int __init
con3270_init(void) con3270_init(void)
{ {
struct ccw_device *cdev;
struct raw3270 *rp; struct raw3270 *rp;
void *cbuf; void *cbuf;
int i; int i;
@ -591,10 +597,7 @@ con3270_init(void)
cpcmd("TERM AUTOCR OFF", NULL, 0, NULL); cpcmd("TERM AUTOCR OFF", NULL, 0, NULL);
} }
cdev = ccw_device_probe_console(); rp = raw3270_setup_console();
if (IS_ERR(cdev))
return -ENODEV;
rp = raw3270_setup_console(cdev);
if (IS_ERR(rp)) if (IS_ERR(rp))
return PTR_ERR(rp); return PTR_ERR(rp);

View file

@ -275,6 +275,15 @@ __raw3270_start(struct raw3270 *rp, struct raw3270_view *view,
return 0; return 0;
} }
int
raw3270_view_active(struct raw3270_view *view)
{
struct raw3270 *rp = view->dev;
return rp && rp->view == view &&
!test_bit(RAW3270_FLAGS_FROZEN, &rp->flags);
}
int int
raw3270_start(struct raw3270_view *view, struct raw3270_request *rq) raw3270_start(struct raw3270_view *view, struct raw3270_request *rq)
{ {
@ -776,22 +785,37 @@ raw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp, char *ascebc)
} }
#ifdef CONFIG_TN3270_CONSOLE #ifdef CONFIG_TN3270_CONSOLE
/* Tentative definition - see below for actual definition. */
static struct ccw_driver raw3270_ccw_driver;
/* /*
* Setup 3270 device configured as console. * Setup 3270 device configured as console.
*/ */
struct raw3270 __init *raw3270_setup_console(struct ccw_device *cdev) struct raw3270 __init *raw3270_setup_console(void)
{ {
struct ccw_device *cdev;
unsigned long flags; unsigned long flags;
struct raw3270 *rp; struct raw3270 *rp;
char *ascebc; char *ascebc;
int rc; int rc;
cdev = ccw_device_create_console(&raw3270_ccw_driver);
if (IS_ERR(cdev))
return ERR_CAST(cdev);
rp = kzalloc(sizeof(struct raw3270), GFP_KERNEL | GFP_DMA); rp = kzalloc(sizeof(struct raw3270), GFP_KERNEL | GFP_DMA);
ascebc = kzalloc(256, GFP_KERNEL); ascebc = kzalloc(256, GFP_KERNEL);
rc = raw3270_setup_device(cdev, rp, ascebc); rc = raw3270_setup_device(cdev, rp, ascebc);
if (rc) if (rc)
return ERR_PTR(rc); return ERR_PTR(rc);
set_bit(RAW3270_FLAGS_CONSOLE, &rp->flags); set_bit(RAW3270_FLAGS_CONSOLE, &rp->flags);
rc = ccw_device_enable_console(cdev);
if (rc) {
ccw_device_destroy_console(cdev);
return ERR_PTR(rc);
}
spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags); spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
do { do {
__raw3270_reset_device(rp); __raw3270_reset_device(rp);

View file

@ -173,6 +173,7 @@ int raw3270_start_locked(struct raw3270_view *, struct raw3270_request *);
int raw3270_start_irq(struct raw3270_view *, struct raw3270_request *); int raw3270_start_irq(struct raw3270_view *, struct raw3270_request *);
int raw3270_reset(struct raw3270_view *); int raw3270_reset(struct raw3270_view *);
struct raw3270_view *raw3270_view(struct raw3270_view *); struct raw3270_view *raw3270_view(struct raw3270_view *);
int raw3270_view_active(struct raw3270_view *);
/* Reference count inliner for view structures. */ /* Reference count inliner for view structures. */
static inline void static inline void
@ -190,7 +191,7 @@ raw3270_put_view(struct raw3270_view *view)
wake_up(&raw3270_wait_queue); wake_up(&raw3270_wait_queue);
} }
struct raw3270 *raw3270_setup_console(struct ccw_device *cdev); struct raw3270 *raw3270_setup_console(void);
void raw3270_wait_cons_dev(struct raw3270 *); void raw3270_wait_cons_dev(struct raw3270 *);
/* Notifier for device addition/removal */ /* Notifier for device addition/removal */

View file

@ -20,7 +20,9 @@ struct read_info_sccb {
struct sccb_header header; /* 0-7 */ struct sccb_header header; /* 0-7 */
u16 rnmax; /* 8-9 */ u16 rnmax; /* 8-9 */
u8 rnsize; /* 10 */ u8 rnsize; /* 10 */
u8 _reserved0[24 - 11]; /* 11-15 */ u8 _reserved0[16 - 11]; /* 11-15 */
u16 ncpurl; /* 16-17 */
u8 _reserved7[24 - 18]; /* 18-23 */
u8 loadparm[8]; /* 24-31 */ u8 loadparm[8]; /* 24-31 */
u8 _reserved1[48 - 32]; /* 32-47 */ u8 _reserved1[48 - 32]; /* 32-47 */
u64 facilities; /* 48-55 */ u64 facilities; /* 48-55 */
@ -32,13 +34,16 @@ struct read_info_sccb {
u8 _reserved4[100 - 92]; /* 92-99 */ u8 _reserved4[100 - 92]; /* 92-99 */
u32 rnsize2; /* 100-103 */ u32 rnsize2; /* 100-103 */
u64 rnmax2; /* 104-111 */ u64 rnmax2; /* 104-111 */
u8 _reserved5[4096 - 112]; /* 112-4095 */ u8 _reserved5[120 - 112]; /* 112-119 */
u16 hcpua; /* 120-121 */
u8 _reserved6[4096 - 122]; /* 122-4095 */
} __packed __aligned(PAGE_SIZE); } __packed __aligned(PAGE_SIZE);
static char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE) __initdata; static char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE) __initdata;
static unsigned int sclp_con_has_vt220 __initdata; static unsigned int sclp_con_has_vt220 __initdata;
static unsigned int sclp_con_has_linemode __initdata; static unsigned int sclp_con_has_linemode __initdata;
static unsigned long sclp_hsa_size; static unsigned long sclp_hsa_size;
static unsigned int sclp_max_cpu;
static struct sclp_ipl_info sclp_ipl_info; static struct sclp_ipl_info sclp_ipl_info;
u64 sclp_facilities; u64 sclp_facilities;
@ -102,6 +107,15 @@ static void __init sclp_facilities_detect(struct read_info_sccb *sccb)
sclp_rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; sclp_rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2;
sclp_rzm <<= 20; sclp_rzm <<= 20;
if (!sccb->hcpua) {
if (MACHINE_IS_VM)
sclp_max_cpu = 64;
else
sclp_max_cpu = sccb->ncpurl;
} else {
sclp_max_cpu = sccb->hcpua + 1;
}
/* Save IPL information */ /* Save IPL information */
sclp_ipl_info.is_valid = 1; sclp_ipl_info.is_valid = 1;
if (sccb->flags & 0x2) if (sccb->flags & 0x2)
@ -129,6 +143,11 @@ unsigned long long sclp_get_rzm(void)
return sclp_rzm; return sclp_rzm;
} }
unsigned int sclp_get_max_cpu(void)
{
return sclp_max_cpu;
}
/* /*
* This function will be called after sclp_facilities_detect(), which gets * This function will be called after sclp_facilities_detect(), which gets
* called from early.c code. The sclp_facilities_detect() function retrieves * called from early.c code. The sclp_facilities_detect() function retrieves
@ -184,9 +203,9 @@ static long __init sclp_hsa_size_init(struct sdias_sccb *sccb)
sccb_init_eq_size(sccb); sccb_init_eq_size(sccb);
if (sclp_cmd_early(SCLP_CMDW_WRITE_EVENT_DATA, sccb)) if (sclp_cmd_early(SCLP_CMDW_WRITE_EVENT_DATA, sccb))
return -EIO; return -EIO;
if (sccb->evbuf.blk_cnt != 0) if (sccb->evbuf.blk_cnt == 0)
return (sccb->evbuf.blk_cnt - 1) * PAGE_SIZE; return 0;
return 0; return (sccb->evbuf.blk_cnt - 1) * PAGE_SIZE;
} }
static long __init sclp_hsa_copy_wait(struct sccb_header *sccb) static long __init sclp_hsa_copy_wait(struct sccb_header *sccb)
@ -195,6 +214,8 @@ static long __init sclp_hsa_copy_wait(struct sccb_header *sccb)
sccb->length = PAGE_SIZE; sccb->length = PAGE_SIZE;
if (sclp_cmd_early(SCLP_CMDW_READ_EVENT_DATA, sccb)) if (sclp_cmd_early(SCLP_CMDW_READ_EVENT_DATA, sccb))
return -EIO; return -EIO;
if (((struct sdias_sccb *) sccb)->evbuf.blk_cnt == 0)
return 0;
return (((struct sdias_sccb *) sccb)->evbuf.blk_cnt - 1) * PAGE_SIZE; return (((struct sdias_sccb *) sccb)->evbuf.blk_cnt - 1) * PAGE_SIZE;
} }

View file

@ -186,55 +186,71 @@ void airq_iv_release(struct airq_iv *iv)
EXPORT_SYMBOL(airq_iv_release); EXPORT_SYMBOL(airq_iv_release);
/** /**
* airq_iv_alloc_bit - allocate an irq bit from an interrupt vector * airq_iv_alloc - allocate irq bits from an interrupt vector
* @iv: pointer to an interrupt vector structure * @iv: pointer to an interrupt vector structure
* @num: number of consecutive irq bits to allocate
* *
* Returns the bit number of the allocated irq, or -1UL if no bit * Returns the bit number of the first irq in the allocated block of irqs,
* is available or the AIRQ_IV_ALLOC flag has not been specified * or -1UL if no bit is available or the AIRQ_IV_ALLOC flag has not been
* specified
*/ */
unsigned long airq_iv_alloc_bit(struct airq_iv *iv) unsigned long airq_iv_alloc(struct airq_iv *iv, unsigned long num)
{ {
unsigned long bit; unsigned long bit, i;
if (!iv->avail) if (!iv->avail || num == 0)
return -1UL; return -1UL;
spin_lock(&iv->lock); spin_lock(&iv->lock);
bit = find_first_bit_inv(iv->avail, iv->bits); bit = find_first_bit_inv(iv->avail, iv->bits);
if (bit < iv->bits) { while (bit + num <= iv->bits) {
clear_bit_inv(bit, iv->avail); for (i = 1; i < num; i++)
if (bit >= iv->end) if (!test_bit_inv(bit + i, iv->avail))
iv->end = bit + 1; break;
} else if (i >= num) {
/* Found a suitable block of irqs */
for (i = 0; i < num; i++)
clear_bit_inv(bit + i, iv->avail);
if (bit + num >= iv->end)
iv->end = bit + num + 1;
break;
}
bit = find_next_bit_inv(iv->avail, iv->bits, bit + i + 1);
}
if (bit + num > iv->bits)
bit = -1UL; bit = -1UL;
spin_unlock(&iv->lock); spin_unlock(&iv->lock);
return bit; return bit;
} }
EXPORT_SYMBOL(airq_iv_alloc_bit); EXPORT_SYMBOL(airq_iv_alloc);
/** /**
* airq_iv_free_bit - free an irq bit of an interrupt vector * airq_iv_free - free irq bits of an interrupt vector
* @iv: pointer to interrupt vector structure * @iv: pointer to interrupt vector structure
* @bit: number of the irq bit to free * @bit: number of the first irq bit to free
* @num: number of consecutive irq bits to free
*/ */
void airq_iv_free_bit(struct airq_iv *iv, unsigned long bit) void airq_iv_free(struct airq_iv *iv, unsigned long bit, unsigned long num)
{ {
if (!iv->avail) unsigned long i;
if (!iv->avail || num == 0)
return; return;
spin_lock(&iv->lock); spin_lock(&iv->lock);
/* Clear (possibly left over) interrupt bit */ for (i = 0; i < num; i++) {
clear_bit_inv(bit, iv->vector); /* Clear (possibly left over) interrupt bit */
/* Make the bit position available again */ clear_bit_inv(bit + i, iv->vector);
set_bit_inv(bit, iv->avail); /* Make the bit positions available again */
if (bit == iv->end - 1) { set_bit_inv(bit + i, iv->avail);
}
if (bit + num >= iv->end) {
/* Find new end of bit-field */ /* Find new end of bit-field */
while (--iv->end > 0) while (iv->end > 0 && !test_bit_inv(iv->end - 1, iv->avail))
if (!test_bit_inv(iv->end - 1, iv->avail)) iv->end--;
break;
} }
spin_unlock(&iv->lock); spin_unlock(&iv->lock);
} }
EXPORT_SYMBOL(airq_iv_free_bit); EXPORT_SYMBOL(airq_iv_free);
/** /**
* airq_iv_scan - scan interrupt vector for non-zero bits * airq_iv_scan - scan interrupt vector for non-zero bits

View file

@ -173,8 +173,7 @@ static struct css_driver chsc_subchannel_driver = {
static int __init chsc_init_dbfs(void) static int __init chsc_init_dbfs(void)
{ {
chsc_debug_msg_id = debug_register("chsc_msg", 16, 1, chsc_debug_msg_id = debug_register("chsc_msg", 8, 1, 4 * sizeof(long));
16 * sizeof(long));
if (!chsc_debug_msg_id) if (!chsc_debug_msg_id)
goto out; goto out;
debug_register_view(chsc_debug_msg_id, &debug_sprintf_view); debug_register_view(chsc_debug_msg_id, &debug_sprintf_view);

View file

@ -54,7 +54,7 @@ debug_info_t *cio_debug_crw_id;
*/ */
static int __init cio_debug_init(void) static int __init cio_debug_init(void)
{ {
cio_debug_msg_id = debug_register("cio_msg", 16, 1, 16 * sizeof(long)); cio_debug_msg_id = debug_register("cio_msg", 16, 1, 11 * sizeof(long));
if (!cio_debug_msg_id) if (!cio_debug_msg_id)
goto out_unregister; goto out_unregister;
debug_register_view(cio_debug_msg_id, &debug_sprintf_view); debug_register_view(cio_debug_msg_id, &debug_sprintf_view);
@ -64,7 +64,7 @@ static int __init cio_debug_init(void)
goto out_unregister; goto out_unregister;
debug_register_view(cio_debug_trace_id, &debug_hex_ascii_view); debug_register_view(cio_debug_trace_id, &debug_hex_ascii_view);
debug_set_level(cio_debug_trace_id, 2); debug_set_level(cio_debug_trace_id, 2);
cio_debug_crw_id = debug_register("cio_crw", 16, 1, 16 * sizeof(long)); cio_debug_crw_id = debug_register("cio_crw", 8, 1, 8 * sizeof(long));
if (!cio_debug_crw_id) if (!cio_debug_crw_id)
goto out_unregister; goto out_unregister;
debug_register_view(cio_debug_crw_id, &debug_sprintf_view); debug_register_view(cio_debug_crw_id, &debug_sprintf_view);

View file

@ -1571,12 +1571,27 @@ out:
return rc; return rc;
} }
#ifdef CONFIG_CCW_CONSOLE static void ccw_device_set_int_class(struct ccw_device *cdev)
static int ccw_device_console_enable(struct ccw_device *cdev,
struct subchannel *sch)
{ {
struct ccw_driver *cdrv = cdev->drv;
/* Note: we interpret class 0 in this context as an uninitialized
* field since it translates to a non-I/O interrupt class. */
if (cdrv->int_class != 0)
cdev->private->int_class = cdrv->int_class;
else
cdev->private->int_class = IRQIO_CIO;
}
#ifdef CONFIG_CCW_CONSOLE
int __init ccw_device_enable_console(struct ccw_device *cdev)
{
struct subchannel *sch = to_subchannel(cdev->dev.parent);
int rc; int rc;
if (!cdev->drv || !cdev->handler)
return -EINVAL;
io_subchannel_init_fields(sch); io_subchannel_init_fields(sch);
rc = cio_commit_config(sch); rc = cio_commit_config(sch);
if (rc) if (rc)
@ -1609,12 +1624,11 @@ out_unlock:
return rc; return rc;
} }
struct ccw_device *ccw_device_probe_console(void) struct ccw_device * __init ccw_device_create_console(struct ccw_driver *drv)
{ {
struct io_subchannel_private *io_priv; struct io_subchannel_private *io_priv;
struct ccw_device *cdev; struct ccw_device *cdev;
struct subchannel *sch; struct subchannel *sch;
int ret;
sch = cio_probe_console(); sch = cio_probe_console();
if (IS_ERR(sch)) if (IS_ERR(sch))
@ -1631,18 +1645,23 @@ struct ccw_device *ccw_device_probe_console(void)
kfree(io_priv); kfree(io_priv);
return cdev; return cdev;
} }
cdev->drv = drv;
set_io_private(sch, io_priv); set_io_private(sch, io_priv);
ret = ccw_device_console_enable(cdev, sch); ccw_device_set_int_class(cdev);
if (ret) {
set_io_private(sch, NULL);
put_device(&sch->dev);
put_device(&cdev->dev);
kfree(io_priv);
return ERR_PTR(ret);
}
return cdev; return cdev;
} }
void __init ccw_device_destroy_console(struct ccw_device *cdev)
{
struct subchannel *sch = to_subchannel(cdev->dev.parent);
struct io_subchannel_private *io_priv = to_io_private(sch);
set_io_private(sch, NULL);
put_device(&sch->dev);
put_device(&cdev->dev);
kfree(io_priv);
}
/** /**
* ccw_device_wait_idle() - busy wait for device to become idle * ccw_device_wait_idle() - busy wait for device to become idle
* @cdev: ccw device * @cdev: ccw device
@ -1726,15 +1745,8 @@ ccw_device_probe (struct device *dev)
int ret; int ret;
cdev->drv = cdrv; /* to let the driver call _set_online */ cdev->drv = cdrv; /* to let the driver call _set_online */
/* Note: we interpret class 0 in this context as an uninitialized ccw_device_set_int_class(cdev);
* field since it translates to a non-I/O interrupt class. */
if (cdrv->int_class != 0)
cdev->private->int_class = cdrv->int_class;
else
cdev->private->int_class = IRQIO_CIO;
ret = cdrv->probe ? cdrv->probe(cdev) : -ENODEV; ret = cdrv->probe ? cdrv->probe(cdev) : -ENODEV;
if (ret) { if (ret) {
cdev->drv = NULL; cdev->drv = NULL;
cdev->private->int_class = IRQIO_CIO; cdev->private->int_class = IRQIO_CIO;

View file

@ -33,8 +33,8 @@ struct qeth_dbf_info qeth_dbf[QETH_DBF_INFOS] = {
/* N P A M L V H */ /* N P A M L V H */
[QETH_DBF_SETUP] = {"qeth_setup", [QETH_DBF_SETUP] = {"qeth_setup",
8, 1, 8, 5, &debug_hex_ascii_view, NULL}, 8, 1, 8, 5, &debug_hex_ascii_view, NULL},
[QETH_DBF_MSG] = {"qeth_msg", [QETH_DBF_MSG] = {"qeth_msg", 8, 1, 11 * sizeof(long), 3,
8, 1, 128, 3, &debug_sprintf_view, NULL}, &debug_sprintf_view, NULL},
[QETH_DBF_CTRL] = {"qeth_control", [QETH_DBF_CTRL] = {"qeth_control",
8, 1, QETH_DBF_CTRL_LEN, 5, &debug_hex_ascii_view, NULL}, 8, 1, QETH_DBF_CTRL_LEN, 5, &debug_hex_ascii_view, NULL},
}; };

View file

@ -193,6 +193,19 @@ static inline int pte_same(pte_t pte_a, pte_t pte_b)
} }
#endif #endif
#ifndef __HAVE_ARCH_PTE_UNUSED
/*
* Some architectures provide facilities to virtualization guests
* so that they can flag allocated pages as unused. This allows the
* host to transparently reclaim unused pages. This function returns
* whether the pte's page is unused.
*/
static inline int pte_unused(pte_t pte)
{
return 0;
}
#endif
#ifndef __HAVE_ARCH_PMD_SAME #ifndef __HAVE_ARCH_PMD_SAME
#ifdef CONFIG_TRANSPARENT_HUGEPAGE #ifdef CONFIG_TRANSPARENT_HUGEPAGE
static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b) static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b)

View file

@ -1487,9 +1487,15 @@ static inline void pgtable_page_dtor(struct page *page)
#if USE_SPLIT_PMD_PTLOCKS #if USE_SPLIT_PMD_PTLOCKS
static struct page *pmd_to_page(pmd_t *pmd)
{
unsigned long mask = ~(PTRS_PER_PMD * sizeof(pmd_t) - 1);
return virt_to_page((void *)((unsigned long) pmd & mask));
}
static inline spinlock_t *pmd_lockptr(struct mm_struct *mm, pmd_t *pmd) static inline spinlock_t *pmd_lockptr(struct mm_struct *mm, pmd_t *pmd)
{ {
return ptlock_ptr(virt_to_page(pmd)); return ptlock_ptr(pmd_to_page(pmd));
} }
static inline bool pgtable_pmd_page_ctor(struct page *page) static inline bool pgtable_pmd_page_ctor(struct page *page)
@ -1508,7 +1514,7 @@ static inline void pgtable_pmd_page_dtor(struct page *page)
ptlock_free(page); ptlock_free(page);
} }
#define pmd_huge_pte(mm, pmd) (virt_to_page(pmd)->pmd_huge_pte) #define pmd_huge_pte(mm, pmd) (pmd_to_page(pmd)->pmd_huge_pte)
#else #else

View file

@ -4721,8 +4721,10 @@ void idle_task_exit(void)
BUG_ON(cpu_online(smp_processor_id())); BUG_ON(cpu_online(smp_processor_id()));
if (mm != &init_mm) if (mm != &init_mm) {
switch_mm(mm, &init_mm, current); switch_mm(mm, &init_mm, current);
finish_arch_post_lock_switch();
}
mmdrop(mm); mmdrop(mm);
} }

View file

@ -31,6 +31,9 @@ void use_mm(struct mm_struct *mm)
tsk->mm = mm; tsk->mm = mm;
switch_mm(active_mm, mm, tsk); switch_mm(active_mm, mm, tsk);
task_unlock(tsk); task_unlock(tsk);
#ifdef finish_arch_post_lock_switch
finish_arch_post_lock_switch();
#endif
if (active_mm != mm) if (active_mm != mm)
mmdrop(active_mm); mmdrop(active_mm);

View file

@ -1165,6 +1165,16 @@ int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
} }
set_pte_at(mm, address, pte, set_pte_at(mm, address, pte,
swp_entry_to_pte(make_hwpoison_entry(page))); swp_entry_to_pte(make_hwpoison_entry(page)));
} else if (pte_unused(pteval)) {
/*
* The guest indicated that the page content is of no
* interest anymore. Simply discard the pte, vmscan
* will take care of the rest.
*/
if (PageAnon(page))
dec_mm_counter(mm, MM_ANONPAGES);
else
dec_mm_counter(mm, MM_FILEPAGES);
} else if (PageAnon(page)) { } else if (PageAnon(page)) {
swp_entry_t entry = { .val = page_private(page) }; swp_entry_t entry = { .val = page_private(page) };
pte_t swp_pte; pte_t swp_pte;