VirtualBox

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

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

Solaris-specific changes needed for building VBox on Solaris 11.4.
ticketref:9956

/Config.kmk,tools/Makefile.kmk: The Solaris package FMRI changed in
Solaris 11.4 so further care is needed when parsing the 'pkg contents -o
pkg.fmri' output. Some further simplification done as well as only the
Solaris 11 update and build number are needed for feature checking
elsewhere.

Additions/solaris/DRM: In Solaris 11 FCS <sys/queue.h> was taken from
FreeBSD and added to the OS. VirtualBox copied this file to
Additions/solaris/DRM/include and it is included by
Additions/solaris/DRM/include/drmP.h. Solaris 11.4 modified <sys/modctl.h>
to include <sys/queue.h> and drmP.h includes <sys/modctl.h> so thus
drmP.h shouldn't include queue.h on Solaris 11.4 FCS and later.

Additions/solaris/SharedFolders,Runtime/r0drv/solaris: Solaris 11.4
removed the 'alignment' argument from the VM map_addr() and
choose_addr() routines so we now leverage RTR0DbgKrnlInfoQuerySymbol()
at module initialization to determine which version of these functions
needs to be invoked.

Runtime/r0drv/solaris: In Solaris 11.4 the VM seg_ops getpolicy()
routine changed its return value and added an extra argument but since
we don't need to do anything for this and Solaris 10 and 11 both check
for a non-NULL s_ops->getpolicy() entry or else for s_ops->capable()
before calling getpolicy() we just set the s_SegVBoxOps getpolicy()
entry to NULL. Solaris 11.4 also added an extra argument to the VM
seg_ops dump() routine but there aren't any checks made before calling
it. Since we don't do anything with dump() we just use #ifdefs to get
the correct prototype at build-time.

Additions/x11/vboxvideo: The Xorg vboxvideo_drv.so shared object on
Solaris 11.4 has an undefined weak symbol reference to assert_c99
which needs to be added to the undefined_xorg file.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.8 KB
Line 
1/* $Id: memobj-r0drv-solaris.h 88215 2021-03-19 18:42:55Z vboxsync $ */
2/** @file
3 * IPRT - Ring-0 Memory Objects - Segment driver, Solaris.
4 */
5
6/*
7 * Copyright (C) 2012-2020 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
260#if defined(VBOX_NEW_CRASH_DUMP_FORMAT)
261static void rtR0SegVBoxSolDump(seg_t *pSeg, dump_addpage_f Func)
262#else
263static void rtR0SegVBoxSolDump(seg_t *pSeg)
264#endif
265{
266 /* Nothing to do. */
267}
268
269
270static int rtR0SegVBoxSolPageLock(seg_t *pSeg, caddr_t virtAddr, size_t cb, page_t ***pppPage, enum lock_type LockType, enum seg_rw ReadWrite)
271{
272 return ENOTSUP;
273}
274
275
276static int rtR0SegVBoxSolSetPageSize(seg_t *pSeg, caddr_t virtAddr, size_t cb, uint_t SizeCode)
277{
278 return ENOTSUP;
279}
280
281
282static int rtR0SegVBoxSolGetMemId(seg_t *pSeg, caddr_t virtAddr, memid_t *pMemId)
283{
284 return ENODEV;
285}
286
287
288static int rtR0SegVBoxSolCapable(seg_t *pSeg, segcapability_t Capab)
289{
290 return 0;
291}
292
293
294static struct seg_ops s_SegVBoxOps =
295{
296 rtR0SegVBoxSolDup,
297 rtR0SegVBoxSolUnmap,
298 rtR0SegVBoxSolFree,
299 rtR0SegVBoxSolFault,
300 rtR0SegVBoxSolFaultA,
301 rtR0SegVBoxSolSetProt,
302 rtR0SegVBoxSolCheckProt,
303 rtR0SegVBoxSolKluster,
304 NULL, /* swapout */
305 rtR0SegVBoxSolSync,
306 rtR0SegVBoxSolInCore,
307 rtR0SegVBoxSolLockOp,
308 rtR0SegVBoxSolGetProt,
309 rtR0SegVBoxSolGetOffset,
310 rtR0SegVBoxSolGetType,
311 rtR0SegVBoxSolGetVp,
312 rtR0SegVBoxSolAdvise,
313 rtR0SegVBoxSolDump,
314 rtR0SegVBoxSolPageLock,
315 rtR0SegVBoxSolSetPageSize,
316 rtR0SegVBoxSolGetMemId,
317 NULL, /* getpolicy() */
318 rtR0SegVBoxSolCapable
319};
320
321#endif /* !IPRT_INCLUDED_SRC_r0drv_solaris_memobj_r0drv_solaris_h */
322
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