From: Roman Kisel <romank@linux.microsoft.com>
To: arnd@arndb.de, bhelgaas@google.com, bp@alien8.de,
catalin.marinas@arm.com, conor+dt@kernel.org,
dan.carpenter@linaro.org, dave.hansen@linux.intel.com,
decui@microsoft.com, haiyangz@microsoft.com, hpa@zytor.com,
joey.gouly@arm.com, krzk+dt@kernel.org, kw@linux.com,
kys@microsoft.com, lenb@kernel.org, lpieralisi@kernel.org,
manivannan.sadhasivam@linaro.org, mark.rutland@arm.com,
maz@kernel.org, mingo@redhat.com, oliver.upton@linux.dev,
rafael@kernel.org, robh@kernel.org, ssengar@linux.microsoft.com,
sudeep.holla@arm.com, suzuki.poulose@arm.com, tglx@linutronix.de,
wei.liu@kernel.org, will@kernel.org, yuzenghui@huawei.com,
devicetree@vger.kernel.org, kvmarm@lists.linux.dev,
linux-acpi@vger.kernel.org, linux-arch@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-pci@vger.kernel.org, x86@kernel.org
Cc: apais@microsoft.com, benhill@microsoft.com,
bperkins@microsoft.com, sunilmut@microsoft.com
Subject: [PATCH hyperv-next v6 01/11] arm64: kvm, smccc: Introduce and use API for detecting hypervisor presence
Date: Fri, 14 Mar 2025 17:19:21 -0700 [thread overview]
Message-ID: <20250315001931.631210-2-romank@linux.microsoft.com> (raw)
In-Reply-To: <20250315001931.631210-1-romank@linux.microsoft.com>
The KVM/arm64 uses SMCCC to detect hypervisor presence. That code is
private, and it follows the SMCCC specification. Other existing and
emerging hypervisor guest implementations can and should use that
standard approach as well.
Factor out a common infrastructure that the guests can use, update KVM
to employ the new API. The central notion of the SMCCC method is the
UUID of the hypervisor, and the API follows that.
No functional changes. Validated with a KVM/arm64 guest.
Signed-off-by: Roman Kisel <romank@linux.microsoft.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
---
arch/arm64/kvm/hypercalls.c | 5 +--
drivers/firmware/smccc/kvm_guest.c | 10 ++----
drivers/firmware/smccc/smccc.c | 19 +++++++++++
include/linux/arm-smccc.h | 55 +++++++++++++++++++++++++++---
4 files changed, 73 insertions(+), 16 deletions(-)
diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 27ce4cb44904..92b9bc1ea8e8 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -353,10 +353,7 @@ int kvm_smccc_call_handler(struct kvm_vcpu *vcpu)
val[0] = gpa;
break;
case ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID:
- val[0] = ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_0;
- val[1] = ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_1;
- val[2] = ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_2;
- val[3] = ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3;
+ UUID_TO_SMCCC_RES(ARM_SMCCC_VENDOR_HYP_UID_KVM, val);
break;
case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID:
val[0] = smccc_feat->vendor_hyp_bmap;
diff --git a/drivers/firmware/smccc/kvm_guest.c b/drivers/firmware/smccc/kvm_guest.c
index f3319be20b36..b5084b309ea0 100644
--- a/drivers/firmware/smccc/kvm_guest.c
+++ b/drivers/firmware/smccc/kvm_guest.c
@@ -14,17 +14,11 @@ static DECLARE_BITMAP(__kvm_arm_hyp_services, ARM_SMCCC_KVM_NUM_FUNCS) __ro_afte
void __init kvm_init_hyp_services(void)
{
+ uuid_t kvm_uuid = ARM_SMCCC_VENDOR_HYP_UID_KVM;
struct arm_smccc_res res;
u32 val[4];
- if (arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_HVC)
- return;
-
- arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID, &res);
- if (res.a0 != ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_0 ||
- res.a1 != ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_1 ||
- res.a2 != ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_2 ||
- res.a3 != ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3)
+ if (!arm_smccc_hyp_present(&kvm_uuid))
return;
memset(&res, 0, sizeof(res));
diff --git a/drivers/firmware/smccc/smccc.c b/drivers/firmware/smccc/smccc.c
index a74600d9f2d7..7399f27d58e5 100644
--- a/drivers/firmware/smccc/smccc.c
+++ b/drivers/firmware/smccc/smccc.c
@@ -67,6 +67,25 @@ s32 arm_smccc_get_soc_id_revision(void)
}
EXPORT_SYMBOL_GPL(arm_smccc_get_soc_id_revision);
+bool arm_smccc_hyp_present(const uuid_t *hyp_uuid)
+{
+ struct arm_smccc_res res = {};
+
+ if (arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_HVC)
+ return false;
+ arm_smccc_1_1_hvc(ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID, &res);
+ if (res.a0 == SMCCC_RET_NOT_SUPPORTED)
+ return false;
+
+ return ({
+ const uuid_t uuid = SMCCC_RES_TO_UUID(res.a0, res.a1, res.a2, res.a3);
+ const bool present = uuid_equal(&uuid, hyp_uuid);
+
+ present;
+ });
+}
+EXPORT_SYMBOL_GPL(arm_smccc_hyp_present);
+
static int __init smccc_devices_init(void)
{
struct platform_device *pdev;
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index 67f6fdf2e7cd..726f18221f1c 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -7,6 +7,11 @@
#include <linux/args.h>
#include <linux/init.h>
+
+#ifndef __ASSEMBLER__
+#include <linux/uuid.h>
+#endif
+
#include <uapi/linux/const.h>
/*
@@ -107,10 +112,10 @@
ARM_SMCCC_FUNC_QUERY_CALL_UID)
/* KVM UID value: 28b46fb6-2ec5-11e9-a9ca-4b564d003a74 */
-#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_0 0xb66fb428U
-#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_1 0xe911c52eU
-#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_2 0x564bcaa9U
-#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3 0x743a004dU
+#define ARM_SMCCC_VENDOR_HYP_UID_KVM UUID_INIT(\
+ 0xb66fb428, 0xc52e, 0xe911, \
+ 0xa9, 0xca, 0x4b, 0x56, \
+ 0x4d, 0x00, 0x3a, 0x74)
/* KVM "vendor specific" services */
#define ARM_SMCCC_KVM_FUNC_FEATURES 0
@@ -333,6 +338,48 @@ s32 arm_smccc_get_soc_id_version(void);
*/
s32 arm_smccc_get_soc_id_revision(void);
+#ifndef __ASSEMBLER__
+
+/**
+ * arm_smccc_hyp_present(const uuid_t *hyp_uuid)
+ *
+ * Returns `true` if the hypervisor advertises its presence via SMCCC.
+ *
+ * When the function returns `false`, the caller shall not assume that
+ * there is no hypervisor running. Instead, the caller must fall back to
+ * other approaches if any are available.
+ */
+bool arm_smccc_hyp_present(const uuid_t *hyp_uuid);
+
+#define SMCCC_RES_TO_UUID(r0, r1, r2, r3) \
+ UUID_INIT( \
+ cpu_to_le32(lower_32_bits(r0)), \
+ cpu_to_le32(lower_32_bits(r1)) & 0xffff, \
+ cpu_to_le32(lower_32_bits(r1)) >> 16, \
+ cpu_to_le32(lower_32_bits(r2)) & 0xff, \
+ (cpu_to_le32(lower_32_bits(r2)) >> 8) & 0xff, \
+ (cpu_to_le32(lower_32_bits(r2)) >> 16) & 0xff, \
+ (cpu_to_le32(lower_32_bits(r2)) >> 24) & 0xff, \
+ cpu_to_le32(lower_32_bits(r3)) & 0xff, \
+ (cpu_to_le32(lower_32_bits(r3)) >> 8) & 0xff, \
+ (cpu_to_le32(lower_32_bits(r3)) >> 16) & 0xff, \
+ (cpu_to_le32(lower_32_bits(r3)) >> 24) & 0xff \
+ )
+
+#define UUID_TO_SMCCC_RES(uuid_init, regs) do { \
+ const uuid_t uuid = uuid_init; \
+ (regs)[0] = le32_to_cpu((u32)uuid.b[0] | (uuid.b[1] << 8) | \
+ ((uuid.b[2]) << 16) | ((uuid.b[3]) << 24)); \
+ (regs)[1] = le32_to_cpu((u32)uuid.b[4] | (uuid.b[5] << 8) | \
+ ((uuid.b[6]) << 16) | ((uuid.b[7]) << 24)); \
+ (regs)[2] = le32_to_cpu((u32)uuid.b[8] | (uuid.b[9] << 8) | \
+ ((uuid.b[10]) << 16) | ((uuid.b[11]) << 24)); \
+ (regs)[3] = le32_to_cpu((u32)uuid.b[12] | (uuid.b[13] << 8) | \
+ ((uuid.b[14]) << 16) | ((uuid.b[15]) << 24)); \
+ } while (0)
+
+#endif /* !__ASSEMBLER__ */
+
/**
* struct arm_smccc_res - Result from SMC/HVC call
* @a0-a3 result values from registers 0 to 3
--
2.43.0
next prev parent reply other threads:[~2025-03-15 0:19 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-15 0:19 [PATCH hyperv-next v6 00/11] arm64: hyperv: Support Virtual Trust Level Boot Roman Kisel
2025-03-15 0:19 ` Roman Kisel [this message]
2025-03-15 0:27 ` [PATCH hyperv-next v6 01/11] arm64: kvm, smccc: Introduce and use API for detecting hypervisor presence Roman Kisel
2025-03-15 13:12 ` Arnd Bergmann
2025-03-17 17:28 ` Roman Kisel
2025-03-17 11:29 ` Mark Rutland
2025-03-17 17:11 ` Roman Kisel
2025-03-15 0:19 ` [PATCH hyperv-next v6 02/11] arm64: hyperv: Use SMCCC to detect " Roman Kisel
2025-03-17 11:37 ` Mark Rutland
2025-03-17 17:12 ` Roman Kisel
2025-03-19 22:11 ` Michael Kelley
2025-03-20 18:47 ` Roman Kisel
2025-03-15 0:19 ` [PATCH hyperv-next v6 03/11] Drivers: hv: Enable VTL mode for arm64 Roman Kisel
2025-03-15 0:19 ` [PATCH hyperv-next v6 04/11] Drivers: hv: Provide arch-neutral implementation of get_vtl() Roman Kisel
2025-03-15 0:19 ` [PATCH hyperv-next v6 05/11] arm64: hyperv: Initialize the Virtual Trust Level field Roman Kisel
2025-03-15 0:19 ` [PATCH hyperv-next v6 06/11] arm64, x86: hyperv: Report the VTL the system boots in Roman Kisel
2025-03-15 0:19 ` [PATCH hyperv-next v6 07/11] dt-bindings: microsoft,vmbus: Add interrupt and DMA coherence properties Roman Kisel
2025-03-16 17:36 ` Krzysztof Kozlowski
2025-03-17 17:07 ` Roman Kisel
2025-03-15 0:19 ` [PATCH hyperv-next v6 08/11] Drivers: hv: vmbus: Get the IRQ number from DeviceTree Roman Kisel
2025-03-15 0:19 ` [PATCH hyperv-next v6 09/11] Drivers: hv: vmbus: Introduce hv_get_vmbus_root_device() Roman Kisel
2025-03-15 0:19 ` [PATCH hyperv-next v6 10/11] ACPI: irq: Introduce acpi_get_gsi_dispatcher() Roman Kisel
2025-03-26 14:55 ` Rafael J. Wysocki
2025-03-26 15:32 ` Roman Kisel
2025-03-15 0:19 ` [PATCH hyperv-next v6 11/11] PCI: hv: Get vPCI MSI IRQ domain from DeviceTree Roman Kisel
2025-03-15 18:49 ` Bjorn Helgaas
2025-03-17 17:07 ` Roman Kisel
2025-03-26 14:56 ` Rafael J. Wysocki
2025-03-26 15:37 ` Roman Kisel
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=20250315001931.631210-2-romank@linux.microsoft.com \
--to=romank@linux.microsoft.com \
--cc=apais@microsoft.com \
--cc=arnd@arndb.de \
--cc=benhill@microsoft.com \
--cc=bhelgaas@google.com \
--cc=bp@alien8.de \
--cc=bperkins@microsoft.com \
--cc=catalin.marinas@arm.com \
--cc=conor+dt@kernel.org \
--cc=dan.carpenter@linaro.org \
--cc=dave.hansen@linux.intel.com \
--cc=decui@microsoft.com \
--cc=devicetree@vger.kernel.org \
--cc=haiyangz@microsoft.com \
--cc=hpa@zytor.com \
--cc=joey.gouly@arm.com \
--cc=krzk+dt@kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=kw@linux.com \
--cc=kys@microsoft.com \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-arch@vger.kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-hyperv@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lpieralisi@kernel.org \
--cc=manivannan.sadhasivam@linaro.org \
--cc=mark.rutland@arm.com \
--cc=maz@kernel.org \
--cc=mingo@redhat.com \
--cc=oliver.upton@linux.dev \
--cc=rafael@kernel.org \
--cc=robh@kernel.org \
--cc=ssengar@linux.microsoft.com \
--cc=sudeep.holla@arm.com \
--cc=sunilmut@microsoft.com \
--cc=suzuki.poulose@arm.com \
--cc=tglx@linutronix.de \
--cc=wei.liu@kernel.org \
--cc=will@kernel.org \
--cc=x86@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 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).