~ubuntu-branches/ubuntu/trusty/virtualbox-ose/trusty

« back to all changes in this revision

Viewing changes to src/VBox/Runtime/r0drv/solaris/memobj-r0drv-solaris.c

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2009-12-18 16:44:29 UTC
  • mfrom: (0.3.3 upstream) (0.4.6 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091218164429-jd34ccexpv5na11a
Tags: 3.1.2-dfsg-1ubuntu1
* Merge from Debian unstable (LP: #498219), remaining changes:
  - Disable update action
    - debian/patches/u01-disable-update-action.dpatch
  - VirtualBox should go in Accessories, not in System tools (LP: #288590)
    - debian/virtualbox-ose-qt.files/virtualbox-ose.desktop
  - Add Apport hook
    - debian/virtualbox-ose.files/source_virtualbox-ose.py
    - debian/virtualbox-ose.install
  - Add Launchpad integration
    - debian/control
    - debian/lpi-bug.xpm
    - debian/patches/u02-lp-integration.dpatch
* Fixes the following bugs:
  - Kernel module fails to build with Linux >= 2.6.32 (LP: #474625)
  - X.Org drivers need to be rebuilt against X-Server 1.7 (LP: #495935)
  - The *-source packages try to build the kernel modules even though the
    kernel headers aren't available (LP: #473334)
* Replace *-source packages with transitional packages for *-dkms.
* Adapt u01-disable-update-action.dpatch and u02-lp-integration.dpatch for
  new upstream version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: memobj-r0drv-solaris.c $ */
2
 
/** @file
3
 
 * IPRT - Ring-0 Memory Objects, Solaris.
4
 
 */
5
 
 
6
 
/*
7
 
 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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
 
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27
 
 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28
 
 * additional information or have any questions.
29
 
 */
30
 
 
31
 
 
32
 
/*******************************************************************************
33
 
*   Header Files                                                               *
34
 
*******************************************************************************/
35
 
#include "the-solaris-kernel.h"
36
 
 
37
 
#include <iprt/memobj.h>
38
 
#include <iprt/mem.h>
39
 
#include <iprt/err.h>
40
 
#include <iprt/assert.h>
41
 
#include <iprt/log.h>
42
 
#include <iprt/param.h>
43
 
#include <iprt/process.h>
44
 
#include "internal/memobj.h"
45
 
 
46
 
 
47
 
/*******************************************************************************
48
 
*   Structures and Typedefs                                                    *
49
 
*******************************************************************************/
50
 
/**
51
 
 * The Solaris version of the memory object structure.
52
 
 */
53
 
typedef struct RTR0MEMOBJSOLARIS
54
 
{
55
 
    /** The core structure. */
56
 
    RTR0MEMOBJINTERNAL  Core;
57
 
    /** Pointer to kernel memory cookie. */
58
 
    ddi_umem_cookie_t   Cookie;
59
 
    /** Shadow locked pages. */
60
 
    page_t              **ppShadowPages;
61
 
} RTR0MEMOBJSOLARIS, *PRTR0MEMOBJSOLARIS;
62
 
 
63
 
/**
64
 
 * Used for supplying the solaris kernel info. about memory limits
65
 
 * during contiguous allocations (i_ddi_mem_alloc)
66
 
 */
67
 
struct ddi_dma_attr g_SolarisX86PhysMemLimits =
68
 
{
69
 
    DMA_ATTR_V0,            /* Version Number */
70
 
    (uint64_t)0,            /* lower limit */
71
 
    (uint64_t)0xffffffff,   /* high limit (32-bit PA, 4G) */
72
 
    (uint64_t)0xffffffff,   /* counter limit */
73
 
    (uint64_t)PAGE_SIZE,    /* alignment */
74
 
    (uint64_t)PAGE_SIZE,    /* burst size */
75
 
    (uint64_t)PAGE_SIZE,    /* effective DMA size */
76
 
    (uint64_t)0xffffffff,   /* max DMA xfer size */
77
 
    (uint64_t)0xffffffff,   /* segment boundary */
78
 
    1,                      /* scatter-gather list length (1 for contiguous) */
79
 
    1,                      /* device granularity */
80
 
    0                       /* bus-specific flags */
81
 
};
82
 
 
83
 
 
84
 
static uint64_t rtR0MemObjSolarisVirtToPhys(struct hat* hatSpace, caddr_t virtAddr)
85
 
{
86
 
    /* We could use paddr_t (more solaris-like) rather than uint64_t but paddr_t isn't defined for 64-bit */
87
 
    pfn_t pfn = hat_getpfnum(hatSpace, virtAddr);
88
 
    if (pfn == PFN_INVALID)
89
 
    {
90
 
        AssertMsgFailed(("rtR0MemObjSolarisVirtToPhys: hat_getpfnum for %p failed.\n", virtAddr));
91
 
        return PFN_INVALID;
92
 
    }
93
 
 
94
 
    uint64_t physAddr = ((uint64_t)pfn << MMU_PAGESHIFT) | ((uintptr_t)virtAddr & MMU_PAGEOFFSET);
95
 
    return physAddr;
96
 
}
97
 
 
98
 
 
99
 
int rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
100
 
{
101
 
    PRTR0MEMOBJSOLARIS pMemSolaris = (PRTR0MEMOBJSOLARIS)pMem;
102
 
 
103
 
    switch (pMemSolaris->Core.enmType)
104
 
    {
105
 
        case RTR0MEMOBJTYPE_CONT:
106
 
            i_ddi_mem_free(pMemSolaris->Core.pv, NULL);
107
 
            break;
108
 
 
109
 
        case RTR0MEMOBJTYPE_PAGE:
110
 
            ddi_umem_free(pMemSolaris->Cookie);
111
 
            break;
112
 
 
113
 
        case RTR0MEMOBJTYPE_LOCK:
114
 
        {
115
 
            struct as *addrSpace;
116
 
            if ((uintptr_t)pMemSolaris->Core.pv < kernelbase)
117
 
            {
118
 
                addrSpace = ((proc_t *)pMemSolaris->Core.u.Lock.R0Process)->p_as;
119
 
                as_pageunlock(addrSpace, pMemSolaris->ppShadowPages, pMemSolaris->Core.pv, pMemSolaris->Core.cb, S_WRITE);
120
 
            }
121
 
            /* Nothing to unlock for kernel addresses. */
122
 
            break;
123
 
        }
124
 
 
125
 
        case RTR0MEMOBJTYPE_MAPPING:
126
 
        {
127
 
            struct hat *hatSpace;
128
 
            struct as *addrSpace;
129
 
            if (pMemSolaris->Core.u.Mapping.R0Process == NIL_RTR0PROCESS)
130
 
            {
131
 
                /* Kernel process*/
132
 
                hatSpace = kas.a_hat;
133
 
                addrSpace = &kas;
134
 
            }
135
 
            else
136
 
            {
137
 
                /* User process */
138
 
                proc_t *userProc = (proc_t *)pMemSolaris->Core.u.Mapping.R0Process;
139
 
                hatSpace = userProc->p_as->a_hat;
140
 
                addrSpace = userProc->p_as;
141
 
            }
142
 
 
143
 
            rw_enter(&addrSpace->a_lock, RW_READER);
144
 
            hat_unload(hatSpace, pMemSolaris->Core.pv, pMemSolaris->Core.cb, HAT_UNLOAD_UNLOCK);
145
 
            rw_exit(&addrSpace->a_lock);
146
 
            as_unmap(addrSpace, pMemSolaris->Core.pv, pMemSolaris->Core.cb);
147
 
            break;
148
 
        }
149
 
 
150
 
        /* unused */
151
 
        case RTR0MEMOBJTYPE_LOW:
152
 
        case RTR0MEMOBJTYPE_PHYS:
153
 
        case RTR0MEMOBJTYPE_RES_VIRT:
154
 
        default:
155
 
            AssertMsgFailed(("enmType=%d\n", pMemSolaris->Core.enmType));
156
 
            return VERR_INTERNAL_ERROR;
157
 
    }
158
 
 
159
 
    return VINF_SUCCESS;
160
 
}
161
 
 
162
 
 
163
 
int rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
164
 
{
165
 
    /* Create the object */
166
 
    PRTR0MEMOBJSOLARIS pMemSolaris = (PRTR0MEMOBJSOLARIS)rtR0MemObjNew(sizeof(*pMemSolaris), RTR0MEMOBJTYPE_PAGE, NULL, cb);
167
 
    if (!pMemSolaris)
168
 
        return VERR_NO_MEMORY;
169
 
 
170
 
    void *virtAddr = ddi_umem_alloc(cb, DDI_UMEM_SLEEP, &pMemSolaris->Cookie);
171
 
    if (!virtAddr)
172
 
    {
173
 
        rtR0MemObjDelete(&pMemSolaris->Core);
174
 
        return VERR_NO_PAGE_MEMORY;
175
 
    }
176
 
 
177
 
    pMemSolaris->Core.pv = virtAddr;
178
 
    pMemSolaris->ppShadowPages = NULL;
179
 
    *ppMem = &pMemSolaris->Core;
180
 
    return VINF_SUCCESS;
181
 
}
182
 
 
183
 
 
184
 
int rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
185
 
{
186
 
    /* Try page alloc first */
187
 
    int rc = rtR0MemObjNativeAllocPage(ppMem, cb, fExecutable);
188
 
    if (RT_SUCCESS(rc))
189
 
    {
190
 
        size_t iPage = cb >> PAGE_SHIFT;
191
 
        while (iPage-- > 0)
192
 
            if (rtR0MemObjNativeGetPagePhysAddr(*ppMem, iPage) > (_4G - PAGE_SIZE))
193
 
            {
194
 
                /* Failed! Fall back to physical contiguous alloc */
195
 
                RTR0MemObjFree(*ppMem, false);
196
 
                rc = rtR0MemObjNativeAllocCont(ppMem, cb, fExecutable);
197
 
                break;
198
 
            }
199
 
    }
200
 
    return rc;
201
 
}
202
 
 
203
 
 
204
 
int rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
205
 
{
206
 
    NOREF(fExecutable);
207
 
 
208
 
    /* Create the object */
209
 
    PRTR0MEMOBJSOLARIS pMemSolaris = (PRTR0MEMOBJSOLARIS)rtR0MemObjNew(sizeof(*pMemSolaris), RTR0MEMOBJTYPE_CONT, NULL, cb);
210
 
    if (!pMemSolaris)
211
 
        return VERR_NO_MEMORY;
212
 
 
213
 
    /* Allocate physically contiguous page-aligned memory. */
214
 
    caddr_t virtAddr;
215
 
    int rc = i_ddi_mem_alloc(NULL, &g_SolarisX86PhysMemLimits, cb, 1, 0, NULL, &virtAddr, NULL, NULL);
216
 
    if (rc != DDI_SUCCESS)
217
 
    {
218
 
        rtR0MemObjDelete(&pMemSolaris->Core);
219
 
        return VERR_NO_CONT_MEMORY;
220
 
    }
221
 
 
222
 
    pMemSolaris->Core.pv = virtAddr;
223
 
    pMemSolaris->Core.u.Cont.Phys = rtR0MemObjSolarisVirtToPhys(kas.a_hat, virtAddr);
224
 
    pMemSolaris->ppShadowPages = NULL;
225
 
    *ppMem = &pMemSolaris->Core;
226
 
    return VINF_SUCCESS;
227
 
}
228
 
 
229
 
 
230
 
int rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
231
 
{
232
 
    /** @todo rtR0MemObjNativeAllocPhysNC / solaris */
233
 
    return VERR_NOT_SUPPORTED; /* see the RTR0MemObjAllocPhysNC specs */
234
 
}
235
 
 
236
 
 
237
 
int rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
238
 
{
239
 
    AssertMsgReturn(PhysHighest >= 16 *_1M, ("PhysHigest=%RHp\n", PhysHighest), VERR_NOT_IMPLEMENTED);
240
 
 
241
 
    return rtR0MemObjNativeAllocCont(ppMem, cb, false);
242
 
}
243
 
 
244
 
 
245
 
int rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb)
246
 
{
247
 
    /* Create the object */
248
 
    PRTR0MEMOBJSOLARIS pMemSolaris = (PRTR0MEMOBJSOLARIS)rtR0MemObjNew(sizeof(*pMemSolaris), RTR0MEMOBJTYPE_PHYS, NULL, cb);
249
 
    if (!pMemSolaris)
250
 
        return VERR_NO_MEMORY;
251
 
 
252
 
    /* There is no allocation here, it needs to be mapped somewhere first */
253
 
    pMemSolaris->Core.u.Phys.fAllocated = false;
254
 
    pMemSolaris->Core.u.Phys.PhysBase = Phys;
255
 
    *ppMem = &pMemSolaris->Core;
256
 
    return VINF_SUCCESS;
257
 
}
258
 
 
259
 
 
260
 
int rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, RTR0PROCESS R0Process)
261
 
{
262
 
    AssertReturn(R0Process == RTR0ProcHandleSelf(), VERR_INVALID_PARAMETER);
263
 
 
264
 
    /* Create the locking object */
265
 
    PRTR0MEMOBJSOLARIS pMemSolaris = (PRTR0MEMOBJSOLARIS)rtR0MemObjNew(sizeof(*pMemSolaris), RTR0MEMOBJTYPE_LOCK, (void *)R3Ptr, cb);
266
 
    if (!pMemSolaris)
267
 
        return VERR_NO_MEMORY;
268
 
 
269
 
    proc_t *userproc = (proc_t *)R0Process;
270
 
    struct as *useras = userproc->p_as;
271
 
    page_t **ppl;
272
 
 
273
 
    /* Lock down user pages */
274
 
    int rc;
275
 
    ppl = NULL;
276
 
    if ((uintptr_t)R3Ptr < kernelbase)
277
 
        rc = as_pagelock(useras, &ppl, (caddr_t)R3Ptr, cb, S_WRITE);
278
 
    else
279
 
        rc = 0;
280
 
    if (rc == 0)
281
 
    {
282
 
        pMemSolaris->Core.u.Lock.R0Process = (RTR0PROCESS)userproc;
283
 
        pMemSolaris->ppShadowPages = ppl;
284
 
        *ppMem = &pMemSolaris->Core;
285
 
        return VINF_SUCCESS;
286
 
    }
287
 
 
288
 
    cmn_err(CE_NOTE,"rtR0MemObjNativeLockUser: as_pagelock failed rc=%d\n", rc);
289
 
    rtR0MemObjDelete(&pMemSolaris->Core);
290
 
    return VERR_LOCK_FAILED;
291
 
}
292
 
 
293
 
 
294
 
int rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb)
295
 
{
296
 
    /* Create the locking object */
297
 
    PRTR0MEMOBJSOLARIS pMemSolaris = (PRTR0MEMOBJSOLARIS)rtR0MemObjNew(sizeof(*pMemSolaris), RTR0MEMOBJTYPE_LOCK, pv, cb);
298
 
    if (!pMemSolaris)
299
 
        return VERR_NO_MEMORY;
300
 
 
301
 
    /* Nothing to do here for kernel addresses. */
302
 
 
303
 
    pMemSolaris->Core.u.Lock.R0Process = RTR0ProcHandleSelf();
304
 
    pMemSolaris->ppShadowPages = NULL;
305
 
    *ppMem = &pMemSolaris->Core;
306
 
    return VINF_SUCCESS;
307
 
}
308
 
 
309
 
 
310
 
int rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment)
311
 
{
312
 
    return VERR_NOT_IMPLEMENTED;
313
 
}
314
 
 
315
 
 
316
 
int rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, RTR0PROCESS R0Process)
317
 
{
318
 
    return VERR_NOT_IMPLEMENTED;
319
 
}
320
 
 
321
 
int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
322
 
                              unsigned fProt, size_t offSub, size_t cbSub)
323
 
{
324
 
    /* @todo rtR0MemObjNativeMapKernel / Solaris - Should be fairly simple alloc kernel memory and memload it. */
325
 
    return VERR_NOT_IMPLEMENTED;
326
 
}
327
 
 
328
 
 
329
 
int rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, PRTR0MEMOBJINTERNAL pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process)
330
 
{
331
 
    AssertMsgReturn(R3PtrFixed == (RTR3PTR)-1, ("%p\n", R3PtrFixed), VERR_NOT_SUPPORTED);
332
 
    AssertMsgReturn(R0Process == RTR0ProcHandleSelf(), ("%p != %p\n", R0Process, RTR0ProcHandleSelf()), VERR_NOT_SUPPORTED);
333
 
 
334
 
    PRTR0MEMOBJSOLARIS pMemToMapSolaris = (PRTR0MEMOBJSOLARIS)pMemToMap;
335
 
    size_t size = pMemToMapSolaris->Core.cb;
336
 
    proc_t *userproc = (proc_t *)R0Process;
337
 
    struct as *useras = userproc->p_as;
338
 
    void *pv = pMemToMapSolaris->Core.pv;
339
 
    pgcnt_t cPages = btop(size);
340
 
    pgcnt_t iPage;
341
 
    caddr_t addr;
342
 
    int rc;
343
 
 
344
 
    /* Request the system for a mapping address. */
345
 
    as_rangelock(useras);
346
 
    map_addr(&addr, size, 0 /* offset */, 1 /* vac-align */, MAP_SHARED | MAP_ANONYMOUS);
347
 
    if (!addr)
348
 
    {
349
 
        as_rangeunlock(useras);
350
 
        cmn_err(CE_NOTE, "rtR0MemObjNativeMapUser: map_addr failed\n");
351
 
        return VERR_MAP_FAILED;
352
 
    }
353
 
 
354
 
    /* Check address against alignment, fail if it doesn't match */
355
 
    if ((uintptr_t)addr & (uAlignment - 1))
356
 
    {
357
 
        as_rangeunlock(useras);
358
 
        cmn_err(CE_NOTE, "rtR0MemObjNativeMapUser: map_addr alignment(%ld) failed.\n", uAlignment);
359
 
        return VERR_MAP_FAILED;
360
 
    }
361
 
 
362
 
    /* Our protection masks are identical to <sys/mman.h> but we
363
 
     * need to add PROT_USER for the pages to be accessible by user
364
 
     */
365
 
    struct segvn_crargs crArgs = SEGVN_ZFOD_ARGS(fProt | PROT_USER, PROT_ALL);
366
 
    rc = as_map(useras, addr, size, segvn_create, &crArgs);
367
 
    as_rangeunlock(useras);
368
 
    if (rc != 0)
369
 
    {
370
 
        cmn_err(CE_NOTE, "rtR0MemObjNativeMapUser: as_map failure.\n");
371
 
        return VERR_MAP_FAILED;
372
 
    }
373
 
 
374
 
    /* Create the mapping object */
375
 
    PRTR0MEMOBJSOLARIS pMemSolaris = (PRTR0MEMOBJSOLARIS)rtR0MemObjNew(sizeof(*pMemSolaris), RTR0MEMOBJTYPE_MAPPING, pv, size);
376
 
    if (!pMemSolaris)
377
 
    {
378
 
        /* Undo mapping on failure. */
379
 
        as_unmap(useras, addr, size);
380
 
        return VERR_NO_MEMORY;
381
 
    }
382
 
 
383
 
    /* Map each page into user space */
384
 
    rw_enter(&useras->a_lock, RW_READER);
385
 
    caddr_t kernAddr = pv;
386
 
    caddr_t pageAddr = addr;
387
 
    for (iPage = 0; iPage < cPages; iPage++)
388
 
    {
389
 
        page_t *pp = page_numtopp_nolock(hat_getpfnum(kas.a_hat, kernAddr));
390
 
        hat_memload(useras->a_hat, pageAddr, pp, (fProt | PROT_USER), HAT_LOAD_LOCK);
391
 
        pageAddr += ptob(1);
392
 
        kernAddr += ptob(1);
393
 
    }
394
 
    rw_exit(&useras->a_lock);
395
 
 
396
 
    pMemSolaris->Core.u.Mapping.R0Process = (RTR0PROCESS)userproc;
397
 
    pMemSolaris->Core.pv = addr;
398
 
    *ppMem = &pMemSolaris->Core;
399
 
    return VINF_SUCCESS;
400
 
}
401
 
 
402
 
 
403
 
int rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt)
404
 
{
405
 
    NOREF(pMem);
406
 
    NOREF(offSub);
407
 
    NOREF(cbSub);
408
 
    NOREF(fProt);
409
 
    return VERR_NOT_SUPPORTED;
410
 
}
411
 
 
412
 
 
413
 
RTHCPHYS rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
414
 
{
415
 
    PRTR0MEMOBJSOLARIS pMemSolaris = (PRTR0MEMOBJSOLARIS)pMem;
416
 
 
417
 
    switch (pMemSolaris->Core.enmType)
418
 
    {
419
 
        case RTR0MEMOBJTYPE_PAGE:
420
 
        case RTR0MEMOBJTYPE_LOW:
421
 
        case RTR0MEMOBJTYPE_MAPPING:
422
 
        {
423
 
            uint8_t *pb = (uint8_t *)pMemSolaris->Core.pv + ((size_t)iPage << PAGE_SHIFT);
424
 
            return rtR0MemObjSolarisVirtToPhys(kas.a_hat, pb);
425
 
        }
426
 
 
427
 
        case RTR0MEMOBJTYPE_LOCK:
428
 
        {
429
 
            struct hat *hatSpace;
430
 
            if (pMemSolaris->Core.u.Lock.R0Process != NIL_RTR0PROCESS)
431
 
            {
432
 
                /* User */
433
 
                proc_t *userProc = (proc_t *)pMemSolaris->Core.u.Lock.R0Process;
434
 
                hatSpace = userProc->p_as->a_hat;
435
 
            }
436
 
            else    /* Kernel */
437
 
                hatSpace = kas.a_hat;
438
 
 
439
 
            uint8_t *pb = (uint8_t *)pMemSolaris->Core.pv + ((size_t)iPage << PAGE_SHIFT);
440
 
            return rtR0MemObjSolarisVirtToPhys(hatSpace, pb);
441
 
        }
442
 
 
443
 
        case RTR0MEMOBJTYPE_CONT:
444
 
            return pMemSolaris->Core.u.Cont.Phys + (iPage << PAGE_SHIFT);
445
 
 
446
 
        case RTR0MEMOBJTYPE_PHYS:
447
 
            return pMemSolaris->Core.u.Phys.PhysBase + (iPage << PAGE_SHIFT);
448
 
 
449
 
        case RTR0MEMOBJTYPE_PHYS_NC:
450
 
            AssertFailed(/* not implemented */);
451
 
        case RTR0MEMOBJTYPE_RES_VIRT:
452
 
        default:
453
 
            return NIL_RTHCPHYS;
454
 
    }
455
 
}
456