VirtualBox

source: vbox/trunk/src/VBox/VMM/PATM/VMMGC/PATMGC.cpp@ 552

Last change on this file since 552 was 367, checked in by vboxsync, 18 years ago

Changed counting of patch page writes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 5.1 KB
Line 
1/* $Id: PATMGC.cpp 367 2007-01-26 17:06:04Z vboxsync $ */
2/** @file
3 * PATM - Dynamic Guest OS Patching Manager - Guest Context
4 */
5
6/*
7 * Copyright (C) 2006 InnoTek Systemberatung GmbH
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * If you received this file as part of a commercial VirtualBox
18 * distribution, then only the terms of your commercial VirtualBox
19 * license agreement apply instead of the previous paragraph.
20 */
21
22
23/*******************************************************************************
24* Header Files *
25*******************************************************************************/
26#define LOG_GROUP LOG_GROUP_PATM
27#include <VBox/cpum.h>
28#include <VBox/stam.h>
29#include <VBox/patm.h>
30#include <VBox/pgm.h>
31#include <VBox/mm.h>
32#include <VBox/sup.h>
33#include <VBox/mm.h>
34#include <VBox/param.h>
35#include <iprt/avl.h>
36#include "PATMInternal.h"
37#include <VBox/vm.h>
38#include <VBox/dbg.h>
39#include <VBox/err.h>
40#include <VBox/em.h>
41#include <VBox/log.h>
42#include <iprt/assert.h>
43#include <iprt/asm.h>
44#include <iprt/string.h>
45#include <stdlib.h>
46#include <stdio.h>
47
48
49/**
50 * #PF Virtual Handler callback for Guest access a page monitored by PATM
51 *
52 * @returns VBox status code (appropritate for trap handling and GC return).
53 * @param pVM VM Handle.
54 * @param uErrorCode CPU Error code.
55 * @param pRegFrame Trap register frame.
56 * @param pvFault The fault address (cr2).
57 * @param pvRange The base address of the handled virtual range.
58 * @param offRange The offset of the access into this range.
59 * (If it's a EIP range this's the EIP, if not it's pvFault.)
60 */
61PATMGCDECL(int) PATMGCMonitorPage(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, void *pvFault, void *pvRange, uintptr_t offRange)
62{
63 pVM->patm.s.pvFaultMonitor = pvFault;
64 return VINF_PATM_CHECK_PATCH_PAGE;
65}
66
67
68/**
69 * Checks if the write is located on a page with was patched before.
70 * (if so, then we are not allowed to turn on r/w)
71 *
72 * @returns VBox status
73 * @param pVM The VM to operate on.
74 * @param pRegFrame CPU context
75 * @param GCPtr GC pointer to write address
76 * @param cbWrite Nr of bytes to write
77 *
78 */
79PATMGCDECL(int) PATMGCHandleWriteToPatchPage(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPTR GCPtr, uint32_t cbWrite)
80{
81 bool ret = false;
82 RTGCUINTPTR pWritePageStart, pWritePageEnd;
83 PPATMPATCHPAGE pPatchPage;
84
85 /* Quick boundary check */
86 if ( GCPtr < pVM->patm.s.pPatchedInstrGCLowest
87 || GCPtr > pVM->patm.s.pPatchedInstrGCHighest
88 )
89 return VERR_PATCH_NOT_FOUND;
90
91 STAM_PROFILE_ADV_START(&pVM->patm.s.StatPatchWriteDetect, a);
92
93 pWritePageStart = (RTGCUINTPTR)GCPtr & PAGE_BASE_GC_MASK;
94 pWritePageEnd = ((RTGCUINTPTR)GCPtr + cbWrite - 1) & PAGE_BASE_GC_MASK;
95
96 pPatchPage = (PPATMPATCHPAGE)RTAvloGCPtrGet(CTXSUFF(&pVM->patm.s.PatchLookupTree)->PatchTreeByPage, (RTGCPTR)pWritePageStart);
97 if ( !pPatchPage
98 && pWritePageStart != pWritePageEnd
99 )
100 {
101 pPatchPage = (PPATMPATCHPAGE)RTAvloGCPtrGet(CTXSUFF(&pVM->patm.s.PatchLookupTree)->PatchTreeByPage, (RTGCPTR)pWritePageEnd);
102 }
103
104#ifdef LOG_ENABLED
105 if (pPatchPage)
106 Log(("PATMIsWriteToPatchPage: Found page %VGv for write to %VGv %d bytes\n", pPatchPage->Core.Key, GCPtr, cbWrite));
107#endif
108
109 if (pPatchPage)
110 {
111 if ( pPatchPage->pLowestAddrGC <= (RTGCPTR)((RTGCUINTPTR)GCPtr + cbWrite)
112 || pPatchPage->pHighestAddrGC > GCPtr)
113 {
114 /* This part of the page was not patched; try to emulate the instruction. */
115 uint32_t cb;
116
117 LogFlow(("PATMHandleWriteToPatchPage: Interpret %VGv accessing %VGv\n", pRegFrame->eip, GCPtr));
118 int rc = EMInterpretInstruction(pVM, pRegFrame, GCPtr, &cb);
119 if (rc == VINF_SUCCESS)
120 {
121 STAM_COUNTER_INC(&pVM->patm.s.StatPatchWriteInterpreted);
122 STAM_PROFILE_ADV_STOP(&pVM->patm.s.StatPatchWriteDetect, a);
123 return VINF_SUCCESS;
124 }
125 STAM_COUNTER_INC(&pVM->patm.s.StatPatchWriteInterpretedFailed);
126 }
127 HCPTRTYPE(PPATCHINFO) *paPatch = (HCPTRTYPE(PPATCHINFO) *)MMHyperHC2GC(pVM, pPatchPage->aPatch);
128
129 /* Increase the invalid write counter for each patch that's registered for that page. */
130 for (uint32_t i=0;i<pPatchPage->cCount;i++)
131 {
132 PPATCHINFO pPatch = (PPATCHINFO)MMHyperHC2GC(pVM, paPatch[i]);
133
134 pPatch->cInvalidWrites++;
135 }
136
137 STAM_PROFILE_ADV_STOP(&pVM->patm.s.StatPatchWriteDetect, a);
138 return VINF_EM_RAW_EMULATE_INSTR;
139 }
140
141 STAM_PROFILE_ADV_STOP(&pVM->patm.s.StatPatchWriteDetect, a);
142 return VERR_PATCH_NOT_FOUND;
143}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette