Skip to content

Commit c70934e

Browse files
sean-jcbonzini
authored andcommitted
KVM: x86: Reject memslot MOVE operations if KVMGT is attached
Disallow moving memslots if the VM has external page-track users, i.e. if KVMGT is being used to expose a virtual GPU to the guest, as KVMGT doesn't correctly handle moving memory regions. Note, this is potential ABI breakage! E.g. userspace could move regions that aren't shadowed by KVMGT without harming the guest. However, the only known user of KVMGT is QEMU, and QEMU doesn't move generic memory regions. KVM's own support for moving memory regions was also broken for multiple years (albeit for an edge case, but arguably moving RAM is itself an edge case), e.g. see commit edd4fa3 ("KVM: x86: Allocate new rmap and large page tracking when moving memslot"). Reviewed-by: Yan Zhao <[email protected]> Tested-by: Yongwei Ma <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Sean Christopherson <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent b271e17 commit c70934e

File tree

3 files changed

+15
-0
lines changed

3 files changed

+15
-0
lines changed

arch/x86/include/asm/kvm_page_track.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,7 @@ kvm_page_track_unregister_notifier(struct kvm *kvm,
7575
void kvm_page_track_write(struct kvm_vcpu *vcpu, gpa_t gpa, const u8 *new,
7676
int bytes);
7777
void kvm_page_track_flush_slot(struct kvm *kvm, struct kvm_memory_slot *slot);
78+
79+
bool kvm_page_track_has_external_user(struct kvm *kvm);
80+
7881
#endif

arch/x86/kvm/mmu/page_track.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,3 +303,8 @@ void kvm_page_track_flush_slot(struct kvm *kvm, struct kvm_memory_slot *slot)
303303
n->track_flush_slot(kvm, slot, n);
304304
srcu_read_unlock(&head->track_srcu, idx);
305305
}
306+
307+
bool kvm_page_track_has_external_user(struct kvm *kvm)
308+
{
309+
return !hlist_empty(&kvm->arch.track_notifier_head.track_notifier_list);
310+
}

arch/x86/kvm/x86.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12632,6 +12632,13 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
1263212632
struct kvm_memory_slot *new,
1263312633
enum kvm_mr_change change)
1263412634
{
12635+
/*
12636+
* KVM doesn't support moving memslots when there are external page
12637+
* trackers attached to the VM, i.e. if KVMGT is in use.
12638+
*/
12639+
if (change == KVM_MR_MOVE && kvm_page_track_has_external_user(kvm))
12640+
return -EINVAL;
12641+
1263512642
if (change == KVM_MR_CREATE || change == KVM_MR_MOVE) {
1263612643
if ((new->base_gfn + new->npages - 1) > kvm_mmu_max_gfn())
1263712644
return -EINVAL;

0 commit comments

Comments
 (0)