Page MenuHomeFreeBSD

D37173.diff
No OneTemporary

D37173.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
@@ -319,9 +319,12 @@
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);
+
cpuset_t vm_active_cpus(struct vm *vm);
cpuset_t vm_debug_cpus(struct vm *vm);
cpuset_t vm_suspended_cpus(struct vm *vm);
+cpuset_t vm_start_cpus(struct vm *vm, const cpuset_t *tostart);
+void vm_await_start(struct vm *vm, const cpuset_t *waiting);
#endif /* _SYS__CPUSET_H_ */
static __inline int
diff --git a/sys/amd64/vmm/io/vlapic.c b/sys/amd64/vmm/io/vlapic.c
--- a/sys/amd64/vmm/io/vlapic.c
+++ b/sys/amd64/vmm/io/vlapic.c
@@ -1039,7 +1039,6 @@
cpuset_t dmask, ipimask;
uint64_t icrval;
uint32_t dest, vec, mode, shorthand;
- struct vlapic *vlapic2;
struct vcpu *vcpu;
struct vm_exit *vmexit;
struct LAPIC *lapic;
@@ -1128,14 +1127,9 @@
i == vlapic->vcpuid)
break;
- /*
- * Userland which doesn't support the IPI exit
- * requires that the boot state is set to SIPI
- * here.
- */
- vcpu = vm_vcpu(vlapic->vm, i);
- vlapic2 = vm_lapic(vcpu);
- vlapic2->boot_state = BS_SIPI;
+ /* vCPU i is waiting for SIPI. */
+ CPU_SETOF(i, &dmask);
+ vm_await_start(vlapic->vm, &dmask);
break;
}
@@ -1158,11 +1152,10 @@
/*
* Ignore SIPIs in any state other than wait-for-SIPI
*/
- vcpu = vm_vcpu(vlapic->vm, i);
- vlapic2 = vm_lapic(vcpu);
- if (vlapic2->boot_state != BS_SIPI)
+ CPU_SETOF(i, &dmask);
+ dmask = vm_start_cpus(vlapic->vm, &dmask);
+ if (CPU_EMPTY(&dmask))
break;
- vlapic2->boot_state = BS_RUNNING;
vmexit = vm_exitinfo(vlapic->vcpu);
vmexit->exitcode = VM_EXITCODE_SPINUP_AP;
@@ -1173,19 +1166,10 @@
break;
}
- CPU_FOREACH_ISSET(i, &dmask) {
- vcpu = vm_vcpu(vlapic->vm, i);
- vlapic2 = vm_lapic(vcpu);
-
- /*
- * Ignore SIPIs in any state other than wait-for-SIPI
- */
- if (vlapic2->boot_state != BS_SIPI)
- continue;
- vlapic2->boot_state = BS_RUNNING;
- CPU_SET(i, &ipimask);
- }
-
+ /*
+ * Ignore SIPIs in any state other than wait-for-SIPI
+ */
+ ipimask = vm_start_cpus(vlapic->vm, &dmask);
break;
default:
return (1);
@@ -1210,9 +1194,6 @@
struct vlapic *vlapic = vm_lapic(vcpu);
vlapic_reset(vlapic);
-
- /* vlapic_reset modifies the boot state. */
- vlapic->boot_state = BS_SIPI;
}
int
@@ -1223,6 +1204,7 @@
case APIC_DELMODE_INIT:
vm_smp_rendezvous(vcpu, vme->u.ipi.dmask, vlapic_handle_init,
NULL);
+ vm_await_start(vcpu_vm(vcpu), &vme->u.ipi.dmask);
break;
case APIC_DELMODE_STARTUP:
break;
@@ -1598,11 +1580,6 @@
lapic->dcr_timer = 0;
vlapic_dcr_write_handler(vlapic);
- if (vlapic->vcpuid == 0)
- vlapic->boot_state = BS_RUNNING; /* BSP */
- else
- vlapic->boot_state = BS_INIT; /* AP */
-
vlapic->svr_last = lapic->svr;
}
@@ -1900,7 +1877,6 @@
sizeof(vlapic->isrvec_stk),
meta, ret, done);
SNAPSHOT_VAR_OR_LEAVE(vlapic->isrvec_stk_top, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vlapic->boot_state, meta, ret, done);
SNAPSHOT_BUF_OR_LEAVE(vlapic->lvt_last,
sizeof(vlapic->lvt_last),
diff --git a/sys/amd64/vmm/io/vlapic_priv.h b/sys/amd64/vmm/io/vlapic_priv.h
--- a/sys/amd64/vmm/io/vlapic_priv.h
+++ b/sys/amd64/vmm/io/vlapic_priv.h
@@ -125,12 +125,6 @@
VLAPIC_CTR1((vlapic), msg " isr7 0x%08x", isrptr[7 << 2]); \
} while (0)
-enum boot_state {
- BS_INIT,
- BS_SIPI,
- BS_RUNNING
-};
-
/*
* 16 priority levels with at most one vector injected per level.
*/
@@ -175,7 +169,6 @@
int isrvec_stk_top;
uint64_t msr_apicbase;
- enum boot_state boot_state;
/*
* Copies of some registers in the virtual APIC page. We do this for
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
@@ -173,6 +173,7 @@
struct vrtc *vrtc; /* (o) virtual RTC */
volatile cpuset_t active_cpus; /* (i) active vcpus */
volatile cpuset_t debug_cpus; /* (i) vcpus stopped for debug */
+ cpuset_t startup_cpus; /* (i) [r] waiting for startup */
int suspend; /* (i) stop VM execution */
volatile cpuset_t suspended_cpus; /* (i) suspended vcpus */
volatile cpuset_t halted_cpus; /* (x) cpus in a hard halt */
@@ -486,6 +487,7 @@
CPU_ZERO(&vm->active_cpus);
CPU_ZERO(&vm->debug_cpus);
+ CPU_ZERO(&vm->startup_cpus);
vm->suspend = 0;
CPU_ZERO(&vm->suspended_cpus);
@@ -2421,6 +2423,30 @@
return (vm->suspended_cpus);
}
+/*
+ * Returns the subset of vCPUs in tostart that are awaiting startup.
+ * These vCPUs are also marked as no longer awaiting startup.
+ */
+cpuset_t
+vm_start_cpus(struct vm *vm, const cpuset_t *tostart)
+{
+ cpuset_t set;
+
+ mtx_lock(&vm->rendezvous_mtx);
+ CPU_AND(&set, &vm->startup_cpus, tostart);
+ CPU_ANDNOT(&vm->startup_cpus, &vm->startup_cpus, &set);
+ mtx_unlock(&vm->rendezvous_mtx);
+ return (set);
+}
+
+void
+vm_await_start(struct vm *vm, const cpuset_t *waiting)
+{
+ mtx_lock(&vm->rendezvous_mtx);
+ CPU_OR(&vm->startup_cpus, &vm->startup_cpus, waiting);
+ mtx_unlock(&vm->rendezvous_mtx);
+}
+
void *
vcpu_stats(struct vcpu *vcpu)
{
@@ -2769,6 +2795,7 @@
if (ret != 0)
goto done;
+ SNAPSHOT_VAR_OR_LEAVE(vm->startup_cpus, meta, ret, done);
done:
return (ret);
}

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 29, 6:27 PM (20 h, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17844259
Default Alt Text
D37173.diff (5 KB)

Event Timeline