VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp@ 39608

Last change on this file since 39608 was 35398, checked in by vboxsync, 14 years ago

re-applied r69255, r69257: properly wrap mem* to xf86mem* for older XF86 modules

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.7 KB
Line 
1/* $Id: HGSMIBase.cpp 35398 2011-01-04 09:39:07Z vboxsync $ */
2/** @file
3 * VirtualBox Video driver, common code - HGSMI initialisation and helper
4 * functions.
5 */
6
7/*
8 * Copyright (C) 2006-2010 Oracle Corporation
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 (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#include <VBox/VBoxVideoGuest.h>
20#include <VBox/VBoxVideo.h>
21#include <VBox/VBoxGuest.h>
22#include <VBox/Hardware/VBoxVideoVBE.h>
23#include <VBox/VMMDev.h>
24
25#include <iprt/asm.h>
26#include <iprt/log.h>
27#include <iprt/string.h>
28
29/** Send completion notification to the host for the command located at offset
30 * @a offt into the host command buffer. */
31static void HGSMINotifyHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx, HGSMIOFFSET offt)
32{
33 VBoxVideoCmnPortWriteUlong(pCtx->port, offt);
34}
35
36
37/**
38 * Inform the host that a command has been handled.
39 *
40 * @param pCtx the context containing the heap to be used
41 * @param pvMem pointer into the heap as mapped in @a pCtx to the command to
42 * be completed
43 */
44RTDECL(void) VBoxHGSMIHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx,
45 void *pvMem)
46{
47 HGSMIBUFFERHEADER *pHdr = HGSMIBufferHeaderFromData(pvMem);
48 HGSMIOFFSET offMem = HGSMIPointerToOffset(&pCtx->areaCtx, pHdr);
49 Assert(offMem != HGSMIOFFSET_VOID);
50 if(offMem != HGSMIOFFSET_VOID)
51 {
52 HGSMINotifyHostCmdComplete(pCtx, offMem);
53 }
54}
55
56
57/** Submit an incoming host command to the appropriate handler. */
58static void hgsmiHostCmdProcess(PHGSMIHOSTCOMMANDCONTEXT pCtx,
59 HGSMIOFFSET offBuffer)
60{
61 int rc = HGSMIBufferProcess(&pCtx->areaCtx, &pCtx->channels, offBuffer);
62 Assert(!RT_FAILURE(rc));
63 if(RT_FAILURE(rc))
64 {
65 /* failure means the command was not submitted to the handler for some reason
66 * it's our responsibility to notify its completion in this case */
67 HGSMINotifyHostCmdComplete(pCtx, offBuffer);
68 }
69 /* if the cmd succeeded it's responsibility of the callback to complete it */
70}
71
72/** Get the next command from the host. */
73static HGSMIOFFSET hgsmiGetHostBuffer(PHGSMIHOSTCOMMANDCONTEXT pCtx)
74{
75 return VBoxVideoCmnPortReadUlong(pCtx->port);
76}
77
78
79/** Get and handle the next command from the host. */
80static void hgsmiHostCommandQueryProcess(PHGSMIHOSTCOMMANDCONTEXT pCtx)
81{
82 HGSMIOFFSET offset = hgsmiGetHostBuffer(pCtx);
83 AssertReturnVoid(offset != HGSMIOFFSET_VOID);
84 hgsmiHostCmdProcess(pCtx, offset);
85}
86
87
88/** Drain the host command queue. */
89RTDECL(void) VBoxHGSMIProcessHostQueue(PHGSMIHOSTCOMMANDCONTEXT pCtx)
90{
91 while (pCtx->pfHostFlags->u32HostFlags & HGSMIHOSTFLAGS_COMMANDS_PENDING)
92 {
93 if (!ASMAtomicCmpXchgBool(&pCtx->fHostCmdProcessing, true, false))
94 return;
95 hgsmiHostCommandQueryProcess(pCtx);
96 ASMAtomicWriteBool(&pCtx->fHostCmdProcessing, false);
97 }
98}
99
100
101/** Detect whether HGSMI is supported by the host. */
102RTDECL(bool) VBoxHGSMIIsSupported(void)
103{
104 uint16_t DispiId;
105
106 VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID);
107 VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_HGSMI);
108
109 DispiId = VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA);
110
111 return (DispiId == VBE_DISPI_ID_HGSMI);
112}
113
114
115/**
116 * Allocate and initialise a command descriptor in the guest heap for a
117 * guest-to-host command.
118 *
119 * @returns pointer to the descriptor's command data buffer
120 * @param pCtx the context containing the heap to be used
121 * @param cbData the size of the command data to go into the descriptor
122 * @param u8Ch the HGSMI channel to be used, set to the descriptor
123 * @param u16Op the HGSMI command to be sent, set to the descriptor
124 */
125RTDECL(void *) VBoxHGSMIBufferAlloc(PHGSMIGUESTCOMMANDCONTEXT pCtx,
126 HGSMISIZE cbData,
127 uint8_t u8Ch,
128 uint16_t u16Op)
129{
130#ifdef VBOX_WITH_WDDM
131 /* @todo: add synchronization */
132#endif
133 return HGSMIHeapAlloc (&pCtx->heapCtx, cbData, u8Ch, u16Op);
134}
135
136
137/**
138 * Free a descriptor allocated by @a VBoxHGSMIBufferAlloc.
139 *
140 * @param pCtx the context containing the heap used
141 * @param pvBuffer the pointer returned by @a VBoxHGSMIBufferAlloc
142 */
143RTDECL(void) VBoxHGSMIBufferFree(PHGSMIGUESTCOMMANDCONTEXT pCtx,
144 void *pvBuffer)
145{
146#ifdef VBOX_WITH_WDDM
147 /* @todo: add synchronization */
148#endif
149 HGSMIHeapFree (&pCtx->heapCtx, pvBuffer);
150}
151
152
153/**
154 * Submit a command descriptor allocated by @a VBoxHGSMIBufferAlloc.
155 *
156 * @param pCtx the context containing the heap used
157 * @param pvBuffer the pointer returned by @a VBoxHGSMIBufferAlloc
158 */
159RTDECL(int) VBoxHGSMIBufferSubmit(PHGSMIGUESTCOMMANDCONTEXT pCtx,
160 void *pvBuffer)
161{
162 /* Initialize the buffer and get the offset for port IO. */
163 HGSMIOFFSET offBuffer = HGSMIHeapBufferOffset (&pCtx->heapCtx, pvBuffer);
164
165 Assert(offBuffer != HGSMIOFFSET_VOID);
166 if (offBuffer != HGSMIOFFSET_VOID)
167 {
168 /* Submit the buffer to the host. */
169 VBoxVideoCmnPortWriteUlong(pCtx->port, offBuffer);
170 return VINF_SUCCESS;
171 }
172
173 return VERR_INVALID_PARAMETER;
174}
175
176
177/** Inform the host of the location of the host flags in VRAM via an HGSMI
178 * command. */
179static int vboxHGSMIReportFlagsLocation(PHGSMIGUESTCOMMANDCONTEXT pCtx,
180 HGSMIOFFSET offLocation)
181{
182 HGSMIBUFFERLOCATION *p;
183 int rc = VINF_SUCCESS;
184
185 /* Allocate the IO buffer. */
186 p = (HGSMIBUFFERLOCATION *)HGSMIHeapAlloc(&pCtx->heapCtx,
187 sizeof(HGSMIBUFFERLOCATION),
188 HGSMI_CH_HGSMI,
189 HGSMI_CC_HOST_FLAGS_LOCATION);
190 if (p)
191 {
192 /* Prepare data to be sent to the host. */
193 p->offLocation = offLocation;
194 p->cbLocation = sizeof(HGSMIHOSTFLAGS);
195 rc = VBoxHGSMIBufferSubmit(pCtx, p);
196 /* Free the IO buffer. */
197 HGSMIHeapFree (&pCtx->heapCtx, p);
198 }
199 else
200 rc = VERR_NO_MEMORY;
201 return rc;
202}
203
204
205/** Notify the host of HGSMI-related guest capabilities via an HGSMI command.
206 */
207static int vboxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
208 uint32_t fCaps)
209{
210 VBVACAPS *pCaps;
211 int rc = VINF_SUCCESS;
212
213 /* Allocate the IO buffer. */
214 pCaps = (VBVACAPS *)HGSMIHeapAlloc(&pCtx->heapCtx,
215 sizeof(VBVACAPS), HGSMI_CH_VBVA,
216 VBVA_INFO_CAPS);
217
218 if (pCaps)
219 {
220 /* Prepare data to be sent to the host. */
221 pCaps->rc = VERR_NOT_IMPLEMENTED;
222 pCaps->fCaps = fCaps;
223 rc = VBoxHGSMIBufferSubmit(pCtx, pCaps);
224 if (RT_SUCCESS(rc))
225 {
226 AssertRC(pCaps->rc);
227 rc = pCaps->rc;
228 }
229 /* Free the IO buffer. */
230 HGSMIHeapFree(&pCtx->heapCtx, pCaps);
231 }
232 else
233 rc = VERR_NO_MEMORY;
234 return rc;
235}
236
237
238/** Tell the host about the location of the area of VRAM set aside for the host
239 * heap. */
240static int vboxHGSMIReportHostArea(PHGSMIGUESTCOMMANDCONTEXT pCtx,
241 uint32_t u32AreaOffset, uint32_t u32AreaSize)
242{
243 VBVAINFOHEAP *p;
244 int rc = VINF_SUCCESS;
245
246 /* Allocate the IO buffer. */
247 p = (VBVAINFOHEAP *)HGSMIHeapAlloc(&pCtx->heapCtx,
248 sizeof (VBVAINFOHEAP), HGSMI_CH_VBVA,
249 VBVA_INFO_HEAP);
250 if (p)
251 {
252 /* Prepare data to be sent to the host. */
253 p->u32HeapOffset = u32AreaOffset;
254 p->u32HeapSize = u32AreaSize;
255 rc = VBoxHGSMIBufferSubmit(pCtx, p);
256 /* Free the IO buffer. */
257 HGSMIHeapFree(&pCtx->heapCtx, p);
258 }
259 else
260 rc = VERR_NO_MEMORY;
261 return rc;
262}
263
264
265/**
266 * Get the information needed to map the basic communication structures in
267 * device memory into our address space. All pointer parameters are optional.
268 *
269 * @param cbVRAM how much video RAM is allocated to the device
270 * @param poffVRAMBaseMapping where to save the offset from the start of the
271 * device VRAM of the whole area to map
272 * @param pcbMapping where to save the mapping size
273 * @param poffGuestHeapMemory where to save the offset into the mapped area
274 * of the guest heap backing memory
275 * @param pcbGuestHeapMemory where to save the size of the guest heap
276 * backing memory
277 * @param poffHostFlags where to save the offset into the mapped area
278 * of the host flags
279 */
280RTDECL(void) VBoxHGSMIGetBaseMappingInfo(uint32_t cbVRAM,
281 uint32_t *poffVRAMBaseMapping,
282 uint32_t *pcbMapping,
283 uint32_t *poffGuestHeapMemory,
284 uint32_t *pcbGuestHeapMemory,
285 uint32_t *poffHostFlags)
286{
287 AssertPtrNullReturnVoid(poffVRAMBaseMapping);
288 AssertPtrNullReturnVoid(pcbMapping);
289 AssertPtrNullReturnVoid(poffGuestHeapMemory);
290 AssertPtrNullReturnVoid(pcbGuestHeapMemory);
291 AssertPtrNullReturnVoid(poffHostFlags);
292 if (poffVRAMBaseMapping)
293 *poffVRAMBaseMapping = cbVRAM - VBVA_ADAPTER_INFORMATION_SIZE;
294 if (pcbMapping)
295 *pcbMapping = VBVA_ADAPTER_INFORMATION_SIZE;
296 if (poffGuestHeapMemory)
297 *poffGuestHeapMemory = 0;
298 if (pcbGuestHeapMemory)
299 *pcbGuestHeapMemory = VBVA_ADAPTER_INFORMATION_SIZE
300 - sizeof(HGSMIHOSTFLAGS);
301 if (poffHostFlags)
302 *poffHostFlags = VBVA_ADAPTER_INFORMATION_SIZE
303 - sizeof(HGSMIHOSTFLAGS);
304}
305
306
307/**
308 * Set up the HGSMI guest-to-host command context.
309 * @returns iprt status value
310 * @param pCtx the context to set up
311 * @param pvGuestHeapMemory a pointer to the mapped backing memory for
312 * the guest heap
313 * @param cbGuestHeapMemory the size of the backing memory area
314 * @param offVRAMGuestHeapMemory the offset of the memory pointed to by
315 * @a pvGuestHeapMemory within the video RAM
316 */
317RTDECL(int) VBoxHGSMISetupGuestContext(PHGSMIGUESTCOMMANDCONTEXT pCtx,
318 void *pvGuestHeapMemory,
319 uint32_t cbGuestHeapMemory,
320 uint32_t offVRAMGuestHeapMemory)
321{
322 /** @todo should we be using a fixed ISA port value here? */
323 pCtx->port = (RTIOPORT)VGA_PORT_HGSMI_GUEST;
324 return HGSMIHeapSetup(&pCtx->heapCtx, pvGuestHeapMemory,
325 cbGuestHeapMemory, offVRAMGuestHeapMemory,
326 false /*fOffsetBased*/);
327}
328
329
330/**
331 * Get the information needed to map the area used by the host to send back
332 * requests.
333 *
334 * @param pCtx the context containing the heap to use
335 * @param cbVRAM how much video RAM is allocated to the device
336 * @param offVRAMBaseMapping the offset of the basic communication structures
337 * into the guest's VRAM
338 * @param poffVRAMHostArea where to store the offset into VRAM of the host
339 * heap area
340 * @param pcbHostArea where to store the size of the host heap area
341 */
342RTDECL(void) VBoxHGSMIGetHostAreaMapping(PHGSMIGUESTCOMMANDCONTEXT pCtx,
343 uint32_t cbVRAM,
344 uint32_t offVRAMBaseMapping,
345 uint32_t *poffVRAMHostArea,
346 uint32_t *pcbHostArea)
347{
348 uint32_t offVRAMHostArea = offVRAMBaseMapping, cbHostArea = 0;
349
350 AssertPtrReturnVoid(poffVRAMHostArea);
351 AssertPtrReturnVoid(pcbHostArea);
352 VBoxQueryConfHGSMI(pCtx, VBOX_VBVA_CONF32_HOST_HEAP_SIZE, &cbHostArea);
353 if (cbHostArea != 0)
354 {
355 uint32_t cbHostAreaMaxSize = cbVRAM / 4;
356 /** @todo what is the idea of this? */
357 if (cbHostAreaMaxSize >= VBVA_ADAPTER_INFORMATION_SIZE)
358 {
359 cbHostAreaMaxSize -= VBVA_ADAPTER_INFORMATION_SIZE;
360 }
361 if (cbHostArea > cbHostAreaMaxSize)
362 {
363 cbHostArea = cbHostAreaMaxSize;
364 }
365 /* Round up to 4096 bytes. */
366 cbHostArea = (cbHostArea + 0xFFF) & ~0xFFF;
367 offVRAMHostArea = offVRAMBaseMapping - cbHostArea;
368 }
369
370 *pcbHostArea = cbHostArea;
371 *poffVRAMHostArea = offVRAMHostArea;
372 LogFunc(("offVRAMHostArea = 0x%08X, cbHostArea = 0x%08X\n",
373 offVRAMHostArea, cbHostArea));
374}
375
376
377/**
378 * Initialise the host context structure.
379 *
380 * @param pCtx the context structure to initialise
381 * @param pvBaseMapping where the basic HGSMI structures are mapped at
382 * @param offHostFlags the offset of the host flags into the basic HGSMI
383 * structures
384 * @param pvHostAreaMapping where the area for the host heap is mapped at
385 * @param offVRAMHostArea offset of the host heap area into VRAM
386 * @param cbHostArea size in bytes of the host heap area
387 */
388RTDECL(void) VBoxHGSMISetupHostContext(PHGSMIHOSTCOMMANDCONTEXT pCtx,
389 void *pvBaseMapping,
390 uint32_t offHostFlags,
391 void *pvHostAreaMapping,
392 uint32_t offVRAMHostArea,
393 uint32_t cbHostArea)
394{
395 uint8_t *pu8HostFlags = ((uint8_t *)pvBaseMapping) + offHostFlags;
396 pCtx->pfHostFlags = (HGSMIHOSTFLAGS *)pu8HostFlags;
397 /** @todo should we really be using a fixed ISA port value here? */
398 pCtx->port = (RTIOPORT)VGA_PORT_HGSMI_HOST;
399 HGSMIAreaInitialize(&pCtx->areaCtx, pvHostAreaMapping, cbHostArea,
400 offVRAMHostArea);
401}
402
403
404/**
405 * Tell the host about the ways it can use to communicate back to us via an
406 * HGSMI command
407 *
408 * @returns iprt status value
409 * @param pCtx the context containing the heap to use
410 * @param offVRAMFlagsLocation where we wish the host to place its flags
411 * relative to the start of the VRAM
412 * @param fCaps additions HGSMI capabilities the guest
413 * supports
414 * @param offVRAMHostArea offset into VRAM of the host heap area
415 * @param cbHostArea size in bytes of the host heap area
416 */
417RTDECL(int) VBoxHGSMISendHostCtxInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
418 HGSMIOFFSET offVRAMFlagsLocation,
419 uint32_t fCaps,
420 uint32_t offVRAMHostArea,
421 uint32_t cbHostArea)
422{
423 Log(("VBoxVideo::vboxSetupAdapterInfo\n"));
424
425 /* setup the flags first to ensure they are initialized by the time the
426 * host heap is ready */
427 int rc = vboxHGSMIReportFlagsLocation(pCtx, offVRAMFlagsLocation);
428 AssertRC(rc);
429 if (RT_SUCCESS(rc) && fCaps)
430 {
431 /* Inform about caps */
432 rc = vboxHGSMISendCapsInfo(pCtx, fCaps);
433 AssertRC(rc);
434 }
435 if (RT_SUCCESS (rc))
436 {
437 /* Report the host heap location. */
438 rc = vboxHGSMIReportHostArea(pCtx, offVRAMHostArea, cbHostArea);
439 AssertRC(rc);
440 }
441 Log(("VBoxVideo::vboxSetupAdapterInfo finished rc = %d\n", rc));
442 return rc;
443}
444
445
446/**
447 * Query the host for an HGSMI configuration parameter via an HGSMI command.
448 * @returns iprt status value
449 * @param pCtx the context containing the heap used
450 * @param u32Index the index of the parameter to query,
451 * @see VBVACONF32::u32Index
452 * @param pulValue where to store the value of the parameter on success
453 */
454RTDECL(int) VBoxQueryConfHGSMI(PHGSMIGUESTCOMMANDCONTEXT pCtx,
455 uint32_t u32Index, uint32_t *pulValue)
456{
457 int rc = VINF_SUCCESS;
458 VBVACONF32 *p;
459 LogFunc(("u32Index = %d\n", u32Index));
460
461 /* Allocate the IO buffer. */
462 p = (VBVACONF32 *)HGSMIHeapAlloc(&pCtx->heapCtx,
463 sizeof(VBVACONF32), HGSMI_CH_VBVA,
464 VBVA_QUERY_CONF32);
465 if (p)
466 {
467 /* Prepare data to be sent to the host. */
468 p->u32Index = u32Index;
469 p->u32Value = 0;
470 rc = VBoxHGSMIBufferSubmit(pCtx, p);
471 if (RT_SUCCESS(rc))
472 {
473 *pulValue = p->u32Value;
474 LogFunc(("u32Value = %d\n", p->u32Value));
475 }
476 /* Free the IO buffer. */
477 HGSMIHeapFree(&pCtx->heapCtx, p);
478 }
479 else
480 rc = VERR_NO_MEMORY;
481 LogFunc(("rc = %d\n", rc));
482 return rc;
483}
484
485
486/**
487 * Pass the host a new mouse pointer shape via an HGSMI command.
488 *
489 * @returns success or failure
490 * @todo why not return an iprt status code?
491 * @param fFlags cursor flags, @see VMMDevReqMousePointer::fFlags
492 * @param cHotX horizontal position of the hot spot
493 * @param cHotY vertical position of the hot spot
494 * @param cWidth width in pixels of the cursor
495 * @param cHeight height in pixels of the cursor
496 * @param pPixels pixel data, @see VMMDevReqMousePointer for the format
497 * @param cbLength size in bytes of the pixel data
498 */
499RTDECL(bool) VBoxHGSMIUpdatePointerShape(PHGSMIGUESTCOMMANDCONTEXT pCtx,
500 uint32_t fFlags,
501 uint32_t cHotX,
502 uint32_t cHotY,
503 uint32_t cWidth,
504 uint32_t cHeight,
505 uint8_t *pPixels,
506 uint32_t cbLength)
507{
508 VBVAMOUSEPOINTERSHAPE *p;
509 uint32_t cbData = 0;
510 int rc = VINF_SUCCESS;
511
512 if (fFlags & VBOX_MOUSE_POINTER_SHAPE)
513 {
514 /* Size of the pointer data: sizeof (AND mask) + sizeof (XOR_MASK) */
515 cbData = ((((cWidth + 7) / 8) * cHeight + 3) & ~3)
516 + cWidth * 4 * cHeight;
517 /* If shape is supplied, then always create the pointer visible.
518 * See comments in 'vboxUpdatePointerShape'
519 */
520 fFlags |= VBOX_MOUSE_POINTER_VISIBLE;
521 }
522 LogFlowFunc(("cbData %d, %dx%d\n", cbData, cWidth, cHeight));
523 if (cbData > cbLength)
524 {
525 LogFunc(("calculated pointer data size is too big (%d bytes, limit %d)\n",
526 cbData, cbLength));
527 return false;
528 }
529 /* Allocate the IO buffer. */
530 p = (VBVAMOUSEPOINTERSHAPE *)HGSMIHeapAlloc(&pCtx->heapCtx,
531 sizeof(VBVAMOUSEPOINTERSHAPE)
532 + cbData,
533 HGSMI_CH_VBVA,
534 VBVA_MOUSE_POINTER_SHAPE);
535 if (p)
536 {
537 /* Prepare data to be sent to the host. */
538 /* Will be updated by the host. */
539 p->i32Result = VINF_SUCCESS;
540 /* We have our custom flags in the field */
541 p->fu32Flags = fFlags;
542 p->u32HotX = cHotX;
543 p->u32HotY = cHotY;
544 p->u32Width = cWidth;
545 p->u32Height = cHeight;
546 if (p->fu32Flags & VBOX_MOUSE_POINTER_SHAPE)
547 /* Copy the actual pointer data. */
548 memcpy (p->au8Data, pPixels, cbData);
549 rc = VBoxHGSMIBufferSubmit(pCtx, p);
550 if (RT_SUCCESS(rc))
551 rc = p->i32Result;
552 /* Free the IO buffer. */
553 HGSMIHeapFree(&pCtx->heapCtx, p);
554 }
555 else
556 rc = VERR_NO_MEMORY;
557 LogFlowFunc(("rc %d\n", rc));
558 return RT_SUCCESS(rc);
559}
560
561
562/** @todo Mouse pointer position to be read from VMMDev memory, address of the memory region
563 * can be queried from VMMDev via an IOCTL. This VMMDev memory region will contain
564 * host information which is needed by the guest.
565 *
566 * Reading will not cause a switch to the host.
567 *
568 * Have to take into account:
569 * * synchronization: host must write to the memory only from EMT,
570 * large structures must be read under flag, which tells the host
571 * that the guest is currently reading the memory (OWNER flag?).
572 * * guest writes: may be allocate a page for the host info and make
573 * the page readonly for the guest.
574 * * the information should be available only for additions drivers.
575 * * VMMDev additions driver will inform the host which version of the info it expects,
576 * host must support all versions.
577 *
578 */
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