2nd batch of s390 patches for 2.6.24.
Subsystems (3)
cover 2nd batch of s390 patches for 2.6.24.
The latest and greatest for 2.6.24. This patch set includes the tlb flush fix that has been discussed back in June/July and a cleanup of the mm related definitions for s390. I have three more patches in the works that go on top of the cleanup. These three patches add two new features:
1) dynamic number of page table levels and 2) 1K/2K sized page tables. For both features common code changes are required. I'll apply a bit more polish to the patches and then send them for review.
The shortlog for this patch set:
Cornelia Huck (3):
[S390] cio: Use to_channelpath() for device to channel path conversion. [S390] cio: Fix incomplete commit for uevent suppression. [S390] struct class_device -> struct device conversion.
Heiko Carstens (1):
[S390] Add per-cpu idle time / idle count sysfs attributes.
Martin Schwidefsky (6):
[S390] Update default configuration.
[S390] tlb flush fix.
[S390] Remove unused user_seg from thread structure. [S390] Introduce follow_table in uaccess_pt.c [S390] Cleanup page table definitions. [S390] 4level-fixup cleanup
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 1/10 Update default configuration.
From: Martin Schwidefsky <[email protected]>
---
arch/s390/defconfig | 108 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 75 insertions(+), 33 deletions(-)
arch/s390/defconfig +75 -33
@@ -1,8 +1,9 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22 -# Tue Jul 17 12:50:23 2007 +# Linux kernel version: 2.6.23 +# Fri Oct 19 18:32:03 2007 # +CONFIG_SCHED_MC=y CONFIG_MMU=y CONFIG_ZONE_DMA=y CONFIG_LOCKDEP_SUPPORT=y
@@ -19,15 +20,11 @@ CONFIG_S390=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # CONFIG_EXPERIMENTAL=y CONFIG_LOCK_KERNEL=y CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y
@@ -43,6 +40,8 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=17 # CONFIG_CPUSETS is not set +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FAIR_USER_SCHED=y CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_BLK_DEV_INITRD=y
@@ -63,7 +62,6 @@ CONFIG_FUTEX=y CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_VM_EVENT_COUNTERS=y
@@ -83,6 +81,7 @@ CONFIG_STOP_MACHINE=y CONFIG_BLOCK=y # CONFIG_BLK_DEV_IO_TRACE is not set CONFIG_BLK_DEV_BSG=y +CONFIG_BLOCK_COMPAT=y # # IO Schedulers
@@ -108,7 +107,6 @@ CONFIG_64BIT=y CONFIG_SMP=y CONFIG_NR_CPUS=32 CONFIG_HOTPLUG_CPU=y -CONFIG_DEFAULT_MIGRATION_COST=1000000 CONFIG_COMPAT=y CONFIG_SYSVIPC_COMPAT=y CONFIG_AUDIT_ARCH=y
@@ -143,9 +141,11 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_RESOURCES_64BIT=y CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y CONFIG_VIRT_TO_BUS=y CONFIG_HOLES_IN_ZONE=y
@@ -219,12 +219,14 @@ CONFIG_INET_TUNNEL=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_LRO=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_TCP_MD5SIG is not set +# CONFIG_IP_VS is not set CONFIG_IPV6=y # CONFIG_IPV6_PRIVACY is not set # CONFIG_IPV6_ROUTER_PREF is not set
@@ -243,7 +245,48 @@ CONFIG_IPV6_SIT=y # CONFIG_IPV6_TUNNEL is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set # CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK_ENABLED=m +CONFIG_NF_CONNTRACK=m +# CONFIG_NF_CT_ACCT is not set +# CONFIG_NF_CONNTRACK_MARK is not set +# CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CT_PROTO_SCTP is not set +# CONFIG_NF_CT_PROTO_UDPLITE is not set +# CONFIG_NF_CONNTRACK_AMANDA is not set +# CONFIG_NF_CONNTRACK_FTP is not set +# CONFIG_NF_CONNTRACK_H323 is not set +# CONFIG_NF_CONNTRACK_IRC is not set +# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set +# CONFIG_NF_CONNTRACK_PPTP is not set +# CONFIG_NF_CONNTRACK_SANE is not set +# CONFIG_NF_CONNTRACK_SIP is not set +# CONFIG_NF_CONNTRACK_TFTP is not set +# CONFIG_NF_CT_NETLINK is not set +# CONFIG_NETFILTER_XTABLES is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_NF_CONNTRACK_IPV4 is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set + +# +# IPv6: Netfilter Configuration (EXPERIMENTAL) +# +# CONFIG_NF_CONNTRACK_IPV6 is not set +# CONFIG_IP6_NF_QUEUE is not set +# CONFIG_IP6_NF_IPTABLES is not set # CONFIG_IP_DCCP is not set CONFIG_IP_SCTP=m # CONFIG_SCTP_DBG_MSG is not set
@@ -306,6 +349,7 @@ CONFIG_NET_CLS_ACT=y CONFIG_NET_ACT_POLICE=y # CONFIG_NET_ACT_GACT is not set # CONFIG_NET_ACT_MIRRED is not set +CONFIG_NET_ACT_NAT=m # CONFIG_NET_ACT_PEDIT is not set # CONFIG_NET_ACT_SIMP is not set CONFIG_NET_CLS_POLICE=y
@@ -329,6 +373,7 @@ CONFIG_CCW=y # # Generic Driver Options # +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set
@@ -400,17 +445,11 @@ CONFIG_SCSI_FC_ATTRS=y # CONFIG_SCSI_ISCSI_ATTRS is not set # CONFIG_SCSI_SAS_ATTRS is not set # CONFIG_SCSI_SAS_LIBSAS is not set - -# -# SCSI low-level drivers -# +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_SCSI_DEBUG is not set CONFIG_ZFCP=y - -# -# Multi-device support (RAID and LVM) -# CONFIG_MD=y CONFIG_BLK_DEV_MD=y CONFIG_MD_LINEAR=m
@@ -438,8 +477,13 @@ CONFIG_BONDING=m # CONFIG_MACVLAN is not set CONFIG_EQUALIZER=m CONFIG_TUN=m +CONFIG_VETH=m CONFIG_NET_ETHERNET=y # CONFIG_MII is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set CONFIG_NETDEV_1000=y CONFIG_NETDEV_10000=y # CONFIG_TR is not set
@@ -473,7 +517,6 @@ CONFIG_CCWGROUP=y CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 -# CONFIG_WATCHDOG is not set CONFIG_HW_RANDOM=m # CONFIG_R3964 is not set CONFIG_RAW_DRIVER=m
@@ -490,7 +533,6 @@ CONFIG_TN3270_CONSOLE=y CONFIG_TN3215=y CONFIG_TN3215_CONSOLE=y CONFIG_CCW_CONSOLE=y -CONFIG_SCLP=y CONFIG_SCLP_TTY=y CONFIG_SCLP_CONSOLE=y CONFIG_SCLP_VT220_TTY=y
@@ -514,6 +556,11 @@ CONFIG_S390_TAPE_34XX=m CONFIG_MONWRITER=m CONFIG_S390_VMUR=m # CONFIG_POWER_SUPPLY is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# # # File systems
@@ -569,7 +616,6 @@ CONFIG_SYSFS=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y # CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y CONFIG_CONFIGFS_FS=m #
@@ -588,10 +634,7 @@ CONFIG_CONFIGFS_FS=m # CONFIG_QNX4FS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set - -# -# Network File Systems -# +CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set
@@ -638,15 +681,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set # CONFIG_SYSV68_PARTITION is not set - -# -# Native Language Support -# # CONFIG_NLS is not set - -# -# Distributed Lock Manager -# CONFIG_DLM=m # CONFIG_DLM_DEBUG is not set
@@ -682,6 +717,7 @@ CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_LOCK_ALLOC is not set # CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set
@@ -700,8 +736,10 @@ CONFIG_FORCED_INLINING=y # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_AEAD=m CONFIG_CRYPTO_BLKCIPHER=y CONFIG_CRYPTO_HASH=m CONFIG_CRYPTO_MANAGER=y
@@ -720,6 +758,7 @@ CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_PCBC=m # CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_XTS is not set # CONFIG_CRYPTO_CRYPTD is not set # CONFIG_CRYPTO_DES is not set CONFIG_CRYPTO_FCRYPT=m
@@ -733,11 +772,13 @@ CONFIG_CRYPTO_FCRYPT=m # CONFIG_CRYPTO_ARC4 is not set # CONFIG_CRYPTO_KHAZAD is not set # CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_SEED=m # CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set # CONFIG_CRYPTO_CRC32C is not set CONFIG_CRYPTO_CAMELLIA=m # CONFIG_CRYPTO_TEST is not set +CONFIG_CRYPTO_AUTHENC=m CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_SHA1_S390 is not set # CONFIG_CRYPTO_SHA256_S390 is not set
@@ -755,5 +796,6 @@ CONFIG_BITREVERSE=m # CONFIG_CRC16 is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=m +CONFIG_CRC7=m # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 2/10 Add per-cpu idle time / idle count sysfs attributes.
In reply to Martin SchwidefskyFrom: Heiko Carstens <[email protected]>
Add two new sysfs entries per cpu: idle_count and idle_time. idle_count contains the number of times a cpu went into idle state. idle_time contains the time a cpu spent in idle state in microseconds. This can be used e.g. by powertop to tell how often idle state is entered and left.
# cat /sys/devices/system/cpu/cpu0/idle_count 504 # cat /sys/devices/system/cpu/cpu0/idle_time 469734037 us
---
arch/s390/kernel/process.c | 16 +++++++++++ arch/s390/kernel/smp.c | 63 ++++++++++++++++++++++++++++++++++++++++++--- include/asm-s390/cpu.h | 25 +++++++++++++++++ 3 files changed, 101 insertions(+), 3 deletions(-)
arch/s390/kernel/process.c +16 -0
@@ -44,6 +44,7 @@#include <asm/processor.h> #include <asm/irq.h> #include <asm/timer.h> +#include <asm/cpu.h> asmlinkage void ret_from_fork(void) asm ("ret_from_fork");
@@ -91,6 +92,14 @@ EXPORT_SYMBOL(unregister_idle_notifier);void do_monitor_call (struct pt_regs *regs,long interruption_code) { +struct s390_idle_data *idle; + + idle = &__get_cpu_var (s390_idle); +spin_lock (&idle->lock); + idle->idle_time +=get_clock () - idle->idle_enter; + idle->in_idle =0 ; +spin_unlock (&idle->lock); +/* disable monitor call class 0 */ __ctl_clear_bit (8 ,15 );
@@ -105,6 +114,7 @@ extern void s390_handle_mcck(void);static void default_idle (void ) {int cpu, rc; +struct s390_idle_data *idle;/* CPU is going idle. */ cpu =smp_processor_id ();
@@ -142,6 +152,12 @@ static void default_idle(void)return ; } + idle = &__get_cpu_var (s390_idle); +spin_lock (&idle->lock); + idle->idle_count++; + idle->in_idle =1 ; + idle->idle_enter =get_clock (); +spin_unlock (&idle->lock);trace_hardirqs_on ();/* Wait for external, I/O or machine check interrupt. */ __load_psw_mask(psw_kernel_bits | PSW_MASK_WAIT |
arch/s390/kernel/smp.c +60 -3
119 lines not on this page · raw message
include/asm-s390/cpu.h new file +25 -0
@@ -0,0 +1,25 @@ +/* +* include/asm-s390/cpu.h +* +* Copyright IBM Corp. 2007 +* Author(s): Heiko Carstens <[email protected]> +*/ + +#ifndef _ASM_S390_CPU_H_ +#define _ASM_S390_CPU_H_ + +#include <linux/types.h> +#include <linux/percpu.h> +#include <linux/spinlock.h> + +struct s390_idle_data { +spinlock_t lock; +unsigned int in_idle; +unsigned long long idle_count; +unsigned long long idle_enter; +unsigned long long idle_time; +}; + +DECLARE_PER_CPU(struct s390_idle_data, s390_idle); + +#endif /* _ASM_S390_CPU_H_ */
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 3/10 cio: Use to_channelpath() for device to channel path conversion.
In reply to Martin SchwidefskyFrom: Cornelia Huck <[email protected]>
We already have a macro for that, so let's use it consistently...
---
drivers/s390/cio/chp.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/s390/cio/chp.c +6 -6
@@ -246,7 +246,7 @@ int chp_add_cmg_attr(struct channel_pathstatic ssize_t chp_status_show (struct device *dev,struct device_attribute *attr,char *buf) { - struct channel_path *chp = container_of(dev, struct channel_path, dev); +struct channel_path *chp =to_channelpath (dev);if (!chp)return 0 ;
@@ -258,7 +258,7 @@ static ssize_t chp_status_write(struct dstruct device_attribute *attr, const char *buf, size_t count) { - struct channel_path *cp = container_of(dev, struct channel_path, dev); + struct channel_path *cp = to_channelpath(dev);char cmd[10 ];int num_args;int error;
@@ -286,7 +286,7 @@ static ssize_t chp_configure_show(structstruct channel_path *cp;int status; - cp = container_of(dev, struct channel_path, dev); + cp =to_channelpath (dev); status =chp_info_get_status (cp->chpid);if (status <0 )return status;
@@ -308,7 +308,7 @@ static ssize_t chp_configure_write(strucreturn -EINVAL ;if (val !=0 && val !=1 )return -EINVAL ; - cp = container_of(dev, struct channel_path, dev); + cp =to_channelpath (dev);chp_cfg_schedule (cp->chpid, val);cfg_wait_idle ();
@@ -320,7 +320,7 @@ static DEVICE_ATTR(configure, 0644, chp_static ssize_t chp_type_show (struct device *dev,struct device_attribute *attr,char *buf) { - struct channel_path *chp = container_of(dev, struct channel_path, dev); +struct channel_path *chp =to_channelpath (dev);if (!chp)return 0 ;
@@ -374,7 +374,7 @@ static void chp_release(struct device *d {struct channel_path *cp; - cp = container_of(dev, struct channel_path, dev); + cp =to_channelpath (dev);kfree (cp); }
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 4/10 cio: Fix incomplete commit for uevent suppression.
In reply to Martin SchwidefskyFrom: Cornelia Huck <[email protected]>
Commit fa1a8c23eb7d3ded8a3c6d0e653339a2bc7fca9e intended to introduce uevent suppression for subchannels, but half of it was lost somewhere. Now, we end up with two uevents for every registered subchannel :( So we should better add the missing part from
http://marc.info/?l=linux-kernel&m=117515953113974&w=2.
---
drivers/s390/cio/css.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/s390/cio/css.c +9 -0
@@ -182,6 +182,15 @@ static int css_register_subchannel(struc sch->dev.bus = &css_bus_type; sch->dev.release = &css_subchannel_release; sch->dev.groups = subch_attr_groups; +/* +* We don't want to generate uevents for I/O subchannels that don't +* have a working ccw device behind them since they will be +* unregistered before they can be used anyway, so we delay the add +* uevent until after device recognition was successful. +*/ +if (!cio_is_console (sch->schid)) +/* Console is special, no need to suppress. */ + sch->dev.uevent_suppress =1 ;css_update_ssd_info (sch);/* make it known to the system */ ret =css_sch_device_register (sch);
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 5/10 struct class_device -> struct device conversion.
In reply to Martin SchwidefskyFrom: Cornelia Huck <[email protected]>
Convert struct class_device users under drivers/s390/char to use struct device.
---
drivers/s390/char/raw3270.c | 26 +++++++++++--------------- drivers/s390/char/tape_class.c | 19 +++++++------------ drivers/s390/char/tape_class.h | 4 ++-- drivers/s390/char/vmlogrdr.c | 15 ++++++--------- 4 files changed, 26 insertions(+), 38 deletions(-)
drivers/s390/char/raw3270.c +11 -15
@@ -48,8 +48,8 @@ struct raw3270 {struct timer_list timer;/* Device timer. */ unsigned char *ascebc;/* ascii -> ebcdic table */ -struct class_device *clttydev;/* 3270-class tty device ptr */ -struct class_device *cltubdev;/* 3270-class tub device ptr */ +struct device *clttydev;/* 3270-class tty device ptr */ +struct device *cltubdev;/* 3270-class tub device ptr */ struct raw3270_request init_request;unsigned char init_data[256 ];
@@ -1107,11 +1107,9 @@ raw3270_delete_device(struct raw3270 *rp/* Remove from device chain. */ mutex_lock (&raw3270_mutex);if (rp->clttydev && !IS_ERR (rp->clttydev)) -class_device_destroy (class3270, -MKDEV (IBM_TTY3270_MAJOR , rp->minor)); +device_destroy (class3270,MKDEV (IBM_TTY3270_MAJOR , rp->minor));if (rp->cltubdev && !IS_ERR (rp->cltubdev)) -class_device_destroy (class3270, -MKDEV (IBM_FS3270_MAJOR , rp->minor)); +device_destroy (class3270,MKDEV (IBM_FS3270_MAJOR , rp->minor));list_del_init (&rp->list);mutex_unlock (&raw3270_mutex);
@@ -1181,24 +1179,22 @@ static int raw3270_create_attributes(strif (rc) goto out; - rp->clttydev =class_device_create (class3270,NULL , -MKDEV (IBM_TTY3270_MAJOR , rp->minor), - &rp->cdev->dev,"tty%s" , - rp->cdev->dev.bus_id); + rp->clttydev =device_create (class3270, &rp->cdev->dev, +MKDEV (IBM_TTY3270_MAJOR , rp->minor), +"tty%s" , rp->cdev->dev.bus_id);if (IS_ERR (rp->clttydev)) { rc =PTR_ERR (rp->clttydev); goto out_ttydev; } - rp->cltubdev =class_device_create (class3270,NULL , -MKDEV (IBM_FS3270_MAJOR , rp->minor), - &rp->cdev->dev,"tub%s" , - rp->cdev->dev.bus_id); + rp->cltubdev =device_create (class3270, &rp->cdev->dev, +MKDEV (IBM_FS3270_MAJOR , rp->minor), +"tub%s" , rp->cdev->dev.bus_id);if (!IS_ERR (rp->cltubdev)) goto out; rc =PTR_ERR (rp->cltubdev); -class_device_destroy (class3270,MKDEV (IBM_TTY3270_MAJOR , rp->minor)); +device_destroy (class3270,MKDEV (IBM_TTY3270_MAJOR , rp->minor)); out_ttydev:sysfs_remove_group (&rp->cdev->dev.kobj, &raw3270_attr_group);
drivers/s390/char/tape_class.c +7 -12
@@ -69,12 +69,9 @@ struct tape_class_device *register_tape_if (rc) goto fail_with_cdev; - tcd->class_device =class_device_create ( - tape_class, -NULL , - tcd->char_device->dev, - device, -"%s" , tcd->device_name + tcd->class_device =device_create (tape_class, device, + tcd->char_device->dev, +"%s" , tcd->device_name ); rc =IS_ERR (tcd->class_device) ?PTR_ERR (tcd->class_device) :0 ;if (rc)
@@ -90,7 +87,7 @@ struct tape_class_device *register_tape_return tcd; fail_with_class_device: -class_device_destroy (tape_class, tcd->char_device->dev); +device_destroy (tape_class, tcd->char_device->dev); fail_with_cdev:cdev_del (tcd->char_device);
@@ -105,11 +102,9 @@ EXPORT_SYMBOL(register_tape_dev);void unregister_tape_dev (struct tape_class_device *tcd) {if (tcd !=NULL && !IS_ERR (tcd)) { -sysfs_remove_link ( - &tcd->class_device->dev->kobj, - tcd->mode_name - ); -class_device_destroy (tape_class, tcd->char_device->dev); +sysfs_remove_link (&tcd->class_device->kobj, + tcd->mode_name); +device_destroy (tape_class, tcd->char_device->dev);cdev_del (tcd->char_device);kfree (tcd); }
drivers/s390/char/tape_class.h +2 -2
@@ -24,8 +24,8 @@#define TAPECLASS_NAME_LEN 32struct tape_class_device { -struct cdev * char_device; -struct class_device * class_device; +struct cdev *char_device; +struct device *class_device;char device_name[TAPECLASS_NAME_LEN ];char mode_name[TAPECLASS_NAME_LEN ]; };
drivers/s390/char/vmlogrdr.c +6 -9
@@ -74,7 +74,7 @@ struct vmlogrdr_priv_t {int dev_in_use;/* 1: already opened, 0: not opened*/ spinlock_t priv_lock;struct device *device; -struct class_device *class_device; +struct device *class_device;int autorecording;int autopurge; };
@@ -762,12 +762,10 @@ static int vmlogrdr_register_device(strudevice_unregister (dev);return ret; } - priv->class_device =class_device_create ( - vmlogrdr_class, -NULL , -MKDEV (vmlogrdr_major, priv->minor_num), - dev, -"%s" , dev->bus_id ); + priv->class_device =device_create (vmlogrdr_class, dev, +MKDEV (vmlogrdr_major, + priv->minor_num), +"%s" , dev->bus_id);if (IS_ERR (priv->class_device)) { ret =PTR_ERR (priv->class_device); priv->class_device=NULL ;
@@ -783,8 +781,7 @@ static int vmlogrdr_register_device(strustatic int vmlogrdr_unregister_device (struct vmlogrdr_priv_t *priv) { -class_device_destroy (vmlogrdr_class, -MKDEV (vmlogrdr_major, priv->minor_num)); +device_destroy (vmlogrdr_class,MKDEV (vmlogrdr_major, priv->minor_num));if (priv->device !=NULL ) {sysfs_remove_group (&priv->device->kobj, &vmlogrdr_attr_group);device_unregister (priv->device);
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 6/10 tlb flush fix.
In reply to Martin SchwidefskyFrom: Martin Schwidefsky <[email protected]>
The current tlb flushing code for page table entries violates the s390 architecture in a small detail. The relevant section from the principles of operation (SA22-7832-02 page 3-47):
"A valid table entry must not be changed while it is attached to any CPU and may be used for translation by that CPU except to
(1) invalidate the entry by using INVALIDATE PAGE TABLE ENTRY or INVALIDATE DAT TABLE ENTRY, (2) alter bits 56-63 of a page-table entry, or (3) make a change by means of a COMPARE AND SWAP AND PURGE instruction that purges the TLB."
That means if one thread of a multithreaded applciation uses a vma while another thread does an unmap on it, the page table entries of that vma needs to get removed with IPTE, IDTE or CSP. In some strange and rare situations a cpu could check-stop (die) because a entry has been pushed out of the TLB that is still needed to complete a (milli-coded) instruction. I've never seen it happen with the current code on any of the supported machines, so right now this is a theoretical problem. But I want to fix it nevertheless, to avoid headaches in the futures.
To get this implemented correctly without changing common code the primitives ptep_get_and_clear, ptep_get_and_clear_full and ptep_set_wrprotect need to use the IPTE instruction to invalidate the pte before the new pte value gets stored. If IPTE is always used for the three primitives three important operations will have a performace
hit: fork, mprotect and exit_mmap. Time for some workarounds:
* 1: ptep_get_and_clear_full is used in unmap_vmas to remove page tables entries in a batched tlb gather operation. If the mmu_gather context passed to unmap_vmas has been started with full_mm_flush==1 or if only one cpu is online or if the mm_struct doesn't has more than one user the fullmm indication in the mmu_gather context is set to one. All TLBs for mm_struct are flushed by the tlb_gather_mmu call. No new TLBs can be created while the unmap is in progress. In this case ptep_get_and_clear_full clears the ptes with a simple store.
* 2: ptep_get_and_clear is used in change_protection to clear the ptes from the page tables before they are reentered with the new access flags. At the end of the update flush_tlb_range clears the remaining TLBs. In general the ptep_get_and_clear has to issue IPTE for each pte and flush_tlb_range is a nop. But if there is only one user of the mm_struct then ptep_get_and_clear uses simple stores to do the update and flush_tlb_range will flush the TLBs.
* 3: Similar to 2, ptep_set_wrprotect is used in copy_page_range for a fork to make all ptes of a cow mapping read-only. At the end of of copy_page_range dup_mmap will flush the TLBs with a call to flush_tlb_mm. Check for mm->mm_users and if there is only one user avoid using IPTE in ptep_set_wrprotect and let flush_tlb_mm clear the TLBs.
Overall for single threaded programs the tlb flush code now performs better, for multi threaded programs it is slightly worse. In particular exit_mmap() now does a single IDTE for the mm and then just frees every page cache reference and every page table page directly without a delay over the mmu_gather structure.
---
arch/s390/kernel/smp.c | 2 include/asm-s390/pgalloc.h | 17 ---- include/asm-s390/pgtable.h | 99 +++++++++++++++++++-------- include/asm-s390/tlb.h | 127 ++++++++++++++++++++++++++++++++--- include/asm-s390/tlbflush.h | 159 +++++++++++++++----------------------------- 5 files changed, 247 insertions(+), 157 deletions(-)
arch/s390/kernel/smp.c +1 -1
@@ -326,7 +326,7 @@ static void smp_ext_bitcall(int cpu, ec_*/ void smp_ptlb_callback (void *info) { -local_flush_tlb (); +__tlb_flush_local (); }void smp_ptlb_all (void )
include/asm-s390/pgalloc.h +0 -17
@@ -82,7 +82,6 @@ static inline void pgd_free(pgd_t *pgd)*/ #define pmd_alloc_one (mm,address) ({ BUG(); ((pmd_t *)2); })#define pmd_free (x) do { } while (0) -#define __pmd_free_tlb (tlb,x) do { } while (0)#define pgd_populate (mm, pmd, pte) BUG()#define pgd_populate_kernel (mm, pmd, pte) BUG()#else /* __s390x__ */
@@ -118,12 +117,6 @@ static inline void pmd_free (pmd_t *pmd)free_pages ((unsigned long ) pmd,PMD_ALLOC_ORDER ); } -#define __pmd_free_tlb (tlb,pmd) \ - do { \ - tlb_flush_mmu(tlb, 0, 0); \ - pmd_free(pmd); \ - } while (0) -static inline void pgd_populate_kernel (struct mm_struct *mm,pgd_t *pgd,pmd_t *pmd) {
@@ -224,14 +217,4 @@ static inline void pte_free(struct page __free_page(pte); } -#define __pte_free_tlb (tlb, pte) \ -({ \ - struct mmu_gather *__tlb = (tlb); \ - struct page *__pte = (pte); \ - struct page *shadow_page = get_shadow_page(__pte); \ - if (shadow_page) \ - tlb_remove_page(__tlb, shadow_page); \ - tlb_remove_page(__tlb, __pte); \ -}) -#endif /* _S390_PGALLOC_H */
include/asm-s390/pgtable.h +71 -28
167 lines not on this page · raw message
include/asm-s390/tlbflush.h +57 -102
198 lines not on this page · raw message
include/asm-s390/tlb.h +118 -9
137 lines not on this page · raw message
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 7/10 Remove unused user_seg from thread structure.
In reply to Martin SchwidefskyFrom: Martin Schwidefsky <[email protected]>
---
arch/s390/kernel/process.c | 2 -- include/asm-s390/processor.h | 14 +++----------- 2 files changed, 3 insertions(+), 13 deletions(-)
arch/s390/kernel/process.c +0 -2
@@ -270,14 +270,12 @@ int copy_thread(int nr, unsigned long clsave_fp_regs (¤t->thread.fp_regs);memcpy (&p->thread.fp_regs, ¤t->thread.fp_regs,sizeof (s390_fp_regs)); - p->thread.user_seg =__pa ((unsigned long ) p->mm->pgd) | _SEGMENT_TABLE;/* Set a new TLS ? */ if (clone_flags &CLONE_SETTLS ) p->thread.acrs[0 ] = regs->gprs[6 ];#else /* CONFIG_64BIT */ /* Save the fpu registers to new thread structure. */ save_fp_regs (&p->thread.fp_regs); - p->thread.user_seg =__pa ((unsigned long ) p->mm->pgd) | _REGION_TABLE;/* Set a new TLS ? */ if (clone_flags &CLONE_SETTLS ) {if (test_thread_flag (TIF_31BIT )) {
include/asm-s390/processor.h +3 -11
@@ -93,7 +93,6 @@ struct thread_struct {s390_fp_regs fp_regs;unsigned int acrs[NUM_ACRS ];unsigned long ksp;/* kernel stack pointer */ -unsigned long user_seg;/* HSTD */ mm_segment_t mm_segment;unsigned long prot_addr;/* address of protection-excep. */ unsigned int error_code;/* error-code of last prog-excep. */
@@ -134,16 +133,9 @@ struct stack_frame {# define __SWAPPER_PG_DIR __pa(&swapper_pg_dir[0]) + _REGION_TABLE#endif /* __s390x__ */ -#define INIT_THREAD {{0,{{0},{0},{0},{0},{0},{0},{0},{0},{0},{0}, \ - {0},{0},{0},{0},{0},{0}}}, \ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \ - sizeof(init_stack) + (unsigned long) &init_stack, \ - __SWAPPER_PG_DIR, \ - {0}, \ - 0,0,0, \ - (per_struct) {{{{0,}}},0,0,0,0,{{0,}}}, \ - 0, 0 \ -} +#define INIT_THREAD { \ + .ksp = sizeof(init_stack) + (unsigned long) &init_stack, \ +}/* * Do necessary setup to start up a new thread.
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 8/10 Introduce follow_table in uaccess_pt.c
In reply to Martin SchwidefskyFrom: Martin Schwidefsky <[email protected]>
Define and use follow_table inline in uaccess_pt.c to simplify the code.
---
arch/s390/lib/uaccess_pt.c | 85 +++++++++++---------------------------------- 1 file changed, 22 insertions(+), 63 deletions(-)
arch/s390/lib/uaccess_pt.c +22 -63
@@ -15,6 +15,22 @@#include <asm/futex.h> #include "uaccess.h" +static inline pte_t *follow_table (struct mm_struct *mm,unsigned long addr) +{ +pgd_t *pgd; +pmd_t *pmd; + + pgd =pgd_offset (mm, addr); +if (pgd_none (*pgd) ||unlikely (pgd_bad (*pgd))) +return NULL ; + + pmd =pmd_offset (pgd, addr); +if (pmd_none (*pmd) ||unlikely (pmd_bad (*pmd))) +return NULL ; + +return pte_offset_map (pmd, addr); +} +static int __handle_fault (struct mm_struct *mm,unsigned long address,int write_access) {
@@ -85,8 +101,6 @@ static size_t __user_copy_pt(unsigned lo {struct mm_struct *mm = current->mm;unsigned long offset, pfn, done, size; -pgd_t *pgd; -pmd_t *pmd;pte_t *pte;void *from, *to;
@@ -94,15 +108,7 @@ static size_t __user_copy_pt(unsigned lo retry:spin_lock (&mm->page_table_lock); do { - pgd = pgd_offset(mm, uaddr); - if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) - goto fault; - - pmd = pmd_offset(pgd, uaddr); - if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) - goto fault; - - pte = pte_offset_map(pmd, uaddr); + pte = follow_table(mm, uaddr); if (!pte || !pte_present(*pte) || (write_user && !pte_write(*pte))) goto fault;
@@ -142,22 +148,12 @@ static unsigned long __dat_user_addr(uns {struct mm_struct *mm = current->mm;unsigned long pfn, ret; -pgd_t *pgd; -pmd_t *pmd;pte_t *pte;int rc; ret =0 ; retry: - pgd =pgd_offset (mm, uaddr); -if (pgd_none (*pgd) ||unlikely (pgd_bad (*pgd))) - goto fault; - - pmd =pmd_offset (pgd, uaddr); -if (pmd_none (*pmd) ||unlikely (pmd_bad (*pmd))) - goto fault; - - pte =pte_offset_map (pmd, uaddr); + pte =follow_table (mm, uaddr);if (!pte || !pte_present (*pte)) goto fault;
@@ -229,8 +225,6 @@ static size_t strnlen_user_pt(size_t couunsigned long uaddr = (unsigned long ) src;struct mm_struct *mm = current->mm;unsigned long offset, pfn, done, len; -pgd_t *pgd; -pmd_t *pmd;pte_t *pte;size_t len_str;
@@ -240,15 +234,7 @@ static size_t strnlen_user_pt(size_t cou retry:spin_lock (&mm->page_table_lock); do { - pgd = pgd_offset(mm, uaddr); - if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) - goto fault; - - pmd = pmd_offset(pgd, uaddr); - if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) - goto fault; - - pte = pte_offset_map(pmd, uaddr); + pte = follow_table(mm, uaddr); if (!pte || !pte_present(*pte)) goto fault;
@@ -308,8 +294,6 @@ static size_t copy_in_user_pt(size_t n, uaddr, done, size;unsigned long uaddr_from = (unsigned long ) from;unsigned long uaddr_to = (unsigned long ) to; -pgd_t *pgd_from, *pgd_to; -pmd_t *pmd_from, *pmd_to;pte_t *pte_from, *pte_to;int write_user;
@@ -317,39 +301,14 @@ static size_t copy_in_user_pt(size_t n, retry:spin_lock (&mm->page_table_lock); do { - pgd_from = pgd_offset(mm, uaddr_from); - if (pgd_none(*pgd_from) || unlikely(pgd_bad(*pgd_from))) { - uaddr = uaddr_from; - write_user = 0; - goto fault; - } - pgd_to = pgd_offset(mm, uaddr_to); - if (pgd_none(*pgd_to) || unlikely(pgd_bad(*pgd_to))) { - uaddr = uaddr_to; - write_user = 1; - goto fault; - } - - pmd_from = pmd_offset(pgd_from, uaddr_from); - if (pmd_none(*pmd_from) || unlikely(pmd_bad(*pmd_from))) { - uaddr = uaddr_from; - write_user = 0; - goto fault; - } - pmd_to = pmd_offset(pgd_to, uaddr_to); - if (pmd_none(*pmd_to) || unlikely(pmd_bad(*pmd_to))) { - uaddr = uaddr_to; - write_user = 1; - goto fault; - } - - pte_from = pte_offset_map(pmd_from, uaddr_from); + pte_from = follow_table(mm, uaddr_from); if (!pte_from || !pte_present(*pte_from)) { uaddr = uaddr_from; write_user = 0; goto fault; } - pte_to = pte_offset_map(pmd_to, uaddr_to); + + pte_to = follow_table(mm, uaddr_to); if (!pte_to || !pte_present(*pte_to) || !pte_write(*pte_to)) { uaddr = uaddr_to; write_user = 1;
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 9/10 Cleanup page table definitions.
In reply to Martin SchwidefskyFrom: Martin Schwidefsky <[email protected]>
- De-confuse the defines for the address-space-control-elements and the segment/region table entries.
- Create out of line functions for page table allocation / freeing.
- Simplify get_shadow_xxx functions.
---
arch/s390/mm/Makefile | 2 arch/s390/mm/init.c | 26 +--- arch/s390/mm/pgtable.c | 96 +++++++++++++++++ arch/s390/mm/vmem.c | 23 +--- include/asm-s390/mmu_context.h | 50 ++++----- include/asm-s390/pgalloc.h | 204 +++++++++++--------------------------- include/asm-s390/pgtable.h | 219 +++++++++++++++++------------------------ include/asm-s390/processor.h | 6 - include/asm-s390/tlbflush.h | 2 9 files changed, 296 insertions(+), 332 deletions(-)
arch/s390/mm/init.c +10 -16
@@ -103,32 +103,26 @@ static void __init setup_ro_region(void)*/ void __init paging_init (void ) { -pgd_t *pg_dir; -int i; -unsigned long pgdir_k;static const int ssm_mask =0x04000000L ;unsigned long max_zone_pfns[MAX_NR_ZONES ]; - pg_dir = swapper_pg_dir; - + init_mm.pgd = swapper_pg_dir; + S390_lowcore.kernel_asce =__pa (init_mm.pgd) &PAGE_MASK ;#ifdef CONFIG_64BIT - pgdir_k = (__pa (swapper_pg_dir) &PAGE_MASK ) | _KERN_REGION_TABLE; -for (i =0 ; i <PTRS_PER_PGD ; i++) -pgd_clear_kernel (pg_dir + i); + S390_lowcore.kernel_asce |= _ASCE_TYPE_REGION3 | _ASCE_TABLE_LENGTH; +pgd_val (*((pgd_t *) init_mm.pgd)) = _REGION3_ENTRY_EMPTY;#else - pgdir_k = (__pa (swapper_pg_dir) &PAGE_MASK ) | _KERNSEG_TABLE; -for (i =0 ; i <PTRS_PER_PGD ; i++) -pmd_clear_kernel ((pmd_t *)(pg_dir + i)); + S390_lowcore.kernel_asce |= _ASCE_TABLE_LENGTH; +pmd_val (*((pmd_t *) init_mm.pgd)) = _SEGMENT_ENTRY_EMPTY;#endif +memcpy (init_mm.pgd +1 , init_mm.pgd, (PTRS_PER_PGD -1 )*sizeof (pgd_t));vmem_map_init ();setup_ro_region (); - S390_lowcore.kernel_asce = pgdir_k; -/* enable virtual mapping in kernel mode */ -__ctl_load (pgdir_k,1 ,1 ); -__ctl_load (pgdir_k,7 ,7 ); -__ctl_load (pgdir_k,13 ,13 ); +__ctl_load (S390_lowcore.kernel_asce,1 ,1 ); +__ctl_load (S390_lowcore.kernel_asce,7 ,7 ); +__ctl_load (S390_lowcore.kernel_asce,13 ,13 );__raw_local_irq_ssm (ssm_mask);memset (max_zone_pfns,0 ,sizeof (max_zone_pfns));
arch/s390/mm/Makefile +1 -1
@@ -2,6 +2,6 @@ # Makefile for the linux s390-specific parts of the memory manager. # -obj-y := init.o fault.o extmem.o mmap.o vmem.o +obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o obj-$(CONFIG_CMM) += cmm.o
arch/s390/mm/pgtable.c new file +96 -0
96 lines not on this page · raw message
arch/s390/mm/vmem.c +9 -14
@@ -75,29 +75,24 @@ static void __init_refok *vmem_alloc_pagstatic inline pmd_t *vmem_pmd_alloc (void ) { -pmd_t *pmd; -int i; - - pmd =vmem_alloc_pages (PMD_ALLOC_ORDER ); +pmd_t *pmd =NULL ; +#ifdef CONFIG_64BIT + pmd =vmem_alloc_pages (2 );if (!pmd)return NULL ; -for (i =0 ; i <PTRS_PER_PMD ; i++) -pmd_clear_kernel (pmd + i); +pmd_clear_kernel (pmd); +memcpy (pmd +1 , pmd, (PTRS_PER_PMD -1 )*sizeof (pmd_t)); +#endif return pmd; }static inline pte_t *vmem_pte_alloc (void ) { -pte_t *pte; -pte_t empty_pte; -int i; - - pte =vmem_alloc_pages (PTE_ALLOC_ORDER ); +pte_t *pte =vmem_alloc_pages (1 );if (!pte)return NULL ; -pte_val (empty_pte) = _PAGE_TYPE_EMPTY; -for (i =0 ; i <PTRS_PER_PTE ; i++) - pte[i] = empty_pte; +pte_val (*pte) = _PAGE_TYPE_EMPTY; +memcpy (pte +1 , pte, (PTRS_PER_PTE -1 )*sizeof (pte_t));return pte; }
include/asm-s390/mmu_context.h +24 -26
69 lines not on this page · raw message
include/asm-s390/pgalloc.h +59 -145
254 lines not on this page · raw message
include/asm-s390/pgtable.h +96 -123
335 lines not on this page · raw message
include/asm-s390/processor.h +0 -6
@@ -127,12 +127,6 @@ struct stack_frame {#define ARCH_MIN_TASKALIGN 8 -#ifndef __s390x__ -# define __SWAPPER_PG_DIR __pa(&swapper_pg_dir[0]) + _SEGMENT_TABLE -#else /* __s390x__ */ -# define __SWAPPER_PG_DIR __pa(&swapper_pg_dir[0]) + _REGION_TABLE -#endif /* __s390x__ */ -#define INIT_THREAD { \ .ksp = sizeof(init_stack) + (unsigned long) &init_stack, \ }
include/asm-s390/tlbflush.h +1 -1
@@ -61,7 +61,7 @@ static inline void __tlb_flush_mm(struct* only ran on the local cpu. */ if (MACHINE_HAS_IDTE ) { -pgd_t *shadow_pgd =get_shadow_pgd (mm->pgd); +pgd_t *shadow_pgd =get_shadow_table (mm->pgd);if (shadow_pgd)__tlb_flush_idte (shadow_pgd);
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.
PATCH 10/10 4level-fixup cleanup
In reply to Martin SchwidefskyFrom: Martin Schwidefsky <[email protected]>
Get independent from asm-generic/4level-fixup.h
---
arch/s390/lib/uaccess_pt.c | 7 ++ arch/s390/mm/init.c | 6 +- arch/s390/mm/vmem.c | 34 ++++++++++-- include/asm-s390/page.h | 4 + include/asm-s390/pgalloc.h | 32 ++++++++--- include/asm-s390/pgtable.h | 123 ++++++++++++++++++++++----------------------- include/asm-s390/tlb.h | 2 7 files changed, 128 insertions(+), 80 deletions(-)
arch/s390/lib/uaccess_pt.c +6 -1
@@ -18,13 +18,18 @@static inline pte_t *follow_table (struct mm_struct *mm,unsigned long addr) {pgd_t *pgd; +pud_t *pud;pmd_t *pmd; pgd =pgd_offset (mm, addr);if (pgd_none (*pgd) ||unlikely (pgd_bad (*pgd)))return NULL ; - pmd =pmd_offset (pgd, addr); + pud =pud_offset (pgd, addr); +if (pud_none (*pud) ||unlikely (pud_bad (*pud))) +return NULL ; + + pmd =pmd_offset (pud, addr);if (pmd_none (*pmd) ||unlikely (pmd_bad (*pmd)))return NULL ;
arch/s390/mm/init.c +4 -2
@@ -81,6 +81,7 @@ void show_mem(void)static void __init setup_ro_region (void ) {pgd_t *pgd; +pud_t *pud;pmd_t *pmd;pte_t *pte;pte_t new_pte;
@@ -91,7 +92,8 @@ static void __init setup_ro_region(void)for (; address < end; address +=PAGE_SIZE ) { pgd =pgd_offset_k (address); - pmd =pmd_offset (pgd, address); + pud =pud_offset (pgd, address); + pmd =pmd_offset (pud, address); pte =pte_offset_kernel (pmd, address); new_pte =mk_pte_phys (address,__pgprot (_PAGE_RO)); *pte = new_pte;
@@ -110,7 +112,7 @@ void __init paging_init(void) S390_lowcore.kernel_asce =__pa (init_mm.pgd) &PAGE_MASK ;#ifdef CONFIG_64BIT S390_lowcore.kernel_asce |= _ASCE_TYPE_REGION3 | _ASCE_TABLE_LENGTH; -pgd_val (*((pgd_t *) init_mm.pgd)) = _REGION3_ENTRY_EMPTY; +pud_val (*((pud_t *) init_mm.pgd)) = _REGION3_ENTRY_EMPTY;#else S390_lowcore.kernel_asce |= _ASCE_TABLE_LENGTH;pmd_val (*((pmd_t *) init_mm.pgd)) = _SEGMENT_ENTRY_EMPTY;
arch/s390/mm/vmem.c +28 -6
@@ -73,6 +73,8 @@ static void __init_refok *vmem_alloc_pagreturn alloc_bootmem_pages ((1 << order) *PAGE_SIZE ); } +#define vmem_pud_alloc () ({ BUG(); ((pud_t *) NULL); }) +static inline pmd_t *vmem_pmd_alloc (void ) {pmd_t *pmd =NULL ;
@@ -103,6 +105,7 @@ static int vmem_add_range(unsigned long {unsigned long address;pgd_t *pg_dir; +pud_t *pu_dir;pmd_t *pm_dir;pte_t *pt_dir;pte_t pte;
@@ -111,13 +114,21 @@ static int vmem_add_range(unsigned longfor (address = start; address < start + size; address +=PAGE_SIZE ) { pg_dir =pgd_offset_k (address);if (pgd_none (*pg_dir)) { + pu_dir =vmem_pud_alloc (); +if (!pu_dir) + goto out; +pgd_populate_kernel (&init_mm, pg_dir, pu_dir); + } + + pu_dir =pud_offset (pg_dir, address); +if (pud_none (*pu_dir)) { pm_dir =vmem_pmd_alloc ();if (!pm_dir) goto out; -pgd_populate_kernel (&init_mm, pg_dir, pm_dir); +pud_populate_kernel (&init_mm, pu_dir, pm_dir); } - pm_dir =pmd_offset (pg_dir, address); + pm_dir =pmd_offset (pu_dir, address);if (pmd_none (*pm_dir)) { pt_dir =vmem_pte_alloc ();if (!pt_dir)
@@ -143,6 +154,7 @@ static void vmem_remove_range(unsigned l {unsigned long address;pgd_t *pg_dir; +pud_t *pu_dir;pmd_t *pm_dir;pte_t *pt_dir;pte_t pte;
@@ -150,9 +162,10 @@ static void vmem_remove_range(unsigned lpte_val (pte) = _PAGE_TYPE_EMPTY;for (address = start; address < start + size; address +=PAGE_SIZE ) { pg_dir =pgd_offset_k (address); -if (pgd_none (*pg_dir)) + pu_dir =pud_offset (pg_dir, address); +if (pud_none (*pu_dir))continue ; - pm_dir =pmd_offset (pg_dir, address); + pm_dir =pmd_offset (pu_dir, address);if (pmd_none (*pm_dir))continue ; pt_dir =pte_offset_kernel (pm_dir, address);
@@ -169,6 +182,7 @@ static int vmem_add_mem_map(unsigned lonunsigned long address, start_addr, end_addr;struct page *map_start, *map_end;pgd_t *pg_dir; +pud_t *pu_dir;pmd_t *pm_dir;pte_t *pt_dir;pte_t pte;
@@ -183,13 +197,21 @@ static int vmem_add_mem_map(unsigned lonfor (address = start_addr; address < end_addr; address +=PAGE_SIZE ) { pg_dir =pgd_offset_k (address);if (pgd_none (*pg_dir)) { + pu_dir =vmem_pud_alloc (); +if (!pu_dir) + goto out; +pgd_populate_kernel (&init_mm, pg_dir, pu_dir); + } + + pu_dir =pud_offset (pg_dir, address); +if (pud_none (*pu_dir)) { pm_dir =vmem_pmd_alloc ();if (!pm_dir) goto out; -pgd_populate_kernel (&init_mm, pg_dir, pm_dir); +pud_populate_kernel (&init_mm, pu_dir, pm_dir); } - pm_dir =pmd_offset (pg_dir, address); + pm_dir =pmd_offset (pu_dir, address);if (pmd_none (*pm_dir)) { pt_dir =vmem_pte_alloc ();if (!pt_dir)
include/asm-s390/page.h +4 -0
@@ -82,6 +82,7 @@ typedef struct { unsigned long pte; } pt #ifndef __s390x__ typedef struct { unsigned long pmd; } pmd_t; +typedef struct { unsigned long pud; } pud_t; typedef struct { unsigned long pgd0; unsigned long pgd1;
@@ -90,6 +91,7 @@ typedef struct { } pgd_t;#define pmd_val (x) ((x).pmd) +#define pud_val (x) ((x).pud)#define pgd_val (x) ((x).pgd0)#else /* __s390x__ */
@@ -98,10 +100,12 @@ typedef struct {unsigned long pmd0; unsigned long pmd1; } pmd_t; +typedef struct {unsigned long pud; }pud_t ;typedef struct {unsigned long pgd; }pgd_t ;#define pmd_val (x) ((x).pmd0)#define pmd_val1 (x) ((x).pmd1) +#define pud_val (x) ((x).pud)#define pgd_val (x) ((x).pgd)#endif /* __s390x__ */
include/asm-s390/pgalloc.h +22 -10
@@ -43,11 +43,17 @@ static inline unsigned long pgd_entry_ty return _SEGMENT_ENTRY_EMPTY; } +#define pud_alloc_one (mm,address) ({ BUG(); ((pud_t *)2); }) +#define pud_free (x) do { } while (0) +#define pmd_alloc_one (mm,address) ({ BUG(); ((pmd_t *)2); })#define pmd_free (x) do { } while (0) -#define pgd_populate (mm, pmd, pte) BUG() -#define pgd_populate_kernel (mm, pmd, pte) BUG() +#define pgd_populate (mm, pgd, pud) BUG() +#define pgd_populate_kernel (mm, pgd, pud) BUG() + +#define pud_populate (mm, pud, pmd) BUG() +#define pud_populate_kernel (mm, pud, pmd) BUG()#else /* __s390x__ */
@@ -56,6 +62,9 @@ static inline unsigned long pgd_entry_tyreturn _REGION3_ENTRY_EMPTY; } +#define pud_alloc_one (mm,address) ({ BUG(); ((pud_t *)2); }) +#define pud_free (x) do { } while (0) +static inline pmd_t *pmd_alloc_one (struct mm_struct *mm,unsigned long vmaddr) {unsigned long *crst =crst_table_alloc (mm, s390_noexec);
@@ -65,20 +74,23 @@ static inline pmd_t *pmd_alloc_one(struc }#define pmd_free (pmd) crst_table_free((unsigned long *) pmd) -static inline void pgd_populate_kernel (struct mm_struct *mm, -pgd_t *pgd,pmd_t *pmd) +#define pgd_populate (mm, pgd, pud) BUG() +#define pgd_populate_kernel (mm, pgd, pud) BUG() + +static inline void pud_populate_kernel (struct mm_struct *mm, +pud_t *pud,pmd_t *pmd) { -pgd_val (*pgd) = _REGION3_ENTRY |__pa (pmd); +pud_val (*pud) = _REGION3_ENTRY |__pa (pmd); } -static inline void pgd_populate (struct mm_struct *mm,pgd_t *pgd,pmd_t *pmd) +static inline void pud_populate (struct mm_struct *mm,pud_t *pud,pmd_t *pmd) { -pgd_t *shadow_pgd =get_shadow_table (pgd); +pud_t *shadow_pud =get_shadow_table (pud);pmd_t *shadow_pmd =get_shadow_table (pmd); -if (shadow_pgd && shadow_pmd) -pgd_populate_kernel (mm, shadow_pgd, shadow_pmd); -pgd_populate_kernel (mm, pgd, pmd); +if (shadow_pud && shadow_pmd) +pud_populate_kernel (mm, shadow_pud, shadow_pmd); +pud_populate_kernel (mm, pud, pmd); }#endif /* __s390x__ */
include/asm-s390/pgtable.h +62 -61
221 lines not on this page · raw message
include/asm-s390/tlb.h +2 -0
@@ -121,6 +121,8 @@ static inline void pmd_free_tlb(struct m#endif } +#define pud_free_tlb (tlb, pud) do { } while (0) +#define tlb_start_vma (tlb, vma) do { } while (0)#define tlb_end_vma (tlb, vma) do { } while (0)#define tlb_remove_tlb_entry (tlb, ptep, addr) do { } while (0)
Signature · 4 lines
blue skies, Martin. "Reality continues to ruin my life." - Calvin.