From: Jeremy Linton <jeremy.linton@xxxxxxx> 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 <mikelley@xxxxxxxxxxxxx> Tweaked to support !hyperv guest enviroments by Jeremy Linton Signed-off-by: Jeremy Linton <jeremy.linton@xxxxxxx> 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 -- kernel@xxxxxxxxxxxxxxxxxxxxxxx To unsubscribe send an email to kernel-leave@xxxxxxxxxxxxxxxxxxxxxxx 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/kernel@xxxxxxxxxxxxxxxxxxxxxxx Do not reply to spam on the list, report it: https://pagure.io/fedora-infrastructure