summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Upton <oupton@google.com>2022-03-22 19:35:37 +0100
committerMarc Zyngier <maz@kernel.org>2022-04-06 11:39:39 +0200
commit827c2ab3314814e1c7d873372c0fe0cad50ba1c5 (patch)
treeababe6af1072773cc5fec01343a0c61bae836018
parentKVM: arm64: Generally disallow SMC64 for AArch32 guests (diff)
downloadlinux-827c2ab3314814e1c7d873372c0fe0cad50ba1c5.tar.xz
linux-827c2ab3314814e1c7d873372c0fe0cad50ba1c5.zip
KVM: arm64: Actually prevent SMC64 SYSTEM_RESET2 from AArch32
The SMCCC does not allow the SMC64 calling convention to be used from AArch32. While KVM checks to see if the calling convention is allowed in PSCI_1_0_FN_PSCI_FEATURES, it does not actually prevent calls to unadvertised PSCI v1.0+ functions. Hoist the check to see if the requested function is allowed into kvm_psci_call(), thereby preventing SMC64 calls from AArch32 for all PSCI versions. Fixes: d43583b890e7 ("KVM: arm64: Expose PSCI SYSTEM_RESET2 call to the guest") Acked-by: Will Deacon <will@kernel.org> Reviewed-by: Reiji Watanabe <reijiw@google.com> Signed-off-by: Oliver Upton <oupton@google.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20220322183538.2757758-3-oupton@google.com
-rw-r--r--arch/arm64/kvm/psci.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/arch/arm64/kvm/psci.c b/arch/arm64/kvm/psci.c
index a76d03d50624..faf403a72fdf 100644
--- a/arch/arm64/kvm/psci.c
+++ b/arch/arm64/kvm/psci.c
@@ -231,10 +231,6 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
unsigned long val;
int ret = 1;
- val = kvm_psci_check_allowed_function(vcpu, psci_fn);
- if (val)
- goto out;
-
switch (psci_fn) {
case PSCI_0_2_FN_PSCI_VERSION:
/*
@@ -302,7 +298,6 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
break;
}
-out:
smccc_set_retval(vcpu, val, 0, 0, 0);
return ret;
}
@@ -422,6 +417,15 @@ static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
*/
int kvm_psci_call(struct kvm_vcpu *vcpu)
{
+ u32 psci_fn = smccc_get_function(vcpu);
+ unsigned long val;
+
+ val = kvm_psci_check_allowed_function(vcpu, psci_fn);
+ if (val) {
+ smccc_set_retval(vcpu, val, 0, 0, 0);
+ return 1;
+ }
+
switch (kvm_psci_version(vcpu)) {
case KVM_ARM_PSCI_1_1:
return kvm_psci_1_x_call(vcpu, 1);