| 1172 | static VMM_STAT(VCPU_IDLE_TICKS, "number of ticks vcpu was idle"); |
| 1173 | |
| 1174 | static int |
| 1175 | vcpu_set_state_locked(struct vm *vm, int vcpuid, enum vcpu_state newstate, |
| 1176 | bool from_idle) |
| 1177 | { |
| 1178 | struct vcpu *vcpu; |
| 1179 | int error; |
| 1180 | |
| 1181 | vcpu = &vm->vcpu[vcpuid]; |
| 1182 | vcpu_assert_locked(vcpu); |
| 1183 | |
| 1184 | /* |
| 1185 | * State transitions from the vmmdev_ioctl() must always begin from |
| 1186 | * the VCPU_IDLE state. This guarantees that there is only a single |
| 1187 | * ioctl() operating on a vcpu at any point. |
| 1188 | */ |
| 1189 | if (from_idle) { |
| 1190 | while (vcpu->state != VCPU_IDLE) { |
| 1191 | vcpu->reqidle = 1; |
| 1192 | vcpu_notify_event_locked(vcpu, false); |
| 1193 | VCPU_CTR1(vm, vcpuid, "vcpu state change from %s to " |
| 1194 | "idle requested", vcpu_state2str(vcpu->state)); |
| 1195 | msleep_spin(&vcpu->state, &vcpu->mtx, "vmstat", hz); |
| 1196 | } |
| 1197 | } else { |
| 1198 | KASSERT(vcpu->state != VCPU_IDLE, ("invalid transition from " |
| 1199 | "vcpu idle state")); |
| 1200 | } |
| 1201 | |
| 1202 | if (vcpu->state == VCPU_RUNNING) { |
| 1203 | KASSERT(vcpu->hostcpu == curcpu, ("curcpu %d and hostcpu %d " |
| 1204 | "mismatch for running vcpu", curcpu, vcpu->hostcpu)); |
| 1205 | } else { |
| 1206 | KASSERT(vcpu->hostcpu == NOCPU, ("Invalid hostcpu %d for a " |
| 1207 | "vcpu that is not running", vcpu->hostcpu)); |
| 1208 | } |
| 1209 | |
| 1210 | /* |
| 1211 | * The following state transitions are allowed: |
| 1212 | * IDLE -> FROZEN -> IDLE |
| 1213 | * FROZEN -> RUNNING -> FROZEN |
| 1214 | * FROZEN -> SLEEPING -> FROZEN |
| 1215 | */ |
| 1216 | switch (vcpu->state) { |
| 1217 | case VCPU_IDLE: |
| 1218 | case VCPU_RUNNING: |
| 1219 | case VCPU_SLEEPING: |
| 1220 | error = (newstate != VCPU_FROZEN); |
| 1221 | break; |
| 1222 | case VCPU_FROZEN: |
| 1223 | error = (newstate == VCPU_FROZEN); |
| 1224 | break; |
| 1225 | default: |
| 1226 | error = 1; |
| 1227 | break; |
| 1228 | } |
| 1229 | |
| 1230 | if (error) |
| 1231 | return (EBUSY); |
no test coverage detected