VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMRC/MMRamRC.cpp@ 77627

Last change on this file since 77627 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 6.4 KB
Line 
1/* $Id: MMRamRC.cpp 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * MMRamGC - Guest Context Ram access Routines, pair for MMRamGCA.asm.
4 */
5
6/*
7 * Copyright (C) 2006-2019 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/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>
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 The cross context VM structure.
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 The cross context VM structure.
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 code.
78 * @param pVM The cross context VM structure.
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.
82 */
83VMMRCDECL(int) MMGCRamRead(PVM pVM, void *pDst, void *pSrc, size_t cb)
84{
85 int rc;
86 PVMCPU pVCpu = VMMGetCpu0(pVM);
87
88 /*
89 * Save the current trap info, because it will get trashed if our access failed.
90 */
91 TRPMSaveTrap(pVCpu);
92
93 /*
94 * Need to serve the request in a silly loop because the assembly code wasn't
95 * written for abrbitrary sizes, only 1/2/4/8.
96 */
97 MMGCRamRegisterTrapHandler(pVM);
98 for (;;)
99 {
100 size_t cbThisRead;
101 switch (cb)
102 {
103 case 1: cbThisRead = 1; break;
104 case 2: cbThisRead = 2; break;
105 case 3: cbThisRead = 2; break;
106 case 4: cbThisRead = 4; break;
107 case 5: cbThisRead = 4; break;
108 case 6: cbThisRead = 4; break;
109 case 7: cbThisRead = 4; break;
110 default:
111 case 8: cbThisRead = 8; break;
112 }
113 rc = MMGCRamReadNoTrapHandler(pDst, pSrc, cbThisRead);
114 if (RT_FAILURE(rc) || cbThisRead == cb)
115 break;
116
117 /* advance */
118 cb -= cbThisRead;
119 pDst = (uint8_t *)pDst + cbThisRead;
120 pSrc = (uint8_t *)pSrc + cbThisRead;
121 }
122 MMGCRamDeregisterTrapHandler(pVM);
123
124 if (RT_FAILURE(rc))
125 TRPMRestoreTrap(pVCpu);
126
127 return rc;
128}
129
130
131/**
132 * Write data in guest context with \#PF control.
133 *
134 * @returns VBox status code.
135 * @param pVM The cross context VM structure.
136 * @param pDst Where to write the data.
137 * @param pSrc Pointer to the data to write.
138 * @param cb Size of data to write, only 1/2/4 is valid.
139 *
140 * @deprecated Don't use this as it doesn't check the page state.
141 */
142VMMRCDECL(int) MMGCRamWrite(PVM pVM, void *pDst, void *pSrc, size_t cb)
143{
144 PVMCPU pVCpu = VMMGetCpu0(pVM);
145 TRPMSaveTrap(pVCpu); /* save the current trap info, because it will get trashed if our access failed. */
146
147 MMGCRamRegisterTrapHandler(pVM);
148 int rc = MMGCRamWriteNoTrapHandler(pDst, pSrc, cb);
149 MMGCRamDeregisterTrapHandler(pVM);
150 if (RT_FAILURE(rc))
151 TRPMRestoreTrap(pVCpu);
152
153 /*
154 * And mark the relevant guest page as accessed and dirty.
155 */
156 PGMGstModifyPage(VMMGetCpu0(pVM), (RTGCPTR)(RTRCUINTPTR)pDst, cb, X86_PTE_A | X86_PTE_D, ~(uint64_t)(X86_PTE_A | X86_PTE_D));
157
158 return rc;
159}
160
161
162/**
163 * \#PF Handler for servicing traps inside MMGCRamReadNoTrapHandler and MMGCRamWriteNoTrapHandler functions.
164 *
165 * @internal
166 */
167DECLCALLBACK(int) mmGCRamTrap0eHandler(PVM pVM, PCPUMCTXCORE pRegFrame)
168{
169 /*
170 * Page fault inside MMGCRamRead()? Resume at *_Error.
171 */
172 if ( (uintptr_t)&MMGCRamReadNoTrapHandler < (uintptr_t)pRegFrame->eip
173 && (uintptr_t)pRegFrame->eip < (uintptr_t)&MMGCRamReadNoTrapHandler_EndProc)
174 {
175 /* Must be a read violation. */
176 AssertReturn(!(TRPMGetErrorCode(VMMGetCpu0(pVM)) & X86_TRAP_PF_RW), VERR_MM_BAD_TRAP_TYPE_IPE);
177 pRegFrame->eip = (uintptr_t)&MMGCRamRead_Error;
178 return VINF_SUCCESS;
179 }
180
181 /*
182 * Page fault inside MMGCRamWrite()? Resume at _Error.
183 */
184 if ( (uintptr_t)&MMGCRamWriteNoTrapHandler < (uintptr_t)pRegFrame->eip
185 && (uintptr_t)pRegFrame->eip < (uintptr_t)&MMGCRamWriteNoTrapHandler_EndProc)
186 {
187 /* Must be a write violation. */
188 AssertReturn(TRPMGetErrorCode(VMMGetCpu0(pVM)) & X86_TRAP_PF_RW, VERR_MM_BAD_TRAP_TYPE_IPE);
189 pRegFrame->eip = (uintptr_t)&MMGCRamWrite_Error;
190 return VINF_SUCCESS;
191 }
192
193 /*
194 * #PF is not handled - cause guru meditation.
195 */
196 return VERR_INTERNAL_ERROR;
197}
198
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