Changeset 63648 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Aug 26, 2016 11:44:40 AM (8 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp
r62653 r63648 29 29 #include <VBox/vmm/pdmapi.h> 30 30 #include <VBox/vmm/pgm.h> 31 #include <VBox/vmm/apic.h> 31 32 #include "GIMHvInternal.h" 32 33 #include "GIMInternal.h" … … 285 286 { 286 287 PGIMHVPOSTMESSAGEIN pMsgIn = (PGIMHVPOSTMESSAGEIN)pHv->pbHypercallIn; 287 P GIMHVCPUpHvCpu = &pVCpu->gim.s.u.HvCpu;288 PCGIMHVCPU pHvCpu = &pVCpu->gim.s.u.HvCpu; 288 289 if ( pMsgIn->uConnectionId == GIM_HV_VMBUS_MSG_CONNECTION_ID 289 290 && pMsgIn->enmMessageType == GIMHVMSGTYPE_VMBUS 290 && !MSR_GIM_HV_SINT_IS_MASKED(pHvCpu->auSint XMsr[GIM_HV_VMBUS_MSG_SINT])291 && !MSR_GIM_HV_SINT_IS_MASKED(pHvCpu->auSintMsrs[GIM_HV_VMBUS_MSG_SINT]) 291 292 && MSR_GIM_HV_SIMP_IS_ENABLED(pHvCpu->uSimpMsr)) 292 293 { … … 332 333 333 334 default: 335 { 336 LogRel(("GIM: HyperV: Unknown/invalid hypercall opcode %#x (%u)\n", uHyperOp, uHyperOp)); 334 337 rcHv = GIM_HV_STATUS_INVALID_HYPERCALL_CODE; 335 338 break; 339 } 336 340 } 337 341 } … … 414 418 #endif 415 419 420 /** 421 * Gets the time reference count for the current VM. 422 * 423 * @returns The time reference count. 424 * @param pVCpu The cross context virtual CPU structure. 425 */ 426 DECLINLINE(uint64_t) gimHvGetTimeRefCount(PVMCPU pVCpu) 427 { 428 /* Hyper-V reports the time in 100 ns units (10 MHz). */ 429 VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu); 430 PCGIMHV pHv = &pVCpu->CTX_SUFF(pVM)->gim.s.u.Hv; 431 uint64_t const u64Tsc = TMCpuTickGet(pVCpu); /** @todo should we be passing VCPU0 always? */ 432 uint64_t const u64TscHz = pHv->cTscTicksPerSecond; 433 uint64_t const u64Tsc100NS = u64TscHz / UINT64_C(10000000); /* 100 ns */ 434 uint64_t const uTimeRefCount = (u64Tsc / u64Tsc100NS); 435 return uTimeRefCount; 436 } 437 438 439 /** 440 * Starts the synthetic timer. 441 * 442 * @param pVCpu The cross context virtual CPU structure. 443 * @param pHvStimer Pointer to the Hyper-V synthetic timer. 444 * 445 * @remarks Caller needs to hold the timer critical section. 446 * @thread Any. 447 */ 448 VMM_INT_DECL(void) gimHvStartStimer(PVMCPU pVCpu, PCGIMHVSTIMER pHvStimer) 449 { 450 PTMTIMER pTimer = pHvStimer->CTX_SUFF(pTimer); 451 Assert(TMTimerIsLockOwner(pTimer)); 452 453 uint64_t const uTimerCount = pHvStimer->uStimerCountMsr; 454 if (uTimerCount) 455 { 456 uint64_t const uTimerCountNS = uTimerCount * 100; 457 458 /* For periodic timers, 'uTimerCountNS' represents the relative interval. */ 459 if (MSR_GIM_HV_STIMER_IS_PERIODIC(pHvStimer->uStimerConfigMsr)) 460 { 461 TMTimerSetNano(pTimer, uTimerCountNS); 462 LogFlow(("GIM%u: HyperV: Started relative periodic STIMER%u with uTimerCountNS=%RU64\n", pVCpu->idCpu, 463 pHvStimer->idxStimer, uTimerCountNS)); 464 } 465 else 466 { 467 /* For one-shot timers, 'uTimerCountNS' represents an absolute expiration wrt to Hyper-V reference time, 468 we convert it to a relative time and program the timer. */ 469 uint64_t const uCurRefTimeNS = gimHvGetTimeRefCount(pVCpu) * 100; 470 if (uTimerCountNS > uCurRefTimeNS) 471 { 472 uint64_t const uRelativeNS = uTimerCountNS - uCurRefTimeNS; 473 TMTimerSetNano(pTimer, uRelativeNS); 474 LogFlow(("GIM%u: HyperV: Started one-shot relative STIMER%u with uRelativeNS=%RU64\n", pVCpu->idCpu, 475 pHvStimer->idxStimer, uRelativeNS)); 476 } 477 } 478 /** @todo frequency hinting? */ 479 } 480 } 481 482 483 /** 484 * Stops the synthetic timer for the given VCPU. 485 * 486 * @param pVCpu The cross context virtual CPU structure. 487 * @param pHvStimer Pointer to the Hyper-V synthetic timer. 488 * 489 * @remarks Caller needs to the hold the timer critical section. 490 * @thread EMT(pVCpu). 491 */ 492 static void gimHvStopStimer(PVMCPU pVCpu, PGIMHVSTIMER pHvStimer) 493 { 494 VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu); 495 496 PTMTIMER pTimer = pHvStimer->CTX_SUFF(pTimer); 497 Assert(TMTimerIsLockOwner(pTimer)); 498 499 if (TMTimerIsActive(pHvStimer->CTX_SUFF(pTimer))) 500 TMTimerStop(pHvStimer->CTX_SUFF(pTimer)); 501 } 502 416 503 417 504 /** … … 432 519 { 433 520 NOREF(pRange); 434 PVM pVM = pVCpu->CTX_SUFF(pVM);435 P GIMHV pHv = &pVM->gim.s.u.Hv;521 PVM pVM = pVCpu->CTX_SUFF(pVM); 522 PCGIMHV pHv = &pVM->gim.s.u.Hv; 436 523 437 524 switch (idMsr) 438 525 { 439 526 case MSR_GIM_HV_TIME_REF_COUNT: 440 { 441 /* Hyper-V reports the time in 100 ns units (10 MHz). */ 442 uint64_t u64Tsc = TMCpuTickGet(pVCpu); 443 uint64_t u64TscHz = pHv->cTscTicksPerSecond; 444 uint64_t u64Tsc100Ns = u64TscHz / UINT64_C(10000000); /* 100 ns */ 445 *puValue = (u64Tsc / u64Tsc100Ns); 446 return VINF_SUCCESS; 447 } 527 *puValue = gimHvGetTimeRefCount(pVCpu); 528 return VINF_SUCCESS; 448 529 449 530 case MSR_GIM_HV_VP_INDEX: … … 452 533 453 534 case MSR_GIM_HV_TPR: 454 return PDMApicReadMsr(pVCpu, MSR_IA32_X2APIC_TPR, puValue); 535 *puValue = APICHvGetTpr(pVCpu); 536 return VINF_SUCCESS; 455 537 456 538 case MSR_GIM_HV_ICR: 457 return PDMApicReadMsr(pVCpu, MSR_IA32_X2APIC_ICR, puValue); 539 *puValue = APICHvGetIcr(pVCpu); 540 return VINF_SUCCESS; 458 541 459 542 case MSR_GIM_HV_GUEST_OS_ID: … … 491 574 { 492 575 PGIMHVCPU pHvCpu = &pVCpu->gim.s.u.HvCpu; 493 *puValue = pHvCpu->auSintXMsr[idMsr - MSR_GIM_HV_SINT0]; 576 *puValue = pHvCpu->auSintMsrs[idMsr - MSR_GIM_HV_SINT0]; 577 return VINF_SUCCESS; 578 } 579 580 case MSR_GIM_HV_STIMER0_CONFIG: 581 case MSR_GIM_HV_STIMER1_CONFIG: 582 case MSR_GIM_HV_STIMER2_CONFIG: 583 case MSR_GIM_HV_STIMER3_CONFIG: 584 { 585 PGIMHVCPU pHvCpu = &pVCpu->gim.s.u.HvCpu; 586 uint8_t const idxStimer = (idMsr - MSR_GIM_HV_STIMER0_CONFIG) >> 1; 587 PCGIMHVSTIMER pcHvStimer = &pHvCpu->aStimers[idxStimer]; 588 *puValue = pcHvStimer->uStimerConfigMsr; 589 return VINF_SUCCESS; 590 } 591 592 case MSR_GIM_HV_STIMER0_COUNT: 593 case MSR_GIM_HV_STIMER1_COUNT: 594 case MSR_GIM_HV_STIMER2_COUNT: 595 case MSR_GIM_HV_STIMER3_COUNT: 596 { 597 PGIMHVCPU pHvCpu = &pVCpu->gim.s.u.HvCpu; 598 uint8_t const idxStimer = (idMsr - MSR_GIM_HV_STIMER0_COUNT) >> 1; 599 PCGIMHVSTIMER pcHvStimer = &pHvCpu->aStimers[idxStimer]; 600 *puValue = pcHvStimer->uStimerCountMsr; 601 return VINF_SUCCESS; 602 } 603 604 case MSR_GIM_HV_EOM: 605 { 606 *puValue = 0; 607 return VINF_SUCCESS; 608 } 609 610 case MSR_GIM_HV_SCONTROL: 611 { 612 PGIMHVCPU pHvCpu = &pVCpu->gim.s.u.HvCpu; 613 *puValue = pHvCpu->uSControlMsr; 494 614 return VINF_SUCCESS; 495 615 } … … 580 700 { 581 701 case MSR_GIM_HV_TPR: 582 return PDMApicWriteMsr(pVCpu, MSR_IA32_X2APIC_TPR, uRawValue);702 return APICHvSetTpr(pVCpu, uRawValue); 583 703 584 704 case MSR_GIM_HV_EOI: 585 return PDMApicWriteMsr(pVCpu, MSR_IA32_X2APIC_EOI, uRawValue);705 return APICHvSetEoi(pVCpu, uRawValue); 586 706 587 707 case MSR_GIM_HV_ICR: 588 return PDMApicWriteMsr(pVCpu, MSR_IA32_X2APIC_ICR, uRawValue);708 return APICHvSetIcr(pVCpu, uRawValue); 589 709 590 710 case MSR_GIM_HV_GUEST_OS_ID: … … 734 854 else 735 855 { 736 LogRelMax(5, ("GIM : HyperV%u: APIC-assist page address %#RGp invalid!\n", pVCpu->idCpu,856 LogRelMax(5, ("GIM%u: HyperV: APIC-assist page address %#RGp invalid!\n", pVCpu->idCpu, 737 857 GCPhysApicAssistPage)); 738 858 } … … 905 1025 } 906 1026 else 907 LogRelMax(5, ("GIM: HyperV: Debug receive buffer address %#RGp invalid! Ignoring debug read!\n", (RTGCPHYS)pHv->uDbgRecvBufferMsr)); 1027 { 1028 LogRelMax(5, ("GIM: HyperV: Debug receive buffer address %#RGp invalid! Ignoring debug read!\n", 1029 (RTGCPHYS)pHv->uDbgRecvBufferMsr)); 1030 } 908 1031 } 909 1032 return VINF_SUCCESS; … … 916 1039 case MSR_GIM_HV_SINT12: case MSR_GIM_HV_SINT13: case MSR_GIM_HV_SINT14: case MSR_GIM_HV_SINT15: 917 1040 { 918 #ifndef IN_RING3 919 /** @todo make this RZ later? */ 920 return VINF_CPUM_R3_MSR_WRITE; 921 #else 922 PGIMHVCPU pHvCpu = &pVCpu->gim.s.u.HvCpu; 923 uint8_t uVector = MSR_GIM_HV_SINT_VECTOR(uRawValue); 1041 uint8_t uVector = MSR_GIM_HV_SINT_GET_VECTOR(uRawValue); 924 1042 bool const fVMBusMsg = RT_BOOL(idMsr == GIM_HV_VMBUS_MSG_SINT); 925 1043 size_t const idxSintMsr = idMsr - MSR_GIM_HV_SINT0; … … 927 1045 if (uVector < GIM_HV_SINT_VECTOR_VALID_MIN) 928 1046 { 929 LogRel(("GIM : HyperV%u: Programmed an invalid vector in SINT%u (%s), uVector=%u -> #GP(0)\n", pVCpu->idCpu,1047 LogRel(("GIM%u: HyperV: Programmed an invalid vector in SINT%u (%s), uVector=%u -> #GP(0)\n", pVCpu->idCpu, 930 1048 idxSintMsr, pszDesc, uVector)); 931 1049 return VERR_CPUM_RAISE_GP_0; 932 1050 } 933 1051 934 pHvCpu->auSintXMsr[idxSintMsr] = uRawValue; 1052 PGIMHVCPU pHvCpu = &pVCpu->gim.s.u.HvCpu; 1053 pHvCpu->auSintMsrs[idxSintMsr] = uRawValue; 935 1054 if (fVMBusMsg) 936 1055 { 937 1056 if (MSR_GIM_HV_SINT_IS_MASKED(uRawValue)) 938 Log Rel(("GIM: HyperV%u: Masked SINT%u (%s)\n", pVCpu->idCpu, idxSintMsr, pszDesc));1057 Log(("GIM%u: HyperV: Masked SINT%u (%s)\n", pVCpu->idCpu, idxSintMsr, pszDesc)); 939 1058 else 940 LogRel(("GIM: HyperV%u: Unmasked SINT%u (%s), uVector=%u\n", pVCpu->idCpu, idxSintMsr, pszDesc, uVector)); 941 } 942 return VINF_SUCCESS; 943 #endif 1059 Log(("GIM%u: HyperV: Unmasked SINT%u (%s), uVector=%u\n", pVCpu->idCpu, idxSintMsr, pszDesc, uVector)); 1060 } 1061 Log(("GIM%u: HyperV: Written SINT%u=%#RX64\n", pVCpu->idCpu, idxSintMsr, uRawValue)); 1062 return VINF_SUCCESS; 1063 } 1064 1065 case MSR_GIM_HV_SCONTROL: 1066 { 1067 #ifndef IN_RING3 1068 /** @todo make this RZ later? */ 1069 return VINF_CPUM_R3_MSR_WRITE; 1070 #else 1071 PGIMHVCPU pHvCpu = &pVCpu->gim.s.u.HvCpu; 1072 pHvCpu->uSControlMsr = uRawValue; 1073 if (MSR_GIM_HV_SCONTROL_IS_ENABLED(uRawValue)) 1074 LogRel(("GIM%u: HyperV: Synthetic interrupt control enabled\n", pVCpu->idCpu)); 1075 else 1076 LogRel(("GIM%u: HyperV: Synthetic interrupt control disabled\n", pVCpu->idCpu)); 1077 return VINF_SUCCESS; 1078 #endif 1079 } 1080 1081 case MSR_GIM_HV_STIMER0_CONFIG: 1082 case MSR_GIM_HV_STIMER1_CONFIG: 1083 case MSR_GIM_HV_STIMER2_CONFIG: 1084 case MSR_GIM_HV_STIMER3_CONFIG: 1085 { 1086 PGIMHVCPU pHvCpu = &pVCpu->gim.s.u.HvCpu; 1087 uint8_t const idxStimer = (idMsr - MSR_GIM_HV_STIMER0_CONFIG) >> 1; 1088 1089 /* Validate the writable bits. */ 1090 if (RT_LIKELY(!(uRawValue & ~MSR_GIM_HV_STIMER_RW_VALID))) 1091 { 1092 Assert(idxStimer < RT_ELEMENTS(pHvCpu->aStimers)); 1093 PGIMHVSTIMER pHvStimer = &pHvCpu->aStimers[idxStimer]; 1094 PTMTIMER pTimer = pHvStimer->CTX_SUFF(pTimer); 1095 1096 /* Lock to prevent concurrent access from the timer callback. */ 1097 int rc = TMTimerLock(pTimer, VERR_IGNORED); 1098 if (rc == VINF_SUCCESS) 1099 { 1100 /* Update the MSR value. */ 1101 pHvStimer->uStimerConfigMsr = uRawValue; 1102 Log(("GIM%u: HyperV: Set STIMER_CONFIG%u=%#RX64\n", pVCpu->idCpu, idxStimer, uRawValue)); 1103 1104 /* Process the MSR bits. */ 1105 if ( !MSR_GIM_HV_STIMER_GET_SINTX(uRawValue) /* Writing SINTx as 0 causes the timer to be disabled. */ 1106 || !MSR_GIM_HV_STIMER_IS_ENABLED(uRawValue)) 1107 { 1108 pHvStimer->uStimerConfigMsr &= ~MSR_GIM_HV_STIMER_ENABLE; 1109 gimHvStopStimer(pVCpu, pHvStimer); 1110 Log(("GIM%u: HyperV: Disabled STIMER_CONFIG%u\n", pVCpu->idCpu, idxStimer)); 1111 } 1112 else if (MSR_GIM_HV_STIMER_IS_ENABLED(uRawValue)) 1113 { 1114 /* Auto-enable implies writing to the STIMERx_COUNT MSR is what starts the timer. */ 1115 if (!MSR_GIM_HV_STIMER_IS_AUTO_ENABLED(uRawValue)) 1116 { 1117 if (!TMTimerIsActive(pHvStimer->CTX_SUFF(pTimer))) 1118 { 1119 gimHvStartStimer(pVCpu, pHvStimer); 1120 Log(("GIM%u: HyperV: Started STIMER%u\n", pVCpu->idCpu, idxStimer)); 1121 } 1122 else 1123 { 1124 /* 1125 * Enabling a timer that's already enabled is undefined behaviour, 1126 * see Hyper-V spec. 15.3.1 "Synthetic Timer Configuration Register". 1127 * 1128 * Our implementation just re-starts the timer. Guests that comform to 1129 * the Hyper-V specs. should not be doing this anyway. 1130 */ 1131 AssertFailed(); 1132 gimHvStopStimer(pVCpu, pHvStimer); 1133 gimHvStartStimer(pVCpu, pHvStimer); 1134 } 1135 } 1136 } 1137 1138 TMTimerUnlock(pTimer); 1139 } 1140 return rc; 1141 } 1142 #ifndef IN_RING3 1143 return VINF_CPUM_R3_MSR_WRITE; 1144 #else 1145 LogRel(("GIM%u: HyperV: Setting reserved bits of STIMER%u MSR (uRawValue=%#RX64) -> #GP(0)\n", pVCpu->idCpu, 1146 idxStimer, uRawValue)); 1147 return VERR_CPUM_RAISE_GP_0; 1148 #endif 1149 } 1150 1151 case MSR_GIM_HV_STIMER0_COUNT: 1152 case MSR_GIM_HV_STIMER1_COUNT: 1153 case MSR_GIM_HV_STIMER2_COUNT: 1154 case MSR_GIM_HV_STIMER3_COUNT: 1155 { 1156 PGIMHVCPU pHvCpu = &pVCpu->gim.s.u.HvCpu; 1157 uint8_t const idxStimer = (idMsr - MSR_GIM_HV_STIMER0_CONFIG) >> 1; 1158 Assert(idxStimer < RT_ELEMENTS(pHvCpu->aStimers)); 1159 PGIMHVSTIMER pHvStimer = &pHvCpu->aStimers[idxStimer]; 1160 int const rcBusy = VINF_CPUM_R3_MSR_WRITE; 1161 1162 /* 1163 * Writing zero to this MSR disables the timer regardless of whether the auto-enable 1164 * flag is set in the config MSR corresponding to the timer. 1165 */ 1166 if (!uRawValue) 1167 { 1168 gimHvStopStimer(pVCpu, pHvStimer); 1169 pHvStimer->uStimerCountMsr = 0; 1170 Log(("GIM%u: HyperV: Set STIMER_COUNT%u=%RU64, stopped timer\n", pVCpu->idCpu, idxStimer, uRawValue)); 1171 return VINF_SUCCESS; 1172 } 1173 1174 /* 1175 * Concurrent writes to the config. MSR can't happen as it's serialized by way 1176 * of being done on the same EMT as this. 1177 */ 1178 if (MSR_GIM_HV_STIMER_IS_AUTO_ENABLED(pHvStimer->uStimerConfigMsr)) 1179 { 1180 PTMTIMER pTimer = pHvStimer->CTX_SUFF(pTimer); 1181 int rc = TMTimerLock(pTimer, rcBusy); 1182 if (rc == VINF_SUCCESS) 1183 { 1184 pHvStimer->uStimerCountMsr = uRawValue; 1185 gimHvStartStimer(pVCpu, pHvStimer); 1186 TMTimerUnlock(pTimer); 1187 Log(("GIM%u: HyperV: Set STIMER_COUNT%u=%RU64 %RU64 msec, auto-started timer\n", pVCpu->idCpu, idxStimer, 1188 uRawValue, (uRawValue * 100) / RT_NS_1MS_64)); 1189 } 1190 return rc; 1191 } 1192 1193 /* Simple update of the counter without any timer start/stop side-effects. */ 1194 pHvStimer->uStimerCountMsr = uRawValue; 1195 Log(("GIM%u: HyperV: Set STIMER_COUNT%u=%RU64\n", pVCpu->idCpu, idxStimer, uRawValue)); 1196 return VINF_SUCCESS; 1197 } 1198 1199 case MSR_GIM_HV_EOM: 1200 { 1201 /** @todo implement EOM. */ 1202 Log(("GIM%u: HyperV: EOM\n", pVCpu->idCpu)); 1203 return VINF_SUCCESS; 944 1204 } 945 1205 … … 949 1209 return VINF_CPUM_R3_MSR_WRITE; 950 1210 #else 951 PGIMHVCPU pHvCpu 1211 PGIMHVCPU pHvCpu = &pVCpu->gim.s.u.HvCpu; 952 1212 pHvCpu->uSiefpMsr = uRawValue; 953 1213 if (MSR_GIM_HV_SIEF_PAGE_IS_ENABLED(uRawValue)) … … 959 1219 if (RT_SUCCESS(rc)) 960 1220 { 1221 LogRel(("GIM%u: HyperV: Enabled synthetic interrupt event flags page at %#RGp\n", pVCpu->idCpu, 1222 GCPhysSiefPage)); 961 1223 /** @todo SIEF setup. */ 962 1224 return VINF_SUCCESS; … … 964 1226 } 965 1227 else 966 LogRelMax(5, ("GIM : HyperV%u: SIEF page address %#RGp invalid!\n", pVCpu->idCpu, GCPhysSiefPage));1228 LogRelMax(5, ("GIM%u: HyperV: SIEF page address %#RGp invalid!\n", pVCpu->idCpu, GCPhysSiefPage)); 967 1229 } 968 1230 else … … 976 1238 case MSR_GIM_HV_SIMP: 977 1239 { 978 if (!pHv->fDbgEnabled)979 return VERR_CPUM_RAISE_GP_0;980 1240 #ifndef IN_RING3 981 1241 return VINF_CPUM_R3_MSR_WRITE; … … 992 1252 int rc2 = PGMPhysSimpleWriteGCPhys(pVM, GCPhysSimp, &abSimp[0], sizeof(abSimp)); 993 1253 if (RT_SUCCESS(rc2)) 994 LogRel(("GIM : HyperV: Enabled synthetic interrupt message page at %#RGp\n", GCPhysSimp));1254 LogRel(("GIM%u: HyperV: Enabled synthetic interrupt message page at %#RGp\n", pVCpu->idCpu, GCPhysSimp)); 995 1255 else 996 1256 { 997 LogRel(("GIM : HyperV: WrMsr on MSR_GIM_HV_SIMP failed to update SIMP at %#RGp rc=%Rrc -> #GP(0)\n",998 GCPhysSimp, rc2));1257 LogRel(("GIM%u: HyperV: Failed to update synthetic interrupt message page at %#RGp. uSimpMsr=%#RX64 rc=%Rrc\n", 1258 pVCpu->idCpu, pHvCpu->uSimpMsr, GCPhysSimp, rc2)); 999 1259 return VERR_CPUM_RAISE_GP_0; 1000 1260 } 1001 1261 } 1002 1262 else 1003 LogRel(("GIM: HyperV: Enabled synthetic interrupt message page at invalid address %#RGp\n",GCPhysSimp)); 1263 { 1264 LogRel(("GIM%u: HyperV: Enabled synthetic interrupt message page at invalid address %#RGp\n", pVCpu->idCpu, 1265 GCPhysSimp)); 1266 } 1004 1267 } 1005 1268 else 1006 LogRel(("GIM : HyperV: Disabled synthetic interrupt message page\n"));1269 LogRel(("GIM%u: HyperV: Disabled synthetic interrupt message page\n", pVCpu->idCpu)); 1007 1270 return VINF_SUCCESS; 1008 1271 #endif -
trunk/src/VBox/VMM/VMMR3/GIM.cpp
r62641 r63648 347 347 } 348 348 return VINF_SUCCESS; 349 } 350 351 352 /** 353 * Applies relocations to data and code managed by this 354 * component. This function will be called at init and 355 * whenever the VMM need to relocate it self inside the GC. 356 * 357 * @param pVM The cross context VM structure. 358 * @param offDelta Relocation delta relative to old location. 359 */ 360 VMMR3_INT_DECL(void) GIMR3Relocate(PVM pVM, RTGCINTPTR offDelta) 361 { 362 switch (pVM->gim.s.enmProviderId) 363 { 364 case GIMPROVIDERID_HYPERV: 365 gimR3HvRelocate(pVM, offDelta); 366 break; 367 368 default: 369 break; 370 } 349 371 } 350 372 -
trunk/src/VBox/VMM/VMMR3/GIMHv.cpp
r62642 r63648 21 21 *********************************************************************************************************************************/ 22 22 #define LOG_GROUP LOG_GROUP_GIM 23 #include <VBox/vmm/apic.h> 23 24 #include <VBox/vmm/gim.h> 24 25 #include <VBox/vmm/cpum.h> … … 49 50 * GIM Hyper-V saved-state version. 50 51 */ 51 #define GIM_HV_SAVED_STATE_VERSION UINT32_C(2) 52 #define GIM_HV_SAVED_STATE_VERSION UINT32_C(3) 53 /** Saved states, prior to any synthetic interrupt controller support. */ 54 #define GIM_HV_SAVED_STATE_VERSION_PRE_SYNIC UINT32_C(2) 52 55 /** Vanilla saved states, prior to any debug support. */ 53 56 #define GIM_HV_SAVED_STATE_VERSION_PRE_DEBUG UINT32_C(1) … … 180 183 static void gimR3HvTermHypercallSupport(PVM pVM); 181 184 static int gimR3HvInitDebugSupport(PVM pVM); 182 #if 0 /** @todo currently unused, which is probably very wrong */183 185 static void gimR3HvTermDebugSupport(PVM pVM); 184 #endif 185 186 static DECLCALLBACK(void) gimR3HvTimerCallback(PVM pVM, PTMTIMER pTimer, void *pvUser); 186 187 187 188 /** … … 197 198 AssertReturn(pVM->gim.s.enmProviderId == GIMPROVIDERID_HYPERV, VERR_INTERNAL_ERROR_5); 198 199 199 int rc;200 200 PGIMHV pHv = &pVM->gim.s.u.Hv; 201 201 … … 209 209 * Validate the Hyper-V settings. 210 210 */ 211 rc= CFGMR3ValidateConfig(pCfgHv, "/HyperV/",211 int rc2 = CFGMR3ValidateConfig(pCfgHv, "/HyperV/", 212 212 "VendorID" 213 213 "|VSInterface" 214 214 "|HypercallDebugInterface", 215 215 "" /* pszValidNodes */, "GIM/HyperV" /* pszWho */, 0 /* uInstance */); 216 if (RT_FAILURE(rc ))217 return rc ;216 if (RT_FAILURE(rc2)) 217 return rc2; 218 218 } 219 219 … … 221 221 * The Hyper-V vendor signature, must be 12 characters. */ 222 222 char szVendor[13]; 223 rc = CFGMR3QueryStringDef(pCfgHv, "VendorID", szVendor, sizeof(szVendor), "VBoxVBoxVBox");223 int rc = CFGMR3QueryStringDef(pCfgHv, "VendorID", szVendor, sizeof(szVendor), "VBoxVBoxVBox"); 224 224 AssertLogRelRCReturn(rc, rc); 225 225 AssertLogRelMsgReturn(strlen(szVendor) == 12, … … 255 255 //| GIM_HV_BASE_FEAT_VP_RUNTIME_MSR 256 256 | GIM_HV_BASE_FEAT_PART_TIME_REF_COUNT_MSR 257 //| GIM_HV_BASE_FEAT_BASIC_SYN TH_IC258 //| GIM_HV_BASE_FEAT_S YNTH_TIMER_MSRS257 //| GIM_HV_BASE_FEAT_BASIC_SYNIC_MSRS 258 //| GIM_HV_BASE_FEAT_STIMER_MSRS 259 259 | GIM_HV_BASE_FEAT_APIC_ACCESS_MSRS 260 260 | GIM_HV_BASE_FEAT_HYPERCALL_MSRS … … 279 279 /* Hypervisor recommendations to the guest. */ 280 280 pHv->uHyperHints = GIM_HV_HINT_MSR_FOR_SYS_RESET 281 | GIM_HV_HINT_RELAX_TIME_CHECKS; 281 | GIM_HV_HINT_RELAX_TIME_CHECKS 282 //| GIM_HV_HINT_X2APIC_MSRS 283 ; 282 284 283 285 /* Expose more if we're posing as Microsoft. We can, if needed, force MSR-based Hv … … 347 349 RT_ZERO(HyperLeaf); 348 350 HyperLeaf.uLeaf = UINT32_C(0x40000000); 349 HyperLeaf.uEax = UINT32_C(0x40000006); /* Minimum value for Hyper-V is 0x40000005. */ 351 if ( pHv->fIsVendorMsHv 352 && pHv->fIsInterfaceVs) 353 HyperLeaf.uEax = UINT32_C(0x40000082); /* Since we expose 0x40000082 below for the Hyper-V PV-debugging case. */ 354 else 355 HyperLeaf.uEax = UINT32_C(0x40000006); /* Minimum value for Hyper-V default is 0x40000005. */ 350 356 /* 351 357 * Don't report vendor as 'Microsoft Hv'[1] by default, see @bugref{7270#c152}. … … 404 410 AssertLogRelRCReturn(rc, rc); 405 411 412 RT_ZERO(HyperLeaf); 413 HyperLeaf.uLeaf = UINT32_C(0x40000005); 414 rc = CPUMR3CpuIdInsert(pVM, &HyperLeaf); 415 AssertLogRelRCReturn(rc, rc); 416 417 /* Leaf 0x40000006 is inserted in gimR3HvInitCompleted(). */ 418 406 419 if ( pHv->fIsVendorMsHv 407 420 && pHv->fIsInterfaceVs) … … 437 450 for (unsigned i = 0; i < RT_ELEMENTS(g_aMsrRanges_HyperV); i++) 438 451 { 439 rc= CPUMR3MsrRangesInsert(pVM, &g_aMsrRanges_HyperV[i]);440 AssertLogRelRCReturn(rc , rc);452 int rc2 = CPUMR3MsrRangesInsert(pVM, &g_aMsrRanges_HyperV[i]); 453 AssertLogRelRCReturn(rc2, rc2); 441 454 } 442 455 … … 449 462 { 450 463 PGIMHVCPU pHvCpu = &pVM->aCpus[i].gim.s.u.HvCpu; 451 for ( size_t idxSintMsr = 0; idxSintMsr < RT_ELEMENTS(pHvCpu->auSintXMsr); idxSintMsr++)452 pHvCpu->auSint XMsr[idxSintMsr] = MSR_GIM_HV_SINT_MASKED;464 for (uint8_t idxSintMsr = 0; idxSintMsr < RT_ELEMENTS(pHvCpu->auSintMsrs); idxSintMsr++) 465 pHvCpu->auSintMsrs[idxSintMsr] = MSR_GIM_HV_SINT_MASKED; 453 466 } 454 467 … … 464 477 rc = gimR3HvInitDebugSupport(pVM); 465 478 AssertLogRelRCReturn(rc, rc); 479 480 /* 481 * Setup up the per-VCPU synthetic timers. 482 */ 483 for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++) 484 { 485 PVMCPU pVCpu = &pVM->aCpus[idCpu]; 486 PGIMHVCPU pHvCpu = &pVCpu->gim.s.u.HvCpu; 487 488 for (uint8_t idxStimer = 0; idxStimer < RT_ELEMENTS(pHvCpu->aStimers); idxStimer++) 489 { 490 PGIMHVSTIMER pHvStimer = &pHvCpu->aStimers[idxStimer]; 491 492 /* Associate the synthetic timer with its corresponding VCPU. */ 493 pHvStimer->idCpu = pVCpu->idCpu; 494 pHvStimer->idxStimer = idxStimer; 495 496 /* Create the timer and associate the context pointers. */ 497 RTStrPrintf(&pHvStimer->szTimerDesc[0], sizeof(pHvStimer->szTimerDesc), "Hyper-V[%u] Timer%u", pVCpu->idCpu, 498 idxStimer); 499 rc = TMR3TimerCreateInternal(pVM, TMCLOCK_VIRTUAL_SYNC, gimR3HvTimerCallback, pHvStimer /* pvUser */, 500 pHvStimer->szTimerDesc, &pHvStimer->pTimerR3); 501 AssertLogRelRCReturn(rc, rc); 502 pHvStimer->pTimerR0 = TMTimerR0Ptr(pHvStimer->pTimerR3); 503 pHvStimer->pTimerRC = TMTimerRCPtr(pHvStimer->pTimerR3); 504 } 505 } 506 507 /* 508 * Inform APIC whether Hyper-V compatibility mode is enabled or not. 509 */ 510 if (pHv->uHyperHints & GIM_HV_HINT_X2APIC_MSRS) 511 APICR3HvSetCompatMode(pVM, true); 512 513 /* 514 * Register statistics. 515 */ 516 for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++) 517 { 518 PVMCPU pVCpu = &pVM->aCpus[idCpu]; 519 PGIMHVCPU pHvCpu = &pVCpu->gim.s.u.HvCpu; 520 521 for (size_t idxStimer = 0; idxStimer < RT_ELEMENTS(pHvCpu->aStatStimerFired); idxStimer++) 522 { 523 int rc2 = STAMR3RegisterF(pVM, &pHvCpu->aStatStimerFired[idxStimer], STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, 524 STAMUNIT_OCCURENCES, "Number of times the synthetic timer fired.", 525 "/GIM/HyperV/%u/Stimer%u_Fired", idCpu, idxStimer); 526 AssertLogRelRCReturn(rc2, rc2); 527 } 528 } 466 529 467 530 return VINF_SUCCESS; … … 516 579 gimR3HvReset(pVM); 517 580 gimR3HvTermHypercallSupport(pVM); 581 gimR3HvTermDebugSupport(pVM); 582 583 for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++) 584 { 585 PGIMHVCPU pHvCpu = &pVM->aCpus[idCpu].gim.s.u.HvCpu; 586 for (uint8_t idxStimer = 0; idxStimer < RT_ELEMENTS(pHvCpu->aStimers); idxStimer++) 587 { 588 PGIMHVSTIMER pHvStimer = &pHvCpu->aStimers[idxStimer]; 589 TMR3TimerDestroy(pHvStimer->pTimerR3); 590 } 591 } 592 518 593 return VINF_SUCCESS; 594 } 595 596 597 /** 598 * Applies relocations to data and code managed by this 599 * component. This function will be called at init and 600 * whenever the VMM need to relocate it self inside the GC. 601 * 602 * @param pVM The cross context VM structure. 603 * @param offDelta Relocation delta relative to old location. 604 */ 605 VMMR3_INT_DECL(void) gimR3HvRelocate(PVM pVM, RTGCINTPTR offDelta) 606 { 607 RT_NOREF1(offDelta); 608 for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++) 609 { 610 PGIMHVCPU pHvCpu = &pVM->aCpus[idCpu].gim.s.u.HvCpu; 611 for (uint8_t idxStimer = 0; idxStimer < RT_ELEMENTS(pHvCpu->aStimers); idxStimer++) 612 { 613 PGIMHVSTIMER pHvStimer = &pHvCpu->aStimers[idxStimer]; 614 pHvStimer->pTimerRC = TMTimerRCPtr(pHvStimer->pTimerR3); 615 } 616 } 519 617 } 520 618 … … 568 666 { 569 667 PGIMHVCPU pHvCpu = &pVM->aCpus[i].gim.s.u.HvCpu; 668 pHvCpu->uSControlMsr = 0; 570 669 pHvCpu->uSimpMsr = 0; 571 670 pHvCpu->uSiefpMsr = 0; 572 671 pHvCpu->uApicAssistPageMsr = 0; 573 for (size_t idxSintMsr = 0; idxSintMsr < RT_ELEMENTS(pHvCpu->auSintXMsr); idxSintMsr++) 574 pHvCpu->auSintXMsr[idxSintMsr] = MSR_GIM_HV_SINT_MASKED; 672 673 for (uint8_t idxSint = 0; idxSint < RT_ELEMENTS(pHvCpu->auSintMsrs); idxSint++) 674 pHvCpu->auSintMsrs[idxSint] = MSR_GIM_HV_SINT_MASKED; 675 676 for (uint8_t idxStimer = 0; idxStimer < RT_ELEMENTS(pHvCpu->aStimers); idxStimer++) 677 { 678 PGIMHVSTIMER pHvStimer = &pHvCpu->aStimers[idxStimer]; 679 pHvStimer->uStimerConfigMsr = 0; 680 pHvStimer->uStimerCountMsr = 0; 681 } 575 682 } 576 683 } … … 741 848 PGIMHVCPU pHvCpu = &pVM->aCpus[i].gim.s.u.HvCpu; 742 849 SSMR3PutU64(pSSM, pHvCpu->uSimpMsr); 743 SSMR3PutU64(pSSM, pHvCpu->auSintXMsr[GIM_HV_VMBUS_MSG_SINT]); 850 for (size_t idxSintMsr = 0; idxSintMsr < RT_ELEMENTS(pHvCpu->auSintMsrs); idxSintMsr++) 851 SSMR3PutU64(pSSM, pHvCpu->auSintMsrs[idxSintMsr]); 744 852 } 745 853 … … 760 868 * Load the Hyper-V SSM version first. 761 869 */ 762 uint32_t uHvSavedStat Version;763 int rc = SSMR3GetU32(pSSM, &uHvSavedStat Version);870 uint32_t uHvSavedStateVersion; 871 int rc = SSMR3GetU32(pSSM, &uHvSavedStateVersion); 764 872 AssertRCReturn(rc, rc); 765 if ( uHvSavedStatVersion != GIM_HV_SAVED_STATE_VERSION 766 && uHvSavedStatVersion != GIM_HV_SAVED_STATE_VERSION_PRE_DEBUG) 873 if ( uHvSavedStateVersion != GIM_HV_SAVED_STATE_VERSION 874 && uHvSavedStateVersion != GIM_HV_SAVED_STATE_VERSION_PRE_SYNIC 875 && uHvSavedStateVersion != GIM_HV_SAVED_STATE_VERSION_PRE_DEBUG) 767 876 return SSMR3SetLoadError(pSSM, VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION, RT_SRC_POS, 768 877 N_("Unsupported Hyper-V saved-state version %u (current %u)!"), 769 uHvSavedStat Version, GIM_HV_SAVED_STATE_VERSION);878 uHvSavedStateVersion, GIM_HV_SAVED_STATE_VERSION); 770 879 771 880 /* … … 855 964 * Load the debug support data. 856 965 */ 857 if (uHvSavedStat Version > GIM_HV_SAVED_STATE_VERSION_PRE_DEBUG)966 if (uHvSavedStateVersion > GIM_HV_SAVED_STATE_VERSION_PRE_DEBUG) 858 967 { 859 968 SSMR3GetU64(pSSM, &pHv->uDbgPendingBufferMsr); … … 870 979 PGIMHVCPU pHvCpu = &pVM->aCpus[i].gim.s.u.HvCpu; 871 980 SSMR3GetU64(pSSM, &pHvCpu->uSimpMsr); 872 SSMR3GetU64(pSSM, &pHvCpu->auSintXMsr[GIM_HV_VMBUS_MSG_SINT]); 981 if (uHvSavedStateVersion <= GIM_HV_SAVED_STATE_VERSION_PRE_SYNIC) 982 SSMR3GetU64(pSSM, &pHvCpu->auSintMsrs[GIM_HV_VMBUS_MSG_SINT]); 983 else 984 { 985 for (uint8_t idxSintMsr = 0; idxSintMsr < RT_ELEMENTS(pHvCpu->auSintMsrs); idxSintMsr++) 986 SSMR3GetU64(pSSM, &pHvCpu->auSintMsrs[idxSintMsr]); 987 } 873 988 } 874 989 … … 910 1025 { 911 1026 /** @todo Inform APIC. */ 912 LogRel(("GIM : HyperV%u: Enabled APIC-assist page at %#RGp\n", pVCpu->idCpu, GCPhysApicAssistPage));1027 LogRel(("GIM%u: HyperV: Enabled APIC-assist page at %#RGp\n", pVCpu->idCpu, GCPhysApicAssistPage)); 913 1028 } 914 1029 else 915 1030 { 916 LogRelFunc(("GIM : HyperV%u: PGMPhysSimpleWriteGCPhys failed. rc=%Rrc\n", pVCpu->idCpu, rc));1031 LogRelFunc(("GIM%u: HyperV: PGMPhysSimpleWriteGCPhys failed. rc=%Rrc\n", pVCpu->idCpu, rc)); 917 1032 rc = VERR_GIM_OPERATION_FAILED; 918 1033 } … … 922 1037 } 923 1038 924 LogRelFunc(("GIM : HyperV%u: Failed to alloc %u bytes\n", pVCpu->idCpu, cbApicAssistPage));1039 LogRelFunc(("GIM%u: HyperV: Failed to alloc %u bytes\n", pVCpu->idCpu, cbApicAssistPage)); 925 1040 return VERR_NO_MEMORY; 926 1041 } … … 935 1050 VMMR3_INT_DECL(int) gimR3HvDisableApicAssistPage(PVMCPU pVCpu) 936 1051 { 937 LogRel(("GIM : HyperV%u: Disabled APIC-assist page\n", pVCpu->idCpu));1052 LogRel(("GIM%u: HyperV: Disabled APIC-assist page\n", pVCpu->idCpu)); 938 1053 /** @todo inform APIC */ 939 1054 return VINF_SUCCESS; 1055 } 1056 1057 1058 /** 1059 * Hyper-V synthetic timer callback. 1060 * 1061 * @param pVM The cross context VM structure. 1062 * @param pTimer Pointer to timer. 1063 * @param pvUser Pointer to the synthetic timer. 1064 */ 1065 static DECLCALLBACK(void) gimR3HvTimerCallback(PVM pVM, PTMTIMER pTimer, void *pvUser) 1066 { 1067 PGIMHVSTIMER pHvStimer = (PGIMHVSTIMER)pvUser; 1068 Assert(pHvStimer); 1069 Assert(TMTimerIsLockOwner(pTimer)); 1070 Assert(pHvStimer->idCpu < pVM->cCpus); 1071 1072 PVMCPU pVCpu = &pVM->aCpus[pHvStimer->idCpu]; 1073 PGIMHVCPU pHvCpu = &pVCpu->gim.s.u.HvCpu; 1074 Assert(pHvStimer->idxStimer < RT_ELEMENTS(pHvCpu->aStatStimerFired)); 1075 1076 STAM_COUNTER_INC(&pHvCpu->aStatStimerFired[pHvStimer->idxStimer]); 1077 1078 uint64_t const uStimerConfig = pHvStimer->uStimerConfigMsr; 1079 uint16_t const idxSint = MSR_GIM_HV_STIMER_GET_SINTX(uStimerConfig); 1080 if (RT_LIKELY(idxSint < RT_ELEMENTS(pHvCpu->auSintMsrs))) 1081 { 1082 uint64_t const uSint = pHvCpu->auSintMsrs[idxSint]; 1083 if (!MSR_GIM_HV_SINT_IS_MASKED(uSint)) 1084 { 1085 uint8_t const uVector = MSR_GIM_HV_SINT_GET_VECTOR(uSint); 1086 bool const fAutoEoi = MSR_GIM_HV_SINT_IS_AUTOEOI(uSint); 1087 APICHvSendInterrupt(pVCpu, uVector, fAutoEoi, XAPICTRIGGERMODE_EDGE); 1088 } 1089 } 1090 1091 /* Re-arm the timer if it's periodic. */ 1092 if (MSR_GIM_HV_STIMER_IS_PERIODIC(uStimerConfig)) 1093 gimHvStartStimer(pVCpu, pHvStimer); 940 1094 } 941 1095 … … 968 1122 { 969 1123 /** @todo SIEF setup. */ 970 LogRel(("GIM : HyperV%u: Enabled SIEF page at %#RGp\n", pVCpu->idCpu, GCPhysSiefPage));1124 LogRel(("GIM%u: HyperV: Enabled SIEF page at %#RGp\n", pVCpu->idCpu, GCPhysSiefPage)); 971 1125 } 972 1126 else 973 1127 { 974 LogRelFunc(("GIM : HyperV%u: PGMPhysSimpleWriteGCPhys failed. rc=%Rrc\n", pVCpu->idCpu, rc));1128 LogRelFunc(("GIM%u: HyperV: PGMPhysSimpleWriteGCPhys failed. rc=%Rrc\n", pVCpu->idCpu, rc)); 975 1129 rc = VERR_GIM_OPERATION_FAILED; 976 1130 } … … 980 1134 } 981 1135 982 LogRelFunc(("GIM : HyperV%u: Failed to alloc %u bytes\n", pVCpu->idCpu, cbSiefPage));1136 LogRelFunc(("GIM%u: HyperV: Failed to alloc %u bytes\n", pVCpu->idCpu, cbSiefPage)); 983 1137 return VERR_NO_MEMORY; 984 1138 } … … 993 1147 VMMR3_INT_DECL(int) gimR3HvDisableSiefPage(PVMCPU pVCpu) 994 1148 { 995 LogRel(("GIM : HyperV%u: Disabled APIC-assist page\n", pVCpu->idCpu));1149 LogRel(("GIM%u: HyperV: Disabled APIC-assist page\n", pVCpu->idCpu)); 996 1150 /** @todo SIEF teardown. */ 997 1151 return VINF_SUCCESS; … … 1142 1296 { 1143 1297 /** @todo SIM setup. */ 1144 LogRel(("GIM : HyperV%u: Enabled SIM page at %#RGp\n", pVCpu->idCpu, GCPhysSimPage));1298 LogRel(("GIM%u: HyperV: Enabled SIM page at %#RGp\n", pVCpu->idCpu, GCPhysSimPage)); 1145 1299 } 1146 1300 else 1147 1301 { 1148 LogRelFunc(("GIM : HyperV%u: PGMPhysSimpleWriteGCPhys failed. rc=%Rrc\n", pVCpu->idCpu, rc));1302 LogRelFunc(("GIM%u: HyperV: PGMPhysSimpleWriteGCPhys failed. rc=%Rrc\n", pVCpu->idCpu, rc)); 1149 1303 rc = VERR_GIM_OPERATION_FAILED; 1150 1304 } … … 1154 1308 } 1155 1309 1156 LogRelFunc(("GIM : HyperV%u: Failed to alloc %u bytes\n", pVCpu->idCpu, cbSimPage));1310 LogRelFunc(("GIM%u: HyperV: Failed to alloc %u bytes\n", pVCpu->idCpu, cbSimPage)); 1157 1311 return VERR_NO_MEMORY; 1158 1312 } … … 1167 1321 VMMR3_INT_DECL(int) gimR3HvDisableSimPage(PVMCPU pVCpu) 1168 1322 { 1169 LogRel(("GIM : HyperV%u: Disabled SIM page\n", pVCpu->idCpu));1323 LogRel(("GIM%u: HyperV: Disabled SIM page\n", pVCpu->idCpu)); 1170 1324 /** @todo SIM teardown. */ 1171 1325 return VINF_SUCCESS; … … 1400 1554 1401 1555 1402 #if 0 /** @todo currently unused, which is probably very wrong */1403 1556 /** 1404 1557 * Terminates Hyper-V guest debug support. … … 1415 1568 } 1416 1569 } 1417 #endif1418 1570 1419 1571 -
trunk/src/VBox/VMM/VMMR3/VM.cpp
r62869 r63648 1264 1264 DBGFR3Relocate(pVM, offDelta); 1265 1265 PDMR3Relocate(pVM, offDelta); 1266 GIMR3Relocate(pVM, offDelta); 1266 1267 } 1267 1268 -
trunk/src/VBox/VMM/include/GIMHvInternal.h
r62641 r63648 476 476 /** Whether the SIEF page is enabled or not. */ 477 477 #define MSR_GIM_HV_SIEF_PAGE_IS_ENABLED(a) RT_BOOL((a) & MSR_GIM_HV_SIEF_PAGE_ENABLE) 478 /** @} */ 479 480 /** @name Hyper-V MSR - Synthetic Interrupt Control (MSR_GIM_HV_CONTROL). 481 * @{ 482 */ 483 /** The SControl enable mask. */ 484 #define MSR_GIM_HV_SCONTROL_ENABLE RT_BIT_64(0) 485 /** Whether SControl is enabled or not. */ 486 #define MSR_GIM_HV_SCONTROL_IS_ENABLED(a) RT_BOOL((a) & MSR_GIM_HV_SCONTROL_ENABLE) 487 /** @} */ 488 489 /** @name Hyper-V MSR - Synthetic Timer Config (MSR_GIM_HV_STIMER_CONFIG). 490 * @{ 491 */ 492 /** The Stimer enable mask. */ 493 #define MSR_GIM_HV_STIMER_ENABLE RT_BIT_64(0) 494 /** Whether Stimer is enabled or not. */ 495 #define MSR_GIM_HV_STIMER_IS_ENABLED(a) RT_BOOL((a) & MSR_GIM_HV_STIMER_ENABLE) 496 /** The Stimer periodic mask. */ 497 #define MSR_GIM_HV_STIMER_PERIODIC RT_BIT_64(1) 498 /** Whether Stimer is enabled or not. */ 499 #define MSR_GIM_HV_STIMER_IS_PERIODIC(a) RT_BOOL((a) & MSR_GIM_HV_STIMER_PERIODIC) 500 /** The Stimer lazy mask. */ 501 #define MSR_GIM_HV_STIMER_LAZY RT_BIT_64(2) 502 /** Whether Stimer is enabled or not. */ 503 #define MSR_GIM_HV_STIMER_IS_LAZY(a) RT_BOOL((a) & MSR_GIM_HV_STIMER_LAZY) 504 /** The Stimer auto-enable mask. */ 505 #define MSR_GIM_HV_STIMER_AUTO_ENABLE RT_BIT_64(3) 506 /** Whether Stimer is enabled or not. */ 507 #define MSR_GIM_HV_STIMER_IS_AUTO_ENABLED(a) RT_BOOL((a) & MSR_GIM_HV_STIMER_AUTO_ENABLE) 508 /** The Stimer SINTx mask (bits 16:19). */ 509 #define MSR_GIM_HV_STIMER_SINTX UINT64_C(0xf0000) 510 /** Gets the Stimer synthetic interrupt source. */ 511 #define MSR_GIM_HV_STIMER_GET_SINTX(a) (((a) >> 16) & 0xf) 512 /** The Stimer valid read/write mask. */ 513 #define MSR_GIM_HV_STIMER_RW_VALID ( MSR_GIM_HV_STIMER_ENABLE | MSR_GIM_HV_STIMER_PERIODIC \ 514 | MSR_GIM_HV_STIMER_LAZY | MSR_GIM_HV_STIMER_AUTO_ENABLE \ 515 | MSR_GIM_HV_STIMER_SINTX) 478 516 /** @} */ 479 517 … … 726 764 /** Whether the interrupt source is masked. */ 727 765 #define MSR_GIM_HV_SINT_IS_MASKED(a) RT_BOOL((a) & MSR_GIM_HV_SINT_MASKED) 728 /** Interrupt vector. */ 729 #define MSR_GIM_HV_SINT_VECTOR(a) ((a) & UINT64_C(0xff)) 766 /** Gets the interrupt vector. */ 767 #define MSR_GIM_HV_SINT_GET_VECTOR(a) ((a) & UINT64_C(0xff)) 768 /** The AutoEoi mask. */ 769 #define MSR_GIM_HV_SINT_AUTOEOI RT_BIT_64(17) 770 /** Gets whether AutoEoi is enabled for the synthetic interrupt. */ 771 #define MSR_GIM_HV_SINT_IS_AUTOEOI(a) RT_BOOL((a) & MSR_GIM_HV_SINT_AUTOEOI) 730 772 /** @} */ 731 773 … … 787 829 /** SynIC version register. */ 788 830 #define GIM_HV_SVERSION 1 789 /** Number of synthetic interrupt sources . */831 /** Number of synthetic interrupt sources (warning, fixed in saved-states!). */ 790 832 #define GIM_HV_SINT_COUNT 16 791 833 /** Lowest valid vector for synthetic interrupt. */ … … 793 835 /** Highest valid vector for synthetic interrupt. */ 794 836 #define GIM_HV_SINT_VECTOR_VALID_MAX 255 837 /** Number of synthetic timers. */ 838 #define GIM_HV_STIMER_COUNT 4 795 839 /** @} */ 796 840 797 841 /** @name Hyper-V synthetic interrupt message type. 842 * See 14.8.2 "SynIC Message Types" 798 843 * @{ 799 844 */ … … 1136 1181 1137 1182 /** 1138 * GIM Hyper-V VCPU instance data. 1183 * Hyper-V per-VCPU synthetic timer. 1184 */ 1185 typedef struct GIMHVSTIMER 1186 { 1187 /** Synthetic timer object - R0 ptr. */ 1188 PTMTIMERR0 pTimerR0; 1189 /** Synthetic timer object - R3 ptr. */ 1190 PTMTIMERR3 pTimerR3; 1191 /** Synthetic timer object - RC ptr. */ 1192 PTMTIMERRC pTimerRC; 1193 /** RC alignment padding. */ 1194 RTRCPTR uAlignment0; 1195 /** Virtual CPU ID this timer belongs to (for reverse mapping). */ 1196 VMCPUID idCpu; 1197 /** The index of this timer in the auStimers array (for reverse mapping). */ 1198 uint32_t idxStimer; 1199 /** Synthetic timer config MSR. */ 1200 uint64_t uStimerConfigMsr; 1201 /** Synthetic timer count MSR. */ 1202 uint64_t uStimerCountMsr; 1203 /** Timer description. */ 1204 char szTimerDesc[24]; 1205 1206 } GIMHVSTIMER; 1207 /** Pointer to per-VCPU Hyper-V synthetic timer. */ 1208 typedef GIMHVSTIMER *PGIMHVSTIMER; 1209 /** Pointer to a const per-VCPU Hyper-V synthetic timer. */ 1210 typedef GIMHVSTIMER const *PCGIMHVSTIMER; 1211 AssertCompileSizeAlignment(GIMHVSTIMER, 8); 1212 1213 /** 1214 * Hyper-V VCPU instance data. 1139 1215 * Changes to this must checked against the padding of the gim union in VMCPU! 1140 1216 */ … … 1146 1222 uint64_t uSimpMsr; 1147 1223 /** Interrupt source MSRs. */ 1148 uint64_t auSint XMsr[GIM_HV_SINT_COUNT];1224 uint64_t auSintMsrs[GIM_HV_SINT_COUNT]; 1149 1225 /** Synethtic interrupt events flag page MSR. */ 1150 1226 uint64_t uSiefpMsr; 1151 1227 /** APIC-assist page MSR. */ 1152 1228 uint64_t uApicAssistPageMsr; 1229 /** Synthetic interrupt control MSR. */ 1230 uint64_t uSControlMsr; 1231 /** Synthetic timers. */ 1232 GIMHVSTIMER aStimers[GIM_HV_STIMER_COUNT]; 1233 /** @} */ 1234 1235 /** @name Statistics. 1236 * @{ */ 1237 STAMCOUNTER aStatStimerFired[GIM_HV_STIMER_COUNT]; 1153 1238 /** @} */ 1154 1239 } GIMHVCPU; … … 1205 1290 VMM_INT_DECL(VBOXSTRICTRC) gimHvWriteMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t uRawValue); 1206 1291 1292 VMM_INT_DECL(void) gimHvStartStimer(PVMCPU pVCpu, PCGIMHVSTIMER pHvStimer); 1293 1207 1294 RT_C_DECLS_END 1208 1295
Note:
See TracChangeset
for help on using the changeset viewer.