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_RISCV_ISA_EXT_A] = RISCV_ISA_EXT_a, 21 [KVM_RISCV_ISA_EXT_C] = RISCV_ISA_EXT_c, 22 [KVM_RISCV_ISA_EXT_D] = RISCV_ISA_EXT_d, 23 [KVM_RISCV_ISA_EXT_F] = RISCV_ISA_EXT_f, 24 [KVM_RISCV_ISA_EXT_H] = RISCV_ISA_EXT_h, 25 [KVM_RISCV_ISA_EXT_I] = RISCV_ISA_EXT_i, 26 [KVM_RISCV_ISA_EXT_M] = RISCV_ISA_EXT_m, 27 [KVM_RISCV_ISA_EXT_V] = RISCV_ISA_EXT_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(ZICNTR), 69 KVM_ISA_EXT_ARR(ZICOND), 70 KVM_ISA_EXT_ARR(ZICSR), 71 KVM_ISA_EXT_ARR(ZIFENCEI), 72 KVM_ISA_EXT_ARR(ZIHINTNTL), 73 KVM_ISA_EXT_ARR(ZIHINTPAUSE), 74 KVM_ISA_EXT_ARR(ZIHPM), 75 KVM_ISA_EXT_ARR(ZILSD), 76 KVM_ISA_EXT_ARR(ZIMOP), 77 KVM_ISA_EXT_ARR(ZKND), 78 KVM_ISA_EXT_ARR(ZKNE), 79 KVM_ISA_EXT_ARR(ZKNH), 80 KVM_ISA_EXT_ARR(ZKR), 81 KVM_ISA_EXT_ARR(ZKSED), 82 KVM_ISA_EXT_ARR(ZKSH), 83 KVM_ISA_EXT_ARR(ZKT), 84 KVM_ISA_EXT_ARR(ZTSO), 85 KVM_ISA_EXT_ARR(ZVBB), 86 KVM_ISA_EXT_ARR(ZVBC), 87 KVM_ISA_EXT_ARR(ZVFBFMIN), 88 KVM_ISA_EXT_ARR(ZVFBFWMA), 89 KVM_ISA_EXT_ARR(ZVFH), 90 KVM_ISA_EXT_ARR(ZVFHMIN), 91 KVM_ISA_EXT_ARR(ZVKB), 92 KVM_ISA_EXT_ARR(ZVKG), 93 KVM_ISA_EXT_ARR(ZVKNED), 94 KVM_ISA_EXT_ARR(ZVKNHA), 95 KVM_ISA_EXT_ARR(ZVKNHB), 96 KVM_ISA_EXT_ARR(ZVKSED), 97 KVM_ISA_EXT_ARR(ZVKSH), 98 KVM_ISA_EXT_ARR(ZVKT), 99 }; 100 101 unsigned long kvm_riscv_base2isa_ext(unsigned long base_ext) 102 { 103 unsigned long i; 104 105 for (i = 0; i < KVM_RISCV_ISA_EXT_MAX; i++) { 106 if (kvm_isa_ext_arr[i] == base_ext) 107 return i; 108 } 109 110 return KVM_RISCV_ISA_EXT_MAX; 111 } 112 113 int __kvm_riscv_isa_check_host(unsigned long kvm_ext, unsigned long *base_ext) 114 { 115 unsigned long host_ext; 116 117 if (kvm_ext >= KVM_RISCV_ISA_EXT_MAX || 118 kvm_ext >= ARRAY_SIZE(kvm_isa_ext_arr)) 119 return -ENOENT; 120 121 kvm_ext = array_index_nospec(kvm_ext, ARRAY_SIZE(kvm_isa_ext_arr)); 122 switch (kvm_isa_ext_arr[kvm_ext]) { 123 case RISCV_ISA_EXT_SMNPM: 124 /* 125 * Pointer masking effective in (H)S-mode is provided by the 126 * Smnpm extension, so that extension is reported to the guest, 127 * even though the CSR bits for configuring VS-mode pointer 128 * masking on the host side are part of the Ssnpm extension. 129 */ 130 host_ext = RISCV_ISA_EXT_SSNPM; 131 break; 132 default: 133 host_ext = kvm_isa_ext_arr[kvm_ext]; 134 break; 135 } 136 137 if (!__riscv_isa_extension_available(NULL, host_ext)) 138 return -ENOENT; 139 140 if (base_ext) 141 *base_ext = kvm_isa_ext_arr[kvm_ext]; 142 143 return 0; 144 } 145 146 bool kvm_riscv_isa_enable_allowed(unsigned long ext) 147 { 148 switch (ext) { 149 case KVM_RISCV_ISA_EXT_H: 150 return false; 151 case KVM_RISCV_ISA_EXT_SSCOFPMF: 152 /* Sscofpmf depends on interrupt filtering defined in ssaia */ 153 return !kvm_riscv_isa_check_host(SSAIA); 154 case KVM_RISCV_ISA_EXT_SVADU: 155 /* 156 * The henvcfg.ADUE is read-only zero if menvcfg.ADUE is zero. 157 * Guest OS can use Svadu only when host OS enable Svadu. 158 */ 159 return arch_has_hw_pte_young(); 160 case KVM_RISCV_ISA_EXT_V: 161 return riscv_v_vstate_ctrl_user_allowed(); 162 default: 163 break; 164 } 165 166 return true; 167 } 168 169 bool kvm_riscv_isa_disable_allowed(unsigned long ext) 170 { 171 switch (ext) { 172 /* Extensions which don't have any mechanism to disable */ 173 case KVM_RISCV_ISA_EXT_A: 174 case KVM_RISCV_ISA_EXT_C: 175 case KVM_RISCV_ISA_EXT_I: 176 case KVM_RISCV_ISA_EXT_M: 177 /* There is not architectural config bit to disable sscofpmf completely */ 178 case KVM_RISCV_ISA_EXT_SSCOFPMF: 179 case KVM_RISCV_ISA_EXT_SSNPM: 180 case KVM_RISCV_ISA_EXT_SSTC: 181 case KVM_RISCV_ISA_EXT_SVINVAL: 182 case KVM_RISCV_ISA_EXT_SVNAPOT: 183 case KVM_RISCV_ISA_EXT_SVVPTC: 184 case KVM_RISCV_ISA_EXT_ZAAMO: 185 case KVM_RISCV_ISA_EXT_ZABHA: 186 case KVM_RISCV_ISA_EXT_ZACAS: 187 case KVM_RISCV_ISA_EXT_ZALASR: 188 case KVM_RISCV_ISA_EXT_ZALRSC: 189 case KVM_RISCV_ISA_EXT_ZAWRS: 190 case KVM_RISCV_ISA_EXT_ZBA: 191 case KVM_RISCV_ISA_EXT_ZBB: 192 case KVM_RISCV_ISA_EXT_ZBC: 193 case KVM_RISCV_ISA_EXT_ZBKB: 194 case KVM_RISCV_ISA_EXT_ZBKC: 195 case KVM_RISCV_ISA_EXT_ZBKX: 196 case KVM_RISCV_ISA_EXT_ZBS: 197 case KVM_RISCV_ISA_EXT_ZCA: 198 case KVM_RISCV_ISA_EXT_ZCB: 199 case KVM_RISCV_ISA_EXT_ZCD: 200 case KVM_RISCV_ISA_EXT_ZCF: 201 case KVM_RISCV_ISA_EXT_ZCMOP: 202 case KVM_RISCV_ISA_EXT_ZFA: 203 case KVM_RISCV_ISA_EXT_ZFBFMIN: 204 case KVM_RISCV_ISA_EXT_ZFH: 205 case KVM_RISCV_ISA_EXT_ZFHMIN: 206 case KVM_RISCV_ISA_EXT_ZICBOP: 207 case KVM_RISCV_ISA_EXT_ZICCRSE: 208 case KVM_RISCV_ISA_EXT_ZICNTR: 209 case KVM_RISCV_ISA_EXT_ZICOND: 210 case KVM_RISCV_ISA_EXT_ZICSR: 211 case KVM_RISCV_ISA_EXT_ZIFENCEI: 212 case KVM_RISCV_ISA_EXT_ZIHINTNTL: 213 case KVM_RISCV_ISA_EXT_ZIHINTPAUSE: 214 case KVM_RISCV_ISA_EXT_ZIHPM: 215 case KVM_RISCV_ISA_EXT_ZIMOP: 216 case KVM_RISCV_ISA_EXT_ZKND: 217 case KVM_RISCV_ISA_EXT_ZKNE: 218 case KVM_RISCV_ISA_EXT_ZKNH: 219 case KVM_RISCV_ISA_EXT_ZKR: 220 case KVM_RISCV_ISA_EXT_ZKSED: 221 case KVM_RISCV_ISA_EXT_ZKSH: 222 case KVM_RISCV_ISA_EXT_ZKT: 223 case KVM_RISCV_ISA_EXT_ZTSO: 224 case KVM_RISCV_ISA_EXT_ZVBB: 225 case KVM_RISCV_ISA_EXT_ZVBC: 226 case KVM_RISCV_ISA_EXT_ZVFBFMIN: 227 case KVM_RISCV_ISA_EXT_ZVFBFWMA: 228 case KVM_RISCV_ISA_EXT_ZVFH: 229 case KVM_RISCV_ISA_EXT_ZVFHMIN: 230 case KVM_RISCV_ISA_EXT_ZVKB: 231 case KVM_RISCV_ISA_EXT_ZVKG: 232 case KVM_RISCV_ISA_EXT_ZVKNED: 233 case KVM_RISCV_ISA_EXT_ZVKNHA: 234 case KVM_RISCV_ISA_EXT_ZVKNHB: 235 case KVM_RISCV_ISA_EXT_ZVKSED: 236 case KVM_RISCV_ISA_EXT_ZVKSH: 237 case KVM_RISCV_ISA_EXT_ZVKT: 238 return false; 239 /* Extensions which can be disabled using Smstateen */ 240 case KVM_RISCV_ISA_EXT_SSAIA: 241 return riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN); 242 case KVM_RISCV_ISA_EXT_SVADE: 243 /* 244 * The henvcfg.ADUE is read-only zero if menvcfg.ADUE is zero. 245 * Svade can't be disabled unless we support Svadu. 246 */ 247 return arch_has_hw_pte_young(); 248 default: 249 break; 250 } 251 252 return true; 253 } 254