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