in kernel/uprobes.c [270:382]
static void handle_insn_ril(struct arch_uprobe *auprobe, struct pt_regs *regs)
{
union split_register *rx;
struct insn_ril *insn;
unsigned int ilen;
void *uptr;
int rc = 0;
insn = (struct insn_ril *) &auprobe->insn;
rx = (union split_register *) ®s->gprs[insn->reg];
uptr = (void *)(regs->psw.addr + (insn->disp * 2));
ilen = insn_length(insn->opc0);
switch (insn->opc0) {
case 0xc0:
switch (insn->opc1) {
case 0x00: /* larl */
rx->u64 = (unsigned long)uptr;
break;
}
break;
case 0xc4:
switch (insn->opc1) {
case 0x02: /* llhrl */
rc = emu_load_ril((u16 __user *)uptr, &rx->u32[1]);
break;
case 0x04: /* lghrl */
rc = emu_load_ril((s16 __user *)uptr, &rx->u64);
break;
case 0x05: /* lhrl */
rc = emu_load_ril((s16 __user *)uptr, &rx->u32[1]);
break;
case 0x06: /* llghrl */
rc = emu_load_ril((u16 __user *)uptr, &rx->u64);
break;
case 0x08: /* lgrl */
rc = emu_load_ril((u64 __user *)uptr, &rx->u64);
break;
case 0x0c: /* lgfrl */
rc = emu_load_ril((s32 __user *)uptr, &rx->u64);
break;
case 0x0d: /* lrl */
rc = emu_load_ril((u32 __user *)uptr, &rx->u32[1]);
break;
case 0x0e: /* llgfrl */
rc = emu_load_ril((u32 __user *)uptr, &rx->u64);
break;
case 0x07: /* sthrl */
rc = emu_store_ril(regs, (u16 __user *)uptr, &rx->u16[3]);
break;
case 0x0b: /* stgrl */
rc = emu_store_ril(regs, (u64 __user *)uptr, &rx->u64);
break;
case 0x0f: /* strl */
rc = emu_store_ril(regs, (u32 __user *)uptr, &rx->u32[1]);
break;
}
break;
case 0xc6:
switch (insn->opc1) {
case 0x02: /* pfdrl */
if (!test_facility(34))
rc = EMU_ILLEGAL_OP;
break;
case 0x04: /* cghrl */
rc = emu_cmp_ril(regs, (s16 __user *)uptr, &rx->s64);
break;
case 0x05: /* chrl */
rc = emu_cmp_ril(regs, (s16 __user *)uptr, &rx->s32[1]);
break;
case 0x06: /* clghrl */
rc = emu_cmp_ril(regs, (u16 __user *)uptr, &rx->u64);
break;
case 0x07: /* clhrl */
rc = emu_cmp_ril(regs, (u16 __user *)uptr, &rx->u32[1]);
break;
case 0x08: /* cgrl */
rc = emu_cmp_ril(regs, (s64 __user *)uptr, &rx->s64);
break;
case 0x0a: /* clgrl */
rc = emu_cmp_ril(regs, (u64 __user *)uptr, &rx->u64);
break;
case 0x0c: /* cgfrl */
rc = emu_cmp_ril(regs, (s32 __user *)uptr, &rx->s64);
break;
case 0x0d: /* crl */
rc = emu_cmp_ril(regs, (s32 __user *)uptr, &rx->s32[1]);
break;
case 0x0e: /* clgfrl */
rc = emu_cmp_ril(regs, (u32 __user *)uptr, &rx->u64);
break;
case 0x0f: /* clrl */
rc = emu_cmp_ril(regs, (u32 __user *)uptr, &rx->u32[1]);
break;
}
break;
}
adjust_psw_addr(®s->psw, ilen);
switch (rc) {
case EMU_ILLEGAL_OP:
regs->int_code = ilen << 16 | 0x0001;
do_report_trap(regs, SIGILL, ILL_ILLOPC, NULL);
break;
case EMU_SPECIFICATION:
regs->int_code = ilen << 16 | 0x0006;
do_report_trap(regs, SIGILL, ILL_ILLOPC , NULL);
break;
case EMU_ADDRESSING:
regs->int_code = ilen << 16 | 0x0005;
do_report_trap(regs, SIGSEGV, SEGV_MAPERR, NULL);
break;
}
}