On Mon, Jul 21, 2025, Atish Patra wrote: > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h > index 3bde4fb5c6aa..9532da14b451 100644 > --- a/include/linux/kvm_host.h > +++ b/include/linux/kvm_host.h > @@ -1387,6 +1387,8 @@ static inline int kvm_vcpu_map_readonly(struct kvm_vcpu *vcpu, gpa_t gpa, > > unsigned long kvm_vcpu_gfn_to_hva(struct kvm_vcpu *vcpu, gfn_t gfn); > unsigned long kvm_vcpu_gfn_to_hva_prot(struct kvm_vcpu *vcpu, gfn_t gfn, bool *writable); > +int kvm_vcpu_validate_gpa_range(struct kvm_vcpu *vcpu, gpa_t gpa, unsigned long len, > + bool write_access); > int kvm_vcpu_read_guest_page(struct kvm_vcpu *vcpu, gfn_t gfn, void *data, int offset, > int len); > int kvm_vcpu_read_guest_atomic(struct kvm_vcpu *vcpu, gpa_t gpa, void *data, > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c > index 222f0e894a0c..11bb5c24ed0d 100644 > --- a/virt/kvm/kvm_main.c > +++ b/virt/kvm/kvm_main.c > @@ -3361,6 +3361,27 @@ int kvm_vcpu_write_guest(struct kvm_vcpu *vcpu, gpa_t gpa, const void *data, > } > EXPORT_SYMBOL_GPL(kvm_vcpu_write_guest); > > +int kvm_vcpu_validate_gpa_range(struct kvm_vcpu *vcpu, gpa_t gpa, unsigned long len, > + bool write_access) Please no. "validate" is way too ambiguous, the result is inherently unstable, I don't want to add vCPU-scoped APIs (too much x86-centric baggage), taking an arbitrary range without a user adds complexity for no benefit, and this is basically the same as kvm_is_gpa_in_memslot(), but with write requirements. I would much prefer to add a simpler helper to complement kvm_is_gpa_in_memslot(), that makes it as obvious as possible exactly what is being "validated", e.g. diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 3bde4fb5c6aa..29be907d28b0 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1915,6 +1915,14 @@ static inline bool kvm_is_gpa_in_memslot(struct kvm *kvm, gpa_t gpa) return !kvm_is_error_hva(hva); } +static inline bool kvm_is_gpa_in_writable_memslot(struct kvm *kvm, gpa_t gpa) +{ + bool writable; + unsigned long hva = gfn_to_hva_prot(kvm, gpa_to_gfn(gpa), &writable); + + return !kvm_is_error_hva(hva) && writable; +} + static inline void kvm_gpc_mark_dirty_in_slot(struct gfn_to_pfn_cache *gpc) { lockdep_assert_held(&gpc->lock);