summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Bruning <max@joyent.com>2011-07-12 07:35:09 -0700
committerMax Bruning <max@joyent.com>2011-07-12 07:35:09 -0700
commite44d671a7df88a9bc1e51b809b5a2a32a85b63bb (patch)
tree092979b6d0b7cc05e57aa48d19c116f032ad3dea
parent81ce4d6b18b89da85c986b24346f2191d5ad2b0e (diff)
downloadillumos-kvm-e44d671a7df88a9bc1e51b809b5a2a32a85b63bb.tar.gz
HVM-477 panic in gfn_to_hva
-rw-r--r--kvm.c14
-rw-r--r--kvm_mmu.c3
-rw-r--r--kvm_vmx.c11
3 files changed, 18 insertions, 10 deletions
diff --git a/kvm.c b/kvm.c
index df30e5f..882cf6a 100644
--- a/kvm.c
+++ b/kvm.c
@@ -953,14 +953,11 @@ skip_lpage:
slots->nmemslots = mem->slot + 1;
slots->memslots[mem->slot].flags |= KVM_MEMSLOT_INVALID;
+ mutex_enter(&kvmp->memslots_lock);
old_memslots = kvmp->memslots;
-#ifdef XXX
- rcu_assign_pointer(kvmp->memslots, slots);
- synchronize_srcu_expedited(&kvm->srcu);
-#else
- XXX_KVM_SYNC_PROBE;
kvmp->memslots = slots;
-#endif
+ mutex_exit(&kvmp->memslots_lock);
+
/*
* From this point no new shadow pages pointing to a deleted
* memslot will be created.
@@ -1002,7 +999,10 @@ skip_lpage:
kvm_arch_commit_memory_region(kvmp, mem, old, user_alloc);
+ mutex_enter(&kvmp->memslots_lock);
kvm_free_physmem_slot(&old, &new);
+ mutex_exit(&kvmp->memslots_lock);
+
kmem_free(old_memslots, sizeof (struct kvm_memslots));
if (flush_shadow)
@@ -2186,8 +2186,8 @@ kvm_close(dev_t dev, int flag, int otyp, cred_t *cred)
kvmp->kvm_clones--;
mutex_exit(&kvm_lock);
} else {
- mutex_exit(&kvm_lock);
kvm_destroy_vm(kvmp);
+ mutex_exit(&kvm_lock);
}
}
diff --git a/kvm_mmu.c b/kvm_mmu.c
index b809435..6e97936 100644
--- a/kvm_mmu.c
+++ b/kvm_mmu.c
@@ -2939,10 +2939,11 @@ kvm_mmu_calculate_mmu_pages(struct kvm *kvm)
unsigned int nr_pages = 0;
struct kvm_memslots *slots;
+ mutex_enter(&kvm->memslots_lock);
slots = kvm->memslots;
for (i = 0; i < slots->nmemslots; i++)
nr_pages += slots->memslots[i].npages;
-
+ mutex_exit(&kvm->memslots_lock);
nr_mmu_pages = nr_pages * KVM_PERMILLE_MMU_PAGES / 1000;
nr_mmu_pages = MAX(nr_mmu_pages, (unsigned int)KVM_MIN_ALLOC_MMU_PAGES);
diff --git a/kvm_vmx.c b/kvm_vmx.c
index b1c3d90..10a37c5 100644
--- a/kvm_vmx.c
+++ b/kvm_vmx.c
@@ -22,6 +22,7 @@
#include <sys/mach_mmu.h>
#include <asm/cpu.h>
#include <sys/x86_archext.h>
+#include <sys/xc_levels.h>
#include "kvm_bitops.h"
#include "msr.h"
@@ -1322,9 +1323,15 @@ vmclear_local_vcpus(void)
* local_vcpus_link)
* __vcpu_clear(vmx);
*/
- for (vmx = list_head(vcpus_on_cpu[cpu]); vmx;
- vmx = list_next(vcpus_on_cpu[cpu], vmx))
+ vmx = list_head(vcpus_on_cpu[cpu]);
+ if (vmx)
+ n = list_next(vcpus_on_cpu[cpu], vmx);
+ while (vmx) {
__vcpu_clear(vmx);
+ vmx = n;
+ if (vmx)
+ n = list_next(vcpus_on_cpu[cpu], vmx);
+ }
}
/*