From: Michael Kelley <mikelley@microsoft.com> To: will@kernel.org, ardb@kernel.org, arnd@arndb.de, catalin.marinas@arm.com, mark.rutland@arm.com, maz@kernel.org, linux-arm-kernel@lists.infradead.org, gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-efi@vger.kernel.org, linux-arch@vger.kernel.org, wei.liu@kernel.org, vkuznets@redhat.com, kys@microsoft.com Cc: mikelley@microsoft.com, sunilmut@microsoft.com, boqun.feng@gmail.com Subject: [PATCH v7 07/10] arm64: hyperv: Initialize hypervisor on boot Date: Mon, 24 Aug 2020 09:46:20 -0700 [thread overview] Message-ID: <1598287583-71762-8-git-send-email-mikelley@microsoft.com> (raw) In-Reply-To: <1598287583-71762-1-git-send-email-mikelley@microsoft.com> Add ARM64-specific code to initialize the Hyper-V hypervisor when booting as a guest VM. Provide functions and data structures indicating hypervisor status that are needed by VMbus driver. This code is built only when CONFIG_HYPERV is enabled. Signed-off-by: Michael Kelley <mikelley@microsoft.com> --- arch/arm64/hyperv/hv_core.c | 144 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c index 966d815..831a69c 100644 --- a/arch/arm64/hyperv/hv_core.c +++ b/arch/arm64/hyperv/hv_core.c @@ -18,10 +18,41 @@ #include <linux/slab.h> #include <linux/hyperv.h> #include <linux/arm-smccc.h> +#include <linux/vmalloc.h> +#include <linux/acpi.h> +#include <linux/module.h> +#include <linux/cpuhotplug.h> +#include <linux/psci.h> #include <asm-generic/bug.h> #include <asm/hyperv-tlfs.h> #include <asm/mshyperv.h> +#include <asm/sysreg.h> +#include <clocksource/hyperv_timer.h> +static bool hyperv_initialized; + +struct ms_hyperv_info ms_hyperv __ro_after_init; +EXPORT_SYMBOL_GPL(ms_hyperv); + +u32 *hv_vp_index; +EXPORT_SYMBOL_GPL(hv_vp_index); + +u32 hv_max_vp_index; +EXPORT_SYMBOL_GPL(hv_max_vp_index); + +static int hv_cpu_init(unsigned int cpu) +{ + u64 msr_vp_index; + + msr_vp_index = hv_get_vpreg(HV_REGISTER_VPINDEX); + + hv_vp_index[smp_processor_id()] = msr_vp_index; + + if (msr_vp_index > hv_max_vp_index) + hv_max_vp_index = msr_vp_index; + + return 0; +} /* * Functions for allocating and freeing memory with size and @@ -67,6 +98,107 @@ void hv_free_hyperv_page(unsigned long addr) /* + * This function is invoked via the ACPI clocksource probe mechanism. We + * don't actually use any values from the ACPI GTDT table, but we set up + * the Hyper-V synthetic clocksource and do other initialization for + * interacting with Hyper-V the first time. Using early_initcall to invoke + * this function is too late because interrupts are already enabled at that + * point, and hv_init_clocksource() must run before interrupts are enabled. + * + * 1. Setup the guest ID. + * 2. Get features and hints info from Hyper-V + * 3. Setup per-cpu VP indices. + * 4. Initialize the Hyper-V clocksource. + */ + +static int __init hyperv_init(struct acpi_table_header *table) +{ + struct hv_get_vp_registers_output result; + u32 a, b, c, d; + u64 guest_id; + int i, cpuhp; + + /* + * If we're in a VM on Hyper-V, the ACPI hypervisor_id field will + * have the string "MsHyperV". + */ + if (strncmp((char *)&acpi_gbl_FADT.hypervisor_id, "MsHyperV", 8)) + return -EINVAL; + + /* Setup the guest ID */ + guest_id = generate_guest_id(0, LINUX_VERSION_CODE, 0); + hv_set_vpreg(HV_REGISTER_GUEST_OSID, guest_id); + + /* Get the features and hints from Hyper-V */ + hv_get_vpreg_128(HV_REGISTER_FEATURES, &result); + ms_hyperv.features = result.as32.a; + ms_hyperv.misc_features = result.as32.c; + + hv_get_vpreg_128(HV_REGISTER_ENLIGHTENMENTS, &result); + ms_hyperv.hints = result.as32.a; + + pr_info("Hyper-V: Features 0x%x, hints 0x%x, misc 0x%x\n", + ms_hyperv.features, ms_hyperv.hints, ms_hyperv.misc_features); + + /* + * If Hyper-V has crash notifications, set crash_kexec_post_notifiers + * so that we will report the panic to Hyper-V before running kdump. + */ + if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) + crash_kexec_post_notifiers = true; + + /* Get information about the Hyper-V host version */ + hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION, &result); + a = result.as32.a; + b = result.as32.b; + c = result.as32.c; + d = result.as32.d; + pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n", + b >> 16, b & 0xFFFF, a, d & 0xFFFFFF, c, d >> 24); + + /* Allocate and initialize percpu VP index array */ + hv_vp_index = kmalloc_array(num_possible_cpus(), sizeof(*hv_vp_index), + GFP_KERNEL); + if (!hv_vp_index) + return -ENOMEM; + + for (i = 0; i < num_possible_cpus(); i++) + hv_vp_index[i] = VP_INVAL; + + cpuhp = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, + "arm64/hyperv_init:online", hv_cpu_init, NULL); + if (cpuhp < 0) + goto free_vp_index; + + hv_init_clocksource(); + if (hv_stimer_alloc()) + goto remove_cpuhp_state; + + hyperv_initialized = true; + return 0; + +remove_cpuhp_state: + cpuhp_remove_state(cpuhp); +free_vp_index: + kfree(hv_vp_index); + hv_vp_index = NULL; + return -EINVAL; +} +TIMER_ACPI_DECLARE(hyperv, ACPI_SIG_GTDT, hyperv_init); + +/* + * This routine is called before kexec/kdump, it does the required cleanup. + */ +void hyperv_cleanup(void) +{ + /* Reset our OS id */ + hv_set_vpreg(HV_REGISTER_GUEST_OSID, 0); + +} +EXPORT_SYMBOL_GPL(hyperv_cleanup); + + +/* * hv_do_hypercall- Invoke the specified hypercall */ u64 hv_do_hypercall(u64 control, void *input, void *output) @@ -291,3 +423,15 @@ void hyperv_report_panic_msg(phys_addr_t pa, size_t size) (HV_CRASH_CTL_CRASH_NOTIFY | HV_CRASH_CTL_CRASH_NOTIFY_MSG)); } EXPORT_SYMBOL_GPL(hyperv_report_panic_msg); + +bool hv_is_hyperv_initialized(void) +{ + return hyperv_initialized; +} +EXPORT_SYMBOL_GPL(hv_is_hyperv_initialized); + +bool hv_is_hibernation_supported(void) +{ + return false; +} +EXPORT_SYMBOL_GPL(hv_is_hibernation_supported); -- 1.8.3.1
WARNING: multiple messages have this Message-ID (diff)
From: Michael Kelley <mikelley@microsoft.com> To: will@kernel.org, ardb@kernel.org, arnd@arndb.de, catalin.marinas@arm.com, mark.rutland@arm.com, maz@kernel.org, linux-arm-kernel@lists.infradead.org, gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-efi@vger.kernel.org, linux-arch@vger.kernel.org, wei.liu@kernel.org, vkuznets@redhat.com, kys@microsoft.com Cc: sunilmut@microsoft.com, boqun.feng@gmail.com, mikelley@microsoft.com Subject: [PATCH v7 07/10] arm64: hyperv: Initialize hypervisor on boot Date: Mon, 24 Aug 2020 09:46:20 -0700 [thread overview] Message-ID: <1598287583-71762-8-git-send-email-mikelley@microsoft.com> (raw) In-Reply-To: <1598287583-71762-1-git-send-email-mikelley@microsoft.com> Add ARM64-specific code to initialize the Hyper-V hypervisor when booting as a guest VM. Provide functions and data structures indicating hypervisor status that are needed by VMbus driver. This code is built only when CONFIG_HYPERV is enabled. Signed-off-by: Michael Kelley <mikelley@microsoft.com> --- arch/arm64/hyperv/hv_core.c | 144 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c index 966d815..831a69c 100644 --- a/arch/arm64/hyperv/hv_core.c +++ b/arch/arm64/hyperv/hv_core.c @@ -18,10 +18,41 @@ #include <linux/slab.h> #include <linux/hyperv.h> #include <linux/arm-smccc.h> +#include <linux/vmalloc.h> +#include <linux/acpi.h> +#include <linux/module.h> +#include <linux/cpuhotplug.h> +#include <linux/psci.h> #include <asm-generic/bug.h> #include <asm/hyperv-tlfs.h> #include <asm/mshyperv.h> +#include <asm/sysreg.h> +#include <clocksource/hyperv_timer.h> +static bool hyperv_initialized; + +struct ms_hyperv_info ms_hyperv __ro_after_init; +EXPORT_SYMBOL_GPL(ms_hyperv); + +u32 *hv_vp_index; +EXPORT_SYMBOL_GPL(hv_vp_index); + +u32 hv_max_vp_index; +EXPORT_SYMBOL_GPL(hv_max_vp_index); + +static int hv_cpu_init(unsigned int cpu) +{ + u64 msr_vp_index; + + msr_vp_index = hv_get_vpreg(HV_REGISTER_VPINDEX); + + hv_vp_index[smp_processor_id()] = msr_vp_index; + + if (msr_vp_index > hv_max_vp_index) + hv_max_vp_index = msr_vp_index; + + return 0; +} /* * Functions for allocating and freeing memory with size and @@ -67,6 +98,107 @@ void hv_free_hyperv_page(unsigned long addr) /* + * This function is invoked via the ACPI clocksource probe mechanism. We + * don't actually use any values from the ACPI GTDT table, but we set up + * the Hyper-V synthetic clocksource and do other initialization for + * interacting with Hyper-V the first time. Using early_initcall to invoke + * this function is too late because interrupts are already enabled at that + * point, and hv_init_clocksource() must run before interrupts are enabled. + * + * 1. Setup the guest ID. + * 2. Get features and hints info from Hyper-V + * 3. Setup per-cpu VP indices. + * 4. Initialize the Hyper-V clocksource. + */ + +static int __init hyperv_init(struct acpi_table_header *table) +{ + struct hv_get_vp_registers_output result; + u32 a, b, c, d; + u64 guest_id; + int i, cpuhp; + + /* + * If we're in a VM on Hyper-V, the ACPI hypervisor_id field will + * have the string "MsHyperV". + */ + if (strncmp((char *)&acpi_gbl_FADT.hypervisor_id, "MsHyperV", 8)) + return -EINVAL; + + /* Setup the guest ID */ + guest_id = generate_guest_id(0, LINUX_VERSION_CODE, 0); + hv_set_vpreg(HV_REGISTER_GUEST_OSID, guest_id); + + /* Get the features and hints from Hyper-V */ + hv_get_vpreg_128(HV_REGISTER_FEATURES, &result); + ms_hyperv.features = result.as32.a; + ms_hyperv.misc_features = result.as32.c; + + hv_get_vpreg_128(HV_REGISTER_ENLIGHTENMENTS, &result); + ms_hyperv.hints = result.as32.a; + + pr_info("Hyper-V: Features 0x%x, hints 0x%x, misc 0x%x\n", + ms_hyperv.features, ms_hyperv.hints, ms_hyperv.misc_features); + + /* + * If Hyper-V has crash notifications, set crash_kexec_post_notifiers + * so that we will report the panic to Hyper-V before running kdump. + */ + if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) + crash_kexec_post_notifiers = true; + + /* Get information about the Hyper-V host version */ + hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION, &result); + a = result.as32.a; + b = result.as32.b; + c = result.as32.c; + d = result.as32.d; + pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n", + b >> 16, b & 0xFFFF, a, d & 0xFFFFFF, c, d >> 24); + + /* Allocate and initialize percpu VP index array */ + hv_vp_index = kmalloc_array(num_possible_cpus(), sizeof(*hv_vp_index), + GFP_KERNEL); + if (!hv_vp_index) + return -ENOMEM; + + for (i = 0; i < num_possible_cpus(); i++) + hv_vp_index[i] = VP_INVAL; + + cpuhp = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, + "arm64/hyperv_init:online", hv_cpu_init, NULL); + if (cpuhp < 0) + goto free_vp_index; + + hv_init_clocksource(); + if (hv_stimer_alloc()) + goto remove_cpuhp_state; + + hyperv_initialized = true; + return 0; + +remove_cpuhp_state: + cpuhp_remove_state(cpuhp); +free_vp_index: + kfree(hv_vp_index); + hv_vp_index = NULL; + return -EINVAL; +} +TIMER_ACPI_DECLARE(hyperv, ACPI_SIG_GTDT, hyperv_init); + +/* + * This routine is called before kexec/kdump, it does the required cleanup. + */ +void hyperv_cleanup(void) +{ + /* Reset our OS id */ + hv_set_vpreg(HV_REGISTER_GUEST_OSID, 0); + +} +EXPORT_SYMBOL_GPL(hyperv_cleanup); + + +/* * hv_do_hypercall- Invoke the specified hypercall */ u64 hv_do_hypercall(u64 control, void *input, void *output) @@ -291,3 +423,15 @@ void hyperv_report_panic_msg(phys_addr_t pa, size_t size) (HV_CRASH_CTL_CRASH_NOTIFY | HV_CRASH_CTL_CRASH_NOTIFY_MSG)); } EXPORT_SYMBOL_GPL(hyperv_report_panic_msg); + +bool hv_is_hyperv_initialized(void) +{ + return hyperv_initialized; +} +EXPORT_SYMBOL_GPL(hv_is_hyperv_initialized); + +bool hv_is_hibernation_supported(void) +{ + return false; +} +EXPORT_SYMBOL_GPL(hv_is_hibernation_supported); -- 1.8.3.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2020-08-24 16:51 UTC|newest] Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-08-24 16:46 [PATCH v7 00/10] Enable Linux guests on Hyper-V on ARM64 Michael Kelley 2020-08-24 16:46 ` Michael Kelley 2020-08-24 16:46 ` [PATCH v7 01/10] arm/arm64: smccc-1.1: Add vendor specific owner definition Michael Kelley 2020-08-24 16:46 ` Michael Kelley 2020-08-24 16:46 ` [PATCH v7 02/10] arm64: hyperv: Add core Hyper-V include files Michael Kelley 2020-08-24 16:46 ` Michael Kelley 2020-08-24 18:38 ` Arnd Bergmann 2020-08-24 18:38 ` Arnd Bergmann 2020-08-24 16:46 ` [PATCH v7 03/10] arm64: hyperv: Add hypercall and register access functions Michael Kelley 2020-08-24 16:46 ` Michael Kelley 2020-08-24 16:46 ` [PATCH v7 04/10] arm64: hyperv: Add memory alloc/free functions for Hyper-V size pages Michael Kelley 2020-08-24 16:46 ` Michael Kelley 2020-08-24 16:46 ` [PATCH v7 05/10] arm64: hyperv: Add interrupt handlers for VMbus and stimer Michael Kelley 2020-08-24 16:46 ` Michael Kelley 2020-08-24 18:54 ` Arnd Bergmann 2020-08-24 18:54 ` Arnd Bergmann 2020-08-25 22:04 ` Michael Kelley 2020-08-25 22:04 ` Michael Kelley 2020-08-26 7:14 ` Arnd Bergmann 2020-08-26 7:14 ` Arnd Bergmann 2020-08-24 16:46 ` [PATCH v7 06/10] arm64: hyperv: Add kexec and panic handlers Michael Kelley 2020-08-24 16:46 ` Michael Kelley 2020-08-24 16:46 ` Michael Kelley [this message] 2020-08-24 16:46 ` [PATCH v7 07/10] arm64: hyperv: Initialize hypervisor on boot Michael Kelley 2020-08-24 18:33 ` Arnd Bergmann 2020-08-24 18:33 ` Arnd Bergmann 2020-08-25 21:20 ` Michael Kelley 2020-08-25 21:20 ` Michael Kelley 2020-08-26 7:18 ` Arnd Bergmann 2020-08-26 7:18 ` Arnd Bergmann 2020-08-24 16:46 ` [PATCH v7 08/10] Drivers: hv: vmbus: Add hooks for per-CPU IRQ Michael Kelley 2020-08-24 16:46 ` Michael Kelley 2020-08-24 16:46 ` [PATCH v7 09/10] arm64: efi: Export screen_info Michael Kelley 2020-08-24 16:46 ` Michael Kelley 2020-08-24 17:21 ` Ard Biesheuvel 2020-08-24 17:21 ` Ard Biesheuvel 2020-08-24 17:35 ` Greg KH 2020-08-24 17:35 ` Greg KH 2020-08-24 17:40 ` Michael Kelley 2020-08-24 17:40 ` Michael Kelley 2020-08-24 17:52 ` Greg KH 2020-08-24 17:52 ` Greg KH 2020-08-24 16:46 ` [PATCH v7 10/10] Drivers: hv: Enable Hyper-V code to be built on ARM64 Michael Kelley 2020-08-24 16:46 ` Michael Kelley 2020-08-24 17:24 ` Ard Biesheuvel 2020-08-24 17:24 ` Ard Biesheuvel 2020-08-24 17:28 ` Michael Kelley 2020-08-24 17:28 ` Michael Kelley 2020-08-25 8:47 ` Ben Dooks 2020-08-25 8:47 ` Ben Dooks
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1598287583-71762-8-git-send-email-mikelley@microsoft.com \ --to=mikelley@microsoft.com \ --cc=ardb@kernel.org \ --cc=arnd@arndb.de \ --cc=boqun.feng@gmail.com \ --cc=catalin.marinas@arm.com \ --cc=gregkh@linuxfoundation.org \ --cc=kys@microsoft.com \ --cc=linux-arch@vger.kernel.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-efi@vger.kernel.org \ --cc=linux-hyperv@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=mark.rutland@arm.com \ --cc=maz@kernel.org \ --cc=sunilmut@microsoft.com \ --cc=vkuznets@redhat.com \ --cc=wei.liu@kernel.org \ --cc=will@kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.