1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2026 Qualcomm Technologies, Inc. 4 */ 5 6 #include <linux/cpufeature.h> 7 #include <linux/errno.h> 8 #include <linux/kvm_host.h> 9 #include <linux/nospec.h> 10 #include <linux/pgtable.h> 11 #include <asm/kvm_isa.h> 12 #include <asm/vector.h> 13 14 #define KVM_ISA_EXT_ARR(ext) \ 15 [KVM_RISCV_ISA_EXT_##ext] = RISCV_ISA_EXT_##ext 16 17 /* Mapping between KVM ISA Extension ID & guest ISA extension ID */ 18 static const unsigned long kvm_isa_ext_arr[] = { 19 /* Single letter extensions (alphabetically sorted) */ 20 KVM_ISA_EXT_ARR(A), 21 KVM_ISA_EXT_ARR(C), 22 KVM_ISA_EXT_ARR(D), 23 KVM_ISA_EXT_ARR(F), 24 KVM_ISA_EXT_ARR(H), 25 KVM_ISA_EXT_ARR(I), 26 KVM_ISA_EXT_ARR(M), 27 KVM_ISA_EXT_ARR(V), 28 /* Multi letter extensions (alphabetically sorted) */ 29 KVM_ISA_EXT_ARR(SMNPM), 30 KVM_ISA_EXT_ARR(SMSTATEEN), 31 KVM_ISA_EXT_ARR(SSAIA), 32 KVM_ISA_EXT_ARR(SSCOFPMF), 33 KVM_ISA_EXT_ARR(SSNPM), 34 KVM_ISA_EXT_ARR(SSTC), 35 KVM_ISA_EXT_ARR(SVADE), 36 KVM_ISA_EXT_ARR(SVADU), 37 KVM_ISA_EXT_ARR(SVINVAL), 38 KVM_ISA_EXT_ARR(SVNAPOT), 39 KVM_ISA_EXT_ARR(SVPBMT), 40 KVM_ISA_EXT_ARR(SVVPTC), 41 KVM_ISA_EXT_ARR(ZAAMO), 42 KVM_ISA_EXT_ARR(ZABHA), 43 KVM_ISA_EXT_ARR(ZACAS), 44 KVM_ISA_EXT_ARR(ZALASR), 45 KVM_ISA_EXT_ARR(ZALRSC), 46 KVM_ISA_EXT_ARR(ZAWRS), 47 KVM_ISA_EXT_ARR(ZBA), 48 KVM_ISA_EXT_ARR(ZBB), 49 KVM_ISA_EXT_ARR(ZBC), 50 KVM_ISA_EXT_ARR(ZBKB), 51 KVM_ISA_EXT_ARR(ZBKC), 52 KVM_ISA_EXT_ARR(ZBKX), 53 KVM_ISA_EXT_ARR(ZBS), 54 KVM_ISA_EXT_ARR(ZCA), 55 KVM_ISA_EXT_ARR(ZCB), 56 KVM_ISA_EXT_ARR(ZCD), 57 KVM_ISA_EXT_ARR(ZCF), 58 KVM_ISA_EXT_ARR(ZCLSD), 59 KVM_ISA_EXT_ARR(ZCMOP), 60 KVM_ISA_EXT_ARR(ZFA), 61 KVM_ISA_EXT_ARR(ZFBFMIN), 62 KVM_ISA_EXT_ARR(ZFH), 63 KVM_ISA_EXT_ARR(ZFHMIN), 64 KVM_ISA_EXT_ARR(ZICBOM), 65 KVM_ISA_EXT_ARR(ZICBOP), 66 KVM_ISA_EXT_ARR(ZICBOZ), 67 KVM_ISA_EXT_ARR(ZICCRSE), 68 KVM_ISA_EXT_ARR(ZICFILP), 69 KVM_ISA_EXT_ARR(ZICFISS), 70 KVM_ISA_EXT_ARR(ZICNTR), 71 KVM_ISA_EXT_ARR(ZICOND), 72 KVM_ISA_EXT_ARR(ZICSR), 73 KVM_ISA_EXT_ARR(ZIFENCEI), 74 KVM_ISA_EXT_ARR(ZIHINTNTL), 75 KVM_ISA_EXT_ARR(ZIHINTPAUSE), 76 KVM_ISA_EXT_ARR(ZIHPM), 77 KVM_ISA_EXT_ARR(ZILSD), 78 KVM_ISA_EXT_ARR(ZIMOP), 79 KVM_ISA_EXT_ARR(ZKND), 80 KVM_ISA_EXT_ARR(ZKNE), 81 KVM_ISA_EXT_ARR(ZKNH), 82 KVM_ISA_EXT_ARR(ZKR), 83 KVM_ISA_EXT_ARR(ZKSED), 84 KVM_ISA_EXT_ARR(ZKSH), 85 KVM_ISA_EXT_ARR(ZKT), 86 KVM_ISA_EXT_ARR(ZTSO), 87 KVM_ISA_EXT_ARR(ZVBB), 88 KVM_ISA_EXT_ARR(ZVBC), 89 KVM_ISA_EXT_ARR(ZVFBFMIN), 90 KVM_ISA_EXT_ARR(ZVFBFWMA), 91 KVM_ISA_EXT_ARR(ZVFH), 92 KVM_ISA_EXT_ARR(ZVFHMIN), 93 KVM_ISA_EXT_ARR(ZVKB), 94 KVM_ISA_EXT_ARR(ZVKG), 95 KVM_ISA_EXT_ARR(ZVKNED), 96 KVM_ISA_EXT_ARR(ZVKNHA), 97 KVM_ISA_EXT_ARR(ZVKNHB), 98 KVM_ISA_EXT_ARR(ZVKSED), 99 KVM_ISA_EXT_ARR(ZVKSH), 100 KVM_ISA_EXT_ARR(ZVKT), 101 }; 102 103 unsigned long kvm_riscv_base2isa_ext(unsigned long base_ext) 104 { 105 unsigned long i; 106 107 for (i = 0; i < KVM_RISCV_ISA_EXT_MAX; i++) { 108 if (kvm_isa_ext_arr[i] == base_ext) 109 return i; 110 } 111 112 return KVM_RISCV_ISA_EXT_MAX; 113 } 114 115 int __kvm_riscv_isa_check_host(unsigned long kvm_ext, unsigned long *base_ext) 116 { 117 unsigned long host_ext; 118 119 if (kvm_ext >= KVM_RISCV_ISA_EXT_MAX || 120 kvm_ext >= ARRAY_SIZE(kvm_isa_ext_arr)) 121 return -ENOENT; 122 123 kvm_ext = array_index_nospec(kvm_ext, ARRAY_SIZE(kvm_isa_ext_arr)); 124 switch (kvm_isa_ext_arr[kvm_ext]) { 125 case RISCV_ISA_EXT_SMNPM: 126 /* 127 * Pointer masking effective in (H)S-mode is provided by the 128 * Smnpm extension, so that extension is reported to the guest, 129 * even though the CSR bits for configuring VS-mode pointer 130 * masking on the host side are part of the Ssnpm extension. 131 */ 132 host_ext = RISCV_ISA_EXT_SSNPM; 133 break; 134 default: 135 host_ext = kvm_isa_ext_arr[kvm_ext]; 136 break; 137 } 138 139 if (!__riscv_isa_extension_available(NULL, host_ext)) 140 return -ENOENT; 141 142 if (base_ext) 143 *base_ext = kvm_isa_ext_arr[kvm_ext]; 144 145 return 0; 146 } 147 148 bool kvm_riscv_isa_enable_allowed(unsigned long ext) 149 { 150 switch (ext) { 151 case KVM_RISCV_ISA_EXT_H: 152 return false; 153 case KVM_RISCV_ISA_EXT_SSCOFPMF: 154 /* Sscofpmf depends on interrupt filtering defined in ssaia */ 155 return !kvm_riscv_isa_check_host(SSAIA); 156 case KVM_RISCV_ISA_EXT_SVADU: 157 /* 158 * The henvcfg.ADUE is read-only zero if menvcfg.ADUE is zero. 159 * Guest OS can use Svadu only when host OS enable Svadu. 160 */ 161 return arch_has_hw_pte_young(); 162 case KVM_RISCV_ISA_EXT_V: 163 return riscv_v_vstate_ctrl_user_allowed(); 164 default: 165 break; 166 } 167 168 return true; 169 } 170 171 bool kvm_riscv_isa_disable_allowed(unsigned long ext) 172 { 173 switch (ext) { 174 /* Extensions which don't have any mechanism to disable */ 175 case KVM_RISCV_ISA_EXT_A: 176 case KVM_RISCV_ISA_EXT_C: 177 case KVM_RISCV_ISA_EXT_I: 178 case KVM_RISCV_ISA_EXT_M: 179 /* There is not architectural config bit to disable sscofpmf completely */ 180 case KVM_RISCV_ISA_EXT_SSCOFPMF: 181 case KVM_RISCV_ISA_EXT_SSNPM: 182 case KVM_RISCV_ISA_EXT_SSTC: 183 case KVM_RISCV_ISA_EXT_SVINVAL: 184 case KVM_RISCV_ISA_EXT_SVNAPOT: 185 case KVM_RISCV_ISA_EXT_SVVPTC: 186 case KVM_RISCV_ISA_EXT_ZAAMO: 187 case KVM_RISCV_ISA_EXT_ZABHA: 188 case KVM_RISCV_ISA_EXT_ZACAS: 189 case KVM_RISCV_ISA_EXT_ZALASR: 190 case KVM_RISCV_ISA_EXT_ZALRSC: 191 case KVM_RISCV_ISA_EXT_ZAWRS: 192 case KVM_RISCV_ISA_EXT_ZBA: 193 case KVM_RISCV_ISA_EXT_ZBB: 194 case KVM_RISCV_ISA_EXT_ZBC: 195 case KVM_RISCV_ISA_EXT_ZBKB: 196 case KVM_RISCV_ISA_EXT_ZBKC: 197 case KVM_RISCV_ISA_EXT_ZBKX: 198 case KVM_RISCV_ISA_EXT_ZBS: 199 case KVM_RISCV_ISA_EXT_ZCA: 200 case KVM_RISCV_ISA_EXT_ZCB: 201 case KVM_RISCV_ISA_EXT_ZCD: 202 case KVM_RISCV_ISA_EXT_ZCF: 203 case KVM_RISCV_ISA_EXT_ZCMOP: 204 case KVM_RISCV_ISA_EXT_ZFA: 205 case KVM_RISCV_ISA_EXT_ZFBFMIN: 206 case KVM_RISCV_ISA_EXT_ZFH: 207 case KVM_RISCV_ISA_EXT_ZFHMIN: 208 case KVM_RISCV_ISA_EXT_ZICBOP: 209 case KVM_RISCV_ISA_EXT_ZICCRSE: 210 case KVM_RISCV_ISA_EXT_ZICNTR: 211 case KVM_RISCV_ISA_EXT_ZICOND: 212 case KVM_RISCV_ISA_EXT_ZICSR: 213 case KVM_RISCV_ISA_EXT_ZIFENCEI: 214 case KVM_RISCV_ISA_EXT_ZIHINTNTL: 215 case KVM_RISCV_ISA_EXT_ZIHINTPAUSE: 216 case KVM_RISCV_ISA_EXT_ZIHPM: 217 case KVM_RISCV_ISA_EXT_ZIMOP: 218 case KVM_RISCV_ISA_EXT_ZKND: 219 case KVM_RISCV_ISA_EXT_ZKNE: 220 case KVM_RISCV_ISA_EXT_ZKNH: 221 case KVM_RISCV_ISA_EXT_ZKR: 222 case KVM_RISCV_ISA_EXT_ZKSED: 223 case KVM_RISCV_ISA_EXT_ZKSH: 224 case KVM_RISCV_ISA_EXT_ZKT: 225 case KVM_RISCV_ISA_EXT_ZTSO: 226 case KVM_RISCV_ISA_EXT_ZVBB: 227 case KVM_RISCV_ISA_EXT_ZVBC: 228 case KVM_RISCV_ISA_EXT_ZVFBFMIN: 229 case KVM_RISCV_ISA_EXT_ZVFBFWMA: 230 case KVM_RISCV_ISA_EXT_ZVFH: 231 case KVM_RISCV_ISA_EXT_ZVFHMIN: 232 case KVM_RISCV_ISA_EXT_ZVKB: 233 case KVM_RISCV_ISA_EXT_ZVKG: 234 case KVM_RISCV_ISA_EXT_ZVKNED: 235 case KVM_RISCV_ISA_EXT_ZVKNHA: 236 case KVM_RISCV_ISA_EXT_ZVKNHB: 237 case KVM_RISCV_ISA_EXT_ZVKSED: 238 case KVM_RISCV_ISA_EXT_ZVKSH: 239 case KVM_RISCV_ISA_EXT_ZVKT: 240 return false; 241 /* Extensions which can be disabled using Smstateen */ 242 case KVM_RISCV_ISA_EXT_SSAIA: 243 return riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN); 244 case KVM_RISCV_ISA_EXT_SVADE: 245 /* 246 * The henvcfg.ADUE is read-only zero if menvcfg.ADUE is zero. 247 * Svade can't be disabled unless we support Svadu. 248 */ 249 return arch_has_hw_pte_young(); 250 default: 251 break; 252 } 253 254 return true; 255 } 256