aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/kvm_host.h34
-rw-r--r--virt/kvm/kvm_main.c8
2 files changed, 29 insertions, 13 deletions
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 1a371447fd45..193bca68372d 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -354,6 +354,7 @@ struct kvm_memslots {
354 /* The mapping table from slot id to the index in memslots[]. */ 354 /* The mapping table from slot id to the index in memslots[]. */
355 short id_to_index[KVM_MEM_SLOTS_NUM]; 355 short id_to_index[KVM_MEM_SLOTS_NUM];
356 atomic_t lru_slot; 356 atomic_t lru_slot;
357 int used_slots;
357}; 358};
358 359
359struct kvm { 360struct kvm {
@@ -791,19 +792,28 @@ static inline void kvm_guest_exit(void)
791static inline struct kvm_memory_slot * 792static inline struct kvm_memory_slot *
792search_memslots(struct kvm_memslots *slots, gfn_t gfn) 793search_memslots(struct kvm_memslots *slots, gfn_t gfn)
793{ 794{
795 int start = 0, end = slots->used_slots;
794 int slot = atomic_read(&slots->lru_slot); 796 int slot = atomic_read(&slots->lru_slot);
795 struct kvm_memory_slot *memslot = &slots->memslots[slot]; 797 struct kvm_memory_slot *memslots = slots->memslots;
796 798
797 if (gfn >= memslot->base_gfn && 799 if (gfn >= memslots[slot].base_gfn &&
798 gfn < memslot->base_gfn + memslot->npages) 800 gfn < memslots[slot].base_gfn + memslots[slot].npages)
799 return memslot; 801 return &memslots[slot];
800 802
801 kvm_for_each_memslot(memslot, slots) 803 while (start < end) {
802 if (gfn >= memslot->base_gfn && 804 slot = start + (end - start) / 2;
803 gfn < memslot->base_gfn + memslot->npages) { 805
804 atomic_set(&slots->lru_slot, memslot - slots->memslots); 806 if (gfn >= memslots[slot].base_gfn)
805 return memslot; 807 end = slot;
806 } 808 else
809 start = slot + 1;
810 }
811
812 if (gfn >= memslots[start].base_gfn &&
813 gfn < memslots[start].base_gfn + memslots[start].npages) {
814 atomic_set(&slots->lru_slot, start);
815 return &memslots[start];
816 }
807 817
808 return NULL; 818 return NULL;
809} 819}
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 162817f853ec..759af6596a07 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -679,8 +679,14 @@ static void update_memslots(struct kvm_memslots *slots,
679 struct kvm_memory_slot *mslots = slots->memslots; 679 struct kvm_memory_slot *mslots = slots->memslots;
680 680
681 WARN_ON(mslots[i].id != id); 681 WARN_ON(mslots[i].id != id);
682 if (!new->npages) 682 if (!new->npages) {
683 new->base_gfn = 0; 683 new->base_gfn = 0;
684 if (mslots[i].npages)
685 slots->used_slots--;
686 } else {
687 if (!mslots[i].npages)
688 slots->used_slots++;
689 }
684 690
685 while (i < KVM_MEM_SLOTS_NUM - 1 && 691 while (i < KVM_MEM_SLOTS_NUM - 1 &&
686 new->base_gfn <= mslots[i + 1].base_gfn) { 692 new->base_gfn <= mslots[i + 1].base_gfn) {