sparc64: Add support for ADI register fields, ASIs and traps
SPARC M7 processor adds new control register fields, ASIs and a new trap to support the ADI (Application Data Integrity) feature. This patch adds definitions for these register fields, ASIs and a handler for the new precise memory corruption detected trap. Signed-off-by: Khalid Aziz <khalid.aziz@oracle.com> Cc: Khalid Aziz <khalid@gonehiking.org> Reviewed-by: Anthony Yznaga <anthony.yznaga@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
ca827d55eb
commit
750375003d
@@ -2656,6 +2656,60 @@ void sun4v_do_mna(struct pt_regs *regs, unsigned long addr, unsigned long type_c
|
||||
force_sig_info(SIGBUS, &info, current);
|
||||
}
|
||||
|
||||
/* sun4v_mem_corrupt_detect_precise() - Handle precise exception on an ADI
|
||||
* tag mismatch.
|
||||
*
|
||||
* ADI version tag mismatch on a load from memory always results in a
|
||||
* precise exception. Tag mismatch on a store to memory will result in
|
||||
* precise exception if MCDPER or PMCDPER is set to 1.
|
||||
*/
|
||||
void sun4v_mem_corrupt_detect_precise(struct pt_regs *regs, unsigned long addr,
|
||||
unsigned long context)
|
||||
{
|
||||
siginfo_t info;
|
||||
|
||||
if (notify_die(DIE_TRAP, "memory corruption precise exception", regs,
|
||||
0, 0x8, SIGSEGV) == NOTIFY_STOP)
|
||||
return;
|
||||
|
||||
if (regs->tstate & TSTATE_PRIV) {
|
||||
/* MCD exception could happen because the task was running
|
||||
* a system call with MCD enabled and passed a non-versioned
|
||||
* pointer or pointer with bad version tag to the system
|
||||
* call.
|
||||
*/
|
||||
const struct exception_table_entry *entry;
|
||||
|
||||
entry = search_exception_tables(regs->tpc);
|
||||
if (entry) {
|
||||
/* Looks like a bad syscall parameter */
|
||||
#ifdef DEBUG_EXCEPTIONS
|
||||
pr_emerg("Exception: PC<%016lx> faddr<UNKNOWN>\n",
|
||||
regs->tpc);
|
||||
pr_emerg("EX_TABLE: insn<%016lx> fixup<%016lx>\n",
|
||||
regs->tpc, entry->fixup);
|
||||
#endif
|
||||
regs->tpc = entry->fixup;
|
||||
regs->tnpc = regs->tpc + 4;
|
||||
return;
|
||||
}
|
||||
pr_emerg("%s: ADDR[%016lx] CTX[%lx], going.\n",
|
||||
__func__, addr, context);
|
||||
die_if_kernel("MCD precise", regs);
|
||||
}
|
||||
|
||||
if (test_thread_flag(TIF_32BIT)) {
|
||||
regs->tpc &= 0xffffffff;
|
||||
regs->tnpc &= 0xffffffff;
|
||||
}
|
||||
info.si_signo = SIGSEGV;
|
||||
info.si_code = SEGV_ADIPERR;
|
||||
info.si_errno = 0;
|
||||
info.si_addr = (void __user *) addr;
|
||||
info.si_trapno = 0;
|
||||
force_sig_info(SIGSEGV, &info, current);
|
||||
}
|
||||
|
||||
void do_privop(struct pt_regs *regs)
|
||||
{
|
||||
enum ctx_state prev_state = exception_enter();
|
||||
|
Reference in New Issue
Block a user