Linux Audio

Check our new training course

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