xref: /openbmc/linux/arch/arm64/kvm/hypercalls.c (revision d4647f0a2ad711101067cba69c34716758aa1e48)
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);
159ed24f4bSMarc Zyngier 	long val = 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:
219ed24f4bSMarc Zyngier 		val = 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:
27*d4647f0aSWill Deacon 			switch (arm64_get_spectre_v2_state()) {
28*d4647f0aSWill Deacon 			case SPECTRE_VULNERABLE:
299ed24f4bSMarc Zyngier 				break;
30*d4647f0aSWill Deacon 			case SPECTRE_MITIGATED:
319ed24f4bSMarc Zyngier 				val = SMCCC_RET_SUCCESS;
329ed24f4bSMarc Zyngier 				break;
33*d4647f0aSWill Deacon 			case SPECTRE_UNAFFECTED:
349ed24f4bSMarc Zyngier 				val = SMCCC_RET_NOT_REQUIRED;
359ed24f4bSMarc Zyngier 				break;
369ed24f4bSMarc Zyngier 			}
379ed24f4bSMarc Zyngier 			break;
389ed24f4bSMarc Zyngier 		case ARM_SMCCC_ARCH_WORKAROUND_2:
399ed24f4bSMarc Zyngier 			switch (kvm_arm_have_ssbd()) {
409ed24f4bSMarc Zyngier 			case KVM_SSBD_FORCE_DISABLE:
419ed24f4bSMarc Zyngier 			case KVM_SSBD_UNKNOWN:
429ed24f4bSMarc Zyngier 				break;
439ed24f4bSMarc Zyngier 			case KVM_SSBD_KERNEL:
449ed24f4bSMarc Zyngier 				val = SMCCC_RET_SUCCESS;
459ed24f4bSMarc Zyngier 				break;
469ed24f4bSMarc Zyngier 			case KVM_SSBD_FORCE_ENABLE:
479ed24f4bSMarc Zyngier 			case KVM_SSBD_MITIGATED:
489ed24f4bSMarc Zyngier 				val = SMCCC_RET_NOT_REQUIRED;
499ed24f4bSMarc Zyngier 				break;
509ed24f4bSMarc Zyngier 			}
519ed24f4bSMarc Zyngier 			break;
529ed24f4bSMarc Zyngier 		case ARM_SMCCC_HV_PV_TIME_FEATURES:
539ed24f4bSMarc Zyngier 			val = SMCCC_RET_SUCCESS;
549ed24f4bSMarc Zyngier 			break;
559ed24f4bSMarc Zyngier 		}
569ed24f4bSMarc Zyngier 		break;
579ed24f4bSMarc Zyngier 	case ARM_SMCCC_HV_PV_TIME_FEATURES:
589ed24f4bSMarc Zyngier 		val = kvm_hypercall_pv_features(vcpu);
599ed24f4bSMarc Zyngier 		break;
609ed24f4bSMarc Zyngier 	case ARM_SMCCC_HV_PV_TIME_ST:
619ed24f4bSMarc Zyngier 		gpa = kvm_init_stolen_time(vcpu);
629ed24f4bSMarc Zyngier 		if (gpa != GPA_INVALID)
639ed24f4bSMarc Zyngier 			val = gpa;
649ed24f4bSMarc Zyngier 		break;
659ed24f4bSMarc Zyngier 	default:
669ed24f4bSMarc Zyngier 		return kvm_psci_call(vcpu);
679ed24f4bSMarc Zyngier 	}
689ed24f4bSMarc Zyngier 
699ed24f4bSMarc Zyngier 	smccc_set_retval(vcpu, val, 0, 0, 0);
709ed24f4bSMarc Zyngier 	return 1;
719ed24f4bSMarc Zyngier }
72