^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) // Copyright (C) 2019 Arm Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/arm-smccc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/kvm_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <asm/kvm_emulate.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <kvm/arm_hypercalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <kvm/arm_psci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) u32 func_id = smccc_get_function(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) long val = SMCCC_RET_NOT_SUPPORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) u32 feature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) gpa_t gpa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) switch (func_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) case ARM_SMCCC_VERSION_FUNC_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) val = ARM_SMCCC_VERSION_1_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) case ARM_SMCCC_ARCH_FEATURES_FUNC_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) feature = smccc_get_arg1(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) switch (feature) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) case ARM_SMCCC_ARCH_WORKAROUND_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) switch (arm64_get_spectre_v2_state()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) case SPECTRE_VULNERABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) case SPECTRE_MITIGATED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) val = SMCCC_RET_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) case SPECTRE_UNAFFECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) val = SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) case ARM_SMCCC_ARCH_WORKAROUND_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) switch (arm64_get_spectre_v4_state()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) case SPECTRE_VULNERABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) case SPECTRE_MITIGATED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * SSBS everywhere: Indicate no firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * support, as the SSBS support will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * indicated to the guest and the default is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * safe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Otherwise, expose a permanent mitigation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * to the guest, and hide SSBS so that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * guest stays protected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (cpus_have_final_cap(ARM64_SSBS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) case SPECTRE_UNAFFECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) val = SMCCC_RET_NOT_REQUIRED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) case ARM_SMCCC_ARCH_WORKAROUND_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) switch (arm64_get_spectre_bhb_state()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) case SPECTRE_VULNERABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) case SPECTRE_MITIGATED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) val = SMCCC_RET_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) case SPECTRE_UNAFFECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) val = SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) case ARM_SMCCC_HV_PV_TIME_FEATURES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) val = SMCCC_RET_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) case ARM_SMCCC_HV_PV_TIME_FEATURES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) val = kvm_hypercall_pv_features(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) case ARM_SMCCC_HV_PV_TIME_ST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) gpa = kvm_init_stolen_time(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (gpa != GPA_INVALID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) val = gpa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) case ARM_SMCCC_TRNG_VERSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) case ARM_SMCCC_TRNG_FEATURES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) case ARM_SMCCC_TRNG_GET_UUID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) case ARM_SMCCC_TRNG_RND32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) case ARM_SMCCC_TRNG_RND64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return kvm_trng_call(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return kvm_psci_call(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) smccc_set_retval(vcpu, val, 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }