xref: /openbmc/linux/arch/arm64/kvm/hypercalls.c (revision 923961a7ff2e94d3d824d9ea7047178a5a123245)
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