VirtualBox

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

Last change on this file since 91446 was 91446, checked in by vboxsync, 4 years ago

IPRT/memobj: Adding RTR0MemObjAllocLarge for speeding up large page allocations. bugref:5324

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.7 KB
Line 
1/* $Id: memobj-r0drv-netbsd.c 91446 2021-09-28 19:53:25Z 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 <bird-src-spam@anduin.net>
30 * Copyright (c) 2011 Andriy Gapon <avg@FreeBSD.org>
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),
236 RTR0MEMOBJTYPE_PAGE, NULL, cb);
237 if (!pMemNetBSD)
238 return VERR_NO_MEMORY;
239
240 void *pvMem = kmem_alloc(cb, KM_SLEEP);
241 if (RT_UNLIKELY(!pvMem))
242 {
243 rtR0MemObjDelete(&pMemNetBSD->Core);
244 return VERR_NO_PAGE_MEMORY;
245 }
246 if (fExecutable)
247 {
248 pmap_protect(pmap_kernel(), (vaddr_t)pvMem, ((vaddr_t)pvMem) + cb,
249 VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
250 }
251
252 pMemNetBSD->Core.pv = pvMem;
253 *ppMem = &pMemNetBSD->Core;
254 return VINF_SUCCESS;
255}
256
257
258DECLHIDDEN(int) rtR0MemObjNativeAllocLarge(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, size_t cbLargePage, uint32_t fFlags,
259 const char *pszTag)
260{
261 return rtR0MemObjFallbackAllocLarge(ppMem, cb, cbLargePage, fFlags, pszTag);
262}
263
264
265DECLHIDDEN(int) rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
266{
267 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD),
268 RTR0MEMOBJTYPE_LOW, NULL, cb);
269 if (!pMemNetBSD)
270 return VERR_NO_MEMORY;
271
272 int rc = rtR0MemObjNetBSDAllocHelper(pMemNetBSD, cb, fExecutable, _4G - 1, false);
273 if (rc)
274 {
275 rtR0MemObjDelete(&pMemNetBSD->Core);
276 return rc;
277 }
278
279 *ppMem = &pMemNetBSD->Core;
280 return VINF_SUCCESS;
281}
282
283
284DECLHIDDEN(int) rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
285{
286 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD),
287 RTR0MEMOBJTYPE_CONT, NULL, cb);
288 if (!pMemNetBSD)
289 return VERR_NO_MEMORY;
290
291 int rc = rtR0MemObjNetBSDAllocHelper(pMemNetBSD, cb, fExecutable, _4G - 1, true);
292 if (rc)
293 {
294 rtR0MemObjDelete(&pMemNetBSD->Core);
295 return rc;
296 }
297
298 *ppMem = &pMemNetBSD->Core;
299 return VINF_SUCCESS;
300}
301
302
303static int rtR0MemObjNetBSDAllocPhysPages(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJTYPE enmType,
304 size_t cb,
305 RTHCPHYS PhysHighest, size_t uAlignment,
306 bool fContiguous)
307{
308 paddr_t VmPhysAddrHigh;
309
310 /* create the object. */
311 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD),
312 enmType, NULL, cb);
313 if (!pMemNetBSD)
314 return VERR_NO_MEMORY;
315
316 if (PhysHighest != NIL_RTHCPHYS)
317 VmPhysAddrHigh = PhysHighest;
318 else
319 VmPhysAddrHigh = ~(paddr_t)0;
320
321 int nsegs = fContiguous ? 1 : INT_MAX;
322
323 int error = uvm_pglistalloc(cb, 0, VmPhysAddrHigh, uAlignment, 0, &pMemNetBSD->pglist, nsegs, 1);
324 if (error)
325 {
326 rtR0MemObjDelete(&pMemNetBSD->Core);
327 return VERR_NO_MEMORY;
328 }
329
330 if (fContiguous)
331 {
332 Assert(enmType == RTR0MEMOBJTYPE_PHYS);
333 const struct vm_page * const pg = TAILQ_FIRST(&pMemNetBSD->pglist);
334 pMemNetBSD->Core.u.Phys.PhysBase = VM_PAGE_TO_PHYS(pg);
335 pMemNetBSD->Core.u.Phys.fAllocated = true;
336 }
337 *ppMem = &pMemNetBSD->Core;
338
339 return VINF_SUCCESS;
340}
341
342
343DECLHIDDEN(int) rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment)
344{
345 return rtR0MemObjNetBSDAllocPhysPages(ppMem, RTR0MEMOBJTYPE_PHYS, cb, PhysHighest, uAlignment, true);
346}
347
348
349DECLHIDDEN(int) rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
350{
351 return rtR0MemObjNetBSDAllocPhysPages(ppMem, RTR0MEMOBJTYPE_PHYS_NC, cb, PhysHighest, PAGE_SIZE, false);
352}
353
354
355DECLHIDDEN(int) rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy)
356{
357 AssertReturn(uCachePolicy == RTMEM_CACHE_POLICY_DONT_CARE, VERR_NOT_SUPPORTED);
358
359 /* create the object. */
360 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD), RTR0MEMOBJTYPE_PHYS, NULL, cb);
361 if (!pMemNetBSD)
362 return VERR_NO_MEMORY;
363
364 /* there is no allocation here, it needs to be mapped somewhere first. */
365 pMemNetBSD->Core.u.Phys.fAllocated = false;
366 pMemNetBSD->Core.u.Phys.PhysBase = Phys;
367 pMemNetBSD->Core.u.Phys.uCachePolicy = uCachePolicy;
368 TAILQ_INIT(&pMemNetBSD->pglist);
369 *ppMem = &pMemNetBSD->Core;
370 return VINF_SUCCESS;
371}
372
373
374DECLHIDDEN(int) rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess, RTR0PROCESS R0Process)
375{
376 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD), RTR0MEMOBJTYPE_LOCK, (void *)R3Ptr, cb);
377 if (!pMemNetBSD)
378 return VERR_NO_MEMORY;
379
380 int rc = uvm_map_pageable(
381 &((struct proc *)R0Process)->p_vmspace->vm_map,
382 R3Ptr,
383 R3Ptr + cb,
384 0, 0);
385 if (rc)
386 {
387 rtR0MemObjDelete(&pMemNetBSD->Core);
388 return VERR_NO_MEMORY;
389 }
390
391 pMemNetBSD->Core.u.Lock.R0Process = R0Process;
392 *ppMem = &pMemNetBSD->Core;
393 return VINF_SUCCESS;
394}
395
396
397DECLHIDDEN(int) rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess)
398{
399 /* Kernel memory (always?) wired; all memory allocated by vbox code is? */
400 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD), RTR0MEMOBJTYPE_LOCK, pv, cb);
401 if (!pMemNetBSD)
402 return VERR_NO_MEMORY;
403
404 pMemNetBSD->Core.u.Lock.R0Process = NIL_RTR0PROCESS;
405 pMemNetBSD->Core.pv = pv;
406 *ppMem = &pMemNetBSD->Core;
407 return VINF_SUCCESS;
408}
409
410DECLHIDDEN(int) rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment)
411{
412 if (pvFixed != (void *)-1)
413 {
414 /* can we support this? or can we assume the virtual space is already reserved? */
415 printf("reserve specified kernel virtual address not supported\n");
416 return VERR_NOT_SUPPORTED;
417 }
418
419 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)rtR0MemObjNew(sizeof(*pMemNetBSD), RTR0MEMOBJTYPE_RES_VIRT, NULL, cb);
420 if (!pMemNetBSD)
421 return VERR_NO_MEMORY;
422
423 vaddr_t virt = uvm_km_alloc(kernel_map, cb, uAlignment,
424 UVM_KMF_VAONLY | UVM_KMF_WAITVA | UVM_KMF_CANFAIL);
425 if (virt == 0)
426 {
427 rtR0MemObjDelete(&pMemNetBSD->Core);
428 return VERR_NO_MEMORY;
429 }
430
431 pMemNetBSD->Core.u.ResVirt.R0Process = NIL_RTR0PROCESS;
432 pMemNetBSD->Core.pv = (void *)virt;
433 *ppMem = &pMemNetBSD->Core;
434 return VINF_SUCCESS;
435}
436
437
438DECLHIDDEN(int) rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, RTR0PROCESS R0Process)
439{
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)
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);
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)
509{
510 printf("NativeMapUser\n");
511 return VERR_NOT_SUPPORTED;
512}
513
514
515DECLHIDDEN(int) rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt)
516{
517 vm_prot_t ProtectionFlags = 0;
518 vaddr_t AddrStart = (vaddr_t)pMem->pv + offSub;
519 vm_map_t pVmMap = rtR0MemObjNetBSDGetMap(pMem);
520
521 if (!pVmMap)
522 return VERR_NOT_SUPPORTED;
523
524 if ((fProt & RTMEM_PROT_READ) == RTMEM_PROT_READ)
525 ProtectionFlags |= UVM_PROT_R;
526 if ((fProt & RTMEM_PROT_WRITE) == RTMEM_PROT_WRITE)
527 ProtectionFlags |= UVM_PROT_W;
528 if ((fProt & RTMEM_PROT_EXEC) == RTMEM_PROT_EXEC)
529 ProtectionFlags |= UVM_PROT_X;
530
531 int error = uvm_map_protect(pVmMap, AddrStart, AddrStart + cbSub,
532 ProtectionFlags, 0);
533 if (!error)
534 return VINF_SUCCESS;
535
536 return VERR_NOT_SUPPORTED;
537}
538
539
540DECLHIDDEN(RTHCPHYS) rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
541{
542 PRTR0MEMOBJNETBSD pMemNetBSD = (PRTR0MEMOBJNETBSD)pMem;
543
544 switch (pMemNetBSD->Core.enmType)
545 {
546 case RTR0MEMOBJTYPE_PAGE:
547 case RTR0MEMOBJTYPE_LOW:
548 {
549 vaddr_t va = (vaddr_t)pMemNetBSD->Core.pv + ptoa(iPage);
550 paddr_t pa = 0;
551 pmap_extract(pmap_kernel(), va, &pa);
552 return pa;
553 }
554 case RTR0MEMOBJTYPE_CONT:
555 return pMemNetBSD->Core.u.Cont.Phys + ptoa(iPage);
556 case RTR0MEMOBJTYPE_PHYS:
557 return pMemNetBSD->Core.u.Phys.PhysBase + ptoa(iPage);
558 case RTR0MEMOBJTYPE_PHYS_NC:
559 {
560 struct vm_page *page;
561 size_t i = 0;
562 TAILQ_FOREACH(page, &pMemNetBSD->pglist, pageq.queue)
563 {
564 if (i == iPage)
565 break;
566 i++;
567 }
568 return VM_PAGE_TO_PHYS(page);
569 }
570 case RTR0MEMOBJTYPE_LOCK:
571 case RTR0MEMOBJTYPE_MAPPING:
572 {
573 pmap_t pmap;
574 if (pMem->u.Lock.R0Process == NIL_RTR0PROCESS)
575 pmap = pmap_kernel();
576 else
577 pmap = ((struct proc *)pMem->u.Lock.R0Process)->p_vmspace->vm_map.pmap;
578 vaddr_t va = (vaddr_t)pMemNetBSD->Core.pv + ptoa(iPage);
579 paddr_t pa = 0;
580 pmap_extract(pmap, va, &pa);
581 return pa;
582 }
583 case RTR0MEMOBJTYPE_RES_VIRT:
584 return NIL_RTHCPHYS;
585 default:
586 return NIL_RTHCPHYS;
587 }
588}
589
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette