Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754552AbcL3TkA (ORCPT ); Fri, 30 Dec 2016 14:40:00 -0500 Received: from p3plsmtps2ded03.prod.phx3.secureserver.net ([208.109.80.60]:36318 "EHLO p3plsmtps2ded03.prod.phx3.secureserver.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754189AbcL3Tjf (ORCPT ); Fri, 30 Dec 2016 14:39:35 -0500 x-originating-ip: 72.167.245.219 From: kys@exchange.microsoft.com To: gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org, devel@linuxdriverproject.org, olaf@aepfle.de, apw@canonical.com, vkuznets@redhat.com, jasowang@redhat.com, leann.ogasawara@canonical.com, rkagan@virtuozzo.com, x86@kernel.org, tglx@linutronix.de, hpa@zytor.com Cc: "K. Y. Srinivasan" Subject: [PATCH 03/18] Drivers: hv vmbus: Move Hypercall page setup out of common code Date: Fri, 30 Dec 2016 13:35:57 -0800 Message-Id: <1483133772-29776-3-git-send-email-kys@exchange.microsoft.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1483133772-29776-1-git-send-email-kys@exchange.microsoft.com> References: <1483133701-29738-1-git-send-email-kys@exchange.microsoft.com> <1483133772-29776-1-git-send-email-kys@exchange.microsoft.com> Reply-To: kys@microsoft.com X-CMAE-Envelope: MS4wfFCFprUgo4Y8WD1GEsBLr1T2LH96K3gdDFo+jq6H8s/OIlYm9a+PtKS8Rm+yZfOqR5R60oI1OdHQfzmWKacYf8BB2cX08TW1WSsVvCAhgFVXT46e5TGS 1civocFLW3INfNW6LtSF1/dbB0tXC7345fHYY77SY9Og3Q9Z+PvenwVWkyoRVWS+mwJfPGwnzHLXx36W0RDW4VgeylzCw9nOT8tFUk3Z0SH7PZ4TCKaZ4IN/ 2shS7Pvuzan2iWjpsQ5ukJQEYA61P88Fs8lisvJxNEbDHId1sgMHV+oqy1YfLE80Zh+TSJOdyccCpq4bPtYGh3q43IceB6wOvlXfo8jghkrIUt6yMOV8HD0B JVWIQu5HgXoax00FZD1tYn2PlYI/27VGDNeWdfJ8q9ofANwAYh0U4mWGMFzpPMH/QbkFIZ+MIREBDdu88EA9/h0/3LTI683LZlaHPt4dT+vvyUJ81GujuA24 5n4sOaysJwePpluUqVgp8wjJsQW79moVvvKYwr3jsUZ3iyjpK8JNj5l8QbZMwIcCLBsBaxgq6QBtEAW5DiQyO6vm1+gzG0eb8AalzA== Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 6548 Lines: 226 From: K. Y. Srinivasan As part of the effort to separate out architecture specific code, move the hypercall page setup to an architecture specific file. Signed-off-by: K. Y. Srinivasan --- arch/x86/Kbuild | 3 ++ arch/x86/hyperv/Makefile | 1 + arch/x86/hyperv/hv_init.c | 62 +++++++++++++++++++++++++++++++++++++++ arch/x86/include/asm/mshyperv.h | 5 +++ arch/x86/kernel/cpu/mshyperv.c | 7 ++++ drivers/hv/hv.c | 45 ++-------------------------- 6 files changed, 81 insertions(+), 42 deletions(-) create mode 100644 arch/x86/hyperv/Makefile create mode 100644 arch/x86/hyperv/hv_init.c diff --git a/arch/x86/Kbuild b/arch/x86/Kbuild index eb3abf8..586b786 100644 --- a/arch/x86/Kbuild +++ b/arch/x86/Kbuild @@ -7,6 +7,9 @@ obj-$(CONFIG_KVM) += kvm/ # Xen paravirtualization support obj-$(CONFIG_XEN) += xen/ +# Hyper-V paravirtualization support +obj-$(CONFIG_HYPERVISOR_GUEST) += hyperv/ + # lguest paravirtualization support obj-$(CONFIG_LGUEST_GUEST) += lguest/ diff --git a/arch/x86/hyperv/Makefile b/arch/x86/hyperv/Makefile new file mode 100644 index 0000000..171ae09 --- /dev/null +++ b/arch/x86/hyperv/Makefile @@ -0,0 +1 @@ +obj-y := hv_init.o diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c new file mode 100644 index 0000000..3206bfda --- /dev/null +++ b/arch/x86/hyperv/hv_init.c @@ -0,0 +1,62 @@ +/* + * X86 specific Hyper-V initialization code. + * + * Copyright (C) 2016, Microsoft, Inc. + * + * Author : K. Y. Srinivasan + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +void *hv_hypercall_pg; +/* + * This function is to be invoked early in the boot sequence after the + * hypervisor has been detected. + * + * 1. Setup the hypercall page. + */ +void hyperv_init(void) +{ + u64 guest_id; + union hv_x64_msr_hypercall_contents hypercall_msr; + + if (x86_hyper != &x86_hyper_ms_hyperv) + return; + + /* + * Setup the hypercall page and enable hypercalls. + * 1. Register the guest ID + * 2. Enable the hypercall and register the hypercall page + */ + guest_id = generate_guest_id(0, LINUX_VERSION_CODE, 0); + wrmsrl(HV_X64_MSR_GUEST_OS_ID, guest_id); + + hv_hypercall_pg = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_EXEC); + if (hv_hypercall_pg == NULL) { + wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0); + return; + } + + rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); + hypercall_msr.enable = 1; + hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg); + wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); +} +EXPORT_SYMBOL_GPL(hv_hypercall_pg); diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index 15a0c27..e5f57e1 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -80,4 +80,9 @@ static inline __u64 generate_guest_id(__u64 d_info1, __u64 kernel_version, void hv_remove_kexec_handler(void); void hv_setup_crash_handler(void (*handler)(struct pt_regs *regs)); void hv_remove_crash_handler(void); + +#if IS_ENABLED(CONFIG_HYPERV) +void hyperv_init(void); +extern void *hv_hypercall_pg; +#endif #endif diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 8f44c5a..8b376f8 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -204,6 +204,13 @@ static void __init ms_hyperv_init_platform(void) */ if (efi_enabled(EFI_BOOT)) x86_platform.get_nmi_reason = hv_get_nmi_reason; + +#if IS_ENABLED(CONFIG_HYPERV) + /* + * Setup the hook to get control post apic initialization. + */ + x86_platform.apic_post_init = hyperv_init; +#endif } const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = { diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index 04a0fd8..a11e827 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -193,7 +193,6 @@ int hv_init(void) { int max_leaf; union hv_x64_msr_hypercall_contents hypercall_msr; - void *virtaddr = NULL; memset(hv_context.synic_event_page, 0, sizeof(void *) * NR_CPUS); memset(hv_context.synic_message_page, 0, @@ -211,33 +210,15 @@ int hv_init(void) max_leaf = query_hypervisor_info(); - /* - * Write our OS ID. - */ - hv_context.guestid = generate_guest_id(0, LINUX_VERSION_CODE, 0); - wrmsrl(HV_X64_MSR_GUEST_OS_ID, hv_context.guestid); /* See if the hypercall page is already set */ - rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); - - virtaddr = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_EXEC); - - if (!virtaddr) - goto cleanup; - - hypercall_msr.enable = 1; - - hypercall_msr.guest_physical_address = vmalloc_to_pfn(virtaddr); - wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); - - /* Confirm that hypercall page did get setup. */ hypercall_msr.as_uint64 = 0; rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); if (!hypercall_msr.enable) - goto cleanup; + return -ENOTSUPP; - hv_context.hypercall_page = virtaddr; + hv_context.hypercall_page = hv_hypercall_pg; #ifdef CONFIG_X86_64 if (ms_hyperv.features & HV_X64_MSR_REFERENCE_TSC_AVAILABLE) { @@ -261,15 +242,6 @@ int hv_init(void) return 0; cleanup: - if (virtaddr) { - if (hypercall_msr.enable) { - hypercall_msr.as_uint64 = 0; - wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); - } - - vfree(virtaddr); - } - return -ENOTSUPP; } @@ -280,20 +252,9 @@ int hv_init(void) */ void hv_cleanup(bool crash) { - union hv_x64_msr_hypercall_contents hypercall_msr; - - /* Reset our OS id */ - wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0); - - if (hv_context.hypercall_page) { - hypercall_msr.as_uint64 = 0; - wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); - if (!crash) - vfree(hv_context.hypercall_page); - hv_context.hypercall_page = NULL; - } #ifdef CONFIG_X86_64 + union hv_x64_msr_hypercall_contents hypercall_msr; /* * Cleanup the TSC page based CS. */ -- 1.7.4.1