1
/* $Id: MMRamRC.cpp 35346 2010-12-27 16:13:13Z vboxsync $ */
3
* MMRamGC - Guest Context Ram access Routines, pair for MMRamGCA.asm.
7
* Copyright (C) 2006-2007 Oracle Corporation
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.
19
/*******************************************************************************
21
*******************************************************************************/
22
#define LOG_GROUP LOG_GROUP_MM
23
#include <VBox/vmm/mm.h>
24
#include <VBox/vmm/cpum.h>
25
#include <VBox/vmm/trpm.h>
26
#include <VBox/vmm/em.h>
27
#include "MMInternal.h"
28
#include <VBox/vmm/vm.h>
29
#include <VBox/vmm/vmm.h>
30
#include <VBox/vmm/pgm.h>
32
#include <iprt/assert.h>
33
#include <VBox/param.h>
37
/*******************************************************************************
38
* Internal Functions *
39
*******************************************************************************/
40
static DECLCALLBACK(int) mmGCRamTrap0eHandler(PVM pVM, PCPUMCTXCORE pRegFrame);
42
DECLASM(void) MMGCRamReadNoTrapHandler_EndProc(void);
43
DECLASM(void) MMGCRamWriteNoTrapHandler_EndProc(void);
44
DECLASM(void) MMGCRamRead_Error(void);
45
DECLASM(void) MMGCRamWrite_Error(void);
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.
54
* @param pVM VM handle.
56
VMMRCDECL(void) MMGCRamRegisterTrapHandler(PVM pVM)
58
TRPMGCSetTempHandler(pVM, 0xe, mmGCRamTrap0eHandler);
63
* Remove MMGCRam Hypervisor page fault handler.
64
* See description of MMGCRamRegisterTrapHandler call.
66
* @param pVM VM handle.
68
VMMRCDECL(void) MMGCRamDeregisterTrapHandler(PVM pVM)
70
TRPMGCSetTempHandler(pVM, 0xe, NULL);
75
* Read data in guest context with #PF control.
77
* @returns VBox status.
78
* @param pVM The VM handle.
79
* @param pDst Where to store the read 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.
83
VMMRCDECL(int) MMGCRamRead(PVM pVM, void *pDst, void *pSrc, size_t cb)
86
PVMCPU pVCpu = VMMGetCpu0(pVM);
88
TRPMSaveTrap(pVCpu); /* save the current trap info, because it will get trashed if our access failed. */
90
MMGCRamRegisterTrapHandler(pVM);
91
rc = MMGCRamReadNoTrapHandler(pDst, pSrc, cb);
92
MMGCRamDeregisterTrapHandler(pVM);
94
TRPMRestoreTrap(pVCpu);
101
* Write data in guest context with #PF control.
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.
109
* @deprecated Don't use this as it doesn't check the page state.
111
VMMRCDECL(int) MMGCRamWrite(PVM pVM, void *pDst, void *pSrc, size_t cb)
113
PVMCPU pVCpu = VMMGetCpu0(pVM);
114
TRPMSaveTrap(pVCpu); /* save the current trap info, because it will get trashed if our access failed. */
116
MMGCRamRegisterTrapHandler(pVM);
117
int rc = MMGCRamWriteNoTrapHandler(pDst, pSrc, cb);
118
MMGCRamDeregisterTrapHandler(pVM);
120
TRPMRestoreTrap(pVCpu);
123
* And mark the relevant guest page as accessed and dirty.
125
PGMGstModifyPage(VMMGetCpu0(pVM), (RTGCPTR)(RTRCUINTPTR)pDst, cb, X86_PTE_A | X86_PTE_D, ~(uint64_t)(X86_PTE_A | X86_PTE_D));
132
* \#PF Handler for servicing traps inside MMGCRamReadNoTrapHandler and MMGCRamWriteNoTrapHandler functions.
136
DECLCALLBACK(int) mmGCRamTrap0eHandler(PVM pVM, PCPUMCTXCORE pRegFrame)
139
* Page fault inside MMGCRamRead()? Resume at *_Error.
141
if ( (uintptr_t)&MMGCRamReadNoTrapHandler < (uintptr_t)pRegFrame->eip
142
&& (uintptr_t)pRegFrame->eip < (uintptr_t)&MMGCRamReadNoTrapHandler_EndProc)
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;
151
* Page fault inside MMGCRamWrite()? Resume at _Error.
153
if ( (uintptr_t)&MMGCRamWriteNoTrapHandler < (uintptr_t)pRegFrame->eip
154
&& (uintptr_t)pRegFrame->eip < (uintptr_t)&MMGCRamWriteNoTrapHandler_EndProc)
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;
163
* #PF is not handled - cause guru meditation.
165
return VERR_INTERNAL_ERROR;