Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/s390/linux

Pull s390 patches from Martin Schwidefsky:
 "A new binary interface to be able to query and modify the LPAR
  scheduler weight and cap settings.  Some improvements for the hvc
  terminal over iucv and a couple of bux fixes"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
  s390/hypfs: add interface for diagnose 0x304
  s390: wire up sys_sched_setattr/sys_sched_getattr
  s390/uapi: fix struct statfs64 definition
  s390/uaccess: remove dead extern declarations, make functions static
  s390/uaccess: test if current->mm is set before walking page tables
  s390/zfcpdump: make zfcpdump depend on 64BIT
  s390/32bit: fix cmpxchg64
  s390/xpram: don't modify module parameters
  s390/zcrypt: remove zcrypt kmsg documentation again
  s390/hvc_iucv: Automatically assign free HVC terminal devices
  s390/hvc_iucv: Display connection details through device attributes
  s390/hvc_iucv: fix sparse warning
  s390/vmur: Link parent CCW device during UR device creation
  • Loading branch information
torvalds committed Jan 28, 2014
2 parents be86497 + 07be038 commit e770d73
Show file tree
Hide file tree
Showing 21 changed files with 344 additions and 56 deletions.
1 change: 1 addition & 0 deletions Documentation/ioctl/ioctl-number.txt
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ Code Seq#(hex) Include File Comments
0x09 all linux/raid/md_u.h
0x10 00-0F drivers/char/s390/vmcp.h
0x10 10-1F arch/s390/include/uapi/sclp_ctl.h
0x10 20-2F arch/s390/include/uapi/asm/hypfs.h
0x12 all linux/fs.h
linux/blkpg.h
0x1b all InfiniBand Subsystem <http://infiniband.sourceforge.net/>
Expand Down
20 changes: 0 additions & 20 deletions Documentation/kmsg/s390/zcrypt

This file was deleted.

2 changes: 1 addition & 1 deletion arch/s390/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ config CRASH_DUMP
config ZFCPDUMP
def_bool n
prompt "zfcpdump support"
depends on SMP
depends on 64BIT && SMP
help
Select this option if you want to build an zfcpdump enabled kernel.
Refer to <file:Documentation/s390/zfcpdump.txt> for more details on this.
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/hypfs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@

obj-$(CONFIG_S390_HYPFS_FS) += s390_hypfs.o

s390_hypfs-objs := inode.o hypfs_diag.o hypfs_vm.o hypfs_dbfs.o
s390_hypfs-objs := inode.o hypfs_diag.o hypfs_vm.o hypfs_dbfs.o hypfs_sprp.o
7 changes: 7 additions & 0 deletions arch/s390/hypfs/hypfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <linux/debugfs.h>
#include <linux/workqueue.h>
#include <linux/kref.h>
#include <asm/hypfs.h>

#define REG_FILE_MODE 0440
#define UPDATE_FILE_MODE 0220
Expand All @@ -36,6 +37,10 @@ extern int hypfs_vm_init(void);
extern void hypfs_vm_exit(void);
extern int hypfs_vm_create_files(struct dentry *root);

/* Set Partition-Resource Parameter */
int hypfs_sprp_init(void);
void hypfs_sprp_exit(void);

/* debugfs interface */
struct hypfs_dbfs_file;

Expand All @@ -52,6 +57,8 @@ struct hypfs_dbfs_file {
int (*data_create)(void **data, void **data_free_ptr,
size_t *size);
void (*data_free)(const void *buf_free_ptr);
long (*unlocked_ioctl) (struct file *, unsigned int,
unsigned long);

/* Private data for hypfs_dbfs.c */
struct hypfs_dbfs_data *data;
Expand Down
16 changes: 16 additions & 0 deletions arch/s390/hypfs/hypfs_dbfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,25 @@ static ssize_t dbfs_read(struct file *file, char __user *buf,
return rc;
}

static long dbfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct hypfs_dbfs_file *df;
long rc;

df = file->f_path.dentry->d_inode->i_private;
mutex_lock(&df->lock);
if (df->unlocked_ioctl)
rc = df->unlocked_ioctl(file, cmd, arg);
else
rc = -ENOTTY;
mutex_unlock(&df->lock);
return rc;
}

static const struct file_operations dbfs_ops = {
.read = dbfs_read,
.llseek = no_llseek,
.unlocked_ioctl = dbfs_ioctl,
};

int hypfs_dbfs_create_file(struct hypfs_dbfs_file *df)
Expand Down
141 changes: 141 additions & 0 deletions arch/s390/hypfs/hypfs_sprp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/*
* Hypervisor filesystem for Linux on s390.
* Set Partition-Resource Parameter interface.
*
* Copyright IBM Corp. 2013
* Author(s): Martin Schwidefsky <[email protected]>
*/

#include <linux/compat.h>
#include <linux/errno.h>
#include <linux/gfp.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <asm/compat.h>
#include <asm/sclp.h>
#include "hypfs.h"

#define DIAG304_SET_WEIGHTS 0
#define DIAG304_QUERY_PRP 1
#define DIAG304_SET_CAPPING 2

#define DIAG304_CMD_MAX 2

static unsigned long hypfs_sprp_diag304(void *data, unsigned long cmd)
{
register unsigned long _data asm("2") = (unsigned long) data;
register unsigned long _rc asm("3");
register unsigned long _cmd asm("4") = cmd;

asm volatile("diag %1,%2,0x304\n"
: "=d" (_rc) : "d" (_data), "d" (_cmd) : "memory");

return _rc;
}

static void hypfs_sprp_free(const void *data)
{
free_page((unsigned long) data);
}

static int hypfs_sprp_create(void **data_ptr, void **free_ptr, size_t *size)
{
unsigned long rc;
void *data;

data = (void *) get_zeroed_page(GFP_KERNEL);
if (!data)
return -ENOMEM;
rc = hypfs_sprp_diag304(data, DIAG304_QUERY_PRP);
if (rc != 1) {
*data_ptr = *free_ptr = NULL;
*size = 0;
free_page((unsigned long) data);
return -EIO;
}
*data_ptr = *free_ptr = data;
*size = PAGE_SIZE;
return 0;
}

static int __hypfs_sprp_ioctl(void __user *user_area)
{
struct hypfs_diag304 diag304;
unsigned long cmd;
void __user *udata;
void *data;
int rc;

if (copy_from_user(&diag304, user_area, sizeof(diag304)))
return -EFAULT;
if ((diag304.args[0] >> 8) != 0 || diag304.args[1] > DIAG304_CMD_MAX)
return -EINVAL;

data = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!data)
return -ENOMEM;

udata = (void __user *)(unsigned long) diag304.data;
if (diag304.args[1] == DIAG304_SET_WEIGHTS ||
diag304.args[1] == DIAG304_SET_CAPPING)
if (copy_from_user(data, udata, PAGE_SIZE)) {
rc = -EFAULT;
goto out;
}

cmd = *(unsigned long *) &diag304.args[0];
diag304.rc = hypfs_sprp_diag304(data, cmd);

if (diag304.args[1] == DIAG304_QUERY_PRP)
if (copy_to_user(udata, data, PAGE_SIZE)) {
rc = -EFAULT;
goto out;
}

rc = copy_to_user(user_area, &diag304, sizeof(diag304)) ? -EFAULT : 0;
out:
free_page((unsigned long) data);
return rc;
}

static long hypfs_sprp_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
void __user *argp;

if (!capable(CAP_SYS_ADMIN))
return -EACCES;
if (is_compat_task())
argp = compat_ptr(arg);
else
argp = (void __user *) arg;
switch (cmd) {
case HYPFS_DIAG304:
return __hypfs_sprp_ioctl(argp);
default: /* unknown ioctl number */
return -ENOTTY;
}
return 0;
}

static struct hypfs_dbfs_file hypfs_sprp_file = {
.name = "diag_304",
.data_create = hypfs_sprp_create,
.data_free = hypfs_sprp_free,
.unlocked_ioctl = hypfs_sprp_ioctl,
};

int hypfs_sprp_init(void)
{
if (!sclp_has_sprp())
return 0;
return hypfs_dbfs_create_file(&hypfs_sprp_file);
}

void hypfs_sprp_exit(void)
{
if (!sclp_has_sprp())
return;
hypfs_dbfs_remove_file(&hypfs_sprp_file);
}
15 changes: 11 additions & 4 deletions arch/s390/hypfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,10 +478,14 @@ static int __init hypfs_init(void)
rc = -ENODATA;
goto fail_hypfs_diag_exit;
}
if (hypfs_sprp_init()) {
rc = -ENODATA;
goto fail_hypfs_vm_exit;
}
s390_kobj = kobject_create_and_add("s390", hypervisor_kobj);
if (!s390_kobj) {
rc = -ENOMEM;
goto fail_hypfs_vm_exit;
goto fail_hypfs_sprp_exit;
}
rc = register_filesystem(&hypfs_type);
if (rc)
Expand All @@ -490,6 +494,8 @@ static int __init hypfs_init(void)

fail_filesystem:
kobject_put(s390_kobj);
fail_hypfs_sprp_exit:
hypfs_sprp_exit();
fail_hypfs_vm_exit:
hypfs_vm_exit();
fail_hypfs_diag_exit:
Expand All @@ -502,11 +508,12 @@ static int __init hypfs_init(void)

static void __exit hypfs_exit(void)
{
hypfs_diag_exit();
hypfs_vm_exit();
hypfs_dbfs_exit();
unregister_filesystem(&hypfs_type);
kobject_put(s390_kobj);
hypfs_sprp_exit();
hypfs_vm_exit();
hypfs_diag_exit();
hypfs_dbfs_exit();
}

module_init(hypfs_init)
Expand Down
5 changes: 3 additions & 2 deletions arch/s390/include/asm/cmpxchg.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,12 @@ static inline unsigned long long __cmpxchg64(void *ptr,
{
register_pair rp_old = {.pair = old};
register_pair rp_new = {.pair = new};
unsigned long long *ullptr = ptr;

asm volatile(
" cds %0,%2,%1"
: "+&d" (rp_old), "=Q" (ptr)
: "d" (rp_new), "Q" (ptr)
: "+d" (rp_old), "+Q" (*ullptr)
: "d" (rp_new)
: "memory", "cc");
return rp_old.pair;
}
Expand Down
1 change: 1 addition & 0 deletions arch/s390/include/asm/sclp.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ int sclp_chp_read_info(struct sclp_chp_info *info);
void sclp_get_ipl_info(struct sclp_ipl_info *info);
bool __init sclp_has_linemode(void);
bool __init sclp_has_vt220(void);
bool sclp_has_sprp(void);
int sclp_pci_configure(u32 fid);
int sclp_pci_deconfigure(u32 fid);
int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode);
Expand Down
25 changes: 25 additions & 0 deletions arch/s390/include/uapi/asm/hypfs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* IOCTL interface for hypfs
*
* Copyright IBM Corp. 2013
*
* Author: Martin Schwidefsky <[email protected]>
*/

#ifndef _ASM_HYPFS_CTL_H
#define _ASM_HYPFS_CTL_H

#include <linux/types.h>

struct hypfs_diag304 {
__u32 args[2];
__u64 data;
__u64 rc;
} __attribute__((packed));

#define HYPFS_IOCTL_MAGIC 0x10

#define HYPFS_DIAG304 \
_IOWR(HYPFS_IOCTL_MAGIC, 0x20, struct hypfs_diag304)

#endif
10 changes: 5 additions & 5 deletions arch/s390/include/uapi/asm/statfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ struct statfs {
struct statfs64 {
unsigned int f_type;
unsigned int f_bsize;
unsigned long f_blocks;
unsigned long f_bfree;
unsigned long f_bavail;
unsigned long f_files;
unsigned long f_ffree;
unsigned long long f_blocks;
unsigned long long f_bfree;
unsigned long long f_bavail;
unsigned long long f_files;
unsigned long long f_ffree;
__kernel_fsid_t f_fsid;
unsigned int f_namelen;
unsigned int f_frsize;
Expand Down
2 changes: 2 additions & 0 deletions arch/s390/include/uapi/asm/unistd.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,8 @@
#define __NR_s390_runtime_instr 342
#define __NR_kcmp 343
#define __NR_finit_module 344
#define __NR_sched_setattr 345
#define __NR_sched_getattr 346
#define NR_syscalls 345

/*
Expand Down
11 changes: 11 additions & 0 deletions arch/s390/kernel/compat_wrapper.S
Original file line number Diff line number Diff line change
Expand Up @@ -1412,3 +1412,14 @@ ENTRY(sys_finit_module_wrapper)
llgtr %r3,%r3 # const char __user *
lgfr %r4,%r4 # int
jg sys_finit_module

ENTRY(sys_sched_setattr_wrapper)
lgfr %r2,%r2 # pid_t
llgtr %r3,%r3 # struct sched_attr __user *
jg sys_sched_setattr

ENTRY(sys_sched_getattr_wrapper)
lgfr %r2,%r2 # pid_t
llgtr %r3,%r3 # const char __user *
llgfr %r3,%r3 # unsigned int
jg sys_sched_getattr
2 changes: 2 additions & 0 deletions arch/s390/kernel/syscalls.S
Original file line number Diff line number Diff line change
Expand Up @@ -353,3 +353,5 @@ SYSCALL(sys_process_vm_writev,sys_process_vm_writev,compat_sys_process_vm_writev
SYSCALL(sys_ni_syscall,sys_s390_runtime_instr,sys_s390_runtime_instr_wrapper)
SYSCALL(sys_kcmp,sys_kcmp,sys_kcmp_wrapper)
SYSCALL(sys_finit_module,sys_finit_module,sys_finit_module_wrapper)
SYSCALL(sys_sched_setattr,sys_sched_setattr,sys_sched_setattr_wrapper) /* 345 */
SYSCALL(sys_sched_getattr,sys_sched_getattr,sys_sched_getattr_wrapper)
9 changes: 0 additions & 9 deletions arch/s390/lib/uaccess.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,6 @@
#ifndef __ARCH_S390_LIB_UACCESS_H
#define __ARCH_S390_LIB_UACCESS_H

extern size_t copy_from_user_std(size_t, const void __user *, void *);
extern size_t copy_to_user_std(size_t, void __user *, const void *);
extern size_t strnlen_user_std(size_t, const char __user *);
extern size_t strncpy_from_user_std(size_t, const char __user *, char *);
extern int futex_atomic_cmpxchg_std(u32 *, u32 __user *, u32, u32);
extern int futex_atomic_op_std(int, u32 __user *, int, int *);

extern size_t copy_from_user_pt(size_t, const void __user *, void *);
extern size_t copy_to_user_pt(size_t, void __user *, const void *);
extern int futex_atomic_op_pt(int, u32 __user *, int, int *);
extern int futex_atomic_cmpxchg_pt(u32 *, u32 __user *, u32, u32);

Expand Down
Loading

0 comments on commit e770d73

Please sign in to comment.