Commit eb914cfe authored by Tianyu Lan's avatar Tianyu Lan Committed by Paolo Bonzini

X86/Hyper-V: Add flush HvFlushGuestPhysicalAddressSpace hypercall support

Hyper-V supports 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: default avatarLan Tianyu <Tianyu.Lan@microsoft.com>
Acked-by: default avatarK. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 3553ae56
obj-y := hv_init.o mmu.o obj-y := hv_init.o mmu.o nested.o
obj-$(CONFIG_X86_64) += hv_apic.o obj-$(CONFIG_X86_64) += hv_apic.o
// SPDX-License-Identifier: GPL-2.0
/*
* Hyper-V nested virtualization code.
*
* Copyright (C) 2018, Microsoft, Inc.
*
* Author : Lan Tianyu <Tianyu.Lan@microsoft.com>
*/
#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;
unsigned long flags;
int ret = -ENOTSUPP;
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);
...@@ -309,6 +309,7 @@ struct ms_hyperv_tsc_page { ...@@ -309,6 +309,7 @@ struct ms_hyperv_tsc_page {
#define HV_X64_MSR_REENLIGHTENMENT_CONTROL 0x40000106 #define HV_X64_MSR_REENLIGHTENMENT_CONTROL 0x40000106
/* Nested features (CPUID 0x4000000A) EAX */ /* Nested features (CPUID 0x4000000A) EAX */
#define HV_X64_NESTED_GUEST_MAPPING_FLUSH BIT(18)
#define HV_X64_NESTED_MSR_BITMAP BIT(19) #define HV_X64_NESTED_MSR_BITMAP BIT(19)
struct hv_reenlightenment_control { struct hv_reenlightenment_control {
...@@ -350,6 +351,7 @@ struct hv_tsc_emulation_status { ...@@ -350,6 +351,7 @@ struct hv_tsc_emulation_status {
#define HVCALL_SEND_IPI_EX 0x0015 #define HVCALL_SEND_IPI_EX 0x0015
#define HVCALL_POST_MESSAGE 0x005c #define HVCALL_POST_MESSAGE 0x005c
#define HVCALL_SIGNAL_EVENT 0x005d #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_ENABLE 0x00000001
#define HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT 12 #define HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT 12
...@@ -741,6 +743,12 @@ struct ipi_arg_ex { ...@@ -741,6 +743,12 @@ struct ipi_arg_ex {
struct hv_vpset vp_set; struct hv_vpset vp_set;
}; };
/* HvFlushGuestPhysicalAddressSpace hypercalls */
struct hv_guest_mapping_flush {
u64 address_space;
u64 flags;
};
/* HvFlushVirtualAddressSpace, HvFlushVirtualAddressList hypercalls */ /* HvFlushVirtualAddressSpace, HvFlushVirtualAddressList hypercalls */
struct hv_tlb_flush { struct hv_tlb_flush {
u64 address_space; u64 address_space;
......
...@@ -305,6 +305,7 @@ void hyperv_reenlightenment_intr(struct pt_regs *regs); ...@@ -305,6 +305,7 @@ void hyperv_reenlightenment_intr(struct pt_regs *regs);
void set_hv_tscchange_cb(void (*cb)(void)); void set_hv_tscchange_cb(void (*cb)(void));
void clear_hv_tscchange_cb(void); void clear_hv_tscchange_cb(void);
void hyperv_stop_tsc_emulation(void); void hyperv_stop_tsc_emulation(void);
int hyperv_flush_guest_mapping(u64 as);
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
void hv_apic_init(void); void hv_apic_init(void);
...@@ -324,6 +325,7 @@ static inline struct hv_vp_assist_page *hv_get_vp_assist_page(unsigned int cpu) ...@@ -324,6 +325,7 @@ static inline struct hv_vp_assist_page *hv_get_vp_assist_page(unsigned int cpu)
{ {
return NULL; return NULL;
} }
static inline int hyperv_flush_guest_mapping(u64 as) { return -1; }
#endif /* CONFIG_HYPERV */ #endif /* CONFIG_HYPERV */
#ifdef CONFIG_HYPERV_TSCPAGE #ifdef CONFIG_HYPERV_TSCPAGE
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment