VirtualBox

source: vbox/trunk/src/VBox/Runtime/r0drv/os2/memobj-r0drv-os2.cpp

Last change on this file was 100357, checked in by vboxsync, 11 months ago

Runtime/RTR0MemObj*: Add PhysHighest parameter to RTR0MemObjAllocCont to indicate the maximum allowed physical address for an allocation, bugref:10457 [second attempt]

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 23.3 KB
Line 
1/* $Id: memobj-r0drv-os2.cpp 100357 2023-07-04 07:00:26Z vboxsync $ */
2/** @file
3 * IPRT - Ring-0 Memory Objects, OS/2.
4 */
5
6/*
7 * Contributed by knut st. osmundsen.
8 *
9 * Copyright (C) 2007-2023 Oracle and/or its affiliates.
10 *
11 * This file is part of VirtualBox base platform packages, as
12 * available from https://www.virtualbox.org.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation, in version 3 of the
17 * License.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see <https://www.gnu.org/licenses>.
26 *
27 * The contents of this file may alternatively be used under the terms
28 * of the Common Development and Distribution License Version 1.0
29 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
30 * in the VirtualBox distribution, in which case the provisions of the
31 * CDDL are applicable instead of those of the GPL.
32 *
33 * You may elect to license modified versions of this file under the
34 * terms and conditions of either the GPL or the CDDL or both.
35 *
36 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
37 * --------------------------------------------------------------------
38 *
39 * This code is based on:
40 *
41 * Copyright (c) 2007 knut st. osmundsen <bird-src-spam@anduin.net>
42 *
43 * Permission is hereby granted, free of charge, to any person
44 * obtaining a copy of this software and associated documentation
45 * files (the "Software"), to deal in the Software without
46 * restriction, including without limitation the rights to use,
47 * copy, modify, merge, publish, distribute, sublicense, and/or sell
48 * copies of the Software, and to permit persons to whom the
49 * Software is furnished to do so, subject to the following
50 * conditions:
51 *
52 * The above copyright notice and this permission notice shall be
53 * included in all copies or substantial portions of the Software.
54 *
55 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
56 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
57 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
58 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
59 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
60 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
61 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
62 * OTHER DEALINGS IN THE SOFTWARE.
63 */
64
65
66/*********************************************************************************************************************************
67* Header Files *
68*********************************************************************************************************************************/
69#include "the-os2-kernel.h"
70
71#include <iprt/memobj.h>
72#include <iprt/mem.h>
73#include <iprt/err.h>
74#include <iprt/assert.h>
75#include <iprt/log.h>
76#include <iprt/param.h>
77#include <iprt/process.h>
78#include "internal/memobj.h"
79
80
81/*********************************************************************************************************************************
82* Structures and Typedefs *
83*********************************************************************************************************************************/
84/**
85 * The OS/2 version of the memory object structure.
86 */
87typedef struct RTR0MEMOBJDARWIN
88{
89 /** The core structure. */
90 RTR0MEMOBJINTERNAL Core;
91 /** Lock for the ring-3 / ring-0 pinned objectes.
92 * This member might not be allocated for some object types. */
93 KernVMLock_t Lock;
94 /** Array of physical pages.
95 * This array can be 0 in length for some object types. */
96 KernPageList_t aPages[1];
97} RTR0MEMOBJOS2, *PRTR0MEMOBJOS2;
98
99
100/*********************************************************************************************************************************
101* Internal Functions *
102*********************************************************************************************************************************/
103static void rtR0MemObjFixPageList(KernPageList_t *paPages, ULONG cPages, ULONG cPagesRet);
104
105
106DECLHIDDEN(int) rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
107{
108 PRTR0MEMOBJOS2 pMemOs2 = (PRTR0MEMOBJOS2)pMem;
109 int rc;
110
111 switch (pMemOs2->Core.enmType)
112 {
113 case RTR0MEMOBJTYPE_PHYS_NC:
114 AssertMsgFailed(("RTR0MEMOBJTYPE_PHYS_NC\n"));
115 return VERR_INTERNAL_ERROR;
116
117 case RTR0MEMOBJTYPE_PHYS:
118 if (!pMemOs2->Core.pv)
119 break;
120
121 case RTR0MEMOBJTYPE_MAPPING:
122 if (pMemOs2->Core.u.Mapping.R0Process == NIL_RTR0PROCESS)
123 break;
124
125 RT_FALL_THRU();
126 case RTR0MEMOBJTYPE_PAGE:
127 case RTR0MEMOBJTYPE_LOW:
128 case RTR0MEMOBJTYPE_CONT:
129 rc = KernVMFree(pMemOs2->Core.pv);
130 AssertMsg(!rc, ("rc=%d type=%d pv=%p cb=%#zx\n", rc, pMemOs2->Core.enmType, pMemOs2->Core.pv, pMemOs2->Core.cb));
131 break;
132
133 case RTR0MEMOBJTYPE_LOCK:
134 rc = KernVMUnlock(&pMemOs2->Lock);
135 AssertMsg(!rc, ("rc=%d\n", rc));
136 break;
137
138 case RTR0MEMOBJTYPE_RES_VIRT:
139 default:
140 AssertMsgFailed(("enmType=%d\n", pMemOs2->Core.enmType));
141 return VERR_INTERNAL_ERROR;
142 }
143
144 return VINF_SUCCESS;
145}
146
147
148DECLHIDDEN(int) rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable, const char *pszTag)
149{
150 NOREF(fExecutable);
151
152 /* create the object. */
153 const ULONG cPages = cb >> PAGE_SHIFT;
154 PRTR0MEMOBJOS2 pMemOs2 = (PRTR0MEMOBJOS2)rtR0MemObjNew(RT_UOFFSETOF_DYN(RTR0MEMOBJOS2, aPages[cPages]),
155 RTR0MEMOBJTYPE_PAGE, NULL, cb, pszTag);
156 if (pMemOs2)
157 {
158 /* do the allocation. */
159 int rc = KernVMAlloc(cb, VMDHA_FIXED, &pMemOs2->Core.pv, (PPVOID)-1, NULL);
160 if (!rc)
161 {
162 ULONG cPagesRet = cPages;
163 rc = KernLinToPageList(pMemOs2->Core.pv, cb, &pMemOs2->aPages[0], &cPagesRet);
164 if (!rc)
165 {
166 rtR0MemObjFixPageList(&pMemOs2->aPages[0], cPages, cPagesRet);
167 pMemOs2->Core.fFlags |= RTR0MEMOBJ_FLAGS_UNINITIALIZED_AT_ALLOC; /* doesn't seem to be possible to zero anything */
168 *ppMem = &pMemOs2->Core;
169 return VINF_SUCCESS;
170 }
171 KernVMFree(pMemOs2->Core.pv);
172 }
173 rtR0MemObjDelete(&pMemOs2->Core);
174 return RTErrConvertFromOS2(rc);
175 }
176 return VERR_NO_MEMORY;
177}
178
179
180DECLHIDDEN(int) rtR0MemObjNativeAllocLarge(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, size_t cbLargePage, uint32_t fFlags,
181 const char *pszTag)
182{
183 return rtR0MemObjFallbackAllocLarge(ppMem, cb, cbLargePage, fFlags, pszTag);
184}
185
186
187DECLHIDDEN(int) rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable, const char *pszTag)
188{
189 NOREF(fExecutable);
190
191 /* create the object. */
192 const ULONG cPages = cb >> PAGE_SHIFT;
193 PRTR0MEMOBJOS2 pMemOs2 = (PRTR0MEMOBJOS2)rtR0MemObjNew(RT_UOFFSETOF_DYN(RTR0MEMOBJOS2, aPages[cPages]),
194 RTR0MEMOBJTYPE_LOW, NULL, cb, pszTag);
195 if (pMemOs2)
196 {
197 /* do the allocation. */
198 int rc = KernVMAlloc(cb, VMDHA_FIXED, &pMemOs2->Core.pv, (PPVOID)-1, NULL);
199 if (!rc)
200 {
201 ULONG cPagesRet = cPages;
202 rc = KernLinToPageList(pMemOs2->Core.pv, cb, &pMemOs2->aPages[0], &cPagesRet);
203 if (!rc)
204 {
205 rtR0MemObjFixPageList(&pMemOs2->aPages[0], cPages, cPagesRet);
206 pMemOs2->Core.fFlags |= RTR0MEMOBJ_FLAGS_UNINITIALIZED_AT_ALLOC; /* doesn't seem to be possible to zero anything */
207 *ppMem = &pMemOs2->Core;
208 return VINF_SUCCESS;
209 }
210 KernVMFree(pMemOs2->Core.pv);
211 }
212 rtR0MemObjDelete(&pMemOs2->Core);
213 rc = RTErrConvertFromOS2(rc);
214 return rc == VERR_NO_MEMORY ? VERR_NO_LOW_MEMORY : rc;
215 }
216 return VERR_NO_MEMORY;
217}
218
219
220DECLHIDDEN(int) rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest,
221 bool fExecutable, const char *pszTag)
222{
223 NOREF(fExecutable);
224 AssertMsgReturn(PhysHighest >= _16M - 1, ("PhysHigest=%RHp\n", PhysHighest), VERR_NOT_SUPPORTED);
225
226 /* create the object. */
227 PRTR0MEMOBJOS2 pMemOs2 = (PRTR0MEMOBJOS2)rtR0MemObjNew(RT_UOFFSETOF(RTR0MEMOBJOS2, Lock), RTR0MEMOBJTYPE_CONT,
228 NULL, cb, pszTag);
229 if (pMemOs2)
230 {
231 /* do the allocation. */
232 ULONG ulPhys = ~0UL;
233 int rc = KernVMAlloc(cb, VMDHA_FIXED | VMDHA_CONTIG | (PhysHighest < _4G - 1 ? VMDHA_16M : 0),
234 &pMemOs2->Core.pv, (PPVOID)&ulPhys, NULL);
235 if (!rc)
236 {
237 Assert(ulPhys != ~0UL);
238 pMemOs2->Core.fFlags |= RTR0MEMOBJ_FLAGS_UNINITIALIZED_AT_ALLOC; /* doesn't seem to be possible to zero anything */
239 pMemOs2->Core.u.Cont.Phys = ulPhys;
240 *ppMem = &pMemOs2->Core;
241 return VINF_SUCCESS;
242 }
243 rtR0MemObjDelete(&pMemOs2->Core);
244 return RTErrConvertFromOS2(rc);
245 }
246 return VERR_NO_MEMORY;
247}
248
249
250DECLHIDDEN(int) rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment,
251 const char *pszTag)
252{
253 AssertMsgReturn(PhysHighest >= _16M - 1, ("PhysHigest=%RHp\n", PhysHighest), VERR_NOT_SUPPORTED);
254
255 /** @todo alignment */
256 if (uAlignment != PAGE_SIZE)
257 return VERR_NOT_SUPPORTED;
258
259 /* create the object. */
260 PRTR0MEMOBJOS2 pMemOs2 = (PRTR0MEMOBJOS2)rtR0MemObjNew(RT_UOFFSETOF(RTR0MEMOBJOS2, Lock), RTR0MEMOBJTYPE_PHYS,
261 NULL, cb, pszTag);
262 if (pMemOs2)
263 {
264 /* do the allocation. */
265 ULONG ulPhys = ~0UL;
266 int rc = KernVMAlloc(cb, VMDHA_FIXED | VMDHA_CONTIG | (PhysHighest < _4G - 1 ? VMDHA_16M : 0),
267 &pMemOs2->Core.pv, (PPVOID)&ulPhys, NULL);
268 if (!rc)
269 {
270 Assert(ulPhys != ~0UL);
271 pMemOs2->Core.fFlags |= RTR0MEMOBJ_FLAGS_UNINITIALIZED_AT_ALLOC; /* doesn't seem to be possible to zero anything */
272 pMemOs2->Core.u.Phys.fAllocated = true;
273 pMemOs2->Core.u.Phys.PhysBase = ulPhys;
274 *ppMem = &pMemOs2->Core;
275 return VINF_SUCCESS;
276 }
277 rtR0MemObjDelete(&pMemOs2->Core);
278 return RTErrConvertFromOS2(rc);
279 }
280 return VERR_NO_MEMORY;
281}
282
283
284DECLHIDDEN(int) rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, const char *pszTag)
285{
286 /** @todo rtR0MemObjNativeAllocPhysNC / os2. */
287 return rtR0MemObjNativeAllocPhys(ppMem, cb, PhysHighest, PAGE_SIZE, pszTag);
288}
289
290
291DECLHIDDEN(int) rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy,
292 const char *pszTag)
293{
294 AssertReturn(uCachePolicy == RTMEM_CACHE_POLICY_DONT_CARE, VERR_NOT_SUPPORTED);
295
296 /* create the object. */
297 PRTR0MEMOBJOS2 pMemOs2 = (PRTR0MEMOBJOS2)rtR0MemObjNew(RT_UOFFSETOF(RTR0MEMOBJOS2, Lock), RTR0MEMOBJTYPE_PHYS,
298 NULL, cb, pszTag);
299 if (pMemOs2)
300 {
301 /* there is no allocation here, right? it needs to be mapped somewhere first. */
302 pMemOs2->Core.u.Phys.fAllocated = false;
303 pMemOs2->Core.u.Phys.PhysBase = Phys;
304 pMemOs2->Core.u.Phys.uCachePolicy = uCachePolicy;
305 *ppMem = &pMemOs2->Core;
306 return VINF_SUCCESS;
307 }
308 return VERR_NO_MEMORY;
309}
310
311
312DECLHIDDEN(int) rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess,
313 RTR0PROCESS R0Process, const char *pszTag)
314{
315 AssertMsgReturn(R0Process == RTR0ProcHandleSelf(), ("%p != %p\n", R0Process, RTR0ProcHandleSelf()), VERR_NOT_SUPPORTED);
316
317 /* create the object. */
318 const ULONG cPages = cb >> PAGE_SHIFT;
319 PRTR0MEMOBJOS2 pMemOs2 = (PRTR0MEMOBJOS2)rtR0MemObjNew(RT_UOFFSETOF_DYN(RTR0MEMOBJOS2, aPages[cPages]),
320 RTR0MEMOBJTYPE_LOCK, (void *)R3Ptr, cb, pszTag);
321 if (pMemOs2)
322 {
323 /* lock it. */
324 ULONG cPagesRet = cPages;
325 int rc = KernVMLock(VMDHL_LONG | (fAccess & RTMEM_PROT_WRITE ? VMDHL_WRITE : 0),
326 (void *)R3Ptr, cb, &pMemOs2->Lock, &pMemOs2->aPages[0], &cPagesRet);
327 if (!rc)
328 {
329 rtR0MemObjFixPageList(&pMemOs2->aPages[0], cPages, cPagesRet);
330 Assert(cb == pMemOs2->Core.cb);
331 Assert(R3Ptr == (RTR3PTR)pMemOs2->Core.pv);
332 pMemOs2->Core.u.Lock.R0Process = R0Process;
333 *ppMem = &pMemOs2->Core;
334 return VINF_SUCCESS;
335 }
336 rtR0MemObjDelete(&pMemOs2->Core);
337 return RTErrConvertFromOS2(rc);
338 }
339 return VERR_NO_MEMORY;
340}
341
342
343DECLHIDDEN(int) rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess, const char *pszTag)
344{
345 /* create the object. */
346 const ULONG cPages = cb >> PAGE_SHIFT;
347 PRTR0MEMOBJOS2 pMemOs2 = (PRTR0MEMOBJOS2)rtR0MemObjNew(RT_UOFFSETOF_DYN(RTR0MEMOBJOS2, aPages[cPages]),
348 RTR0MEMOBJTYPE_LOCK, pv, cb, pszTag);
349 if (pMemOs2)
350 {
351 /* lock it. */
352 ULONG cPagesRet = cPages;
353 int rc = KernVMLock(VMDHL_LONG | (fAccess & RTMEM_PROT_WRITE ? VMDHL_WRITE : 0),
354 pv, cb, &pMemOs2->Lock, &pMemOs2->aPages[0], &cPagesRet);
355 if (!rc)
356 {
357 rtR0MemObjFixPageList(&pMemOs2->aPages[0], cPages, cPagesRet);
358 pMemOs2->Core.u.Lock.R0Process = NIL_RTR0PROCESS;
359 *ppMem = &pMemOs2->Core;
360 return VINF_SUCCESS;
361 }
362 rtR0MemObjDelete(&pMemOs2->Core);
363 return RTErrConvertFromOS2(rc);
364 }
365 return VERR_NO_MEMORY;
366}
367
368
369DECLHIDDEN(int) rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment,
370 const char *pszTag)
371{
372 RT_NOREF(ppMem, pvFixed, cb, uAlignment, pszTag);
373 return VERR_NOT_SUPPORTED;
374}
375
376
377DECLHIDDEN(int) rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment,
378 RTR0PROCESS R0Process, const char *pszTag)
379{
380 RT_NOREF(ppMem, R3PtrFixed, cb, uAlignment, R0Process, pszTag);
381 return VERR_NOT_SUPPORTED;
382}
383
384
385DECLHIDDEN(int) rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
386 unsigned fProt, size_t offSub, size_t cbSub, const char *pszTag)
387{
388 AssertMsgReturn(pvFixed == (void *)-1, ("%p\n", pvFixed), VERR_NOT_SUPPORTED);
389
390 /*
391 * Check that the specified alignment is supported.
392 */
393 if (uAlignment > PAGE_SIZE)
394 return VERR_NOT_SUPPORTED;
395
396/** @todo finish the implementation. */
397
398 int rc;
399 void *pvR0 = NULL;
400 PRTR0MEMOBJOS2 pMemToMapOs2 = (PRTR0MEMOBJOS2)pMemToMap;
401 switch (pMemToMapOs2->Core.enmType)
402 {
403 /*
404 * These has kernel mappings.
405 */
406 case RTR0MEMOBJTYPE_PAGE:
407 case RTR0MEMOBJTYPE_LOW:
408 case RTR0MEMOBJTYPE_CONT:
409 pvR0 = pMemToMapOs2->Core.pv;
410 break;
411
412 case RTR0MEMOBJTYPE_PHYS:
413 pvR0 = pMemToMapOs2->Core.pv;
414 if (!pvR0)
415 {
416 /* no ring-0 mapping, so allocate a mapping in the process. */
417 AssertMsgReturn(fProt & RTMEM_PROT_WRITE, ("%#x\n", fProt), VERR_NOT_SUPPORTED);
418 Assert(!pMemToMapOs2->Core.u.Phys.fAllocated);
419 ULONG ulPhys = (ULONG)pMemToMapOs2->Core.u.Phys.PhysBase;
420 AssertReturn(ulPhys == pMemToMapOs2->Core.u.Phys.PhysBase, VERR_OUT_OF_RANGE);
421 rc = KernVMAlloc(pMemToMapOs2->Core.cb, VMDHA_PHYS, &pvR0, (PPVOID)&ulPhys, NULL);
422 if (rc)
423 return RTErrConvertFromOS2(rc);
424 pMemToMapOs2->Core.pv = pvR0;
425 }
426 break;
427
428 case RTR0MEMOBJTYPE_PHYS_NC:
429 AssertMsgFailed(("RTR0MEMOBJTYPE_PHYS_NC\n"));
430 return VERR_INTERNAL_ERROR_3;
431
432 case RTR0MEMOBJTYPE_LOCK:
433 if (pMemToMapOs2->Core.u.Lock.R0Process != NIL_RTR0PROCESS)
434 return VERR_NOT_SUPPORTED; /** @todo implement this... */
435 pvR0 = pMemToMapOs2->Core.pv;
436 break;
437
438 case RTR0MEMOBJTYPE_RES_VIRT:
439 case RTR0MEMOBJTYPE_MAPPING:
440 default:
441 AssertMsgFailed(("enmType=%d\n", pMemToMapOs2->Core.enmType));
442 return VERR_INTERNAL_ERROR;
443 }
444
445 /*
446 * Create a dummy mapping object for it.
447 *
448 * All mappings are read/write/execute in OS/2 and there isn't
449 * any cache options, so sharing is ok. And the main memory object
450 * isn't actually freed until all the mappings have been freed up
451 * (reference counting).
452 */
453 if (!cbSub)
454 cbSub = pMemToMapOs2->Core.cb - offSub;
455 PRTR0MEMOBJOS2 pMemOs2 = (PRTR0MEMOBJOS2)rtR0MemObjNew(RT_UOFFSETOF(RTR0MEMOBJOS2, Lock), RTR0MEMOBJTYPE_MAPPING,
456 (uint8_t *)pvR0 + offSub, cbSub, pszTag);
457 if (pMemOs2)
458 {
459 pMemOs2->Core.u.Mapping.R0Process = NIL_RTR0PROCESS;
460 *ppMem = &pMemOs2->Core;
461 return VINF_SUCCESS;
462 }
463 return VERR_NO_MEMORY;
464}
465
466
467DECLHIDDEN(int) rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment,
468 unsigned fProt, RTR0PROCESS R0Process, size_t offSub, size_t cbSub, const char *pszTag)
469{
470 AssertMsgReturn(R0Process == RTR0ProcHandleSelf(), ("%p != %p\n", R0Process, RTR0ProcHandleSelf()), VERR_NOT_SUPPORTED);
471 AssertMsgReturn(R3PtrFixed == (RTR3PTR)-1, ("%p\n", R3PtrFixed), VERR_NOT_SUPPORTED);
472 if (uAlignment > PAGE_SIZE)
473 return VERR_NOT_SUPPORTED;
474 AssertMsgReturn(!offSub && !cbSub, ("%#zx %#zx\n", offSub, cbSub), VERR_NOT_SUPPORTED); /** @todo implement sub maps */
475
476 int rc;
477 void *pvR0;
478 void *pvR3 = NULL;
479 PRTR0MEMOBJOS2 pMemToMapOs2 = (PRTR0MEMOBJOS2)pMemToMap;
480 switch (pMemToMapOs2->Core.enmType)
481 {
482 /*
483 * These has kernel mappings.
484 */
485 case RTR0MEMOBJTYPE_PAGE:
486 case RTR0MEMOBJTYPE_LOW:
487 case RTR0MEMOBJTYPE_CONT:
488 pvR0 = pMemToMapOs2->Core.pv;
489 break;
490
491 case RTR0MEMOBJTYPE_PHYS:
492 pvR0 = pMemToMapOs2->Core.pv;
493#if 0/* this is wrong. */
494 if (!pvR0)
495 {
496 /* no ring-0 mapping, so allocate a mapping in the process. */
497 AssertMsgReturn(fProt & RTMEM_PROT_WRITE, ("%#x\n", fProt), VERR_NOT_SUPPORTED);
498 Assert(!pMemToMapOs2->Core.u.Phys.fAllocated);
499 ULONG ulPhys = pMemToMapOs2->Core.u.Phys.PhysBase;
500 rc = KernVMAlloc(pMemToMapOs2->Core.cb, VMDHA_PHYS | VMDHA_PROCESS, &pvR3, (PPVOID)&ulPhys, NULL);
501 if (rc)
502 return RTErrConvertFromOS2(rc);
503 }
504 break;
505#endif
506 return VERR_NOT_SUPPORTED;
507
508 case RTR0MEMOBJTYPE_PHYS_NC:
509 AssertMsgFailed(("RTR0MEMOBJTYPE_PHYS_NC\n"));
510 return VERR_INTERNAL_ERROR_5;
511
512 case RTR0MEMOBJTYPE_LOCK:
513 if (pMemToMapOs2->Core.u.Lock.R0Process != NIL_RTR0PROCESS)
514 return VERR_NOT_SUPPORTED; /** @todo implement this... */
515 pvR0 = pMemToMapOs2->Core.pv;
516 break;
517
518 case RTR0MEMOBJTYPE_RES_VIRT:
519 case RTR0MEMOBJTYPE_MAPPING:
520 default:
521 AssertMsgFailed(("enmType=%d\n", pMemToMapOs2->Core.enmType));
522 return VERR_INTERNAL_ERROR;
523 }
524
525 /*
526 * Map the ring-0 memory into the current process.
527 */
528 if (!pvR3)
529 {
530 Assert(pvR0);
531 ULONG flFlags = 0;
532 if (uAlignment == PAGE_SIZE)
533 flFlags |= VMDHGP_4MB;
534 if (fProt & RTMEM_PROT_WRITE)
535 flFlags |= VMDHGP_WRITE;
536 rc = RTR0Os2DHVMGlobalToProcess(flFlags, pvR0, pMemToMapOs2->Core.cb, &pvR3);
537 if (rc)
538 return RTErrConvertFromOS2(rc);
539 }
540 Assert(pvR3);
541
542 /*
543 * Create a mapping object for it.
544 */
545 PRTR0MEMOBJOS2 pMemOs2 = (PRTR0MEMOBJOS2)rtR0MemObjNew(RT_UOFFSETOF(RTR0MEMOBJOS2, Lock), RTR0MEMOBJTYPE_MAPPING,
546 pvR3, pMemToMapOs2->Core.cb, pszTag);
547 if (pMemOs2)
548 {
549 Assert(pMemOs2->Core.pv == pvR3);
550 pMemOs2->Core.u.Mapping.R0Process = R0Process;
551 *ppMem = &pMemOs2->Core;
552 return VINF_SUCCESS;
553 }
554 KernVMFree(pvR3);
555 return VERR_NO_MEMORY;
556}
557
558
559DECLHIDDEN(int) rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt)
560{
561 NOREF(pMem);
562 NOREF(offSub);
563 NOREF(cbSub);
564 NOREF(fProt);
565 return VERR_NOT_SUPPORTED;
566}
567
568
569DECLHIDDEN(RTHCPHYS) rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
570{
571 PRTR0MEMOBJOS2 pMemOs2 = (PRTR0MEMOBJOS2)pMem;
572
573 switch (pMemOs2->Core.enmType)
574 {
575 case RTR0MEMOBJTYPE_PAGE:
576 case RTR0MEMOBJTYPE_LOW:
577 case RTR0MEMOBJTYPE_LOCK:
578 case RTR0MEMOBJTYPE_PHYS_NC:
579 return pMemOs2->aPages[iPage].Addr;
580
581 case RTR0MEMOBJTYPE_CONT:
582 return pMemOs2->Core.u.Cont.Phys + (iPage << PAGE_SHIFT);
583
584 case RTR0MEMOBJTYPE_PHYS:
585 return pMemOs2->Core.u.Phys.PhysBase + (iPage << PAGE_SHIFT);
586
587 case RTR0MEMOBJTYPE_RES_VIRT:
588 case RTR0MEMOBJTYPE_MAPPING:
589 default:
590 return NIL_RTHCPHYS;
591 }
592}
593
594
595/**
596 * Expands the page list so we can index pages directly.
597 *
598 * @param paPages The page list array to fix.
599 * @param cPages The number of pages that's supposed to go into the list.
600 * @param cPagesRet The actual number of pages in the list.
601 */
602static void rtR0MemObjFixPageList(KernPageList_t *paPages, ULONG cPages, ULONG cPagesRet)
603{
604 Assert(cPages >= cPagesRet);
605 if (cPages != cPagesRet)
606 {
607 ULONG iIn = cPagesRet;
608 ULONG iOut = cPages;
609 do
610 {
611 iIn--;
612 iOut--;
613 Assert(iIn <= iOut);
614
615 KernPageList_t Page = paPages[iIn];
616 Assert(!(Page.Addr & PAGE_OFFSET_MASK));
617 Assert(Page.Size == RT_ALIGN_Z(Page.Size, PAGE_SIZE));
618
619 if (Page.Size > PAGE_SIZE)
620 {
621 do
622 {
623 Page.Size -= PAGE_SIZE;
624 paPages[iOut].Addr = Page.Addr + Page.Size;
625 paPages[iOut].Size = PAGE_SIZE;
626 iOut--;
627 } while (Page.Size > PAGE_SIZE);
628 }
629
630 paPages[iOut].Addr = Page.Addr;
631 paPages[iOut].Size = PAGE_SIZE;
632 } while ( iIn != iOut
633 && iIn > 0);
634 }
635}
636
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use