VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/Support/linux/SUPLib-linux.cpp@ 1850

Last change on this file since 1850 was 1, checked in by vboxsync, 55 years ago

import

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.1 KB
Line 
1/** @file
2 *
3 * VBox host drivers - Ring-0 support drivers - Linux host:
4 * Linux implementations for driver support library
5 */
6
7/*
8 * Copyright (C) 2006 InnoTek Systemberatung GmbH
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License as published by the Free Software Foundation,
14 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
15 * distribution. VirtualBox OSE is distributed in the hope that it will
16 * be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * If you received this file as part of a commercial VirtualBox
19 * distribution, then only the terms of your commercial VirtualBox
20 * license agreement apply instead of the previous paragraph.
21 */
22
23
24/*******************************************************************************
25* Header Files *
26*******************************************************************************/
27#include <sys/fcntl.h>
28#include <sys/ioctl.h>
29#include <errno.h>
30#include <unistd.h>
31#include <stdlib.h>
32#include <malloc.h>
33#include <string.h>
34
35#include <VBox/sup.h>
36#include <VBox/types.h>
37#include <iprt/path.h>
38#include <iprt/assert.h>
39#include <VBox/err.h>
40#include <VBox/param.h>
41#include "SUPLibInternal.h"
42#include "SUPDRVIOC.h"
43
44
45/*******************************************************************************
46* Defined Constants And Macros *
47*******************************************************************************/
48/** Unix Device name. */
49#define DEVICE_NAME "/dev/vboxdrv"
50
51
52
53/*******************************************************************************
54* Global Variables *
55*******************************************************************************/
56/** Handle to the open device. */
57static int g_hDevice = -1;
58/** Flags whether or not we've loaded the kernel module. */
59static bool g_fLoadedModule = false;
60
61
62/*******************************************************************************
63* Internal Functions *
64*******************************************************************************/
65
66
67/**
68 * Initialize the OS specific part of the library.
69 * On Linux this involves:
70 * - loading the module.
71 * - open driver.
72 *
73 * @returns 0 on success.
74 * @returns current -1 on failure but this must be changed to proper error codes.
75 * @param cbReserved Ignored on linux.
76 */
77int suplibOsInit(size_t cbReserve)
78{
79 /*
80 * Check if already initialized.
81 */
82 if (g_hDevice >= 0)
83 return 0;
84
85 /*
86 * Try open the device.
87 */
88 g_hDevice = open(DEVICE_NAME, O_RDWR, 0);
89 if (g_hDevice < 0)
90 {
91 /*
92 * Try load the device.
93 */
94 //todo suplibOsLoadKernelModule();
95 g_hDevice = open(DEVICE_NAME, O_RDWR, 0);
96 if (g_hDevice < 0)
97 {
98 switch (errno)
99 {
100 case ENXIO: /* see man 2 open, ENODEV is actually a kernel bug */
101 case ENODEV: return VERR_VM_DRIVER_LOAD_ERROR;
102 case EPERM:
103 case EACCES: return VERR_VM_DRIVER_NOT_ACCESSIBLE;
104 case ENOENT: return VERR_VM_DRIVER_NOT_INSTALLED;
105 default:
106 return VERR_VM_DRIVER_OPEN_ERROR;
107 }
108 }
109 }
110
111 /*
112 * Mark the file handle close on exec.
113 */
114 if (fcntl(g_hDevice, F_SETFD, FD_CLOEXEC) == -1)
115 {
116 close(g_hDevice);
117 g_hDevice = -1;
118 return RTErrConvertFromErrno(errno);
119 }
120
121 /*
122 * Check driver version.
123 */
124 /** @todo implement driver version checking. */
125
126 /*
127 * We're done.
128 */
129 NOREF(cbReserve);
130 return 0;
131}
132
133
134int suplibOsTerm(void)
135{
136 /*
137 * Check if we're initited at all.
138 */
139 if (g_hDevice >= 0)
140 {
141 if (close(g_hDevice))
142 AssertFailed();
143 g_hDevice = -1;
144 }
145
146 /*
147 * If we started the service we might consider stopping it too.
148 *
149 * Since this won't work unless the the process starting it is the
150 * last user we might wanna skip this...
151 */
152 if (g_fLoadedModule)
153 {
154 //todo kernel module unloading.
155 //suplibOsStopService();
156 //g_fStartedService = false;
157 }
158
159 return 0;
160}
161
162
163/**
164 * Installs anything required by the support library.
165 *
166 * @returns 0 on success.
167 * @returns error code on failure.
168 */
169int suplibOsInstall(void)
170{
171 // nothing to do on Linux
172 return VERR_NOT_IMPLEMENTED;
173}
174
175
176/**
177 * Installs anything required by the support library.
178 *
179 * @returns 0 on success.
180 * @returns error code on failure.
181 */
182int suplibOsUninstall(void)
183{
184 // nothing to do on Linux
185 return VERR_NOT_IMPLEMENTED;
186}
187
188
189/**
190 * Send a I/O Control request to the device.
191 *
192 * @returns 0 on success.
193 * @returns VBOX error code on failure.
194 * @param uFunction IO Control function.
195 * @param pvIn Input data buffer.
196 * @param cbIn Size of input data.
197 * @param pvOut Output data buffer.
198 * @param cbOut Size of output data.
199 */
200int suplibOsIOCtl(unsigned uFunction, void *pvIn, size_t cbIn, void *pvOut, size_t cbOut)
201{
202 AssertMsg(g_hDevice != -1, ("SUPLIB not initiated successfully!\n"));
203 /*
204 * Issue device iocontrol.
205 */
206 SUPDRVIOCTLDATA Args;
207 Args.pvIn = pvIn;
208 Args.cbIn = cbIn;
209 Args.pvOut = pvOut;
210 Args.cbOut = cbOut;
211
212 if (ioctl(g_hDevice, uFunction, &Args) >= 0)
213 return VINF_SUCCESS;
214
215 /* This is the reverse operation of the one found in SUPDrv-linux.c */
216 switch (errno)
217 {
218 case EACCES: return VERR_GENERAL_FAILURE;
219 case EINVAL: return VERR_INVALID_PARAMETER;
220 case EILSEQ: return VERR_INVALID_MAGIC;
221 case ENXIO: return VERR_INVALID_HANDLE;
222 case EFAULT: return VERR_INVALID_POINTER;
223 case ENOLCK: return VERR_LOCK_FAILED;
224 case EEXIST: return VERR_ALREADY_LOADED;
225 case EPERM: return VERR_PERMISSION_DENIED;
226 case ENOSYS: return VERR_VERSION_MISMATCH;
227 }
228
229 return RTErrConvertFromErrno(errno);
230}
231
232
233/**
234 * Allocate a number of zero-filled pages in user space.
235 *
236 * @returns VBox status code.
237 * @param cPages Number of pages to allocate.
238 * @param ppvPages Where to return the base pointer.
239 */
240int suplibOsPageAlloc(size_t cPages, void **ppvPages)
241{
242#if 0
243 int rc = posix_memalign(ppvPages, PAGE_SIZE, cPages << PAGE_SHIFT)
244 if (!rc)
245 {
246 memset(*ppvPages, 0, cPages << PAGE_SHIFT);
247 return VINF_SUCCESS;
248 }
249 return RTErrConvertFromErrno(rc);
250#else
251 *ppvPages = memalign(PAGE_SIZE, cPages << PAGE_SHIFT);
252 if (*ppvPages)
253 {
254 memset(*ppvPages, 0, cPages << PAGE_SHIFT);
255 return VINF_SUCCESS;
256 }
257 return VERR_NO_MEMORY;
258#endif
259}
260
261
262/**
263 * Frees pages allocated by suplibOsPageAlloc().
264 *
265 * @returns VBox status code.
266 * @param pvPages Pointer to pages.
267 */
268int suplibOsPageFree(void *pvPages)
269{
270 free(pvPages);
271 return VINF_SUCCESS;
272}
273
274
275
276
277
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