cregit-Linux how code gets into the kernel

Release 4.14 arch/s390/hypfs/hypfs_sprp.c

Directory: arch/s390/hypfs
// SPDX-License-Identifier: GPL-2.0
/*
 *    Hypervisor filesystem for Linux on s390.
 *    Set Partition-Resource Parameter interface.
 *
 *    Copyright IBM Corp. 2013
 *    Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
 */

#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/diag.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 inline 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; }

Contributors

PersonTokensPropCommitsCommitProp
Martin Schwidefsky57100.00%2100.00%
Total57100.00%2100.00%


static unsigned long hypfs_sprp_diag304(void *data, unsigned long cmd) { diag_stat_inc(DIAG_STAT_X304); return __hypfs_sprp_diag304(data, cmd); }

Contributors

PersonTokensPropCommitsCommitProp
Martin Schwidefsky28100.00%1100.00%
Total28100.00%1100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
Martin Schwidefsky20100.00%1100.00%
Total20100.00%1100.00%


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; }

Contributors

PersonTokensPropCommitsCommitProp
Martin Schwidefsky107100.00%1100.00%
Total107100.00%1100.00%


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; }

Contributors

PersonTokensPropCommitsCommitProp
Martin Schwidefsky249100.00%1100.00%
Total249100.00%1100.00%


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; }

Contributors

PersonTokensPropCommitsCommitProp
Martin Schwidefsky82100.00%1100.00%
Total82100.00%1100.00%

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); }

Contributors

PersonTokensPropCommitsCommitProp
Martin Schwidefsky2187.50%150.00%
David Hildenbrand312.50%150.00%
Total24100.00%2100.00%


void hypfs_sprp_exit(void) { if (!sclp.has_sprp) return; hypfs_dbfs_remove_file(&hypfs_sprp_file); }

Contributors

PersonTokensPropCommitsCommitProp
Martin Schwidefsky1885.71%150.00%
David Hildenbrand314.29%150.00%
Total21100.00%2100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Martin Schwidefsky65698.94%250.00%
David Hildenbrand60.90%125.00%
Greg Kroah-Hartman10.15%125.00%
Total663100.00%4100.00%
Directory: arch/s390/hypfs
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.