VirtualBox

Changeset 72415 in vbox


Ignore:
Timestamp:
Jun 1, 2018 8:29:34 PM (7 years ago)
Author:
vboxsync
Message:

NEM/win: More MSR work. Document IA32_APIC_BASE issues (no X2APIC, ++). bugref:9044

Location:
trunk
Files:
3 edited

Legend:

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

    r72207 r72415  
    877877#define CPUMCTX_EXTRN_OTHER_MSRS                UINT64_C(0x0000008000000000)
    878878
     879/** Mask of all the MSRs. */
     880#define CPUMCTX_EXTRN_ALL_MSRS                  (  CPUMCTX_EXTRN_EFER | CPUMCTX_EXTRN_KERNEL_GS_BASE | CPUMCTX_EXTRN_SYSCALL_MSRS \
     881                                                 | CPUMCTX_EXTRN_SYSENTER_MSRS | CPUMCTX_EXTRN_TSC_AUX | CPUMCTX_EXTRN_OTHER_MSRS)
     882
    879883/** Mask of bits the keepers can use for state tracking. */
    880884#define CPUMCTX_EXTRN_KEEPER_STATE_MASK         UINT64_C(0xffff000000000000)
  • trunk/src/VBox/VMM/VMMAll/NEMAllNativeTemplate-win.cpp.h

    r72412 r72415  
    23112311    {
    23122312        /*
    2313          * Handle writes.
     2313         * Get all the MSR state.  Since we're getting EFER, we also need to
     2314         * get CR0, CR4 and CR3.
    23142315         */
    2315         if (pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE)
    2316         {
    2317             rcStrict = CPUMSetGuestMsr(pVCpu, pMsg->MsrNumber, RT_MAKE_U64((uint32_t)pMsg->Rax, (uint32_t)pMsg->Rdx));
    2318             Log4(("MsrExit/%u: %04x:%08RX64/%s: WRMSR %08x, %08x:%08x -> %Rrc\n",
    2319                   pVCpu->idCpu, pMsg->Header.CsSegment.Selector, pMsg->Header.Rip, nemHCWinExecStateToLogStr(&pMsg->Header),
    2320                   pMsg->MsrNumber, (uint32_t)pMsg->Rax, (uint32_t)pMsg->Rdx, VBOXSTRICTRC_VAL(rcStrict) ));
    2321             if (rcStrict == VINF_SUCCESS)
     2316        nemHCWinCopyStateFromX64Header(pVCpu, pCtx, &pMsg->Header);
     2317        rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, pGVCpu, pCtx,
     2318                                                       CPUMCTX_EXTRN_ALL_MSRS | CPUMCTX_EXTRN_CR0
     2319                                                     | CPUMCTX_EXTRN_CR3 | CPUMCTX_EXTRN_CR4,
     2320                                                     "MSRs");
     2321        if (rcStrict == VINF_SUCCESS)
     2322        {
     2323
     2324            /*
     2325             * Handle writes.
     2326             */
     2327            if (pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE)
    23222328            {
    2323                 nemHCWinCopyStateFromX64Header(pVCpu, pCtx, &pMsg->Header);
    2324                 nemHCWinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pMsg->Header);
    2325                 return VINF_SUCCESS;
     2329                rcStrict = CPUMSetGuestMsr(pVCpu, pMsg->MsrNumber, RT_MAKE_U64((uint32_t)pMsg->Rax, (uint32_t)pMsg->Rdx));
     2330                Log4(("MsrExit/%u: %04x:%08RX64/%s: WRMSR %08x, %08x:%08x -> %Rrc\n",
     2331                      pVCpu->idCpu, pMsg->Header.CsSegment.Selector, pMsg->Header.Rip, nemHCWinExecStateToLogStr(&pMsg->Header),
     2332                      pMsg->MsrNumber, (uint32_t)pMsg->Rax, (uint32_t)pMsg->Rdx, VBOXSTRICTRC_VAL(rcStrict) ));
     2333                if (rcStrict == VINF_SUCCESS)
     2334                {
     2335                    nemHCWinCopyStateFromX64Header(pVCpu, pCtx, &pMsg->Header);
     2336                    nemHCWinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pMsg->Header);
     2337                    return VINF_SUCCESS;
     2338                }
     2339# ifndef IN_RING3
     2340                /* move to ring-3 and handle the trap/whatever there, as we want to LogRel this. */
     2341                if (rcStrict == VERR_CPUM_RAISE_GP_0)
     2342                    rcStrict = VINF_CPUM_R3_MSR_WRITE;
     2343                return rcStrict;
     2344# else
     2345                LogRel(("MsrExit/%u: %04x:%08RX64/%s: WRMSR %08x, %08x:%08x -> %Rrc!\n",
     2346                        pVCpu->idCpu, pMsg->Header.CsSegment.Selector, pMsg->Header.Rip, nemHCWinExecStateToLogStr(&pMsg->Header),
     2347                        pMsg->MsrNumber, (uint32_t)pMsg->Rax, (uint32_t)pMsg->Rdx, VBOXSTRICTRC_VAL(rcStrict) ));
     2348# endif
    23262349            }
     2350            /*
     2351             * Handle reads.
     2352             */
     2353            else
     2354            {
     2355                uint64_t uValue = 0;
     2356                rcStrict = CPUMQueryGuestMsr(pVCpu, pMsg->MsrNumber, &uValue);
     2357                Log4(("MsrExit/%u: %04x:%08RX64/%s: RDMSR %08x -> %08RX64 / %Rrc\n",
     2358                      pVCpu->idCpu, pMsg->Header.CsSegment.Selector, pMsg->Header.Rip, nemHCWinExecStateToLogStr(&pMsg->Header),
     2359                      pMsg->MsrNumber, uValue, VBOXSTRICTRC_VAL(rcStrict) ));
     2360                if (rcStrict == VINF_SUCCESS)
     2361                {
     2362                    nemHCWinCopyStateFromX64Header(pVCpu, pCtx, &pMsg->Header);
     2363                    pCtx->rax = (uint32_t)uValue;
     2364                    pCtx->rdx = uValue >> 32;
     2365                    pCtx->fExtrn &= ~(CPUMCTX_EXTRN_RAX | CPUMCTX_EXTRN_RDX);
     2366                    nemHCWinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pMsg->Header);
     2367                    return VINF_SUCCESS;
     2368                }
    23272369# ifndef IN_RING3
    2328             /* move to ring-3 and handle the trap/whatever there, as we want to LogRel this. */
    2329             if (rcStrict == VERR_CPUM_RAISE_GP_0)
    2330                 rcStrict = VINF_CPUM_R3_MSR_WRITE;
     2370                /* move to ring-3 and handle the trap/whatever there, as we want to LogRel this. */
     2371                if (rcStrict == VERR_CPUM_RAISE_GP_0)
     2372                    rcStrict = VINF_CPUM_R3_MSR_READ;
     2373                return rcStrict;
     2374# else
     2375                LogRel(("MsrExit/%u: %04x:%08RX64/%s: RDMSR %08x -> %08RX64 / %Rrc\n",
     2376                        pVCpu->idCpu, pMsg->Header.CsSegment.Selector, pMsg->Header.Rip, nemHCWinExecStateToLogStr(&pMsg->Header),
     2377                        pMsg->MsrNumber, uValue, VBOXSTRICTRC_VAL(rcStrict) ));
     2378# endif
     2379            }
     2380        }
     2381        else
     2382        {
     2383            LogRel(("MsrExit/%u: %04x:%08RX64/%s: %sMSR %08x -> %Rrc - msr state import\n",
     2384                    pVCpu->idCpu, pMsg->Header.CsSegment.Selector, pMsg->Header.Rip, nemHCWinExecStateToLogStr(&pMsg->Header),
     2385                    pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE ? "WR" : "RD",
     2386                    pMsg->MsrNumber, VBOXSTRICTRC_VAL(rcStrict) ));
    23312387            return rcStrict;
    2332 # else
    2333             LogRel(("MsrExit/%u: %04x:%08RX64/%s: WRMSR %08x, %08x:%08x -> %Rrc!\n",
    2334                     pVCpu->idCpu, pMsg->Header.CsSegment.Selector, pMsg->Header.Rip, nemHCWinExecStateToLogStr(&pMsg->Header),
    2335                     pMsg->MsrNumber, (uint32_t)pMsg->Rax, (uint32_t)pMsg->Rdx, VBOXSTRICTRC_VAL(rcStrict) ));
    2336 # endif
    2337         }
    2338         /*
    2339          * Handle reads.
    2340          */
    2341         else
    2342         {
    2343             uint64_t uValue = 0;
    2344             rcStrict = CPUMQueryGuestMsr(pVCpu, pMsg->MsrNumber, &uValue);
    2345             Log4(("MsrExit/%u: %04x:%08RX64/%s: RDMSR %08x -> %08RX64 / %Rrc\n",
    2346                   pVCpu->idCpu, pMsg->Header.CsSegment.Selector, pMsg->Header.Rip, nemHCWinExecStateToLogStr(&pMsg->Header),
    2347                   pMsg->MsrNumber, uValue, VBOXSTRICTRC_VAL(rcStrict) ));
    2348             if (rcStrict == VINF_SUCCESS)
    2349             {
    2350                 nemHCWinCopyStateFromX64Header(pVCpu, pCtx, &pMsg->Header);
    2351                 pCtx->rax = (uint32_t)uValue;
    2352                 pCtx->rdx = uValue >> 32;
    2353                 pCtx->fExtrn &= ~(CPUMCTX_EXTRN_RAX | CPUMCTX_EXTRN_RDX);
    2354                 nemHCWinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pMsg->Header);
    2355                 return VINF_SUCCESS;
    2356             }
    2357 # ifndef IN_RING3
    2358             /* move to ring-3 and handle the trap/whatever there, as we want to LogRel this. */
    2359             if (rcStrict == VERR_CPUM_RAISE_GP_0)
    2360                 rcStrict = VINF_CPUM_R3_MSR_READ;
    2361             return rcStrict;
    2362 # else
    2363             LogRel(("MsrExit/%u: %04x:%08RX64/%s: RDMSR %08x -> %08RX64 / %Rrc\n",
    2364                     pVCpu->idCpu, pMsg->Header.CsSegment.Selector, pMsg->Header.Rip, nemHCWinExecStateToLogStr(&pMsg->Header),
    2365                     pMsg->MsrNumber, uValue, VBOXSTRICTRC_VAL(rcStrict) ));
    2366 # endif
    23672388        }
    23682389    }
     
    23792400     * If we get down here, we're supposed to #GP(0).
    23802401     */
    2381     rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, pGVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM, "NMI");
     2402    rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, pGVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM, "MSR");
    23822403    if (rcStrict == VINF_SUCCESS)
    23832404    {
     
    24132434    {
    24142435        /*
    2415          * Handle writes.
     2436         * Get all the MSR state.  Since we're getting EFER, we also need to
     2437         * get CR0, CR4 and CR3.
    24162438         */
    2417         if (pExit->MsrAccess.AccessInfo.IsWrite)
    2418         {
    2419             rcStrict = CPUMSetGuestMsr(pVCpu, pExit->MsrAccess.MsrNumber,
    2420                                        RT_MAKE_U64((uint32_t)pExit->MsrAccess.Rax, (uint32_t)pExit->MsrAccess.Rdx));
    2421             Log4(("MsrExit/%u: %04x:%08RX64/%s: WRMSR %08x, %08x:%08x -> %Rrc\n",
    2422                   pVCpu->idCpu, pExit->VpContext.Cs.Selector, pExit->VpContext.Rip, nemR3WinExecStateToLogStr(&pExit->VpContext),
    2423                   pExit->MsrAccess.MsrNumber, (uint32_t)pExit->MsrAccess.Rax, (uint32_t)pExit->MsrAccess.Rdx, VBOXSTRICTRC_VAL(rcStrict) ));
    2424             if (rcStrict == VINF_SUCCESS)
     2439        nemR3WinCopyStateFromX64Header(pVCpu, pCtx, &pExit->VpContext);
     2440        rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, NULL, pCtx,
     2441                                                       CPUMCTX_EXTRN_ALL_MSRS | CPUMCTX_EXTRN_CR0
     2442                                                     | CPUMCTX_EXTRN_CR3 | CPUMCTX_EXTRN_CR4,
     2443                                                     "MSRs");
     2444        if (rcStrict == VINF_SUCCESS)
     2445        {
     2446            /*
     2447             * Handle writes.
     2448             */
     2449            if (pExit->MsrAccess.AccessInfo.IsWrite)
    24252450            {
    2426                 nemR3WinCopyStateFromX64Header(pVCpu, pCtx, &pExit->VpContext);
    2427                 nemR3WinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pExit->VpContext);
    2428                 return VINF_SUCCESS;
     2451                rcStrict = CPUMSetGuestMsr(pVCpu, pExit->MsrAccess.MsrNumber,
     2452                                           RT_MAKE_U64((uint32_t)pExit->MsrAccess.Rax, (uint32_t)pExit->MsrAccess.Rdx));
     2453                Log4(("MsrExit/%u: %04x:%08RX64/%s: WRMSR %08x, %08x:%08x -> %Rrc\n", pVCpu->idCpu, pExit->VpContext.Cs.Selector,
     2454                      pExit->VpContext.Rip, nemR3WinExecStateToLogStr(&pExit->VpContext), pExit->MsrAccess.MsrNumber,
     2455                      (uint32_t)pExit->MsrAccess.Rax, (uint32_t)pExit->MsrAccess.Rdx, VBOXSTRICTRC_VAL(rcStrict) ));
     2456                if (rcStrict == VINF_SUCCESS)
     2457                {
     2458                    nemR3WinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pExit->VpContext);
     2459                    return VINF_SUCCESS;
     2460                }
     2461                LogRel(("MsrExit/%u: %04x:%08RX64/%s: WRMSR %08x, %08x:%08x -> %Rrc!\n", pVCpu->idCpu,
     2462                        pExit->VpContext.Cs.Selector, pExit->VpContext.Rip, nemR3WinExecStateToLogStr(&pExit->VpContext),
     2463                        pExit->MsrAccess.MsrNumber, (uint32_t)pExit->MsrAccess.Rax, (uint32_t)pExit->MsrAccess.Rdx,
     2464                        VBOXSTRICTRC_VAL(rcStrict) ));
    24292465            }
    2430             LogRel(("MsrExit/%u: %04x:%08RX64/%s: WRMSR %08x, %08x:%08x -> %Rrc!\n",
     2466            /*
     2467             * Handle reads.
     2468             */
     2469            else
     2470            {
     2471                uint64_t uValue = 0;
     2472                rcStrict = CPUMQueryGuestMsr(pVCpu, pExit->MsrAccess.MsrNumber, &uValue);
     2473                Log4(("MsrExit/%u: %04x:%08RX64/%s: RDMSR %08x -> %08RX64 / %Rrc\n", pVCpu->idCpu,
     2474                      pExit->VpContext.Cs.Selector, pExit->VpContext.Rip, nemR3WinExecStateToLogStr(&pExit->VpContext),
     2475                      pExit->MsrAccess.MsrNumber, uValue, VBOXSTRICTRC_VAL(rcStrict) ));
     2476                if (rcStrict == VINF_SUCCESS)
     2477                {
     2478                    pCtx->rax = (uint32_t)uValue;
     2479                    pCtx->rdx = uValue >> 32;
     2480                    pCtx->fExtrn &= ~(CPUMCTX_EXTRN_RAX | CPUMCTX_EXTRN_RDX);
     2481                    nemR3WinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pExit->VpContext);
     2482                    return VINF_SUCCESS;
     2483                }
     2484                LogRel(("MsrExit/%u: %04x:%08RX64/%s: RDMSR %08x -> %08RX64 / %Rrc\n", pVCpu->idCpu, pExit->VpContext.Cs.Selector,
     2485                        pExit->VpContext.Rip, nemR3WinExecStateToLogStr(&pExit->VpContext), pExit->MsrAccess.MsrNumber,
     2486                        uValue, VBOXSTRICTRC_VAL(rcStrict) ));
     2487            }
     2488        }
     2489        else
     2490        {
     2491            LogRel(("MsrExit/%u: %04x:%08RX64/%s: %sMSR %08x -> %Rrc - msr state import\n",
    24312492                    pVCpu->idCpu, pExit->VpContext.Cs.Selector, pExit->VpContext.Rip, nemR3WinExecStateToLogStr(&pExit->VpContext),
    2432                     pExit->MsrAccess.MsrNumber, (uint32_t)pExit->MsrAccess.Rax, (uint32_t)pExit->MsrAccess.Rdx, VBOXSTRICTRC_VAL(rcStrict) ));
    2433         }
    2434         /*
    2435          * Handle reads.
    2436          */
    2437         else
    2438         {
    2439             uint64_t uValue = 0;
    2440             rcStrict = CPUMQueryGuestMsr(pVCpu, pExit->MsrAccess.MsrNumber, &uValue);
    2441             Log4(("MsrExit/%u: %04x:%08RX64/%s: RDMSR %08x -> %08RX64 / %Rrc\n",
    2442                   pVCpu->idCpu, pExit->VpContext.Cs.Selector, pExit->VpContext.Rip, nemR3WinExecStateToLogStr(&pExit->VpContext),
    2443                   pExit->MsrAccess.MsrNumber, uValue, VBOXSTRICTRC_VAL(rcStrict) ));
    2444             if (rcStrict == VINF_SUCCESS)
    2445             {
    2446                 nemR3WinCopyStateFromX64Header(pVCpu, pCtx, &pExit->VpContext);
    2447                 pCtx->rax = (uint32_t)uValue;
    2448                 pCtx->rdx = uValue >> 32;
    2449                 pCtx->fExtrn &= ~(CPUMCTX_EXTRN_RAX | CPUMCTX_EXTRN_RDX);
    2450                 nemR3WinAdvanceGuestRipAndClearRF(pVCpu, pCtx, &pExit->VpContext);
    2451                 return VINF_SUCCESS;
    2452             }
    2453             LogRel(("MsrExit/%u: %04x:%08RX64/%s: RDMSR %08x -> %08RX64 / %Rrc\n",
    2454                     pVCpu->idCpu, pExit->VpContext.Cs.Selector, pExit->VpContext.Rip, nemR3WinExecStateToLogStr(&pExit->VpContext),
    2455                     pExit->MsrAccess.MsrNumber, uValue, VBOXSTRICTRC_VAL(rcStrict) ));
     2493                    pExit->MsrAccess.AccessInfo.IsWrite ? "WR" : "RD", pExit->MsrAccess.MsrNumber, VBOXSTRICTRC_VAL(rcStrict) ));
     2494            return rcStrict;
    24562495        }
    24572496    }
    24582497    else if (pExit->MsrAccess.AccessInfo.IsWrite)
    2459         Log4(("MsrExit/%u: %04x:%08RX64/%s: CPL %u -> #GP(0); WRMSR %08x, %08x:%08x\n",
    2460               pVCpu->idCpu, pExit->VpContext.Cs.Selector, pExit->VpContext.Rip, nemR3WinExecStateToLogStr(&pExit->VpContext),
    2461               pExit->VpContext.ExecutionState.Cpl, pExit->MsrAccess.MsrNumber, (uint32_t)pExit->MsrAccess.Rax, (uint32_t)pExit->MsrAccess.Rdx ));
     2498        Log4(("MsrExit/%u: %04x:%08RX64/%s: CPL %u -> #GP(0); WRMSR %08x, %08x:%08x\n", pVCpu->idCpu, pExit->VpContext.Cs.Selector,
     2499              pExit->VpContext.Rip, nemR3WinExecStateToLogStr(&pExit->VpContext), pExit->VpContext.ExecutionState.Cpl,
     2500              pExit->MsrAccess.MsrNumber, (uint32_t)pExit->MsrAccess.Rax, (uint32_t)pExit->MsrAccess.Rdx ));
    24622501    else
    2463         Log4(("MsrExit/%u: %04x:%08RX64/%s: CPL %u -> #GP(0); RDMSR %08x\n",
    2464               pVCpu->idCpu, pExit->VpContext.Cs.Selector, pExit->VpContext.Rip, nemR3WinExecStateToLogStr(&pExit->VpContext),
    2465               pExit->VpContext.ExecutionState.Cpl, pExit->MsrAccess.MsrNumber));
     2502        Log4(("MsrExit/%u: %04x:%08RX64/%s: CPL %u -> #GP(0); RDMSR %08x\n", pVCpu->idCpu, pExit->VpContext.Cs.Selector,
     2503              pExit->VpContext.Rip, nemR3WinExecStateToLogStr(&pExit->VpContext), pExit->VpContext.ExecutionState.Cpl,
     2504              pExit->MsrAccess.MsrNumber));
    24662505
    24672506    /*
    24682507     * If we get down here, we're supposed to #GP(0).
    24692508     */
    2470     rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, NULL, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM, "NMI");
     2509    rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, NULL, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM, "MSR");
    24712510    if (rcStrict == VINF_SUCCESS)
    24722511    {
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp

    r72412 r72415  
    24322432 *
    24332433 *
    2434  * - Need to figure out how to emulate X2APIC (AMD Ryzen), doesn't work with
    2435  *   debian 9.0/64.
     2434 * - The IA32_APIC_BASE register does not work right:
     2435 *
     2436 *      - Attempts by the guest to clear bit 11 (EN) are ignored, both the
     2437 *        guest and the VMM reads back the old value.
     2438 *
     2439 *      - Attempts to modify the base address (bits NN:12) seems to be ignored
     2440 *        in the same way.
     2441 *
     2442 *      - The VMM can modify both the base address as well as the the EN and
     2443 *        BSP bits, however this is useless if we cannot intercept the WRMSR.
     2444 *
     2445 *      - Attempts by the guest to set the EXTD bit (X2APIC) result in #GP(0),
     2446 *        while the VMM ends up with with ERROR_HV_INVALID_PARAMETER.  Seems
     2447 *        there is no way to support X2APIC.
    24362448 *
    24372449 *
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