VirtualBox

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

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

scm --update-copyright-year

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