summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kvm.c15
-rw-r--r--kvm_host.h1
-rw-r--r--kvm_vmx.c8
3 files changed, 18 insertions, 6 deletions
diff --git a/kvm.c b/kvm.c
index 1ffccc6..a5ed95d 100644
--- a/kvm.c
+++ b/kvm.c
@@ -648,6 +648,7 @@ kvm_destroy_vm(struct kvm *kvmp)
continue;
avl_destroy(&kvmp->kvm_avlmp);
mutex_destroy(&kvmp->kvm_avllock);
+ mutex_destroy(&kvmp->memslots_lock);
mutex_destroy(&kvmp->slots_lock);
mutex_destroy(&kvmp->irq_lock);
mutex_destroy(&kvmp->lock);
@@ -718,6 +719,7 @@ kvm_create_vm(void)
#endif
mutex_init(&kvmp->lock, NULL, MUTEX_DRIVER, NULL);
+ mutex_init(&kvmp->memslots_lock, NULL, MUTEX_DRIVER, NULL);
mutex_init(&kvmp->irq_lock, NULL, MUTEX_DRIVER, NULL);
mutex_init(&kvmp->slots_lock, NULL, MUTEX_DRIVER, NULL);
mutex_init(&kvmp->kvm_avllock, NULL, MUTEX_DRIVER, NULL);
@@ -1073,15 +1075,20 @@ gfn_to_memslot_unaliased(struct kvm *kvm, gfn_t gfn)
struct kvm_memslots *slots = rcu_dereference(kvm->memslots);
#else
struct kvm_memslots *slots = kvm->memslots;
+
+ mutex_enter(&kvm->memslots_lock);
#endif
for (i = 0; i < slots->nmemslots; ++i) {
struct kvm_memory_slot *memslot = &slots->memslots[i];
if (gfn >= memslot->base_gfn &&
- gfn < memslot->base_gfn + memslot->npages)
+ gfn < memslot->base_gfn + memslot->npages) {
+ mutex_exit(&kvm->memslots_lock);
return (memslot);
+ }
}
+ mutex_exit(&kvm->memslots_lock);
return (NULL);
}
@@ -1104,6 +1111,8 @@ kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn)
gfn = unalias_gfn_instantiation(kvm, gfn);
+ mutex_enter(&kvm->memslots_lock);
+
for (i = 0; i < KVM_MEMORY_SLOTS; ++i) {
struct kvm_memory_slot *memslot = &slots->memslots[i];
@@ -1112,10 +1121,12 @@ kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn)
if (gfn >= memslot->base_gfn &&
gfn < memslot->base_gfn + memslot->npages) {
+ mutex_exit(&kvm->memslots_lock);
return (1);
}
}
+ mutex_exit(&kvm->memslots_lock);
return (0);
}
@@ -1160,6 +1171,7 @@ memslot_id(struct kvm *kvm, gfn_t gfn)
struct kvm_memory_slot *memslot = NULL;
gfn = unalias_gfn(kvm, gfn);
+ mutex_enter(&kvm->memslots_lock);
for (i = 0; i < slots->nmemslots; ++i) {
memslot = &slots->memslots[i];
@@ -1168,6 +1180,7 @@ memslot_id(struct kvm *kvm, gfn_t gfn)
break;
}
+ mutex_exit(&kvm->memslots_lock);
return (memslot - slots->memslots);
}
diff --git a/kvm_host.h b/kvm_host.h
index d414850..62d809d 100644
--- a/kvm_host.h
+++ b/kvm_host.h
@@ -188,6 +188,7 @@ typedef struct kvm {
kmutex_t slots_lock;
struct as *mm; /* userspace tied to this vm */
struct kvm_memslots *memslots;
+ kmutex_t memslots_lock; /* linux uses rcu for this */
/* the following was a read-copy update mechanism */
/* we'll use a reader-writer lock, for now */
krwlock_t kvm_rwlock;
diff --git a/kvm_vmx.c b/kvm_vmx.c
index 5611623..b1c3d90 100644
--- a/kvm_vmx.c
+++ b/kvm_vmx.c
@@ -1653,14 +1653,12 @@ rmode_tss_base(struct kvm *kvm)
struct kvm_memslots *slots;
gfn_t base_gfn;
-#ifdef XXX
- slots = rcu_dereference(kvm->memslots);
-#else
- XXX_KVM_PROBE;
+ mutex_enter(&kvm->memslots_lock);
slots = kvm->memslots;
-#endif
+
base_gfn = kvm->memslots->memslots[0].base_gfn +
kvm->memslots->memslots[0].npages - 3;
+ mutex_exit(&kvm->memslots_lock);
return (base_gfn << PAGESHIFT);
}