VirtualBox

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

Last change on this file since 100356 was 100356, checked in by vboxsync, 17 months ago

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

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