VirtualBox

source: vbox/trunk/src/VBox/Runtime/r0drv/netbsd/memobj-r0drv-netbsd.c@ 95411

Last change on this file since 95411 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 Author Date Id Revision
File size: 20.8 KB
Line 
1/* $Id: memobj-r0drv-netbsd.c 93115 2022-01-01 11:31:46Z vboxsync $ */
2/** @file
3 * IPRT - Ring-0 Memory Objects, NetBSD.
4 */
5
6/*
7 * Contributed by knut st. osmundsen, Andriy Gapon, Arto Huusko.
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 * Copyright (c) 2007 knut st. osmundsen <[email protected]>
30 * Copyright (c) 2011 Andriy Gapon <[email protected]>
31 * Copyright (c) 2014 Arto Huusko
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-netbsd-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 NetBSD version of the memory object structure.
76 */
77typedef struct RTR0MEMOBJNETBSD
78{
79 /** The core structure. */
80 RTR0MEMOBJINTERNAL Core;
81 size_t size;
82 struct pglist pglist;
83} RTR0MEMOBJNETBSD, *PRTR0MEMOBJNETBSD;
84
85
86typedef struct vm_map* vm_map_t;
87
88/**
89 * Gets the virtual memory map the specified object is mapped into.
90 *
91 * @returns VM map handle on success, NULL if no map.
92 * @param pMem The memory object.
93 */
94static vm_map_t rtR0MemObjNetBSDGetMap(PRTR0MEMOBJINTERNAL pMem)
95{
96 switch (pMem->enmType)
97 {
98 case RTR0MEMOBJTYPE_PAGE:
99 case RTR0MEMOBJTYPE_LOW:
100 case RTR0MEMOBJTYPE_CONT:
101 return kernel_map;
102
103 case RTR0MEMOBJTYPE_PHYS:
104 case RTR0MEMOBJTYPE_PHYS_NC:
105 return NULL; /* pretend these have no mapping atm. */
106
107 case RTR0MEMOBJTYPE_LOCK:
108 return pMem->u.Lock.R0Process == NIL_RTR0PROCESS
109 ? kernel_map
110 : &((struct proc *)pMem->u.Lock.R0Process)->p_vmspace->vm_map;
111
112 case RTR0MEMOBJTYPE_RES_VIRT:
113 return pMem->u.ResVirt.R0Process == NIL_RTR0PROCESS
114 ? kernel_map
115 : &((struct proc *)pMem->u.ResVirt.R0Process)->p_vmspace->vm_map;
116
117 case RTR0MEMOBJTYPE_MAPPING:
118 return pMem->u.Mapping.R0Process == NIL_RTR0PROCESS
119 ? kernel_map
120 : &((struct proc *)pMem->u.Mapping.R0Process)->p_vmspace->vm_map;
121
122 default:
123 return NULL;
124 }
125}
126
127
128DECLHIDDEN(int) rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
129{
130 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)pMem;
131 int rc;
132
133 switch (pMemNetBSD->Core.enmType)
134 {
135 case RTR0MEMOBJTYPE_PAGE:
136 {
137 kmem_free(pMemNetBSD->Core.pv, pMemNetBSD->Core.cb);
138 break;
139 }
140 case RTR0MEMOBJTYPE_LOW:
141 case RTR0MEMOBJTYPE_CONT:
142 {
143 /* Unmap */
144 pmap_kremove((vaddr_t)pMemNetBSD->Core.pv, pMemNetBSD->Core.cb);
145 /* Free the virtual space */
146 uvm_km_free(kernel_map, (vaddr_t)pMemNetBSD->Core.pv, pMemNetBSD->Core.cb, UVM_KMF_VAONLY);
147 /* Free the physical pages */
148 uvm_pglistfree(&pMemNetBSD->pglist);
149 break;
150 }
151 case RTR0MEMOBJTYPE_PHYS:
152 case RTR0MEMOBJTYPE_PHYS_NC:
153 {
154 /* Free the physical pages */
155 uvm_pglistfree(&pMemNetBSD->pglist);
156 break;
157 }
158 case RTR0MEMOBJTYPE_LOCK:
159 if (pMemNetBSD->Core.u.Lock.R0Process != NIL_RTR0PROCESS)
160 {
161 uvm_map_pageable(
162 &((struct proc *)pMemNetBSD->Core.u.Lock.R0Process)->p_vmspace->vm_map,
163 (vaddr_t)pMemNetBSD->Core.pv,
164 ((vaddr_t)pMemNetBSD->Core.pv) + pMemNetBSD->Core.cb,
165 1, 0);
166 }
167 break;
168 case RTR0MEMOBJTYPE_RES_VIRT:
169 if (pMemNetBSD->Core.u.Lock.R0Process == NIL_RTR0PROCESS)
170 {
171 uvm_km_free(kernel_map, (vaddr_t)pMemNetBSD->Core.pv, pMemNetBSD->Core.cb, UVM_KMF_VAONLY);
172 }
173 break;
174 case RTR0MEMOBJTYPE_MAPPING:
175 if (pMemNetBSD->Core.u.Lock.R0Process == NIL_RTR0PROCESS)
176 {
177 pmap_kremove((vaddr_t)pMemNetBSD->Core.pv, pMemNetBSD->Core.cb);
178 uvm_km_free(kernel_map, (vaddr_t)pMemNetBSD->Core.pv, pMemNetBSD->Core.cb, UVM_KMF_VAONLY);
179 }
180 break;
181
182 default:
183 AssertMsgFailed(("enmType=%d\n", pMemNetBSD->Core.enmType));
184 return VERR_INTERNAL_ERROR;
185 }
186
187 return VINF_SUCCESS;
188}
189
190static int rtR0MemObjNetBSDAllocHelper(PRTR0MEMOBJNETBSD pMemNetBSD, size_t cb, bool fExecutable,
191 paddr_t VmPhysAddrHigh, bool fContiguous)
192{
193 /* Virtual space first */
194 vaddr_t virt = uvm_km_alloc(kernel_map, cb, 0, UVM_KMF_VAONLY | UVM_KMF_WAITVA | UVM_KMF_CANFAIL);
195 if (virt == 0)
196 return VERR_NO_MEMORY;
197
198 struct pglist *rlist = &pMemNetBSD->pglist;
199
200 int nsegs = fContiguous ? 1 : INT_MAX;
201
202 /* Physical pages */
203 if (uvm_pglistalloc(cb, 0, VmPhysAddrHigh, PAGE_SIZE, 0, rlist, nsegs, 1) != 0)
204 {
205 uvm_km_free(kernel_map, virt, cb, UVM_KMF_VAONLY);
206 return VERR_NO_MEMORY; /** @todo inaccurate status code */
207 }
208
209 /* Map */
210 struct vm_page *page;
211 vm_prot_t prot = VM_PROT_READ | VM_PROT_WRITE;
212 if (fExecutable)
213 prot |= VM_PROT_EXECUTE;
214 vaddr_t virt2 = virt;
215 TAILQ_FOREACH(page, rlist, pageq.queue)
216 {
217 pmap_kenter_pa(virt2, VM_PAGE_TO_PHYS(page), prot, 0);
218 virt2 += PAGE_SIZE;
219 }
220
221 pMemNetBSD->Core.fFlags |= RTR0MEMOBJ_FLAGS_UNINITIALIZED_AT_ALLOC; /*?*/
222 pMemNetBSD->Core.pv = (void *)virt;
223 if (fContiguous)
224 {
225 page = TAILQ_FIRST(rlist);
226 pMemNetBSD->Core.u.Cont.Phys = VM_PAGE_TO_PHYS(page);
227 }
228 return VINF_SUCCESS;
229}
230
231
232DECLHIDDEN(int) rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable, const char *pszTag)
233{
234 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD), RTR0MEMOBJTYPE_PAGE, NULL, cb, pszTag);
235 if (pMemNetBSD)
236 {
237 void *pvMem = kmem_alloc(cb, KM_SLEEP);
238 if (pvMem)
239 {
240 if (fExecutable)
241 pmap_protect(pmap_kernel(), (vaddr_t)pvMem, (vaddr_t)pvMem + cb, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
242
243 pMemNetBSD->Core.fFlags |= RTR0MEMOBJ_FLAGS_UNINITIALIZED_AT_ALLOC;
244 pMemNetBSD->Core.pv = pvMem;
245 *ppMem = &pMemNetBSD->Core;
246 return VINF_SUCCESS;
247 }
248 rtR0MemObjDelete(&pMemNetBSD->Core);
249 return VERR_NO_PAGE_MEMORY;
250 }
251 return VERR_NO_MEMORY;
252}
253
254
255DECLHIDDEN(int) rtR0MemObjNativeAllocLarge(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, size_t cbLargePage, uint32_t fFlags,
256 const char *pszTag)
257{
258 return rtR0MemObjFallbackAllocLarge(ppMem, cb, cbLargePage, fFlags, pszTag);
259}
260
261
262DECLHIDDEN(int) rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable, const char *pszTag)
263{
264 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD), RTR0MEMOBJTYPE_LOW, NULL, cb, pszTag);
265 if (pMemNetBSD)
266 {
267 int rc = rtR0MemObjNetBSDAllocHelper(pMemNetBSD, cb, fExecutable, _4G - 1, false /*fContiguous*/);
268 if (RT_SUCCESS(rc))
269 {
270 *ppMem = &pMemNetBSD->Core;
271 return VINF_SUCCESS;
272 }
273 rtR0MemObjDelete(&pMemNetBSD->Core);
274 return rc;
275 }
276 return VERR_NO_MEMORY;
277}
278
279
280DECLHIDDEN(int) rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable, const char *pszTag)
281{
282 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD), RTR0MEMOBJTYPE_CONT, NULL, cb, pszTag);
283 if (pMemNetBSD)
284 {
285 int rc = rtR0MemObjNetBSDAllocHelper(pMemNetBSD, cb, fExecutable, _4G - 1, true /*fContiguous*/);
286 if (RT_SUCCESS(rc))
287 {
288 *ppMem = &pMemNetBSD->Core;
289 return VINF_SUCCESS;
290 }
291 rtR0MemObjDelete(&pMemNetBSD->Core);
292 return rc;
293 }
294 return VERR_NO_MEMORY;
295}
296
297
298static int rtR0MemObjNetBSDAllocPhysPages(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJTYPE enmType, size_t cb,
299 RTHCPHYS PhysHighest, size_t uAlignment, bool fContiguous, const char *pszTag)
300{
301 /* create the object. */
302 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD), enmType, NULL, cb, pszTag);
303 if (pMemNetBSD)
304 {
305 paddr_t const VmPhysAddrHigh = PhysHighest != NIL_RTHCPHYS ? PhysHighest : ~(paddr_t)0;
306 int const nsegs = fContiguous ? 1 : INT_MAX;
307 int rc = uvm_pglistalloc(cb, 0, VmPhysAddrHigh, uAlignment, 0, &pMemNetBSD->pglist, nsegs, 1);
308 if (!rc)
309 {
310 pMemNetBSD->Core.fFlags |= RTR0MEMOBJ_FLAGS_UNINITIALIZED_AT_ALLOC; /*?*/
311 if (fContiguous)
312 {
313 Assert(enmType == RTR0MEMOBJTYPE_PHYS);
314 const struct vm_page * const pg = TAILQ_FIRST(&pMemNetBSD->pglist);
315 pMemNetBSD->Core.u.Phys.PhysBase = VM_PAGE_TO_PHYS(pg);
316 pMemNetBSD->Core.u.Phys.fAllocated = true;
317 }
318 *ppMem = &pMemNetBSD->Core;
319 return VINF_SUCCESS;
320 }
321 rtR0MemObjDelete(&pMemNetBSD->Core);
322 return VERR_NO_PAGE_MEMORY;
323 }
324 return VERR_NO_MEMORY;
325}
326
327
328DECLHIDDEN(int) rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment,
329 const char *pszTag)
330{
331 return rtR0MemObjNetBSDAllocPhysPages(ppMem, RTR0MEMOBJTYPE_PHYS, cb, PhysHighest, uAlignment, true, pszTag);
332}
333
334
335DECLHIDDEN(int) rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, const char *pszTag)
336{
337 return rtR0MemObjNetBSDAllocPhysPages(ppMem, RTR0MEMOBJTYPE_PHYS_NC, cb, PhysHighest, PAGE_SIZE, false, pszTag);
338}
339
340
341DECLHIDDEN(int) rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy,
342 const char *pszTag)
343{
344 AssertReturn(uCachePolicy == RTMEM_CACHE_POLICY_DONT_CARE, VERR_NOT_SUPPORTED);
345
346 /* create the object. */
347 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD), RTR0MEMOBJTYPE_PHYS, NULL, cb, pszTag);
348 if (pMemNetBSD)
349 {
350 /* there is no allocation here, it needs to be mapped somewhere first. */
351 pMemNetBSD->Core.u.Phys.fAllocated = false;
352 pMemNetBSD->Core.u.Phys.PhysBase = Phys;
353 pMemNetBSD->Core.u.Phys.uCachePolicy = uCachePolicy;
354 TAILQ_INIT(&pMemNetBSD->pglist);
355 *ppMem = &pMemNetBSD->Core;
356 return VINF_SUCCESS;
357 }
358 return VERR_NO_MEMORY;
359}
360
361
362DECLHIDDEN(int) rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess,
363 RTR0PROCESS R0Process, const char *pszTag)
364{
365 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD), RTR0MEMOBJTYPE_LOCK,
366 (void *)R3Ptr, cb, pszTag);
367 if (pMemNetBSD)
368 {
369 int rc = uvm_map_pageable(&((struct proc *)R0Process)->p_vmspace->vm_map, R3Ptr, R3Ptr + cb,
370 0 /*new_pageable*/, 0 /*lockflags*/);
371 if (!rc)
372 {
373 pMemNetBSD->Core.u.Lock.R0Process = R0Process;
374 *ppMem = &pMemNetBSD->Core;
375 return VINF_SUCCESS;
376 }
377 rtR0MemObjDelete(&pMemNetBSD->Core);
378 return VERR_LOCK_FAILED;
379 }
380 return VERR_NO_MEMORY;
381}
382
383
384DECLHIDDEN(int) rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess, const char *pszTag)
385{
386 /* Kernel memory (always?) wired; all memory allocated by vbox code is? */
387 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD), RTR0MEMOBJTYPE_LOCK, pv, cb, pszTag);
388 if (pMemNetBSD)
389 {
390 pMemNetBSD->Core.u.Lock.R0Process = NIL_RTR0PROCESS;
391 pMemNetBSD->Core.pv = pv;
392 *ppMem = &pMemNetBSD->Core;
393 return VINF_SUCCESS;
394 }
395 return VERR_NO_MEMORY;
396}
397
398DECLHIDDEN(int) rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment,
399 const char *pszTag)
400{
401 if (pvFixed != (void *)-1)
402 {
403 /* can we support this? or can we assume the virtual space is already reserved? */
404 printf("reserve specified kernel virtual address not supported\n");
405 return VERR_NOT_SUPPORTED;
406 }
407
408 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD), RTR0MEMOBJTYPE_RES_VIRT,
409 NULL, cb, pszTag);
410 if (pMemNetBSD)
411 {
412 vaddr_t virt = uvm_km_alloc(kernel_map, cb, uAlignment, UVM_KMF_VAONLY | UVM_KMF_WAITVA | UVM_KMF_CANFAIL);
413 if (virt != 0)
414 {
415 pMemNetBSD->Core.u.ResVirt.R0Process = NIL_RTR0PROCESS;
416 pMemNetBSD->Core.pv = (void *)virt;
417 *ppMem = &pMemNetBSD->Core;
418 return VINF_SUCCESS;
419 }
420 rtR0MemObjDelete(&pMemNetBSD->Core);
421 return VERR_NO_MEMORY;
422 }
423 return VERR_NO_MEMORY;
424}
425
426
427DECLHIDDEN(int) rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment,
428 RTR0PROCESS R0Process, const char *pszTag)
429{
430 RT_NOREF(ppMem, R3PtrFixed, cb, uAlignment, R0Process, pszTag);
431 printf("NativeReserveUser\n");
432 return VERR_NOT_SUPPORTED;
433}
434
435
436DECLHIDDEN(int) rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
437 unsigned fProt, size_t offSub, size_t cbSub, const char *pszTag)
438{
439 if (pvFixed != (void *)-1)
440 {
441 /* can we support this? or can we assume the virtual space is already reserved? */
442 printf("map to specified kernel virtual address not supported\n");
443 return VERR_NOT_SUPPORTED;
444 }
445
446 PRTR0MEMOBJNETBSD pMemNetBSD0 = (PRTR0MEMOBJNETBSD)pMemToMap;
447 if ((pMemNetBSD0->Core.enmType != RTR0MEMOBJTYPE_PHYS)
448 && (pMemNetBSD0->Core.enmType != RTR0MEMOBJTYPE_PHYS_NC))
449 {
450 printf("memory to map is not physical\n");
451 return VERR_NOT_SUPPORTED;
452 }
453 size_t sz = cbSub > 0 ? cbSub : pMemNetBSD0->Core.cb;
454
455 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD), RTR0MEMOBJTYPE_MAPPING, NULL, sz, pszTag);
456
457 vaddr_t virt = uvm_km_alloc(kernel_map, sz, uAlignment, UVM_KMF_VAONLY | UVM_KMF_WAITVA | UVM_KMF_CANFAIL);
458 if (virt != 0)
459 {
460 vm_prot_t prot = 0;
461 if (fProt & RTMEM_PROT_READ)
462 prot |= VM_PROT_READ;
463 if (fProt & RTMEM_PROT_WRITE)
464 prot |= VM_PROT_WRITE;
465 if (fProt & RTMEM_PROT_EXEC)
466 prot |= VM_PROT_EXECUTE;
467
468 struct vm_page *page;
469 vaddr_t virt2 = virt;
470 size_t map_pos = 0;
471 TAILQ_FOREACH(page, &pMemNetBSD0->pglist, pageq.queue)
472 {
473 if (map_pos >= offSub)
474 {
475 if (cbSub > 0 && (map_pos >= offSub + cbSub))
476 break;
477
478 pmap_kenter_pa(virt2, VM_PAGE_TO_PHYS(page), prot, 0);
479 virt2 += PAGE_SIZE;
480 }
481 map_pos += PAGE_SIZE;
482 }
483
484 pMemNetBSD->Core.pv = (void *)virt;
485 pMemNetBSD->Core.u.Mapping.R0Process = NIL_RTR0PROCESS;
486 *ppMem = &pMemNetBSD->Core;
487 return VINF_SUCCESS;
488 }
489
490 rtR0MemObjDelete(&pMemNetBSD->Core);
491 return VERR_NO_MEMORY;
492}
493
494
495DECLHIDDEN(int) rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment,
496 unsigned fProt, RTR0PROCESS R0Process, size_t offSub, size_t cbSub, const char *pszTag)
497{
498 RT_NOREF(ppMem, pMemToMap, R3PtrFixed, uAlignment, fProt, R0Process, offSub, cbSub, pszTag);
499 printf("NativeMapUser\n");
500 return VERR_NOT_SUPPORTED;
501}
502
503
504DECLHIDDEN(int) rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt)
505{
506 vm_map_t const pVmMap = rtR0MemObjNetBSDGetMap(pMem);
507 if (pVmMap)
508 {
509 vaddr_t const AddrStart = (vaddr_t)pMem->pv + offSub;
510 vm_prot_t ProtectionFlags = 0;
511 if (fProt & RTMEM_PROT_READ)
512 ProtectionFlags |= UVM_PROT_R;
513 if (fProt & RTMEM_PROT_WRITE)
514 ProtectionFlags |= UVM_PROT_W;
515 if (fProt & RTMEM_PROT_EXEC)
516 ProtectionFlags |= UVM_PROT_X;
517
518 int rc = uvm_map_protect(pVmMap, AddrStart, AddrStart + cbSub, ProtectionFlags, 0);
519 if (!rc)
520 return VINF_SUCCESS;
521 return RTErrConvertFromErrno(rc);
522 }
523 return VERR_NOT_SUPPORTED;
524}
525
526
527DECLHIDDEN(RTHCPHYS) rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
528{
529 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)pMem;
530
531 switch (pMemNetBSD->Core.enmType)
532 {
533 case RTR0MEMOBJTYPE_PAGE:
534 case RTR0MEMOBJTYPE_LOW:
535 {
536 vaddr_t va = (vaddr_t)pMemNetBSD->Core.pv + ptoa(iPage);
537 paddr_t pa = 0;
538 pmap_extract(pmap_kernel(), va, &pa);
539 return pa;
540 }
541 case RTR0MEMOBJTYPE_CONT:
542 return pMemNetBSD->Core.u.Cont.Phys + ptoa(iPage);
543 case RTR0MEMOBJTYPE_PHYS:
544 return pMemNetBSD->Core.u.Phys.PhysBase + ptoa(iPage);
545 case RTR0MEMOBJTYPE_PHYS_NC:
546 {
547 struct vm_page *page;
548 size_t i = 0;
549 TAILQ_FOREACH(page, &pMemNetBSD->pglist, pageq.queue)
550 {
551 if (i == iPage)
552 break;
553 i++;
554 }
555 return VM_PAGE_TO_PHYS(page);
556 }
557 case RTR0MEMOBJTYPE_LOCK:
558 case RTR0MEMOBJTYPE_MAPPING:
559 {
560 pmap_t pmap;
561 if (pMem->u.Lock.R0Process == NIL_RTR0PROCESS)
562 pmap = pmap_kernel();
563 else
564 pmap = ((struct proc *)pMem->u.Lock.R0Process)->p_vmspace->vm_map.pmap;
565 vaddr_t va = (vaddr_t)pMemNetBSD->Core.pv + ptoa(iPage);
566 paddr_t pa = 0;
567 pmap_extract(pmap, va, &pa);
568 return pa;
569 }
570 case RTR0MEMOBJTYPE_RES_VIRT:
571 return NIL_RTHCPHYS;
572 default:
573 return NIL_RTHCPHYS;
574 }
575}
576
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