powerpc/dexcr: Handle hashchk exception
authorBenjamin Gray <bgray@linux.ibm.com>
Mon, 19 Jun 2023 07:36:25 +0000 (17:36 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Mon, 19 Jun 2023 07:36:26 +0000 (17:36 +1000)
Recognise and pass the appropriate signal to the user program when a
hashchk instruction triggers. This is independent of allowing
configuration of DEXCR[NPHIE], as a hypervisor can enforce this aspect
regardless of the kernel.

The signal mirrors how ARM reports their similar check failure. For
example, their FPAC handler in arch/arm64/kernel/traps.c do_el0_fpac()
does this. When we fail to read the instruction that caused the fault
we send a segfault, similar to how emulate_math() does it.

Signed-off-by: Benjamin Gray <bgray@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://msgid.link/20230616034846.311705-5-bgray@linux.ibm.com
arch/powerpc/include/asm/ppc-opcode.h
arch/powerpc/kernel/traps.c

index ca5a0da7df4e533318eae617f36b40d71735ed65..ef6972aa33b92ace1658405427397304576c2107 100644 (file)
 #define OP_31_XOP_STFSX            663
 #define OP_31_XOP_STFSUX    695
 #define OP_31_XOP_STFDX     727
+#define OP_31_XOP_HASHCHK   754
 #define OP_31_XOP_STFDUX    759
 #define OP_31_XOP_LHBRX     790
 #define OP_31_XOP_LFIWAX    855
index 9bdd79aa51cfc12422476e00b4994534b7192a54..e59ec6d32d37530950b5e883451902990bbc07f0 100644 (file)
@@ -1516,6 +1516,22 @@ static void do_program_check(struct pt_regs *regs)
                                return;
                        }
                }
+
+               if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE) && user_mode(regs)) {
+                       ppc_inst_t insn;
+
+                       if (get_user_instr(insn, (void __user *)regs->nip)) {
+                               _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
+                               return;
+                       }
+
+                       if (ppc_inst_primary_opcode(insn) == 31 &&
+                           get_xop(ppc_inst_val(insn)) == OP_31_XOP_HASHCHK) {
+                               _exception(SIGILL, regs, ILL_ILLOPN, regs->nip);
+                               return;
+                       }
+               }
+
                _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
                return;
        }