VirtualBox

source: vbox/trunk/src/VBox/Runtime/r0drv/solaris/memobj-r0drv-solaris.h@ 99743

Last change on this file since 99743 was 98103, checked in by vboxsync, 2 years ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.1 KB
Line 
1/* $Id: memobj-r0drv-solaris.h 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * IPRT - Ring-0 Memory Objects - Segment driver, Solaris.
4 */
5
6/*
7 * Copyright (C) 2012-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37#ifndef IPRT_INCLUDED_SRC_r0drv_solaris_memobj_r0drv_solaris_h
38#define IPRT_INCLUDED_SRC_r0drv_solaris_memobj_r0drv_solaris_h
39#ifndef RT_WITHOUT_PRAGMA_ONCE
40# pragma once
41#endif
42
43/*******************************************************************************
44* Header Files *
45*******************************************************************************/
46#include "the-solaris-kernel.h"
47
48
49/*******************************************************************************
50* Structures and Typedefs *
51*******************************************************************************/
52typedef struct SEGVBOX_CRARGS
53{
54 uint64_t *paPhysAddrs;
55 size_t cbPageSize;
56 uint_t fPageAccess;
57} SEGVBOX_CRARGS;
58typedef SEGVBOX_CRARGS *PSEGVBOX_CRARGS;
59
60typedef struct SEGVBOX_DATA
61{
62 uint_t fPageAccess;
63 size_t cbPageSize;
64} SEGVBOX_DATA;
65typedef SEGVBOX_DATA *PSEGVBOX_DATA;
66
67static struct seg_ops s_SegVBoxOps;
68static vnode_t s_segVBoxVnode;
69
70
71DECLINLINE(int) rtR0SegVBoxSolCreate(seg_t *pSeg, void *pvArgs)
72{
73 struct as *pAddrSpace = pSeg->s_as;
74 PSEGVBOX_CRARGS pArgs = pvArgs;
75 PSEGVBOX_DATA pData = kmem_zalloc(sizeof(*pData), KM_SLEEP);
76
77 AssertPtr(pAddrSpace);
78 AssertPtr(pArgs);
79 AssertPtr(pData);
80
81 /*
82 * Currently we only map _4K pages but this segment driver can handle any size
83 * supported by the Solaris HAT layer.
84 */
85 size_t cbPageSize = pArgs->cbPageSize;
86 size_t uPageShift = 0;
87 switch (cbPageSize)
88 {
89 case _4K: uPageShift = 12; break;
90 case _2M: uPageShift = 21; break;
91 default: AssertReleaseMsgFailed(("Unsupported page size for mapping cbPageSize=%llx\n", cbPageSize)); break;
92 }
93
94 hat_map(pAddrSpace->a_hat, pSeg->s_base, pSeg->s_size, HAT_MAP);
95 pData->fPageAccess = pArgs->fPageAccess | PROT_USER;
96 pData->cbPageSize = cbPageSize;
97
98 pSeg->s_ops = &s_SegVBoxOps;
99 pSeg->s_data = pData;
100
101 /*
102 * Now load and lock down the mappings to the physical addresses.
103 */
104 caddr_t virtAddr = pSeg->s_base;
105 pgcnt_t cPages = (pSeg->s_size + cbPageSize - 1) >> uPageShift;
106 for (pgcnt_t iPage = 0; iPage < cPages; ++iPage, virtAddr += cbPageSize)
107 {
108 hat_devload(pAddrSpace->a_hat, virtAddr, cbPageSize, pArgs->paPhysAddrs[iPage] >> uPageShift,
109 pData->fPageAccess | HAT_UNORDERED_OK, HAT_LOAD_LOCK);
110 }
111
112 return 0;
113}
114
115
116static int rtR0SegVBoxSolDup(seg_t *pSrcSeg, seg_t *pDstSeg)
117{
118 /*
119 * Duplicate a segment and return the new segment in 'pDstSeg'.
120 */
121 PSEGVBOX_DATA pSrcData = pSrcSeg->s_data;
122 PSEGVBOX_DATA pDstData = kmem_zalloc(sizeof(*pDstData), KM_SLEEP);
123
124 AssertPtr(pDstData);
125 AssertPtr(pSrcData);
126
127 pDstData->fPageAccess = pSrcData->fPageAccess;
128 pDstData->cbPageSize = pSrcData->cbPageSize;
129 pDstSeg->s_ops = &s_SegVBoxOps;
130 pDstSeg->s_data = pDstData;
131
132 return 0;
133}
134
135
136static int rtR0SegVBoxSolUnmap(seg_t *pSeg, caddr_t virtAddr, size_t cb)
137{
138 PSEGVBOX_DATA pData = pSeg->s_data;
139
140 AssertRelease(pData);
141 AssertReleaseMsg(virtAddr >= pSeg->s_base, ("virtAddr=%p s_base=%p\n", virtAddr, pSeg->s_base));
142 AssertReleaseMsg(virtAddr + cb <= pSeg->s_base + pSeg->s_size, ("virtAddr=%p cb=%llu s_base=%p s_size=%llu\n", virtAddr,
143 cb, pSeg->s_base, pSeg->s_size));
144 size_t cbPageOffset = pData->cbPageSize - 1;
145 AssertRelease(!(cb & cbPageOffset));
146 AssertRelease(!((uintptr_t)virtAddr & cbPageOffset));
147
148 if ( virtAddr != pSeg->s_base
149 || cb != pSeg->s_size)
150 {
151 return ENOTSUP;
152 }
153
154 hat_unload(pSeg->s_as->a_hat, virtAddr, cb, HAT_UNLOAD_UNMAP | HAT_UNLOAD_UNLOCK);
155
156 seg_free(pSeg);
157 return 0;
158}
159
160
161static void rtR0SegVBoxSolFree(seg_t *pSeg)
162{
163 PSEGVBOX_DATA pData = pSeg->s_data;
164 kmem_free(pData, sizeof(*pData));
165}
166
167
168static int rtR0SegVBoxSolFault(struct hat *pHat, seg_t *pSeg, caddr_t virtAddr, size_t cb, enum fault_type FaultType,
169 enum seg_rw ReadWrite)
170{
171 /*
172 * We would demand fault if the (u)read() path would SEGOP_FAULT() on buffers mapped in via our
173 * segment driver i.e. prefaults before DMA. Don't fail in such case where we're called directly,
174 * see @bugref{5047}.
175 */
176 return 0;
177}
178
179
180static int rtR0SegVBoxSolFaultA(seg_t *pSeg, caddr_t virtAddr)
181{
182 return 0;
183}
184
185
186static int rtR0SegVBoxSolSetProt(seg_t *pSeg, caddr_t virtAddr, size_t cb, uint_t fPageAccess)
187{
188 return EACCES;
189}
190
191
192static int rtR0SegVBoxSolCheckProt(seg_t *pSeg, caddr_t virtAddr, size_t cb, uint_t fPageAccess)
193{
194 return EINVAL;
195}
196
197
198static int rtR0SegVBoxSolKluster(seg_t *pSeg, caddr_t virtAddr, ssize_t Delta)
199{
200 return -1;
201}
202
203
204static int rtR0SegVBoxSolSync(seg_t *pSeg, caddr_t virtAddr, size_t cb, int Attr, uint_t fFlags)
205{
206 return 0;
207}
208
209
210static size_t rtR0SegVBoxSolInCore(seg_t *pSeg, caddr_t virtAddr, size_t cb, char *pVec)
211{
212 PSEGVBOX_DATA pData = pSeg->s_data;
213 AssertRelease(pData);
214 size_t uPageOffset = pData->cbPageSize - 1;
215 size_t uPageMask = ~uPageOffset;
216 size_t cbLen = (cb + uPageOffset) & uPageMask;
217 for (virtAddr = 0; cbLen != 0; cbLen -= pData->cbPageSize, virtAddr += pData->cbPageSize)
218 *pVec++ = 1;
219 return cbLen;
220}
221
222
223static int rtR0SegVBoxSolLockOp(seg_t *pSeg, caddr_t virtAddr, size_t cb, int Attr, int Op, ulong_t *pLockMap, size_t off)
224{
225 return 0;
226}
227
228
229static int rtR0SegVBoxSolGetProt(seg_t *pSeg, caddr_t virtAddr, size_t cb, uint_t *pafPageAccess)
230{
231 PSEGVBOX_DATA pData = pSeg->s_data;
232 size_t iPage = seg_page(pSeg, virtAddr + cb) - seg_page(pSeg, virtAddr) + 1;
233 if (iPage)
234 {
235 do
236 {
237 iPage--;
238 pafPageAccess[iPage] = pData->fPageAccess;
239 } while (iPage);
240 }
241 return 0;
242}
243
244
245static u_offset_t rtR0SegVBoxSolGetOffset(seg_t *pSeg, caddr_t virtAddr)
246{
247 return ((uintptr_t)virtAddr - (uintptr_t)pSeg->s_base);
248}
249
250
251static int rtR0SegVBoxSolGetType(seg_t *pSeg, caddr_t virtAddr)
252{
253 return MAP_SHARED;
254}
255
256
257static int rtR0SegVBoxSolGetVp(seg_t *pSeg, caddr_t virtAddr, vnode_t **ppVnode)
258{
259 *ppVnode = &s_segVBoxVnode;
260 return 0;
261}
262
263
264static int rtR0SegVBoxSolAdvise(seg_t *pSeg, caddr_t virtAddr, size_t cb, uint_t Behav /* wut? */)
265{
266 return 0;
267}
268
269
270#if defined(VBOX_NEW_CRASH_DUMP_FORMAT)
271static void rtR0SegVBoxSolDump(seg_t *pSeg, dump_addpage_f Func)
272#else
273static void rtR0SegVBoxSolDump(seg_t *pSeg)
274#endif
275{
276 /* Nothing to do. */
277}
278
279
280static int rtR0SegVBoxSolPageLock(seg_t *pSeg, caddr_t virtAddr, size_t cb, page_t ***pppPage, enum lock_type LockType, enum seg_rw ReadWrite)
281{
282 return ENOTSUP;
283}
284
285
286static int rtR0SegVBoxSolSetPageSize(seg_t *pSeg, caddr_t virtAddr, size_t cb, uint_t SizeCode)
287{
288 return ENOTSUP;
289}
290
291
292static int rtR0SegVBoxSolGetMemId(seg_t *pSeg, caddr_t virtAddr, memid_t *pMemId)
293{
294 return ENODEV;
295}
296
297
298#ifdef SEGOP_CAPABLE
299static int rtR0SegVBoxSolCapable(seg_t *pSeg, segcapability_t Capab)
300{
301 return 0;
302}
303#endif
304
305
306static struct seg_ops s_SegVBoxOps =
307{
308 rtR0SegVBoxSolDup,
309 rtR0SegVBoxSolUnmap,
310 rtR0SegVBoxSolFree,
311 rtR0SegVBoxSolFault,
312 rtR0SegVBoxSolFaultA,
313 rtR0SegVBoxSolSetProt,
314 rtR0SegVBoxSolCheckProt,
315 rtR0SegVBoxSolKluster,
316 NULL, /* swapout */
317 rtR0SegVBoxSolSync,
318 rtR0SegVBoxSolInCore,
319 rtR0SegVBoxSolLockOp,
320 rtR0SegVBoxSolGetProt,
321 rtR0SegVBoxSolGetOffset,
322 rtR0SegVBoxSolGetType,
323 rtR0SegVBoxSolGetVp,
324 rtR0SegVBoxSolAdvise,
325 rtR0SegVBoxSolDump,
326 rtR0SegVBoxSolPageLock,
327 rtR0SegVBoxSolSetPageSize,
328 rtR0SegVBoxSolGetMemId,
329 NULL, /* getpolicy() */
330#ifdef SEGOP_CAPABLE
331 rtR0SegVBoxSolCapable
332#endif
333};
334
335#endif /* !IPRT_INCLUDED_SRC_r0drv_solaris_memobj_r0drv_solaris_h */
336
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