Page MenuHomeFreeBSD

D37972.id114850.diff
No OneTemporary

D37972.id114850.diff

diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h
--- a/sys/amd64/include/vmm.h
+++ b/sys/amd64/include/vmm.h
@@ -322,6 +322,7 @@
typedef void (*vm_rendezvous_func_t)(struct vcpu *vcpu, void *arg);
int vm_smp_rendezvous(struct vcpu *vcpu, cpuset_t dest,
vm_rendezvous_func_t func, void *arg);
+void vm_handle_rendezvous_from_lock_all(struct vm *vm, int maxi);
cpuset_t vm_active_cpus(struct vm *vm);
cpuset_t vm_debug_cpus(struct vm *vm);
diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -181,6 +181,7 @@
cpuset_t rendezvous_done_cpus; /* (x) [r] rendezvous finished */
void *rendezvous_arg; /* (x) [r] rendezvous func/arg */
vm_rendezvous_func_t rendezvous_func;
+ int rendezvous_vcpu_req;
struct mtx rendezvous_mtx; /* (o) rendezvous lock */
struct mem_map mem_maps[VM_MAX_MEMMAPS]; /* (i) [m+v] guest address space */
struct mem_seg mem_segs[VM_MAX_MEMSEGS]; /* (o) [m+v] guest memory regions */
@@ -1411,7 +1412,7 @@
}
static int
-vm_handle_rendezvous(struct vcpu *vcpu)
+vm_handle_rendezvous_locked(struct vcpu *vcpu, bool wait)
{
struct vm *vm = vcpu->vm;
struct thread *td;
@@ -1420,7 +1421,6 @@
error = 0;
vcpuid = vcpu->vcpuid;
td = curthread;
- mtx_lock(&vm->rendezvous_mtx);
while (vm->rendezvous_func != NULL) {
/* 'rendezvous_req_cpus' must be a subset of 'active_cpus' */
CPU_AND(&vm->rendezvous_req_cpus, &vm->rendezvous_req_cpus, &vm->active_cpus);
@@ -1438,21 +1438,56 @@
wakeup(&vm->rendezvous_func);
break;
}
- VMM_CTR0(vcpu, "Wait for rendezvous completion");
- mtx_sleep(&vm->rendezvous_func, &vm->rendezvous_mtx, 0,
- "vmrndv", hz);
- if (td_ast_pending(td, TDA_SUSPEND)) {
- mtx_unlock(&vm->rendezvous_mtx);
- error = thread_check_susp(td, true);
- if (error != 0)
- return (error);
- mtx_lock(&vm->rendezvous_mtx);
+ if (wait) {
+ VMM_CTR0(vcpu, "Wait for rendezvous completion");
+ mtx_sleep(&vm->rendezvous_func, &vm->rendezvous_mtx, 0,
+ "vmrndv", hz);
+ if (td_ast_pending(td, TDA_SUSPEND)) {
+ mtx_unlock(&vm->rendezvous_mtx);
+ error = thread_check_susp(td, true);
+ if (error != 0)
+ return (error);
+ mtx_lock(&vm->rendezvous_mtx);
+ }
}
}
- mtx_unlock(&vm->rendezvous_mtx);
return (0);
}
+static int
+vm_handle_rendezvous(struct vcpu *vcpu)
+{
+ struct vm *vm;
+ int res;
+
+ vm = vcpu->vm;
+ mtx_lock(&vm->rendezvous_mtx);
+ res = vm_handle_rendezvous_locked(vcpu, true);
+ mtx_unlock(&vm->rendezvous_mtx);
+ return (res);
+}
+
+/*
+ * Handle rendezvous request for all vcpus frozen by the caller.
+ */
+void
+vm_handle_rendezvous_from_lock_all(struct vm *vm, int maxi)
+{
+ struct vcpu *vcpu;
+ int i;
+
+ if (vm->rendezvous_func == NULL)
+ return;
+
+ mtx_lock(&vm->rendezvous_mtx);
+ for (i = 0; vm->rendezvous_func != NULL && i < maxi; i++) {
+ vcpu = vm_vcpu(vm, i);
+ if (vcpu != NULL && vcpu->vcpuid != vm->rendezvous_vcpu_req)
+ vm_handle_rendezvous_locked(vcpu, false);
+ }
+ mtx_unlock(&vm->rendezvous_mtx);
+}
+
/*
* Emulate a guest 'hlt' by sleeping until the vcpu is ready to run.
*/
@@ -2646,6 +2681,7 @@
CPU_ZERO(&vm->rendezvous_done_cpus);
vm->rendezvous_arg = arg;
vm->rendezvous_func = func;
+ vm->rendezvous_vcpu_req = vcpu->vcpuid;
mtx_unlock(&vm->rendezvous_mtx);
/*
diff --git a/sys/amd64/vmm/vmm_dev.c b/sys/amd64/vmm/vmm_dev.c
--- a/sys/amd64/vmm/vmm_dev.c
+++ b/sys/amd64/vmm/vmm_dev.c
@@ -147,14 +147,17 @@
static int
vcpu_lock_all(struct vmmdev_softc *sc)
{
+ struct vm *vm;
struct vcpu *vcpu;
int error;
uint16_t i, j, maxcpus;
- vm_slock_vcpus(sc->vm);
- maxcpus = vm_get_maxcpus(sc->vm);
+ vm = sc->vm;
+ vm_slock_vcpus(vm);
+ maxcpus = vm_get_maxcpus(vm);
for (i = 0; i < maxcpus; i++) {
- vcpu = vm_vcpu(sc->vm, i);
+ vm_handle_rendezvous_from_lock_all(vm, i);
+ vcpu = vm_vcpu(vm, i);
if (vcpu == NULL)
continue;
error = vcpu_lock_one(vcpu);
@@ -164,12 +167,12 @@
if (error) {
for (j = 0; j < i; j++) {
- vcpu = vm_vcpu(sc->vm, j);
+ vcpu = vm_vcpu(vm, j);
if (vcpu == NULL)
continue;
vcpu_unlock_one(sc, j, vcpu);
}
- vm_unlock_vcpus(sc->vm);
+ vm_unlock_vcpus(vm);
}
return (error);

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 19, 8:27 PM (3 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25673167
Default Alt Text
D37972.id114850.diff (4 KB)

Event Timeline