root/arch/s390/lib/probes.c

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

DEFINITIONS

This source file includes following definitions.
  1. probe_is_prohibited_opcode
  2. probe_get_fixup_type
  3. probe_is_insn_relative_long

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  *    Common helper functions for kprobes and uprobes
   4  *
   5  *    Copyright IBM Corp. 2014
   6  */
   7 
   8 #include <linux/errno.h>
   9 #include <asm/kprobes.h>
  10 #include <asm/dis.h>
  11 
  12 int probe_is_prohibited_opcode(u16 *insn)
  13 {
  14         if (!is_known_insn((unsigned char *)insn))
  15                 return -EINVAL;
  16         switch (insn[0] >> 8) {
  17         case 0x0c:      /* bassm */
  18         case 0x0b:      /* bsm   */
  19         case 0x83:      /* diag  */
  20         case 0x44:      /* ex    */
  21         case 0xac:      /* stnsm */
  22         case 0xad:      /* stosm */
  23                 return -EINVAL;
  24         case 0xc6:
  25                 switch (insn[0] & 0x0f) {
  26                 case 0x00: /* exrl   */
  27                         return -EINVAL;
  28                 }
  29         }
  30         switch (insn[0]) {
  31         case 0x0101:    /* pr    */
  32         case 0xb25a:    /* bsa   */
  33         case 0xb240:    /* bakr  */
  34         case 0xb258:    /* bsg   */
  35         case 0xb218:    /* pc    */
  36         case 0xb228:    /* pt    */
  37         case 0xb98d:    /* epsw  */
  38         case 0xe560:    /* tbegin */
  39         case 0xe561:    /* tbeginc */
  40         case 0xb2f8:    /* tend  */
  41                 return -EINVAL;
  42         }
  43         return 0;
  44 }
  45 
  46 int probe_get_fixup_type(u16 *insn)
  47 {
  48         /* default fixup method */
  49         int fixup = FIXUP_PSW_NORMAL;
  50 
  51         switch (insn[0] >> 8) {
  52         case 0x05:      /* balr */
  53         case 0x0d:      /* basr */
  54                 fixup = FIXUP_RETURN_REGISTER;
  55                 /* if r2 = 0, no branch will be taken */
  56                 if ((insn[0] & 0x0f) == 0)
  57                         fixup |= FIXUP_BRANCH_NOT_TAKEN;
  58                 break;
  59         case 0x06:      /* bctr */
  60         case 0x07:      /* bcr  */
  61                 fixup = FIXUP_BRANCH_NOT_TAKEN;
  62                 break;
  63         case 0x45:      /* bal  */
  64         case 0x4d:      /* bas  */
  65                 fixup = FIXUP_RETURN_REGISTER;
  66                 break;
  67         case 0x47:      /* bc   */
  68         case 0x46:      /* bct  */
  69         case 0x86:      /* bxh  */
  70         case 0x87:      /* bxle */
  71                 fixup = FIXUP_BRANCH_NOT_TAKEN;
  72                 break;
  73         case 0x82:      /* lpsw */
  74                 fixup = FIXUP_NOT_REQUIRED;
  75                 break;
  76         case 0xb2:      /* lpswe */
  77                 if ((insn[0] & 0xff) == 0xb2)
  78                         fixup = FIXUP_NOT_REQUIRED;
  79                 break;
  80         case 0xa7:      /* bras */
  81                 if ((insn[0] & 0x0f) == 0x05)
  82                         fixup |= FIXUP_RETURN_REGISTER;
  83                 break;
  84         case 0xc0:
  85                 if ((insn[0] & 0x0f) == 0x05)   /* brasl */
  86                         fixup |= FIXUP_RETURN_REGISTER;
  87                 break;
  88         case 0xeb:
  89                 switch (insn[2] & 0xff) {
  90                 case 0x44: /* bxhg  */
  91                 case 0x45: /* bxleg */
  92                         fixup = FIXUP_BRANCH_NOT_TAKEN;
  93                         break;
  94                 }
  95                 break;
  96         case 0xe3:      /* bctg */
  97                 if ((insn[2] & 0xff) == 0x46)
  98                         fixup = FIXUP_BRANCH_NOT_TAKEN;
  99                 break;
 100         case 0xec:
 101                 switch (insn[2] & 0xff) {
 102                 case 0xe5: /* clgrb */
 103                 case 0xe6: /* cgrb  */
 104                 case 0xf6: /* crb   */
 105                 case 0xf7: /* clrb  */
 106                 case 0xfc: /* cgib  */
 107                 case 0xfd: /* cglib */
 108                 case 0xfe: /* cib   */
 109                 case 0xff: /* clib  */
 110                         fixup = FIXUP_BRANCH_NOT_TAKEN;
 111                         break;
 112                 }
 113                 break;
 114         }
 115         return fixup;
 116 }
 117 
 118 int probe_is_insn_relative_long(u16 *insn)
 119 {
 120         /* Check if we have a RIL-b or RIL-c format instruction which
 121          * we need to modify in order to avoid instruction emulation. */
 122         switch (insn[0] >> 8) {
 123         case 0xc0:
 124                 if ((insn[0] & 0x0f) == 0x00) /* larl */
 125                         return true;
 126                 break;
 127         case 0xc4:
 128                 switch (insn[0] & 0x0f) {
 129                 case 0x02: /* llhrl  */
 130                 case 0x04: /* lghrl  */
 131                 case 0x05: /* lhrl   */
 132                 case 0x06: /* llghrl */
 133                 case 0x07: /* sthrl  */
 134                 case 0x08: /* lgrl   */
 135                 case 0x0b: /* stgrl  */
 136                 case 0x0c: /* lgfrl  */
 137                 case 0x0d: /* lrl    */
 138                 case 0x0e: /* llgfrl */
 139                 case 0x0f: /* strl   */
 140                         return true;
 141                 }
 142                 break;
 143         case 0xc6:
 144                 switch (insn[0] & 0x0f) {
 145                 case 0x02: /* pfdrl  */
 146                 case 0x04: /* cghrl  */
 147                 case 0x05: /* chrl   */
 148                 case 0x06: /* clghrl */
 149                 case 0x07: /* clhrl  */
 150                 case 0x08: /* cgrl   */
 151                 case 0x0a: /* clgrl  */
 152                 case 0x0c: /* cgfrl  */
 153                 case 0x0d: /* crl    */
 154                 case 0x0e: /* clgfrl */
 155                 case 0x0f: /* clrl   */
 156                         return true;
 157                 }
 158                 break;
 159         }
 160         return false;
 161 }

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