VirtualBox

source: vbox/trunk/src/VBox/Runtime/r0drv/netbsd/memobj-r0drv-netbsd.c@ 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 Author Date Id Revision
File size: 19.9 KB
Line 
1/* $Id: memobj-r0drv-netbsd.c 91481 2021-09-30 00:06:31Z 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-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 * 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,
195 UVM_KMF_VAONLY | UVM_KMF_WAITVA | UVM_KMF_CANFAIL);
196 if (virt == 0)
197 return VERR_NO_MEMORY;
198
199 struct pglist *rlist = &pMemNetBSD->pglist;
200
201 int nsegs = fContiguous ? 1 : INT_MAX;
202
203 /* Physical pages */
204 if (uvm_pglistalloc(cb, 0, VmPhysAddrHigh,
205 PAGE_SIZE, 0, rlist, nsegs, 1) != 0)
206 {
207 uvm_km_free(kernel_map, virt, cb, UVM_KMF_VAONLY);
208 return VERR_NO_MEMORY;
209 }
210
211 /* Map */
212 struct vm_page *page;
213 vm_prot_t prot = VM_PROT_READ | VM_PROT_WRITE;
214 if (fExecutable)
215 prot |= VM_PROT_EXECUTE;
216 vaddr_t virt2 = virt;
217 TAILQ_FOREACH(page, rlist, pageq.queue)
218 {
219 pmap_kenter_pa(virt2, VM_PAGE_TO_PHYS(page), prot, 0);
220 virt2 += PAGE_SIZE;
221 }
222
223 pMemNetBSD->Core.pv = (void *)virt;
224 if (fContiguous)
225 {
226 page = TAILQ_FIRST(rlist);
227 pMemNetBSD->Core.u.Cont.Phys = VM_PAGE_TO_PHYS(page);
228 }
229 return VINF_SUCCESS;
230}
231
232
233DECLHIDDEN(int) rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
234{
235 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD), RTR0MEMOBJTYPE_PAGE, NULL, cb, NULL);
236 if (!pMemNetBSD)
237 return VERR_NO_MEMORY;
238
239 void *pvMem = kmem_alloc(cb, KM_SLEEP);
240 if (RT_UNLIKELY(!pvMem))
241 {
242 rtR0MemObjDelete(&pMemNetBSD->Core);
243 return VERR_NO_PAGE_MEMORY;
244 }
245 if (fExecutable)
246 {
247 pmap_protect(pmap_kernel(), (vaddr_t)pvMem, ((vaddr_t)pvMem) + cb,
248 VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
249 }
250
251 pMemNetBSD->Core.pv = pvMem;
252 *ppMem = &pMemNetBSD->Core;
253 return VINF_SUCCESS;
254}
255
256
257DECLHIDDEN(int) rtR0MemObjNativeAllocLarge(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, size_t cbLargePage, uint32_t fFlags,
258 const char *pszTag)
259{
260 return rtR0MemObjFallbackAllocLarge(ppMem, cb, cbLargePage, fFlags, pszTag);
261}
262
263
264DECLHIDDEN(int) rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
265{
266 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD), RTR0MEMOBJTYPE_LOW, NULL, cb, NULL);
267 if (!pMemNetBSD)
268 return VERR_NO_MEMORY;
269
270 int rc = rtR0MemObjNetBSDAllocHelper(pMemNetBSD, cb, fExecutable, _4G - 1, false);
271 if (rc)
272 {
273 rtR0MemObjDelete(&pMemNetBSD->Core);
274 return rc;
275 }
276
277 *ppMem = &pMemNetBSD->Core;
278 return VINF_SUCCESS;
279}
280
281
282DECLHIDDEN(int) rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
283{
284 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD), RTR0MEMOBJTYPE_CONT, NULL, cb, NULL);
285 if (!pMemNetBSD)
286 return VERR_NO_MEMORY;
287
288 int rc = rtR0MemObjNetBSDAllocHelper(pMemNetBSD, cb, fExecutable, _4G - 1, true);
289 if (rc)
290 {
291 rtR0MemObjDelete(&pMemNetBSD->Core);
292 return rc;
293 }
294
295 *ppMem = &pMemNetBSD->Core;
296 return VINF_SUCCESS;
297}
298
299
300static int rtR0MemObjNetBSDAllocPhysPages(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJTYPE enmType, size_t cb,
301 RTHCPHYS PhysHighest, size_t uAlignment, bool fContiguous, const char *pszTag)
302{
303 paddr_t VmPhysAddrHigh;
304
305 /* create the object. */
306 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD), enmType, NULL, cb, pszTag);
307 if (!pMemNetBSD)
308 return VERR_NO_MEMORY;
309
310 if (PhysHighest != NIL_RTHCPHYS)
311 VmPhysAddrHigh = PhysHighest;
312 else
313 VmPhysAddrHigh = ~(paddr_t)0;
314
315 int nsegs = fContiguous ? 1 : INT_MAX;
316
317 int error = uvm_pglistalloc(cb, 0, VmPhysAddrHigh, uAlignment, 0, &pMemNetBSD->pglist, nsegs, 1);
318 if (error)
319 {
320 rtR0MemObjDelete(&pMemNetBSD->Core);
321 return VERR_NO_MEMORY;
322 }
323
324 if (fContiguous)
325 {
326 Assert(enmType == RTR0MEMOBJTYPE_PHYS);
327 const struct vm_page * const pg = TAILQ_FIRST(&pMemNetBSD->pglist);
328 pMemNetBSD->Core.u.Phys.PhysBase = VM_PAGE_TO_PHYS(pg);
329 pMemNetBSD->Core.u.Phys.fAllocated = true;
330 }
331 *ppMem = &pMemNetBSD->Core;
332
333 return VINF_SUCCESS;
334}
335
336
337DECLHIDDEN(int) rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment,
338 const char *pszTag)
339{
340 return rtR0MemObjNetBSDAllocPhysPages(ppMem, RTR0MEMOBJTYPE_PHYS, cb, PhysHighest, uAlignment, true, pszTag);
341}
342
343
344DECLHIDDEN(int) rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
345{
346 return rtR0MemObjNetBSDAllocPhysPages(ppMem, RTR0MEMOBJTYPE_PHYS_NC, cb, PhysHighest, PAGE_SIZE, false, pszTag);
347}
348
349
350DECLHIDDEN(int) rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy,
351 const char *pszTag)
352{
353 AssertReturn(uCachePolicy == RTMEM_CACHE_POLICY_DONT_CARE, VERR_NOT_SUPPORTED);
354
355 /* create the object. */
356 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD), RTR0MEMOBJTYPE_PHYS, NULL, cb, pszTag);
357 if (!pMemNetBSD)
358 return VERR_NO_MEMORY;
359
360 /* there is no allocation here, it needs to be mapped somewhere first. */
361 pMemNetBSD->Core.u.Phys.fAllocated = false;
362 pMemNetBSD->Core.u.Phys.PhysBase = Phys;
363 pMemNetBSD->Core.u.Phys.uCachePolicy = uCachePolicy;
364 TAILQ_INIT(&pMemNetBSD->pglist);
365 *ppMem = &pMemNetBSD->Core;
366 return VINF_SUCCESS;
367}
368
369
370DECLHIDDEN(int) rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess, RTR0PROCESS R0Process)
371{
372 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD), RTR0MEMOBJTYPE_LOCK, (void *)R3Ptr, cb, NULL);
373 if (!pMemNetBSD)
374 return VERR_NO_MEMORY;
375
376 int rc = uvm_map_pageable(
377 &((struct proc *)R0Process)->p_vmspace->vm_map,
378 R3Ptr,
379 R3Ptr + cb,
380 0, 0);
381 if (rc)
382 {
383 rtR0MemObjDelete(&pMemNetBSD->Core);
384 return VERR_NO_MEMORY;
385 }
386
387 pMemNetBSD->Core.u.Lock.R0Process = R0Process;
388 *ppMem = &pMemNetBSD->Core;
389 return VINF_SUCCESS;
390}
391
392
393DECLHIDDEN(int) rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess)
394{
395 /* Kernel memory (always?) wired; all memory allocated by vbox code is? */
396 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD), RTR0MEMOBJTYPE_LOCK, pv, cb, NULL);
397 if (!pMemNetBSD)
398 return VERR_NO_MEMORY;
399
400 pMemNetBSD->Core.u.Lock.R0Process = NIL_RTR0PROCESS;
401 pMemNetBSD->Core.pv = pv;
402 *ppMem = &pMemNetBSD->Core;
403 return VINF_SUCCESS;
404}
405
406DECLHIDDEN(int) rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment,
407 const char *pszTag)
408{
409 if (pvFixed != (void *)-1)
410 {
411 /* can we support this? or can we assume the virtual space is already reserved? */
412 printf("reserve specified kernel virtual address not supported\n");
413 return VERR_NOT_SUPPORTED;
414 }
415
416 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD), RTR0MEMOBJTYPE_RES_VIRT,
417 NULL, cb, pszTag);
418 if (!pMemNetBSD)
419 return VERR_NO_MEMORY;
420
421 vaddr_t virt = uvm_km_alloc(kernel_map, cb, uAlignment,
422 UVM_KMF_VAONLY | UVM_KMF_WAITVA | UVM_KMF_CANFAIL);
423 if (virt == 0)
424 {
425 rtR0MemObjDelete(&pMemNetBSD->Core);
426 return VERR_NO_MEMORY;
427 }
428
429 pMemNetBSD->Core.u.ResVirt.R0Process = NIL_RTR0PROCESS;
430 pMemNetBSD->Core.pv = (void *)virt;
431 *ppMem = &pMemNetBSD->Core;
432 return VINF_SUCCESS;
433}
434
435
436DECLHIDDEN(int) rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment,
437 RTR0PROCESS R0Process, const char *pszTag)
438{
439 RT_NOREF(ppMem, R3PtrFixed, cb, uAlignment, R0Process, pszTag);
440 printf("NativeReserveUser\n");
441 return VERR_NOT_SUPPORTED;
442}
443
444
445DECLHIDDEN(int) rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
446 unsigned fProt, size_t offSub, size_t cbSub, const char *pszTag)
447{
448 if (pvFixed != (void *)-1)
449 {
450 /* can we support this? or can we assume the virtual space is already reserved? */
451 printf("map to specified kernel virtual address not supported\n");
452 return VERR_NOT_SUPPORTED;
453 }
454
455 PRTR0MEMOBJNETBSD pMemNetBSD0 = (PRTR0MEMOBJNETBSD)pMemToMap;
456 if ((pMemNetBSD0->Core.enmType != RTR0MEMOBJTYPE_PHYS)
457 && (pMemNetBSD0->Core.enmType != RTR0MEMOBJTYPE_PHYS_NC))
458 {
459 printf("memory to map is not physical\n");
460 return VERR_NOT_SUPPORTED;
461 }
462 size_t sz = cbSub > 0 ? cbSub : pMemNetBSD0->Core.cb;
463
464 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD), RTR0MEMOBJTYPE_MAPPING, NULL, sz, pszTag);
465
466 vaddr_t virt = uvm_km_alloc(kernel_map, sz, uAlignment,
467 UVM_KMF_VAONLY | UVM_KMF_WAITVA | UVM_KMF_CANFAIL);
468 if (virt == 0)
469 {
470 rtR0MemObjDelete(&pMemNetBSD->Core);
471 return VERR_NO_MEMORY;
472 }
473
474 vm_prot_t prot = 0;
475
476 if ((fProt & RTMEM_PROT_READ) == RTMEM_PROT_READ)
477 prot |= VM_PROT_READ;
478 if ((fProt & RTMEM_PROT_WRITE) == RTMEM_PROT_WRITE)
479 prot |= VM_PROT_WRITE;
480 if ((fProt & RTMEM_PROT_EXEC) == RTMEM_PROT_EXEC)
481 prot |= VM_PROT_EXECUTE;
482
483 struct vm_page *page;
484 vaddr_t virt2 = virt;
485 size_t map_pos = 0;
486 TAILQ_FOREACH(page, &pMemNetBSD0->pglist, pageq.queue)
487 {
488 if (map_pos >= offSub)
489 {
490 if (cbSub > 0 && (map_pos >= offSub + cbSub))
491 break;
492
493 pmap_kenter_pa(virt2, VM_PAGE_TO_PHYS(page), prot, 0);
494 virt2 += PAGE_SIZE;
495 }
496 map_pos += PAGE_SIZE;
497 }
498
499 pMemNetBSD->Core.pv = (void *)virt;
500 pMemNetBSD->Core.u.Mapping.R0Process = NIL_RTR0PROCESS;
501 *ppMem = &pMemNetBSD->Core;
502
503 return VINF_SUCCESS;
504}
505
506
507DECLHIDDEN(int) rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment,
508 unsigned fProt, RTR0PROCESS R0Process, size_t offSub, size_t cbSub, const char *pszTag)
509{
510 RT_NOREF(ppMem, pMemToMap, R3PtrFixed, uAlignment, fProt, R0Process, offSub, cbSub, pszTag);
511 printf("NativeMapUser\n");
512 return VERR_NOT_SUPPORTED;
513}
514
515
516DECLHIDDEN(int) rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt)
517{
518 vm_prot_t ProtectionFlags = 0;
519 vaddr_t AddrStart = (vaddr_t)pMem->pv + offSub;
520 vm_map_t pVmMap = rtR0MemObjNetBSDGetMap(pMem);
521
522 if (!pVmMap)
523 return VERR_NOT_SUPPORTED;
524
525 if ((fProt & RTMEM_PROT_READ) == RTMEM_PROT_READ)
526 ProtectionFlags |= UVM_PROT_R;
527 if ((fProt & RTMEM_PROT_WRITE) == RTMEM_PROT_WRITE)
528 ProtectionFlags |= UVM_PROT_W;
529 if ((fProt & RTMEM_PROT_EXEC) == RTMEM_PROT_EXEC)
530 ProtectionFlags |= UVM_PROT_X;
531
532 int error = uvm_map_protect(pVmMap, AddrStart, AddrStart + cbSub,
533 ProtectionFlags, 0);
534 if (!error)
535 return VINF_SUCCESS;
536
537 return VERR_NOT_SUPPORTED;
538}
539
540
541DECLHIDDEN(RTHCPHYS) rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
542{
543 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)pMem;
544
545 switch (pMemNetBSD->Core.enmType)
546 {
547 case RTR0MEMOBJTYPE_PAGE:
548 case RTR0MEMOBJTYPE_LOW:
549 {
550 vaddr_t va = (vaddr_t)pMemNetBSD->Core.pv + ptoa(iPage);
551 paddr_t pa = 0;
552 pmap_extract(pmap_kernel(), va, &pa);
553 return pa;
554 }
555 case RTR0MEMOBJTYPE_CONT:
556 return pMemNetBSD->Core.u.Cont.Phys + ptoa(iPage);
557 case RTR0MEMOBJTYPE_PHYS:
558 return pMemNetBSD->Core.u.Phys.PhysBase + ptoa(iPage);
559 case RTR0MEMOBJTYPE_PHYS_NC:
560 {
561 struct vm_page *page;
562 size_t i = 0;
563 TAILQ_FOREACH(page, &pMemNetBSD->pglist, pageq.queue)
564 {
565 if (i == iPage)
566 break;
567 i++;
568 }
569 return VM_PAGE_TO_PHYS(page);
570 }
571 case RTR0MEMOBJTYPE_LOCK:
572 case RTR0MEMOBJTYPE_MAPPING:
573 {
574 pmap_t pmap;
575 if (pMem->u.Lock.R0Process == NIL_RTR0PROCESS)
576 pmap = pmap_kernel();
577 else
578 pmap = ((struct proc *)pMem->u.Lock.R0Process)->p_vmspace->vm_map.pmap;
579 vaddr_t va = (vaddr_t)pMemNetBSD->Core.pv + ptoa(iPage);
580 paddr_t pa = 0;
581 pmap_extract(pmap, va, &pa);
582 return pa;
583 }
584 case RTR0MEMOBJTYPE_RES_VIRT:
585 return NIL_RTHCPHYS;
586 default:
587 return NIL_RTHCPHYS;
588 }
589}
590
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