VirtualBox

Changeset 47123 in vbox


Ignore:
Timestamp:
Jul 12, 2013 3:31:44 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
87217
Message:

VMM/HM: Dispatch host NMIs on Intel. Added separate STAM counter for host NMIs with the necessary changes to old, new VT-x, AMD-V code.

Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/hm_vmx.h

    r47109 r47123  
    15271527
    15281528
    1529 #if RT_INLINE_ASM_GNU_STYLE
    1530 # define __STR(x)   #x
    1531 # define STR(x)     __STR(x)
    1532 #endif
    1533 
    1534 
    15351529/** @defgroup grp_vmx_asm   vmx assembly helpers
    15361530 * @ingroup grp_vmx
     
    15471541 */
    15481542DECLASM(int) VMXRestoreHostState(uint32_t fRestoreHostFlags, PVMXRESTOREHOST pRestoreHost);
     1543
     1544
     1545/**
     1546 * Dispatches an NMI to the host.
     1547 */
     1548DECLASM(int) VMXDispatchHostNmi(void);
    15491549
    15501550
     
    15681568       "ja       2f                                             \n\t"
    15691569       "je       1f                                             \n\t"
    1570        "movl     $"STR(VERR_VMX_INVALID_VMXON_PTR)", %0         \n\t"
     1570       "movl     $"RT_XSTR(VERR_VMX_INVALID_VMXON_PTR)", %0     \n\t"
    15711571       "jmp      2f                                             \n\t"
    15721572       "1:                                                      \n\t"
    1573        "movl     $"STR(VERR_VMX_VMXON_FAILED)", %0              \n\t"
     1573       "movl     $"RT_XSTR(VERR_VMX_VMXON_FAILED)", %0          \n\t"
    15741574       "2:                                                      \n\t"
    15751575       "add      $8, %%esp                                      \n\t"
     
    16481648       ".byte   0x66, 0x0F, 0xC7, 0x34, 0x24  # VMCLEAR [esp]   \n\t"
    16491649       "jnc     1f                                              \n\t"
    1650        "movl    $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0           \n\t"
     1650       "movl    $"RT_XSTR(VERR_VMX_INVALID_VMCS_PTR)", %0       \n\t"
    16511651       "1:                                                      \n\t"
    16521652       "add     $8, %%esp                                       \n\t"
     
    16961696       ".byte   0x0F, 0xC7, 0x34, 0x24  # VMPTRLD [esp]         \n\t"
    16971697       "jnc     1f                                              \n\t"
    1698        "movl    $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0           \n\t"
     1698       "movl    $"RT_XSTR(VERR_VMX_INVALID_VMCS_PTR)", %0       \n\t"
    16991699       "1:                                                      \n\t"
    17001700       "add     $8, %%esp                                       \n\t"
     
    17501750       "ja     2f                                               \n\t"
    17511751       "je     1f                                               \n\t"
    1752        "movl   $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0            \n\t"
     1752       "movl   $"RT_XSTR(VERR_VMX_INVALID_VMCS_PTR)", %0        \n\t"
    17531753       "jmp    2f                                               \n\t"
    17541754       "1:                                                      \n\t"
    1755        "movl   $"STR(VERR_VMX_INVALID_VMCS_FIELD)", %0          \n\t"
     1755       "movl   $"RT_XSTR(VERR_VMX_INVALID_VMCS_FIELD)", %0      \n\t"
    17561756       "2:                                                      \n\t"
    17571757       :"=rm"(rc)
     
    18541854# if RT_INLINE_ASM_GNU_STYLE
    18551855    __asm__ __volatile__ (
    1856        "movl   $"STR(VINF_SUCCESS)", %0                          \n\t"
     1856       "movl   $"RT_XSTR(VINF_SUCCESS)", %0                      \n\t"
    18571857       ".byte  0x0F, 0x78, 0xc2        # VMREAD eax, edx         \n\t"
    18581858       "ja     2f                                                \n\t"
    18591859       "je     1f                                                \n\t"
    1860        "movl   $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0             \n\t"
     1860       "movl   $"RT_XSTR(VERR_VMX_INVALID_VMCS_PTR)", %0         \n\t"
    18611861       "jmp    2f                                                \n\t"
    18621862       "1:                                                       \n\t"
    1863        "movl   $"STR(VERR_VMX_INVALID_VMCS_FIELD)", %0           \n\t"
     1863       "movl   $"RT_XSTR(VERR_VMX_INVALID_VMCS_FIELD)", %0       \n\t"
    18641864       "2:                                                       \n\t"
    18651865       :"=&r"(rc),
  • trunk/include/VBox/vmm/vm.h

    r46833 r47123  
    149149        struct HMCPU    s;
    150150#endif
    151         uint8_t             padding[5504];      /* multiple of 64 */
     151        uint8_t             padding[5568];      /* multiple of 64 */
    152152    } hm;
    153153
     
    226226
    227227    /** Align the following members on page boundary. */
    228     uint8_t                 abAlignment2[256];
     228    uint8_t                 abAlignment2[192];
    229229
    230230    /** PGM part. */
  • trunk/include/VBox/vmm/vm.mac

    r46268 r47123  
    135135
    136136    .cpum                   resb 3584
    137     .hm                     resb 5504
     137    .hm                     resb 5568
    138138    .em                     resb 1472
    139139    .iem                    resb 3072
  • trunk/src/VBox/VMM/VMMR0/HMR0A.asm

    r46942 r47123  
    373373    ret
    374374ENDPROC VMXRestoreHostState
     375
     376
     377;/**
     378; * Dispatches an NMI to the host.
     379; */
     380ALIGNCODE(16)
     381BEGINPROC VMXDispatchHostNmi
     382    int 2   ; NMI is always vector 2. The IDT[2] IRQ handler cannot be anything else. See Intel spec. 6.3.1 "External Interrupts".
     383    ret
     384ENDPROC VMXDispatchHostNmi
    375385
    376386
  • trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp

    r47119 r47123  
    35323532{
    35333533    HMSVM_VALIDATE_EXIT_HANDLER_PARAMS();
    3534     STAM_COUNTER_INC(&pVCpu->hm.s.StatExitExtInt);
     3534
     3535#ifdef VBOX_WITH_STATISTICS
     3536    if (pSvmTransient->u64ExitCode == SVM_EXIT_NMI)
     3537        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitHostNmi);
     3538    else if (pSvmTransient->u64ExitCode == SVM_EXIT_INTR)
     3539        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitExtInt);
     3540#endif
    35353541
    35363542    /*
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r47110 r47123  
    73657365    if (uIntrType == VMX_EXIT_INTERRUPTION_INFO_TYPE_NMI)
    73667366    {
    7367         /** @todo We should inject the NMI to the host by calling the NMI
    7368          *  interrupt handler! See Intel spec. 27.5.5 "Updating Non-Register State". */
     7367        /*
     7368         * This cannot be a guest NMI as the only way for the guest to receive an NMI is if we injected it ourselves and
     7369         * anything we inject is not going to cause a VM-exit directly for the event being injected.
     7370         * See Intel spec. 27.2.3 "Information for VM Exits During Event Delivery".
     7371         *
     7372         * Dispatch the NMI to the host. See Intel spec. 27.5.5 "Updating Non-Register State".
     7373         */
     7374        VMXDispatchHostNmi();
     7375        STAM_COUNTER_INC(&pVCpu->hm.s.StatExitHostNmi);
    73697376        STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExitXcptNmi, y3);
    7370         return VINF_EM_RAW_INTERRUPT;
     7377        return VINF_SUCCESS;
    73717378    }
    73727379
     
    74347441                    {
    74357442                        AssertMsgFailed(("Unexpected VM-exit caused by exception %#x\n", uVector));
     7443                        pVCpu->hm.s.u32HMError = uVector;
    74367444                        rc = VERR_VMX_UNEXPECTED_EXCEPTION;
    74377445                    }
     
    74427450        }
    74437451
    7444         case VMX_EXIT_INTERRUPTION_INFO_TYPE_DB_XCPT:
    74457452        default:
    74467453        {
     7454            pVCpu->hm.s.u32HMError = uExitIntrInfo;
    74477455            rc = VERR_VMX_UNEXPECTED_INTERRUPTION_EXIT_CODE;
    74487456            AssertMsgFailed(("Unexpected interruption code %#x\n", VMX_EXIT_INTERRUPTION_INFO_TYPE(uExitIntrInfo)));
  • trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp

    r46871 r47123  
    22292229        goto ResumeExecution;
    22302230
    2231     case SVM_EXIT_INTR:         STAM_COUNTER_INC(&pVCpu->hm.s.StatExitExtInt);  /* no break */
     2231    case SVM_EXIT_INTR:
    22322232    case SVM_EXIT_FERR_FREEZE:
    22332233    case SVM_EXIT_NMI:
    22342234    case SVM_EXIT_SMI:
    22352235    case SVM_EXIT_INIT:
     2236#ifdef VBOX_WITH_STATISTICS
     2237        if (vector == SVM_EXIT_INTR)
     2238            STAM_COUNTER_INC(&pVCpu->hm.s.StatExitExtInt);
     2239        else if (vector == SVM_EXIT_NMI)
     2240            STAM_COUNTER_INC(&pVCpu->hm.s.StatExitHostNmi);
     2241#endif
    22362242        /* External interrupt; leave to allow it to be dispatched again. */
    22372243        rc = VINF_EM_RAW_INTERRUPT;
  • trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp

    r47109 r47123  
    35353535        case VMX_EXIT_INTERRUPTION_INFO_TYPE_NMI:       /* Non-maskable interrupt. */
    35363536            /* External interrupt; leave to allow it to be dispatched again. */
     3537            STAM_COUNTER_INC(&pVCpu->hm.s.StatExitHostNmi);
    35373538            rc = VINF_EM_RAW_INTERRUPT;
    35383539            break;
  • trunk/src/VBox/VMM/VMMR3/HM.cpp

    r47109 r47123  
    682682        HM_REG_COUNTER(&pVCpu->hm.s.StatExitMaxResume,          "/HM/CPU%d/Exit/MaxResume", "Maximum VMRESUME inner-loop counter reached.");
    683683        HM_REG_COUNTER(&pVCpu->hm.s.StatExitExtInt,             "/HM/CPU%d/Exit/ExtInt", "Host interrupt received.");
     684        HM_REG_COUNTER(&pVCpu->hm.s.StatExitHostNmi,            "/HM/CPU%d/Exit/HostNmi", "Host NMI received.");
    684685        HM_REG_COUNTER(&pVCpu->hm.s.StatExitPreemptTimer,       "/HM/CPU%d/Exit/PreemptTimer", "VMX-preemption timer expired.");
    685686        HM_REG_COUNTER(&pVCpu->hm.s.StatExitTprBelowThreshold,  "/HM/CPU%d/Exit/TprBelowThreshold", "TPR lowered below threshold by the guest.");
  • trunk/src/VBox/VMM/include/HMInternal.h

    r47090 r47123  
    849849    STAMCOUNTER             StatExitMaxResume;
    850850    STAMCOUNTER             StatExitExtInt;
     851    STAMCOUNTER             StatExitHostNmi;
    851852    STAMCOUNTER             StatExitPreemptTimer;
    852853    STAMCOUNTER             StatExitTprBelowThreshold;
Note: See TracChangeset for help on using the changeset viewer.

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