// SPDX-License-Identifier: GPL-2.0
/*
* Common helper functions for kprobes and uprobes
*
* Copyright IBM Corp. 2014
*/
#include <linux/errno.h>
#include <asm /kprobes.h>
#include <asm /dis.h>
int probe_is_prohibited_opcode(u16 *insn)
{
if (!is_known_insn((unsigned char *)insn))
return -EINVAL;
switch (insn[0 ] >> 8 ) {
case 0 x0c: /* bassm */
case 0 x0b: /* bsm */
case 0 x83: /* diag */
case 0 x44: /* ex */
case 0 xac: /* stnsm */
case 0 xad: /* stosm */
return -EINVAL;
case 0 xc6:
switch (insn[0 ] & 0 x0f) {
case 0 x00: /* exrl */
return -EINVAL;
}
}
switch (insn[0 ]) {
case 0 x0101: /* pr */
case 0 xb25a: /* bsa */
case 0 xb240: /* bakr */
case 0 xb258: /* bsg */
case 0 xb218: /* pc */
case 0 xb228: /* pt */
case 0 xb98d: /* epsw */
case 0 xe560: /* tbegin */
case 0 xe561: /* tbeginc */
case 0 xb2f8: /* tend */
return -EINVAL;
}
return 0 ;
}
int probe_get_fixup_type(u16 *insn)
{
/* default fixup method */
int fixup = FIXUP_PSW_NORMAL;
switch (insn[0 ] >> 8 ) {
case 0 x05: /* balr */
case 0 x0d: /* basr */
fixup = FIXUP_RETURN_REGISTER;
/* if r2 = 0, no branch will be taken */
if ((insn[0 ] & 0 x0f) == 0 )
fixup |= FIXUP_BRANCH_NOT_TAKEN;
break ;
case 0 x06: /* bctr */
case 0 x07: /* bcr */
fixup = FIXUP_BRANCH_NOT_TAKEN;
break ;
case 0 x45: /* bal */
case 0 x4d: /* bas */
fixup = FIXUP_RETURN_REGISTER;
break ;
case 0 x47: /* bc */
case 0 x46: /* bct */
case 0 x86: /* bxh */
case 0 x87: /* bxle */
fixup = FIXUP_BRANCH_NOT_TAKEN;
break ;
case 0 x82: /* lpsw */
fixup = FIXUP_NOT_REQUIRED;
break ;
case 0 xb2: /* lpswe */
if ((insn[0 ] & 0 xff) == 0 xb2)
fixup = FIXUP_NOT_REQUIRED;
break ;
case 0 xa7: /* bras */
if ((insn[0 ] & 0 x0f) == 0 x05)
fixup |= FIXUP_RETURN_REGISTER;
break ;
case 0 xc0:
if ((insn[0 ] & 0 x0f) == 0 x05) /* brasl */
fixup |= FIXUP_RETURN_REGISTER;
break ;
case 0 xeb:
switch (insn[2 ] & 0 xff) {
case 0 x44: /* bxhg */
case 0 x45: /* bxleg */
fixup = FIXUP_BRANCH_NOT_TAKEN;
break ;
}
break ;
case 0 xe3: /* bctg */
if ((insn[2 ] & 0 xff) == 0 x46)
fixup = FIXUP_BRANCH_NOT_TAKEN;
break ;
case 0 xec:
switch (insn[2 ] & 0 xff) {
case 0 xe5: /* clgrb */
case 0 xe6: /* cgrb */
case 0 xf6: /* crb */
case 0 xf7: /* clrb */
case 0 xfc: /* cgib */
case 0 xfd: /* cglib */
case 0 xfe: /* cib */
case 0 xff: /* clib */
fixup = FIXUP_BRANCH_NOT_TAKEN;
break ;
}
break ;
}
return fixup;
}
int probe_is_insn_relative_long(u16 *insn)
{
/* Check if we have a RIL-b or RIL-c format instruction which
* we need to modify in order to avoid instruction emulation. */
switch (insn[0 ] >> 8 ) {
case 0 xc0:
if ((insn[0 ] & 0 x0f) == 0 x00) /* larl */
return true ;
break ;
case 0 xc4:
switch (insn[0 ] & 0 x0f) {
case 0 x02: /* llhrl */
case 0 x04: /* lghrl */
case 0 x05: /* lhrl */
case 0 x06: /* llghrl */
case 0 x07: /* sthrl */
case 0 x08: /* lgrl */
case 0 x0b: /* stgrl */
case 0 x0c: /* lgfrl */
case 0 x0d: /* lrl */
case 0 x0e: /* llgfrl */
case 0 x0f: /* strl */
return true ;
}
break ;
case 0 xc6:
switch (insn[0 ] & 0 x0f) {
case 0 x02: /* pfdrl */
case 0 x04: /* cghrl */
case 0 x05: /* chrl */
case 0 x06: /* clghrl */
case 0 x07: /* clhrl */
case 0 x08: /* cgrl */
case 0 x0a: /* clgrl */
case 0 x0c: /* cgfrl */
case 0 x0d: /* crl */
case 0 x0e: /* clgfrl */
case 0 x0f: /* clrl */
return true ;
}
break ;
}
return false ;
}
Messung V0.5 in Prozent C=96 H=93 G=94
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-08)
¤
*© Formatika GbR, Deutschland