VirtualBox

source: vbox/trunk/src/VBox/Runtime/r0drv/solaris/initterm-r0drv-solaris.c@ 41628

Last change on this file since 41628 was 40972, checked in by vboxsync, 13 years ago

Runtime/r0drv/solaris: use page.h's PG_KFLT define.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.0 KB
Line 
1/* $Id: initterm-r0drv-solaris.c 40972 2012-04-18 13:30:14Z vboxsync $ */
2/** @file
3 * IPRT - Initialization & Termination, Ring-0 Driver, Solaris.
4 */
5
6/*
7 * Copyright (C) 2006-2010 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
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#include "the-solaris-kernel.h"
32#include "internal/iprt.h"
33
34#include <iprt/assert.h>
35#include <iprt/err.h>
36#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
37# include <iprt/asm-amd64-x86.h>
38#endif
39#include "internal/initterm.h"
40
41
42/*******************************************************************************
43* Global Variables *
44*******************************************************************************/
45/** Kernel debug info handle. */
46RTDBGKRNLINFO g_hKrnlDbgInfo;
47/** Indicates that the spl routines (and therefore a bunch of other ones too)
48 * will set EFLAGS::IF and break code that disables interrupts. */
49bool g_frtSolSplSetsEIF = false;
50/** timeout_generic address. */
51PFNSOL_timeout_generic g_pfnrtR0Sol_timeout_generic = NULL;
52/** untimeout_generic address. */
53PFNSOL_untimeout_generic g_pfnrtR0Sol_untimeout_generic = NULL;
54/** cyclic_reprogram address. */
55PFNSOL_cyclic_reprogram g_pfnrtR0Sol_cyclic_reprogram = NULL;
56/** Whether to use the kernel page freelist. */
57bool g_frtSolUseKflt = false;
58/** Whether we've completed R0 initialization. */
59bool g_frtSolInitDone = false;
60/** Whether to use old-style xc_call interface. */
61bool g_frtSolOldIPI = false;
62/** Whether to use old-style xc_call interface using one ulong_t as the CPU set
63 * representation. */
64bool g_frtSolOldIPIUlong = false;
65/** The xc_call callout table structure. */
66RTR0FNSOLXCCALL g_rtSolXcCall;
67/** Thread preemption offset. */
68size_t g_offrtSolThreadPreempt;
69/** Host scheduler preemption offset. */
70size_t g_offrtSolCpuPreempt;
71/** Host scheduler force preemption offset. */
72size_t g_offrtSolCpuForceKernelPreempt;
73/* Resolve using dl_lookup (remove if no longer relevant for supported S10 versions) */
74extern void contig_free(void *addr, size_t size);
75#pragma weak contig_free
76/** contig_free address. */
77PFNSOL_contig_free g_pfnrtR0Sol_contig_free = contig_free;
78
79DECLHIDDEN(int) rtR0InitNative(void)
80{
81 /*
82 * IPRT has not yet been initialized at this point, so use Solaris' native cmn_err() for logging.
83 */
84 int rc = RTR0DbgKrnlInfoOpen(&g_hKrnlDbgInfo, 0 /* fFlags */);
85 if (RT_SUCCESS(rc))
86 {
87#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
88 /*
89 * Detect whether spl*() is preserving the interrupt flag or not.
90 * This is a problem on S10.
91 */
92 RTCCUINTREG uOldFlags = ASMIntDisableFlags();
93 int iOld = splr(DISP_LEVEL);
94 if (ASMIntAreEnabled())
95 g_frtSolSplSetsEIF = true;
96 splx(iOld);
97 if (ASMIntAreEnabled())
98 g_frtSolSplSetsEIF = true;
99 ASMSetFlags(uOldFlags);
100#else
101 /* PORTME: See if the amd64/x86 problem applies to this architecture. */
102#endif
103
104 /*
105 * Mandatory: Preemption offsets.
106 */
107 rc = RTR0DbgKrnlInfoQueryMember(g_hKrnlDbgInfo, "cpu_t", "cpu_runrun", &g_offrtSolCpuPreempt);
108 if (RT_FAILURE(rc))
109 {
110 cmn_err(CE_NOTE, "Failed to find cpu_t::cpu_runrun!\n");
111 goto errorbail;
112 }
113
114 rc = RTR0DbgKrnlInfoQueryMember(g_hKrnlDbgInfo, "cpu_t", "cpu_kprunrun", &g_offrtSolCpuForceKernelPreempt);
115 if (RT_FAILURE(rc))
116 {
117 cmn_err(CE_NOTE, "Failed to find cpu_t::cpu_kprunrun!\n");
118 goto errorbail;
119 }
120
121 rc = RTR0DbgKrnlInfoQueryMember(g_hKrnlDbgInfo, "kthread_t", "t_preempt", &g_offrtSolThreadPreempt);
122 if (RT_FAILURE(rc))
123 {
124 cmn_err(CE_NOTE, "Failed to find kthread_t::t_preempt!\n");
125 goto errorbail;
126 }
127 cmn_err(CE_CONT, "!cpu_t::cpu_runrun @ 0x%lx\n", g_offrtSolCpuPreempt);
128 cmn_err(CE_CONT, "!cpu_t::cpu_kprunrun @ 0x%lx\n", g_offrtSolCpuForceKernelPreempt);
129 cmn_err(CE_CONT, "!kthread_t::t_preempt @ 0x%lx\n", g_offrtSolThreadPreempt);
130
131 /*
132 * Mandatory: CPU cross call infrastructure. Refer the-solaris-kernel.h for details.
133 */
134 rc = RTR0DbgKrnlInfoQuerySymbol(g_hKrnlDbgInfo, NULL /* pszModule */, "xc_init_cpu", NULL /* ppvSymbol */);
135 if (RT_SUCCESS(rc))
136 {
137 if (ncpus > IPRT_SOL_NCPUS)
138 {
139 cmn_err(CE_NOTE, "rtR0InitNative: CPU count mismatch! ncpus=%d IPRT_SOL_NCPUS=%d\n", ncpus, IPRT_SOL_NCPUS);
140 rc = VERR_NOT_SUPPORTED;
141 goto errorbail;
142 }
143 g_rtSolXcCall.u.pfnSol_xc_call = (void *)xc_call;
144 }
145 else
146 {
147 g_frtSolOldIPI = true;
148 g_rtSolXcCall.u.pfnSol_xc_call_old = (void *)xc_call;
149 if (max_cpuid + 1 == sizeof(ulong_t) * 8)
150 {
151 g_frtSolOldIPIUlong = true;
152 g_rtSolXcCall.u.pfnSol_xc_call_old_ulong = (void *)xc_call;
153 }
154 else if (max_cpuid + 1 != IPRT_SOL_NCPUS)
155 {
156 cmn_err(CE_NOTE, "rtR0InitNative: cpuset_t size mismatch! max_cpuid=%d IPRT_SOL_NCPUS=%d\n", max_cpuid, IPRT_SOL_NCPUS);
157 rc = VERR_NOT_SUPPORTED;
158 goto errorbail;
159 }
160 }
161
162 /*
163 * Optional: Timeout hooks.
164 */
165 RTR0DbgKrnlInfoQuerySymbol(g_hKrnlDbgInfo, NULL /* pszModule */, "timeout_generic", (void **)&g_pfnrtR0Sol_timeout_generic);
166 RTR0DbgKrnlInfoQuerySymbol(g_hKrnlDbgInfo, NULL /* pszModule */, "untimeout_generic", (void **)&g_pfnrtR0Sol_untimeout_generic);
167 if ((g_pfnrtR0Sol_timeout_generic == NULL) != (g_pfnrtR0Sol_untimeout_generic == NULL))
168 {
169 static const char *s_apszFn[2] = { "timeout_generic", "untimeout_generic" };
170 bool iMissingFn = g_pfnrtR0Sol_timeout_generic == NULL;
171 cmn_err(CE_NOTE, "rtR0InitNative: Weird! Found %s but not %s!\n", s_apszFn[!iMissingFn], s_apszFn[iMissingFn]);
172 g_pfnrtR0Sol_timeout_generic = NULL;
173 g_pfnrtR0Sol_untimeout_generic = NULL;
174 }
175 RTR0DbgKrnlInfoQuerySymbol(g_hKrnlDbgInfo, NULL /* pszModule */, "cyclic_reprogram", (void **)&g_pfnrtR0Sol_cyclic_reprogram);
176
177 /*
178 * Optional: Kernel page freelist (kflt)
179 *
180 * Only applicable to 64-bit Solaris kernels. Use kflt flags to get pages from kernel page freelists
181 * while allocating physical pages, once the userpages are exhausted. snv_161+, see @bugref{5632}.
182 */
183 rc = RTR0DbgKrnlInfoQuerySymbol(g_hKrnlDbgInfo, NULL /* pszModule */, "kflt_init", NULL /* ppvSymbol */);
184 if (RT_SUCCESS(rc))
185 {
186 int *pKfltDisable = NULL;
187 rc = RTR0DbgKrnlInfoQuerySymbol(g_hKrnlDbgInfo, NULL /* pszModule */, "kflt_disable", (void **)&pKfltDisable);
188 if (RT_SUCCESS(rc) && pKfltDisable && *pKfltDisable == 0)
189 g_frtSolUseKflt = true;
190 }
191
192 /*
193 * Weak binding failures: contig_free
194 */
195 if (g_pfnrtR0Sol_contig_free == NULL)
196 {
197 rc = RTR0DbgKrnlInfoQuerySymbol(g_hKrnlDbgInfo, NULL /* pszModule */, "contig_free", (void **)&g_pfnrtR0Sol_contig_free);
198 if (RT_FAILURE(rc))
199 {
200 cmn_err(CE_NOTE, "rtR0InitNative: failed to find contig_free!\n");
201 goto errorbail;
202 }
203 }
204
205 g_frtSolInitDone = true;
206 return VINF_SUCCESS;
207 }
208 else
209 {
210 cmn_err(CE_NOTE, "RTR0DbgKrnlInfoOpen failed. rc=%d\n", rc);
211 return rc;
212 }
213
214errorbail:
215 RTR0DbgKrnlInfoRelease(g_hKrnlDbgInfo);
216 return rc;
217}
218
219
220DECLHIDDEN(void) rtR0TermNative(void)
221{
222 RTR0DbgKrnlInfoRelease(g_hKrnlDbgInfo);
223 g_frtSolInitDone = false;
224}
225
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