VirtualBox

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

Last change on this file since 91480 was 91480, checked in by vboxsync, 3 years ago

IPRT/memobj: Passing pszTag around...

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