VirtualBox

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

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

backed out r69255, r69257 (does currently not compile)

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette