VirtualBox

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

Last change on this file since 91481 was 91481, 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.6 KB
Line 
1/* $Id: memobj-r0drv-os2.cpp 91481 2021-09-30 00:06:31Z 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 const char *pszTag)
232{
233 AssertMsgReturn(PhysHighest >= 16 *_1M, ("PhysHigest=%RHp\n", PhysHighest), VERR_NOT_SUPPORTED);
234
235 /** @todo alignment */
236 if (uAlignment != PAGE_SIZE)
237 return VERR_NOT_SUPPORTED;
238
239 /* create the object. */
240 PRTR0MEMOBJOS2 pMemOs2 = (PRTR0MEMOBJOS2)rtR0MemObjNew(RT_UOFFSETOF(RTR0MEMOBJOS2, Lock), RTR0MEMOBJTYPE_PHYS,
241 NULL, cb, pszTag);
242 if (!pMemOs2)
243 return VERR_NO_MEMORY;
244
245 /* do the allocation. */
246 ULONG ulPhys = ~0UL;
247 int rc = KernVMAlloc(cb, VMDHA_FIXED | VMDHA_CONTIG | (PhysHighest < _4G ? VMDHA_16M : 0), &pMemOs2->Core.pv, (PPVOID)&ulPhys, NULL);
248 if (!rc)
249 {
250 Assert(ulPhys != ~0UL);
251 pMemOs2->Core.u.Phys.fAllocated = true;
252 pMemOs2->Core.u.Phys.PhysBase = ulPhys;
253 *ppMem = &pMemOs2->Core;
254 return VINF_SUCCESS;
255 }
256 rtR0MemObjDelete(&pMemOs2->Core);
257 return RTErrConvertFromOS2(rc);
258}
259
260
261DECLHIDDEN(int) rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, const char *pszTag)
262{
263 /** @todo rtR0MemObjNativeAllocPhysNC / os2. */
264 return rtR0MemObjNativeAllocPhys(ppMem, cb, PhysHighest, PAGE_SIZE, pszTag);
265}
266
267
268DECLHIDDEN(int) rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy,
269 const char *pszTag)
270{
271 AssertReturn(uCachePolicy == RTMEM_CACHE_POLICY_DONT_CARE, VERR_NOT_SUPPORTED);
272
273 /* create the object. */
274 PRTR0MEMOBJOS2 pMemOs2 = (PRTR0MEMOBJOS2)rtR0MemObjNew(RT_UOFFSETOF(RTR0MEMOBJOS2, Lock), RTR0MEMOBJTYPE_PHYS,
275 NULL, cb, pszTag);
276 if (!pMemOs2)
277 return VERR_NO_MEMORY;
278
279 /* there is no allocation here, right? it needs to be mapped somewhere first. */
280 pMemOs2->Core.u.Phys.fAllocated = false;
281 pMemOs2->Core.u.Phys.PhysBase = Phys;
282 pMemOs2->Core.u.Phys.uCachePolicy = uCachePolicy;
283 *ppMem = &pMemOs2->Core;
284 return VINF_SUCCESS;
285}
286
287
288DECLHIDDEN(int) rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess,
289 RTR0PROCESS R0Process)
290{
291 AssertMsgReturn(R0Process == RTR0ProcHandleSelf(), ("%p != %p\n", R0Process, RTR0ProcHandleSelf()), VERR_NOT_SUPPORTED);
292
293 /* create the object. */
294 const ULONG cPages = cb >> PAGE_SHIFT;
295 PRTR0MEMOBJOS2 pMemOs2 = (PRTR0MEMOBJOS2)rtR0MemObjNew(RT_UOFFSETOF_DYN(RTR0MEMOBJOS2, aPages[cPages]),
296 RTR0MEMOBJTYPE_LOCK, (void *)R3Ptr, cb, NULL);
297 if (!pMemOs2)
298 return VERR_NO_MEMORY;
299
300 /* lock it. */
301 ULONG cPagesRet = cPages;
302 int rc = KernVMLock(VMDHL_LONG | (fAccess & RTMEM_PROT_WRITE ? VMDHL_WRITE : 0),
303 (void *)R3Ptr, cb, &pMemOs2->Lock, &pMemOs2->aPages[0], &cPagesRet);
304 if (!rc)
305 {
306 rtR0MemObjFixPageList(&pMemOs2->aPages[0], cPages, cPagesRet);
307 Assert(cb == pMemOs2->Core.cb);
308 Assert(R3Ptr == (RTR3PTR)pMemOs2->Core.pv);
309 pMemOs2->Core.u.Lock.R0Process = R0Process;
310 *ppMem = &pMemOs2->Core;
311 return VINF_SUCCESS;
312 }
313 rtR0MemObjDelete(&pMemOs2->Core);
314 return RTErrConvertFromOS2(rc);
315}
316
317
318DECLHIDDEN(int) rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess)
319{
320 /* create the object. */
321 const ULONG cPages = cb >> PAGE_SHIFT;
322 PRTR0MEMOBJOS2 pMemOs2 = (PRTR0MEMOBJOS2)rtR0MemObjNew(RT_UOFFSETOF_DYN(RTR0MEMOBJOS2, aPages[cPages]),
323 RTR0MEMOBJTYPE_LOCK, pv, cb, NULL);
324 if (!pMemOs2)
325 return VERR_NO_MEMORY;
326
327 /* lock it. */
328 ULONG cPagesRet = cPages;
329 int rc = KernVMLock(VMDHL_LONG | (fAccess & RTMEM_PROT_WRITE ? VMDHL_WRITE : 0),
330 pv, cb, &pMemOs2->Lock, &pMemOs2->aPages[0], &cPagesRet);
331 if (!rc)
332 {
333 rtR0MemObjFixPageList(&pMemOs2->aPages[0], cPages, cPagesRet);
334 pMemOs2->Core.u.Lock.R0Process = NIL_RTR0PROCESS;
335 *ppMem = &pMemOs2->Core;
336 return VINF_SUCCESS;
337 }
338 rtR0MemObjDelete(&pMemOs2->Core);
339 return RTErrConvertFromOS2(rc);
340}
341
342
343DECLHIDDEN(int) rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment,
344 const char *pszTag)
345{
346 RT_NOREF(ppMem, pvFixed, cb, uAlignment, pszTag);
347 return VERR_NOT_SUPPORTED;
348}
349
350
351DECLHIDDEN(int) rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment,
352 RTR0PROCESS R0Process, const char *pszTag)
353{
354 RT_NOREF(ppMem, R3PtrFixed, cb, uAlignment, R0Process, pszTag);
355 return VERR_NOT_SUPPORTED;
356}
357
358
359DECLHIDDEN(int) rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
360 unsigned fProt, size_t offSub, size_t cbSub, const char *pszTag)
361{
362 AssertMsgReturn(pvFixed == (void *)-1, ("%p\n", pvFixed), VERR_NOT_SUPPORTED);
363
364 /*
365 * Check that the specified alignment is supported.
366 */
367 if (uAlignment > PAGE_SIZE)
368 return VERR_NOT_SUPPORTED;
369
370/** @todo finish the implementation. */
371
372 int rc;
373 void *pvR0 = NULL;
374 PRTR0MEMOBJOS2 pMemToMapOs2 = (PRTR0MEMOBJOS2)pMemToMap;
375 switch (pMemToMapOs2->Core.enmType)
376 {
377 /*
378 * These has kernel mappings.
379 */
380 case RTR0MEMOBJTYPE_PAGE:
381 case RTR0MEMOBJTYPE_LOW:
382 case RTR0MEMOBJTYPE_CONT:
383 pvR0 = pMemToMapOs2->Core.pv;
384 break;
385
386 case RTR0MEMOBJTYPE_PHYS:
387 pvR0 = pMemToMapOs2->Core.pv;
388 if (!pvR0)
389 {
390 /* no ring-0 mapping, so allocate a mapping in the process. */
391 AssertMsgReturn(fProt & RTMEM_PROT_WRITE, ("%#x\n", fProt), VERR_NOT_SUPPORTED);
392 Assert(!pMemToMapOs2->Core.u.Phys.fAllocated);
393 ULONG ulPhys = (ULONG)pMemToMapOs2->Core.u.Phys.PhysBase;
394 AssertReturn(ulPhys == pMemToMapOs2->Core.u.Phys.PhysBase, VERR_OUT_OF_RANGE);
395 rc = KernVMAlloc(pMemToMapOs2->Core.cb, VMDHA_PHYS, &pvR0, (PPVOID)&ulPhys, NULL);
396 if (rc)
397 return RTErrConvertFromOS2(rc);
398 pMemToMapOs2->Core.pv = pvR0;
399 }
400 break;
401
402 case RTR0MEMOBJTYPE_PHYS_NC:
403 AssertMsgFailed(("RTR0MEMOBJTYPE_PHYS_NC\n"));
404 return VERR_INTERNAL_ERROR_3;
405
406 case RTR0MEMOBJTYPE_LOCK:
407 if (pMemToMapOs2->Core.u.Lock.R0Process != NIL_RTR0PROCESS)
408 return VERR_NOT_SUPPORTED; /** @todo implement this... */
409 pvR0 = pMemToMapOs2->Core.pv;
410 break;
411
412 case RTR0MEMOBJTYPE_RES_VIRT:
413 case RTR0MEMOBJTYPE_MAPPING:
414 default:
415 AssertMsgFailed(("enmType=%d\n", pMemToMapOs2->Core.enmType));
416 return VERR_INTERNAL_ERROR;
417 }
418
419 /*
420 * Create a dummy mapping object for it.
421 *
422 * All mappings are read/write/execute in OS/2 and there isn't
423 * any cache options, so sharing is ok. And the main memory object
424 * isn't actually freed until all the mappings have been freed up
425 * (reference counting).
426 */
427 if (!cbSub)
428 cbSub = pMemToMapOs2->Core.cb - offSub;
429 PRTR0MEMOBJOS2 pMemOs2 = (PRTR0MEMOBJOS2)rtR0MemObjNew(RT_UOFFSETOF(RTR0MEMOBJOS2, Lock), RTR0MEMOBJTYPE_MAPPING,
430 (uint8_t *)pvR0 + offSub, cbSub, pszTag);
431 if (pMemOs2)
432 {
433 pMemOs2->Core.u.Mapping.R0Process = NIL_RTR0PROCESS;
434 *ppMem = &pMemOs2->Core;
435 return VINF_SUCCESS;
436 }
437 return VERR_NO_MEMORY;
438}
439
440
441DECLHIDDEN(int) rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment,
442 unsigned fProt, RTR0PROCESS R0Process, size_t offSub, size_t cbSub, const char *pszTag)
443{
444 AssertMsgReturn(R0Process == RTR0ProcHandleSelf(), ("%p != %p\n", R0Process, RTR0ProcHandleSelf()), VERR_NOT_SUPPORTED);
445 AssertMsgReturn(R3PtrFixed == (RTR3PTR)-1, ("%p\n", R3PtrFixed), VERR_NOT_SUPPORTED);
446 if (uAlignment > PAGE_SIZE)
447 return VERR_NOT_SUPPORTED;
448 AssertMsgReturn(!offSub && !cbSub, ("%#zx %#zx\n", offSub, cbSub), VERR_NOT_SUPPORTED); /** @todo implement sub maps */
449
450 int rc;
451 void *pvR0;
452 void *pvR3 = NULL;
453 PRTR0MEMOBJOS2 pMemToMapOs2 = (PRTR0MEMOBJOS2)pMemToMap;
454 switch (pMemToMapOs2->Core.enmType)
455 {
456 /*
457 * These has kernel mappings.
458 */
459 case RTR0MEMOBJTYPE_PAGE:
460 case RTR0MEMOBJTYPE_LOW:
461 case RTR0MEMOBJTYPE_CONT:
462 pvR0 = pMemToMapOs2->Core.pv;
463 break;
464
465 case RTR0MEMOBJTYPE_PHYS:
466 pvR0 = pMemToMapOs2->Core.pv;
467#if 0/* this is wrong. */
468 if (!pvR0)
469 {
470 /* no ring-0 mapping, so allocate a mapping in the process. */
471 AssertMsgReturn(fProt & RTMEM_PROT_WRITE, ("%#x\n", fProt), VERR_NOT_SUPPORTED);
472 Assert(!pMemToMapOs2->Core.u.Phys.fAllocated);
473 ULONG ulPhys = pMemToMapOs2->Core.u.Phys.PhysBase;
474 rc = KernVMAlloc(pMemToMapOs2->Core.cb, VMDHA_PHYS | VMDHA_PROCESS, &pvR3, (PPVOID)&ulPhys, NULL);
475 if (rc)
476 return RTErrConvertFromOS2(rc);
477 }
478 break;
479#endif
480 return VERR_NOT_SUPPORTED;
481
482 case RTR0MEMOBJTYPE_PHYS_NC:
483 AssertMsgFailed(("RTR0MEMOBJTYPE_PHYS_NC\n"));
484 return VERR_INTERNAL_ERROR_5;
485
486 case RTR0MEMOBJTYPE_LOCK:
487 if (pMemToMapOs2->Core.u.Lock.R0Process != NIL_RTR0PROCESS)
488 return VERR_NOT_SUPPORTED; /** @todo implement this... */
489 pvR0 = pMemToMapOs2->Core.pv;
490 break;
491
492 case RTR0MEMOBJTYPE_RES_VIRT:
493 case RTR0MEMOBJTYPE_MAPPING:
494 default:
495 AssertMsgFailed(("enmType=%d\n", pMemToMapOs2->Core.enmType));
496 return VERR_INTERNAL_ERROR;
497 }
498
499 /*
500 * Map the ring-0 memory into the current process.
501 */
502 if (!pvR3)
503 {
504 Assert(pvR0);
505 ULONG flFlags = 0;
506 if (uAlignment == PAGE_SIZE)
507 flFlags |= VMDHGP_4MB;
508 if (fProt & RTMEM_PROT_WRITE)
509 flFlags |= VMDHGP_WRITE;
510 rc = RTR0Os2DHVMGlobalToProcess(flFlags, pvR0, pMemToMapOs2->Core.cb, &pvR3);
511 if (rc)
512 return RTErrConvertFromOS2(rc);
513 }
514 Assert(pvR3);
515
516 /*
517 * Create a mapping object for it.
518 */
519 PRTR0MEMOBJOS2 pMemOs2 = (PRTR0MEMOBJOS2)rtR0MemObjNew(RT_UOFFSETOF(RTR0MEMOBJOS2, Lock), RTR0MEMOBJTYPE_MAPPING,
520 pvR3, pMemToMapOs2->Core.cb, pszTag);
521 if (pMemOs2)
522 {
523 Assert(pMemOs2->Core.pv == pvR3);
524 pMemOs2->Core.u.Mapping.R0Process = R0Process;
525 *ppMem = &pMemOs2->Core;
526 return VINF_SUCCESS;
527 }
528 KernVMFree(pvR3);
529 return VERR_NO_MEMORY;
530}
531
532
533DECLHIDDEN(int) rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt)
534{
535 NOREF(pMem);
536 NOREF(offSub);
537 NOREF(cbSub);
538 NOREF(fProt);
539 return VERR_NOT_SUPPORTED;
540}
541
542
543DECLHIDDEN(RTHCPHYS) rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
544{
545 PRTR0MEMOBJOS2 pMemOs2 = (PRTR0MEMOBJOS2)pMem;
546
547 switch (pMemOs2->Core.enmType)
548 {
549 case RTR0MEMOBJTYPE_PAGE:
550 case RTR0MEMOBJTYPE_LOW:
551 case RTR0MEMOBJTYPE_LOCK:
552 case RTR0MEMOBJTYPE_PHYS_NC:
553 return pMemOs2->aPages[iPage].Addr;
554
555 case RTR0MEMOBJTYPE_CONT:
556 return pMemOs2->Core.u.Cont.Phys + (iPage << PAGE_SHIFT);
557
558 case RTR0MEMOBJTYPE_PHYS:
559 return pMemOs2->Core.u.Phys.PhysBase + (iPage << PAGE_SHIFT);
560
561 case RTR0MEMOBJTYPE_RES_VIRT:
562 case RTR0MEMOBJTYPE_MAPPING:
563 default:
564 return NIL_RTHCPHYS;
565 }
566}
567
568
569/**
570 * Expands the page list so we can index pages directly.
571 *
572 * @param paPages The page list array to fix.
573 * @param cPages The number of pages that's supposed to go into the list.
574 * @param cPagesRet The actual number of pages in the list.
575 */
576static void rtR0MemObjFixPageList(KernPageList_t *paPages, ULONG cPages, ULONG cPagesRet)
577{
578 Assert(cPages >= cPagesRet);
579 if (cPages != cPagesRet)
580 {
581 ULONG iIn = cPagesRet;
582 ULONG iOut = cPages;
583 do
584 {
585 iIn--;
586 iOut--;
587 Assert(iIn <= iOut);
588
589 KernPageList_t Page = paPages[iIn];
590 Assert(!(Page.Addr & PAGE_OFFSET_MASK));
591 Assert(Page.Size == RT_ALIGN_Z(Page.Size, PAGE_SIZE));
592
593 if (Page.Size > PAGE_SIZE)
594 {
595 do
596 {
597 Page.Size -= PAGE_SIZE;
598 paPages[iOut].Addr = Page.Addr + Page.Size;
599 paPages[iOut].Size = PAGE_SIZE;
600 iOut--;
601 } while (Page.Size > PAGE_SIZE);
602 }
603
604 paPages[iOut].Addr = Page.Addr;
605 paPages[iOut].Size = PAGE_SIZE;
606 } while ( iIn != iOut
607 && iIn > 0);
608 }
609}
610
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