[PATCH 1/3] arm64: hyperv: move hyperv detection earlier in boot

Anirudh Raybharam
2025-11-25T17:02:46Z

From: Anirudh Rayabharam <anirudh@anirudhrb.com>

From: Anirudh Rayabharam (Microsoft) <anirudh@anirudhrb.com>

Move hyperv detection earlier in the boot. The goal is to detect hyperv
and the type of partition we're running in before the GICv3 setup.

This will be used in the subsequent patches to allocate an SGI for use
by the hyperv subsystem.

Signed-off-by: Anirudh Rayabharam (Microsoft) <anirudh@anirudhrb.com>
---
arch/arm64/hyperv/mshyperv.c | 18 ++++++++++++++----
arch/arm64/include/asm/mshyperv.h | 2 ++
arch/arm64/kernel/setup.c | 6 ++++++
3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
index 4fdc26ade1d7..cc443a5d6c71 100644
--- a/arch/arm64/hyperv/mshyperv.c
+++ b/arch/arm64/hyperv/mshyperv.c
@@ -17,6 +17,7 @@
#include <linux/cpuhotplug.h>
#include <asm/mshyperv.h>

+static bool hyperv_detected;
static bool hyperv_initialized;

int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
@@ -70,20 +71,21 @@ static bool __init hyperv_detect_via_smccc(void)
return arm_smccc_hypervisor_has_uuid(&hyperv_uuid);
}

-static int __init hyperv_init(void)
+void __init hyperv_early_init(void)
{
struct hv_get_vp_registers_output result;
u64 guest_id;
- int ret;

/*
* Allow for a kernel built with CONFIG_HYPERV to be running in
* a non-Hyper-V environment.
*
- * In such cases, do nothing and return success.
+ * In such cases, do nothing and return.
*/
if (!hyperv_detect_via_acpi() && !hyperv_detect_via_smccc())
- return 0;
+ return;
+
+ hyperv_detected = true;

/* Setup the guest ID */
guest_id = hv_generate_guest_id(LINUX_VERSION_CODE);
@@ -103,6 +105,14 @@ static int __init hyperv_init(void)
ms_hyperv.misc_features);

hv_identify_partition_type();
+}
+
+static int __init hyperv_init(void)
+{
+ int ret;
+
+ if (!hyperv_detected)
+ return 0;

ret = hv_common_init();
if (ret)
diff --git a/arch/arm64/include/asm/mshyperv.h b/arch/arm64/include/asm/mshyperv.h
index b721d3134ab6..58fde70c2e39 100644
--- a/arch/arm64/include/asm/mshyperv.h
+++ b/arch/arm64/include/asm/mshyperv.h
@@ -53,6 +53,8 @@ static inline u64 hv_get_non_nested_msr(unsigned int reg)
return hv_get_msr(reg);
}

+void hyperv_early_init(void);
+
/* SMCCC hypercall parameters */
#define HV_SMCCC_FUNC_NUMBER 1
#define HV_FUNC_ID ARM_SMCCC_CALL_VAL( \
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 23c05dc7a8f2..eccf5f19da6b 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -54,6 +54,7 @@
#include <asm/efi.h>
#include <asm/xen/hypervisor.h>
#include <asm/mmu_context.h>
+#include <asm/mshyperv.h>

static int num_standard_resources;
static struct resource *standard_resources;
@@ -354,6 +355,11 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
else
psci_acpi_init();

+ /*
+ * This must come after psci init since Hyper-V detection uses SMCCC
+ */
+ hyperv_early_init();
+
arm64_rsi_init();

init_bootcpu_ops();
--
2.34.1