1 /* 2 * Copyright IBM Corp. 2012 3 * Author(s): Jan Glauber <jang@linux.vnet.ibm.com> 4 */ 5 6 #include <linux/kernel.h> 7 #include <linux/syscalls.h> 8 #include <linux/signal.h> 9 #include <linux/mm.h> 10 #include <linux/slab.h> 11 #include <linux/init.h> 12 #include <linux/errno.h> 13 #include <linux/kernel_stat.h> 14 #include <asm/runtime_instr.h> 15 #include <asm/cpu_mf.h> 16 #include <asm/irq.h> 17 18 /* empty control block to disable RI by loading it */ 19 struct runtime_instr_cb runtime_instr_empty_cb; 20 21 static int runtime_instr_avail(void) 22 { 23 return test_facility(64); 24 } 25 26 static void disable_runtime_instr(void) 27 { 28 struct pt_regs *regs = task_pt_regs(current); 29 30 load_runtime_instr_cb(&runtime_instr_empty_cb); 31 32 /* 33 * Make sure the RI bit is deleted from the PSW. If the user did not 34 * switch off RI before the system call the process will get a 35 * specification exception otherwise. 36 */ 37 regs->psw.mask &= ~PSW_MASK_RI; 38 } 39 40 static void init_runtime_instr_cb(struct runtime_instr_cb *cb) 41 { 42 cb->buf_limit = 0xfff; 43 cb->int_requested = 1; 44 cb->pstate = 1; 45 cb->pstate_set_buf = 1; 46 cb->pstate_sample = 1; 47 cb->pstate_collect = 1; 48 cb->key = PAGE_DEFAULT_KEY; 49 cb->valid = 1; 50 } 51 52 void exit_thread_runtime_instr(void) 53 { 54 struct task_struct *task = current; 55 56 if (!task->thread.ri_cb) 57 return; 58 disable_runtime_instr(); 59 kfree(task->thread.ri_cb); 60 task->thread.ri_signum = 0; 61 task->thread.ri_cb = NULL; 62 } 63 64 static void runtime_instr_int_handler(struct ext_code ext_code, 65 unsigned int param32, unsigned long param64) 66 { 67 struct siginfo info; 68 69 if (!(param32 & CPU_MF_INT_RI_MASK)) 70 return; 71 72 inc_irq_stat(IRQEXT_CMR); 73 74 if (!current->thread.ri_cb) 75 return; 76 if (current->thread.ri_signum < SIGRTMIN || 77 current->thread.ri_signum > SIGRTMAX) { 78 WARN_ON_ONCE(1); 79 return; 80 } 81 82 memset(&info, 0, sizeof(info)); 83 info.si_signo = current->thread.ri_signum; 84 info.si_code = SI_QUEUE; 85 if (param32 & CPU_MF_INT_RI_BUF_FULL) 86 info.si_int = ENOBUFS; 87 else if (param32 & CPU_MF_INT_RI_HALTED) 88 info.si_int = ECANCELED; 89 else 90 return; /* unknown reason */ 91 92 send_sig_info(current->thread.ri_signum, &info, current); 93 } 94 95 SYSCALL_DEFINE2(s390_runtime_instr, int, command, int, signum) 96 { 97 struct runtime_instr_cb *cb; 98 99 if (!runtime_instr_avail()) 100 return -EOPNOTSUPP; 101 102 if (command == S390_RUNTIME_INSTR_STOP) { 103 preempt_disable(); 104 exit_thread_runtime_instr(); 105 preempt_enable(); 106 return 0; 107 } 108 109 if (command != S390_RUNTIME_INSTR_START || 110 (signum < SIGRTMIN || signum > SIGRTMAX)) 111 return -EINVAL; 112 113 if (!current->thread.ri_cb) { 114 cb = kzalloc(sizeof(*cb), GFP_KERNEL); 115 if (!cb) 116 return -ENOMEM; 117 } else { 118 cb = current->thread.ri_cb; 119 memset(cb, 0, sizeof(*cb)); 120 } 121 122 init_runtime_instr_cb(cb); 123 current->thread.ri_signum = signum; 124 125 /* now load the control block to make it available */ 126 preempt_disable(); 127 current->thread.ri_cb = cb; 128 load_runtime_instr_cb(cb); 129 preempt_enable(); 130 return 0; 131 } 132 133 static int __init runtime_instr_init(void) 134 { 135 int rc; 136 137 if (!runtime_instr_avail()) 138 return 0; 139 140 irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT); 141 rc = register_external_irq(EXT_IRQ_MEASURE_ALERT, 142 runtime_instr_int_handler); 143 if (rc) 144 irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT); 145 else 146 pr_info("Runtime instrumentation facility initialized\n"); 147 return rc; 148 } 149 device_initcall(runtime_instr_init); 150