Message ID | 20180604090749.489-2-Tianyu.Lan@microsoft.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
> -----Original Message----- > From: linux-kernel-owner@vger.kernel.org <linux-kernel-owner@vger.kernel.org> On Behalf > Of Tianyu Lan > Sent: Monday, June 4, 2018 2:08 AM > Cc: Tianyu Lan <Tianyu.Lan@microsoft.com>; KY Srinivasan <kys@microsoft.com>; Haiyang > Zhang <haiyangz@microsoft.com>; Stephen Hemminger <sthemmin@microsoft.com>; > tglx@linutronix.de; mingo@redhat.com; hpa@zytor.com; x86@kernel.org; > pbonzini@redhat.com; rkrcmar@redhat.com; devel@linuxdriverproject.org; linux- > kernel@vger.kernel.org; kvm@vger.kernel.org; vkuznets@redhat.com > Subject: [RFC Patch 1/3] X86/Hyper-V: Add flush HvFlushGuestPhysicalAddressSpace hypercall > support > > Hyper-V provides a pv hypercall HvFlushGuestPhysicalAddressSpace to flush > nested VM address space mapping in l1 hypervisor and it's to reduce overhead > of flushing ept tlb among vcpus. This patch is to implement it. > > Signed-off-by: Lan Tianyu <Tianyu.Lan@microsoft.com> > --- > diff --git a/arch/x86/hyperv/nested.c b/arch/x86/hyperv/nested.c > new file mode 100644 > index 000000000000..17f7c288eccc > --- /dev/null > +++ b/arch/x86/hyperv/nested.c > +#include <linux/types.h> > +#include <asm/hyperv-tlfs.h> > +#include <asm/mshyperv.h> > +#include <asm/tlbflush.h> > + > +int hyperv_flush_guest_mapping(u64 as) > +{ > + struct hv_guest_mapping_flush **flush_pcpu; > + struct hv_guest_mapping_flush *flush; > + u64 status = U64_MAX; Initializing status to U64_MAX doesn't seem necessary. > + unsigned long flags; > + int ret = -EFAULT; > + > + if (!hv_hypercall_pg) > + goto fault; > + > + local_irq_save(flags); > + > + flush_pcpu = (struct hv_guest_mapping_flush **) > + this_cpu_ptr(hyperv_pcpu_input_arg); > + > + flush = *flush_pcpu; > + > + if (unlikely(!flush)) { > + local_irq_restore(flags); > + goto fault; > + } > + > + flush->address_space = as; > + flush->flags = 0; > + > + status = hv_do_hypercall(HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_SPACE, > + flush, NULL); > + local_irq_restore(flags); > + > + if (!(status & HV_HYPERCALL_RESULT_MASK)) > + ret = 0; > + > +fault: > + return ret; > +} > +EXPORT_SYMBOL_GPL(hyperv_flush_guest_mapping); > diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h > index b8c89265baf0..53bbeb08faea 100644 > --- a/arch/x86/include/asm/hyperv-tlfs.h > +++ b/arch/x86/include/asm/hyperv-tlfs.h > @@ -309,6 +309,7 @@ struct ms_hyperv_tsc_page { > #define HV_X64_MSR_REENLIGHTENMENT_CONTROL 0x40000106 > > /* Nested features (CPUID 0x4000000A) EAX */ > +#define HV_X64_NESTED_GUSET_MAPPING_FLUSH BIT(18) The #define name is misspelled. "_GUSET_" should be "_GUEST_". And the matching usage in patch 3/3 will need to be updated as well. Michael
Hi Michael: Thanks for your review. On 6/6/2018 12:59 AM, Michael Kelley (EOSG) wrote: >> -----Original Message----- >> From: linux-kernel-owner@vger.kernel.org <linux-kernel-owner@vger.kernel.org> On Behalf >> Of Tianyu Lan >> Sent: Monday, June 4, 2018 2:08 AM >> Cc: Tianyu Lan <Tianyu.Lan@microsoft.com>; KY Srinivasan <kys@microsoft.com>; Haiyang >> Zhang <haiyangz@microsoft.com>; Stephen Hemminger <sthemmin@microsoft.com>; >> tglx@linutronix.de; mingo@redhat.com; hpa@zytor.com; x86@kernel.org; >> pbonzini@redhat.com; rkrcmar@redhat.com; devel@linuxdriverproject.org; linux- >> kernel@vger.kernel.org; kvm@vger.kernel.org; vkuznets@redhat.com >> Subject: [RFC Patch 1/3] X86/Hyper-V: Add flush HvFlushGuestPhysicalAddressSpace hypercall >> support >> >> Hyper-V provides a pv hypercall HvFlushGuestPhysicalAddressSpace to flush >> nested VM address space mapping in l1 hypervisor and it's to reduce overhead >> of flushing ept tlb among vcpus. This patch is to implement it. >> >> Signed-off-by: Lan Tianyu <Tianyu.Lan@microsoft.com> >> --- >> diff --git a/arch/x86/hyperv/nested.c b/arch/x86/hyperv/nested.c >> new file mode 100644 >> index 000000000000..17f7c288eccc >> --- /dev/null >> +++ b/arch/x86/hyperv/nested.c >> +#include <linux/types.h> >> +#include <asm/hyperv-tlfs.h> >> +#include <asm/mshyperv.h> >> +#include <asm/tlbflush.h> >> + >> +int hyperv_flush_guest_mapping(u64 as) >> +{ >> + struct hv_guest_mapping_flush **flush_pcpu; >> + struct hv_guest_mapping_flush *flush; >> + u64 status = U64_MAX; > > Initializing status to U64_MAX doesn't seem necessary. > >> + unsigned long flags; >> + int ret = -EFAULT; >> + >> + if (!hv_hypercall_pg) >> + goto fault; >> + >> + local_irq_save(flags); >> + >> + flush_pcpu = (struct hv_guest_mapping_flush **) >> + this_cpu_ptr(hyperv_pcpu_input_arg); >> + >> + flush = *flush_pcpu; >> + >> + if (unlikely(!flush)) { >> + local_irq_restore(flags); >> + goto fault; >> + } >> + >> + flush->address_space = as; >> + flush->flags = 0; >> + >> + status = hv_do_hypercall(HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_SPACE, >> + flush, NULL); >> + local_irq_restore(flags); >> + >> + if (!(status & HV_HYPERCALL_RESULT_MASK)) >> + ret = 0; >> + >> +fault: >> + return ret; >> +} >> +EXPORT_SYMBOL_GPL(hyperv_flush_guest_mapping); >> diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h >> index b8c89265baf0..53bbeb08faea 100644 >> --- a/arch/x86/include/asm/hyperv-tlfs.h >> +++ b/arch/x86/include/asm/hyperv-tlfs.h >> @@ -309,6 +309,7 @@ struct ms_hyperv_tsc_page { >> #define HV_X64_MSR_REENLIGHTENMENT_CONTROL 0x40000106 >> >> /* Nested features (CPUID 0x4000000A) EAX */ >> +#define HV_X64_NESTED_GUSET_MAPPING_FLUSH BIT(18) > > The #define name is misspelled. "_GUSET_" should be "_GUEST_". > And the matching usage in patch 3/3 will need to be updated as well. > > Michael > Nice catch! Will update.
diff --git a/arch/x86/hyperv/Makefile b/arch/x86/hyperv/Makefile index b173d404e3df..b21ee65c4101 100644 --- a/arch/x86/hyperv/Makefile +++ b/arch/x86/hyperv/Makefile @@ -1,2 +1,2 @@ -obj-y := hv_init.o mmu.o +obj-y := hv_init.o mmu.o nested.o obj-$(CONFIG_X86_64) += hv_apic.o diff --git a/arch/x86/hyperv/nested.c b/arch/x86/hyperv/nested.c new file mode 100644 index 000000000000..17f7c288eccc --- /dev/null +++ b/arch/x86/hyperv/nested.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * Hyper-V nested virtualization code. + * + * Copyright (C) 2018, Microsoft, Inc. + * + * Author : Lan Tianyu <Tianyu.Lan@microsoft.com> + * + * 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 <linux/types.h> +#include <asm/hyperv-tlfs.h> +#include <asm/mshyperv.h> +#include <asm/tlbflush.h> + +int hyperv_flush_guest_mapping(u64 as) +{ + struct hv_guest_mapping_flush **flush_pcpu; + struct hv_guest_mapping_flush *flush; + u64 status = U64_MAX; + unsigned long flags; + int ret = -EFAULT; + + if (!hv_hypercall_pg) + goto fault; + + local_irq_save(flags); + + flush_pcpu = (struct hv_guest_mapping_flush **) + this_cpu_ptr(hyperv_pcpu_input_arg); + + flush = *flush_pcpu; + + if (unlikely(!flush)) { + local_irq_restore(flags); + goto fault; + } + + flush->address_space = as; + flush->flags = 0; + + status = hv_do_hypercall(HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_SPACE, + flush, NULL); + local_irq_restore(flags); + + if (!(status & HV_HYPERCALL_RESULT_MASK)) + ret = 0; + +fault: + return ret; +} +EXPORT_SYMBOL_GPL(hyperv_flush_guest_mapping); diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h index b8c89265baf0..53bbeb08faea 100644 --- a/arch/x86/include/asm/hyperv-tlfs.h +++ b/arch/x86/include/asm/hyperv-tlfs.h @@ -309,6 +309,7 @@ struct ms_hyperv_tsc_page { #define HV_X64_MSR_REENLIGHTENMENT_CONTROL 0x40000106 /* Nested features (CPUID 0x4000000A) EAX */ +#define HV_X64_NESTED_GUSET_MAPPING_FLUSH BIT(18) #define HV_X64_NESTED_MSR_BITMAP BIT(19) struct hv_reenlightenment_control { @@ -350,6 +351,7 @@ struct hv_tsc_emulation_status { #define HVCALL_SEND_IPI_EX 0x0015 #define HVCALL_POST_MESSAGE 0x005c #define HVCALL_SIGNAL_EVENT 0x005d +#define HVCALL_FLUSH_GUEST_PHYSICAL_ADDRESS_SPACE 0x00af #define HV_X64_MSR_VP_ASSIST_PAGE_ENABLE 0x00000001 #define HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT 12 @@ -741,6 +743,12 @@ struct ipi_arg_ex { struct hv_vpset vp_set; }; +/* HvFlushGuestPhysicalAddressSpace hypercalls */ +struct hv_guest_mapping_flush { + u64 address_space; + u64 flags; +}; + /* HvFlushVirtualAddressSpace, HvFlushVirtualAddressList hypercalls */ struct hv_tlb_flush { u64 address_space; diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index 3cd14311edfa..a6a615b49876 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -302,6 +302,7 @@ void hyperv_reenlightenment_intr(struct pt_regs *regs); void set_hv_tscchange_cb(void (*cb)(void)); void clear_hv_tscchange_cb(void); void hyperv_stop_tsc_emulation(void); +int hyperv_flush_guest_mapping(u64 as); #ifdef CONFIG_X86_64 void hv_apic_init(void); @@ -321,6 +322,7 @@ static inline struct hv_vp_assist_page *hv_get_vp_assist_page(unsigned int cpu) { return NULL; } +static inline int hyperv_flush_guest_mapping(u64 as) { return -1; } #endif /* CONFIG_HYPERV */ #ifdef CONFIG_HYPERV_TSCPAGE
Hyper-V provides a pv hypercall HvFlushGuestPhysicalAddressSpace to flush nested VM address space mapping in l1 hypervisor and it's to reduce overhead of flushing ept tlb among vcpus. This patch is to implement it. Signed-off-by: Lan Tianyu <Tianyu.Lan@microsoft.com> --- arch/x86/hyperv/Makefile | 2 +- arch/x86/hyperv/nested.c | 64 ++++++++++++++++++++++++++++++++++++++ arch/x86/include/asm/hyperv-tlfs.h | 8 +++++ arch/x86/include/asm/mshyperv.h | 2 ++ 4 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 arch/x86/hyperv/nested.c