Message ID | 20230811045127.3308641-6-rananta@google.com (mailing list archive) |
---|---|
State | Handled Elsewhere |
Headers | show |
Series | KVM: arm64: Add support for FEAT_TLBIRANGE | expand |
On Fri, Aug 11, 2023, Raghavendra Rao Ananta wrote: > diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c > index ec169f5c7dce2..00f7bda9202f2 100644 > --- a/arch/x86/kvm/mmu/mmu.c > +++ b/arch/x86/kvm/mmu/mmu.c > @@ -278,16 +278,14 @@ static inline bool kvm_available_flush_remote_tlbs_range(void) > return kvm_x86_ops.flush_remote_tlbs_range; > } > > -void kvm_flush_remote_tlbs_range(struct kvm *kvm, gfn_t start_gfn, > - gfn_t nr_pages) > +int kvm_arch_flush_remote_tlbs_range(struct kvm *kvm, gfn_t gfn, u64 nr_pages) > { > int ret = -EOPNOTSUPP; > > if (kvm_x86_ops.flush_remote_tlbs_range) > - ret = static_call(kvm_x86_flush_remote_tlbs_range)(kvm, start_gfn, > - nr_pages); > - if (ret) > - kvm_flush_remote_tlbs(kvm); > + ret = static_call(kvm_x86_flush_remote_tlbs_range)(kvm, gfn, nr_pages); > + > + return ret; Please write this as if (kvm_x86_ops.flush_remote_tlbs_range) return static_call(kvm_x86_flush_remote_tlbs_range)(kvm, gfn, nr_pages); return -EOPNOTSUPP; or alternatively if (!kvm_x86_ops.flush_remote_tlbs_range) return -EOPNOTSUPP; return static_call(kvm_x86_flush_remote_tlbs_range)(kvm, gfn, nr_pages); Hmm, I'll throw my official vote for the second version. The local "ret" is unnecessary and is suprisingly dangerous. I screwed up the conflict resolution when cherry-picking my CONFIG_HYPERV change to see what the conflict looked like and ended up with a double flush: int ret = -EOPNOTSUPP; if (kvm_x86_ops.flush_remote_tlbs_range) ret = static_call(kvm_x86_flush_remote_tlbs_range)(kvm, gfn, nr_pages); if (ret) kvm_flush_remote_tlbs(kvm); return ret; Dropping "ret" makes it much harder to get trigger happy when resolving conflicts. No need for a new version to fix the above, assuming Marc/Oliver is ok doing fixup when applying. Nit aside, looks good for x86, and I know of no conflicts, so take 'er away! Acked-by: Sean Christopherson <seanjc@google.com>
On Tue, 15 Aug 2023 23:30:08 +0100, Sean Christopherson <seanjc@google.com> wrote: > > On Fri, Aug 11, 2023, Raghavendra Rao Ananta wrote: > > diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c > > index ec169f5c7dce2..00f7bda9202f2 100644 > > --- a/arch/x86/kvm/mmu/mmu.c > > +++ b/arch/x86/kvm/mmu/mmu.c > > @@ -278,16 +278,14 @@ static inline bool kvm_available_flush_remote_tlbs_range(void) > > return kvm_x86_ops.flush_remote_tlbs_range; > > } > > > > -void kvm_flush_remote_tlbs_range(struct kvm *kvm, gfn_t start_gfn, > > - gfn_t nr_pages) > > +int kvm_arch_flush_remote_tlbs_range(struct kvm *kvm, gfn_t gfn, u64 nr_pages) > > { > > int ret = -EOPNOTSUPP; > > > > if (kvm_x86_ops.flush_remote_tlbs_range) > > - ret = static_call(kvm_x86_flush_remote_tlbs_range)(kvm, start_gfn, > > - nr_pages); > > - if (ret) > > - kvm_flush_remote_tlbs(kvm); > > + ret = static_call(kvm_x86_flush_remote_tlbs_range)(kvm, gfn, nr_pages); > > + > > + return ret; > > Please write this as > > if (kvm_x86_ops.flush_remote_tlbs_range) > return static_call(kvm_x86_flush_remote_tlbs_range)(kvm, gfn, nr_pages); > > return -EOPNOTSUPP; > > or alternatively > > if (!kvm_x86_ops.flush_remote_tlbs_range) > return -EOPNOTSUPP; > > return static_call(kvm_x86_flush_remote_tlbs_range)(kvm, gfn, nr_pages); > > Hmm, I'll throw my official vote for the second version. I've applied the second version locally. M.
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index a2d3cfc2eb75c..b547d17c58f63 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1804,6 +1804,8 @@ static inline int kvm_arch_flush_remote_tlbs(struct kvm *kvm) return -ENOTSUPP; } +#define __KVM_HAVE_ARCH_FLUSH_REMOTE_TLBS_RANGE + #define kvm_arch_pmi_in_guest(vcpu) \ ((vcpu) && (vcpu)->arch.handling_intr_from_guest) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index ec169f5c7dce2..00f7bda9202f2 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -278,16 +278,14 @@ static inline bool kvm_available_flush_remote_tlbs_range(void) return kvm_x86_ops.flush_remote_tlbs_range; } -void kvm_flush_remote_tlbs_range(struct kvm *kvm, gfn_t start_gfn, - gfn_t nr_pages) +int kvm_arch_flush_remote_tlbs_range(struct kvm *kvm, gfn_t gfn, u64 nr_pages) { int ret = -EOPNOTSUPP; if (kvm_x86_ops.flush_remote_tlbs_range) - ret = static_call(kvm_x86_flush_remote_tlbs_range)(kvm, start_gfn, - nr_pages); - if (ret) - kvm_flush_remote_tlbs(kvm); + ret = static_call(kvm_x86_flush_remote_tlbs_range)(kvm, gfn, nr_pages); + + return ret; } static gfn_t kvm_mmu_page_get_gfn(struct kvm_mmu_page *sp, int index); diff --git a/arch/x86/kvm/mmu/mmu_internal.h b/arch/x86/kvm/mmu/mmu_internal.h index d39af5639ce97..86cb83bb34804 100644 --- a/arch/x86/kvm/mmu/mmu_internal.h +++ b/arch/x86/kvm/mmu/mmu_internal.h @@ -170,9 +170,6 @@ bool kvm_mmu_slot_gfn_write_protect(struct kvm *kvm, struct kvm_memory_slot *slot, u64 gfn, int min_level); -void kvm_flush_remote_tlbs_range(struct kvm *kvm, gfn_t start_gfn, - gfn_t nr_pages); - /* Flush the given page (huge or not) of guest memory. */ static inline void kvm_flush_remote_tlbs_gfn(struct kvm *kvm, gfn_t gfn, int level) { diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index ade5d4500c2ce..89d2614e4b7a6 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1359,6 +1359,7 @@ int kvm_vcpu_yield_to(struct kvm_vcpu *target); void kvm_vcpu_on_spin(struct kvm_vcpu *vcpu, bool yield_to_kernel_mode); void kvm_flush_remote_tlbs(struct kvm *kvm); +void kvm_flush_remote_tlbs_range(struct kvm *kvm, gfn_t gfn, u64 nr_pages); #ifdef KVM_ARCH_NR_OBJS_PER_MEMORY_CACHE int kvm_mmu_topup_memory_cache(struct kvm_mmu_memory_cache *mc, int min); @@ -1488,6 +1489,16 @@ static inline int kvm_arch_flush_remote_tlbs(struct kvm *kvm) int kvm_arch_flush_remote_tlbs(struct kvm *kvm); #endif +#ifndef __KVM_HAVE_ARCH_FLUSH_REMOTE_TLBS_RANGE +static inline int kvm_arch_flush_remote_tlbs_range(struct kvm *kvm, + gfn_t gfn, u64 nr_pages) +{ + return -EOPNOTSUPP; +} +#else +int kvm_arch_flush_remote_tlbs_range(struct kvm *kvm, gfn_t gfn, u64 nr_pages); +#endif + #ifdef __KVM_HAVE_ARCH_NONCOHERENT_DMA void kvm_arch_register_noncoherent_dma(struct kvm *kvm); void kvm_arch_unregister_noncoherent_dma(struct kvm *kvm); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index d6b0507861550..26e91000f579d 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -366,6 +366,19 @@ void kvm_flush_remote_tlbs(struct kvm *kvm) } EXPORT_SYMBOL_GPL(kvm_flush_remote_tlbs); +void kvm_flush_remote_tlbs_range(struct kvm *kvm, gfn_t gfn, u64 nr_pages) +{ + if (!kvm_arch_flush_remote_tlbs_range(kvm, gfn, nr_pages)) + return; + + /* + * Fall back to a flushing entire TLBs if the architecture range-based + * TLB invalidation is unsupported or can't be performed for whatever + * reason. + */ + kvm_flush_remote_tlbs(kvm); +} + static void kvm_flush_shadow_all(struct kvm *kvm) { kvm_arch_flush_shadow_all(kvm);