1 // SPDX-License-Identifier: GPL-2.0 2 3 #define pr_fmt(fmt) "smccc: KVM: " fmt 4 5 #include <linux/arm-smccc.h> 6 #include <linux/bitmap.h> 7 #include <linux/cache.h> 8 #include <linux/kernel.h> 9 #include <linux/memblock.h> 10 #include <linux/string.h> 11 12 #include <uapi/linux/psci.h> 13 14 #include <asm/hypervisor.h> 15 16 static DECLARE_BITMAP(__kvm_arm_hyp_services, ARM_SMCCC_KVM_NUM_FUNCS) __ro_after_init = { }; 17 18 void __init kvm_init_hyp_services(void) 19 { 20 struct arm_smccc_res res; 21 u32 val[4]; 22 23 if (arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_HVC) 24 return; 25 26 arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID, &res); 27 if (res.a0 != ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_0 || 28 res.a1 != ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_1 || 29 res.a2 != ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_2 || 30 res.a3 != ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3) 31 return; 32 33 memset(&res, 0, sizeof(res)); 34 arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID, &res); 35 36 val[0] = lower_32_bits(res.a0); 37 val[1] = lower_32_bits(res.a1); 38 val[2] = lower_32_bits(res.a2); 39 val[3] = lower_32_bits(res.a3); 40 41 bitmap_from_arr32(__kvm_arm_hyp_services, val, ARM_SMCCC_KVM_NUM_FUNCS); 42 43 pr_info("hypervisor services detected (0x%08lx 0x%08lx 0x%08lx 0x%08lx)\n", 44 res.a3, res.a2, res.a1, res.a0); 45 46 kvm_arch_init_hyp_services(); 47 } 48 49 bool kvm_arm_hyp_service_available(u32 func_id) 50 { 51 if (func_id >= ARM_SMCCC_KVM_NUM_FUNCS) 52 return false; 53 54 return test_bit(func_id, __kvm_arm_hyp_services); 55 } 56 EXPORT_SYMBOL_GPL(kvm_arm_hyp_service_available); 57 58 #ifdef CONFIG_ARM64 59 void __init kvm_arm_target_impl_cpu_init(void) 60 { 61 int i; 62 u32 ver; 63 u64 max_cpus; 64 struct arm_smccc_res res; 65 struct target_impl_cpu *target; 66 67 if (!kvm_arm_hyp_service_available(ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_VER) || 68 !kvm_arm_hyp_service_available(ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS)) 69 return; 70 71 arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_VER_FUNC_ID, 72 0, &res); 73 if (res.a0 != SMCCC_RET_SUCCESS) 74 return; 75 76 /* Version info is in lower 32 bits and is in SMMCCC_VERSION format */ 77 ver = lower_32_bits(res.a1); 78 if (PSCI_VERSION_MAJOR(ver) != 1) { 79 pr_warn("Unsupported target CPU implementation version v%d.%d\n", 80 PSCI_VERSION_MAJOR(ver), PSCI_VERSION_MINOR(ver)); 81 return; 82 } 83 84 if (!res.a2) { 85 pr_warn("No target implementation CPUs specified\n"); 86 return; 87 } 88 89 max_cpus = res.a2; 90 target = memblock_alloc(sizeof(*target) * max_cpus, __alignof__(*target)); 91 if (!target) { 92 pr_warn("Not enough memory for struct target_impl_cpu\n"); 93 return; 94 } 95 96 for (i = 0; i < max_cpus; i++) { 97 arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID, 98 i, 0, 0, &res); 99 if (res.a0 != SMCCC_RET_SUCCESS) { 100 pr_warn("Discovering target implementation CPUs failed\n"); 101 goto mem_free; 102 } 103 target[i].midr = res.a1; 104 target[i].revidr = res.a2; 105 target[i].aidr = res.a3; 106 } 107 108 if (!cpu_errata_set_target_impl(max_cpus, target)) { 109 pr_warn("Failed to set target implementation CPUs\n"); 110 goto mem_free; 111 } 112 113 pr_info("Number of target implementation CPUs is %lld\n", max_cpus); 114 return; 115 116 mem_free: 117 memblock_free(target, sizeof(*target) * max_cpus); 118 } 119 #endif 120