All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Pierre-Clément Tosi" <ptosi@google.com>
To: kvm@vger.kernel.org, linux-doc@vger.kernel.org,
	 linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,  kvmarm@lists.linux.dev
Cc: "Joey Gouly" <joey.gouly@arm.com>,
	"Marc Zyngier" <maz@kernel.org>,
	"Oliver Upton" <oupton@kernel.org>,
	"Suzuki K Poulose" <suzuki.poulose@arm.com>,
	"Vincent Donnefort" <vdonnefort@google.com>,
	"Will Deacon" <will@kernel.org>,
	"Zenghui Yu" <yuzenghui@huawei.com>,
	"Pierre-Clément Tosi" <ptosi@google.com>
Subject: [PATCH] KVM: arm64: Prevent FWD_TO_USER of SMCCC to pKVM
Date: Mon, 01 Dec 2025 18:19:52 +0000	[thread overview]
Message-ID: <20251201-smccc-filter-v1-1-b4831416f8a3@google.com> (raw)

With protected VMs, forwarding guest HVC/SMCs happens at two interfaces:

     pKVM [EL2] <--> KVM [EL1] <--> VMM [EL0]

so it might be possible for EL0 to successfully register with EL1 to
handle guest SMCCC calls but never see the KVM_EXIT_HYPERCALL, even if
the calls are properly issued by the guest, due to EL2 handling them so
that (host) EL1 never gets a chance to exit to EL0.

Instead, avoid that confusing situation and make userspace fail early by
disallowing KVM_ARM_VM_SMCCC_FILTER-ing calls from protected guests in
the KVM FID range (which pKVM re-uses).

DEN0028 defines 65536 "Vendor Specific Hypervisor Service Calls":

- the first ARM_SMCCC_KVM_NUM_FUNCS (128) can be custom-defined
- the following 3 are currently standardized
- the rest is "reserved for future expansion"

so reserve them all, like commit 821d935c87bc ("KVM: arm64: Introduce
support for userspace SMCCC filtering") with the Arm Architecture Calls.

Alternatively, we could have only reserved the ARM_SMCCC_KVM_NUM_FUNCS
(or even a subset of it) and the "Call UID Query" but that would have
risked future conflicts between that uAPI and an extension of the SMCCC
or of the pKVM ABI.

Signed-off-by: Pierre-Clément Tosi <ptosi@google.com>
---
 Documentation/virt/kvm/devices/vm.rst | 11 ++++++++++
 arch/arm64/kvm/hypercalls.c           | 39 +++++++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+)

diff --git a/Documentation/virt/kvm/devices/vm.rst b/Documentation/virt/kvm/devices/vm.rst
index a4d39fa1b0834b090318250db3b670b0b3174259..9ed4b7afe022023346d4835d33a901e557fc4765 100644
--- a/Documentation/virt/kvm/devices/vm.rst
+++ b/Documentation/virt/kvm/devices/vm.rst
@@ -400,3 +400,14 @@ will reject attempts to define a filter for any portion of these ranges:
         0x8000_0000 0x8000_FFFF
         0xC000_0000 0xC000_FFFF
         =========== ===============
+
+Protected KVM (pKVM) reserves the 'Vendor Specific Hypervisor Service Calls'
+range of function IDs and will reject attempts to define a filter for any
+portion of these ranges for a protected VM (``KVM_VM_TYPE_ARM_PROTECTED``):
+
+        =========== ===============
+        Start       End (inclusive)
+        =========== ===============
+        0x8600_0000 0x8600_FFFF
+        0xC600_0000 0xC600_FFFF
+        =========== ===============
diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 58c5fe7d757274d9079606fcc378485980c6c0f8..5ddcdd70a6b280914048e7683dafb778d0f24658 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -135,6 +135,21 @@ static bool kvm_smccc_test_fw_bmap(struct kvm_vcpu *vcpu, u32 func_id)
 						   ARM_SMCCC_SMC_64,		\
 						   0, ARM_SMCCC_FUNC_MASK)
 
+#define SMC32_VHYP_RANGE_BEGIN	ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID
+#define SMC32_VHYP_RANGE_END	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,		\
+						   ARM_SMCCC_SMC_32,		\
+						   ARM_SMCCC_OWNER_VENDOR_HYP,	\
+						   ARM_SMCCC_FUNC_MASK)
+
+#define SMC64_VHYP_RANGE_BEGIN	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,		\
+						   ARM_SMCCC_SMC_64,		\
+						   ARM_SMCCC_OWNER_VENDOR_HYP,	\
+						   0)
+#define SMC64_VHYP_RANGE_END	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,		\
+						   ARM_SMCCC_SMC_64,		\
+						   ARM_SMCCC_OWNER_VENDOR_HYP,	\
+						   ARM_SMCCC_FUNC_MASK)
+
 static int kvm_smccc_filter_insert_reserved(struct kvm *kvm)
 {
 	int r;
@@ -158,6 +173,30 @@ static int kvm_smccc_filter_insert_reserved(struct kvm *kvm)
 	if (r)
 		goto out_destroy;
 
+	/*
+	 * Prevent userspace from registering to handle any SMCCC call in the
+	 * vendor hypervisor range for pVMs, avoiding the confusion of guest
+	 * calls seemingly not resulting in KVM_RUN exits because pKVM handles
+	 * them without ever returning to the host. This is NOT for security.
+	 */
+	if (kvm_vm_is_protected(kvm)) {
+		r = mtree_insert_range(&kvm->arch.smccc_filter,
+				       SMC32_VHYP_RANGE_BEGIN,
+				       SMC32_VHYP_RANGE_END,
+				       xa_mk_value(KVM_SMCCC_FILTER_HANDLE),
+				       GFP_KERNEL_ACCOUNT);
+		if (r)
+			goto out_destroy;
+
+		r = mtree_insert_range(&kvm->arch.smccc_filter,
+				       SMC64_VHYP_RANGE_BEGIN,
+				       SMC64_VHYP_RANGE_END,
+				       xa_mk_value(KVM_SMCCC_FILTER_HANDLE),
+				       GFP_KERNEL_ACCOUNT);
+		if (r)
+			goto out_destroy;
+	}
+
 	return 0;
 out_destroy:
 	mtree_destroy(&kvm->arch.smccc_filter);

---
base-commit: 7d0a66e4bb9081d75c82ec4957c50034cb0ea449
change-id: 20251201-smccc-filter-588ddf12b355

Best regards,
-- 
Pierre-Clément Tosi <ptosi@google.com>


             reply	other threads:[~2025-12-01 18:19 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-01 18:19 Pierre-Clément Tosi [this message]
2025-12-01 18:48 ` [PATCH] KVM: arm64: Prevent FWD_TO_USER of SMCCC to pKVM Marc Zyngier
2025-12-01 19:58   ` Pierre-Clément Tosi

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=20251201-smccc-filter-v1-1-b4831416f8a3@google.com \
    --to=ptosi@google.com \
    --cc=joey.gouly@arm.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.linux.dev \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maz@kernel.org \
    --cc=oupton@kernel.org \
    --cc=suzuki.poulose@arm.com \
    --cc=vdonnefort@google.com \
    --cc=will@kernel.org \
    --cc=yuzenghui@huawei.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.