linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: Fuad Tabba <tabba@google.com>
To: kvmarm@lists.cs.columbia.edu
Cc: maz@kernel.org, will@kernel.org, james.morse@arm.com,
	 alexandru.elisei@arm.com, suzuki.poulose@arm.com,
	mark.rutland@arm.com,  christoffer.dall@arm.com,
	pbonzini@redhat.com, drjones@redhat.com,  oupton@google.com,
	qperret@google.com, kvm@vger.kernel.org,
	 linux-arm-kernel@lists.infradead.org, kernel-team@android.com,
	 tabba@google.com
Subject: [PATCH v4 15/15] KVM: arm64: Handle protected guests at 32 bits
Date: Tue, 17 Aug 2021 09:11:34 +0100	[thread overview]
Message-ID: <20210817081134.2918285-16-tabba@google.com> (raw)
In-Reply-To: <20210817081134.2918285-1-tabba@google.com>

Protected KVM does not support protected AArch32 guests. However,
it is possible for the guest to force run AArch32, potentially
causing problems. Add an extra check so that if the hypervisor
catches the guest doing that, it can prevent the guest from
running again by resetting vcpu->arch.target and returning
ARM_EXCEPTION_IL.

If this were to happen, The VMM can try and fix it by re-
initializing the vcpu with KVM_ARM_VCPU_INIT, however, this is
likely not possible for protected VMs.

Adapted from commit 22f553842b14 ("KVM: arm64: Handle Asymmetric
AArch32 systems")

Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/kvm/hyp/nvhe/switch.c | 37 ++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index 398e62098898..0c24b7f473bf 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -20,6 +20,7 @@
 #include <asm/kprobes.h>
 #include <asm/kvm_asm.h>
 #include <asm/kvm_emulate.h>
+#include <asm/kvm_fixed_config.h>
 #include <asm/kvm_hyp.h>
 #include <asm/kvm_mmu.h>
 #include <asm/fpsimd.h>
@@ -195,6 +196,39 @@ exit_handle_fn kvm_get_nvhe_exit_handler(struct kvm_vcpu *vcpu)
 		return NULL;
 }
 
+/*
+ * Some guests (e.g., protected VMs) might not be allowed to run in AArch32. The
+ * check below is based on the one in kvm_arch_vcpu_ioctl_run().
+ * The ARMv8 architecture does not give the hypervisor a mechanism to prevent a
+ * guest from dropping to AArch32 EL0 if implemented by the CPU. If the
+ * hypervisor spots a guest in such a state ensure it is handled, and don't
+ * trust the host to spot or fix it.
+ *
+ * Returns true if the check passed and the guest run loop can continue, or
+ * false if the guest should exit to the host.
+ */
+static bool check_aarch32_guest(struct kvm_vcpu *vcpu, u64 *exit_code)
+{
+	if (kvm_vm_is_protected(kern_hyp_va(vcpu->kvm)) &&
+	    vcpu_mode_is_32bit(vcpu) &&
+	    FIELD_GET(ARM64_FEATURE_MASK(ID_AA64PFR0_EL0),
+					 PVM_ID_AA64PFR0_RESTRICT_UNSIGNED) <
+		ID_AA64PFR0_ELx_32BIT_64BIT) {
+		/*
+		 * As we have caught the guest red-handed, decide that it isn't
+		 * fit for purpose anymore by making the vcpu invalid. The VMM
+		 * can try and fix it by re-initializing the vcpu with
+		 * KVM_ARM_VCPU_INIT, however, this is likely not possible for
+		 * protected VMs.
+		 */
+		vcpu->arch.target = -1;
+		*exit_code = ARM_EXCEPTION_IL;
+		return false;
+	}
+
+	return true;
+}
+
 /* Switch to the guest for legacy non-VHE systems */
 int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
 {
@@ -255,6 +289,9 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
 		/* Jump in the fire! */
 		exit_code = __guest_enter(vcpu);
 
+		if (unlikely(!check_aarch32_guest(vcpu, &exit_code)))
+			break;
+
 		/* And we're baaack! */
 	} while (fixup_guest_exit(vcpu, &exit_code));
 
-- 
2.33.0.rc1.237.g0d66db33f3-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2021-08-17  8:23 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-17  8:11 [PATCH v4 00/15] KVM: arm64: Fixed features for protected VMs Fuad Tabba
2021-08-17  8:11 ` [PATCH v4 01/15] KVM: arm64: placeholder to check if VM is protected Fuad Tabba
2021-08-17  8:11 ` [PATCH v4 02/15] KVM: arm64: Remove trailing whitespace in comment Fuad Tabba
2021-08-17  8:11 ` [PATCH v4 03/15] KVM: arm64: MDCR_EL2 is a 64-bit register Fuad Tabba
2021-08-18 14:32   ` Marc Zyngier
2021-08-17  8:11 ` [PATCH v4 04/15] KVM: arm64: Fix names of config register fields Fuad Tabba
2021-08-17  8:11 ` [PATCH v4 05/15] KVM: arm64: Refactor sys_regs.h,c for nVHE reuse Fuad Tabba
2021-08-17  8:11 ` [PATCH v4 06/15] KVM: arm64: Restore mdcr_el2 from vcpu Fuad Tabba
2021-08-18 13:13   ` Will Deacon
2021-08-18 14:42   ` Marc Zyngier
2021-08-17  8:11 ` [PATCH v4 07/15] KVM: arm64: Keep mdcr_el2's value as set by __init_el2_debug Fuad Tabba
2021-08-18 13:17   ` Will Deacon
2021-08-17  8:11 ` [PATCH v4 08/15] KVM: arm64: Track value of cptr_el2 in struct kvm_vcpu_arch Fuad Tabba
2021-08-17  8:11 ` [PATCH v4 09/15] KVM: arm64: Add feature register flag definitions Fuad Tabba
2021-08-18 13:21   ` Will Deacon
2021-08-17  8:11 ` [PATCH v4 10/15] KVM: arm64: Add config register bit definitions Fuad Tabba
2021-08-18 15:16   ` Marc Zyngier
2021-08-17  8:11 ` [PATCH v4 11/15] KVM: arm64: Guest exit handlers for nVHE hyp Fuad Tabba
2021-08-18 16:45   ` Marc Zyngier
2021-08-19 14:35     ` Marc Zyngier
2021-08-23 10:21       ` Fuad Tabba
2021-08-23 12:10         ` Marc Zyngier
2021-08-17  8:11 ` [PATCH v4 12/15] KVM: arm64: Add trap handlers for protected VMs Fuad Tabba
2021-08-17  8:11 ` [PATCH v4 13/15] KVM: arm64: Move sanitized copies of CPU features Fuad Tabba
2021-08-17  8:11 ` [PATCH v4 14/15] KVM: arm64: Trap access to pVM restricted features Fuad Tabba
2021-08-17  8:11 ` Fuad Tabba [this message]
2021-08-19  8:10   ` [PATCH v4 15/15] KVM: arm64: Handle protected guests at 32 bits Oliver Upton
2021-08-23 10:25     ` Fuad Tabba
2021-08-20 10:34 ` [PATCH v4 00/15] KVM: arm64: Fixed features for protected VMs Marc Zyngier
2021-08-23 10:23   ` Fuad Tabba

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210817081134.2918285-16-tabba@google.com \
    --to=tabba@google.com \
    --cc=alexandru.elisei@arm.com \
    --cc=christoffer.dall@arm.com \
    --cc=drjones@redhat.com \
    --cc=james.morse@arm.com \
    --cc=kernel-team@android.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.cs.columbia.edu \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=mark.rutland@arm.com \
    --cc=maz@kernel.org \
    --cc=oupton@google.com \
    --cc=pbonzini@redhat.com \
    --cc=qperret@google.com \
    --cc=suzuki.poulose@arm.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).