VirtualBox

Changeset 60398 in vbox


Ignore:
Timestamp:
Apr 8, 2016 4:29:01 PM (8 years ago)
Author:
vboxsync
Message:

VMM/APIC: Get rid of specialized R0 code and clean up ordering issues.
It's still not nice that CPUMR3Reset() momentarily gets an un-initialized APIC base MSR until
it's re-cached again using CPUMR3InitCompleted() but I hope to eventually get rid of this
caching business entirely once the old APIC infrastructure can be kicked out.

Location:
trunk
Files:
1 deleted
5 edited

Legend:

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

    r60377 r60398  
    927927 * @{
    928928 */
    929 VMMR3_INT_DECL(int)         APICR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat);
    930929VMMR3_INT_DECL(void)        APICR3InitIpi(PVMCPU pVCpu);
    931930VMMR3_INT_DECL(void)        APICR3Reset(PVMCPU pVCpu);
  • trunk/src/VBox/VMM/Makefile.kmk

    r60307 r60398  
    649649 ifdef VBOX_WITH_NEW_APIC
    650650  VMMR0_SOURCES += \
    651         VMMAll/APICAll.cpp \
    652         VMMR0/APICR0.cpp
     651        VMMAll/APICAll.cpp
    653652 endif
    654653 VMMR0_SOURCES.amd64 = \
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r60364 r60398  
    469469                        if (RT_SUCCESS(rc))
    470470                        {
    471 #ifdef VBOX_WITH_NEW_APIC
    472                             rc = APICR0InitVM(pVM);
    473 #endif
     471                            VMM_CHECK_SMAP_CHECK2(pVM, rc = VERR_VMM_RING0_ASSERTION);
    474472                            if (RT_SUCCESS(rc))
    475473                            {
    476                                 VMM_CHECK_SMAP_CHECK2(pVM, rc = VERR_VMM_RING0_ASSERTION);
    477                                 if (RT_SUCCESS(rc))
    478                                 {
    479                                     GVMMR0DoneInitVM(pVM);
    480                                     VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
    481                                     return rc;
    482                                 }
    483 #ifdef VBOX_WITH_NEW_APIC
    484                             APICR0TermVM(pVM);
    485 #endif
     474                                GVMMR0DoneInitVM(pVM);
     475                                VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
     476                                return rc;
    486477                            }
    487478
     
    528519    if (GVMMR0DoingTermVM(pVM, pGVM))
    529520    {
    530 #ifdef VBOX_WITH_NEW_APIC
    531         APICR0TermVM(pVM);
    532 #endif
    533521        GIMR0TermVM(pVM);
    534522
  • trunk/src/VBox/VMM/VMMR3/APIC.cpp

    r60379 r60398  
    445445
    446446/**
    447  * Called when a init phase has completed.
    448  *
    449  * @returns VBox status code.
    450  * @param   pVM                 The cross context VM structure.
    451  * @param   enmWhat             Which init phase.
    452  */
    453 VMMR3_INT_DECL(int) APICR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat)
    454 {
    455     switch (enmWhat)
    456     {
    457         case VMINITCOMPLETED_RING0:
    458         {
    459             /*
    460              * Map the virtual-PIB into RC.
    461              * The virtual-PIB should've already been mapped into R0 and R3, see APICR0InitVM().
    462              */
    463             PAPIC   pApic = VM_TO_APIC(pVM);
    464             RTGCPTR GCPtrApicPib;
    465             if (   RT_VALID_PTR(pApic->pvApicPibR3)
    466                 && pApic->HCPhysApicPib != NIL_RTHCPHYS)
    467             {
    468                 int rc = MMR3HyperMapHCPhys(pVM, (void *)pApic->pvApicPibR3, NIL_RTR0PTR, pApic->HCPhysApicPib,
    469                                             (size_t)pApic->cbApicPib, "APIC PIB", &GCPtrApicPib);
    470                 if (RT_FAILURE(rc))
    471                 {
    472                     LogRel(("APIC: Failed to map HC APIC PIB of %u bytes at %#RHp to RC, rc=%Rrc\n", pApic->cbApicPib,
    473                             pApic->HCPhysApicPib, rc));
    474                     return rc;
    475                 }
    476             }
    477             else
    478             {
    479                 LogRel(("APIC: Failed to find R3 mapping for virtual-PIB\n"));
    480                 return VERR_MAP_FAILED;
    481             }
    482 
    483             /*
    484              * Map the virtual-APIC pages into RC and initialize per-VCPU APIC state.
    485              * The virtual-APIC pages should by now have been mapped into R0 and R3 by APICR0InitVM().
    486              */
    487             for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
    488             {
    489                 PVMCPU   pVCpu    = &pVM->aCpus[idCpu];
    490                 PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
    491 
    492                 if (   RT_VALID_PTR(pApicCpu->pvApicPageR3)
    493                     && pApicCpu->HCPhysApicPage != NIL_RTHCPHYS)
    494                 {
    495                     RTGCPTR GCPtrApicPage;
    496                     int rc = MMR3HyperMapHCPhys(pVM, (void *)pApicCpu->pvApicPageR3, NIL_RTR0PTR, pApicCpu->HCPhysApicPage,
    497                                                 (size_t)pApicCpu->cbApicPage, "APIC", &GCPtrApicPage);
    498                     if (RT_SUCCESS(rc))
    499                     {
    500                         pApicCpu->pvApicPageRC = GCPtrApicPage;
    501 
    502                         /*
    503                          * Associate the per-VCPU PIB RC pointer to the per-VM PIB RC mapping.
    504                          */
    505                         size_t const offApicPib = idCpu * sizeof(APICPIB);
    506                         pApicCpu->pvApicPibRC   = GCPtrApicPib + offApicPib;
    507 
    508                         /*
    509                          * Initialize the remaining state now that we have R3 mappings.
    510                          */
    511                         APICR3Reset(pVCpu);
    512                     }
    513                     else
    514                     {
    515                         LogRel(("APIC%u: Failed to map HC virtual-APIC page of %u bytes at %#RHp to RC, rc=%Rrc\n",
    516                                 pVCpu->idCpu, pApicCpu->cbApicPage, pApicCpu->HCPhysApicPage, rc));
    517                         return rc;
    518                     }
    519                 }
    520                 else
    521                 {
    522                     LogRel(("APIC%u: Failed to find R3 mapping for virtual-APIC page\n", pVCpu->idCpu));
    523                     return VERR_MAP_FAILED;
    524                 }
    525             }
    526             return VINF_SUCCESS;
    527         }
    528 
    529         case VMINITCOMPLETED_HM:
    530         {
    531             CPUMCPUIDLEAF CpuLeaf;
    532             int rc = CPUMR3CpuIdGetLeaf(pVM, &CpuLeaf, 1, 0);
    533             AssertRCReturn(rc, rc);
    534 
    535             PAPIC pApic = VM_TO_APIC(pVM);
    536             pApic->fSupportsTscDeadline = RT_BOOL(CpuLeaf.uEcx & X86_CPUID_FEATURE_ECX_TSCDEADL);
    537             pApic->fPostedIntrsEnabled  = HMR3IsPostedIntrsEnabled(pVM->pUVM);
    538             pApic->fVirtApicRegsEnabled = HMR3IsVirtApicRegsEnabled(pVM->pUVM);
    539             return VINF_SUCCESS;
    540         }
    541 
    542         default:
    543             return VINF_SUCCESS;
    544     }
    545 }
    546 
    547 
    548 /**
    549447 * Receives an INIT IPI.
    550448 *
     
    1095993
    1096994    pApic->pApicDevRC     = PDMINS_2_DATA_RCPTR(pDevIns);
    1097 
    1098     /*
    1099      * We can get invoked via PGMR3FinalizeMappings() which happens before initializing R0.
    1100      * This we may not have allocated and mapped the R0, R3 data yet. Hence the NULL checks.
    1101      */
    1102     if (pApic->pvApicPibR3)
     995    if (pApic->pvApicPibRC)
    1103996        pApic->pvApicPibRC = MMHyperR3ToRC(pVM, (void *)pApic->pvApicPibR3);
    1104997
     
    11091002        pApicCpu->pTimerRC     = TMTimerRCPtr(pApicCpu->pTimerR3);
    11101003
     1004        if (pApicCpu->pvApicPageRC)
     1005            pApicCpu->pvApicPageRC = MMHyperR3ToRC(pVM, (void *)pApicCpu->pvApicPageR3);
     1006        if (pApicCpu->pvApicPibRC)
     1007            pApicCpu->pvApicPibRC  = MMHyperR3ToRC(pVM, (void *)pApicCpu->pvApicPibR3);
     1008    }
     1009}
     1010
     1011
     1012/**
     1013 * Terminates the APIC state.
     1014 *
     1015 * @param   pVM     The cross context VM structure.
     1016 */
     1017static void apicR3TermState(PVM pVM)
     1018{
     1019    PAPIC pApic = VM_TO_APIC(pVM);
     1020    if (pApic->pvApicPibR3)
     1021    {
     1022        size_t const cPages = pApic->cbApicPib >> PAGE_SHIFT;
     1023        if (cPages == 1)
     1024            SUPR3PageFreeEx((void *)pApic->pvApicPibR3, cPages);
     1025        else
     1026            SUPR3ContFree((void *)pApic->pvApicPibR3, cPages);
     1027        pApic->pvApicPibR3 = NULL;
     1028    }
     1029
     1030    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     1031    {
     1032        PVMCPU   pVCpu      = &pVM->aCpus[idCpu];
     1033        PAPICCPU pApicCpu   = VMCPU_TO_APICCPU(pVCpu);
    11111034        if (pApicCpu->pvApicPageR3)
    1112             pApicCpu->pvApicPageRC = MMHyperR3ToRC(pVM, (void *)pApicCpu->pvApicPageR3);
    1113 
    1114         if (pApicCpu->pvApicPibR3)
    1115             pApicCpu->pvApicPibRC  = MMHyperR3ToRC(pVM, (void *)pApicCpu->pvApicPibR3);
    1116     }
     1035        {
     1036            SUPR3PageFreeEx((void *)pApicCpu->pvApicPageR3, 1 /* cPages */);
     1037            pApicCpu->pvApicPageR3 = NULL;
     1038        }
     1039    }
     1040}
     1041
     1042
     1043/**
     1044 * Initializes the APIC state.
     1045 *
     1046 * @returns VBox status code.
     1047 * @param   pVM     The cross context VM structure.
     1048 */
     1049static int apicR3InitState(PVM pVM)
     1050{
     1051    PAPIC pApic = VM_TO_APIC(pVM);
     1052    bool const fNeedGCMapping = !HMIsEnabled(pVM);
     1053
     1054    /*
     1055     * Allocate and map the pending-interrupt bitmap (PIB).
     1056     *
     1057     * We allocate all the VCPUs' PIBs contiguously in order to save space as
     1058     * physically contiguous allocations are rounded to a multiple of page size.
     1059     */
     1060    pApic->cbApicPib    = RT_ALIGN_Z(pVM->cCpus * sizeof(APICPIB), PAGE_SIZE);
     1061    size_t const cPages = pApic->cbApicPib >> PAGE_SHIFT;
     1062    Assert(!pApic->pvApicPibR3);
     1063    if (cPages == 1)
     1064    {
     1065        SUPPAGE SupApicPib;
     1066        RT_ZERO(SupApicPib);
     1067        SupApicPib.Phys = NIL_RTHCPHYS;
     1068        int rc = SUPR3PageAllocEx(cPages, 0 /* fFlags */, (void **)&pApic->pvApicPibR3, &pApic->pvApicPibR0, &SupApicPib);
     1069        if (RT_SUCCESS(rc))
     1070        {
     1071            pApic->HCPhysApicPib = SupApicPib.Phys;
     1072            Assert(pApic->HCPhysApicPib != NIL_RTHCPHYS);
     1073            Assert(pApic->pvApicPibR3);
     1074        }
     1075        else
     1076        {
     1077            LogRel(("APIC: Failed to allocate %u bytes for the pending-interrupt bitmap, rc=%Rrc\n", pApic->cbApicPib, rc));
     1078            return rc;
     1079        }
     1080    }
     1081    else
     1082        pApic->pvApicPibR3 = SUPR3ContAlloc(cPages, &pApic->pvApicPibR0, &pApic->HCPhysApicPib);
     1083
     1084    if (pApic->pvApicPibR3)
     1085    {
     1086        /* Map the pending-interrupt bitmap (PIB) into GC.  */
     1087        if (fNeedGCMapping)
     1088        {
     1089            int rc = MMR3HyperMapHCPhys(pVM, (void *)pApic->pvApicPibR3, NIL_RTR0PTR, pApic->HCPhysApicPib, pApic->cbApicPib,
     1090                                        "APIC PIB", (PRTGCPTR)&pApic->pvApicPibRC);
     1091            if (RT_FAILURE(rc))
     1092            {
     1093                LogRel(("APIC: Failed to map %u bytes for the pending-interrupt bitmap to GC, rc=%Rrc\n", pApic->cbApicPib, rc));
     1094                apicR3TermState(pVM);
     1095                return rc;
     1096            }
     1097        }
     1098
     1099        for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     1100        {
     1101            PVMCPU   pVCpu    = &pVM->aCpus[idCpu];
     1102            PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
     1103
     1104            /* Allocate and map the virtual-APIC page. */
     1105            SUPPAGE SupApicPage;
     1106            RT_ZERO(SupApicPage);
     1107            SupApicPage.Phys = NIL_RTHCPHYS;
     1108
     1109            pApicCpu->cbApicPage = sizeof(XAPICPAGE);
     1110            AssertCompile(sizeof(XAPICPAGE) == PAGE_SIZE);
     1111
     1112            Assert(!pApicCpu->pvApicPageR3);
     1113            int rc = SUPR3PageAllocEx(1 /* cPages */, 0 /* fFlags */, (void **)&pApicCpu->pvApicPageR3, &pApicCpu->pvApicPageR0,
     1114                                      &SupApicPage);
     1115            if (RT_SUCCESS(rc))
     1116            {
     1117                pApicCpu->HCPhysApicPage = SupApicPage.Phys;
     1118                Assert(pApicCpu->HCPhysApicPage != NIL_RTHCPHYS);
     1119
     1120                /* Map the virtual-APIC page into GC. */
     1121                if (fNeedGCMapping)
     1122                {
     1123                    rc = MMR3HyperMapHCPhys(pVM, (void *)pApicCpu->pvApicPageR3, NIL_RTR0PTR, pApicCpu->HCPhysApicPage,
     1124                                            pApicCpu->cbApicPage, "APIC", (PRTGCPTR)&pApicCpu->pvApicPageRC);
     1125                    if (RT_FAILURE(rc))
     1126                    {
     1127                        LogRel(("APIC%u: Failed to map %u bytes for the virtual-APIC page to GC, rc=%Rrc", idCpu,
     1128                                pApicCpu->cbApicPage, rc));
     1129                        apicR3TermState(pVM);
     1130                        return rc;
     1131                    }
     1132                }
     1133
     1134                /* Associate the per-VCPU PIB pointers to the per-VM PIB mapping. */
     1135                size_t const offApicPib    = idCpu * sizeof(APICPIB);
     1136                pApicCpu->pvApicPibR0      = (RTR0PTR)((const uint8_t *)pApic->pvApicPibR0 + offApicPib);
     1137                pApicCpu->pvApicPibR3      = (RTR3PTR)((const uint8_t *)pApic->pvApicPibR3 + offApicPib);
     1138                if (fNeedGCMapping)
     1139                    pApicCpu->pvApicPibRC += offApicPib;
     1140
     1141                /* Initialize the virtual-APIC state. */
     1142                memset((void *)pApicCpu->pvApicPageR3, 0, pApicCpu->cbApicPage);
     1143                APICR3Reset(pVCpu);
     1144            }
     1145            else
     1146            {
     1147                LogRel(("APIC%u: Failed to allocate %u bytes for the virtual-APIC page\n", pApicCpu->cbApicPage));
     1148                apicR3TermState(pVM);
     1149                return VERR_NO_MEMORY;
     1150            }
     1151        }
     1152
     1153        return VINF_SUCCESS;
     1154    }
     1155
     1156    LogRel(("APIC: Failed to allocate %u bytes of contiguous low-memory for the pending-interrupt bitmap\n", pApic->cbApicPib));
     1157    return VERR_NO_MEMORY;
     1158}
     1159
     1160
     1161/**
     1162 * @interface_method_impl{PDMDEVREG,pfnDestruct}
     1163 */
     1164static DECLCALLBACK(int) apicR3Destruct(PPDMDEVINS pDevIns)
     1165{
     1166    PVM pVM = PDMDevHlpGetVM(pDevIns);
     1167    apicR3TermState(pVM);
     1168    return VINF_SUCCESS;
     1169}
     1170
     1171
     1172/**
     1173 * @interface_method_impl{PDMDEVREG,pfnInitComplete}
     1174 */
     1175static DECLCALLBACK(int) apicR3InitComplete(PPDMDEVINS pDevIns)
     1176{
     1177    PVM   pVM   = PDMDevHlpGetVM(pDevIns);
     1178    PAPIC pApic = VM_TO_APIC(pVM);
     1179
     1180    CPUMCPUIDLEAF CpuLeaf;
     1181    int rc = CPUMR3CpuIdGetLeaf(pVM, &CpuLeaf, 1, 0);
     1182    AssertRCReturn(rc, rc);
     1183    pApic->fSupportsTscDeadline = RT_BOOL(CpuLeaf.uEcx & X86_CPUID_FEATURE_ECX_TSCDEADL);
     1184
     1185    pApic->fPostedIntrsEnabled  = HMR3IsPostedIntrsEnabled(pVM->pUVM);
     1186    pApic->fVirtApicRegsEnabled = HMR3IsVirtApicRegsEnabled(pVM->pUVM);
     1187
     1188    LogRel(("APIC: fPostedIntrsEnabled=%RTbool fVirtApicRegsEnabled=%RTbool fSupportsTscDeadline=%RTbool\n",
     1189            pApic->fPostedIntrsEnabled, pApic->fVirtApicRegsEnabled, pApic->fSupportsTscDeadline));
     1190    return VINF_SUCCESS;
    11171191}
    11181192
     
    11671241
    11681242    /*
    1169      * Initialize part of APIC state.
     1243     * Initialize the APIC state.
    11701244     */
    11711245    pApicDev->pDevInsR3 = pDevIns;
     
    11771251    pApic->pApicDevRC   = PDMINS_2_DATA_RCPTR(pDevIns);
    11781252
    1179     for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
    1180     {
    1181         PVMCPU   pVCpu    = &pVM->aCpus[idCpu];
    1182         PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
    1183         RTStrPrintf(&pApicCpu->szTimerDesc[0], sizeof(pApicCpu->szTimerDesc), "APIC Timer %u", pVCpu->idCpu);
    1184 
    1185         /* Initialize the APIC base MSR as we require it for registering the MMIO range. */
    1186         apicR3ResetBaseMsr(pVCpu);
    1187 
    1188         /* Disable the APIC until we're fully initialized in APICR3InitCompleted(), see @bugref{8245#c46}. */
    1189         apicR3SetEnabled(pVCpu, false);
    1190     }
     1253    rc = apicR3InitState(pVM);
     1254    AssertRCReturn(rc, rc);
    11911255
    11921256    /*
     
    12851349        PVMCPU   pVCpu    = &pVM->aCpus[idCpu];
    12861350        PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
     1351        RTStrPrintf(&pApicCpu->szTimerDesc[0], sizeof(pApicCpu->szTimerDesc), "APIC Timer %u", pVCpu->idCpu);
    12871352        rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, apicR3TimerCallback, pVCpu, TMTIMER_FLAGS_NO_CRIT_SECT,
    12881353                                    pApicCpu->szTimerDesc, &pApicCpu->pTimerR3);
     
    13711436    apicR3Construct,
    13721437    /* pfnDestruct */
    1373     NULL,
     1438    apicR3Destruct,
    13741439    /* pfnRelocate */
    13751440    apicR3Relocate,
     
    13911456    NULL,
    13921457    /* pfnInitComplete */
    1393     NULL,
     1458    apicR3InitComplete,
    13941459    /* pfnPowerOff */
    13951460    NULL,
  • trunk/src/VBox/VMM/VMMR3/VM.cpp

    r60387 r60398  
    11791179    if (RT_SUCCESS(rc))
    11801180        rc = PGMR3InitCompleted(pVM, enmWhat);
    1181 #ifdef VBOX_WITH_NEW_APIC
    1182     if (RT_SUCCESS(rc))
    1183         rc = APICR3InitCompleted(pVM, enmWhat);
    1184 #endif
    11851181    if (RT_SUCCESS(rc))
    11861182        rc = CPUMR3InitCompleted(pVM, enmWhat);
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