Files
build/patch/kernel/archive/wsl2-arm64-6.1/1667-arm64-hyperv-Enable-Hyper-V-synthetic-clocks-timers.patch
2025-01-05 10:15:14 +01:00

186 lines
5.7 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Michael Kelley <mikelley@microsoft.com>
Date: Mon, 28 Feb 2022 08:41:24 -0800
Subject: arm64: hyperv: Enable Hyper-V synthetic clocks/timers
This patch adds support for Hyper-V synthetic clocks and timers on
ARM64. Upstream code assumes changes to Hyper-V that were made
in Fall 2021 that fully virtualize the ARM64 architectural counter
and timer so that the driver in drivers/clocksource/arm_arch_timer.c
can be used. But older versions of Hyper-V don't have this
support and must use the Hyper-V synthetic clocks and timers.
As such, this patch is out-of-tree code.
This patch does two related things. First it splits the general
Hyper-V initialization code to create hyperv_early_init() that runs
much earlier during kernel boot. This early init function is needed
so that core Hyper-V functionality is ready before the synthetic clocks
and timers are initialized. Second, it adds Hyper-V clock and timer
initialization via TIMER_ACPI_DECLARE() and hyperv_timer_init()
in the Hyper-V clocksource driver in drivers/clocksource/hyperv_timer.c.
Signed-off-by: Michael Kelley <mikelley@microsoft.com>
[tyhicks: Forward port around a minor text conflict caused by commit
245b993d8f6c ("clocksource: hyper-v: unexport __init-annotated
hv_init_clocksource()")
Signed-off-by: Tyler Hicks <tyhicks@linux.microsoft.com>
[kms: Forward port to 6.1]
Signed-off-by: Kelsey Steele <kelseysteele@microsoft.com>
---
arch/arm64/hyperv/mshyperv.c | 15 +++++---
arch/arm64/include/asm/mshyperv.h | 18 ++++++++++
arch/arm64/kernel/setup.c | 4 +++
drivers/clocksource/hyperv_timer.c | 14 ++++++++
drivers/hv/Kconfig | 2 +-
5 files changed, 47 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
index 111111111111..222222222222 100644
--- a/arch/arm64/hyperv/mshyperv.c
+++ b/arch/arm64/hyperv/mshyperv.c
@@ -19,12 +19,11 @@
static bool hyperv_initialized;
-static int __init hyperv_init(void)
+void __init hyperv_early_init(void)
{
struct hv_get_vp_registers_output result;
u32 a, b, c, d;
u64 guest_id;
- int ret;
/*
* Allow for a kernel built with CONFIG_HYPERV to be running in
@@ -32,10 +31,10 @@ static int __init hyperv_init(void)
* In such cases, do nothing and return success.
*/
if (acpi_disabled)
- return 0;
+ return;
if (strncmp((char *)&acpi_gbl_FADT.hypervisor_id, "MsHyperV", 8))
- return 0;
+ return;
/* Setup the guest ID */
guest_id = hv_generate_guest_id(LINUX_VERSION_CODE);
@@ -63,6 +62,13 @@ static int __init hyperv_init(void)
pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
b >> 16, b & 0xFFFF, a, d & 0xFFFFFF, c, d >> 24);
+ hyperv_initialized = true;
+}
+
+static int __init hyperv_init(void)
+{
+ int ret;
+
ret = hv_common_init();
if (ret)
return ret;
@@ -74,7 +80,6 @@ static int __init hyperv_init(void)
return ret;
}
- hyperv_initialized = true;
return 0;
}
diff --git a/arch/arm64/include/asm/mshyperv.h b/arch/arm64/include/asm/mshyperv.h
index 111111111111..222222222222 100644
--- a/arch/arm64/include/asm/mshyperv.h
+++ b/arch/arm64/include/asm/mshyperv.h
@@ -21,6 +21,13 @@
#include <linux/types.h>
#include <linux/arm-smccc.h>
#include <asm/hyperv-tlfs.h>
+#include <clocksource/arm_arch_timer.h>
+
+#if IS_ENABLED(CONFIG_HYPERV)
+void __init hyperv_early_init(void);
+#else
+static inline void hyperv_early_init(void) {};
+#endif
extern u64 hv_do_hvc(u64 control, ...);
extern u64 hv_do_hvc_fast_get(u64 control, u64 input1, u64 input2, u64 input3,
@@ -45,6 +52,17 @@ static inline u64 hv_get_register(unsigned int reg)
return hv_get_vpreg(reg);
}
+/* Define the interrupt ID used by STIMER0 Direct Mode interrupts. This
+ * value can't come from ACPI tables because it is needed before the
+ * Linux ACPI subsystem is initialized.
+ */
+#define HYPERV_STIMER0_VECTOR 31
+
+static inline u64 hv_get_raw_timer(void)
+{
+ return arch_timer_read_counter();
+}
+
/* 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 111111111111..222222222222 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -50,6 +50,7 @@
#include <asm/traps.h>
#include <asm/efi.h>
#include <asm/xen/hypervisor.h>
+#include <asm/mshyperv.h>
#include <asm/mmu_context.h>
static int num_standard_resources;
@@ -343,6 +344,9 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
if (acpi_disabled)
unflatten_device_tree();
+ /* Do after acpi_boot_table_init() so local FADT is available */
+ hyperv_early_init();
+
bootmem_init();
kasan_init();
diff --git a/drivers/clocksource/hyperv_timer.c b/drivers/clocksource/hyperv_timer.c
index 111111111111..222222222222 100644
--- a/drivers/clocksource/hyperv_timer.c
+++ b/drivers/clocksource/hyperv_timer.c
@@ -566,3 +566,17 @@ void __init hv_init_clocksource(void)
hv_sched_clock_offset = hv_read_reference_counter();
hv_setup_sched_clock(read_hv_sched_clock_msr);
}
+
+/* Initialize everything on ARM64 */
+static int __init hyperv_timer_init(struct acpi_table_header *table)
+{
+ if (!hv_is_hyperv_initialized())
+ return -EINVAL;
+
+ hv_init_clocksource();
+ if (hv_stimer_alloc(true))
+ return -EINVAL;
+
+ return 0;
+}
+TIMER_ACPI_DECLARE(hyperv, ACPI_SIG_GTDT, hyperv_timer_init);
diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
index 111111111111..222222222222 100644
--- a/drivers/hv/Kconfig
+++ b/drivers/hv/Kconfig
@@ -14,7 +14,7 @@ config HYPERV
system.
config HYPERV_TIMER
- def_bool HYPERV && X86
+ def_bool HYPERV
config HYPERV_UTILS
tristate "Microsoft Hyper-V Utilities driver"
--
Armbian