~ubuntu-branches/ubuntu/trusty/virtualbox-lts-xenial/trusty-proposed

« back to all changes in this revision

Viewing changes to src/VBox/Additions/common/VBoxGuestLib/GenericRequest.cpp

  • Committer: Package Import Robot
  • Author(s): Gianfranco Costamagna
  • Date: 2016-02-23 14:28:26 UTC
  • Revision ID: package-import@ubuntu.com-20160223142826-bdu69el2z6wa2a44
Tags: upstream-4.3.36-dfsg
ImportĀ upstreamĀ versionĀ 4.3.36-dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Revision: 87431 $ */
 
2
/** @file
 
3
 * VBoxGuestLibR0 - Generic VMMDev request management.
 
4
 */
 
5
 
 
6
/*
 
7
 * Copyright (C) 2006-2013 Oracle Corporation
 
8
 *
 
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.
 
16
 *
 
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.
 
22
 *
 
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.
 
25
 */
 
26
 
 
27
#include "VBGLInternal.h"
 
28
#include <iprt/asm.h>
 
29
#include <iprt/asm-amd64-x86.h>
 
30
#include <iprt/assert.h>
 
31
#include <iprt/string.h>
 
32
 
 
33
DECLVBGL(int) VbglGRVerify (const VMMDevRequestHeader *pReq, size_t cbReq)
 
34
{
 
35
    size_t cbReqExpected;
 
36
 
 
37
    if (!pReq || cbReq < sizeof (VMMDevRequestHeader))
 
38
    {
 
39
        dprintf(("VbglGRVerify: Invalid parameter: pReq = %p, cbReq = %d\n", pReq, cbReq));
 
40
        return VERR_INVALID_PARAMETER;
 
41
    }
 
42
 
 
43
    if (pReq->size > cbReq)
 
44
    {
 
45
        dprintf(("VbglGRVerify: request size %d > buffer size %d\n", pReq->size, cbReq));
 
46
        return VERR_INVALID_PARAMETER;
 
47
    }
 
48
 
 
49
    /* The request size must correspond to the request type. */
 
50
    cbReqExpected = vmmdevGetRequestSize(pReq->requestType);
 
51
 
 
52
    if (cbReq < cbReqExpected)
 
53
    {
 
54
        dprintf(("VbglGRVerify: buffer size %d < expected size %d\n", cbReq, cbReqExpected));
 
55
        return VERR_INVALID_PARAMETER;
 
56
    }
 
57
 
 
58
    if (cbReqExpected == cbReq)
 
59
    {
 
60
        /* This is most likely a fixed size request, and in this case the request size
 
61
         * must be also equal to the expected size.
 
62
         */
 
63
        if (pReq->size != cbReqExpected)
 
64
        {
 
65
            dprintf(("VbglGRVerify: request size %d != expected size %d\n", pReq->size, cbReqExpected));
 
66
            return VERR_INVALID_PARAMETER;
 
67
        }
 
68
 
 
69
        return VINF_SUCCESS;
 
70
    }
 
71
 
 
72
    /*
 
73
     * This can be a variable size request. Check the request type and limit the size
 
74
     * to VMMDEV_MAX_VMMDEVREQ_SIZE, which is max size supported by the host.
 
75
     *
 
76
     * Note: Keep this list sorted for easier human lookup!
 
77
     */
 
78
    if (   pReq->requestType == VMMDevReq_ChangeMemBalloon
 
79
#ifdef VBOX_WITH_64_BITS_GUESTS
 
80
        || pReq->requestType == VMMDevReq_HGCMCall32
 
81
        || pReq->requestType == VMMDevReq_HGCMCall64
 
82
#else
 
83
        || pReq->requestType == VMMDevReq_HGCMCall
 
84
#endif /* VBOX_WITH_64_BITS_GUESTS */
 
85
        || pReq->requestType == VMMDevReq_RegisterSharedModule
 
86
        || pReq->requestType == VMMDevReq_ReportGuestUserState
 
87
        || pReq->requestType == VMMDevReq_LogString
 
88
        || pReq->requestType == VMMDevReq_SetPointerShape
 
89
        || pReq->requestType == VMMDevReq_VideoSetVisibleRegion)
 
90
    {
 
91
        if (cbReq > VMMDEV_MAX_VMMDEVREQ_SIZE)
 
92
        {
 
93
            dprintf(("VbglGRVerify: VMMDevReq_LogString: buffer size %d too big\n", cbReq));
 
94
            return VERR_BUFFER_OVERFLOW; /* @todo is this error code ok? */
 
95
        }
 
96
    }
 
97
    else
 
98
    {
 
99
        dprintf(("VbglGRVerify: request size %d > buffer size %d\n", pReq->size, cbReq));
 
100
        return VERR_IO_BAD_LENGTH; /* @todo is this error code ok? */
 
101
    }
 
102
 
 
103
    return VINF_SUCCESS;
 
104
}
 
105
 
 
106
DECLVBGL(int) VbglGRAlloc (VMMDevRequestHeader **ppReq, uint32_t cbSize, VMMDevRequestType reqType)
 
107
{
 
108
    VMMDevRequestHeader *pReq;
 
109
    int rc = vbglR0Enter ();
 
110
 
 
111
    if (RT_FAILURE(rc))
 
112
        return rc;
 
113
 
 
114
    if (!ppReq || cbSize < sizeof (VMMDevRequestHeader))
 
115
    {
 
116
        dprintf(("VbglGRAlloc: Invalid parameter: ppReq = %p, cbSize = %u\n", ppReq, cbSize));
 
117
        return VERR_INVALID_PARAMETER;
 
118
    }
 
119
 
 
120
    pReq = (VMMDevRequestHeader *)VbglPhysHeapAlloc (cbSize);
 
121
    if (!pReq)
 
122
    {
 
123
        AssertMsgFailed(("VbglGRAlloc: no memory\n"));
 
124
        rc = VERR_NO_MEMORY;
 
125
    }
 
126
    else
 
127
    {
 
128
        memset(pReq, 0xAA, cbSize);
 
129
 
 
130
        pReq->size        = cbSize;
 
131
        pReq->version     = VMMDEV_REQUEST_HEADER_VERSION;
 
132
        pReq->requestType = reqType;
 
133
        pReq->rc          = VERR_GENERAL_FAILURE;
 
134
        pReq->reserved1   = 0;
 
135
        pReq->reserved2   = 0;
 
136
 
 
137
        *ppReq = pReq;
 
138
    }
 
139
 
 
140
    return rc;
 
141
}
 
142
 
 
143
DECLVBGL(int) VbglGRPerform (VMMDevRequestHeader *pReq)
 
144
{
 
145
    RTCCPHYS physaddr;
 
146
    int rc = vbglR0Enter ();
 
147
 
 
148
    if (RT_FAILURE(rc))
 
149
        return rc;
 
150
 
 
151
    if (!pReq)
 
152
        return VERR_INVALID_PARAMETER;
 
153
 
 
154
    physaddr = VbglPhysHeapGetPhysAddr (pReq);
 
155
    if (  !physaddr
 
156
       || (physaddr >> 32) != 0) /* Port IO is 32 bit. */
 
157
    {
 
158
        rc = VERR_VBGL_INVALID_ADDR;
 
159
    }
 
160
    else
 
161
    {
 
162
        ASMOutU32(g_vbgldata.portVMMDev + VMMDEV_PORT_OFF_REQUEST, (uint32_t)physaddr);
 
163
        /* Make the compiler aware that the host has changed memory. */
 
164
        ASMCompilerBarrier();
 
165
        rc = pReq->rc;
 
166
    }
 
167
    return rc;
 
168
}
 
169
 
 
170
DECLVBGL(void) VbglGRFree (VMMDevRequestHeader *pReq)
 
171
{
 
172
    int rc = vbglR0Enter ();
 
173
 
 
174
    if (RT_FAILURE(rc))
 
175
        return;
 
176
 
 
177
    VbglPhysHeapFree (pReq);
 
178
}
 
179