Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F142050602
D37168.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
39 KB
Referenced Files
None
Subscribers
None
D37168.diff
View Options
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
@@ -264,14 +264,14 @@
int vm_set_register(struct vcpu *vcpu, int reg, uint64_t val);
int vm_get_seg_desc(struct vcpu *vcpu, int reg,
struct seg_desc *ret_desc);
-int vm_set_seg_desc(struct vm *vm, int vcpu, int reg,
+int vm_set_seg_desc(struct vcpu *vcpu, int reg,
struct seg_desc *desc);
-int vm_run(struct vm *vm, struct vm_run *vmrun);
+int vm_run(struct vcpu *vcpu, struct vm_exit *vme_user);
int vm_suspend(struct vm *vm, enum vm_suspend_how how);
-int vm_inject_nmi(struct vm *vm, int vcpu);
+int vm_inject_nmi(struct vcpu *vcpu);
int vm_nmi_pending(struct vcpu *vcpu);
void vm_nmi_clear(struct vcpu *vcpu);
-int vm_inject_extint(struct vm *vm, int vcpu);
+int vm_inject_extint(struct vcpu *vcpu);
int vm_extint_pending(struct vcpu *vcpu);
void vm_extint_clear(struct vcpu *vcpu);
int vcpu_vcpuid(struct vcpu *vcpu);
@@ -280,14 +280,14 @@
struct vlapic *vm_lapic(struct vcpu *vcpu);
struct vioapic *vm_ioapic(struct vm *vm);
struct vhpet *vm_hpet(struct vm *vm);
-int vm_get_capability(struct vm *vm, int vcpu, int type, int *val);
-int vm_set_capability(struct vm *vm, int vcpu, int type, int val);
-int vm_get_x2apic_state(struct vm *vm, int vcpu, enum x2apic_state *state);
-int vm_set_x2apic_state(struct vm *vm, int vcpu, enum x2apic_state state);
+int vm_get_capability(struct vcpu *vcpu, int type, int *val);
+int vm_set_capability(struct vcpu *vcpu, int type, int val);
+int vm_get_x2apic_state(struct vcpu *vcpu, enum x2apic_state *state);
+int vm_set_x2apic_state(struct vcpu *vcpu, enum x2apic_state state);
int vm_apicid2vcpuid(struct vm *vm, int apicid);
-int vm_activate_cpu(struct vm *vm, int vcpu);
-int vm_suspend_cpu(struct vm *vm, int vcpu);
-int vm_resume_cpu(struct vm *vm, int vcpu);
+int vm_activate_cpu(struct vcpu *vcpu);
+int vm_suspend_cpu(struct vm *vm, struct vcpu *vcpu);
+int vm_resume_cpu(struct vm *vm, struct vcpu *vcpu);
int vm_restart_instruction(struct vcpu *vcpu);
struct vm_exit *vm_exitinfo(struct vcpu *vcpu);
void vm_exit_suspended(struct vcpu *vcpu, uint64_t rip);
@@ -361,8 +361,7 @@
VCPU_SLEEPING,
};
-int vcpu_set_state(struct vm *vm, int vcpu, enum vcpu_state state,
- bool from_idle);
+int vcpu_set_state(struct vcpu *vcpu, enum vcpu_state state, bool from_idle);
enum vcpu_state vcpu_get_state(struct vcpu *vcpu, int *hostcpu);
static int __inline
@@ -383,7 +382,7 @@
#endif
void *vcpu_stats(struct vcpu *vcpu);
-void vcpu_notify_event(struct vm *vm, int vcpuid, bool lapic_intr);
+void vcpu_notify_event(struct vcpu *vcpu, bool lapic_intr);
struct vmspace *vm_get_vmspace(struct vm *vm);
struct vatpic *vm_atpic(struct vm *vm);
struct vatpit *vm_atpit(struct vm *vm);
@@ -429,7 +428,7 @@
*/
int vm_entry_intinfo(struct vcpu *vcpu, uint64_t *info);
-int vm_get_intinfo(struct vm *vm, int vcpuid, uint64_t *info1, uint64_t *info2);
+int vm_get_intinfo(struct vcpu *vcpu, uint64_t *info1, uint64_t *info2);
/*
* Function used to keep track of the guest's TSC offset. The
diff --git a/sys/amd64/vmm/io/vatpic.c b/sys/amd64/vmm/io/vatpic.c
--- a/sys/amd64/vmm/io/vatpic.c
+++ b/sys/amd64/vmm/io/vatpic.c
@@ -262,7 +262,7 @@
* interrupt.
*/
atpic->intr_raised = true;
- lapic_set_local_intr(vatpic->vm, -1, APIC_LVT_LINT0);
+ lapic_set_local_intr(vatpic->vm, NULL, APIC_LVT_LINT0);
vioapic_pulse_irq(vatpic->vm, 0);
} else {
VATPIC_CTR3(vatpic, "atpic master no eligible interrupts "
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
@@ -460,13 +460,13 @@
return (0);
}
if (vlapic_set_intr_ready(vlapic, vec, false))
- vcpu_notify_event(vlapic->vm, vlapic->vcpuid, true);
+ vcpu_notify_event(vlapic->vcpu, true);
break;
case APIC_LVT_DM_NMI:
- vm_inject_nmi(vlapic->vm, vlapic->vcpuid);
+ vm_inject_nmi(vlapic->vcpu);
break;
case APIC_LVT_DM_EXTINT:
- vm_inject_extint(vlapic->vm, vlapic->vcpuid);
+ vm_inject_extint(vlapic->vcpu);
break;
default:
// Other modes ignored
@@ -680,10 +680,10 @@
*/
switch (vector) {
case APIC_LVT_LINT0:
- vm_inject_extint(vlapic->vm, vlapic->vcpuid);
+ vm_inject_extint(vlapic->vcpu);
break;
case APIC_LVT_LINT1:
- vm_inject_nmi(vlapic->vm, vlapic->vcpuid);
+ vm_inject_nmi(vlapic->vcpu);
break;
default:
break;
@@ -1040,6 +1040,7 @@
uint64_t icrval;
uint32_t dest, vec, mode, shorthand;
struct vlapic *vlapic2;
+ struct vcpu *vcpu;
struct vm_exit *vmexit;
struct LAPIC *lapic;
@@ -1100,7 +1101,8 @@
}
CPU_FOREACH_ISSET(i, &dmask) {
- lapic_intr_edge(vlapic->vm, i, vec);
+ vcpu = vm_vcpu(vlapic->vm, i);
+ lapic_intr_edge(vcpu, vec);
vmm_stat_array_incr(vlapic->vcpu, IPIS_SENT, i, 1);
VLAPIC_CTR2(vlapic,
"vlapic sending ipi %d to vcpuid %d", vec, i);
@@ -1109,7 +1111,8 @@
break;
case APIC_DELMODE_NMI:
CPU_FOREACH_ISSET(i, &dmask) {
- vm_inject_nmi(vlapic->vm, i);
+ vcpu = vm_vcpu(vlapic->vm, i);
+ vm_inject_nmi(vcpu);
VLAPIC_CTR1(vlapic,
"vlapic sending ipi nmi to vcpuid %d", i);
}
@@ -1130,7 +1133,8 @@
* requires that the boot state is set to SIPI
* here.
*/
- vlapic2 = vm_lapic(vm_vcpu(vlapic->vm, i));
+ vcpu = vm_vcpu(vlapic->vm, i);
+ vlapic2 = vm_lapic(vcpu);
vlapic2->boot_state = BS_SIPI;
break;
}
@@ -1154,7 +1158,8 @@
/*
* Ignore SIPIs in any state other than wait-for-SIPI
*/
- vlapic2 = vm_lapic(vm_vcpu(vlapic->vm, i));
+ vcpu = vm_vcpu(vlapic->vm, i);
+ vlapic2 = vm_lapic(vcpu);
if (vlapic2->boot_state != BS_SIPI)
break;
vlapic2->boot_state = BS_RUNNING;
@@ -1169,7 +1174,8 @@
}
CPU_FOREACH_ISSET(i, &dmask) {
- vlapic2 = vm_lapic(vm_vcpu(vlapic->vm, i));
+ vcpu = vm_vcpu(vlapic->vm, i);
+ vlapic2 = vm_lapic(vcpu);
/*
* Ignore SIPIs in any state other than wait-for-SIPI
@@ -1235,7 +1241,7 @@
KASSERT(x2apic(vlapic), ("SELF_IPI does not exist in xAPIC mode"));
vec = val & 0xff;
- lapic_intr_edge(vlapic->vm, vlapic->vcpuid, vec);
+ lapic_intr_edge(vlapic->vcpu, vec);
vmm_stat_array_incr(vlapic->vcpu, IPIS_SENT, vlapic->vcpuid, 1);
VLAPIC_CTR1(vlapic, "vlapic self-ipi %d", vec);
}
@@ -1696,6 +1702,7 @@
vlapic_deliver_intr(struct vm *vm, bool level, uint32_t dest, bool phys,
int delmode, int vec)
{
+ struct vcpu *vcpu;
bool lowprio;
int vcpuid;
cpuset_t dmask;
@@ -1716,10 +1723,11 @@
vlapic_calcdest(vm, &dmask, dest, phys, lowprio, false);
CPU_FOREACH_ISSET(vcpuid, &dmask) {
+ vcpu = vm_vcpu(vm, vcpuid);
if (delmode == IOART_DELEXINT) {
- vm_inject_extint(vm, vcpuid);
+ vm_inject_extint(vcpu);
} else {
- lapic_set_intr(vm, vcpuid, vec, level);
+ lapic_set_intr(vcpu, vec, level);
}
}
}
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
@@ -309,12 +309,6 @@
}
#endif
-static __inline void *
-vcpu_cookie(struct vm *vm, int i)
-{
- return (vm->vcpu[i].cookie);
-}
-
static void
vcpu_cleanup(struct vm *vm, int i, bool destroy)
{
@@ -354,7 +348,7 @@
vcpu->cookie = vmmops_vcpu_init(vm->cookie, vcpu, vcpu_id);
vcpu->vlapic = vmmops_vlapic_init(vcpu->cookie);
- vm_set_x2apic_state(vm, vcpu_id, X2APIC_DISABLED);
+ vm_set_x2apic_state(vcpu, X2APIC_DISABLED);
vcpu->reqidle = 0;
vcpu->exitintinfo = 0;
vcpu->nmi_pending = 0;
@@ -1172,16 +1166,13 @@
}
int
-vm_set_seg_desc(struct vm *vm, int vcpu, int reg,
- struct seg_desc *desc)
+vm_set_seg_desc(struct vcpu *vcpu, int reg, struct seg_desc *desc)
{
- if (vcpu < 0 || vcpu >= vm->maxcpus)
- return (EINVAL);
if (!is_segment_register(reg) && !is_descriptor_table(reg))
return (EINVAL);
- return (vmmops_setdesc(vcpu_cookie(vm, vcpu), reg, desc));
+ return (vmmops_setdesc(vcpu->cookie, reg, desc));
}
static void
@@ -1228,13 +1219,11 @@
static VMM_STAT(VCPU_IDLE_TICKS, "number of ticks vcpu was idle");
static int
-vcpu_set_state_locked(struct vm *vm, int vcpuid, enum vcpu_state newstate,
+vcpu_set_state_locked(struct vcpu *vcpu, enum vcpu_state newstate,
bool from_idle)
{
- struct vcpu *vcpu;
int error;
- vcpu = &vm->vcpu[vcpuid];
vcpu_assert_locked(vcpu);
/*
@@ -1246,7 +1235,7 @@
while (vcpu->state != VCPU_IDLE) {
vcpu->reqidle = 1;
vcpu_notify_event_locked(vcpu, false);
- VCPU_CTR1(vm, vcpuid, "vcpu state change from %s to "
+ VMM_CTR1(vcpu, "vcpu state change from %s to "
"idle requested", vcpu_state2str(vcpu->state));
msleep_spin(&vcpu->state, &vcpu->mtx, "vmstat", hz);
}
@@ -1286,7 +1275,7 @@
if (error)
return (EBUSY);
- VCPU_CTR2(vm, vcpuid, "vcpu state changed from %s to %s",
+ VMM_CTR2(vcpu, "vcpu state changed from %s to %s",
vcpu_state2str(vcpu->state), vcpu_state2str(newstate));
vcpu->state = newstate;
@@ -1302,20 +1291,20 @@
}
static void
-vcpu_require_state(struct vm *vm, int vcpuid, enum vcpu_state newstate)
+vcpu_require_state(struct vcpu *vcpu, enum vcpu_state newstate)
{
int error;
- if ((error = vcpu_set_state(vm, vcpuid, newstate, false)) != 0)
+ if ((error = vcpu_set_state(vcpu, newstate, false)) != 0)
panic("Error %d setting state to %d\n", error, newstate);
}
static void
-vcpu_require_state_locked(struct vm *vm, int vcpuid, enum vcpu_state newstate)
+vcpu_require_state_locked(struct vcpu *vcpu, enum vcpu_state newstate)
{
int error;
- if ((error = vcpu_set_state_locked(vm, vcpuid, newstate, false)) != 0)
+ if ((error = vcpu_set_state_locked(vcpu, newstate, false)) != 0)
panic("Error %d setting state to %d", error, newstate);
}
@@ -1366,21 +1355,21 @@
* Emulate a guest 'hlt' by sleeping until the vcpu is ready to run.
*/
static int
-vm_handle_hlt(struct vm *vm, int vcpuid, bool intr_disabled, bool *retu)
+vm_handle_hlt(struct vcpu *vcpu, bool intr_disabled, bool *retu)
{
- struct vcpu *vcpu;
+ struct vm *vm = vcpu->vm;
const char *wmesg;
struct thread *td;
- int error, t, vcpu_halted, vm_halted;
+ int error, t, vcpuid, vcpu_halted, vm_halted;
- KASSERT(!CPU_ISSET(vcpuid, &vm->halted_cpus), ("vcpu already halted"));
-
- vcpu = &vm->vcpu[vcpuid];
+ vcpuid = vcpu->vcpuid;
vcpu_halted = 0;
vm_halted = 0;
error = 0;
td = curthread;
+ KASSERT(!CPU_ISSET(vcpuid, &vm->halted_cpus), ("vcpu already halted"));
+
vcpu_lock(vcpu);
while (1) {
/*
@@ -1418,7 +1407,7 @@
*/
if (intr_disabled) {
wmesg = "vmhalt";
- VCPU_CTR0(vm, vcpuid, "Halted");
+ VMM_CTR0(vcpu, "Halted");
if (!vcpu_halted && halt_detection_enabled) {
vcpu_halted = 1;
CPU_SET_ATOMIC(vcpuid, &vm->halted_cpus);
@@ -1432,13 +1421,13 @@
}
t = ticks;
- vcpu_require_state_locked(vm, vcpuid, VCPU_SLEEPING);
+ vcpu_require_state_locked(vcpu, VCPU_SLEEPING);
/*
* XXX msleep_spin() cannot be interrupted by signals so
* wake up periodically to check pending signals.
*/
msleep_spin(vcpu, &vcpu->mtx, wmesg, hz);
- vcpu_require_state_locked(vm, vcpuid, VCPU_FROZEN);
+ vcpu_require_state_locked(vcpu, VCPU_FROZEN);
vmm_stat_incr(vcpu, VCPU_IDLE_TICKS, ticks - t);
if (td_ast_pending(td, TDA_SUSPEND)) {
vcpu_unlock(vcpu);
@@ -1466,14 +1455,13 @@
}
static int
-vm_handle_paging(struct vm *vm, int vcpuid, bool *retu)
+vm_handle_paging(struct vcpu *vcpu, bool *retu)
{
+ struct vm *vm = vcpu->vm;
int rv, ftype;
struct vm_map *map;
- struct vcpu *vcpu;
struct vm_exit *vme;
- vcpu = &vm->vcpu[vcpuid];
vme = &vcpu->exitinfo;
KASSERT(vme->inst_length == 0, ("%s: invalid inst_length %d",
@@ -1488,7 +1476,7 @@
rv = pmap_emulate_accessed_dirty(vmspace_pmap(vm->vmspace),
vme->u.paging.gpa, ftype);
if (rv == 0) {
- VCPU_CTR2(vm, vcpuid, "%s bit emulation for gpa %#lx",
+ VMM_CTR2(vcpu, "%s bit emulation for gpa %#lx",
ftype == VM_PROT_READ ? "accessed" : "dirty",
vme->u.paging.gpa);
goto done;
@@ -1498,7 +1486,7 @@
map = &vm->vmspace->vm_map;
rv = vm_fault(map, vme->u.paging.gpa, ftype, VM_FAULT_NORMAL, NULL);
- VCPU_CTR3(vm, vcpuid, "vm_handle_paging rv = %d, gpa = %#lx, "
+ VMM_CTR3(vcpu, "vm_handle_paging rv = %d, gpa = %#lx, "
"ftype = %d", rv, vme->u.paging.gpa, ftype);
if (rv != KERN_SUCCESS)
@@ -1508,10 +1496,9 @@
}
static int
-vm_handle_inst_emul(struct vm *vm, int vcpuid, bool *retu)
+vm_handle_inst_emul(struct vcpu *vcpu, bool *retu)
{
struct vie *vie;
- struct vcpu *vcpu;
struct vm_exit *vme;
uint64_t gla, gpa, cs_base;
struct vm_guest_paging *paging;
@@ -1520,7 +1507,6 @@
enum vm_cpu_mode cpu_mode;
int cs_d, error, fault;
- vcpu = &vm->vcpu[vcpuid];
vme = &vcpu->exitinfo;
KASSERT(vme->inst_length == 0, ("%s: invalid inst_length %d",
@@ -1534,7 +1520,7 @@
paging = &vme->u.inst_emul.paging;
cpu_mode = paging->cpu_mode;
- VCPU_CTR1(vm, vcpuid, "inst_emul fault accessing gpa %#lx", gpa);
+ VMM_CTR1(vcpu, "inst_emul fault accessing gpa %#lx", gpa);
/* Fetch, decode and emulate the faulting instruction */
if (vie->num_valid == 0) {
@@ -1550,7 +1536,7 @@
return (error);
if (vmm_decode_instruction(vcpu, gla, cpu_mode, cs_d, vie) != 0) {
- VCPU_CTR1(vm, vcpuid, "Error decoding instruction at %#lx",
+ VMM_CTR1(vcpu, "Error decoding instruction at %#lx",
vme->rip + cs_base);
*retu = true; /* dump instruction bytes in userspace */
return (0);
@@ -1561,8 +1547,8 @@
*/
vme->inst_length = vie->num_processed;
vcpu->nextrip += vie->num_processed;
- VCPU_CTR1(vm, vcpuid, "nextrip updated to %#lx after instruction "
- "decoding", vcpu->nextrip);
+ VMM_CTR1(vcpu, "nextrip updated to %#lx after instruction decoding",
+ vcpu->nextrip);
/* return to userland unless this is an in-kernel emulated device */
if (gpa >= DEFAULT_APIC_BASE && gpa < DEFAULT_APIC_BASE + PAGE_SIZE) {
@@ -1586,17 +1572,16 @@
}
static int
-vm_handle_suspend(struct vm *vm, int vcpuid, bool *retu)
+vm_handle_suspend(struct vcpu *vcpu, bool *retu)
{
+ struct vm *vm = vcpu->vm;
int error, i;
- struct vcpu *vcpu;
struct thread *td;
error = 0;
- vcpu = &vm->vcpu[vcpuid];
td = curthread;
- CPU_SET_ATOMIC(vcpuid, &vm->suspended_cpus);
+ CPU_SET_ATOMIC(vcpu->vcpuid, &vm->suspended_cpus);
/*
* Wait until all 'active_cpus' have suspended themselves.
@@ -1608,22 +1593,22 @@
vcpu_lock(vcpu);
while (error == 0) {
if (CPU_CMP(&vm->suspended_cpus, &vm->active_cpus) == 0) {
- VCPU_CTR0(vm, vcpuid, "All vcpus suspended");
+ VMM_CTR0(vcpu, "All vcpus suspended");
break;
}
if (vm->rendezvous_func == NULL) {
- VCPU_CTR0(vm, vcpuid, "Sleeping during suspend");
- vcpu_require_state_locked(vm, vcpuid, VCPU_SLEEPING);
+ VMM_CTR0(vcpu, "Sleeping during suspend");
+ vcpu_require_state_locked(vcpu, VCPU_SLEEPING);
msleep_spin(vcpu, &vcpu->mtx, "vmsusp", hz);
- vcpu_require_state_locked(vm, vcpuid, VCPU_FROZEN);
+ vcpu_require_state_locked(vcpu, VCPU_FROZEN);
if (td_ast_pending(td, TDA_SUSPEND)) {
vcpu_unlock(vcpu);
error = thread_check_susp(td, false);
vcpu_lock(vcpu);
}
} else {
- VCPU_CTR0(vm, vcpuid, "Rendezvous during suspend");
+ VMM_CTR0(vcpu, "Rendezvous during suspend");
vcpu_unlock(vcpu);
error = vm_handle_rendezvous(vcpu);
vcpu_lock(vcpu);
@@ -1636,7 +1621,7 @@
*/
for (i = 0; i < vm->maxcpus; i++) {
if (CPU_ISSET(i, &vm->suspended_cpus)) {
- vcpu_notify_event(vm, i, false);
+ vcpu_notify_event(vm_vcpu(vm, i), false);
}
}
@@ -1645,10 +1630,8 @@
}
static int
-vm_handle_reqidle(struct vm *vm, int vcpuid, bool *retu)
+vm_handle_reqidle(struct vcpu *vcpu, bool *retu)
{
- struct vcpu *vcpu = &vm->vcpu[vcpuid];
-
vcpu_lock(vcpu);
KASSERT(vcpu->reqidle, ("invalid vcpu reqidle %d", vcpu->reqidle));
vcpu->reqidle = 0;
@@ -1678,7 +1661,7 @@
*/
for (i = 0; i < vm->maxcpus; i++) {
if (CPU_ISSET(i, &vm->active_cpus))
- vcpu_notify_event(vm, i, false);
+ vcpu_notify_event(vm_vcpu(vm, i), false);
}
return (0);
@@ -1751,21 +1734,18 @@
}
int
-vm_run(struct vm *vm, struct vm_run *vmrun)
+vm_run(struct vcpu *vcpu, struct vm_exit *vme_user)
{
+ struct vm *vm = vcpu->vm;
struct vm_eventinfo evinfo;
int error, vcpuid;
- struct vcpu *vcpu;
struct pcb *pcb;
uint64_t tscval;
struct vm_exit *vme;
bool retu, intr_disabled;
pmap_t pmap;
- vcpuid = vmrun->cpuid;
-
- if (vcpuid < 0 || vcpuid >= vm->maxcpus)
- return (EINVAL);
+ vcpuid = vcpu->vcpuid;
if (!CPU_ISSET(vcpuid, &vm->active_cpus))
return (EINVAL);
@@ -1774,7 +1754,6 @@
return (EINVAL);
pmap = vmspace_pmap(vm->vmspace);
- vcpu = &vm->vcpu[vcpuid];
vme = &vcpu->exitinfo;
evinfo.rptr = &vm->rendezvous_func;
evinfo.sptr = &vm->suspend;
@@ -1792,9 +1771,9 @@
restore_guest_fpustate(vcpu);
- vcpu_require_state(vm, vcpuid, VCPU_RUNNING);
+ vcpu_require_state(vcpu, VCPU_RUNNING);
error = vmmops_run(vcpu->cookie, vcpu->nextrip, pmap, &evinfo);
- vcpu_require_state(vm, vcpuid, VCPU_FROZEN);
+ vcpu_require_state(vcpu, VCPU_FROZEN);
save_guest_fpustate(vcpu);
@@ -1807,10 +1786,10 @@
vcpu->nextrip = vme->rip + vme->inst_length;
switch (vme->exitcode) {
case VM_EXITCODE_REQIDLE:
- error = vm_handle_reqidle(vm, vcpuid, &retu);
+ error = vm_handle_reqidle(vcpu, &retu);
break;
case VM_EXITCODE_SUSPENDED:
- error = vm_handle_suspend(vm, vcpuid, &retu);
+ error = vm_handle_suspend(vcpu, &retu);
break;
case VM_EXITCODE_IOAPIC_EOI:
vioapic_process_eoi(vm, vme->u.ioapic_eoi.vector);
@@ -1820,17 +1799,17 @@
break;
case VM_EXITCODE_HLT:
intr_disabled = ((vme->u.hlt.rflags & PSL_I) == 0);
- error = vm_handle_hlt(vm, vcpuid, intr_disabled, &retu);
+ error = vm_handle_hlt(vcpu, intr_disabled, &retu);
break;
case VM_EXITCODE_PAGING:
- error = vm_handle_paging(vm, vcpuid, &retu);
+ error = vm_handle_paging(vcpu, &retu);
break;
case VM_EXITCODE_INST_EMUL:
- error = vm_handle_inst_emul(vm, vcpuid, &retu);
+ error = vm_handle_inst_emul(vcpu, &retu);
break;
case VM_EXITCODE_INOUT:
case VM_EXITCODE_INOUT_STR:
- error = vm_handle_inout(vm, vcpuid, vme, &retu);
+ error = vm_handle_inout(vcpu, vme, &retu);
break;
case VM_EXITCODE_MONITOR:
case VM_EXITCODE_MWAIT:
@@ -1856,10 +1835,10 @@
goto restart;
vmm_stat_incr(vcpu, VMEXIT_USERSPACE, 1);
- VCPU_CTR2(vm, vcpuid, "retu %d/%d", error, vme->exitcode);
+ VMM_CTR2(vcpu, "retu %d/%d", error, vme->exitcode);
/* copy the exit information */
- bcopy(vme, &vmrun->vm_exit, sizeof(struct vm_exit));
+ *vme_user = *vme;
return (error);
}
@@ -2071,14 +2050,8 @@
}
int
-vm_get_intinfo(struct vm *vm, int vcpuid, uint64_t *info1, uint64_t *info2)
+vm_get_intinfo(struct vcpu *vcpu, uint64_t *info1, uint64_t *info2)
{
- struct vcpu *vcpu;
-
- if (vcpuid < 0 || vcpuid >= vm->maxcpus)
- return (EINVAL);
-
- vcpu = &vm->vcpu[vcpuid];
*info1 = vcpu->exitintinfo;
*info2 = vcpu_exception_intinfo(vcpu);
return (0);
@@ -2168,17 +2141,11 @@
static VMM_STAT(VCPU_NMI_COUNT, "number of NMIs delivered to vcpu");
int
-vm_inject_nmi(struct vm *vm, int vcpuid)
+vm_inject_nmi(struct vcpu *vcpu)
{
- struct vcpu *vcpu;
-
- if (vcpuid < 0 || vcpuid >= vm->maxcpus)
- return (EINVAL);
-
- vcpu = &vm->vcpu[vcpuid];
vcpu->nmi_pending = 1;
- vcpu_notify_event(vm, vcpuid, false);
+ vcpu_notify_event(vcpu, false);
return (0);
}
@@ -2201,17 +2168,11 @@
static VMM_STAT(VCPU_EXTINT_COUNT, "number of ExtINTs delivered to vcpu");
int
-vm_inject_extint(struct vm *vm, int vcpuid)
+vm_inject_extint(struct vcpu *vcpu)
{
- struct vcpu *vcpu;
-
- if (vcpuid < 0 || vcpuid >= vm->maxcpus)
- return (EINVAL);
-
- vcpu = &vm->vcpu[vcpuid];
vcpu->extint_pending = 1;
- vcpu_notify_event(vm, vcpuid, false);
+ vcpu_notify_event(vcpu, false);
return (0);
}
@@ -2232,27 +2193,21 @@
}
int
-vm_get_capability(struct vm *vm, int vcpu, int type, int *retval)
+vm_get_capability(struct vcpu *vcpu, int type, int *retval)
{
- if (vcpu < 0 || vcpu >= vm->maxcpus)
- return (EINVAL);
-
if (type < 0 || type >= VM_CAP_MAX)
return (EINVAL);
- return (vmmops_getcap(vcpu_cookie(vm, vcpu), type, retval));
+ return (vmmops_getcap(vcpu->cookie, type, retval));
}
int
-vm_set_capability(struct vm *vm, int vcpu, int type, int val)
+vm_set_capability(struct vcpu *vcpu, int type, int val)
{
- if (vcpu < 0 || vcpu >= vm->maxcpus)
- return (EINVAL);
-
if (type < 0 || type >= VM_CAP_MAX)
return (EINVAL);
- return (vmmops_setcap(vcpu_cookie(vm, vcpu), type, val));
+ return (vmmops_setcap(vcpu->cookie, type, val));
}
struct vm *
@@ -2343,19 +2298,12 @@
}
int
-vcpu_set_state(struct vm *vm, int vcpuid, enum vcpu_state newstate,
- bool from_idle)
+vcpu_set_state(struct vcpu *vcpu, enum vcpu_state newstate, bool from_idle)
{
int error;
- struct vcpu *vcpu;
-
- if (vcpuid < 0 || vcpuid >= vm->maxcpus)
- panic("vm_set_run_state: invalid vcpuid %d", vcpuid);
-
- vcpu = &vm->vcpu[vcpuid];
vcpu_lock(vcpu);
- error = vcpu_set_state_locked(vm, vcpuid, newstate, from_idle);
+ error = vcpu_set_state_locked(vcpu, newstate, from_idle);
vcpu_unlock(vcpu);
return (error);
@@ -2376,58 +2324,48 @@
}
int
-vm_activate_cpu(struct vm *vm, int vcpuid)
+vm_activate_cpu(struct vcpu *vcpu)
{
+ struct vm *vm = vcpu->vm;
- if (vcpuid < 0 || vcpuid >= vm->maxcpus)
- return (EINVAL);
-
- if (CPU_ISSET(vcpuid, &vm->active_cpus))
+ if (CPU_ISSET(vcpu->vcpuid, &vm->active_cpus))
return (EBUSY);
- VCPU_CTR0(vm, vcpuid, "activated");
- CPU_SET_ATOMIC(vcpuid, &vm->active_cpus);
+ VMM_CTR0(vcpu, "activated");
+ CPU_SET_ATOMIC(vcpu->vcpuid, &vm->active_cpus);
return (0);
}
int
-vm_suspend_cpu(struct vm *vm, int vcpuid)
+vm_suspend_cpu(struct vm *vm, struct vcpu *vcpu)
{
- int i;
-
- if (vcpuid < -1 || vcpuid >= vm->maxcpus)
- return (EINVAL);
-
- if (vcpuid == -1) {
+ if (vcpu == NULL) {
vm->debug_cpus = vm->active_cpus;
- for (i = 0; i < vm->maxcpus; i++) {
+ for (int i = 0; i < vm->maxcpus; i++) {
if (CPU_ISSET(i, &vm->active_cpus))
- vcpu_notify_event(vm, i, false);
+ vcpu_notify_event(vm_vcpu(vm, i), false);
}
} else {
- if (!CPU_ISSET(vcpuid, &vm->active_cpus))
+ if (!CPU_ISSET(vcpu->vcpuid, &vm->active_cpus))
return (EINVAL);
- CPU_SET_ATOMIC(vcpuid, &vm->debug_cpus);
- vcpu_notify_event(vm, vcpuid, false);
+ CPU_SET_ATOMIC(vcpu->vcpuid, &vm->debug_cpus);
+ vcpu_notify_event(vcpu, false);
}
return (0);
}
int
-vm_resume_cpu(struct vm *vm, int vcpuid)
+vm_resume_cpu(struct vm *vm, struct vcpu *vcpu)
{
- if (vcpuid < -1 || vcpuid >= vm->maxcpus)
- return (EINVAL);
-
- if (vcpuid == -1) {
+ if (vcpu == NULL) {
CPU_ZERO(&vm->debug_cpus);
} else {
- if (!CPU_ISSET(vcpuid, &vm->debug_cpus))
+ if (!CPU_ISSET(vcpu->vcpuid, &vm->debug_cpus))
return (EINVAL);
- CPU_CLR_ATOMIC(vcpuid, &vm->debug_cpus);
+ CPU_CLR_ATOMIC(vcpu->vcpuid, &vm->debug_cpus);
}
return (0);
}
@@ -2468,28 +2406,19 @@
}
int
-vm_get_x2apic_state(struct vm *vm, int vcpuid, enum x2apic_state *state)
+vm_get_x2apic_state(struct vcpu *vcpu, enum x2apic_state *state)
{
- if (vcpuid < 0 || vcpuid >= vm->maxcpus)
- return (EINVAL);
-
- *state = vm->vcpu[vcpuid].x2apic_state;
+ *state = vcpu->x2apic_state;
return (0);
}
int
-vm_set_x2apic_state(struct vm *vm, int vcpuid, enum x2apic_state state)
+vm_set_x2apic_state(struct vcpu *vcpu, enum x2apic_state state)
{
- struct vcpu *vcpu;
-
- if (vcpuid < 0 || vcpuid >= vm->maxcpus)
- return (EINVAL);
-
if (state >= X2APIC_STATE_LAST)
return (EINVAL);
- vcpu = &vm->vcpu[vcpuid];
vcpu->x2apic_state = state;
vlapic_set_x2apic_state(vcpu, state);
@@ -2536,10 +2465,8 @@
}
void
-vcpu_notify_event(struct vm *vm, int vcpuid, bool lapic_intr)
+vcpu_notify_event(struct vcpu *vcpu, bool lapic_intr)
{
- struct vcpu *vcpu = &vm->vcpu[vcpuid];
-
vcpu_lock(vcpu);
vcpu_notify_event_locked(vcpu, lapic_intr);
vcpu_unlock(vcpu);
@@ -2578,7 +2505,7 @@
if (vm->rendezvous_func != NULL) {
/*
* If a rendezvous is already in progress then we need to
- * call the rendezvous handler in case this 'vcpuid' is one
+ * call the rendezvous handler in case this 'vcpu' is one
* of the targets of the rendezvous.
*/
VMM_CTR0(vcpu, "Rendezvous already in progress");
@@ -2604,7 +2531,7 @@
*/
for (i = 0; i < vm->maxcpus; i++) {
if (CPU_ISSET(i, &dest))
- vcpu_notify_event(vm, i, false);
+ vcpu_notify_event(vm_vcpu(vm, i), false);
}
return (vm_handle_rendezvous(vcpu));
@@ -2751,22 +2678,22 @@
VMM_STAT_DECLARE(VMM_MEM_WIRED);
static void
-vm_get_rescnt(struct vm *vm, int vcpu, struct vmm_stat_type *stat)
+vm_get_rescnt(struct vcpu *vcpu, struct vmm_stat_type *stat)
{
- if (vcpu == 0) {
- vmm_stat_set(vm_vcpu(vm, vcpu), VMM_MEM_RESIDENT,
- PAGE_SIZE * vmspace_resident_count(vm->vmspace));
+ if (vcpu->vcpuid == 0) {
+ vmm_stat_set(vcpu, VMM_MEM_RESIDENT, PAGE_SIZE *
+ vmspace_resident_count(vcpu->vm->vmspace));
}
}
static void
-vm_get_wiredcnt(struct vm *vm, int vcpu, struct vmm_stat_type *stat)
+vm_get_wiredcnt(struct vcpu *vcpu, struct vmm_stat_type *stat)
{
- if (vcpu == 0) {
- vmm_stat_set(vm_vcpu(vm, vcpu), VMM_MEM_WIRED,
- PAGE_SIZE * pmap_wired_count(vmspace_pmap(vm->vmspace)));
+ if (vcpu->vcpuid == 0) {
+ vmm_stat_set(vcpu, VMM_MEM_WIRED, PAGE_SIZE *
+ pmap_wired_count(vmspace_pmap(vcpu->vm->vmspace)));
}
}
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
@@ -131,22 +131,24 @@
if (vcpu < 0 || vcpu >= vm_get_maxcpus(sc->vm))
return (EINVAL);
- error = vcpu_set_state(sc->vm, vcpu, VCPU_FROZEN, true);
+ error = vcpu_set_state(vm_vcpu(sc->vm, vcpu), VCPU_FROZEN, true);
return (error);
}
static void
-vcpu_unlock_one(struct vmmdev_softc *sc, int vcpu)
+vcpu_unlock_one(struct vmmdev_softc *sc, int vcpuid)
{
+ struct vcpu *vcpu;
enum vcpu_state state;
- state = vcpu_get_state(vm_vcpu(sc->vm, vcpu), NULL);
+ vcpu = vm_vcpu(sc->vm, vcpuid);
+ state = vcpu_get_state(vcpu, NULL);
if (state != VCPU_FROZEN) {
panic("vcpu %s(%d) has invalid state %d", vm_name(sc->vm),
- vcpu, state);
+ vcpuid, state);
}
- vcpu_set_state(sc->vm, vcpu, VCPU_IDLE, false);
+ vcpu_set_state(vcpu, VCPU_IDLE, false);
}
static int
@@ -366,6 +368,15 @@
return (error);
}
+static struct vcpu *
+lookup_vcpu(struct vm *vm, int vcpuid)
+{
+ if (vcpuid < 0 || vcpuid >= vm_get_maxcpus(vm))
+ return (NULL);
+
+ return (vm_vcpu(vm, vcpuid));
+}
+
static int
vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
struct thread *td)
@@ -389,7 +400,6 @@
struct vm_pptdev_mmio *pptmmio;
struct vm_pptdev_msi *pptmsi;
struct vm_pptdev_msix *pptmsix;
- struct vm_nmi *vmnmi;
#ifdef COMPAT_FREEBSD13
struct vm_stats_old *vmstats_old;
#endif
@@ -399,7 +409,6 @@
struct vm_gpa_pte *gpapte;
struct vm_suspend *vmsuspend;
struct vm_gla2gpa *gg;
- struct vm_activate_cpu *vac;
struct vm_cpuset *vm_cpuset;
struct vm_intinfo *vmii;
struct vm_rtc_time *rtctime;
@@ -427,7 +436,13 @@
state_changed = 0;
/*
- * Some VMM ioctls can operate only on vcpus that are not running.
+ * For VMM ioctls that operate on a single vCPU, lookup the
+ * vcpu. For VMM ioctls which require one or more vCPUs to
+ * not be running, lock necessary vCPUs.
+ *
+ * XXX fragile, handle with care
+ * Most of these assume that the first field of the ioctl data
+ * is the vcpuid.
*/
switch (cmd) {
case VM_RUN:
@@ -450,8 +465,7 @@
case VM_GET_INTINFO:
case VM_RESTART_INSTRUCTION:
/*
- * XXX fragile, handle with care
- * Assumes that the first field of the ioctl data is the vcpu.
+ * ioctls that can operate only on vcpus that are not running.
*/
vcpuid = *(int *)data;
error = vcpu_lock_one(sc, vcpuid);
@@ -498,6 +512,42 @@
state_changed = 1;
break;
+#ifdef COMPAT_FREEBSD13
+ case VM_STATS_OLD:
+#endif
+ case VM_STATS:
+ case VM_INJECT_NMI:
+ case VM_LAPIC_IRQ:
+ case VM_GET_X2APIC_STATE:
+ /*
+ * These do not need the vCPU locked but do operate on
+ * a specific vCPU.
+ */
+ vcpuid = *(int *)data;
+ vcpu = lookup_vcpu(sc->vm, vcpuid);
+ if (vcpu == NULL) {
+ error = EINVAL;
+ goto done;
+ }
+ break;
+
+ case VM_LAPIC_LOCAL_IRQ:
+ case VM_SUSPEND_CPU:
+ case VM_RESUME_CPU:
+ /*
+ * These can either operate on all CPUs via a vcpuid of
+ * -1 or on a specific vCPU.
+ */
+ vcpuid = *(int *)data;
+ if (vcpuid == -1)
+ break;
+ vcpu = lookup_vcpu(sc->vm, vcpuid);
+ if (vcpu == NULL) {
+ error = EINVAL;
+ goto done;
+ }
+ break;
+
default:
break;
}
@@ -505,7 +555,7 @@
switch(cmd) {
case VM_RUN:
vmrun = (struct vm_run *)data;
- error = vm_run(sc->vm, vmrun);
+ error = vm_run(vcpu, &vmrun->vm_exit);
break;
case VM_SUSPEND:
vmsuspend = (struct vm_suspend *)data;
@@ -524,7 +574,7 @@
case VM_STATS_OLD:
vmstats_old = (struct vm_stats_old *)data;
getmicrotime(&vmstats_old->tv);
- error = vmm_stat_copy(sc->vm, vmstats_old->cpuid, 0,
+ error = vmm_stat_copy(vcpu, 0,
nitems(vmstats_old->statbuf),
&vmstats_old->num_entries,
vmstats_old->statbuf);
@@ -533,7 +583,7 @@
case VM_STATS: {
vmstats = (struct vm_stats *)data;
getmicrotime(&vmstats->tv);
- error = vmm_stat_copy(sc->vm, vmstats->cpuid, vmstats->index,
+ error = vmm_stat_copy(vcpu, vmstats->index,
nitems(vmstats->statbuf),
&vmstats->num_entries, vmstats->statbuf);
break;
@@ -586,17 +636,15 @@
vmexc->restart_instruction);
break;
case VM_INJECT_NMI:
- vmnmi = (struct vm_nmi *)data;
- error = vm_inject_nmi(sc->vm, vmnmi->cpuid);
+ error = vm_inject_nmi(vcpu);
break;
case VM_LAPIC_IRQ:
vmirq = (struct vm_lapic_irq *)data;
- error = lapic_intr_edge(sc->vm, vmirq->cpuid, vmirq->vector);
+ error = lapic_intr_edge(vcpu, vmirq->vector);
break;
case VM_LAPIC_LOCAL_IRQ:
vmirq = (struct vm_lapic_irq *)data;
- error = lapic_set_local_intr(sc->vm, vmirq->cpuid,
- vmirq->vector);
+ error = lapic_set_local_intr(sc->vm, vcpu, vmirq->vector);
break;
case VM_LAPIC_MSI:
vmmsi = (struct vm_lapic_msi *)data;
@@ -721,7 +769,7 @@
break;
case VM_SET_SEGMENT_DESCRIPTOR:
vmsegdesc = (struct vm_seg_desc *)data;
- error = vm_set_seg_desc(sc->vm, vmsegdesc->cpuid,
+ error = vm_set_seg_desc(vcpu,
vmsegdesc->regnum,
&vmsegdesc->desc);
break;
@@ -775,25 +823,23 @@
break;
case VM_GET_CAPABILITY:
vmcap = (struct vm_capability *)data;
- error = vm_get_capability(sc->vm, vmcap->cpuid,
+ error = vm_get_capability(vcpu,
vmcap->captype,
&vmcap->capval);
break;
case VM_SET_CAPABILITY:
vmcap = (struct vm_capability *)data;
- error = vm_set_capability(sc->vm, vmcap->cpuid,
+ error = vm_set_capability(vcpu,
vmcap->captype,
vmcap->capval);
break;
case VM_SET_X2APIC_STATE:
x2apic = (struct vm_x2apic *)data;
- error = vm_set_x2apic_state(sc->vm,
- x2apic->cpuid, x2apic->state);
+ error = vm_set_x2apic_state(vcpu, x2apic->state);
break;
case VM_GET_X2APIC_STATE:
x2apic = (struct vm_x2apic *)data;
- error = vm_get_x2apic_state(sc->vm,
- x2apic->cpuid, &x2apic->state);
+ error = vm_get_x2apic_state(vcpu, &x2apic->state);
break;
case VM_GET_GPA_PMAP:
gpapte = (struct vm_gpa_pte *)data;
@@ -823,8 +869,7 @@
("%s: vm_gla2gpa unknown error %d", __func__, error));
break;
case VM_ACTIVATE_CPU:
- vac = (struct vm_activate_cpu *)data;
- error = vm_activate_cpu(sc->vm, vac->vcpuid);
+ error = vm_activate_cpu(vcpu);
break;
case VM_GET_CPUS:
error = 0;
@@ -848,12 +893,10 @@
free(cpuset, M_TEMP);
break;
case VM_SUSPEND_CPU:
- vac = (struct vm_activate_cpu *)data;
- error = vm_suspend_cpu(sc->vm, vac->vcpuid);
+ error = vm_suspend_cpu(sc->vm, vcpu);
break;
case VM_RESUME_CPU:
- vac = (struct vm_activate_cpu *)data;
- error = vm_resume_cpu(sc->vm, vac->vcpuid);
+ error = vm_resume_cpu(sc->vm, vcpu);
break;
case VM_SET_INTINFO:
vmii = (struct vm_intinfo *)data;
@@ -861,8 +904,7 @@
break;
case VM_GET_INTINFO:
vmii = (struct vm_intinfo *)data;
- error = vm_get_intinfo(sc->vm, vmii->vcpuid, &vmii->info1,
- &vmii->info2);
+ error = vm_get_intinfo(vcpu, &vmii->info1, &vmii->info2);
break;
case VM_RTC_WRITE:
rtcdata = (struct vm_rtc_data *)data;
diff --git a/sys/amd64/vmm/vmm_ioport.h b/sys/amd64/vmm/vmm_ioport.h
--- a/sys/amd64/vmm/vmm_ioport.h
+++ b/sys/amd64/vmm/vmm_ioport.h
@@ -34,6 +34,6 @@
typedef int (*ioport_handler_func_t)(struct vm *vm,
bool in, int port, int bytes, uint32_t *val);
-int vm_handle_inout(struct vm *vm, int vcpuid, struct vm_exit *vme, bool *retu);
+int vm_handle_inout(struct vcpu *vcpu, struct vm_exit *vme, bool *retu);
#endif /* _VMM_IOPORT_H_ */
diff --git a/sys/amd64/vmm/vmm_ioport.c b/sys/amd64/vmm/vmm_ioport.c
--- a/sys/amd64/vmm/vmm_ioport.c
+++ b/sys/amd64/vmm/vmm_ioport.c
@@ -100,8 +100,7 @@
#endif /* KTR */
static int
-emulate_inout_port(struct vm *vm, int vcpuid, struct vm_exit *vmexit,
- bool *retu)
+emulate_inout_port(struct vcpu *vcpu, struct vm_exit *vmexit, bool *retu)
{
ioport_handler_func_t handler;
uint32_t mask, val;
@@ -122,8 +121,8 @@
val = vmexit->u.inout.eax & mask;
}
- error = (*handler)(vm, vmexit->u.inout.in, vmexit->u.inout.port,
- vmexit->u.inout.bytes, &val);
+ error = (*handler)(vcpu_vm(vcpu), vmexit->u.inout.in,
+ vmexit->u.inout.port, vmexit->u.inout.bytes, &val);
if (error) {
/*
* The value returned by this function is also the return value
@@ -138,7 +137,7 @@
if (vmexit->u.inout.in) {
vmexit->u.inout.eax &= ~mask;
vmexit->u.inout.eax |= val & mask;
- error = vm_set_register(vm_vcpu(vm, vcpuid), VM_REG_GUEST_RAX,
+ error = vm_set_register(vcpu, VM_REG_GUEST_RAX,
vmexit->u.inout.eax);
KASSERT(error == 0, ("emulate_ioport: error %d setting guest "
"rax register", error));
@@ -148,14 +147,14 @@
}
static int
-emulate_inout_str(struct vm *vm, int vcpuid, struct vm_exit *vmexit, bool *retu)
+emulate_inout_str(struct vcpu *vcpu, struct vm_exit *vmexit, bool *retu)
{
*retu = true;
return (0); /* Return to userspace to finish emulation */
}
int
-vm_handle_inout(struct vm *vm, int vcpuid, struct vm_exit *vmexit, bool *retu)
+vm_handle_inout(struct vcpu *vcpu, struct vm_exit *vmexit, bool *retu)
{
int bytes __diagused, error;
@@ -164,11 +163,11 @@
("vm_handle_inout: invalid operand size %d", bytes));
if (vmexit->u.inout.string)
- error = emulate_inout_str(vm, vcpuid, vmexit, retu);
+ error = emulate_inout_str(vcpu, vmexit, retu);
else
- error = emulate_inout_port(vm, vcpuid, vmexit, retu);
+ error = emulate_inout_port(vcpu, vmexit, retu);
- VCPU_CTR4(vm, vcpuid, "%s%s 0x%04x: %s",
+ VCPU_CTR4(vcpu_vm(vcpu), vcpu_vcpuid(vcpu), "%s%s 0x%04x: %s",
vmexit->u.inout.rep ? "rep " : "",
inout_instruction(vmexit),
vmexit->u.inout.port,
diff --git a/sys/amd64/vmm/vmm_lapic.h b/sys/amd64/vmm/vmm_lapic.h
--- a/sys/amd64/vmm/vmm_lapic.h
+++ b/sys/amd64/vmm/vmm_lapic.h
@@ -47,29 +47,29 @@
* Signals to the LAPIC that an interrupt at 'vector' needs to be generated
* to the 'cpu', the state is recorded in IRR.
*/
-int lapic_set_intr(struct vm *vm, int cpu, int vector, bool trig);
+int lapic_set_intr(struct vcpu *vcpu, int vector, bool trig);
#define LAPIC_TRIG_LEVEL true
#define LAPIC_TRIG_EDGE false
static __inline int
-lapic_intr_level(struct vm *vm, int cpu, int vector)
+lapic_intr_level(struct vcpu *vcpu, int vector)
{
- return (lapic_set_intr(vm, cpu, vector, LAPIC_TRIG_LEVEL));
+ return (lapic_set_intr(vcpu, vector, LAPIC_TRIG_LEVEL));
}
static __inline int
-lapic_intr_edge(struct vm *vm, int cpu, int vector)
+lapic_intr_edge(struct vcpu *vcpu, int vector)
{
- return (lapic_set_intr(vm, cpu, vector, LAPIC_TRIG_EDGE));
+ return (lapic_set_intr(vcpu, vector, LAPIC_TRIG_EDGE));
}
/*
* Triggers the LAPIC local interrupt (LVT) 'vector' on 'cpu'. 'cpu' can
* be set to -1 to trigger the interrupt on all CPUs.
*/
-int lapic_set_local_intr(struct vm *vm, int cpu, int vector);
+int lapic_set_local_intr(struct vm *vm, struct vcpu *vcpu, int vector);
int lapic_intr_msi(struct vm *vm, uint64_t addr, uint64_t msg);
diff --git a/sys/amd64/vmm/vmm_lapic.c b/sys/amd64/vmm/vmm_lapic.c
--- a/sys/amd64/vmm/vmm_lapic.c
+++ b/sys/amd64/vmm/vmm_lapic.c
@@ -52,13 +52,10 @@
#define MSI_X86_ADDR_LOG 0x00000004 /* Destination Mode */
int
-lapic_set_intr(struct vm *vm, int cpu, int vector, bool level)
+lapic_set_intr(struct vcpu *vcpu, int vector, bool level)
{
struct vlapic *vlapic;
- if (cpu < 0 || cpu >= vm_get_maxcpus(vm))
- return (EINVAL);
-
/*
* According to section "Maskable Hardware Interrupts" in Intel SDM
* vectors 16 through 255 can be delivered through the local APIC.
@@ -66,32 +63,31 @@
if (vector < 16 || vector > 255)
return (EINVAL);
- vlapic = vm_lapic(vm_vcpu(vm, cpu));
+ vlapic = vm_lapic(vcpu);
if (vlapic_set_intr_ready(vlapic, vector, level))
- vcpu_notify_event(vm, cpu, true);
+ vcpu_notify_event(vcpu, true);
return (0);
}
int
-lapic_set_local_intr(struct vm *vm, int cpu, int vector)
+lapic_set_local_intr(struct vm *vm, struct vcpu *vcpu, int vector)
{
struct vlapic *vlapic;
cpuset_t dmask;
- int error;
+ int cpu, error;
- if (cpu < -1 || cpu >= vm_get_maxcpus(vm))
- return (EINVAL);
-
- if (cpu == -1)
+ if (vcpu == NULL) {
+ error = 0;
dmask = vm_active_cpus(vm);
- else
- CPU_SETOF(cpu, &dmask);
- error = 0;
- CPU_FOREACH_ISSET(cpu, &dmask) {
- vlapic = vm_lapic(vm_vcpu(vm, cpu));
+ CPU_FOREACH_ISSET(cpu, &dmask) {
+ vlapic = vm_lapic(vm_vcpu(vm, cpu));
+ error = vlapic_trigger_lvt(vlapic, vector);
+ if (error)
+ break;
+ }
+ } else {
+ vlapic = vm_lapic(vcpu);
error = vlapic_trigger_lvt(vlapic, vector);
- if (error)
- break;
}
return (error);
diff --git a/sys/amd64/vmm/vmm_stat.h b/sys/amd64/vmm/vmm_stat.h
--- a/sys/amd64/vmm/vmm_stat.h
+++ b/sys/amd64/vmm/vmm_stat.h
@@ -45,7 +45,7 @@
};
struct vmm_stat_type;
-typedef void (*vmm_stat_func_t)(struct vm *vm, int vcpu,
+typedef void (*vmm_stat_func_t)(struct vcpu *vcpu,
struct vmm_stat_type *stat);
struct vmm_stat_type {
@@ -87,7 +87,7 @@
void vmm_stat_init(void *vp);
void vmm_stat_free(void *vp);
-int vmm_stat_copy(struct vm *vm, int vcpu, int index, int count,
+int vmm_stat_copy(struct vcpu *vcpu, int index, int count,
int *num_stats, uint64_t *buf);
int vmm_stat_desc_copy(int index, char *buf, int buflen);
diff --git a/sys/amd64/vmm/vmm_stat.c b/sys/amd64/vmm/vmm_stat.c
--- a/sys/amd64/vmm/vmm_stat.c
+++ b/sys/amd64/vmm/vmm_stat.c
@@ -82,16 +82,13 @@
}
int
-vmm_stat_copy(struct vm *vm, int vcpu, int index, int count, int *num_stats,
+vmm_stat_copy(struct vcpu *vcpu, int index, int count, int *num_stats,
uint64_t *buf)
{
struct vmm_stat_type *vst;
uint64_t *stats;
int i, tocopy;
- if (vcpu < 0 || vcpu >= vm_get_maxcpus(vm))
- return (EINVAL);
-
if (index < 0 || count < 0)
return (EINVAL);
@@ -109,11 +106,11 @@
for (i = 0; i < vst_num_types; i++) {
vst = vsttab[i];
if (vst->func != NULL)
- (*vst->func)(vm, vcpu, vst);
+ (*vst->func)(vcpu, vst);
}
/* Copy over the stats */
- stats = vcpu_stats(vm_vcpu(vm, vcpu));
+ stats = vcpu_stats(vcpu);
memcpy(buf, stats + index, tocopy * sizeof(stats[0]));
*num_stats = tocopy;
return (0);
diff --git a/sys/amd64/vmm/x86.c b/sys/amd64/vmm/x86.c
--- a/sys/amd64/vmm/x86.c
+++ b/sys/amd64/vmm/x86.c
@@ -204,7 +204,7 @@
regs[2] &= ~AMDID2_MWAITX;
/* Advertise RDTSCP if it is enabled. */
- error = vm_get_capability(vm, vcpu_id,
+ error = vm_get_capability(vcpu,
VM_CAP_RDTSCP, &enable_rdtscp);
if (error == 0 && enable_rdtscp)
regs[3] |= AMDID_RDTSCP;
@@ -311,7 +311,7 @@
case CPUID_0000_0001:
do_cpuid(1, regs);
- error = vm_get_x2apic_state(vm, vcpu_id, &x2apic_state);
+ error = vm_get_x2apic_state(vcpu, &x2apic_state);
if (error) {
panic("x86_emulate_cpuid: error %d "
"fetching x2apic state", error);
@@ -456,13 +456,13 @@
regs[3] &= CPUID_STDEXT3_MD_CLEAR;
/* Advertise RDPID if it is enabled. */
- error = vm_get_capability(vm, vcpu_id,
- VM_CAP_RDPID, &enable_rdpid);
+ error = vm_get_capability(vcpu, VM_CAP_RDPID,
+ &enable_rdpid);
if (error == 0 && enable_rdpid)
regs[2] |= CPUID_STDEXT2_RDPID;
/* Advertise INVPCID if it is enabled. */
- error = vm_get_capability(vm, vcpu_id,
+ error = vm_get_capability(vcpu,
VM_CAP_ENABLE_INVPCID, &enable_invpcid);
if (error == 0 && enable_invpcid)
regs[1] |= CPUID_STDEXT_INVPCID;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 16, 11:48 AM (10 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27660378
Default Alt Text
D37168.diff (39 KB)
Attached To
Mode
D37168: vmm: Lookup vcpu pointers in vmmdev_ioctl.
Attached
Detach File
Event Timeline
Log In to Comment