diff options
Diffstat (limited to 'arch/x86/hyperv/mmu.c')
| -rw-r--r-- | arch/x86/hyperv/mmu.c | 11 | 
1 files changed, 10 insertions, 1 deletions
diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c index 0ad2378fe6ad..8460bd35e10c 100644 --- a/arch/x86/hyperv/mmu.c +++ b/arch/x86/hyperv/mmu.c @@ -52,6 +52,11 @@ static inline int fill_gva_list(u64 gva_list[], int offset,  	return gva_n - offset;  } +static bool cpu_is_lazy(int cpu) +{ +	return per_cpu(cpu_tlbstate_shared.is_lazy, cpu); +} +  static void hyperv_flush_tlb_multi(const struct cpumask *cpus,  				   const struct flush_tlb_info *info)  { @@ -60,6 +65,7 @@ static void hyperv_flush_tlb_multi(const struct cpumask *cpus,  	struct hv_tlb_flush *flush;  	u64 status;  	unsigned long flags; +	bool do_lazy = !info->freed_tables;  	trace_hyperv_mmu_flush_tlb_multi(cpus, info); @@ -112,6 +118,8 @@ static void hyperv_flush_tlb_multi(const struct cpumask *cpus,  			goto do_ex_hypercall;  		for_each_cpu(cpu, cpus) { +			if (do_lazy && cpu_is_lazy(cpu)) +				continue;  			vcpu = hv_cpu_number_to_vp_number(cpu);  			if (vcpu == VP_INVAL) {  				local_irq_restore(flags); @@ -198,7 +206,8 @@ static u64 hyperv_flush_tlb_others_ex(const struct cpumask *cpus,  	flush->hv_vp_set.valid_bank_mask = 0;  	flush->hv_vp_set.format = HV_GENERIC_SET_SPARSE_4K; -	nr_bank = cpumask_to_vpset(&(flush->hv_vp_set), cpus); +	nr_bank = cpumask_to_vpset_skip(&flush->hv_vp_set, cpus, +			info->freed_tables ? NULL : cpu_is_lazy);  	if (nr_bank < 0)  		return HV_STATUS_INVALID_PARAMETER;  |