KVM: Tweak kvm_hva_range and hva_handler_t to allow reusing for gfn ranges

Rework and rename "struct kvm_hva_range" into "kvm_mmu_notifier_range" so
that the structure can be used to handle notifications that operate on gfn
context, i.e. that aren't tied to a host virtual address.  Rename the
handler typedef too (arguably it should always have been gfn_handler_t).

Practically speaking, this is a nop for 64-bit kernels as the only
meaningful change is to store start+end as u64s instead of unsigned longs.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Reviewed-by: Fuad Tabba <tabba@google.com>
Tested-by: Fuad Tabba <tabba@google.com>
Message-Id: <20231027182217.3615211-2-seanjc@google.com>
Reviewed-by: Kai Huang <kai.huang@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Sean Christopherson 2023-10-27 11:21:43 -07:00 committed by Paolo Bonzini
parent ef5b6a542b
commit e97b39c5c4

View file

@ -541,18 +541,22 @@ static inline struct kvm *mmu_notifier_to_kvm(struct mmu_notifier *mn)
return container_of(mn, struct kvm, mmu_notifier); return container_of(mn, struct kvm, mmu_notifier);
} }
typedef bool (*hva_handler_t)(struct kvm *kvm, struct kvm_gfn_range *range); typedef bool (*gfn_handler_t)(struct kvm *kvm, struct kvm_gfn_range *range);
typedef void (*on_lock_fn_t)(struct kvm *kvm, unsigned long start, typedef void (*on_lock_fn_t)(struct kvm *kvm, unsigned long start,
unsigned long end); unsigned long end);
typedef void (*on_unlock_fn_t)(struct kvm *kvm); typedef void (*on_unlock_fn_t)(struct kvm *kvm);
struct kvm_hva_range { struct kvm_mmu_notifier_range {
unsigned long start; /*
unsigned long end; * 64-bit addresses, as KVM notifiers can operate on host virtual
* addresses (unsigned long) and guest physical addresses (64-bit).
*/
u64 start;
u64 end;
union kvm_mmu_notifier_arg arg; union kvm_mmu_notifier_arg arg;
hva_handler_t handler; gfn_handler_t handler;
on_lock_fn_t on_lock; on_lock_fn_t on_lock;
on_unlock_fn_t on_unlock; on_unlock_fn_t on_unlock;
bool flush_on_ret; bool flush_on_ret;
@ -581,7 +585,7 @@ static const union kvm_mmu_notifier_arg KVM_MMU_NOTIFIER_NO_ARG;
node = interval_tree_iter_next(node, start, last)) \ node = interval_tree_iter_next(node, start, last)) \
static __always_inline int __kvm_handle_hva_range(struct kvm *kvm, static __always_inline int __kvm_handle_hva_range(struct kvm *kvm,
const struct kvm_hva_range *range) const struct kvm_mmu_notifier_range *range)
{ {
bool ret = false, locked = false; bool ret = false, locked = false;
struct kvm_gfn_range gfn_range; struct kvm_gfn_range gfn_range;
@ -608,9 +612,9 @@ static __always_inline int __kvm_handle_hva_range(struct kvm *kvm,
unsigned long hva_start, hva_end; unsigned long hva_start, hva_end;
slot = container_of(node, struct kvm_memory_slot, hva_node[slots->node_idx]); slot = container_of(node, struct kvm_memory_slot, hva_node[slots->node_idx]);
hva_start = max(range->start, slot->userspace_addr); hva_start = max_t(unsigned long, range->start, slot->userspace_addr);
hva_end = min(range->end, slot->userspace_addr + hva_end = min_t(unsigned long, range->end,
(slot->npages << PAGE_SHIFT)); slot->userspace_addr + (slot->npages << PAGE_SHIFT));
/* /*
* To optimize for the likely case where the address * To optimize for the likely case where the address
@ -660,10 +664,10 @@ static __always_inline int kvm_handle_hva_range(struct mmu_notifier *mn,
unsigned long start, unsigned long start,
unsigned long end, unsigned long end,
union kvm_mmu_notifier_arg arg, union kvm_mmu_notifier_arg arg,
hva_handler_t handler) gfn_handler_t handler)
{ {
struct kvm *kvm = mmu_notifier_to_kvm(mn); struct kvm *kvm = mmu_notifier_to_kvm(mn);
const struct kvm_hva_range range = { const struct kvm_mmu_notifier_range range = {
.start = start, .start = start,
.end = end, .end = end,
.arg = arg, .arg = arg,
@ -680,10 +684,10 @@ static __always_inline int kvm_handle_hva_range(struct mmu_notifier *mn,
static __always_inline int kvm_handle_hva_range_no_flush(struct mmu_notifier *mn, static __always_inline int kvm_handle_hva_range_no_flush(struct mmu_notifier *mn,
unsigned long start, unsigned long start,
unsigned long end, unsigned long end,
hva_handler_t handler) gfn_handler_t handler)
{ {
struct kvm *kvm = mmu_notifier_to_kvm(mn); struct kvm *kvm = mmu_notifier_to_kvm(mn);
const struct kvm_hva_range range = { const struct kvm_mmu_notifier_range range = {
.start = start, .start = start,
.end = end, .end = end,
.handler = handler, .handler = handler,
@ -771,7 +775,7 @@ static int kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
const struct mmu_notifier_range *range) const struct mmu_notifier_range *range)
{ {
struct kvm *kvm = mmu_notifier_to_kvm(mn); struct kvm *kvm = mmu_notifier_to_kvm(mn);
const struct kvm_hva_range hva_range = { const struct kvm_mmu_notifier_range hva_range = {
.start = range->start, .start = range->start,
.end = range->end, .end = range->end,
.handler = kvm_unmap_gfn_range, .handler = kvm_unmap_gfn_range,
@ -835,7 +839,7 @@ static void kvm_mmu_notifier_invalidate_range_end(struct mmu_notifier *mn,
const struct mmu_notifier_range *range) const struct mmu_notifier_range *range)
{ {
struct kvm *kvm = mmu_notifier_to_kvm(mn); struct kvm *kvm = mmu_notifier_to_kvm(mn);
const struct kvm_hva_range hva_range = { const struct kvm_mmu_notifier_range hva_range = {
.start = range->start, .start = range->start,
.end = range->end, .end = range->end,
.handler = (void *)kvm_null_fn, .handler = (void *)kvm_null_fn,