1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (C) 2019 Arm Ltd. 3 4 #include <linux/arm-smccc.h> 5 #include <linux/kvm_host.h> 6 7 #include <asm/kvm_emulate.h> 8 9 #include <kvm/arm_hypercalls.h> 10 #include <kvm/arm_psci.h> 11 12 static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val) 13 { 14 struct system_time_snapshot systime_snapshot; 15 u64 cycles = ~0UL; 16 u32 feature; 17 18 /* 19 * system time and counter value must captured at the same 20 * time to keep consistency and precision. 21 */ 22 ktime_get_snapshot(&systime_snapshot); 23 24 /* 25 * This is only valid if the current clocksource is the 26 * architected counter, as this is the only one the guest 27 * can see. 28 */ 29 if (systime_snapshot.cs_id != CSID_ARM_ARCH_COUNTER) 30 return; 31 32 /* 33 * The guest selects one of the two reference counters 34 * (virtual or physical) with the first argument of the SMCCC 35 * call. In case the identifier is not supported, error out. 36 */ 37 feature = smccc_get_arg1(vcpu); 38 switch (feature) { 39 case KVM_PTP_VIRT_COUNTER: 40 cycles = systime_snapshot.cycles - vcpu_read_sys_reg(vcpu, CNTVOFF_EL2); 41 break; 42 case KVM_PTP_PHYS_COUNTER: 43 cycles = systime_snapshot.cycles; 44 break; 45 default: 46 return; 47 } 48 49 /* 50 * This relies on the top bit of val[0] never being set for 51 * valid values of system time, because that is *really* far 52 * in the future (about 292 years from 1970, and at that stage 53 * nobody will give a damn about it). 54 */ 55 val[0] = upper_32_bits(systime_snapshot.real); 56 val[1] = lower_32_bits(systime_snapshot.real); 57 val[2] = upper_32_bits(cycles); 58 val[3] = lower_32_bits(cycles); 59 } 60 61 int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) 62 { 63 u32 func_id = smccc_get_function(vcpu); 64 u64 val[4] = {SMCCC_RET_NOT_SUPPORTED}; 65 u32 feature; 66 gpa_t gpa; 67 68 switch (func_id) { 69 case ARM_SMCCC_VERSION_FUNC_ID: 70 val[0] = ARM_SMCCC_VERSION_1_1; 71 break; 72 case ARM_SMCCC_ARCH_FEATURES_FUNC_ID: 73 feature = smccc_get_arg1(vcpu); 74 switch (feature) { 75 case ARM_SMCCC_ARCH_WORKAROUND_1: 76 switch (arm64_get_spectre_v2_state()) { 77 case SPECTRE_VULNERABLE: 78 break; 79 case SPECTRE_MITIGATED: 80 val[0] = SMCCC_RET_SUCCESS; 81 break; 82 case SPECTRE_UNAFFECTED: 83 val[0] = SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED; 84 break; 85 } 86 break; 87 case ARM_SMCCC_ARCH_WORKAROUND_2: 88 switch (arm64_get_spectre_v4_state()) { 89 case SPECTRE_VULNERABLE: 90 break; 91 case SPECTRE_MITIGATED: 92 /* 93 * SSBS everywhere: Indicate no firmware 94 * support, as the SSBS support will be 95 * indicated to the guest and the default is 96 * safe. 97 * 98 * Otherwise, expose a permanent mitigation 99 * to the guest, and hide SSBS so that the 100 * guest stays protected. 101 */ 102 if (cpus_have_final_cap(ARM64_SSBS)) 103 break; 104 fallthrough; 105 case SPECTRE_UNAFFECTED: 106 val[0] = SMCCC_RET_NOT_REQUIRED; 107 break; 108 } 109 break; 110 case ARM_SMCCC_ARCH_WORKAROUND_3: 111 switch (arm64_get_spectre_bhb_state()) { 112 case SPECTRE_VULNERABLE: 113 break; 114 case SPECTRE_MITIGATED: 115 val[0] = SMCCC_RET_SUCCESS; 116 break; 117 case SPECTRE_UNAFFECTED: 118 val[0] = SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED; 119 break; 120 } 121 break; 122 case ARM_SMCCC_HV_PV_TIME_FEATURES: 123 val[0] = SMCCC_RET_SUCCESS; 124 break; 125 } 126 break; 127 case ARM_SMCCC_HV_PV_TIME_FEATURES: 128 val[0] = kvm_hypercall_pv_features(vcpu); 129 break; 130 case ARM_SMCCC_HV_PV_TIME_ST: 131 gpa = kvm_init_stolen_time(vcpu); 132 if (gpa != GPA_INVALID) 133 val[0] = gpa; 134 break; 135 case ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID: 136 val[0] = ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_0; 137 val[1] = ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_1; 138 val[2] = ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_2; 139 val[3] = ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3; 140 break; 141 case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID: 142 val[0] = BIT(ARM_SMCCC_KVM_FUNC_FEATURES); 143 val[0] |= BIT(ARM_SMCCC_KVM_FUNC_PTP); 144 break; 145 case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID: 146 kvm_ptp_get_time(vcpu, val); 147 break; 148 case ARM_SMCCC_TRNG_VERSION: 149 case ARM_SMCCC_TRNG_FEATURES: 150 case ARM_SMCCC_TRNG_GET_UUID: 151 case ARM_SMCCC_TRNG_RND32: 152 case ARM_SMCCC_TRNG_RND64: 153 return kvm_trng_call(vcpu); 154 default: 155 return kvm_psci_call(vcpu); 156 } 157 158 smccc_set_retval(vcpu, val[0], val[1], val[2], val[3]); 159 return 1; 160 } 161