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:
Khalid Aziz
2018-02-21 10:15:45 -07:00
committed by David S. Miller
parent ca827d55eb
commit 750375003d
10 changed files with 109 additions and 2 deletions

View File

@@ -160,6 +160,9 @@ void sun4v_resum_overflow(struct pt_regs *regs);
void sun4v_nonresum_error(struct pt_regs *regs,
unsigned long offset);
void sun4v_nonresum_overflow(struct pt_regs *regs);
void sun4v_mem_corrupt_detect_precise(struct pt_regs *regs,
unsigned long addr,
unsigned long context);
extern unsigned long sun4v_err_itlb_vaddr;
extern unsigned long sun4v_err_itlb_ctx;

View File

@@ -897,6 +897,7 @@ sparc64_boot_end:
#include "syscalls.S"
#include "helpers.S"
#include "sun4v_tlb_miss.S"
#include "sun4v_mcd.S"
#include "sun4v_ivec.S"
#include "ktlb.S"
#include "tsb.S"

View File

@@ -0,0 +1,18 @@
/* sun4v_mcd.S: Sun4v memory corruption detected precise exception handler
*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
* Authors: Bob Picco <bob.picco@oracle.com>,
* Khalid Aziz <khalid.aziz@oracle.com>
*
* This work is licensed under the terms of the GNU GPL, version 2.
*/
.text
.align 32
sun4v_mcd_detect_precise:
mov %l4, %o1
mov %l5, %o2
call sun4v_mem_corrupt_detect_precise
add %sp, PTREGS_OFF, %o0
ba,a,pt %xcc, rtrap
nop

View File

@@ -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();

View File

@@ -26,8 +26,10 @@ tl0_ill: membar #Sync
TRAP_7INSNS(do_illegal_instruction)
tl0_privop: TRAP(do_privop)
tl0_resv012: BTRAP(0x12) BTRAP(0x13) BTRAP(0x14) BTRAP(0x15) BTRAP(0x16) BTRAP(0x17)
tl0_resv018: BTRAP(0x18) BTRAP(0x19) BTRAP(0x1a) BTRAP(0x1b) BTRAP(0x1c) BTRAP(0x1d)
tl0_resv01e: BTRAP(0x1e) BTRAP(0x1f)
tl0_resv018: BTRAP(0x18) BTRAP(0x19)
tl0_mcd: SUN4V_MCD_PRECISE
tl0_resv01b: BTRAP(0x1b)
tl0_resv01c: BTRAP(0x1c) BTRAP(0x1d) BTRAP(0x1e) BTRAP(0x1f)
tl0_fpdis: TRAP_NOSAVE(do_fpdis)
tl0_fpieee: TRAP_SAVEFPU(do_fpieee)
tl0_fpother: TRAP_NOSAVE(do_fpother_check_fitos)