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 int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) 13 { 14 u32 func_id = smccc_get_function(vcpu); 15 long val = SMCCC_RET_NOT_SUPPORTED; 16 u32 feature; 17 gpa_t gpa; 18 19 switch (func_id) { 20 case ARM_SMCCC_VERSION_FUNC_ID: 21 val = ARM_SMCCC_VERSION_1_1; 22 break; 23 case ARM_SMCCC_ARCH_FEATURES_FUNC_ID: 24 feature = smccc_get_arg1(vcpu); 25 switch (feature) { 26 case ARM_SMCCC_ARCH_WORKAROUND_1: 27 switch (arm64_get_spectre_v2_state()) { 28 case SPECTRE_VULNERABLE: 29 break; 30 case SPECTRE_MITIGATED: 31 val = SMCCC_RET_SUCCESS; 32 break; 33 case SPECTRE_UNAFFECTED: 34 val = SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED; 35 break; 36 } 37 break; 38 case ARM_SMCCC_ARCH_WORKAROUND_2: 39 switch (arm64_get_spectre_v4_state()) { 40 case SPECTRE_VULNERABLE: 41 break; 42 case SPECTRE_MITIGATED: 43 /* 44 * SSBS everywhere: Indicate no firmware 45 * support, as the SSBS support will be 46 * indicated to the guest and the default is 47 * safe. 48 * 49 * Otherwise, expose a permanent mitigation 50 * to the guest, and hide SSBS so that the 51 * guest stays protected. 52 */ 53 if (cpus_have_final_cap(ARM64_SSBS)) 54 break; 55 fallthrough; 56 case SPECTRE_UNAFFECTED: 57 val = SMCCC_RET_NOT_REQUIRED; 58 break; 59 } 60 break; 61 case ARM_SMCCC_HV_PV_TIME_FEATURES: 62 val = SMCCC_RET_SUCCESS; 63 break; 64 } 65 break; 66 case ARM_SMCCC_HV_PV_TIME_FEATURES: 67 val = kvm_hypercall_pv_features(vcpu); 68 break; 69 case ARM_SMCCC_HV_PV_TIME_ST: 70 gpa = kvm_init_stolen_time(vcpu); 71 if (gpa != GPA_INVALID) 72 val = gpa; 73 break; 74 default: 75 return kvm_psci_call(vcpu); 76 } 77 78 smccc_set_retval(vcpu, val, 0, 0, 0); 79 return 1; 80 } 81