2019-10-21 16:28:15 +01:00
// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2019 Arm Ltd.
# include <linux/arm-smccc.h>
# include <linux/kvm_host.h>
# include <asm/kvm_emulate.h>
# include <kvm/arm_hypercalls.h>
# include <kvm/arm_psci.h>
int kvm_hvc_call_handler ( struct kvm_vcpu * vcpu )
{
u32 func_id = smccc_get_function ( vcpu ) ;
2019-10-21 16:28:16 +01:00
long val = SMCCC_RET_NOT_SUPPORTED ;
2019-10-21 16:28:15 +01:00
u32 feature ;
2019-10-21 16:28:18 +01:00
gpa_t gpa ;
2019-10-21 16:28:15 +01:00
switch ( func_id ) {
case ARM_SMCCC_VERSION_FUNC_ID :
val = ARM_SMCCC_VERSION_1_1 ;
break ;
case ARM_SMCCC_ARCH_FEATURES_FUNC_ID :
feature = smccc_get_arg1 ( vcpu ) ;
switch ( feature ) {
case ARM_SMCCC_ARCH_WORKAROUND_1 :
2020-09-15 23:30:17 +01:00
switch ( arm64_get_spectre_v2_state ( ) ) {
case SPECTRE_VULNERABLE :
2019-10-21 16:28:15 +01:00
break ;
2020-09-15 23:30:17 +01:00
case SPECTRE_MITIGATED :
2019-10-21 16:28:15 +01:00
val = SMCCC_RET_SUCCESS ;
break ;
2020-09-15 23:30:17 +01:00
case SPECTRE_UNAFFECTED :
2019-10-21 16:28:15 +01:00
val = SMCCC_RET_NOT_REQUIRED ;
break ;
}
break ;
case ARM_SMCCC_ARCH_WORKAROUND_2 :
2020-09-18 14:08:54 +01:00
switch ( arm64_get_spectre_v4_state ( ) ) {
case SPECTRE_VULNERABLE :
2019-10-21 16:28:15 +01:00
break ;
2020-09-18 14:08:54 +01:00
case SPECTRE_MITIGATED :
/*
* SSBS everywhere : Indicate no firmware
* support , as the SSBS support will be
* indicated to the guest and the default is
* safe .
*
* Otherwise , expose a permanent mitigation
* to the guest , and hide SSBS so that the
* guest stays protected .
*/
if ( cpus_have_final_cap ( ARM64_SSBS ) )
break ;
fallthrough ;
case SPECTRE_UNAFFECTED :
2019-10-21 16:28:15 +01:00
val = SMCCC_RET_NOT_REQUIRED ;
break ;
}
break ;
2019-10-21 16:28:16 +01:00
case ARM_SMCCC_HV_PV_TIME_FEATURES :
val = SMCCC_RET_SUCCESS ;
break ;
2019-10-21 16:28:15 +01:00
}
break ;
2019-10-21 16:28:16 +01:00
case ARM_SMCCC_HV_PV_TIME_FEATURES :
val = kvm_hypercall_pv_features ( vcpu ) ;
break ;
2019-10-21 16:28:18 +01:00
case ARM_SMCCC_HV_PV_TIME_ST :
gpa = kvm_init_stolen_time ( vcpu ) ;
if ( gpa ! = GPA_INVALID )
val = gpa ;
break ;
2019-10-21 16:28:15 +01:00
default :
return kvm_psci_call ( vcpu ) ;
}
smccc_set_retval ( vcpu , val , 0 , 0 , 0 ) ;
return 1 ;
}