~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/s390/hypfs/hypfs_sprp.c

Version: ~ [ linux-5.12 ] ~ [ linux-5.11.16 ] ~ [ linux-5.10.32 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.114 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.188 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.231 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.267 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.267 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *    Hypervisor filesystem for Linux on s390.
  3  *    Set Partition-Resource Parameter interface.
  4  *
  5  *    Copyright IBM Corp. 2013
  6  *    Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
  7  */
  8 
  9 #include <linux/compat.h>
 10 #include <linux/errno.h>
 11 #include <linux/gfp.h>
 12 #include <linux/string.h>
 13 #include <linux/types.h>
 14 #include <linux/uaccess.h>
 15 #include <asm/compat.h>
 16 #include <asm/diag.h>
 17 #include <asm/sclp.h>
 18 #include "hypfs.h"
 19 
 20 #define DIAG304_SET_WEIGHTS     0
 21 #define DIAG304_QUERY_PRP       1
 22 #define DIAG304_SET_CAPPING     2
 23 
 24 #define DIAG304_CMD_MAX         2
 25 
 26 static inline unsigned long __hypfs_sprp_diag304(void *data, unsigned long cmd)
 27 {
 28         register unsigned long _data asm("2") = (unsigned long) data;
 29         register unsigned long _rc asm("3");
 30         register unsigned long _cmd asm("4") = cmd;
 31 
 32         asm volatile("diag %1,%2,0x304\n"
 33                      : "=d" (_rc) : "d" (_data), "d" (_cmd) : "memory");
 34 
 35         return _rc;
 36 }
 37 
 38 static unsigned long hypfs_sprp_diag304(void *data, unsigned long cmd)
 39 {
 40         diag_stat_inc(DIAG_STAT_X304);
 41         return __hypfs_sprp_diag304(data, cmd);
 42 }
 43 
 44 static void hypfs_sprp_free(const void *data)
 45 {
 46         free_page((unsigned long) data);
 47 }
 48 
 49 static int hypfs_sprp_create(void **data_ptr, void **free_ptr, size_t *size)
 50 {
 51         unsigned long rc;
 52         void *data;
 53 
 54         data = (void *) get_zeroed_page(GFP_KERNEL);
 55         if (!data)
 56                 return -ENOMEM;
 57         rc = hypfs_sprp_diag304(data, DIAG304_QUERY_PRP);
 58         if (rc != 1) {
 59                 *data_ptr = *free_ptr = NULL;
 60                 *size = 0;
 61                 free_page((unsigned long) data);
 62                 return -EIO;
 63         }
 64         *data_ptr = *free_ptr = data;
 65         *size = PAGE_SIZE;
 66         return 0;
 67 }
 68 
 69 static int __hypfs_sprp_ioctl(void __user *user_area)
 70 {
 71         struct hypfs_diag304 diag304;
 72         unsigned long cmd;
 73         void __user *udata;
 74         void *data;
 75         int rc;
 76 
 77         if (copy_from_user(&diag304, user_area, sizeof(diag304)))
 78                 return -EFAULT;
 79         if ((diag304.args[0] >> 8) != 0 || diag304.args[1] > DIAG304_CMD_MAX)
 80                 return -EINVAL;
 81 
 82         data = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
 83         if (!data)
 84                 return -ENOMEM;
 85 
 86         udata = (void __user *)(unsigned long) diag304.data;
 87         if (diag304.args[1] == DIAG304_SET_WEIGHTS ||
 88             diag304.args[1] == DIAG304_SET_CAPPING)
 89                 if (copy_from_user(data, udata, PAGE_SIZE)) {
 90                         rc = -EFAULT;
 91                         goto out;
 92                 }
 93 
 94         cmd = *(unsigned long *) &diag304.args[0];
 95         diag304.rc = hypfs_sprp_diag304(data, cmd);
 96 
 97         if (diag304.args[1] == DIAG304_QUERY_PRP)
 98                 if (copy_to_user(udata, data, PAGE_SIZE)) {
 99                         rc = -EFAULT;
100                         goto out;
101                 }
102 
103         rc = copy_to_user(user_area, &diag304, sizeof(diag304)) ? -EFAULT : 0;
104 out:
105         free_page((unsigned long) data);
106         return rc;
107 }
108 
109 static long hypfs_sprp_ioctl(struct file *file, unsigned int cmd,
110                                unsigned long arg)
111 {
112         void __user *argp;
113 
114         if (!capable(CAP_SYS_ADMIN))
115                 return -EACCES;
116         if (is_compat_task())
117                 argp = compat_ptr(arg);
118         else
119                 argp = (void __user *) arg;
120         switch (cmd) {
121         case HYPFS_DIAG304:
122                 return __hypfs_sprp_ioctl(argp);
123         default: /* unknown ioctl number */
124                 return -ENOTTY;
125         }
126         return 0;
127 }
128 
129 static struct hypfs_dbfs_file hypfs_sprp_file = {
130         .name           = "diag_304",
131         .data_create    = hypfs_sprp_create,
132         .data_free      = hypfs_sprp_free,
133         .unlocked_ioctl = hypfs_sprp_ioctl,
134 };
135 
136 int hypfs_sprp_init(void)
137 {
138         if (!sclp.has_sprp)
139                 return 0;
140         return hypfs_dbfs_create_file(&hypfs_sprp_file);
141 }
142 
143 void hypfs_sprp_exit(void)
144 {
145         if (!sclp.has_sprp)
146                 return;
147         hypfs_dbfs_remove_file(&hypfs_sprp_file);
148 }
149 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp