1 /* $Id: GenericRequest.cpp $ */
3 * VBoxGuestLibR0 - Generic VMMDev request management.
7 * Copyright (C) 2006-2016 Oracle Corporation
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.
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.
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.
27 #include "VBGLInternal.h"
29 #include <iprt/asm-amd64-x86.h>
30 #include <iprt/assert.h>
31 #include <iprt/string.h>
34 DECLVBGL(int) VbglGRVerify(const VMMDevRequestHeader
*pReq
, size_t cbReq
)
38 if (RT_UNLIKELY(!pReq
|| cbReq
< sizeof(VMMDevRequestHeader
)))
40 dprintf(("VbglGRVerify: Invalid parameter: pReq = %p, cbReq = %zu\n", pReq
, cbReq
));
41 return VERR_INVALID_PARAMETER
;
44 if (RT_UNLIKELY(pReq
->size
> cbReq
))
46 dprintf(("VbglGRVerify: request size %u > buffer size %zu\n", pReq
->size
, cbReq
));
47 return VERR_INVALID_PARAMETER
;
50 /* The request size must correspond to the request type. */
51 cbReqExpected
= vmmdevGetRequestSize(pReq
->requestType
);
52 if (RT_UNLIKELY(cbReq
< cbReqExpected
))
54 dprintf(("VbglGRVerify: buffer size %zu < expected size %zu\n", cbReq
, cbReqExpected
));
55 return VERR_INVALID_PARAMETER
;
58 if (cbReqExpected
== cbReq
)
61 * This is most likely a fixed size request, and in this case the
62 * request size must be also equal to the expected size.
64 if (RT_UNLIKELY(pReq
->size
!= cbReqExpected
))
66 dprintf(("VbglGRVerify: request size %u != expected size %zu\n", pReq
->size
, cbReqExpected
));
67 return VERR_INVALID_PARAMETER
;
74 * This can be a variable size request. Check the request type and limit the size
75 * to VMMDEV_MAX_VMMDEVREQ_SIZE, which is max size supported by the host.
77 * Note: Keep this list sorted for easier human lookup!
79 if ( pReq
->requestType
== VMMDevReq_ChangeMemBalloon
80 #ifdef VBOX_WITH_64_BITS_GUESTS
81 || pReq
->requestType
== VMMDevReq_HGCMCall32
82 || pReq
->requestType
== VMMDevReq_HGCMCall64
84 || pReq
->requestType
== VMMDevReq_HGCMCall
86 || pReq
->requestType
== VMMDevReq_RegisterSharedModule
87 || pReq
->requestType
== VMMDevReq_ReportGuestUserState
88 || pReq
->requestType
== VMMDevReq_LogString
89 || pReq
->requestType
== VMMDevReq_SetPointerShape
90 || pReq
->requestType
== VMMDevReq_VideoSetVisibleRegion
)
92 if (RT_UNLIKELY(cbReq
> VMMDEV_MAX_VMMDEVREQ_SIZE
))
94 dprintf(("VbglGRVerify: VMMDevReq_LogString: buffer size %zu too big\n", cbReq
));
95 return VERR_BUFFER_OVERFLOW
; /** @todo is this error code ok? */
100 dprintf(("VbglGRVerify: request size %u > buffer size %zu\n", pReq
->size
, cbReq
));
101 return VERR_IO_BAD_LENGTH
; /** @todo is this error code ok? */
107 DECLVBGL(int) VbglGRAlloc(VMMDevRequestHeader
**ppReq
, size_t cbReq
, VMMDevRequestType enmReqType
)
109 int rc
= vbglR0Enter();
113 && cbReq
>= sizeof(VMMDevRequestHeader
)
114 && cbReq
== (uint32_t)cbReq
)
116 VMMDevRequestHeader
*pReq
= (VMMDevRequestHeader
*)VbglPhysHeapAlloc((uint32_t)cbReq
);
117 AssertMsgReturn(pReq
, ("VbglGRAlloc: no memory (cbReq=%u)\n", cbReq
), VERR_NO_MEMORY
);
118 memset(pReq
, 0xAA, cbReq
);
120 pReq
->size
= (uint32_t)cbReq
;
121 pReq
->version
= VMMDEV_REQUEST_HEADER_VERSION
;
122 pReq
->requestType
= enmReqType
;
123 pReq
->rc
= VERR_GENERAL_FAILURE
;
132 dprintf(("VbglGRAlloc: Invalid parameter: ppReq=%p cbReq=%u\n", ppReq
, cbReq
));
133 rc
= VERR_INVALID_PARAMETER
;
139 DECLVBGL(int) VbglGRPerform(VMMDevRequestHeader
*pReq
)
141 int rc
= vbglR0Enter();
146 RTCCPHYS PhysAddr
= VbglPhysHeapGetPhysAddr(pReq
);
148 && PhysAddr
< _4G
) /* Port IO is 32 bit. */
150 ASMOutU32(g_vbgldata
.portVMMDev
+ VMMDEV_PORT_OFF_REQUEST
, (uint32_t)PhysAddr
);
151 /* Make the compiler aware that the host has changed memory. */
152 ASMCompilerBarrier();
156 rc
= VERR_VBGL_INVALID_ADDR
;
159 rc
= VERR_INVALID_PARAMETER
;
164 DECLVBGL(void) VbglGRFree(VMMDevRequestHeader
*pReq
)
166 int rc
= vbglR0Enter();
168 VbglPhysHeapFree(pReq
);