VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMGC/MMRamGC.cpp@ 30338

Last change on this file since 30338 was 30338, checked in by vboxsync, 14 years ago

EM,IOM: Don't try write directly to the fault address as the backing page might be read-only (shared page, write monitored page or zero page) and require special handle. Took the simple way out, which is to take the same path as in ring-0/3. Converted the remaining EMGCA.asm bits to EMAllA.asm code.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 5.2 KB
Line 
1/* $Id: MMRamGC.cpp 30338 2010-06-21 14:48:17Z vboxsync $ */
2/** @file
3 * MMRamGC - Guest Context Ram access Routines, pair for MMRamGCA.asm.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Oracle Corporation
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 (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#define LOG_GROUP LOG_GROUP_MM
23#include <VBox/mm.h>
24#include <VBox/cpum.h>
25#include <VBox/trpm.h>
26#include <VBox/em.h>
27#include "MMInternal.h"
28#include <VBox/vm.h>
29#include <VBox/vmm.h>
30#include <VBox/pgm.h>
31
32#include <iprt/assert.h>
33#include <VBox/param.h>
34#include <VBox/err.h>
35
36
37/*******************************************************************************
38* Internal Functions *
39*******************************************************************************/
40static DECLCALLBACK(int) mmGCRamTrap0eHandler(PVM pVM, PCPUMCTXCORE pRegFrame);
41
42DECLASM(void) MMGCRamReadNoTrapHandler_EndProc(void);
43DECLASM(void) MMGCRamWriteNoTrapHandler_EndProc(void);
44DECLASM(void) MMGCRamRead_Error(void);
45DECLASM(void) MMGCRamWrite_Error(void);
46
47
48/**
49 * Install MMGCRam Hypervisor page fault handler for normal working
50 * of MMGCRamRead and MMGCRamWrite calls.
51 * This handler will be automatically removed at page fault.
52 * In other case it must be removed by MMGCRamDeregisterTrapHandler call.
53 *
54 * @param pVM VM handle.
55 */
56VMMRCDECL(void) MMGCRamRegisterTrapHandler(PVM pVM)
57{
58 TRPMGCSetTempHandler(pVM, 0xe, mmGCRamTrap0eHandler);
59}
60
61
62/**
63 * Remove MMGCRam Hypervisor page fault handler.
64 * See description of MMGCRamRegisterTrapHandler call.
65 *
66 * @param pVM VM handle.
67 */
68VMMRCDECL(void) MMGCRamDeregisterTrapHandler(PVM pVM)
69{
70 TRPMGCSetTempHandler(pVM, 0xe, NULL);
71}
72
73
74/**
75 * Read data in guest context with #PF control.
76 *
77 * @returns VBox status.
78 * @param pVM The VM handle.
79 * @param pDst Where to store the readed data.
80 * @param pSrc Pointer to the data to read.
81 * @param cb Size of data to read, only 1/2/4/8 is valid.
82 */
83VMMRCDECL(int) MMGCRamRead(PVM pVM, void *pDst, void *pSrc, size_t cb)
84{
85 int rc;
86 PVMCPU pVCpu = VMMGetCpu0(pVM);
87
88 TRPMSaveTrap(pVCpu); /* save the current trap info, because it will get trashed if our access failed. */
89
90 MMGCRamRegisterTrapHandler(pVM);
91 rc = MMGCRamReadNoTrapHandler(pDst, pSrc, cb);
92 MMGCRamDeregisterTrapHandler(pVM);
93 if (RT_FAILURE(rc))
94 TRPMRestoreTrap(pVCpu);
95
96 return rc;
97}
98
99
100/**
101 * Write data in guest context with #PF control.
102 *
103 * @returns VBox status.
104 * @param pVM The VM handle.
105 * @param pDst Where to write the data.
106 * @param pSrc Pointer to the data to write.
107 * @param cb Size of data to write, only 1/2/4 is valid.
108 *
109 * @deprecated Don't use this as it doesn't check the page state.
110 */
111VMMRCDECL(int) MMGCRamWrite(PVM pVM, void *pDst, void *pSrc, size_t cb)
112{
113 PVMCPU pVCpu = VMMGetCpu0(pVM);
114 TRPMSaveTrap(pVCpu); /* save the current trap info, because it will get trashed if our access failed. */
115
116 MMGCRamRegisterTrapHandler(pVM);
117 int rc = MMGCRamWriteNoTrapHandler(pDst, pSrc, cb);
118 MMGCRamDeregisterTrapHandler(pVM);
119 if (RT_FAILURE(rc))
120 TRPMRestoreTrap(pVCpu);
121
122 /*
123 * And mark the relevant guest page as accessed and dirty.
124 */
125 PGMGstModifyPage(VMMGetCpu0(pVM), (RTGCPTR)(RTRCUINTPTR)pDst, cb, X86_PTE_A | X86_PTE_D, ~(uint64_t)(X86_PTE_A | X86_PTE_D));
126
127 return rc;
128}
129
130
131/**
132 * \#PF Handler for servicing traps inside MMGCRamReadNoTrapHandler and MMGCRamWriteNoTrapHandler functions.
133 *
134 * @internal
135 */
136DECLCALLBACK(int) mmGCRamTrap0eHandler(PVM pVM, PCPUMCTXCORE pRegFrame)
137{
138 /*
139 * Page fault inside MMGCRamRead()? Resume at *_Error.
140 */
141 if ( (uintptr_t)&MMGCRamReadNoTrapHandler < (uintptr_t)pRegFrame->eip
142 && (uintptr_t)pRegFrame->eip < (uintptr_t)&MMGCRamReadNoTrapHandler_EndProc)
143 {
144 /* Must be a read violation. */
145 AssertReturn(!(TRPMGetErrorCode(VMMGetCpu0(pVM)) & X86_TRAP_PF_RW), VERR_INTERNAL_ERROR);
146 pRegFrame->eip = (uintptr_t)&MMGCRamRead_Error;
147 return VINF_SUCCESS;
148 }
149
150 /*
151 * Page fault inside MMGCRamWrite()? Resume at _Error.
152 */
153 if ( (uintptr_t)&MMGCRamWriteNoTrapHandler < (uintptr_t)pRegFrame->eip
154 && (uintptr_t)pRegFrame->eip < (uintptr_t)&MMGCRamWriteNoTrapHandler_EndProc)
155 {
156 /* Must be a write violation. */
157 AssertReturn(TRPMGetErrorCode(VMMGetCpu0(pVM)) & X86_TRAP_PF_RW, VERR_INTERNAL_ERROR);
158 pRegFrame->eip = (uintptr_t)&MMGCRamWrite_Error;
159 return VINF_SUCCESS;
160 }
161
162 /*
163 * #PF is not handled - cause guru meditation.
164 */
165 return VERR_INTERNAL_ERROR;
166}
167
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