1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Processor Activity Instrumentation support for cryptography counters 4 * 5 * Copyright IBM Corp. 2022 6 * Author(s): Thomas Richter <tmricht@linux.ibm.com> 7 */ 8 #ifndef _ASM_S390_PAI_H 9 #define _ASM_S390_PAI_H 10 11 #include <linux/jump_label.h> 12 #include <asm/lowcore.h> 13 #include <asm/ptrace.h> 14 15 struct qpaci_info_block { 16 u64 header; 17 struct { 18 u64 : 8; 19 u64 num_cc : 8; /* # of supported crypto counters */ 20 u64 : 9; 21 u64 num_nnpa : 7; /* # of supported NNPA counters */ 22 u64 : 32; 23 }; 24 }; 25 26 static inline int qpaci(struct qpaci_info_block *info) 27 { 28 /* Size of info (in double words minus one) */ 29 size_t size = sizeof(*info) / sizeof(u64) - 1; 30 int cc; 31 32 asm volatile( 33 " lgr 0,%[size]\n" 34 " .insn s,0xb28f0000,%[info]\n" 35 " lgr %[size],0\n" 36 " ipm %[cc]\n" 37 " srl %[cc],28\n" 38 : [cc] "=d" (cc), [info] "=Q" (*info), [size] "+&d" (size) 39 : 40 : "0", "cc", "memory"); 41 return cc ? (size + 1) * sizeof(u64) : 0; 42 } 43 44 #define PAI_CRYPTO_BASE 0x1000 /* First event number */ 45 #define PAI_CRYPTO_MAXCTR 256 /* Max # of event counters */ 46 #define PAI_CRYPTO_KERNEL_OFFSET 2048 47 #define PAI_NNPA_BASE 0x1800 /* First event number */ 48 #define PAI_NNPA_MAXCTR 128 /* Max # of event counters */ 49 50 DECLARE_STATIC_KEY_FALSE(pai_key); 51 52 static __always_inline void pai_kernel_enter(struct pt_regs *regs) 53 { 54 if (!IS_ENABLED(CONFIG_PERF_EVENTS)) 55 return; 56 if (!static_branch_unlikely(&pai_key)) 57 return; 58 if (!S390_lowcore.ccd) 59 return; 60 if (!user_mode(regs)) 61 return; 62 WRITE_ONCE(S390_lowcore.ccd, S390_lowcore.ccd | PAI_CRYPTO_KERNEL_OFFSET); 63 } 64 65 static __always_inline void pai_kernel_exit(struct pt_regs *regs) 66 { 67 if (!IS_ENABLED(CONFIG_PERF_EVENTS)) 68 return; 69 if (!static_branch_unlikely(&pai_key)) 70 return; 71 if (!S390_lowcore.ccd) 72 return; 73 if (!user_mode(regs)) 74 return; 75 WRITE_ONCE(S390_lowcore.ccd, S390_lowcore.ccd & ~PAI_CRYPTO_KERNEL_OFFSET); 76 } 77 78 enum paievt_mode { 79 PAI_MODE_NONE, 80 PAI_MODE_SAMPLING, 81 PAI_MODE_COUNTING, 82 }; 83 84 #define PAI_SAVE_AREA(x) ((x)->hw.event_base) 85 #endif 86