Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-ports-gnome
Path: blob/main/emulators/virtualbox-ose/files/patch-src-VBox-Additions-common-VBoxGuest-VBoxGuest-freebsd.c
17391 views
1
--- src/VBox/Additions/common/VBoxGuest/VBoxGuest-freebsd.c.orig 2019-01-25 18:12:28 UTC
2
+++ src/VBox/Additions/common/VBoxGuest/VBoxGuest-freebsd.c
3
@@ -45,6 +45,7 @@
4
#include <sys/uio.h>
5
#include <sys/bus.h>
6
#include <sys/poll.h>
7
+#include <sys/proc.h>
8
#include <sys/selinfo.h>
9
#include <sys/queue.h>
10
#include <sys/lock.h>
11
@@ -61,6 +62,7 @@
12
#include <VBox/version.h>
13
#include <VBox/log.h>
14
#include <iprt/assert.h>
15
+#include <iprt/err.h>
16
#include <iprt/initterm.h>
17
#include <iprt/process.h>
18
#include <iprt/string.h>
19
@@ -102,8 +104,6 @@ struct VBoxGuestDeviceState
20
struct resource *pIrqRes;
21
/** Pointer to the IRQ handler. */
22
void *pfnIrqHandler;
23
- /** VMMDev version */
24
- uint32_t u32Version;
25
};
26
27
28
@@ -113,8 +113,7 @@ struct VBoxGuestDeviceState
29
/*
30
* Character device file handlers.
31
*/
32
-static d_fdopen_t vgdrvFreeBSDOpen;
33
-static d_close_t vgdrvFreeBSDClose;
34
+static d_open_t vgdrvFreeBSDOpen;
35
static d_ioctl_t vgdrvFreeBSDIOCtl;
36
static int vgdrvFreeBSDIOCtlSlow(PVBOXGUESTSESSION pSession, u_long ulCmd, caddr_t pvData, struct thread *pTd);
37
static d_write_t vgdrvFreeBSDWrite;
38
@@ -145,8 +144,7 @@ static struct cdevsw g_vgdrvFreeBSDChrDevSW =
39
{
40
.d_version = D_VERSION,
41
.d_flags = D_TRACKCLOSE | D_NEEDMINOR,
42
- .d_fdopen = vgdrvFreeBSDOpen,
43
- .d_close = vgdrvFreeBSDClose,
44
+ .d_open = vgdrvFreeBSDOpen,
45
.d_ioctl = vgdrvFreeBSDIOCtl,
46
.d_read = vgdrvFreeBSDRead,
47
.d_write = vgdrvFreeBSDWrite,
48
@@ -154,81 +152,28 @@ static struct cdevsw g_vgdrvFreeBSDChrDevSW =
49
.d_name = "vboxguest"
50
};
51
52
+/** Device structure. */
53
+static struct cdev *g_pDev;
54
+
55
/** Device extention & session data association structure. */
56
static VBOXGUESTDEVEXT g_DevExt;
57
58
-/** List of cloned device. Managed by the kernel. */
59
-static struct clonedevs *g_pvgdrvFreeBSDClones;
60
-/** The dev_clone event handler tag. */
61
-static eventhandler_tag g_vgdrvFreeBSDEHTag;
62
/** Reference counter */
63
static volatile uint32_t cUsers;
64
/** selinfo structure used for polling. */
65
static struct selinfo g_SelInfo;
66
67
-/**
68
- * DEVFS event handler.
69
- */
70
-static void vgdrvFreeBSDClone(void *pvArg, struct ucred *pCred, char *pszName, int cchName, struct cdev **ppDev)
71
+static void vgdrvFreeBSDDtr(void *pSession)
72
{
73
- int iUnit;
74
- int rc;
75
-
76
- Log(("vgdrvFreeBSDClone: pszName=%s ppDev=%p\n", pszName, ppDev));
77
-
78
- /*
79
- * One device node per user, si_drv1 points to the session.
80
- * /dev/vboxguest<N> where N = {0...255}.
81
- */
82
- if (!ppDev)
83
- return;
84
- if (strcmp(pszName, "vboxguest") == 0)
85
- iUnit = -1;
86
- else if (dev_stdclone(pszName, NULL, "vboxguest", &iUnit) != 1)
87
- return;
88
- if (iUnit >= 256)
89
- {
90
- Log(("vgdrvFreeBSDClone: iUnit=%d >= 256 - rejected\n", iUnit));
91
- return;
92
- }
93
-
94
- Log(("vgdrvFreeBSDClone: pszName=%s iUnit=%d\n", pszName, iUnit));
95
-
96
- rc = clone_create(&g_pvgdrvFreeBSDClones, &g_vgdrvFreeBSDChrDevSW, &iUnit, ppDev, 0);
97
- Log(("vgdrvFreeBSDClone: clone_create -> %d; iUnit=%d\n", rc, iUnit));
98
- if (rc)
99
- {
100
- *ppDev = make_dev(&g_vgdrvFreeBSDChrDevSW,
101
- iUnit,
102
- UID_ROOT,
103
- GID_WHEEL,
104
- 0664,
105
- "vboxguest%d", iUnit);
106
- if (*ppDev)
107
- {
108
- dev_ref(*ppDev);
109
- (*ppDev)->si_flags |= SI_CHEAPCLONE;
110
- Log(("vgdrvFreeBSDClone: Created *ppDev=%p iUnit=%d si_drv1=%p si_drv2=%p\n",
111
- *ppDev, iUnit, (*ppDev)->si_drv1, (*ppDev)->si_drv2));
112
- (*ppDev)->si_drv1 = (*ppDev)->si_drv2 = NULL;
113
- }
114
- else
115
- Log(("vgdrvFreeBSDClone: make_dev iUnit=%d failed\n", iUnit));
116
- }
117
- else
118
- Log(("vgdrvFreeBSDClone: Existing *ppDev=%p iUnit=%d si_drv1=%p si_drv2=%p\n",
119
- *ppDev, iUnit, (*ppDev)->si_drv1, (*ppDev)->si_drv2));
120
+ VGDrvCommonCloseSession(&g_DevExt, pSession);
121
+ ASMAtomicDecU32(&cUsers);
122
}
123
124
/**
125
* File open handler
126
*
127
*/
128
-#if __FreeBSD_version >= 700000
129
-static int vgdrvFreeBSDOpen(struct cdev *pDev, int fOpen, struct thread *pTd, struct file *pFd)
130
-#else
131
-static int vgdrvFreeBSDOpen(struct cdev *pDev, int fOpen, struct thread *pTd)
132
-#endif
133
+static int vgdrvFreeBSDOpen(struct cdev *pDev, int fOpen, int DevType, struct thread *pTd)
134
{
135
int rc;
136
PVBOXGUESTSESSION pSession;
137
@@ -240,12 +185,6 @@ static int vgdrvFreeBSDOpen(struct cdev *pDev, int fOp
138
LogFlow(("vgdrvFreeBSDOpen:\n"));
139
140
/*
141
- * Try grab it (we don't grab the giant, remember).
142
- */
143
- if (!ASMAtomicCmpXchgPtr(&pDev->si_drv1, (void *)0x42, NULL))
144
- return EBUSY;
145
-
146
- /*
147
* Create a new session.
148
*/
149
fRequestor = VMMDEV_REQUESTOR_USERMODE | VMMDEV_REQUESTOR_TRUST_NOT_GIVEN;
150
@@ -262,14 +201,13 @@ static int vgdrvFreeBSDOpen(struct cdev *pDev, int fOp
151
rc = VGDrvCommonCreateUserSession(&g_DevExt, fRequestor, &pSession);
152
if (RT_SUCCESS(rc))
153
{
154
- if (ASMAtomicCmpXchgPtr(&pDev->si_drv1, pSession, (void *)0x42))
155
- {
156
- Log(("vgdrvFreeBSDOpen: success - g_DevExt=%p pSession=%p rc=%d pid=%d\n", &g_DevExt, pSession, rc, (int)RTProcSelf()));
157
+ Log(("vgdrvFreeBSDOpen: success - g_DevExt=%p pSession=%p rc=%d pid=%d\n", &g_DevExt, pSession, rc, (int)RTProcSelf()));
158
+ rc = devfs_set_cdevpriv(pSession, vgdrvFreeBSDDtr);
159
+ if (rc)
160
+ VGDrvCommonCloseSession(&g_DevExt, pSession);
161
+ else
162
ASMAtomicIncU32(&cUsers);
163
- return 0;
164
- }
165
-
166
- VGDrvCommonCloseSession(&g_DevExt, pSession);
167
+ return rc;
168
}
169
170
LogRel(("vgdrvFreeBSDOpen: failed. rc=%d\n", rc));
171
@@ -277,33 +215,6 @@ static int vgdrvFreeBSDOpen(struct cdev *pDev, int fOp
172
}
173
174
/**
175
- * File close handler
176
- *
177
- */
178
-static int vgdrvFreeBSDClose(struct cdev *pDev, int fFile, int DevType, struct thread *pTd)
179
-{
180
- PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pDev->si_drv1;
181
- Log(("vgdrvFreeBSDClose: fFile=%#x pSession=%p\n", fFile, pSession));
182
-
183
- /*
184
- * Close the session if it's still hanging on to the device...
185
- */
186
- if (VALID_PTR(pSession))
187
- {
188
- VGDrvCommonCloseSession(&g_DevExt, pSession);
189
- if (!ASMAtomicCmpXchgPtr(&pDev->si_drv1, NULL, pSession))
190
- Log(("vgdrvFreeBSDClose: si_drv1=%p expected %p!\n", pDev->si_drv1, pSession));
191
- ASMAtomicDecU32(&cUsers);
192
- /* Don't use destroy_dev here because it may sleep resulting in a hanging user process. */
193
- destroy_dev_sched(pDev);
194
- }
195
- else
196
- Log(("vgdrvFreeBSDClose: si_drv1=%p!\n", pSession));
197
- return 0;
198
-}
199
-
200
-
201
-/**
202
* I/O control request.
203
*
204
* @returns depends...
205
@@ -316,8 +227,12 @@ static int vgdrvFreeBSDClose(struct cdev *pDev, int fF
206
static int vgdrvFreeBSDIOCtl(struct cdev *pDev, u_long ulCmd, caddr_t pvData, int fFile, struct thread *pTd)
207
{
208
PVBOXGUESTSESSION pSession;
209
- devfs_get_cdevpriv((void **)&pSession);
210
+ int rc;
211
212
+ rc = devfs_get_cdevpriv((void **)&pSession);
213
+ if (rc)
214
+ return rc;
215
+
216
/*
217
* Deal with the fast ioctl path first.
218
*/
219
@@ -512,12 +427,14 @@ int VBOXCALL VBoxGuestIDC(void *pvSession, uintptr_t u
220
221
static int vgdrvFreeBSDPoll(struct cdev *pDev, int fEvents, struct thread *td)
222
{
223
- int fEventsProcessed;
224
+ PVBOXGUESTSESSION pSession;
225
+ int fEventsProcessed, rc;
226
227
LogFlow(("vgdrvFreeBSDPoll: fEvents=%d\n", fEvents));
228
229
- PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pDev->si_drv1;
230
- if (RT_UNLIKELY(!VALID_PTR(pSession))) {
231
+ rc = devfs_get_cdevpriv((void **)&pSession);
232
+ if (rc)
233
+ {
234
Log(("vgdrvFreeBSDPoll: no state data for %s\n", devtoname(pDev)));
235
return (fEvents & (POLLHUP|POLLIN|POLLRDNORM|POLLOUT|POLLWRNORM));
236
}
237
@@ -558,11 +475,8 @@ static int vgdrvFreeBSDDetach(device_t pDevice)
238
/*
239
* Reverse what we did in vgdrvFreeBSDAttach.
240
*/
241
- if (g_vgdrvFreeBSDEHTag != NULL)
242
- EVENTHANDLER_DEREGISTER(dev_clone, g_vgdrvFreeBSDEHTag);
243
+ destroy_dev(g_pDev);
244
245
- clone_cleanup(&g_pvgdrvFreeBSDClones);
246
-
247
vgdrvFreeBSDRemoveIRQ(pDevice, pState);
248
249
if (pState->pVMMDevMemRes)
250
@@ -727,18 +641,21 @@ static int vgdrvFreeBSDAttach(device_t pDevice)
251
VGDrvCommonProcessOptionsFromHost(&g_DevExt);
252
253
/*
254
- * Configure device cloning.
255
+ * Configure device.
256
*/
257
- clone_setup(&g_pvgdrvFreeBSDClones);
258
- g_vgdrvFreeBSDEHTag = EVENTHANDLER_REGISTER(dev_clone, vgdrvFreeBSDClone, 0, 1000);
259
- if (g_vgdrvFreeBSDEHTag)
260
+ g_pDev = make_dev(&g_vgdrvFreeBSDChrDevSW,
261
+ 0,
262
+ UID_ROOT,
263
+ GID_WHEEL,
264
+ 0664,
265
+ "vboxguest");
266
+ if (g_pDev)
267
{
268
printf(DEVICE_NAME ": loaded successfully\n");
269
return 0;
270
}
271
272
- printf(DEVICE_NAME ": EVENTHANDLER_REGISTER(dev_clone,,,) failed\n");
273
- clone_cleanup(&g_pvgdrvFreeBSDClones);
274
+ printf(DEVICE_NAME ": make_dev failed\n");
275
vgdrvFreeBSDRemoveIRQ(pDevice, pState);
276
}
277
else
278
279