VirtualBox

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

Last change on this file since 78381 was 76585, checked in by vboxsync, 6 years ago

*: scm --fix-header-guard-endif

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