root/arch/s390/kernel/runtime_instr.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. runtime_instr_release
  2. disable_runtime_instr
  3. init_runtime_instr_cb
  4. SYSCALL_DEFINE2

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Copyright IBM Corp. 2012
   4  * Author(s): Jan Glauber <jang@linux.vnet.ibm.com>
   5  */
   6 
   7 #include <linux/kernel.h>
   8 #include <linux/syscalls.h>
   9 #include <linux/signal.h>
  10 #include <linux/mm.h>
  11 #include <linux/slab.h>
  12 #include <linux/init.h>
  13 #include <linux/errno.h>
  14 #include <linux/kernel_stat.h>
  15 #include <linux/sched/task_stack.h>
  16 
  17 #include <asm/runtime_instr.h>
  18 #include <asm/cpu_mf.h>
  19 #include <asm/irq.h>
  20 
  21 #include "entry.h"
  22 
  23 /* empty control block to disable RI by loading it */
  24 struct runtime_instr_cb runtime_instr_empty_cb;
  25 
  26 void runtime_instr_release(struct task_struct *tsk)
  27 {
  28         kfree(tsk->thread.ri_cb);
  29 }
  30 
  31 static void disable_runtime_instr(void)
  32 {
  33         struct task_struct *task = current;
  34         struct pt_regs *regs;
  35 
  36         if (!task->thread.ri_cb)
  37                 return;
  38         regs = task_pt_regs(task);
  39         preempt_disable();
  40         load_runtime_instr_cb(&runtime_instr_empty_cb);
  41         kfree(task->thread.ri_cb);
  42         task->thread.ri_cb = NULL;
  43         preempt_enable();
  44 
  45         /*
  46          * Make sure the RI bit is deleted from the PSW. If the user did not
  47          * switch off RI before the system call the process will get a
  48          * specification exception otherwise.
  49          */
  50         regs->psw.mask &= ~PSW_MASK_RI;
  51 }
  52 
  53 static void init_runtime_instr_cb(struct runtime_instr_cb *cb)
  54 {
  55         cb->rla = 0xfff;
  56         cb->s = 1;
  57         cb->k = 1;
  58         cb->ps = 1;
  59         cb->pc = 1;
  60         cb->key = PAGE_DEFAULT_KEY;
  61         cb->v = 1;
  62 }
  63 
  64 /*
  65  * The signum argument is unused. In older kernels it was used to
  66  * specify a real-time signal. For backwards compatibility user space
  67  * should pass a valid real-time signal number (the signum argument
  68  * was checked in older kernels).
  69  */
  70 SYSCALL_DEFINE2(s390_runtime_instr, int, command, int, signum)
  71 {
  72         struct runtime_instr_cb *cb;
  73 
  74         if (!test_facility(64))
  75                 return -EOPNOTSUPP;
  76 
  77         if (command == S390_RUNTIME_INSTR_STOP) {
  78                 disable_runtime_instr();
  79                 return 0;
  80         }
  81 
  82         if (command != S390_RUNTIME_INSTR_START)
  83                 return -EINVAL;
  84 
  85         if (!current->thread.ri_cb) {
  86                 cb = kzalloc(sizeof(*cb), GFP_KERNEL);
  87                 if (!cb)
  88                         return -ENOMEM;
  89         } else {
  90                 cb = current->thread.ri_cb;
  91                 memset(cb, 0, sizeof(*cb));
  92         }
  93 
  94         init_runtime_instr_cb(cb);
  95 
  96         /* now load the control block to make it available */
  97         preempt_disable();
  98         current->thread.ri_cb = cb;
  99         load_runtime_instr_cb(cb);
 100         preempt_enable();
 101         return 0;
 102 }

/* [<][>][^][v][top][bottom][index][help] */