diff options
author | David Stevens <stevensd@chromium.org> | 2021-10-15 19:30:21 +0300 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2021-10-22 12:19:25 +0300 |
commit | 1e76a3ce0d3cdfc6b506e21047a26471bc1cc92e (patch) | |
tree | 44855eb8b79c5f2a487a1d403169a3578e48ef53 /arch/x86/kvm/mmu/page_track.c | |
parent | 3f9808cac06c8dd4f800101e04f84fe3180198b0 (diff) | |
download | linux-1e76a3ce0d3cdfc6b506e21047a26471bc1cc92e.tar.xz |
KVM: cleanup allocation of rmaps and page tracking data
Unify the flags for rmaps and page tracking data, using a
single flag in struct kvm_arch and a single loop to go
over all the address spaces and memslots. This avoids
code duplication between alloc_all_memslots_rmaps and
kvm_page_track_enable_mmu_write_tracking.
Signed-off-by: David Stevens <stevensd@chromium.org>
[This patch is the delta between David's v2 and v3, with conflicts
fixed and my own commit message. - Paolo]
Co-developed-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/kvm/mmu/page_track.c')
-rw-r--r-- | arch/x86/kvm/mmu/page_track.c | 57 |
1 files changed, 15 insertions, 42 deletions
diff --git a/arch/x86/kvm/mmu/page_track.c b/arch/x86/kvm/mmu/page_track.c index bb5d60bd4dbf..cc4eb5b7fb76 100644 --- a/arch/x86/kvm/mmu/page_track.c +++ b/arch/x86/kvm/mmu/page_track.c @@ -19,14 +19,10 @@ #include "mmu.h" #include "mmu_internal.h" -static bool write_tracking_enabled(struct kvm *kvm) +bool kvm_page_track_write_tracking_enabled(struct kvm *kvm) { - /* - * Read memslots_mmu_write_tracking before gfn_track pointers. Pairs - * with smp_store_release in kvm_page_track_enable_mmu_write_tracking. - */ return IS_ENABLED(CONFIG_KVM_EXTERNAL_WRITE_TRACKING) || - smp_load_acquire(&kvm->arch.memslots_mmu_write_tracking); + !tdp_enabled || kvm_shadow_root_allocated(kvm); } void kvm_page_track_free_memslot(struct kvm_memory_slot *slot) @@ -46,7 +42,8 @@ int kvm_page_track_create_memslot(struct kvm *kvm, int i; for (i = 0; i < KVM_PAGE_TRACK_MAX; i++) { - if (i == KVM_PAGE_TRACK_WRITE && !write_tracking_enabled(kvm)) + if (i == KVM_PAGE_TRACK_WRITE && + !kvm_page_track_write_tracking_enabled(kvm)) continue; slot->arch.gfn_track[i] = @@ -71,43 +68,18 @@ static inline bool page_track_mode_is_valid(enum kvm_page_track_mode mode) return true; } -int kvm_page_track_enable_mmu_write_tracking(struct kvm *kvm) +int kvm_page_track_write_tracking_alloc(struct kvm_memory_slot *slot) { - struct kvm_memslots *slots; - struct kvm_memory_slot *slot; - unsigned short **gfn_track; - int i; + unsigned short *gfn_track; - if (write_tracking_enabled(kvm)) + if (slot->arch.gfn_track[KVM_PAGE_TRACK_WRITE]) return 0; - mutex_lock(&kvm->slots_arch_lock); - - if (write_tracking_enabled(kvm)) { - mutex_unlock(&kvm->slots_arch_lock); - return 0; - } - - for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) { - slots = __kvm_memslots(kvm, i); - kvm_for_each_memslot(slot, slots) { - gfn_track = slot->arch.gfn_track + KVM_PAGE_TRACK_WRITE; - *gfn_track = kvcalloc(slot->npages, sizeof(*gfn_track), - GFP_KERNEL_ACCOUNT); - if (*gfn_track == NULL) { - mutex_unlock(&kvm->slots_arch_lock); - return -ENOMEM; - } - } - } - - /* - * Ensure that memslots_mmu_write_tracking becomes true strictly - * after all the pointers are set. - */ - smp_store_release(&kvm->arch.memslots_mmu_write_tracking, true); - mutex_unlock(&kvm->slots_arch_lock); + gfn_track = kvcalloc(slot->npages, sizeof(*gfn_track), GFP_KERNEL_ACCOUNT); + if (gfn_track == NULL) + return -ENOMEM; + slot->arch.gfn_track[KVM_PAGE_TRACK_WRITE] = gfn_track; return 0; } @@ -147,7 +119,7 @@ void kvm_slot_page_track_add_page(struct kvm *kvm, return; if (WARN_ON(mode == KVM_PAGE_TRACK_WRITE && - !write_tracking_enabled(kvm))) + !kvm_page_track_write_tracking_enabled(kvm))) return; update_gfn_track(slot, gfn, mode, 1); @@ -185,7 +157,7 @@ void kvm_slot_page_track_remove_page(struct kvm *kvm, return; if (WARN_ON(mode == KVM_PAGE_TRACK_WRITE && - !write_tracking_enabled(kvm))) + !kvm_page_track_write_tracking_enabled(kvm))) return; update_gfn_track(slot, gfn, mode, -1); @@ -213,7 +185,8 @@ bool kvm_slot_page_track_is_active(struct kvm_vcpu *vcpu, if (!slot) return false; - if (mode == KVM_PAGE_TRACK_WRITE && !write_tracking_enabled(vcpu->kvm)) + if (mode == KVM_PAGE_TRACK_WRITE && + !kvm_page_track_write_tracking_enabled(vcpu->kvm)) return false; index = gfn_to_index(gfn, slot->base_gfn, PG_LEVEL_4K); |