Changeset 56672 in vbox for trunk/src/VBox
- Timestamp:
- Jun 29, 2015 12:53:55 PM (9 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/GIMR0Hv.cpp
r56287 r56672 99 99 return VERR_GIM_PVTSC_NOT_ENABLED; 100 100 101 /** @todo this is buggy when large pages are used due to a PGM limitation, see 102 * @bugref{7532}. 103 * 104 * In any case, we do not ever update this page while the guest is 105 * running after setting it up (in ring-3, see gimR3HvEnableTscPage()) as 106 * the TSC offset is handled in the VMCS/VMCB (HM) or by trapping RDTSC 107 * (raw-mode). */ 108 #if 0 101 109 PCGIMHV pcHv = &pVM->gim.s.u.Hv; 102 110 PCGIMMMIO2REGION pcRegion = &pcHv->aMmio2Regions[GIM_HV_REF_TSC_PAGE_REGION_IDX]; … … 128 136 Assert(pRefTsc->u32TscSequence != 0); 129 137 Assert(pRefTsc->u32TscSequence != UINT32_C(0xffffffff)); 138 #endif 130 139 return VINF_SUCCESS; 131 140 } -
trunk/src/VBox/VMM/VMMR3/GIMHv.cpp
r55439 r56672 131 131 pRegion->iRegion = GIM_HV_HYPERCALL_PAGE_REGION_IDX; 132 132 pRegion->fRCMapping = false; 133 pRegion->cbRegion = PAGE_SIZE; 133 pRegion->cbRegion = PAGE_SIZE; /* Sanity checked in gimR3HvLoad(), gimR3HvEnableTscPage() & gimR3HvEnableHypercallPage() */ 134 134 pRegion->GCPhysPage = NIL_RTGCPHYS; 135 135 RTStrCopy(pRegion->szDescription, sizeof(pRegion->szDescription), "Hyper-V hypercall page"); … … 138 138 pRegion->iRegion = GIM_HV_REF_TSC_PAGE_REGION_IDX; 139 139 pRegion->fRCMapping = false; 140 pRegion->cbRegion = PAGE_SIZE; 140 pRegion->cbRegion = PAGE_SIZE; /* Sanity checked in gimR3HvLoad(), gimR3HvEnableTscPage() & gimR3HvEnableHypercallPage() */ 141 141 pRegion->GCPhysPage = NIL_RTGCPHYS; 142 142 RTStrCopy(pRegion->szDescription, sizeof(pRegion->szDescription), "Hyper-V TSC page"); … … 479 479 rc = SSMR3GetStrZ(pSSM, pRegion->szDescription, sizeof(pRegion->szDescription)); 480 480 AssertRCReturn(rc, rc); 481 482 if (pRegion->cbRegion != PAGE_SIZE) 483 return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Hypercall page region size %u invalid, expected %u"), 484 pRegion->cbRegion, PAGE_SIZE); 485 481 486 if (MSR_GIM_HV_HYPERCALL_IS_ENABLED(pHv->u64HypercallMsr)) 482 487 { … … 505 510 rc = SSMR3GetU32(pSSM, &uTscSequence); 506 511 AssertRCReturn(rc, rc); 512 513 if (pRegion->cbRegion != PAGE_SIZE) 514 return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("TSC page region size %u invalid, expected %u"), 515 pRegion->cbRegion, PAGE_SIZE); 516 507 517 if (MSR_GIM_HV_REF_TSC_IS_ENABLED(pHv->u64TscPageMsr)) 508 518 { … … 560 570 */ 561 571 Assert(!pRegion->fMapped); 572 573 /** @todo this is buggy when large pages are used due to a PGM limitation, see 574 * @bugref{7532}. Instead of the overlay style mapping, we just 575 * rewrite guest memory directly. */ 576 #if 0 562 577 rc = GIMR3Mmio2Map(pVM, pRegion, GCPhysTscPage); 563 578 if (RT_SUCCESS(rc)) … … 592 607 else 593 608 LogRelFunc(("GIMR3Mmio2Map failed. rc=%Rrc\n", rc)); 594 595 609 return VERR_GIM_OPERATION_FAILED; 610 #else 611 AssertReturn(pRegion->cbRegion == PAGE_SIZE, VERR_GIM_IPE_2); 612 PGIMHVREFTSC pRefTsc = (PGIMHVREFTSC)RTMemAllocZ(PAGE_SIZE); 613 if (RT_UNLIKELY(!pRefTsc)) 614 { 615 LogRelFunc(("Failed to alloc %u bytes\n", PAGE_SIZE)); 616 return VERR_NO_MEMORY; 617 } 618 619 uint64_t const u64TscKHz = TMCpuTicksPerSecond(pVM) / UINT64_C(1000); 620 uint32_t u32TscSeq = 1; 621 if ( fUseThisTscSeq 622 && uTscSeq < UINT32_C(0xfffffffe)) 623 u32TscSeq = uTscSeq + 1; 624 pRefTsc->u32TscSequence = u32TscSeq; 625 pRefTsc->u64TscScale = ((INT64_C(10000) << 32) / u64TscKHz) << 32; 626 pRefTsc->i64TscOffset = 0; 627 628 rc = PGMPhysSimpleWriteGCPhys(pVM, GCPhysTscPage, pRefTsc, sizeof(*pRefTsc)); 629 if (RT_SUCCESS(rc)) 630 { 631 LogRel(("GIM: HyperV: Enabled TSC page at %#RGp - u64TscScale=%#RX64 u64TscKHz=%#RX64 (%'RU64) Seq=%#RU32\n", 632 GCPhysTscPage, pRefTsc->u64TscScale, u64TscKHz, u64TscKHz, pRefTsc->u32TscSequence)); 633 634 pRegion->GCPhysPage = GCPhysTscPage; 635 pRegion->fMapped = true; 636 TMR3CpuTickParavirtEnable(pVM); 637 } 638 else 639 { 640 LogRelFunc(("GIM: HyperV: PGMPhysSimpleWriteGCPhys failed. rc=%Rrc\n", rc)); 641 rc = VERR_GIM_OPERATION_FAILED; 642 } 643 RTMemFree(pRefTsc); 644 return rc; 645 #endif 596 646 } 597 647 … … 609 659 if (pRegion->fMapped) 610 660 { 661 #if 0 611 662 GIMR3Mmio2Unmap(pVM, pRegion); 612 663 Assert(!pRegion->fMapped); 664 #else 665 pRegion->fMapped = false; 666 #endif 613 667 LogRel(("GIM: HyperV: Disabled TSC-page\n")); 614 668 … … 631 685 if (pRegion->fMapped) 632 686 { 687 #if 0 633 688 GIMR3Mmio2Unmap(pVM, pRegion); 634 689 Assert(!pRegion->fMapped); 690 #else 691 pRegion->fMapped = false; 692 #endif 635 693 for (VMCPUID i = 0; i < pVM->cCpus; i++) 636 694 VMMHypercallsDisable(&pVM->aCpus[i]); … … 674 732 */ 675 733 Assert(!pRegion->fMapped); 734 735 /** @todo this is buggy when large pages are used due to a PGM limitation, see 736 * @bugref{7532}. Instead of the overlay style mapping, we just 737 * rewrite guest memory directly. */ 738 #if 0 676 739 int rc = GIMR3Mmio2Map(pVM, pRegion, GCPhysHypercallPage); 677 740 if (RT_SUCCESS(rc)) … … 711 774 LogRel(("GIM: HyperV: GIMR3Mmio2Map failed. rc=%Rrc\n", rc)); 712 775 return rc; 713 } 714 776 #else 777 AssertReturn(pRegion->cbRegion == PAGE_SIZE, VERR_GIM_IPE_3); 778 void *pvHypercallPage = RTMemAllocZ(PAGE_SIZE); 779 if (RT_UNLIKELY(!pvHypercallPage)) 780 { 781 LogRelFunc(("Failed to alloc %u bytes\n", PAGE_SIZE)); 782 return VERR_NO_MEMORY; 783 } 784 785 /* 786 * Patch the hypercall-page. 787 */ 788 size_t cbWritten = 0; 789 int rc = VMMPatchHypercall(pVM, pvHypercallPage, PAGE_SIZE, &cbWritten); 790 if ( RT_SUCCESS(rc) 791 && cbWritten < PAGE_SIZE) 792 { 793 uint8_t *pbLast = (uint8_t *)pvHypercallPage + cbWritten; 794 *pbLast = 0xc3; /* RET */ 795 796 rc = PGMPhysSimpleWriteGCPhys(pVM, GCPhysHypercallPage, pvHypercallPage, PAGE_SIZE); 797 if (RT_SUCCESS(rc)) 798 { 799 /* 800 * Notify VMM that hypercalls are now enabled for all VCPUs. 801 */ 802 for (VMCPUID i = 0; i < pVM->cCpus; i++) 803 VMMHypercallsEnable(&pVM->aCpus[i]); 804 805 pRegion->GCPhysPage = GCPhysHypercallPage; 806 pRegion->fMapped = true; 807 LogRel(("GIM: HyperV: Enabled hypercalls at %#RGp\n", GCPhysHypercallPage)); 808 } 809 else 810 LogRel(("GIM: HyperV: PGMPhysSimpleWriteGCPhys failed during hypercall page setup. rc=%Rrc\n", rc)); 811 } 812 else 813 { 814 if (rc == VINF_SUCCESS) 815 rc = VERR_GIM_OPERATION_FAILED; 816 LogRel(("GIM: HyperV: VMMPatchHypercall failed. rc=%Rrc cbWritten=%u\n", rc, cbWritten)); 817 } 818 819 RTMemFree(pvHypercallPage); 820 return rc; 821 #endif 822 } 823
Note:
See TracChangeset
for help on using the changeset viewer.