xref: /openbmc/linux/arch/arm64/kvm/hypercalls.c (revision 9ed24f4b712b855dcf7be3025b75b051cb73a2b7)
1*9ed24f4bSMarc Zyngier // SPDX-License-Identifier: GPL-2.0
2*9ed24f4bSMarc Zyngier // Copyright (C) 2019 Arm Ltd.
3*9ed24f4bSMarc Zyngier 
4*9ed24f4bSMarc Zyngier #include <linux/arm-smccc.h>
5*9ed24f4bSMarc Zyngier #include <linux/kvm_host.h>
6*9ed24f4bSMarc Zyngier 
7*9ed24f4bSMarc Zyngier #include <asm/kvm_emulate.h>
8*9ed24f4bSMarc Zyngier 
9*9ed24f4bSMarc Zyngier #include <kvm/arm_hypercalls.h>
10*9ed24f4bSMarc Zyngier #include <kvm/arm_psci.h>
11*9ed24f4bSMarc Zyngier 
12*9ed24f4bSMarc Zyngier int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
13*9ed24f4bSMarc Zyngier {
14*9ed24f4bSMarc Zyngier 	u32 func_id = smccc_get_function(vcpu);
15*9ed24f4bSMarc Zyngier 	long val = SMCCC_RET_NOT_SUPPORTED;
16*9ed24f4bSMarc Zyngier 	u32 feature;
17*9ed24f4bSMarc Zyngier 	gpa_t gpa;
18*9ed24f4bSMarc Zyngier 
19*9ed24f4bSMarc Zyngier 	switch (func_id) {
20*9ed24f4bSMarc Zyngier 	case ARM_SMCCC_VERSION_FUNC_ID:
21*9ed24f4bSMarc Zyngier 		val = ARM_SMCCC_VERSION_1_1;
22*9ed24f4bSMarc Zyngier 		break;
23*9ed24f4bSMarc Zyngier 	case ARM_SMCCC_ARCH_FEATURES_FUNC_ID:
24*9ed24f4bSMarc Zyngier 		feature = smccc_get_arg1(vcpu);
25*9ed24f4bSMarc Zyngier 		switch (feature) {
26*9ed24f4bSMarc Zyngier 		case ARM_SMCCC_ARCH_WORKAROUND_1:
27*9ed24f4bSMarc Zyngier 			switch (kvm_arm_harden_branch_predictor()) {
28*9ed24f4bSMarc Zyngier 			case KVM_BP_HARDEN_UNKNOWN:
29*9ed24f4bSMarc Zyngier 				break;
30*9ed24f4bSMarc Zyngier 			case KVM_BP_HARDEN_WA_NEEDED:
31*9ed24f4bSMarc Zyngier 				val = SMCCC_RET_SUCCESS;
32*9ed24f4bSMarc Zyngier 				break;
33*9ed24f4bSMarc Zyngier 			case KVM_BP_HARDEN_NOT_REQUIRED:
34*9ed24f4bSMarc Zyngier 				val = SMCCC_RET_NOT_REQUIRED;
35*9ed24f4bSMarc Zyngier 				break;
36*9ed24f4bSMarc Zyngier 			}
37*9ed24f4bSMarc Zyngier 			break;
38*9ed24f4bSMarc Zyngier 		case ARM_SMCCC_ARCH_WORKAROUND_2:
39*9ed24f4bSMarc Zyngier 			switch (kvm_arm_have_ssbd()) {
40*9ed24f4bSMarc Zyngier 			case KVM_SSBD_FORCE_DISABLE:
41*9ed24f4bSMarc Zyngier 			case KVM_SSBD_UNKNOWN:
42*9ed24f4bSMarc Zyngier 				break;
43*9ed24f4bSMarc Zyngier 			case KVM_SSBD_KERNEL:
44*9ed24f4bSMarc Zyngier 				val = SMCCC_RET_SUCCESS;
45*9ed24f4bSMarc Zyngier 				break;
46*9ed24f4bSMarc Zyngier 			case KVM_SSBD_FORCE_ENABLE:
47*9ed24f4bSMarc Zyngier 			case KVM_SSBD_MITIGATED:
48*9ed24f4bSMarc Zyngier 				val = SMCCC_RET_NOT_REQUIRED;
49*9ed24f4bSMarc Zyngier 				break;
50*9ed24f4bSMarc Zyngier 			}
51*9ed24f4bSMarc Zyngier 			break;
52*9ed24f4bSMarc Zyngier 		case ARM_SMCCC_HV_PV_TIME_FEATURES:
53*9ed24f4bSMarc Zyngier 			val = SMCCC_RET_SUCCESS;
54*9ed24f4bSMarc Zyngier 			break;
55*9ed24f4bSMarc Zyngier 		}
56*9ed24f4bSMarc Zyngier 		break;
57*9ed24f4bSMarc Zyngier 	case ARM_SMCCC_HV_PV_TIME_FEATURES:
58*9ed24f4bSMarc Zyngier 		val = kvm_hypercall_pv_features(vcpu);
59*9ed24f4bSMarc Zyngier 		break;
60*9ed24f4bSMarc Zyngier 	case ARM_SMCCC_HV_PV_TIME_ST:
61*9ed24f4bSMarc Zyngier 		gpa = kvm_init_stolen_time(vcpu);
62*9ed24f4bSMarc Zyngier 		if (gpa != GPA_INVALID)
63*9ed24f4bSMarc Zyngier 			val = gpa;
64*9ed24f4bSMarc Zyngier 		break;
65*9ed24f4bSMarc Zyngier 	default:
66*9ed24f4bSMarc Zyngier 		return kvm_psci_call(vcpu);
67*9ed24f4bSMarc Zyngier 	}
68*9ed24f4bSMarc Zyngier 
69*9ed24f4bSMarc Zyngier 	smccc_set_retval(vcpu, val, 0, 0, 0);
70*9ed24f4bSMarc Zyngier 	return 1;
71*9ed24f4bSMarc Zyngier }
72