19ed24f4bSMarc Zyngier // SPDX-License-Identifier: GPL-2.0 29ed24f4bSMarc Zyngier // Copyright (C) 2019 Arm Ltd. 39ed24f4bSMarc Zyngier 49ed24f4bSMarc Zyngier #include <linux/arm-smccc.h> 59ed24f4bSMarc Zyngier #include <linux/kvm_host.h> 69ed24f4bSMarc Zyngier 79ed24f4bSMarc Zyngier #include <asm/kvm_emulate.h> 89ed24f4bSMarc Zyngier 99ed24f4bSMarc Zyngier #include <kvm/arm_hypercalls.h> 109ed24f4bSMarc Zyngier #include <kvm/arm_psci.h> 119ed24f4bSMarc Zyngier 129ed24f4bSMarc Zyngier int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) 139ed24f4bSMarc Zyngier { 149ed24f4bSMarc Zyngier u32 func_id = smccc_get_function(vcpu); 15*923961a7SWill Deacon u64 val[4] = {SMCCC_RET_NOT_SUPPORTED}; 169ed24f4bSMarc Zyngier u32 feature; 179ed24f4bSMarc Zyngier gpa_t gpa; 189ed24f4bSMarc Zyngier 199ed24f4bSMarc Zyngier switch (func_id) { 209ed24f4bSMarc Zyngier case ARM_SMCCC_VERSION_FUNC_ID: 21*923961a7SWill Deacon val[0] = ARM_SMCCC_VERSION_1_1; 229ed24f4bSMarc Zyngier break; 239ed24f4bSMarc Zyngier case ARM_SMCCC_ARCH_FEATURES_FUNC_ID: 249ed24f4bSMarc Zyngier feature = smccc_get_arg1(vcpu); 259ed24f4bSMarc Zyngier switch (feature) { 269ed24f4bSMarc Zyngier case ARM_SMCCC_ARCH_WORKAROUND_1: 27d4647f0aSWill Deacon switch (arm64_get_spectre_v2_state()) { 28d4647f0aSWill Deacon case SPECTRE_VULNERABLE: 299ed24f4bSMarc Zyngier break; 30d4647f0aSWill Deacon case SPECTRE_MITIGATED: 31*923961a7SWill Deacon val[0] = SMCCC_RET_SUCCESS; 329ed24f4bSMarc Zyngier break; 33d4647f0aSWill Deacon case SPECTRE_UNAFFECTED: 34*923961a7SWill Deacon val[0] = SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED; 359ed24f4bSMarc Zyngier break; 369ed24f4bSMarc Zyngier } 379ed24f4bSMarc Zyngier break; 389ed24f4bSMarc Zyngier case ARM_SMCCC_ARCH_WORKAROUND_2: 39d63d975aSMarc Zyngier switch (arm64_get_spectre_v4_state()) { 40d63d975aSMarc Zyngier case SPECTRE_VULNERABLE: 419ed24f4bSMarc Zyngier break; 42d63d975aSMarc Zyngier case SPECTRE_MITIGATED: 43d63d975aSMarc Zyngier /* 44d63d975aSMarc Zyngier * SSBS everywhere: Indicate no firmware 45d63d975aSMarc Zyngier * support, as the SSBS support will be 46d63d975aSMarc Zyngier * indicated to the guest and the default is 47d63d975aSMarc Zyngier * safe. 48d63d975aSMarc Zyngier * 49d63d975aSMarc Zyngier * Otherwise, expose a permanent mitigation 50d63d975aSMarc Zyngier * to the guest, and hide SSBS so that the 51d63d975aSMarc Zyngier * guest stays protected. 52d63d975aSMarc Zyngier */ 53d63d975aSMarc Zyngier if (cpus_have_final_cap(ARM64_SSBS)) 54d63d975aSMarc Zyngier break; 55d63d975aSMarc Zyngier fallthrough; 56d63d975aSMarc Zyngier case SPECTRE_UNAFFECTED: 57*923961a7SWill Deacon val[0] = SMCCC_RET_NOT_REQUIRED; 589ed24f4bSMarc Zyngier break; 599ed24f4bSMarc Zyngier } 609ed24f4bSMarc Zyngier break; 619ed24f4bSMarc Zyngier case ARM_SMCCC_HV_PV_TIME_FEATURES: 62*923961a7SWill Deacon val[0] = SMCCC_RET_SUCCESS; 639ed24f4bSMarc Zyngier break; 649ed24f4bSMarc Zyngier } 659ed24f4bSMarc Zyngier break; 669ed24f4bSMarc Zyngier case ARM_SMCCC_HV_PV_TIME_FEATURES: 67*923961a7SWill Deacon val[0] = kvm_hypercall_pv_features(vcpu); 689ed24f4bSMarc Zyngier break; 699ed24f4bSMarc Zyngier case ARM_SMCCC_HV_PV_TIME_ST: 709ed24f4bSMarc Zyngier gpa = kvm_init_stolen_time(vcpu); 719ed24f4bSMarc Zyngier if (gpa != GPA_INVALID) 72*923961a7SWill Deacon val[0] = gpa; 73*923961a7SWill Deacon break; 74*923961a7SWill Deacon case ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID: 75*923961a7SWill Deacon val[0] = ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_0; 76*923961a7SWill Deacon val[1] = ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_1; 77*923961a7SWill Deacon val[2] = ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_2; 78*923961a7SWill Deacon val[3] = ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3; 79*923961a7SWill Deacon break; 80*923961a7SWill Deacon case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID: 81*923961a7SWill Deacon val[0] = BIT(ARM_SMCCC_KVM_FUNC_FEATURES); 829ed24f4bSMarc Zyngier break; 83a8e190cdSArd Biesheuvel case ARM_SMCCC_TRNG_VERSION: 84a8e190cdSArd Biesheuvel case ARM_SMCCC_TRNG_FEATURES: 85a8e190cdSArd Biesheuvel case ARM_SMCCC_TRNG_GET_UUID: 86a8e190cdSArd Biesheuvel case ARM_SMCCC_TRNG_RND32: 87a8e190cdSArd Biesheuvel case ARM_SMCCC_TRNG_RND64: 88a8e190cdSArd Biesheuvel return kvm_trng_call(vcpu); 899ed24f4bSMarc Zyngier default: 909ed24f4bSMarc Zyngier return kvm_psci_call(vcpu); 919ed24f4bSMarc Zyngier } 929ed24f4bSMarc Zyngier 93*923961a7SWill Deacon smccc_set_retval(vcpu, val[0], val[1], val[2], val[3]); 949ed24f4bSMarc Zyngier return 1; 959ed24f4bSMarc Zyngier } 96