Christoffer Dall | 55009c6 | 2019-10-21 16:28:15 +0100 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | // Copyright (C) 2019 Arm Ltd. |
| 3 | |
| 4 | #include <linux/arm-smccc.h> |
| 5 | #include <linux/kvm_host.h> |
| 6 | |
| 7 | #include <asm/kvm_emulate.h> |
| 8 | |
| 9 | #include <kvm/arm_hypercalls.h> |
| 10 | #include <kvm/arm_psci.h> |
| 11 | |
| 12 | int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) |
| 13 | { |
| 14 | u32 func_id = smccc_get_function(vcpu); |
Steven Price | b48c1a4 | 2019-10-21 16:28:16 +0100 | [diff] [blame] | 15 | long val = SMCCC_RET_NOT_SUPPORTED; |
Christoffer Dall | 55009c6 | 2019-10-21 16:28:15 +0100 | [diff] [blame] | 16 | u32 feature; |
Steven Price | 8564d63 | 2019-10-21 16:28:18 +0100 | [diff] [blame] | 17 | gpa_t gpa; |
Christoffer Dall | 55009c6 | 2019-10-21 16:28:15 +0100 | [diff] [blame] | 18 | |
| 19 | switch (func_id) { |
| 20 | case ARM_SMCCC_VERSION_FUNC_ID: |
| 21 | val = ARM_SMCCC_VERSION_1_1; |
| 22 | break; |
| 23 | case ARM_SMCCC_ARCH_FEATURES_FUNC_ID: |
| 24 | feature = smccc_get_arg1(vcpu); |
| 25 | switch (feature) { |
| 26 | case ARM_SMCCC_ARCH_WORKAROUND_1: |
Will Deacon | d4647f0 | 2020-09-15 23:30:17 +0100 | [diff] [blame] | 27 | switch (arm64_get_spectre_v2_state()) { |
| 28 | case SPECTRE_VULNERABLE: |
Christoffer Dall | 55009c6 | 2019-10-21 16:28:15 +0100 | [diff] [blame] | 29 | break; |
Will Deacon | d4647f0 | 2020-09-15 23:30:17 +0100 | [diff] [blame] | 30 | case SPECTRE_MITIGATED: |
Christoffer Dall | 55009c6 | 2019-10-21 16:28:15 +0100 | [diff] [blame] | 31 | val = SMCCC_RET_SUCCESS; |
| 32 | break; |
Will Deacon | d4647f0 | 2020-09-15 23:30:17 +0100 | [diff] [blame] | 33 | case SPECTRE_UNAFFECTED: |
Stephen Boyd | 1de111b | 2020-10-23 08:47:50 -0700 | [diff] [blame] | 34 | val = SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED; |
Christoffer Dall | 55009c6 | 2019-10-21 16:28:15 +0100 | [diff] [blame] | 35 | break; |
| 36 | } |
| 37 | break; |
| 38 | case ARM_SMCCC_ARCH_WORKAROUND_2: |
Marc Zyngier | d63d975 | 2020-09-18 14:08:54 +0100 | [diff] [blame] | 39 | switch (arm64_get_spectre_v4_state()) { |
| 40 | case SPECTRE_VULNERABLE: |
Christoffer Dall | 55009c6 | 2019-10-21 16:28:15 +0100 | [diff] [blame] | 41 | break; |
Marc Zyngier | d63d975 | 2020-09-18 14:08:54 +0100 | [diff] [blame] | 42 | case SPECTRE_MITIGATED: |
| 43 | /* |
| 44 | * SSBS everywhere: Indicate no firmware |
| 45 | * support, as the SSBS support will be |
| 46 | * indicated to the guest and the default is |
| 47 | * safe. |
| 48 | * |
| 49 | * Otherwise, expose a permanent mitigation |
| 50 | * to the guest, and hide SSBS so that the |
| 51 | * guest stays protected. |
| 52 | */ |
| 53 | if (cpus_have_final_cap(ARM64_SSBS)) |
| 54 | break; |
| 55 | fallthrough; |
| 56 | case SPECTRE_UNAFFECTED: |
Christoffer Dall | 55009c6 | 2019-10-21 16:28:15 +0100 | [diff] [blame] | 57 | val = SMCCC_RET_NOT_REQUIRED; |
| 58 | break; |
| 59 | } |
| 60 | break; |
James Morse | d05b159 | 2021-12-10 11:16:18 +0000 | [diff] [blame] | 61 | case ARM_SMCCC_ARCH_WORKAROUND_3: |
| 62 | switch (arm64_get_spectre_bhb_state()) { |
| 63 | case SPECTRE_VULNERABLE: |
| 64 | break; |
| 65 | case SPECTRE_MITIGATED: |
| 66 | val = SMCCC_RET_SUCCESS; |
| 67 | break; |
| 68 | case SPECTRE_UNAFFECTED: |
| 69 | val = SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED; |
| 70 | break; |
| 71 | } |
| 72 | break; |
Steven Price | b48c1a4 | 2019-10-21 16:28:16 +0100 | [diff] [blame] | 73 | case ARM_SMCCC_HV_PV_TIME_FEATURES: |
| 74 | val = SMCCC_RET_SUCCESS; |
| 75 | break; |
Christoffer Dall | 55009c6 | 2019-10-21 16:28:15 +0100 | [diff] [blame] | 76 | } |
| 77 | break; |
Steven Price | b48c1a4 | 2019-10-21 16:28:16 +0100 | [diff] [blame] | 78 | case ARM_SMCCC_HV_PV_TIME_FEATURES: |
| 79 | val = kvm_hypercall_pv_features(vcpu); |
| 80 | break; |
Steven Price | 8564d63 | 2019-10-21 16:28:18 +0100 | [diff] [blame] | 81 | case ARM_SMCCC_HV_PV_TIME_ST: |
| 82 | gpa = kvm_init_stolen_time(vcpu); |
| 83 | if (gpa != GPA_INVALID) |
| 84 | val = gpa; |
| 85 | break; |
Ard Biesheuvel | 801a536 | 2021-01-06 10:34:53 +0000 | [diff] [blame] | 86 | case ARM_SMCCC_TRNG_VERSION: |
| 87 | case ARM_SMCCC_TRNG_FEATURES: |
| 88 | case ARM_SMCCC_TRNG_GET_UUID: |
| 89 | case ARM_SMCCC_TRNG_RND32: |
| 90 | case ARM_SMCCC_TRNG_RND64: |
| 91 | return kvm_trng_call(vcpu); |
Christoffer Dall | 55009c6 | 2019-10-21 16:28:15 +0100 | [diff] [blame] | 92 | default: |
| 93 | return kvm_psci_call(vcpu); |
| 94 | } |
| 95 | |
| 96 | smccc_set_retval(vcpu, val, 0, 0, 0); |
| 97 | return 1; |
| 98 | } |