Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Khalid Aziz and committed by
David S. Miller
75037500 ca827d55

+109 -2
+2
arch/sparc/include/asm/hypervisor.h
··· 570 570 #define HV_FAULT_TYPE_RESV1 13 571 571 #define HV_FAULT_TYPE_UNALIGNED 14 572 572 #define HV_FAULT_TYPE_INV_PGSZ 15 573 + #define HV_FAULT_TYPE_MCD 17 574 + #define HV_FAULT_TYPE_MCD_DIS 18 573 575 /* Values 16 --> -2 are reserved. */ 574 576 #define HV_FAULT_TYPE_MULTIPLE -1 575 577
+2
arch/sparc/include/asm/pgtable_64.h
··· 164 164 #define _PAGE_E_4V _AC(0x0000000000000800,UL) /* side-Effect */ 165 165 #define _PAGE_CP_4V _AC(0x0000000000000400,UL) /* Cacheable in P-Cache */ 166 166 #define _PAGE_CV_4V _AC(0x0000000000000200,UL) /* Cacheable in V-Cache */ 167 + /* Bit 9 is used to enable MCD corruption detection instead on M7 */ 168 + #define _PAGE_MCD_4V _AC(0x0000000000000200,UL) /* Memory Corruption */ 167 169 #define _PAGE_P_4V _AC(0x0000000000000100,UL) /* Privileged Page */ 168 170 #define _PAGE_EXEC_4V _AC(0x0000000000000080,UL) /* Executable Page */ 169 171 #define _PAGE_W_4V _AC(0x0000000000000040,UL) /* Writable */
+10
arch/sparc/include/asm/ttable.h
··· 219 219 nop; \ 220 220 nop; 221 221 222 + #define SUN4V_MCD_PRECISE \ 223 + ldxa [%g0] ASI_SCRATCHPAD, %g2; \ 224 + ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4; \ 225 + ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5; \ 226 + ba,pt %xcc, etrap; \ 227 + rd %pc, %g7; \ 228 + ba,pt %xcc, sun4v_mcd_detect_precise; \ 229 + nop; \ 230 + nop; 231 + 222 232 /* Before touching these macros, you owe it to yourself to go and 223 233 * see how arch/sparc64/kernel/winfixup.S works... -DaveM 224 234 *
+5
arch/sparc/include/uapi/asm/asi.h
··· 145 145 * ASIs, "(4V)" designates SUN4V specific ASIs. "(NG4)" designates SPARC-T4 146 146 * and later ASIs. 147 147 */ 148 + #define ASI_MCD_PRIV_PRIMARY 0x02 /* (NG7) Privileged MCD version VA */ 149 + #define ASI_MCD_REAL 0x05 /* (NG7) Privileged MCD version PA */ 148 150 #define ASI_PHYS_USE_EC 0x14 /* PADDR, E-cachable */ 149 151 #define ASI_PHYS_BYPASS_EC_E 0x15 /* PADDR, E-bit */ 150 152 #define ASI_BLK_AIUP_4V 0x16 /* (4V) Prim, user, block ld/st */ ··· 247 245 #define ASI_UDBL_CONTROL_R 0x7f /* External UDB control regs rd low*/ 248 246 #define ASI_INTR_R 0x7f /* IRQ vector dispatch read */ 249 247 #define ASI_INTR_DATAN_R 0x7f /* (III) In irq vector data reg N */ 248 + #define ASI_MCD_PRIMARY 0x90 /* (NG7) MCD version load/store */ 249 + #define ASI_MCD_ST_BLKINIT_PRIMARY \ 250 + 0x92 /* (NG7) MCD store BLKINIT primary */ 250 251 #define ASI_PIC 0xb0 /* (NG4) PIC registers */ 251 252 #define ASI_PST8_P 0xc0 /* Primary, 8 8-bit, partial */ 252 253 #define ASI_PST8_S 0xc1 /* Secondary, 8 8-bit, partial */
+10
arch/sparc/include/uapi/asm/pstate.h
··· 11 11 * ----------------------------------------------------------------------- 12 12 * 63 12 11 10 9 8 7 6 5 4 3 2 1 0 13 13 */ 14 + /* IG on V9 conflicts with MCDE on M7. PSTATE_MCDE will only be used on 15 + * processors that support ADI which do not use IG, hence there is no 16 + * functional conflict 17 + */ 14 18 #define PSTATE_IG _AC(0x0000000000000800,UL) /* Interrupt Globals. */ 19 + #define PSTATE_MCDE _AC(0x0000000000000800,UL) /* MCD Enable */ 15 20 #define PSTATE_MG _AC(0x0000000000000400,UL) /* MMU Globals. */ 16 21 #define PSTATE_CLE _AC(0x0000000000000200,UL) /* Current Little Endian.*/ 17 22 #define PSTATE_TLE _AC(0x0000000000000100,UL) /* Trap Little Endian. */ ··· 53 48 #define TSTATE_ASI _AC(0x00000000ff000000,UL) /* AddrSpace ID. */ 54 49 #define TSTATE_PIL _AC(0x0000000000f00000,UL) /* %pil (Linux traps)*/ 55 50 #define TSTATE_PSTATE _AC(0x00000000000fff00,UL) /* PSTATE. */ 51 + /* IG on V9 conflicts with MCDE on M7. TSTATE_MCDE will only be used on 52 + * processors that support ADI which do not support IG, hence there is 53 + * no functional conflict 54 + */ 56 55 #define TSTATE_IG _AC(0x0000000000080000,UL) /* Interrupt Globals.*/ 56 + #define TSTATE_MCDE _AC(0x0000000000080000,UL) /* MCD enable. */ 57 57 #define TSTATE_MG _AC(0x0000000000040000,UL) /* MMU Globals. */ 58 58 #define TSTATE_CLE _AC(0x0000000000020000,UL) /* CurrLittleEndian. */ 59 59 #define TSTATE_TLE _AC(0x0000000000010000,UL) /* TrapLittleEndian. */
+3
arch/sparc/kernel/entry.h
··· 160 160 void sun4v_nonresum_error(struct pt_regs *regs, 161 161 unsigned long offset); 162 162 void sun4v_nonresum_overflow(struct pt_regs *regs); 163 + void sun4v_mem_corrupt_detect_precise(struct pt_regs *regs, 164 + unsigned long addr, 165 + unsigned long context); 163 166 164 167 extern unsigned long sun4v_err_itlb_vaddr; 165 168 extern unsigned long sun4v_err_itlb_ctx;
+1
arch/sparc/kernel/head_64.S
··· 897 897 #include "syscalls.S" 898 898 #include "helpers.S" 899 899 #include "sun4v_tlb_miss.S" 900 + #include "sun4v_mcd.S" 900 901 #include "sun4v_ivec.S" 901 902 #include "ktlb.S" 902 903 #include "tsb.S"
+18
arch/sparc/kernel/sun4v_mcd.S
··· 1 + /* sun4v_mcd.S: Sun4v memory corruption detected precise exception handler 2 + * 3 + * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. 4 + * Authors: Bob Picco <bob.picco@oracle.com>, 5 + * Khalid Aziz <khalid.aziz@oracle.com> 6 + * 7 + * This work is licensed under the terms of the GNU GPL, version 2. 8 + */ 9 + .text 10 + .align 32 11 + 12 + sun4v_mcd_detect_precise: 13 + mov %l4, %o1 14 + mov %l5, %o2 15 + call sun4v_mem_corrupt_detect_precise 16 + add %sp, PTREGS_OFF, %o0 17 + ba,a,pt %xcc, rtrap 18 + nop
+54
arch/sparc/kernel/traps_64.c
··· 2656 2656 force_sig_info(SIGBUS, &info, current); 2657 2657 } 2658 2658 2659 + /* sun4v_mem_corrupt_detect_precise() - Handle precise exception on an ADI 2660 + * tag mismatch. 2661 + * 2662 + * ADI version tag mismatch on a load from memory always results in a 2663 + * precise exception. Tag mismatch on a store to memory will result in 2664 + * precise exception if MCDPER or PMCDPER is set to 1. 2665 + */ 2666 + void sun4v_mem_corrupt_detect_precise(struct pt_regs *regs, unsigned long addr, 2667 + unsigned long context) 2668 + { 2669 + siginfo_t info; 2670 + 2671 + if (notify_die(DIE_TRAP, "memory corruption precise exception", regs, 2672 + 0, 0x8, SIGSEGV) == NOTIFY_STOP) 2673 + return; 2674 + 2675 + if (regs->tstate & TSTATE_PRIV) { 2676 + /* MCD exception could happen because the task was running 2677 + * a system call with MCD enabled and passed a non-versioned 2678 + * pointer or pointer with bad version tag to the system 2679 + * call. 2680 + */ 2681 + const struct exception_table_entry *entry; 2682 + 2683 + entry = search_exception_tables(regs->tpc); 2684 + if (entry) { 2685 + /* Looks like a bad syscall parameter */ 2686 + #ifdef DEBUG_EXCEPTIONS 2687 + pr_emerg("Exception: PC<%016lx> faddr<UNKNOWN>\n", 2688 + regs->tpc); 2689 + pr_emerg("EX_TABLE: insn<%016lx> fixup<%016lx>\n", 2690 + regs->tpc, entry->fixup); 2691 + #endif 2692 + regs->tpc = entry->fixup; 2693 + regs->tnpc = regs->tpc + 4; 2694 + return; 2695 + } 2696 + pr_emerg("%s: ADDR[%016lx] CTX[%lx], going.\n", 2697 + __func__, addr, context); 2698 + die_if_kernel("MCD precise", regs); 2699 + } 2700 + 2701 + if (test_thread_flag(TIF_32BIT)) { 2702 + regs->tpc &= 0xffffffff; 2703 + regs->tnpc &= 0xffffffff; 2704 + } 2705 + info.si_signo = SIGSEGV; 2706 + info.si_code = SEGV_ADIPERR; 2707 + info.si_errno = 0; 2708 + info.si_addr = (void __user *) addr; 2709 + info.si_trapno = 0; 2710 + force_sig_info(SIGSEGV, &info, current); 2711 + } 2712 + 2659 2713 void do_privop(struct pt_regs *regs) 2660 2714 { 2661 2715 enum ctx_state prev_state = exception_enter();
+4 -2
arch/sparc/kernel/ttable_64.S
··· 26 26 TRAP_7INSNS(do_illegal_instruction) 27 27 tl0_privop: TRAP(do_privop) 28 28 tl0_resv012: BTRAP(0x12) BTRAP(0x13) BTRAP(0x14) BTRAP(0x15) BTRAP(0x16) BTRAP(0x17) 29 - tl0_resv018: BTRAP(0x18) BTRAP(0x19) BTRAP(0x1a) BTRAP(0x1b) BTRAP(0x1c) BTRAP(0x1d) 30 - tl0_resv01e: BTRAP(0x1e) BTRAP(0x1f) 29 + tl0_resv018: BTRAP(0x18) BTRAP(0x19) 30 + tl0_mcd: SUN4V_MCD_PRECISE 31 + tl0_resv01b: BTRAP(0x1b) 32 + tl0_resv01c: BTRAP(0x1c) BTRAP(0x1d) BTRAP(0x1e) BTRAP(0x1f) 31 33 tl0_fpdis: TRAP_NOSAVE(do_fpdis) 32 34 tl0_fpieee: TRAP_SAVEFPU(do_fpieee) 33 35 tl0_fpother: TRAP_NOSAVE(do_fpother_check_fitos)