Changeset 60398 in vbox
- Timestamp:
- Apr 8, 2016 4:29:01 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 1 deleted
- 5 edited
-
include/VBox/vmm/apic.h (modified) (1 diff)
-
src/VBox/VMM/Makefile.kmk (modified) (1 diff)
-
src/VBox/VMM/VMMR0/APICR0.cpp (deleted)
-
src/VBox/VMM/VMMR0/VMMR0.cpp (modified) (2 diffs)
-
src/VBox/VMM/VMMR3/APIC.cpp (modified) (8 diffs)
-
src/VBox/VMM/VMMR3/VM.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/apic.h
r60377 r60398 927 927 * @{ 928 928 */ 929 VMMR3_INT_DECL(int) APICR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat);930 929 VMMR3_INT_DECL(void) APICR3InitIpi(PVMCPU pVCpu); 931 930 VMMR3_INT_DECL(void) APICR3Reset(PVMCPU pVCpu); -
trunk/src/VBox/VMM/Makefile.kmk
r60307 r60398 649 649 ifdef VBOX_WITH_NEW_APIC 650 650 VMMR0_SOURCES += \ 651 VMMAll/APICAll.cpp \ 652 VMMR0/APICR0.cpp 651 VMMAll/APICAll.cpp 653 652 endif 654 653 VMMR0_SOURCES.amd64 = \ -
trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
r60364 r60398 469 469 if (RT_SUCCESS(rc)) 470 470 { 471 #ifdef VBOX_WITH_NEW_APIC 472 rc = APICR0InitVM(pVM); 473 #endif 471 VMM_CHECK_SMAP_CHECK2(pVM, rc = VERR_VMM_RING0_ASSERTION); 474 472 if (RT_SUCCESS(rc)) 475 473 { 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; 486 477 } 487 478 … … 528 519 if (GVMMR0DoingTermVM(pVM, pGVM)) 529 520 { 530 #ifdef VBOX_WITH_NEW_APIC531 APICR0TermVM(pVM);532 #endif533 521 GIMR0TermVM(pVM); 534 522 -
trunk/src/VBox/VMM/VMMR3/APIC.cpp
r60379 r60398 445 445 446 446 /** 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 else478 {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 else514 {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 else521 {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 /**549 447 * Receives an INIT IPI. 550 448 * … … 1095 993 1096 994 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) 1103 996 pApic->pvApicPibRC = MMHyperR3ToRC(pVM, (void *)pApic->pvApicPibR3); 1104 997 … … 1109 1002 pApicCpu->pTimerRC = TMTimerRCPtr(pApicCpu->pTimerR3); 1110 1003 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 */ 1017 static 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); 1111 1034 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 */ 1049 static 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 */ 1164 static 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 */ 1175 static 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; 1117 1191 } 1118 1192 … … 1167 1241 1168 1242 /* 1169 * Initialize part ofAPIC state.1243 * Initialize the APIC state. 1170 1244 */ 1171 1245 pApicDev->pDevInsR3 = pDevIns; … … 1177 1251 pApic->pApicDevRC = PDMINS_2_DATA_RCPTR(pDevIns); 1178 1252 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); 1191 1255 1192 1256 /* … … 1285 1349 PVMCPU pVCpu = &pVM->aCpus[idCpu]; 1286 1350 PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu); 1351 RTStrPrintf(&pApicCpu->szTimerDesc[0], sizeof(pApicCpu->szTimerDesc), "APIC Timer %u", pVCpu->idCpu); 1287 1352 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, apicR3TimerCallback, pVCpu, TMTIMER_FLAGS_NO_CRIT_SECT, 1288 1353 pApicCpu->szTimerDesc, &pApicCpu->pTimerR3); … … 1371 1436 apicR3Construct, 1372 1437 /* pfnDestruct */ 1373 NULL,1438 apicR3Destruct, 1374 1439 /* pfnRelocate */ 1375 1440 apicR3Relocate, … … 1391 1456 NULL, 1392 1457 /* pfnInitComplete */ 1393 NULL,1458 apicR3InitComplete, 1394 1459 /* pfnPowerOff */ 1395 1460 NULL, -
trunk/src/VBox/VMM/VMMR3/VM.cpp
r60387 r60398 1179 1179 if (RT_SUCCESS(rc)) 1180 1180 rc = PGMR3InitCompleted(pVM, enmWhat); 1181 #ifdef VBOX_WITH_NEW_APIC1182 if (RT_SUCCESS(rc))1183 rc = APICR3InitCompleted(pVM, enmWhat);1184 #endif1185 1181 if (RT_SUCCESS(rc)) 1186 1182 rc = CPUMR3InitCompleted(pVM, enmWhat);
Note:
See TracChangeset
for help on using the changeset viewer.

