From: Jeremy Linton <[email protected]>

NOT_UPSTREAM/HYPERV: Enable HYPERV_TIMER on ARM64

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2007430
Upstream Status: RHEL-only

The existing windows/arm64 hyperv host expects that HYPERV_TIMER
is enabled by the linux guests (as x86), and so guests that
aren't utilizing this will fail to boot fairly early in the
boot cycle. Other linux/distro/kernel's being distributed by
MS/etc have a patch similar to this one in their tree. Its
been indicated to me that the host will eventually be fixed but
for the time being that isn't the case and anyone with a
publically available windows/arm machine can't boot fedora and
centos kernel's provided because of this.

Originally-by: Michael Kelley <[email protected]>
Tweaked to support !hyperv guest enviroments by Jeremy Linton

Signed-off-by: Jeremy Linton <[email protected]>

diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
index blahblah..blahblah 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 = generate_guest_id(0, LINUX_VERSION_CODE, 0);
@@ -63,6 +62,16 @@ 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;
+
+       if (!hyperv_initialized)
+               return 0;
+
        ret = hv_common_init();
        if (ret)
                return ret;
@@ -74,7 +83,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 blahblah..blahblah 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
 
 /*
  * Declare calls to get and set Hyper-V VP register values on ARM64, which
@@ -41,6 +48,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 blahblah..blahblah 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;
@@ -347,6 +348,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 blahblah..blahblah 100644
--- a/drivers/clocksource/hyperv_timer.c
+++ b/drivers/clocksource/hyperv_timer.c
@@ -566,3 +566,17 @@ void __init hv_init_clocksource(void)
        hv_setup_sched_clock(read_hv_sched_clock_msr);
 }
 EXPORT_SYMBOL_GPL(hv_init_clocksource);
+
+/* 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 blahblah..blahblah 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"

--
https://gitlab.com/cki-project/kernel-ark/-/merge_requests/1393
_______________________________________________
kernel mailing list -- [email protected]
To unsubscribe send an email to [email protected]
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedoraproject.org/archives/list/[email protected]
Do not reply to spam on the list, report it: 
https://pagure.io/fedora-infrastructure

Reply via email to