VirtualBox

Changeset 15852 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jan 8, 2009 10:56:11 AM (16 years ago)
Author:
vboxsync
Message:

Another experiment with limiting the time spent in ring 0.

Location:
trunk/src/VBox/VMM
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/HWACCMInternal.h

    r15702 r15852  
    435435typedef struct HWACCMCPU
    436436{
     437    /** Time of entry into the ring 0 world switcher code. */
     438    uint64_t                    u64TimeEntry;
     439
    437440    /** Old style FPU reporting trap mask override performed (optimization) */
    438441    bool                        fFPUOldStyleOverride;
  • trunk/src/VBox/VMM/VMM.cpp

    r15508 r15852  
    14261426            LogRel((pVM->vmm.s.szRing0AssertMsg2));
    14271427            return VERR_VMM_RING0_ASSERTION;
     1428
     1429        /*
     1430         * A forced switch to ring 0 for preemption purposes.
     1431         */
     1432        case VMMCALLHOST_VM_R0_PREEMPT:
     1433            pVM->vmm.s.rcCallHost = VINF_SUCCESS;
     1434            break;
    14281435
    14291436        default:
  • trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp

    r15749 r15852  
    3939#include <iprt/asm.h>
    4040#include <iprt/string.h>
     41#include <iprt/time.h>
    4142#include "HWVMXR0.h"
    4243
     
    18931894    RTGCUINTPTR errCode, instrInfo;
    18941895    bool        fSyncTPR = false;
     1896    bool        fPreemptPending = false;
    18951897    PHWACCM_CPUINFO pCpu = 0;
    18961898    unsigned    cResume = 0;
     
    19661968    }
    19671969#endif
     1970
     1971    /* Fetch the current time so we can bail out when necessary. */
     1972    pVCpu->hwaccm.s.u64TimeEntry = RTTimeNanoTS();
    19681973
    19691974    /* We can jump to this point to resume execution after determining that a VM-exit is innocent.
     
    19801985
    19811986    /* Safety precaution; looping for too long here can have a very bad effect on the host */
    1982     if (++cResume > HWACCM_MAX_RESUME_LOOPS)
     1987    if (    ++cResume > HWACCM_MAX_RESUME_LOOPS
     1988        ||  RTTimeNanoTS() - pVCpu->hwaccm.s.u64TimeEntry >= 2000000)
    19831989    {
    19841990        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitMaxResume);
     
    21572163    STAM_PROFILE_ADV_START(&pVCpu->hwaccm.s.StatExit1, v);
    21582164
    2159     if (rc != VINF_SUCCESS)
     2165    if (VBOX_FAILURE(rc))
    21602166    {
    21612167        VMXR0ReportWorldSwitchError(pVM, pVCpu, rc, pCtx);
    21622168        goto end;
    21632169    }
     2170    if (rc == VINF_VMX_PREEMPT_PENDING)
     2171        fPreemptPending = true;
     2172
    21642173    /* Success. Query the guest state and figure out what has happened. */
    21652174
     
    22362245    {
    22372246        rc = PDMApicSetTPR(pVM, pVM->hwaccm.s.vmx.pAPIC[0x80] >> 4);
     2247        AssertRC(rc);
     2248    }
     2249
     2250    if (fPreemptPending)
     2251    {
     2252        fPreemptPending = false;
     2253        rc = VMMR0CallHost(pVM, VMMCALLHOST_VM_R0_PREEMPT, 0);
    22382254        AssertRC(rc);
    22392255    }
     
    30093025
    30103026    case VMX_EXIT_PREEMPTION_TIMER:     /* 52 VMX-preemption timer expired. The preemption timer counted down to zero. */
    3011 #ifdef RT_OS_WINDOWS
    30123027        goto ResumeExecution;
    3013 #else
    3014         break; /* enable interrupts again */
    3015 #endif
    30163028
    30173029    default:
     
    35833595    aParam[5] = 0;
    35843596
    3585     if (pVM->hwaccm.s.vmx.msr.vmx_pin_ctls.n.allowed1 & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER)
    3586     {
    3587         uint32_t uBit, val;
    3588 
    3589         rc = VMXReadVMCS32(VMX_VMCS_CTRL_PIN_EXEC_CONTROLS, &val);
    3590         AssertRC(rc);
    3591         val  = val | VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER;
    3592         rc = VMXWriteVMCS(VMX_VMCS_CTRL_PIN_EXEC_CONTROLS, val);
    3593         AssertRC(rc);
    3594 
    3595         uBit = MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(pVM->hwaccm.s.vmx.msr.vmx_misc);
    3596         val = 1000000 / RT_BIT(uBit);
    3597         VMXWriteVMCS(VMX_VMCS32_GUEST_PREEMPTION_TIMER_VALUE, val);
    3598     }
    3599 
    36003597    rc = VMXR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hwaccm.s.pfnVMXGCStartVM64, 6, &aParam[0]);
    3601 
    3602     if (pVM->hwaccm.s.vmx.msr.vmx_pin_ctls.n.allowed1 & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER)
    3603     {
    3604         uint32_t val;
    3605 
    3606         rc = VMXReadVMCS32(VMX_VMCS_CTRL_PIN_EXEC_CONTROLS, &val);
    3607         AssertRC(rc);
    3608         val  = val & ~VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER;
    3609         rc = VMXWriteVMCS(VMX_VMCS_CTRL_PIN_EXEC_CONTROLS, val);
    3610         AssertRC(rc);
    3611     }
    36123598
    36133599#ifdef DEBUG
     
    36213607#endif
    36223608
     3609    /* Check if we've been running too long. */
     3610    if (    rc == VINF_SUCCESS
     3611        &&  RTTimeNanoTS() - pVM->hwaccm.s.u64TimeEntry >= 2000000
     3612    {
     3613        return VINF_VMX_PREEMPT_PENDING;
     3614    }
    36233615    return rc;
    36243616}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette