* Write to segment selector, control and general purpose register of VMCB. */
| 251 | * Write to segment selector, control and general purpose register of VMCB. |
| 252 | */ |
| 253 | int |
| 254 | vmcb_write(struct svm_softc *sc, int vcpu, int ident, uint64_t val) |
| 255 | { |
| 256 | struct vmcb *vmcb; |
| 257 | struct vmcb_state *state; |
| 258 | struct vmcb_segment *seg; |
| 259 | int err, dirtyseg; |
| 260 | |
| 261 | vmcb = svm_get_vmcb(sc, vcpu); |
| 262 | state = &vmcb->state; |
| 263 | dirtyseg = 0; |
| 264 | err = 0; |
| 265 | |
| 266 | if (VMCB_ACCESS_OK(ident)) |
| 267 | return (vmcb_access(sc, vcpu, 1, ident, &val)); |
| 268 | |
| 269 | switch (ident) { |
| 270 | case VM_REG_GUEST_CR0: |
| 271 | state->cr0 = val; |
| 272 | svm_set_dirty(sc, vcpu, VMCB_CACHE_CR); |
| 273 | break; |
| 274 | |
| 275 | case VM_REG_GUEST_CR2: |
| 276 | state->cr2 = val; |
| 277 | svm_set_dirty(sc, vcpu, VMCB_CACHE_CR2); |
| 278 | break; |
| 279 | |
| 280 | case VM_REG_GUEST_CR3: |
| 281 | state->cr3 = val; |
| 282 | svm_set_dirty(sc, vcpu, VMCB_CACHE_CR); |
| 283 | break; |
| 284 | |
| 285 | case VM_REG_GUEST_CR4: |
| 286 | state->cr4 = val; |
| 287 | svm_set_dirty(sc, vcpu, VMCB_CACHE_CR); |
| 288 | break; |
| 289 | |
| 290 | case VM_REG_GUEST_DR6: |
| 291 | state->dr6 = val; |
| 292 | svm_set_dirty(sc, vcpu, VMCB_CACHE_DR); |
| 293 | break; |
| 294 | |
| 295 | case VM_REG_GUEST_DR7: |
| 296 | state->dr7 = val; |
| 297 | svm_set_dirty(sc, vcpu, VMCB_CACHE_DR); |
| 298 | break; |
| 299 | |
| 300 | case VM_REG_GUEST_EFER: |
| 301 | /* EFER_SVM must always be set when the guest is executing */ |
| 302 | state->efer = val | EFER_SVM; |
| 303 | svm_set_dirty(sc, vcpu, VMCB_CACHE_CR); |
| 304 | break; |
| 305 | |
| 306 | case VM_REG_GUEST_RAX: |
| 307 | state->rax = val; |
| 308 | break; |
| 309 | |
| 310 | case VM_REG_GUEST_RFLAGS: |
no test coverage detected