Deleted Added
full compact
28c28
< __FBSDID("$FreeBSD: projects/bhyve_svm/sys/amd64/vmm/amd/svm.c 270511 2014-08-25 00:58:20Z neel $");
---
> __FBSDID("$FreeBSD: projects/bhyve_svm/sys/amd64/vmm/amd/svm.c 270962 2014-09-02 04:22:42Z neel $");
120c120,121
< static VMM_STAT_AMD(VCPU_EXITINTINFO, "Valid EXITINTINFO");
---
> static VMM_STAT_AMD(VCPU_EXITINTINFO, "Valid VMCB EXITINTINFO");
> static VMM_STAT_AMD(VCPU_INTINFO_INJECTED, "VMM pending exception injected");
489c490
< svm_vcpu_mode(uint64_t efer)
---
> svm_vcpu_mode(struct vmcb *vmcb)
490a492,493
> struct vmcb_segment *seg;
> struct vmcb_state *state;
492,495c495,511
< if (efer & EFER_LMA)
< return (CPU_MODE_64BIT);
< else
< return (CPU_MODE_COMPATIBILITY);
---
> state = &vmcb->state;
>
> if (state->efer & EFER_LMA) {
> seg = vmcb_seg(vmcb, VM_REG_GUEST_CS);
> /*
> * Section 4.8.1 for APM2, check if Code Segment has
> * Long attribute set in descriptor.
> */
> if (seg->attrib & VMCB_CS_ATTRIB_L)
> return (CPU_MODE_64BIT);
> else
> return (CPU_MODE_COMPATIBILITY);
> } else if (state->cr0 & CR0_PE) {
> return (CPU_MODE_PROTECTED);
> } else {
> return (CPU_MODE_REAL);
> }
572c588
< svm_paging_info(struct vmcb_state *state, struct vm_guest_paging *paging)
---
> svm_paging_info(struct vmcb *vmcb, struct vm_guest_paging *paging)
573a590
> struct vmcb_state *state;
574a592
> state = &vmcb->state;
577c595
< paging->cpu_mode = svm_vcpu_mode(state->efer);
---
> paging->cpu_mode = svm_vcpu_mode(vmcb);
579c597
< state->efer);
---
> state->efer);
581a600
>
610c629
< svm_paging_info(state, &vis->paging);
---
> svm_paging_info(svm_get_vmcb(svm_sc, vcpu), &vis->paging);
651a671,705
> static void
> svm_handle_inst_emul(struct vmcb *vmcb, uint64_t gpa, struct vm_exit *vmexit)
> {
> struct vm_guest_paging *paging;
> struct vmcb_segment *seg;
>
> paging = &vmexit->u.inst_emul.paging;
> vmexit->exitcode = VM_EXITCODE_INST_EMUL;
> vmexit->u.inst_emul.gpa = gpa;
> vmexit->u.inst_emul.gla = VIE_INVALID_GLA;
> svm_paging_info(vmcb, paging);
>
> /*
> * If DecodeAssist SVM feature doesn't exist, we don't have NPF
> * instuction length. RIP will be calculated based on the length
> * determined by instruction emulation.
> */
> vmexit->inst_length = VIE_INST_SIZE;
>
> seg = vmcb_seg(vmcb, VM_REG_GUEST_CS);
> switch(paging->cpu_mode) {
> case CPU_MODE_PROTECTED:
> case CPU_MODE_COMPATIBILITY:
> /*
> * Section 4.8.1 of APM2, Default Operand Size or D bit.
> */
> vmexit->u.inst_emul.cs_d = (seg->attrib & VMCB_CS_ATTRIB_D) ?
> 1 : 0;
> break;
> default:
> vmexit->u.inst_emul.cs_d = 0;
> break;
> }
> }
>
674a729,751
> static void
> svm_save_intinfo(struct svm_softc *svm_sc, int vcpu)
> {
> struct vmcb_ctrl *ctrl;
> uint64_t intinfo;
>
> ctrl = svm_get_vmcb_ctrl(svm_sc, vcpu);
> intinfo = ctrl->exitintinfo;
> if (!VMCB_EXITINTINFO_VALID(intinfo))
> return;
>
> /*
> * From APMv2, Section "Intercepts during IDT interrupt delivery"
> *
> * If a #VMEXIT happened during event delivery then record the event
> * that was being delivered.
> */
> VCPU_CTR2(svm_sc->vm, vcpu, "SVM:Pending INTINFO(0x%lx), vector=%d.\n",
> intinfo, VMCB_EXITINTINFO_VECTOR(intinfo));
> vmm_stat_incr(svm_sc->vm, vcpu, VCPU_EXITINTINFO, 1);
> vm_exit_intinfo(svm_sc->vm, vcpu, intinfo);
> }
>
707a785,786
> svm_save_intinfo(svm_sc, vcpu);
>
785d863
< update_rip = true;
850,867c928,929
< vmexit->exitcode = VM_EXITCODE_INST_EMUL;
< vmexit->u.inst_emul.gpa = info2;
< vmexit->u.inst_emul.gla = VIE_INVALID_GLA;
< vmexit->u.inst_emul.paging.cr3 = state->cr3;
< vmexit->u.inst_emul.paging.cpu_mode =
< svm_vcpu_mode(state->efer);
< vmexit->u.inst_emul.paging.paging_mode =
< svm_paging_mode(state->cr0, state->cr4,
< state->efer);
< /* XXX: get CPL from SS */
< vmexit->u.inst_emul.paging.cpl = 0;
< /*
< * If DecodeAssist SVM feature doesn't exist,
< * we don't have faulty instuction length. New
< * RIP will be calculated based on software
< * instruction emulation.
< */
< vmexit->inst_length = VIE_INST_SIZE;
---
> svm_handle_inst_emul(svm_get_vmcb(svm_sc, vcpu),
> info2, vmexit);
946a1009,1030
> static void
> svm_inj_intinfo(struct svm_softc *svm_sc, int vcpu)
> {
> struct vmcb_ctrl *ctrl;
> uint64_t intinfo;
>
> ctrl = svm_get_vmcb_ctrl(svm_sc, vcpu);
>
> if (!vm_entry_intinfo(svm_sc->vm, vcpu, &intinfo))
> return;
>
> KASSERT(VMCB_EXITINTINFO_VALID(intinfo), ("%s: entry intinfo is not "
> "valid: %#lx", __func__, intinfo));
>
> vmcb_eventinject(ctrl, VMCB_EXITINTINFO_TYPE(intinfo),
> VMCB_EXITINTINFO_VECTOR(intinfo),
> VMCB_EXITINTINFO_EC(intinfo),
> VMCB_EXITINTINFO_EC_VALID(intinfo));
> vmm_stat_incr(svm_sc->vm, vcpu, VCPU_INTINFO_INJECTED, 1);
> VCPU_CTR1(svm_sc->vm, vcpu, "Injected entry intinfo: %#lx", intinfo);
> }
>
955d1038
< struct vm_exception exc;
964,969c1047
< if (vm_exception_pending(svm_sc->vm, vcpu, &exc)) {
< KASSERT(exc.vector >= 0 && exc.vector < 32,
< ("Exception vector% invalid", exc.vector));
< vmcb_eventinject(ctrl, VMCB_EVENTINJ_TYPE_EXCEPTION, exc.vector,
< exc.error_code, exc.error_code_valid);
< }
---
> svm_inj_intinfo(svm_sc, vcpu);
1047,1071d1124
< static void
< svm_handle_exitintinfo(struct svm_softc *svm_sc, int vcpu)
< {
< struct vmcb_ctrl *ctrl;
< uint64_t intinfo;
<
< ctrl = svm_get_vmcb_ctrl(svm_sc, vcpu);
<
< /*
< * VMEXIT while delivering an exception or interrupt.
< * Inject it as virtual interrupt.
< * Section 15.7.2 Intercepts during IDT interrupt delivery.
< */
< intinfo = ctrl->exitintinfo;
<
< if (VMCB_EXITINTINFO_VALID(intinfo)) {
< vmm_stat_incr(svm_sc->vm, vcpu, VCPU_EXITINTINFO, 1);
< VCPU_CTR1(svm_sc->vm, vcpu, "SVM:EXITINTINFO:0x%lx is valid\n",
< intinfo);
< vmcb_eventinject(ctrl, VMCB_EXITINTINFO_TYPE(intinfo),
< VMCB_EXITINTINFO_VECTOR(intinfo),
< VMCB_EXITINTINFO_EC(intinfo),
< VMCB_EXITINTINFO_EC_VALID(intinfo));
< }
< }
1109,1110c1162,1164
< * Flush all TLB mapping for this guest on this CPU,
< * it might have stale entries.
---
> * Flush all TLB mappings for this guest on this CPU,
> * it might have stale entries since vcpu has migrated
> * or vmm is restarted.
1188,1189d1241
< svm_handle_exitintinfo(svm_sc, vcpu);
<