VirtualBox

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

Last change on this file since 86697 was 82968, checked in by vboxsync, 5 years ago

Copyright year updates by scm.

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