Changeset 11925 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Sep 1, 2008 3:03:24 PM (16 years ago)
- Location:
- trunk/src/VBox/VMM/PATM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/PATM/PATM.cpp
r11311 r11925 82 82 static int patmReinit(PVM pVM); 83 83 static DECLCALLBACK(int) RelocatePatches(PAVLOU32NODECORE pNode, void *pParam); 84 static DECLCALLBACK(int) patmVirtPageHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser);85 84 86 85 #ifdef VBOX_WITH_DEBUGGER … … 819 818 * @param pvUser User argument. 820 819 */ 821 staticDECLCALLBACK(int) patmVirtPageHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser)820 DECLCALLBACK(int) patmVirtPageHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser) 822 821 { 823 822 Assert(enmAccessType == PGMACCESSTYPE_WRITE); -
trunk/src/VBox/VMM/PATM/PATMInternal.h
r11070 r11925 28 28 #include <VBox/stam.h> 29 29 #include <VBox/dis.h> 30 #include <VBox/pgm.h> 30 31 #include <iprt/avl.h> 31 32 #include <iprt/param.h> … … 521 522 DECLCALLBACK(int) patmr3Save(PVM pVM, PSSMHANDLE pSSM); 522 523 524 DECLCALLBACK(int) patmVirtPageHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser); 523 525 524 526 /** -
trunk/src/VBox/VMM/PATM/PATMSSM.cpp
r11920 r11925 56 56 #define PATM_ADD_PTR(a, b) *(uintptr_t *)&(a) = (uintptr_t)(a) + (uintptr_t)(b) 57 57 58 static void patmCorrect AbsoluteFixup(PVM pVM, PATM &patmInfo, int32_t offset, RTRCPTR *pFixup);58 static void patmCorrectFixup(PVM pVM, PATM &patmInfo, PPATCHINFO pPatch, PRELOCREC pRec, int32_t offset, RTRCPTR *pFixup); 59 59 60 60 #ifdef VBOX_STRICT … … 440 440 * Restore patch memory contents 441 441 */ 442 Log(("Restore patch memory: new %VRv old %VRv\n", pVM->patm.s.pPatchMemGC, patmInfo.pPatchMemGC)); 442 443 rc = SSMR3GetMem(pSSM, pVM->patm.s.pPatchMemHC, pVM->patm.s.cbPatchMem); 443 444 AssertRCReturn(rc, rc); … … 596 597 pFixup = (RTRCPTR *)rec.pRelocPos; 597 598 598 /* Correct absolute fixups that refer to PATM structures in the hypervisor region (their addresses might have changed). */ 599 if (rec.uType == FIXUP_ABSOLUTE) 600 patmCorrectAbsoluteFixup(pVM, patmInfo, offset, pFixup); 599 if (pPatchRec->patch.uState != PATCH_REFUSED) 600 { 601 if ( rec.uType == FIXUP_REL_JMPTOPATCH 602 && (pPatchRec->patch.flags & PATMFL_PATCHED_GUEST_CODE)) 603 { 604 Assert(pPatchRec->patch.cbPatchJump == SIZEOF_NEARJUMP32 || pPatchRec->patch.cbPatchJump == SIZEOF_NEAR_COND_JUMP32); 605 unsigned offset = (pPatchRec->patch.cbPatchJump == SIZEOF_NEARJUMP32) ? 1 : 2; 606 607 Assert(pPatchRec->patch.pPrivInstrHC); 608 rec.pRelocPos = pPatchRec->patch.pPrivInstrHC + offset; 609 pFixup = (RTRCPTR *)rec.pRelocPos; 610 } 611 612 patmCorrectFixup(pVM, patmInfo, &pPatchRec->patch, &rec, offset, pFixup); 613 } 601 614 602 615 rc = patmPatchAddReloc32(pVM, &pPatchRec->patch, rec.pRelocPos, rec.uType, rec.pSource, rec.pDest); … … 657 670 pFixup = (RTRCPTR *)pRec->pRelocPos; 658 671 659 /* Correct absolute fixups that refer to PATM structures in the hypervisor region (their addresses might have changed). */ 660 if (pRec->uType == FIXUP_ABSOLUTE) 661 patmCorrectAbsoluteFixup(pVM, patmInfo, offset, pFixup); 672 /* Correct fixups that refer to PATM structures in the hypervisor region (their addresses might have changed). */ 673 patmCorrectFixup(pVM, patmInfo, &pVM->patm.s.pGlobalPatchRec->patch, pRec, offset, pFixup); 662 674 } 663 675 … … 675 687 676 688 /** 677 * Correct absolutefixups to predefined hypervisor PATM regions. (their addresses might have changed)689 * Correct fixups to predefined hypervisor PATM regions. (their addresses might have changed) 678 690 * 679 691 * @returns VBox status code. 680 692 * @param pVM VM Handle. 681 693 * @param patmInfo Saved PATM structure 694 * @param pPatch Patch record 695 * @param pRec Relocation record 682 696 * @param offset Offset of referenced data/code 683 697 * @param pFixup Fixup address 684 698 */ 685 static void patmCorrect AbsoluteFixup(PVM pVM, PATM &patmInfo, int32_t offset, RTRCPTR *pFixup)699 static void patmCorrectFixup(PVM pVM, PATM &patmInfo, PPATCHINFO pPatch, PRELOCREC pRec, int32_t offset, RTRCPTR *pFixup) 686 700 { 687 if ( patmInfo.pPatchMemGC + offset >= patmInfo.pGCStateGC 688 && patmInfo.pPatchMemGC + offset < patmInfo.pGCStateGC + sizeof(PATMGCSTATE)) 689 { 690 LogFlow(("Changing absolute GCState from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pGCStateGC) + pVM->patm.s.pGCStateGC)); 691 *pFixup = (*pFixup - patmInfo.pGCStateGC) + pVM->patm.s.pGCStateGC; 692 } 693 else 694 if ( patmInfo.pPatchMemGC + offset >= patmInfo.pCPUMCtxGC 695 && patmInfo.pPatchMemGC + offset < patmInfo.pCPUMCtxGC + sizeof(CPUMCTX)) 696 { 697 LogFlow(("Changing absolute CPUMCTX from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pCPUMCtxGC) + pVM->patm.s.pCPUMCtxGC)); 698 *pFixup = (*pFixup - patmInfo.pCPUMCtxGC) + pVM->patm.s.pCPUMCtxGC; 699 } 700 else 701 if ( patmInfo.pPatchMemGC + offset >= patmInfo.pStatsGC 702 && patmInfo.pPatchMemGC + offset < patmInfo.pStatsGC + sizeof(CPUMCTX)) 703 { 704 LogFlow(("Changing absolute Stats from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pStatsGC) + pVM->patm.s.pStatsGC)); 705 *pFixup = (*pFixup - patmInfo.pStatsGC) + pVM->patm.s.pStatsGC; 706 } 707 else 708 if ( patmInfo.pPatchMemGC + offset >= patmInfo.pGCStackGC 709 && patmInfo.pPatchMemGC + offset < patmInfo.pGCStackGC + PATM_STACK_TOTAL_SIZE) 710 { 711 LogFlow(("Changing absolute Stats from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pGCStackGC) + pVM->patm.s.pGCStackGC)); 712 *pFixup = (*pFixup - patmInfo.pGCStackGC) + pVM->patm.s.pGCStackGC; 713 } 714 else 715 if ( patmInfo.pPatchMemGC + offset >= patmInfo.pPatchMemGC 716 && patmInfo.pPatchMemGC + offset < patmInfo.pPatchMemGC + patmInfo.cbPatchMem) 717 { 718 LogFlow(("Changing absolute Stats from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pPatchMemGC) + pVM->patm.s.pPatchMemGC)); 719 *pFixup = (*pFixup - patmInfo.pPatchMemGC) + pVM->patm.s.pPatchMemGC; 720 } 721 else 722 AssertFailed(); 723 } 701 int32_t delta = pVM->patm.s.pPatchMemGC - patmInfo.pPatchMemGC; 702 703 switch (pRec->uType) 704 { 705 case FIXUP_ABSOLUTE: 706 { 707 if (pRec->pSource && !PATMIsPatchGCAddr(pVM, pRec->pSource)) 708 break; 709 710 if ( patmInfo.pPatchMemGC + offset >= patmInfo.pGCStateGC 711 && patmInfo.pPatchMemGC + offset < patmInfo.pGCStateGC + sizeof(PATMGCSTATE)) 712 { 713 LogFlow(("Changing absolute GCState from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pGCStateGC) + pVM->patm.s.pGCStateGC)); 714 *pFixup = (*pFixup - patmInfo.pGCStateGC) + pVM->patm.s.pGCStateGC; 715 } 716 else 717 if ( patmInfo.pPatchMemGC + offset >= patmInfo.pCPUMCtxGC 718 && patmInfo.pPatchMemGC + offset < patmInfo.pCPUMCtxGC + sizeof(CPUMCTX)) 719 { 720 LogFlow(("Changing absolute CPUMCTX from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pCPUMCtxGC) + pVM->patm.s.pCPUMCtxGC)); 721 *pFixup = (*pFixup - patmInfo.pCPUMCtxGC) + pVM->patm.s.pCPUMCtxGC; 722 } 723 else 724 if ( patmInfo.pPatchMemGC + offset >= patmInfo.pStatsGC 725 && patmInfo.pPatchMemGC + offset < patmInfo.pStatsGC + sizeof(CPUMCTX)) 726 { 727 LogFlow(("Changing absolute Stats from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pStatsGC) + pVM->patm.s.pStatsGC)); 728 *pFixup = (*pFixup - patmInfo.pStatsGC) + pVM->patm.s.pStatsGC; 729 } 730 else 731 if ( patmInfo.pPatchMemGC + offset >= patmInfo.pGCStackGC 732 && patmInfo.pPatchMemGC + offset < patmInfo.pGCStackGC + PATM_STACK_TOTAL_SIZE) 733 { 734 LogFlow(("Changing absolute Stats from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pGCStackGC) + pVM->patm.s.pGCStackGC)); 735 *pFixup = (*pFixup - patmInfo.pGCStackGC) + pVM->patm.s.pGCStackGC; 736 } 737 else 738 if ( patmInfo.pPatchMemGC + offset >= patmInfo.pPatchMemGC 739 && patmInfo.pPatchMemGC + offset < patmInfo.pPatchMemGC + patmInfo.cbPatchMem) 740 { 741 LogFlow(("Changing absolute Stats from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pPatchMemGC) + pVM->patm.s.pPatchMemGC)); 742 *pFixup = (*pFixup - patmInfo.pPatchMemGC) + pVM->patm.s.pPatchMemGC; 743 } 744 else 745 AssertFailed(); 746 break; 747 } 748 749 case FIXUP_REL_JMPTOPATCH: 750 { 751 RTRCPTR pTarget = (RTRCPTR)((RTRCINTPTR)pRec->pDest + delta); 752 753 if ( pPatch->uState == PATCH_ENABLED 754 && (pPatch->flags & PATMFL_PATCHED_GUEST_CODE)) 755 { 756 uint8_t oldJump[SIZEOF_NEAR_COND_JUMP32]; 757 uint8_t temp[SIZEOF_NEAR_COND_JUMP32]; 758 RTRCPTR pJumpOffGC; 759 RTRCINTPTR displ = (RTRCINTPTR)pTarget - (RTRCINTPTR)pRec->pSource; 760 RTRCINTPTR displOld= (RTRCINTPTR)pRec->pDest - (RTRCINTPTR)pRec->pSource; 761 762 Log(("Relative fixup (g2p) %08X -> %08X at %08X (source=%08x, target=%08x)\n", *(int32_t*)pRec->pRelocPos, displ, pRec->pRelocPos, pRec->pSource, pRec->pDest)); 763 764 Assert(pRec->pSource - pPatch->cbPatchJump == pPatch->pPrivInstrGC); 765 #ifdef PATM_RESOLVE_CONFLICTS_WITH_JUMP_PATCHES 766 if (pPatch->cbPatchJump == SIZEOF_NEAR_COND_JUMP32) 767 { 768 Assert(pPatch->flags & PATMFL_JUMP_CONFLICT); 769 770 pJumpOffGC = pPatch->pPrivInstrGC + 2; //two byte opcode 771 oldJump[0] = pPatch->aPrivInstr[0]; 772 oldJump[1] = pPatch->aPrivInstr[1]; 773 *(RTRCUINTPTR *)&oldJump[2] = displOld; 774 } 775 else 776 #endif 777 if (pPatch->cbPatchJump == SIZEOF_NEARJUMP32) 778 { 779 pJumpOffGC = pPatch->pPrivInstrGC + 1; //one byte opcode 780 oldJump[0] = 0xE9; 781 *(RTRCUINTPTR *)&oldJump[1] = displOld; 782 } 783 else 784 { 785 AssertMsgFailed(("Invalid patch jump size %d\n", pPatch->cbPatchJump)); 786 break; 787 } 788 Assert(pPatch->cbPatchJump <= sizeof(temp)); 789 790 /* 791 * Read old patch jump and compare it to the one we previously installed 792 */ 793 int rc = PGMPhysReadGCPtr(pVM, temp, pPatch->pPrivInstrGC, pPatch->cbPatchJump); 794 Assert(VBOX_SUCCESS(rc) || rc == VERR_PAGE_NOT_PRESENT || rc == VERR_PAGE_TABLE_NOT_PRESENT); 795 796 if (rc == VERR_PAGE_NOT_PRESENT || rc == VERR_PAGE_TABLE_NOT_PRESENT) 797 { 798 RTRCPTR pPage = pPatch->pPrivInstrGC & PAGE_BASE_GC_MASK; 799 800 rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_ALL, pPage, pPage + (PAGE_SIZE - 1) /* inclusive! */, 0, patmVirtPageHandler, "PATMGCMonitorPage", 0, "PATMMonitorPatchJump"); 801 Assert(VBOX_SUCCESS(rc) || rc == VERR_PGM_HANDLER_VIRTUAL_CONFLICT); 802 } 803 else 804 if (memcmp(temp, oldJump, pPatch->cbPatchJump)) 805 { 806 Log(("PATM: Patch jump was overwritten -> disabling patch!!\n")); 807 /* 808 * Disable patch; this is not a good solution 809 */ 810 /* @todo hopefully it was completely overwritten (if the read was successful)!!!! */ 811 pPatch->uState = PATCH_DISABLED; 812 } 813 else 814 if (VBOX_SUCCESS(rc)) 815 { 816 rc = PGMPhysWriteGCPtrDirty(pVM, pJumpOffGC, &displ, sizeof(displ)); 817 AssertRC(rc); 818 } 819 else 820 { 821 AssertMsgFailed(("Unexpected error %d from MMR3PhysReadGCVirt\n", rc)); 822 } 823 } 824 else 825 { 826 Log(("Skip the guest jump to patch code for this disabled patch %08X - %08X\n", pPatch->pPrivInstrHC, pRec->pRelocPos)); 827 } 828 829 pRec->pDest = pTarget; 830 break; 831 } 832 833 case FIXUP_REL_JMPTOGUEST: 834 { 835 RTRCPTR pSource = (RTRCPTR)((RTRCINTPTR)pRec->pSource + delta); 836 RTRCINTPTR displ = (RTRCINTPTR)pRec->pDest - (RTRCINTPTR)pSource; 837 838 Assert(!(pPatch->flags & PATMFL_GLOBAL_FUNCTIONS)); 839 Log(("Relative fixup (p2g) %08X -> %08X at %08X (source=%08x, target=%08x)\n", *(int32_t*)pRec->pRelocPos, displ, pRec->pRelocPos, pRec->pSource, pRec->pDest)); 840 *(RTRCUINTPTR *)pRec->pRelocPos = displ; 841 pRec->pSource = pSource; 842 break; 843 844 } 845 } 846 } 847
Note:
See TracChangeset
for help on using the changeset viewer.