~ubuntu-branches/ubuntu/vivid/virtualbox-ose/vivid

« back to all changes in this revision

Viewing changes to src/VBox/VMM/VMMR0/HWSVMR0.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2010-03-11 17:16:37 UTC
  • mfrom: (0.3.4 upstream) (0.4.8 sid)
  • Revision ID: james.westby@ubuntu.com-20100311171637-43z64ia3ccpj8vqn
Tags: 3.1.4-dfsg-2ubuntu1
* Merge from Debian unstable (LP: #528561), remaining changes:
  - VirtualBox should go in Accessories, not in System tools (LP: #288590)
    - debian/virtualbox-ose-qt.files/virtualbox-ose.desktop
  - Add Apport hook
    - debian/virtualbox-ose.files/source_virtualbox-ose.py
    - debian/virtualbox-ose.install
  - Add Launchpad integration
    - debian/control
    - debian/lpi-bug.xpm
    - debian/patches/u02-lp-integration.dpatch
  - Replace *-source packages with transitional packages for *-dkms
* Fix crash in vboxvideo_drm with kernel 2.6.33 / backported drm code
  (LP: #535297)
* Add a list of linux-headers packages to the apport hook
* Update debian/patches/u02-lp-integration.dpatch with a
  DEP-3 compliant header
* Add ${misc:Depends} to virtualbox-ose-source and virtualbox-ose-guest-source
  Depends

Show diffs side-by-side

added added

removed removed

Lines of Context:
77
77
    /* We must turn on AMD-V and setup the host state physical address, as those MSRs are per-cpu/core. */
78
78
    uint64_t val = ASMRdMsr(MSR_K6_EFER);
79
79
    if (val & MSR_K6_EFER_SVME)
80
 
        return VERR_SVM_IN_USE;
 
80
    {
 
81
        /* If the VBOX_HWVIRTEX_IGNORE_SVM_IN_USE hack is active, then we blindly use AMD-V. */
 
82
        if (    pVM
 
83
            &&  pVM->hwaccm.s.svm.fIgnoreInUseError)
 
84
        {
 
85
            pCpu->fIgnoreAMDVInUseError = true;
 
86
        }
 
87
 
 
88
        if (!pCpu->fIgnoreAMDVInUseError)
 
89
            return VERR_SVM_IN_USE;
 
90
    }
81
91
 
82
92
    /* Turn on AMD-V in the EFER MSR. */
83
93
    ASMWrMsr(MSR_K6_EFER, val | MSR_K6_EFER_SVME);
561
571
       )
562
572
    {
563
573
        uint8_t     u8Vector;
564
 
        int         rc;
565
574
        TRPMEVENT   enmType;
566
575
        SVM_EVENT   Event;
567
576
        RTGCUINT    u32ErrorCode;
1016
1025
#endif
1017
1026
 
1018
1027
    /* Check for pending actions that force us to go back to ring 3. */
 
1028
    if (    VM_FF_ISPENDING(pVM, VM_FF_HWACCM_TO_R3_MASK | VM_FF_REQUEST | VM_FF_PGM_POOL_FLUSH_PENDING)
 
1029
        ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HWACCM_TO_R3_MASK | VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL | VMCPU_FF_REQUEST))
 
1030
    {
 
1031
        /* Check if a sync operation is pending. */
 
1032
        if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL))
 
1033
        {
 
1034
            rc = PGMSyncCR3(pVCpu, pCtx->cr0, pCtx->cr3, pCtx->cr4, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3));
 
1035
            AssertRC(rc);
 
1036
            if (rc != VINF_SUCCESS)
 
1037
            {
 
1038
                Log(("Pending pool sync is forcing us back to ring 3; rc=%d\n", rc));
 
1039
                goto end;
 
1040
            }
 
1041
        }
 
1042
 
1019
1043
#ifdef DEBUG
1020
 
    /* Intercept X86_XCPT_DB if stepping is enabled */
1021
 
    if (!DBGFIsStepping(pVCpu))
 
1044
        /* Intercept X86_XCPT_DB if stepping is enabled */
 
1045
        if (!DBGFIsStepping(pVCpu))
1022
1046
#endif
1023
 
    {
1024
 
        if (    VM_FF_ISPENDING(pVM, VM_FF_HWACCM_TO_R3_MASK)
1025
 
            ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HWACCM_TO_R3_MASK))
1026
 
        {
1027
 
            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TO_R3);
1028
 
            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatSwitchToR3);
1029
 
            STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatEntry, x);
1030
 
            rc = RT_UNLIKELY(VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY)) ? VINF_EM_NO_MEMORY : VINF_EM_RAW_TO_R3;
1031
 
            goto end;
1032
 
        }
1033
 
    }
1034
 
 
1035
 
    /* Pending request packets might contain actions that need immediate attention, such as pending hardware interrupts. */
1036
 
    if (    VM_FF_ISPENDING(pVM, VM_FF_REQUEST)
1037
 
        ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_REQUEST))
1038
 
    {
1039
 
        STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatEntry, x);
1040
 
        rc = VINF_EM_PENDING_REQUEST;
1041
 
        goto end;
 
1047
        {
 
1048
            if (    VM_FF_ISPENDING(pVM, VM_FF_HWACCM_TO_R3_MASK)
 
1049
                ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HWACCM_TO_R3_MASK))
 
1050
            {
 
1051
                VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TO_R3);
 
1052
                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatSwitchToR3);
 
1053
                STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatEntry, x);
 
1054
                rc = RT_UNLIKELY(VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY)) ? VINF_EM_NO_MEMORY : VINF_EM_RAW_TO_R3;
 
1055
                goto end;
 
1056
            }
 
1057
        }
 
1058
 
 
1059
        /* Pending request packets might contain actions that need immediate attention, such as pending hardware interrupts. */
 
1060
        if (    VM_FF_ISPENDING(pVM, VM_FF_REQUEST)
 
1061
            ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_REQUEST))
 
1062
        {
 
1063
            STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatEntry, x);
 
1064
            rc = VINF_EM_PENDING_REQUEST;
 
1065
            goto end;
 
1066
        }
 
1067
 
 
1068
        /* Check if a pgm pool flush is in progress. */
 
1069
        if (VM_FF_ISPENDING(pVM, VM_FF_PGM_POOL_FLUSH_PENDING))
 
1070
        {
 
1071
            STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatEntry, x);
 
1072
            rc = VINF_PGM_POOL_FLUSH_PENDING;
 
1073
            goto end;
 
1074
        }
1042
1075
    }
1043
1076
 
1044
1077
#ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION
1080
1113
        bool fPending;
1081
1114
 
1082
1115
        /* TPR caching in CR8 */
1083
 
        int rc = PDMApicGetTPR(pVCpu, &u8LastTPR, &fPending);
1084
 
        AssertRC(rc);
 
1116
        int rc2 = PDMApicGetTPR(pVCpu, &u8LastTPR, &fPending);
 
1117
        AssertRC(rc2);
1085
1118
 
1086
1119
        if (pVM->hwaccm.s.fTPRPatchingActive)
1087
1120
        {
1702
1735
                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitShadowPF);
1703
1736
 
1704
1737
                TRPMResetTrap(pVCpu);
1705
 
 
1706
1738
                STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit1, x);
1707
1739
                goto ResumeExecution;
1708
1740
            }
2025
2057
        default:
2026
2058
            AssertFailed();
2027
2059
        }
2028
 
        /* Check if a sync operation is pending. */
2029
 
        if (    rc == VINF_SUCCESS /* don't bother if we are going to ring 3 anyway */
2030
 
            &&  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL))
2031
 
        {
2032
 
            rc = PGMSyncCR3(pVCpu, pCtx->cr0, pCtx->cr3, pCtx->cr4, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3));
2033
 
            AssertRC(rc);
2034
 
 
2035
 
            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFlushTLBCRxChange);
2036
 
 
2037
 
            /* Must be set by PGMSyncCR3 */
2038
 
            AssertMsg(rc == VINF_SUCCESS || rc == VINF_PGM_SYNC_CR3 || PGMGetGuestMode(pVCpu) <= PGMMODE_PROTECTED || pVCpu->hwaccm.s.fForceTLBFlush,
2039
 
                      ("rc=%Rrc mode=%d fForceTLBFlush=%RTbool\n", rc, PGMGetGuestMode(pVCpu), pVCpu->hwaccm.s.fForceTLBFlush));
2040
 
        }
2041
2060
        if (rc == VINF_SUCCESS)
2042
2061
        {
2043
2062
            /* EIP has been updated already. */
2677
2696
     */
2678
2697
    rc = PGMInvalidatePage(pVCpu, addr);
2679
2698
    if (RT_SUCCESS(rc))
2680
 
    {
2681
 
        /* Manually invalidate the page for the VM's TLB. */
2682
 
        Log(("SVMR0InvlpgA %RGv ASID=%d\n", addr, uASID));
2683
 
        SVMR0InvlpgA(addr, uASID);
2684
2699
        return VINF_SUCCESS;
2685
 
    }
 
2700
 
2686
2701
    AssertRC(rc);
2687
2702
    return rc;
2688
2703
}
2724
2739
                Assert(cbOp == pDis->opsize);
2725
2740
                rc = svmR0InterpretInvlPg(pVCpu, pDis, pRegFrame, uASID);
2726
2741
                if (RT_SUCCESS(rc))
2727
 
                {
2728
2742
                    pRegFrame->rip += cbOp; /* Move on to the next instruction. */
2729
 
                }
 
2743
 
2730
2744
                return rc;
2731
2745
            }
2732
2746
        }