mirror of
https://github.com/armbian/build
synced 2025-09-24 19:47:06 +07:00
186 lines
5.7 KiB
Diff
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
|
|
|