diff options
Diffstat (limited to 'include/VBox')
150 files changed, 10248 insertions, 5439 deletions
diff --git a/include/VBox/DevPCNet.h b/include/VBox/DevPCNet.h deleted file mode 100644 index 52e357ad..00000000 --- a/include/VBox/DevPCNet.h +++ /dev/null @@ -1,99 +0,0 @@ -/** @file - * DevPCNet - Private guest interface for the PCNet device. (DEV) - */ - -/* - * Copyright (C) 2008 Oracle Corporation - * - * This file is part of VirtualBox Open Source Edition (OSE), as - * available from http://www.virtualbox.org. This file is free software; - * you can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) as published by the Free Software - * Foundation, in version 2 as it comes in the "COPYING" file of the - * VirtualBox OSE distribution. VirtualBox OSE is distributed in the - * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. - * - * The contents of this file may alternatively be used under the terms - * of the Common Development and Distribution License Version 1.0 - * (CDDL) only, as it comes in the "COPYING.CDDL" file of the - * VirtualBox OSE distribution, in which case the provisions of the - * CDDL are applicable instead of those of the GPL. - * - * You may elect to license modified versions of this file under the - * terms and conditions of either the GPL or the CDDL or both. - */ - -#ifndef ___VBox_DevPCNet_h -#define ___VBox_DevPCNet_h - -#include <iprt/types.h> - -/** @defgroup grp_devpcnet AMD PCnet-PCI II / PCnet-FAST III (Am79C970A / Am79C973) Ethernet Controller Emulation. - * { - */ - -#define PCNET_GUEST_INTERFACE_VERSION (1) -#define PCNET_GUEST_SHARED_MEMORY_SIZE _512K -#define PCNET_GUEST_TX_DESCRIPTOR_SIZE 16 -#define PCNET_GUEST_RX_DESCRIPTOR_SIZE 16 -#define PCNET_GUEST_MAX_TX_DESCRIPTORS 128 -#define PCNET_GUEST_MAX_RX_DESCRIPTORS 256 -#define PCNET_GUEST_NIC_BUFFER_SIZE 1536 - -/* 256*16 + 128*16 + 256*1536 + 128*1536 = 582KB */ - -/** - * The header of the PCNet shared memory (VBox specific). - */ -#pragma pack(1) /* paranoia */ -typedef struct -{ - /** The size of the shared memory that's being used. - * (This is <= PCNET_GUEST_SHARED_MEMORY_SIZE.) */ - uint32_t cbUsed; - /** Version (PCNET_GUEST_INTERFACE_VERSION). */ - uint32_t u32Version; - /** Flags (See PCNET_GUEST_FLAGS_*). */ - uint32_t fFlags; - /** Align the following members to 64 bit. */ - uint32_t u32Alignment; - - union - { - struct - { - /** The size (in bytes) of the transmit descriptor array. */ - uint32_t cbTxDescriptors; - /** The size (in bytes) of the receive descriptor array. */ - uint32_t cbRxDescriptors; - /** Offset of the transmit descriptors relative to this header. */ - uint32_t offTxDescriptors; - /** Offset of the receive descriptors relative to this header. */ - uint32_t offRxDescriptors; - /** Offset of the transmit buffers relative to this header. */ - uint32_t offTxBuffers; - /** Offset of the receive buffers relative to this header. */ - uint32_t offRxBuffers; - } V1; - } V; - -} PCNETGUESTSHAREDMEMORY; -#pragma pack() -/** Pointer to the PCNet shared memory header. */ -typedef PCNETGUESTSHAREDMEMORY *PPCNETGUESTSHAREDMEMORY; -/** Const pointer to the PCNet shared memory header. */ -typedef const PCNETGUESTSHAREDMEMORY *PCPCNETGUESTSHAREDMEMORY; - -/** @name fFlags definitions - * @{ - */ -/** Host admits existence private PCNet interface. */ -#define PCNET_GUEST_FLAGS_ADMIT_HOST RT_BIT(0) -/** Guest admits using the private PCNet interface. */ -#define PCNET_GUEST_FLAGS_ADMIT_GUEST RT_BIT(1) -/** @} */ - -/** @} */ - -#endif - diff --git a/include/VBox/ExtPack/ExtPack.h b/include/VBox/ExtPack/ExtPack.h index 4e03b382..c9a6175a 100644 --- a/include/VBox/ExtPack/ExtPack.h +++ b/include/VBox/ExtPack/ExtPack.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -149,6 +149,9 @@ typedef struct VBOXEXTPACKHLP */ DECLR3CALLBACKMEMBER(VBOXEXTPACKCTX, pfnGetContext,(PCVBOXEXTPACKHLP pHlp)); + DECLR3CALLBACKMEMBER(int, pfnLoadHGCMService,(PCVBOXEXTPACKHLP pHlp, VBOXEXTPACK_IF_CS(IConsole) *pConsole, + const char *pszServiceLibrary, const char *pszServiceName)); + DECLR3CALLBACKMEMBER(int, pfnReserved1,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */ DECLR3CALLBACKMEMBER(int, pfnReserved2,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */ DECLR3CALLBACKMEMBER(int, pfnReserved3,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */ @@ -157,13 +160,12 @@ typedef struct VBOXEXTPACKHLP DECLR3CALLBACKMEMBER(int, pfnReserved6,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */ DECLR3CALLBACKMEMBER(int, pfnReserved7,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */ DECLR3CALLBACKMEMBER(int, pfnReserved8,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */ - DECLR3CALLBACKMEMBER(int, pfnReserved9,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */ /** End of structure marker (VBOXEXTPACKHLP_VERSION). */ uint32_t u32EndMarker; } VBOXEXTPACKHLP; /** Current version of the VBOXEXTPACKHLP structure. */ -#define VBOXEXTPACKHLP_VERSION RT_MAKE_U32(0, 1) +#define VBOXEXTPACKHLP_VERSION RT_MAKE_U32(1, 1) /** Pointer to the extension pack callback table. */ diff --git a/include/VBox/HGSMI/HGSMI.h b/include/VBox/HGSMI/HGSMI.h index 352487d9..c34f190c 100644 --- a/include/VBox/HGSMI/HGSMI.h +++ b/include/VBox/HGSMI/HGSMI.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2006-2008 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/HGSMI/HGSMIChSetup.h b/include/VBox/HGSMI/HGSMIChSetup.h index 5f116510..3084a76d 100644 --- a/include/VBox/HGSMI/HGSMIChSetup.h +++ b/include/VBox/HGSMI/HGSMIChSetup.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2009 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -44,9 +44,9 @@ AssertCompileSize(HGSMIBUFFERLOCATION, 8); /* HGSMI setup and configuration data structures. */ /* host->guest commands pending, should be accessed under FIFO lock only */ -#define HGSMIHOSTFLAGS_COMMANDS_PENDING 0x1 +#define HGSMIHOSTFLAGS_COMMANDS_PENDING 0x1 /* IRQ is fired, should be accessed under VGAState::lock only */ -#define HGSMIHOSTFLAGS_IRQ 0x2 +#define HGSMIHOSTFLAGS_IRQ 0x2 #ifdef VBOX_WITH_WDDM /* one or more guest commands is completed, should be accessed under FIFO lock only */ # define HGSMIHOSTFLAGS_GCOMMAND_COMPLETED 0x4 diff --git a/include/VBox/HGSMI/HGSMIChannels.h b/include/VBox/HGSMI/HGSMIChannels.h index 3b5bd6db..cde3430d 100644 --- a/include/VBox/HGSMI/HGSMIChannels.h +++ b/include/VBox/HGSMI/HGSMIChannels.h @@ -6,7 +6,7 @@ */ /* - * Copyright (C) 2006-2008 Oracle Corporation + * Copyright (C) 2006-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/Hardware/VBoxVideoVBE.h b/include/VBox/Hardware/VBoxVideoVBE.h index 405ab3d2..dc61d45d 100644 --- a/include/VBox/Hardware/VBoxVideoVBE.h +++ b/include/VBox/Hardware/VBoxVideoVBE.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2011 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -80,6 +80,7 @@ #define VGA_PORT_HGSMI_HOST 0x3b0 #define VGA_PORT_HGSMI_GUEST 0x3d0 +/* this should be in sync with monitorCount <xsd:maxInclusive value="8"/> in src/VBox/Main/xml/VirtualBox-settings-common.xsd */ #define VBOX_VIDEO_MAX_SCREENS 64 #endif /* !___VBox_Hardware_VBoxVideoVBE_h */ diff --git a/include/VBox/HostServices/GuestControlSvc.h b/include/VBox/HostServices/GuestControlSvc.h index d7864601..a173fbea 100644 --- a/include/VBox/HostServices/GuestControlSvc.h +++ b/include/VBox/HostServices/GuestControlSvc.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2011-2012 Oracle Corporation + * Copyright (C) 2011-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -41,6 +41,45 @@ namespace guestControl { * Typedefs, constants and inlines * ******************************************************************************/ +#define HGCMSERVICE_NAME "VBoxGuestControlSvc" + +/** Maximum number of concurrent guest sessions a VM can have. */ +#define VBOX_GUESTCTRL_MAX_SESSIONS 32 +/** Maximum number of concurrent guest objects (processes, files, ...) + * a guest session can have. */ +#define VBOX_GUESTCTRL_MAX_OBJECTS _2K +/** Maximum of callback contexts a guest process can have. */ +#define VBOX_GUESTCTRL_MAX_CONTEXTS _64K + +/** Base (start) of guest control session IDs. Session + * ID 0 is reserved for the root process which + * hosts all other guest session processes. */ +#define VBOX_GUESTCTRL_SESSION_ID_BASE 1 + +/** Builds a context ID out of the session ID, object ID and an + * increasing count. */ +#define VBOX_GUESTCTRL_CONTEXTID_MAKE(uSession, uObject, uCount) \ + ( (uint32_t)((uSession) & 0x1f) << 27 \ + | (uint32_t)((uObject) & 0x7ff) << 16 \ + | (uint32_t)((uCount) & 0xffff) \ + ) +/** Creates a context ID out of a session ID. */ +#define VBOX_GUESTCTRL_CONTEXTID_MAKE_SESSION(uSession) \ + ((uint32_t)((uSession) & 0x1f) << 27) +/** Gets the session ID out of a context ID. */ +#define VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(uContextID) \ + (((uContextID) >> 27) & 0x1f) +/** Gets the process ID out of a context ID. */ +#define VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(uContextID) \ + (((uContextID) >> 16) & 0x7ff) +/** Gets the context count of a process out of a context ID. */ +#define VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(uContextID) \ + ((uContextID) & 0xffff) +/** Filter context IDs by session. Can be used in conjunction + * with VbglR3GuestCtrlMsgFilterSet(). */ +#define VBOX_GUESTCTRL_FILTER_BY_SESSION(uSession) \ + (VBOX_GUESTCTRL_CONTEXTID_MAKE_SESSION(uSession) | 0xF8000000) + /** * Process status when executed in the guest. */ @@ -75,7 +114,26 @@ enum eProcessStatus #define INPUT_FLAG_EOF RT_BIT(0) /** - * Execution flags. + * Guest session creation flags. + * Only handled internally at the moment. + */ +#define SESSIONCREATIONFLAG_NONE 0x0 + +/** + * Guest directory removement flags. + * Essentially using what IPRT's RTDIRRMREC_F_ + * defines have to offer. + */ +#define DIRREMOVE_FLAG_RECURSIVE RT_BIT(0) +/** Delete the content of the directory and the directory itself. */ +#define DIRREMOVE_FLAG_CONTENT_AND_DIR RT_BIT(1) +/** Only delete the content of the directory, omit the directory it self. */ +#define DIRREMOVE_FLAG_CONTENT_ONLY RT_BIT(2) +/** Mask of valid flags. */ +#define DIRREMOVE_FLAG_VALID_MASK UINT32_C(0x00000003) + +/** + * Guest process creation flags. * Note: Has to match Main's ProcessCreateFlag_* flags! */ #define EXECUTEPROCESSFLAG_NONE 0x0 @@ -96,6 +154,20 @@ enum eProcessStatus #define OUTPUT_HANDLE_ID_STDERR 2 /** + * Guest path rename flags. + * Essentially using what IPRT's RTPATHRENAME_FLAGS_ + * defines have to offer. + */ +/** Do not replace anything. */ +#define PATHRENAME_FLAG_NO_REPLACE UINT32_C(0) +/** This will replace attempt any target which isn't a directory. */ +#define PATHRENAME_FLAG_REPLACE RT_BIT(0) +/** Don't allow symbolic links as part of the path. */ +#define PATHRENAME_FLAG_NO_SYMLINKS RT_BIT(1) +/** Mask of valid flags. */ +#define PATHRENAME_FLAG_VALID_MASK UINT32_C(0x00000002) + +/** * Defines for guest process array lengths. */ #define GUESTPROCESS_MAX_CMD_LEN _1K @@ -103,6 +175,7 @@ enum eProcessStatus #define GUESTPROCESS_MAX_ENV_LEN _64K #define GUESTPROCESS_MAX_USER_LEN 128 #define GUESTPROCESS_MAX_PASSWORD_LEN 128 +#define GUESTPROCESS_MAX_DOMAIN_LEN 256 /** @name Internal tools built into VBoxService which are used in order to * accomplish tasks host<->guest. @@ -134,95 +207,34 @@ enum eInputStatus }; /** - * The guest control callback data header. Must come first - * on each callback structure defined below this struct. + * Structure keeping the context of a host callback. */ -typedef struct VBoxGuestCtrlCallbackHeader +typedef struct VBoxGuestCtrlHostCbCtx { - /** Magic number to identify the structure. */ - uint32_t u32Magic; - /** Context ID to identify callback data. */ - uint32_t u32ContextID; -} CALLBACKHEADER; -typedef CALLBACKHEADER *PCALLBACKHEADER; + /** HGCM Function number. */ + uint32_t uFunction; + /** The context ID. */ + uint32_t uContextID; + /** Protocol version of this guest session. Might + * be 0 if not supported. */ + uint32_t uProtocol; -typedef struct VBoxGuestCtrlCallbackDataClientDisconnected -{ - /** Callback data header. */ - CALLBACKHEADER hdr; -} CALLBACKDATACLIENTDISCONNECTED; -typedef CALLBACKDATACLIENTDISCONNECTED *PCALLBACKDATACLIENTDISCONNECTED; +} VBOXGUESTCTRLHOSTCBCTX, *PVBOXGUESTCTRLHOSTCBCTX; /** - * Data structure to pass to the service extension callback. We use this to - * notify the host of changes to properties. - */ -typedef struct VBoxGuestCtrlCallbackDataExecStatus + * Structure for low level HGCM host callback from + * the guest. No deep copy. */ +typedef struct VBoxGuestCtrlHostCallback { - /** Callback data header. */ - CALLBACKHEADER hdr; - /** The process ID (PID). */ - uint32_t u32PID; - /** The process status. */ - uint32_t u32Status; - /** Optional flags, varies, based on u32Status. */ - uint32_t u32Flags; - /** Optional data buffer (not used atm). */ - void *pvData; - /** Size of optional data buffer (not used atm). */ - uint32_t cbData; -} CALLBACKDATAEXECSTATUS; -typedef CALLBACKDATAEXECSTATUS *PCALLBACKDATAEXECSTATUS; + VBoxGuestCtrlHostCallback(uint32_t cParms, VBOXHGCMSVCPARM paParms[]) + : mParms(cParms), mpaParms(paParms) { } -typedef struct VBoxGuestCtrlCallbackDataExecOut -{ - /** Callback data header. */ - CALLBACKHEADER hdr; - /** The process ID (PID). */ - uint32_t u32PID; - /** The handle ID (stdout/stderr). */ - uint32_t u32HandleId; - /** Optional flags (not used atm). */ - uint32_t u32Flags; - /** Optional data buffer. */ - void *pvData; - /** Size (in bytes) of optional data buffer. */ - uint32_t cbData; -} CALLBACKDATAEXECOUT; -typedef CALLBACKDATAEXECOUT *PCALLBACKDATAEXECOUT; + /** Number of HGCM parameters. */ + uint32_t mParms; + /** Actual HGCM parameters. */ + PVBOXHGCMSVCPARM mpaParms; -typedef struct VBoxGuestCtrlCallbackDataExecInStatus -{ - /** Callback data header. */ - CALLBACKHEADER hdr; - /** The process ID (PID). */ - uint32_t u32PID; - /** Current input status. */ - uint32_t u32Status; - /** Optional flags. */ - uint32_t u32Flags; - /** Size (in bytes) of processed input data. */ - uint32_t cbProcessed; -} CALLBACKDATAEXECINSTATUS; -typedef CALLBACKDATAEXECINSTATUS *PCALLBACKDATAEXECINSTATUS; - -enum eVBoxGuestCtrlCallbackDataMagic -{ - CALLBACKDATAMAGIC_CLIENT_DISCONNECTED = 0x08041984, - - CALLBACKDATAMAGIC_EXEC_STATUS = 0x26011982, - CALLBACKDATAMAGIC_EXEC_OUT = 0x11061949, - CALLBACKDATAMAGIC_EXEC_IN_STATUS = 0x19091951 -}; - -enum eVBoxGuestCtrlCallbackType -{ - VBOXGUESTCTRLCALLBACKTYPE_UNKNOWN = 0, - - VBOXGUESTCTRLCALLBACKTYPE_EXEC_START = 1, - VBOXGUESTCTRLCALLBACKTYPE_EXEC_OUTPUT = 2, - VBOXGUESTCTRLCALLBACKTYPE_EXEC_INPUT_STATUS = 3 -}; +} VBOXGUESTCTRLHOSTCALLBACK, *PVBOXGUESTCTRLHOSTCALLBACK; /** * The service functions which are callable by host. @@ -233,35 +245,40 @@ enum eHostFn * The host asks the client to cancel all pending waits and exit. */ HOST_CANCEL_PENDING_WAITS = 0, - - /* - * Execution handling. + /** + * The host wants to create a guest session. */ - + HOST_SESSION_CREATE = 20, + /** + * The host wants to close a guest session. + */ + HOST_SESSION_CLOSE = 21, /** * The host wants to execute something in the guest. This can be a command line * or starting a program. + ** Note: Legacy (VBox < 4.3) command. */ HOST_EXEC_CMD = 100, /** * Sends input data for stdin to a running process executed by HOST_EXEC_CMD. + ** Note: Legacy (VBox < 4.3) command. */ HOST_EXEC_SET_INPUT = 101, /** * Gets the current status of a running process, e.g. * new data on stdout/stderr, process terminated etc. + ** Note: Legacy (VBox < 4.3) command. */ HOST_EXEC_GET_OUTPUT = 102, - - /* - * Guest control 2.0 commands start in the 2xx number space. + /** + * Terminates a running guest process. */ - + HOST_EXEC_TERMINATE = 110, /** * Waits for a certain event to happen. This can be an input, output * or status event. */ - HOST_EXEC_WAIT_FOR = 210, + HOST_EXEC_WAIT_FOR = 120, /** * Opens a guest file. */ @@ -273,23 +290,41 @@ enum eHostFn /** * Reads from an opened guest file. */ - HOST_FILE_READ = 242, + HOST_FILE_READ = 250, + /** + * Reads from an opened guest file at + * a specified offset. + */ + HOST_FILE_READ_AT = 251, /** * Write to an opened guest file. */ - HOST_FILE_WRITE = 243, + HOST_FILE_WRITE = 260, + /** + * Write to an opened guest file at + * a specified offset. + */ + HOST_FILE_WRITE_AT = 261, /** * Changes the read & write position of an opened guest file. */ - HOST_FILE_SEEK = 244, + HOST_FILE_SEEK = 270, /** * Gets the current file position of an opened guest file. */ - HOST_FILE_TELL = 245 + HOST_FILE_TELL = 271, + /** + * Removes a directory on the guest. + */ + HOST_DIR_REMOVE = 320, + /** + * Renames a path on the guest. + */ + HOST_PATH_RENAME = 330 }; /** - * The service functions which are called by guest. The numbers may not change, + * The service functions which are called by guest. The numbers may not change, * so we hardcode them. */ enum eGuestFn @@ -298,7 +333,7 @@ enum eGuestFn * Guest waits for a new message the host wants to process on the guest side. * This is a blocking call and can be deferred. */ - GUEST_GET_HOST_MSG = 1, + GUEST_MSG_WAIT = 1, /** * Guest asks the host to cancel all pending waits the guest itself waits on. * This becomes necessary when the guest wants to quit but still waits for @@ -310,30 +345,52 @@ enum eGuestFn * detected when calling service::clientDisconnect(). */ GUEST_DISCONNECTED = 3, - - /* - * Process execution. - * The 1xx commands are legacy guest control commands and - * will be replaced by newer commands in the future. + /** + * Sets a message filter to only get messages which have a certain + * context ID scheme (that is, a specific session, object etc). + * Since VBox 4.3+. */ - + GUEST_MSG_FILTER_SET = 4, + /** + * Unsets (and resets) a previously set message filter. + */ + GUEST_MSG_FILTER_UNSET = 5, + /** + * Skips the current assigned message returned by GUEST_MSG_WAIT. + * Needed for telling the host service to not keep stale + * host commands in the queue. + */ + GUEST_MSG_SKIP = 10, + /** + * General reply to a host message. Only contains basic data + * along with a simple payload. + */ + GUEST_MSG_REPLY = 11, + /** + * General message for updating a pending progress for + * a long task. + */ + GUEST_MSG_PROGRESS_UPDATE = 12, + /** + * Guest reports back a guest session status. + */ + GUEST_SESSION_NOTIFY = 20, + /** + * Guest wants to close a specific guest session. + */ + GUEST_SESSION_CLOSE = 21, /** * Guests sends output from an executed process. */ - GUEST_EXEC_SEND_OUTPUT = 100, + GUEST_EXEC_OUTPUT = 100, /** * Guest sends a status update of an executed process to the host. */ - GUEST_EXEC_SEND_STATUS = 101, + GUEST_EXEC_STATUS = 101, /** * Guests sends an input status notification to the host. */ - GUEST_EXEC_SEND_INPUT_STATUS = 102, - - /* - * Guest control 2.0 commands start in the 2xx number space. - */ - + GUEST_EXEC_INPUT_STATUS = 102, /** * Guest notifies the host about some I/O event. This can be * a stdout, stderr or a stdin event. The actual event only tells @@ -341,24 +398,87 @@ enum eGuestFn * transmitting the data. */ GUEST_EXEC_IO_NOTIFY = 210, - /** Guest notifies the host about a file event, like opening, - * closing, seeking etc. + /** + * Guest notifies the host about some directory event. + */ + GUEST_DIR_NOTIFY = 230, + /** + * Guest notifies the host about some file event. */ GUEST_FILE_NOTIFY = 240 }; /** + * Guest session notification types. + * @sa HGCMMsgSessionNotify. + */ +enum GUEST_SESSION_NOTIFYTYPE +{ + GUEST_SESSION_NOTIFYTYPE_UNDEFINED = 0, + /** Something went wrong (see rc). */ + GUEST_SESSION_NOTIFYTYPE_ERROR = 1, + /** Guest session has been started. */ + GUEST_SESSION_NOTIFYTYPE_STARTED = 11, + /** Guest session terminated normally. */ + GUEST_SESSION_NOTIFYTYPE_TEN = 20, + /** Guest session terminated via signal. */ + GUEST_SESSION_NOTIFYTYPE_TES = 30, + /** Guest session terminated abnormally. */ + GUEST_SESSION_NOTIFYTYPE_TEA = 40, + /** Guest session timed out and was killed. */ + GUEST_SESSION_NOTIFYTYPE_TOK = 50, + /** Guest session timed out and was not killed successfully. */ + GUEST_SESSION_NOTIFYTYPE_TOA = 60, + /** Service/OS is stopping, process was killed. */ + GUEST_SESSION_NOTIFYTYPE_DWN = 150 +}; + +/** + * Guest directory notification types. + * @sa HGCMMsgDirNotify. + */ +enum GUEST_DIR_NOTIFYTYPE +{ + GUEST_DIR_NOTIFYTYPE_UNKNOWN = 0, + /** Something went wrong (see rc). */ + GUEST_DIR_NOTIFYTYPE_ERROR = 1, + /** Guest directory opened. */ + GUEST_DIR_NOTIFYTYPE_OPEN = 10, + /** Guest directory closed. */ + GUEST_DIR_NOTIFYTYPE_CLOSE = 20, + /** Information about an open guest directory. */ + GUEST_DIR_NOTIFYTYPE_INFO = 40, + /** Guest directory created. */ + GUEST_DIR_NOTIFYTYPE_CREATE = 70, + /** Guest directory deleted. */ + GUEST_DIR_NOTIFYTYPE_REMOVE = 80 +}; + +/** * Guest file notification types. + * @sa HGCMMsgFileNotify. */ -enum eGuestFileNotifyType +enum GUEST_FILE_NOTIFYTYPE { - GUESTFILENOTIFYTYPE_ERROR = 0, - GUESTFILENOTIFYTYPE_OPEN = 10, - GUESTFILENOTIFYTYPE_CLOSE = 20, - GUESTFILENOTIFYTYPE_READ = 30, - GUESTFILENOTIFYTYPE_WRITE = 40, - GUESTFILENOTIFYTYPE_SEEK = 50, - GUESTFILENOTIFYTYPE_TELL = 60 + GUEST_FILE_NOTIFYTYPE_UNKNOWN = 0, + GUEST_FILE_NOTIFYTYPE_ERROR = 1, + GUEST_FILE_NOTIFYTYPE_OPEN = 10, + GUEST_FILE_NOTIFYTYPE_CLOSE = 20, + GUEST_FILE_NOTIFYTYPE_READ = 30, + GUEST_FILE_NOTIFYTYPE_WRITE = 40, + GUEST_FILE_NOTIFYTYPE_SEEK = 50, + GUEST_FILE_NOTIFYTYPE_TELL = 60 +}; + +/** + * Guest file seeking types. Has to + * match FileSeekType in Main. + */ +enum GUEST_FILE_SEEKTYPE +{ + GUEST_FILE_SEEKTYPE_BEGIN = 1, + GUEST_FILE_SEEKTYPE_CURRENT = 4, + GUEST_FILE_SEEKTYPE_END = 8 }; /* @@ -366,10 +486,14 @@ enum eGuestFileNotifyType */ #pragma pack (1) -typedef struct VBoxGuestCtrlHGCMMsgType +/** + * Waits for a host command to arrive. The structure then contains the + * actual message type + required number of parameters needed to successfully + * retrieve that host command (in a next round). + */ +typedef struct HGCMMsgCmdWaitFor { VBoxGuestHGCMCallInfo hdr; - /** * The returned command the host wants to * run on the guest. @@ -377,22 +501,137 @@ typedef struct VBoxGuestCtrlHGCMMsgType HGCMFunctionParameter msg; /* OUT uint32_t */ /** Number of parameters the message needs. */ HGCMFunctionParameter num_parms; /* OUT uint32_t */ +} HGCMMsgCmdWaitFor; + +/** + * Asks the guest control host service to set a command + * filter for this client. This filter will then only + * deliver messages to the client which match the + * wanted context ID (ranges). + */ +typedef struct HGCMMsgCmdFilterSet +{ + VBoxGuestHGCMCallInfo hdr; + /** Value to filter for after filter mask + * was applied. */ + HGCMFunctionParameter value; /* IN uint32_t */ + /** Mask to add to the current set filter. */ + HGCMFunctionParameter mask_add; /* IN uint32_t */ + /** Mask to remove from the current set filter. */ + HGCMFunctionParameter mask_remove; /* IN uint32_t */ + /** Filter flags; currently unused. */ + HGCMFunctionParameter flags; /* IN uint32_t */ +} HGCMMsgCmdFilterSet; -} VBoxGuestCtrlHGCMMsgType; +/** + * Asks the guest control host service to disable + * a previously set message filter again. + */ +typedef struct HGCMMsgCmdFilterUnset +{ + VBoxGuestHGCMCallInfo hdr; + /** Unset flags; currently unused. */ + HGCMFunctionParameter flags; /* IN uint32_t */ +} HGCMMsgCmdFilterUnset; + +/** + * Asks the guest control host service to skip the + * currently assigned host command returned by + * VbglR3GuestCtrlMsgWaitFor(). + */ +typedef struct HGCMMsgCmdSkip +{ + VBoxGuestHGCMCallInfo hdr; + /** Skip flags; currently unused. */ + HGCMFunctionParameter flags; /* IN uint32_t */ +} HGCMMsgCmdSkip; /** * Asks the guest control host service to cancel all pending (outstanding) - * waits which were not processed yet. This is handy for a graceful shutdown. + * waits which were not processed yet. This is handy for a graceful shutdown. + */ +typedef struct HGCMMsgCancelPendingWaits +{ + VBoxGuestHGCMCallInfo hdr; +} HGCMMsgCancelPendingWaits; + +typedef struct HGCMMsgCmdReply +{ + VBoxGuestHGCMCallInfo hdr; + /** Context ID. */ + HGCMFunctionParameter context; + /** Message type. */ + HGCMFunctionParameter type; + /** IPRT result of overall operation. */ + HGCMFunctionParameter rc; + /** Optional payload to this reply. */ + HGCMFunctionParameter payload; +} HGCMMsgCmdReply; + +/** + * Creates a guest session. + */ +typedef struct HGCMMsgSessionOpen +{ + VBoxGuestHGCMCallInfo hdr; + /** Context ID. */ + HGCMFunctionParameter context; + /** The guest control protocol version this + * session is about to use. */ + HGCMFunctionParameter protocol; + /** The user name to run the guest session under. */ + HGCMFunctionParameter username; + /** The user's password. */ + HGCMFunctionParameter password; + /** The domain to run the guest session under. */ + HGCMFunctionParameter domain; + /** Session creation flags. */ + HGCMFunctionParameter flags; +} HGCMMsgSessionOpen; + +/** + * Terminates (closes) a guest session. + */ +typedef struct HGCMMsgSessionClose +{ + VBoxGuestHGCMCallInfo hdr; + /** Context ID. */ + HGCMFunctionParameter context; + /** Session termination flags. */ + HGCMFunctionParameter flags; +} HGCMMsgSessionClose; + +/** + * Reports back a guest session's status. */ -typedef struct VBoxGuestCtrlHGCMMsgCancelPendingWaits +typedef struct HGCMMsgSessionNotify +{ + VBoxGuestHGCMCallInfo hdr; + /** Context ID. */ + HGCMFunctionParameter context; + /** Notification type. */ + HGCMFunctionParameter type; + /** Notification result. */ + HGCMFunctionParameter result; +} HGCMMsgSessionNotify; + +typedef struct HGCMMsgPathRename { VBoxGuestHGCMCallInfo hdr; -} VBoxGuestCtrlHGCMMsgCancelPendingWaits; + /** UInt32: Context ID. */ + HGCMFunctionParameter context; + /** Source to rename. */ + HGCMFunctionParameter source; + /** Destination to rename source to. */ + HGCMFunctionParameter dest; + /** UInt32: Rename flags. */ + HGCMFunctionParameter flags; +} HGCMMsgPathRename; /** * Executes a command inside the guest. */ -typedef struct VBoxGuestCtrlHGCMMsgExecCmd +typedef struct HGCMMsgProcExec { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ @@ -411,22 +650,43 @@ typedef struct VBoxGuestCtrlHGCMMsgExecCmd HGCMFunctionParameter cb_env; /** The actual environment block. */ HGCMFunctionParameter env; - /** The user name to run the executed command under. */ - HGCMFunctionParameter username; - /** The user's password. */ - HGCMFunctionParameter password; - /** Timeout (in msec) which either specifies the - * overall lifetime of the process or how long it - * can take to bring the process up and running - - * (depends on the IGuest::ProcessCreateFlag_*). */ - HGCMFunctionParameter timeout; - -} VBoxGuestCtrlHGCMMsgExecCmd; + union + { + struct + { + /** The user name to run the executed command under. + * Only for VBox < 4.3 hosts. */ + HGCMFunctionParameter username; + /** The user's password. + * Only for VBox < 4.3 hosts. */ + HGCMFunctionParameter password; + /** Timeout (in msec) which either specifies the + * overall lifetime of the process or how long it + * can take to bring the process up and running - + * (depends on the IGuest::ProcessCreateFlag_*). */ + HGCMFunctionParameter timeout; + } v1; + struct + { + /** Timeout (in ms) which either specifies the + * overall lifetime of the process or how long it + * can take to bring the process up and running - + * (depends on the IGuest::ProcessCreateFlag_*). */ + HGCMFunctionParameter timeout; + /** Process priority. */ + HGCMFunctionParameter priority; + /** Number of process affinity blocks. */ + HGCMFunctionParameter num_affinity; + /** Pointer to process affinity blocks (uint64_t). */ + HGCMFunctionParameter affinity; + } v2; + } u; +} HGCMMsgProcExec; /** - * Injects input to a previously executed process via stdin. + * Sends input to a guest process via stdin. */ -typedef struct VBoxGuestCtrlHGCMMsgExecIn +typedef struct HGCMMsgProcInput { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ @@ -439,14 +699,13 @@ typedef struct VBoxGuestCtrlHGCMMsgExecIn HGCMFunctionParameter data; /** Actual size of data (in bytes). */ HGCMFunctionParameter size; - -} VBoxGuestCtrlHGCMMsgExecIn; +} HGCMMsgProcInput; /** * Retrieves ouptut from a previously executed process * from stdout/stderr. */ -typedef struct VBoxGuestCtrlHGCMMsgExecOut +typedef struct HGCMMsgProcOutput { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ @@ -459,14 +718,12 @@ typedef struct VBoxGuestCtrlHGCMMsgExecOut HGCMFunctionParameter flags; /** Data buffer. */ HGCMFunctionParameter data; - -} VBoxGuestCtrlHGCMMsgExecOut; +} HGCMMsgProcOutput; /** - * Reports the current status of a (just) started - * or terminated process. + * Reports the current status of a guest process. */ -typedef struct VBoxGuestCtrlHGCMMsgExecStatus +typedef struct HGCMMsgProcStatus { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ @@ -479,13 +736,12 @@ typedef struct VBoxGuestCtrlHGCMMsgExecStatus HGCMFunctionParameter flags; /** Optional data buffer (not used atm). */ HGCMFunctionParameter data; - -} VBoxGuestCtrlHGCMMsgExecStatus; +} HGCMMsgProcStatus; /** * Reports back the status of data written to a process. */ -typedef struct VBoxGuestCtrlHGCMMsgExecStatusIn +typedef struct HGCMMsgProcStatusInput { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ @@ -498,81 +754,119 @@ typedef struct VBoxGuestCtrlHGCMMsgExecStatusIn HGCMFunctionParameter flags; /** Data written. */ HGCMFunctionParameter written; - -} VBoxGuestCtrlHGCMMsgExecStatusIn; +} HGCMMsgProcStatusInput; /* * Guest control 2.0 messages. */ /** - * Reports back the currente I/O status of a guest process. + * Terminates a guest process. */ -typedef struct VBoxGuestCtrlHGCMMsgExecIONotify +typedef struct HGCMMsgProcTerminate { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ HGCMFunctionParameter context; - /** Data written. */ - HGCMFunctionParameter written; + /** The process ID (PID). */ + HGCMFunctionParameter pid; +} HGCMMsgProcTerminate; -} VBoxGuestCtrlHGCMMsgExecIONotify; +/** + * Waits for certain events to happen. + */ +typedef struct HGCMMsgProcWaitFor +{ + VBoxGuestHGCMCallInfo hdr; + /** Context ID. */ + HGCMFunctionParameter context; + /** The process ID (PID). */ + HGCMFunctionParameter pid; + /** Wait (event) flags. */ + HGCMFunctionParameter flags; + /** Timeout (in ms). */ + HGCMFunctionParameter timeout; +} HGCMMsgProcWaitFor; + +typedef struct HGCMMsgDirRemove +{ + VBoxGuestHGCMCallInfo hdr; + /** UInt32: Context ID. */ + HGCMFunctionParameter context; + /** Directory to remove. */ + HGCMFunctionParameter path; + /** UInt32: Removement flags. */ + HGCMFunctionParameter flags; +} HGCMMsgDirRemove; /** * Opens a guest file. */ -typedef struct VBoxGuestCtrlHGCMMsgFileOpen +typedef struct HGCMMsgFileOpen { VBoxGuestHGCMCallInfo hdr; - /** Context ID. */ + /** UInt32: Context ID. */ HGCMFunctionParameter context; /** File to open. */ HGCMFunctionParameter filename; /** Open mode. */ HGCMFunctionParameter openmode; - /** Disposition. */ + /** Disposition mode. */ HGCMFunctionParameter disposition; - /** Creation mode. */ + /** Sharing mode. */ + HGCMFunctionParameter sharing; + /** UInt32: Creation mode. */ HGCMFunctionParameter creationmode; - /** Offset. */ + /** UInt64: Initial offset. */ HGCMFunctionParameter offset; - -} VBoxGuestCtrlHGCMMsgFileOpen; +} HGCMMsgFileOpen; /** * Closes a guest file. */ -typedef struct VBoxGuestCtrlHGCMMsgFileClose +typedef struct HGCMMsgFileClose { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ HGCMFunctionParameter context; /** File handle to close. */ HGCMFunctionParameter handle; - -} VBoxGuestCtrlHGCMMsgFileClose; +} HGCMMsgFileClose; /** * Reads from a guest file. */ -typedef struct VBoxGuestCtrlHGCMMsgFileRead +typedef struct HGCMMsgFileRead { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ HGCMFunctionParameter context; /** File handle to read from. */ HGCMFunctionParameter handle; - /** Actual size of data (in bytes). */ + /** Size (in bytes) to read. */ HGCMFunctionParameter size; - /** Where to put the read data into. */ - HGCMFunctionParameter data; +} HGCMMsgFileRead; -} VBoxGuestCtrlHGCMMsgFileRead; +/** + * Reads at a specified offset from a guest file. + */ +typedef struct HGCMMsgFileReadAt +{ + VBoxGuestHGCMCallInfo hdr; + /** Context ID. */ + HGCMFunctionParameter context; + /** File handle to read from. */ + HGCMFunctionParameter handle; + /** Offset where to start reading from. */ + HGCMFunctionParameter offset; + /** Actual size of data (in bytes). */ + HGCMFunctionParameter size; +} HGCMMsgFileReadAt; /** * Writes to a guest file. */ -typedef struct VBoxGuestCtrlHGCMMsgFileWrite +typedef struct HGCMMsgFileWrite { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ @@ -583,13 +877,30 @@ typedef struct VBoxGuestCtrlHGCMMsgFileWrite HGCMFunctionParameter size; /** Data buffer to write to the file. */ HGCMFunctionParameter data; +} HGCMMsgFileWrite; -} VBoxGuestCtrlHGCMMsgFileWrite; +/** + * Writes at a specified offset to a guest file. + */ +typedef struct HGCMMsgFileWriteAt +{ + VBoxGuestHGCMCallInfo hdr; + /** Context ID. */ + HGCMFunctionParameter context; + /** File handle to write to. */ + HGCMFunctionParameter handle; + /** Offset where to start reading from. */ + HGCMFunctionParameter offset; + /** Actual size of data (in bytes). */ + HGCMFunctionParameter size; + /** Data buffer to write to the file. */ + HGCMFunctionParameter data; +} HGCMMsgFileWriteAt; /** * Seeks the read/write position of a guest file. */ -typedef struct VBoxGuestCtrlHGCMMsgFileSeek +typedef struct HGCMMsgFileSeek { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ @@ -600,48 +911,276 @@ typedef struct VBoxGuestCtrlHGCMMsgFileSeek HGCMFunctionParameter method; /** The seeking offset. */ HGCMFunctionParameter offset; - -} VBoxGuestCtrlHGCMMsgFileSeek; +} HGCMMsgFileSeek; /** * Tells the current read/write position of a guest file. */ -typedef struct VBoxGuestCtrlHGCMMsgFileTell +typedef struct HGCMMsgFileTell { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ HGCMFunctionParameter context; /** File handle to get the current position for. */ HGCMFunctionParameter handle; +} HGCMMsgFileTell; -} VBoxGuestCtrlHGCMMsgFileTell; +/****************************************************************************** +* HGCM replies from the guest. These are handled in Main's low-level HGCM * +* callbacks and dispatched to the appropriate guest object. * +******************************************************************************/ -typedef struct VBoxGuestCtrlHGCMMsgFileNotify +typedef struct HGCMReplyFileNotify { VBoxGuestHGCMCallInfo hdr; /** Context ID. */ HGCMFunctionParameter context; - /** The file handle. */ - HGCMFunctionParameter handle; /** Notification type. */ HGCMFunctionParameter type; - /** Notification payload. */ - HGCMFunctionParameter payload; - -} VBoxGuestCtrlHGCMMsgFileNotify; + /** IPRT result of overall operation. */ + HGCMFunctionParameter rc; + union + { + struct + { + /** Guest file handle. */ + HGCMFunctionParameter handle; + } open; + /** Note: Close does not have any additional data (yet). */ + struct + { + /** Actual data read (if any). */ + HGCMFunctionParameter data; + } read; + struct + { + /** How much data (in bytes) have been successfully written. */ + HGCMFunctionParameter written; + } write; + struct + { + HGCMFunctionParameter offset; + } seek; + struct + { + HGCMFunctionParameter offset; + } tell; + } u; +} HGCMReplyFileNotify; + +typedef struct HGCMReplyDirNotify +{ + VBoxGuestHGCMCallInfo hdr; + /** Context ID. */ + HGCMFunctionParameter context; + /** Notification type. */ + HGCMFunctionParameter type; + /** IPRT result of overall operation. */ + HGCMFunctionParameter rc; + union + { + struct + { + /** Directory information. */ + HGCMFunctionParameter objInfo; + } info; + struct + { + /** Guest directory handle. */ + HGCMFunctionParameter handle; + } open; + struct + { + /** Current read directory entry. */ + HGCMFunctionParameter entry; + /** Extended entry object information. Optional. */ + HGCMFunctionParameter objInfo; + } read; + } u; +} HGCMReplyDirNotify; #pragma pack () +/****************************************************************************** +* Callback data structures. * +******************************************************************************/ + +/** + * The guest control callback data header. Must come first + * on each callback structure defined below this struct. + */ +typedef struct CALLBACKDATA_HEADER +{ + /** Context ID to identify callback data. This is + * and *must* be the very first parameter in this + * structure to still be backwards compatible. */ + uint32_t uContextID; +} CALLBACKDATA_HEADER, *PCALLBACKDATA_HEADER; + +/* + * These structures make up the actual low level HGCM callback data sent from + * the guest back to the host. + */ + +typedef struct CALLBACKDATA_CLIENT_DISCONNECTED +{ + /** Callback data header. */ + CALLBACKDATA_HEADER hdr; +} CALLBACKDATA_CLIENT_DISCONNECTED, *PCALLBACKDATA_CLIENT_DISCONNECTED; + +typedef struct CALLBACKDATA_MSG_REPLY +{ + /** Callback data header. */ + CALLBACKDATA_HEADER hdr; + /** Notification type. */ + uint32_t uType; + /** Notification result. Note: int vs. uint32! */ + uint32_t rc; + /** Pointer to optional payload. */ + void *pvPayload; + /** Payload size (in bytes). */ + uint32_t cbPayload; +} CALLBACKDATA_MSG_REPLY, *PCALLBACKDATA_MSG_REPLY; + +typedef struct CALLBACKDATA_SESSION_NOTIFY +{ + /** Callback data header. */ + CALLBACKDATA_HEADER hdr; + /** Notification type. */ + uint32_t uType; + /** Notification result. Note: int vs. uint32! */ + uint32_t uResult; +} CALLBACKDATA_SESSION_NOTIFY, *PCALLBACKDATA_SESSION_NOTIFY; + +typedef struct CALLBACKDATA_PROC_STATUS +{ + /** Callback data header. */ + CALLBACKDATA_HEADER hdr; + /** The process ID (PID). */ + uint32_t uPID; + /** The process status. */ + uint32_t uStatus; + /** Optional flags, varies, based on u32Status. */ + uint32_t uFlags; + /** Optional data buffer (not used atm). */ + void *pvData; + /** Size of optional data buffer (not used atm). */ + uint32_t cbData; +} CALLBACKDATA_PROC_STATUS, *PCALLBACKDATA_PROC_STATUS; + +typedef struct CALLBACKDATA_PROC_OUTPUT +{ + /** Callback data header. */ + CALLBACKDATA_HEADER hdr; + /** The process ID (PID). */ + uint32_t uPID; + /** The handle ID (stdout/stderr). */ + uint32_t uHandle; + /** Optional flags (not used atm). */ + uint32_t uFlags; + /** Optional data buffer. */ + void *pvData; + /** Size (in bytes) of optional data buffer. */ + uint32_t cbData; +} CALLBACKDATA_PROC_OUTPUT, *PCALLBACKDATA_PROC_OUTPUT; + +typedef struct CALLBACKDATA_PROC_INPUT +{ + /** Callback data header. */ + CALLBACKDATA_HEADER hdr; + /** The process ID (PID). */ + uint32_t uPID; + /** Current input status. */ + uint32_t uStatus; + /** Optional flags. */ + uint32_t uFlags; + /** Size (in bytes) of processed input data. */ + uint32_t uProcessed; +} CALLBACKDATA_PROC_INPUT, *PCALLBACKDATA_PROC_INPUT; + /** - * Structure for buffering execution requests in the host service. + * General guest directory notification callback. */ -typedef struct VBoxGuestCtrlParamBuffer +typedef struct CALLBACKDATA_DIR_NOTIFY { - uint32_t uMsg; - uint32_t uParmCount; - PVBOXHGCMSVCPARM pParms; -} VBOXGUESTCTRPARAMBUFFER; -typedef VBOXGUESTCTRPARAMBUFFER *PVBOXGUESTCTRPARAMBUFFER; + /** Callback data header. */ + CALLBACKDATA_HEADER hdr; + /** Notification type. */ + uint32_t uType; + /** IPRT result of overall operation. */ + uint32_t rc; + union + { + struct + { + /** Size (in bytes) of directory information. */ + uint32_t cbObjInfo; + /** Pointer to directory information. */ + void *pvObjInfo; + } info; + struct + { + /** Guest directory handle. */ + uint32_t uHandle; + } open; + /** Note: Close does not have any additional data (yet). */ + struct + { + /** Size (in bytes) of directory entry information. */ + uint32_t cbEntry; + /** Pointer to directory entry information. */ + void *pvEntry; + /** Size (in bytes) of directory entry object information. */ + uint32_t cbObjInfo; + /** Pointer to directory entry object information. */ + void *pvObjInfo; + } read; + } u; +} CALLBACKDATA_DIR_NOTIFY, *PCALLBACKDATA_DIR_NOTIFY; + +/** + * General guest file notification callback. + */ +typedef struct CALLBACKDATA_FILE_NOTIFY +{ + /** Callback data header. */ + CALLBACKDATA_HEADER hdr; + /** Notification type. */ + uint32_t uType; + /** IPRT result of overall operation. */ + uint32_t rc; + union + { + struct + { + /** Guest file handle. */ + uint32_t uHandle; + } open; + /** Note: Close does not have any additional data (yet). */ + struct + { + /** How much data (in bytes) have been read. */ + uint32_t cbData; + /** Actual data read (if any). */ + void *pvData; + } read; + struct + { + /** How much data (in bytes) have been successfully written. */ + uint32_t cbWritten; + } write; + struct + { + /** New file offset after successful seek. */ + uint64_t uOffActual; + } seek; + struct + { + /** New file offset after successful tell. */ + uint64_t uOffActual; + } tell; + } u; +} CALLBACKDATA_FILE_NOTIFY, *PCALLBACKDATA_FILE_NOTIFY; } /* namespace guestControl */ diff --git a/include/VBox/HostServices/GuestPropertySvc.h b/include/VBox/HostServices/GuestPropertySvc.h index 7e99d2ec..baa54c82 100644 --- a/include/VBox/HostServices/GuestPropertySvc.h +++ b/include/VBox/HostServices/GuestPropertySvc.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/HostServices/Service.h b/include/VBox/HostServices/Service.h index 98e227a2..b82a04f9 100644 --- a/include/VBox/HostServices/Service.h +++ b/include/VBox/HostServices/Service.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/HostServices/VBoxClipboardExt.h b/include/VBox/HostServices/VBoxClipboardExt.h index a1392ec0..b9d52dbb 100644 --- a/include/VBox/HostServices/VBoxClipboardExt.h +++ b/include/VBox/HostServices/VBoxClipboardExt.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/HostServices/VBoxClipboardSvc.h b/include/VBox/HostServices/VBoxClipboardSvc.h index 0bb5607c..d8240e60 100644 --- a/include/VBox/HostServices/VBoxClipboardSvc.h +++ b/include/VBox/HostServices/VBoxClipboardSvc.h @@ -1,10 +1,9 @@ /** @file - * Shared Clipboard: - * Common header for host service and guest clients. + * Shared Clipboard - Common header for host service and guest clients. */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -43,9 +42,9 @@ /* * Supported data formats. Bit mask. */ -#define VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT 0x01 -#define VBOX_SHARED_CLIPBOARD_FMT_BITMAP 0x02 -#define VBOX_SHARED_CLIPBOARD_FMT_HTML 0x04 +#define VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT UINT32_C(0x01) +#define VBOX_SHARED_CLIPBOARD_FMT_BITMAP UINT32_C(0x02) +#define VBOX_SHARED_CLIPBOARD_FMT_HTML UINT32_C(0x04) /* * The service functions which are callable by host. diff --git a/include/VBox/HostServices/VBoxCrOpenGLSvc.h b/include/VBox/HostServices/VBoxCrOpenGLSvc.h index 150faac7..e09f9a2f 100644 --- a/include/VBox/HostServices/VBoxCrOpenGLSvc.h +++ b/include/VBox/HostServices/VBoxCrOpenGLSvc.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -31,6 +31,8 @@ #include <VBox/VMMDev.h> #include <VBox/VBoxGuest2.h> #include <VBox/hgcmsvc.h> +#include <VBox/VBoxVideo.h> +#include <VBox/VBoxVideoHost3D.h> /* crOpenGL host functions */ #define SHCRGL_HOST_FN_SET_CONSOLE (1) @@ -43,6 +45,11 @@ #endif #define SHCRGL_HOST_FN_VIEWPORT_CHANGED (15) #define SHCRGL_HOST_FN_SET_OUTPUT_REDIRECT (20) +#define SHCRGL_HOST_FN_DEV_RESIZE (22) +#define SHCRGL_HOST_FN_VIEWPORT_CHANGED2 (23) +#define SHCRGL_HOST_FN_TAKE_SCREENSHOT (24) +#define SHCRGL_HOST_FN_WINDOWS_SHOW (25) +#define SHCRGL_HOST_FN_CTL (26) /* crOpenGL guest functions */ #define SHCRGL_GUEST_FN_WRITE (2) #define SHCRGL_GUEST_FN_READ (3) @@ -52,22 +59,27 @@ #define SHCRGL_GUEST_FN_SET_PID (12) #define SHCRGL_GUEST_FN_WRITE_BUFFER (13) #define SHCRGL_GUEST_FN_WRITE_READ_BUFFERED (14) +#define SHCRGL_GUEST_FN_GET_CAPS (15) /* Parameters count */ #define SHCRGL_CPARMS_SET_CONSOLE (1) #define SHCRGL_CPARMS_SET_VM (1) -#define SHCRGL_CPARMS_SET_VISIBLE_REGION (2) +#define SHCRGL_CPARMS_SET_VISIBLE_REGION (1) #define SHCRGL_CPARMS_WRITE (1) #define SHCRGL_CPARMS_READ (2) #define SHCRGL_CPARMS_WRITE_READ (3) #define SHCRGL_CPARMS_SET_VERSION (2) #define SHCRGL_CPARMS_SCREEN_CHANGED (1) +#define SHCRGL_CPARMS_DEV_RESIZE (1) #define SHCRGL_CPARMS_INJECT (2) #define SHCRGL_CPARMS_SET_PID (1) #define SHCRGL_CPARMS_WRITE_BUFFER (4) #define SHCRGL_CPARMS_WRITE_READ_BUFFERED (3) #define SHCRGL_CPARMS_SET_OUTPUT_REDIRECT (1) +#define SHCRGL_CPARMS_CRCMD_NOTIFY_CMDS (0) #define SHCRGL_CPARMS_VIEWPORT_CHANGED (5) +#define SHCRGL_CPARMS_VIEWPORT_CHANGED2 (1) +#define SHCRGL_CPARMS_GET_CAPS (1) /* @todo Move to H3DOR.h begin */ @@ -89,7 +101,7 @@ typedef struct { int32_t x, int32_t y, uint32_t w, uint32_t h)); /* Update the window visible region. */ DECLR3CALLBACKMEMBER(void, H3DORVisibleRegion, (void *pvInstance, - uint32_t cRects, RTRECT *paRects)); + uint32_t cRects, const RTRECT *paRects)); /* A rendered 3D frame is ready. Format of pvData is "pszFormat" parameter of H3DORBegin. */ DECLR3CALLBACKMEMBER(void, H3DORFrame, (void *pvInstance, void *pvData, uint32_t cbData)); @@ -268,6 +280,17 @@ typedef struct } CRVBOXHGCMSETVERSION; +/** GUEST_FN_GET_CAPS Parameters structure. */ +typedef struct +{ + VBoxGuestHGCMCallInfo hdr; + + /** 32bit, out + * Caps + */ + HGCMFunctionParameter Caps; +} CRVBOXHGCMGETCAPS; + /** GUEST_FN_INJECT Parameters structure. */ typedef struct { @@ -343,4 +366,44 @@ typedef struct } CRVBOXHGCMWRITEREADBUFFERED; + +typedef struct +{ + VBVAINFOSCREEN Screen; + void *pvVRAM; +} CRVBOXHGCMDEVRESIZE; + +typedef struct +{ + uint32_t u32Screen; + uint32_t x; + uint32_t y; + uint32_t width; + uint32_t height; +} CRVBOXHGCMVIEWPORT; + +typedef DECLCALLBACKPTR(void, PFNCRSCREENSHOTREPORT)(void *pvCtx, uint32_t uScreen, + uint32_t x, uint32_t y, uint32_t uBitsPerPixel, + uint32_t uBytesPerLine, uint32_t uGuestWidth, uint32_t uGuestHeight, + uint8_t *pu8BufferAddress, uint64_t u64TimeStamp); + +typedef DECLCALLBACKPTR(bool, PFNCRSCREENSHOTBEGIN)(void *pvCtx, uint32_t uScreen, uint64_t u64TimeStamp); +typedef DECLCALLBACKPTR(void, PFNCRSCREENSHOTEND)(void *pvCtx, uint32_t uScreen, uint64_t u64TimeStamp); + +#define CRSCREEN_ALL (0xffffffff) + +typedef struct +{ + /* screen id or CRSCREEN_ALL to specify all enabled */ + uint32_t u32Screen; + uint32_t u32Width; + uint32_t u32Height; + uint32_t u32Pitch; + void *pvBuffer; + void *pvContext; + PFNCRSCREENSHOTBEGIN pfnScreenshotBegin; + PFNCRSCREENSHOTREPORT pfnScreenshotPerform; + PFNCRSCREENSHOTEND pfnScreenshotEnd; +} CRVBOXHGCMTAKESCREENSHOT; + #endif diff --git a/include/VBox/HostServices/VBoxHostChannel.h b/include/VBox/HostServices/VBoxHostChannel.h index e3c30337..bf3c1434 100644 --- a/include/VBox/HostServices/VBoxHostChannel.h +++ b/include/VBox/HostServices/VBoxHostChannel.h @@ -1,5 +1,5 @@ /** @file - * + * * Host Channel: the service definition. */ @@ -168,6 +168,13 @@ typedef struct VBOXHOSTCHANNELCALLBACKS */ DECLR3CALLBACKMEMBER(void, HostChannelCallbackEvent, (void *pvCallbacks, void *pvChannel, uint32_t u32Id, const void *pvEvent, uint32_t cbEvent)); + + /* The channel has been deleted by the provider. pvCallback will not be used anymore. + * + * @param pvCallbacks The callback context specified in HostChannelAttach. + * @param pvChannel The channel instance returned by HostChannelAttach. + */ + DECLR3CALLBACKMEMBER(void, HostChannelCallbackDeleted, (void *pvCallbacks, void *pvChannel)); } VBOXHOSTCHANNELCALLBACKS; typedef struct VBOXHOSTCHANNELINTERFACE diff --git a/include/VBox/HostServices/VBoxOGLOp.h b/include/VBox/HostServices/VBoxOGLOp.h index d125c254..02c80289 100644 --- a/include/VBox/HostServices/VBoxOGLOp.h +++ b/include/VBox/HostServices/VBoxOGLOp.h @@ -4,7 +4,7 @@ /* * - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/RemoteDesktop/VRDE.h b/include/VBox/RemoteDesktop/VRDE.h index d8a4946d..ba129862 100644 --- a/include/VBox/RemoteDesktop/VRDE.h +++ b/include/VBox/RemoteDesktop/VRDE.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2011 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -1135,11 +1135,9 @@ typedef struct _VRDEENTRYPOINTS_3 * which tells the server to bind to either of ports: * 3000, 3010, 3011, 3012, 4000. */ -#ifdef VBOX_WITH_VRDP_VIDEO_CHANNEL #define VRDE_QP_VIDEO_CHANNEL (5) #define VRDE_QP_VIDEO_CHANNEL_QUALITY (6) #define VRDE_QP_VIDEO_CHANNEL_SUNFLSH (7) -#endif /* VBOX_WITH_VRDP_VIDEO_CHANNEL */ #define VRDE_QP_FEATURE (8) /* VRDEFEATURE structure. Generic interface to query named VRDE properties. */ #define VRDE_SP_BASE 0x1000 diff --git a/include/VBox/RemoteDesktop/VRDEImage.h b/include/VBox/RemoteDesktop/VRDEImage.h index 929b08ba..951852db 100644 --- a/include/VBox/RemoteDesktop/VRDEImage.h +++ b/include/VBox/RemoteDesktop/VRDEImage.h @@ -208,16 +208,19 @@ typedef struct VRDEIMAGEINTERFACE /* * Notifications. - * u32Id paramater of VRDEIMAGECALLBACKS::VRDEImageCbNotify. + * u32Id parameter of VRDEIMAGECALLBACKS::VRDEImageCbNotify. */ -#define VRDE_IMAGE_NOTIFY_HANDLE_CREATE 1 /* Result of an image handle create request. */ +#define VRDE_IMAGE_NOTIFY_HANDLE_CREATE 1 /* Async result of VRDEImageHandleCreate. + * pvData: uint32_t = 0 if stream was not created, + * a non zero value otherwise. + */ typedef struct VRDEIMAGECALLBACKS { /** The header. */ VRDEINTERFACEHDR header; - /** Generic notification callback. Reserved for future use. + /** Generic notification callback. * * @param hServer The server instance handle. * @param pvContext The callbacks context specified in VRDEGetInterface. diff --git a/include/VBox/RemoteDesktop/VRDEInput.h b/include/VBox/RemoteDesktop/VRDEInput.h new file mode 100644 index 00000000..093591e2 --- /dev/null +++ b/include/VBox/RemoteDesktop/VRDEInput.h @@ -0,0 +1,220 @@ +/** @file + * VBox Remote Desktop Extension (VRDE) - Input interface. + */ + +/* + * Copyright (C) 2013 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL) only, as it comes in the "COPYING.CDDL" file of the + * VirtualBox OSE distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + */ + +#ifndef ___VBox_RemoteDesktop_VRDEInput_h +#define ___VBox_RemoteDesktop_VRDEInput_h + + +/* + * Interface for receiving input events from the client. + */ + +/* All structures in this file are packed. + * Everything is little-endian. + */ +#pragma pack(1) + +/* + * The application interface between VirtualBox and the VRDE server. + */ + +#define VRDE_INPUT_INTERFACE_NAME "VRDE::INPUT" + +/* + * Supported input methods. + */ +#define VRDE_INPUT_METHOD_TOUCH 1 + +/* + * fu32Flags for VRDEInputSetup + */ +#define VRDE_INPUT_F_ENABLE 1 + +/* The interface entry points. Interface version 1. */ +typedef struct VRDEINPUTINTERFACE +{ + /* The header. */ + VRDEINTERFACEHDR header; + + /* Tell the server that an input method will be used or disabled, etc. + * VRDECallbackInputSetup will be called with a result. + * + * @param hServer The VRDE server instance. + * @param u32Method The method VRDE_INPUT_METHOD_*. + * @param fu32Flags What to do with the method VRDE_INPUT_F_*. + * @param pvSetup Method specific parameters (optional). + * @param cbSetup Size of method specific parameters (optional). + */ + DECLR3CALLBACKMEMBER(void, VRDEInputSetup, (HVRDESERVER hServer, + uint32_t u32Method, + uint32_t fu32Flags, + const void *pvSetup, + uint32_t cbSetup)); +} VRDEINPUTINTERFACE; + + +/* Interface callbacks. */ +typedef struct VRDEINPUTCALLBACKS +{ + /* The header. */ + VRDEINTERFACEHDR header; + + /* VRDPInputSetup async result. + * + * @param pvCallback The callbacks context specified in VRDEGetInterface. + * @param rcSetup The result code of the request. + * @param u32Method The method VRDE_INPUT_METHOD_*. + * @param pvResult The result information. + * @param cbResult The size of buffer pointed by pvResult. + */ + DECLR3CALLBACKMEMBER(void, VRDECallbackInputSetup,(void *pvCallback, + int rcRequest, + uint32_t u32Method, + const void *pvResult, + uint32_t cbResult)); + + /* Input event. + * + * @param pvCallback The callbacks context specified in VRDEGetInterface. + * @param u32Method The method VRDE_INPUT_METHOD_*. + * @param pvEvent The event data. + * @param cbEvent The size of buffer pointed by pvEvent. + */ + DECLR3CALLBACKMEMBER(void, VRDECallbackInputEvent,(void *pvCallback, + uint32_t u32Method, + const void *pvEvent, + uint32_t cbEvent)); +} VRDEINPUTCALLBACKS; + + +/* + * Touch input definitions VRDE_INPUT_METHOD_TOUCH. + */ + +/* pvResult is not used */ + +/* RDPINPUT_HEADER */ +typedef struct VRDEINPUTHEADER +{ + uint16_t u16EventId; + uint32_t u32PDULength; +} VRDEINPUTHEADER; + +/* VRDEINPUTHEADER::u16EventId */ +#define VRDEINPUT_EVENTID_SC_READY 0x0001 +#define VRDEINPUT_EVENTID_CS_READY 0x0002 +#define VRDEINPUT_EVENTID_TOUCH 0x0003 +#define VRDEINPUT_EVENTID_SUSPEND_TOUCH 0x0004 +#define VRDEINPUT_EVENTID_RESUME_TOUCH 0x0005 +#define VRDEINPUT_EVENTID_DISMISS_HOVERING_CONTACT 0x0006 + +/* RDPINPUT_SC_READY_PDU */ +typedef struct VRDEINPUT_SC_READY_PDU +{ + VRDEINPUTHEADER header; + uint32_t u32ProtocolVersion; +} VRDEINPUT_SC_READY_PDU; + +#define VRDEINPUT_PROTOCOL_V1 0x00010000 +#define VRDEINPUT_PROTOCOL_V101 0x00010001 + +/* RDPINPUT_CS_READY_PDU */ +typedef struct VRDEINPUT_CS_READY_PDU +{ + VRDEINPUTHEADER header; + uint32_t u32Flags; + uint32_t u32ProtocolVersion; + uint16_t u16MaxTouchContacts; +} VRDEINPUT_CS_READY_PDU; + +#define VRDEINPUT_READY_FLAGS_SHOW_TOUCH_VISUALS 0x00000001 +#define VRDEINPUT_READY_FLAGS_DISABLE_TIMESTAMP_INJECTION 0x00000002 + +/* RDPINPUT_CONTACT_DATA */ +typedef struct VRDEINPUT_CONTACT_DATA +{ + uint8_t u8ContactId; + uint16_t u16FieldsPresent; + int32_t i32X; + int32_t i32Y; + uint32_t u32ContactFlags; + int16_t i16ContactRectLeft; + int16_t i16ContactRectTop; + int16_t i16ContactRectRight; + int16_t i16ContactRectBottom; + uint32_t u32Orientation; + uint32_t u32Pressure; +} VRDEINPUT_CONTACT_DATA; + +#define VRDEINPUT_CONTACT_DATA_CONTACTRECT_PRESENT 0x0001 +#define VRDEINPUT_CONTACT_DATA_ORIENTATION_PRESENT 0x0002 +#define VRDEINPUT_CONTACT_DATA_PRESSURE_PRESENT 0x0004 + +#define VRDEINPUT_CONTACT_FLAG_DOWN 0x0001 +#define VRDEINPUT_CONTACT_FLAG_UPDATE 0x0002 +#define VRDEINPUT_CONTACT_FLAG_UP 0x0004 +#define VRDEINPUT_CONTACT_FLAG_INRANGE 0x0008 +#define VRDEINPUT_CONTACT_FLAG_INCONTACT 0x0010 +#define VRDEINPUT_CONTACT_FLAG_CANCELED 0x0020 + +/* RDPINPUT_TOUCH_FRAME */ +typedef struct VRDEINPUT_TOUCH_FRAME +{ + uint16_t u16ContactCount; + uint64_t u64FrameOffset; + VRDEINPUT_CONTACT_DATA aContacts[1]; +} VRDEINPUT_TOUCH_FRAME; + +/* RDPINPUT_TOUCH_EVENT_PDU */ +typedef struct VRDEINPUT_TOUCH_EVENT_PDU +{ + VRDEINPUTHEADER header; + uint32_t u32EncodeTime; + uint16_t u16FrameCount; + VRDEINPUT_TOUCH_FRAME aFrames[1]; +} VRDEINPUT_TOUCH_EVENT_PDU; + +/* RDPINPUT_SUSPEND_TOUCH_PDU */ +typedef struct VRDEINPUT_SUSPEND_TOUCH_PDU +{ + VRDEINPUTHEADER header; +} VRDEINPUT_SUSPEND_TOUCH_PDU; + +/* RDPINPUT_RESUME_TOUCH_PDU */ +typedef struct VRDEINPUT_RESUME_TOUCH_PDU +{ + VRDEINPUTHEADER header; +} VRDEINPUT_RESUME_TOUCH_PDU; + +/* RDPINPUT_DISMISS_HOVERING_CONTACT_PDU */ +typedef struct VRDEINPUT_DISMISS_HOVERING_CONTACT_PDU +{ + VRDEINPUTHEADER header; + uint8_t u8ContactId; +} VRDEINPUT_DISMISS_HOVERING_CONTACT_PDU; + +#pragma pack() + +#endif diff --git a/include/VBox/RemoteDesktop/VRDEVideoIn.h b/include/VBox/RemoteDesktop/VRDEVideoIn.h new file mode 100644 index 00000000..0ff12f56 --- /dev/null +++ b/include/VBox/RemoteDesktop/VRDEVideoIn.h @@ -0,0 +1,1078 @@ +/** @file + * VBox Remote Desktop Extension (VRDE) - Video Input interface. + */ + +/* + * Copyright (C) 2012-2013 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL) only, as it comes in the "COPYING.CDDL" file of the + * VirtualBox OSE distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + */ + +#ifndef ___VBox_RemoteDesktop_VRDEVideoIn_h +#define ___VBox_RemoteDesktop_VRDEVideoIn_h + + +/* Define VRDE_VIDEOIN_WITH_VRDEINTERFACE to include the server VRDE interface parts. */ + +#ifdef VRDE_VIDEOIN_WITH_VRDEINTERFACE +#include <VBox/RemoteDesktop/VRDE.h> +#endif /* VRDE_VIDEOIN_WITH_VRDEINTERFACE */ + +#ifdef AssertCompileSize +#define ASSERTSIZE(type, size) AssertCompileSize(type, size); +#else +#define ASSERTSIZE(type, size) +#endif /* AssertCompileSize */ + + +/* + * Interface for accessing a video camera device on the client. + * + * Async callbacks are used for providing feedback, reporting errors, etc. + * + * Initial version supports: Camera + Processing Unit + Streaming Control. + * + * There are 2 modes: + * 1) The virtual WebCam is already attached to the guest. + * 2) The virtual WebCam will be attached when the client has it. + * + * Initially the mode 1 is supported. + * + * Mode 1 details: + * The WebCam has some fixed functionality, according to the descriptors, + * which has been already read by the guest. So some of functions will + * not work if the client does not support them. + * + * Mode 2 details: + * Virtual WebCam descriptors are built from the client capabilities. + * + * Similarly to the smartcard, the server will inform the ConsoleVRDE that there is a WebCam. + * ConsoleVRDE creates a VRDEVIDEOIN handle and forwards virtual WebCam requests to it. + * + * Interface with VBox. + * + * Virtual WebCam ConsoleVRDE VRDE + * + * Negotiate <-> + * <- VideoInDeviceNotify(Attached, DeviceId) + * -> GetDeviceDesc + * <- DeviceDesc + * 2 <- CreateCamera + * 2 CameraCreated -> + * + * CameraRequest -> Request -> + * Response <- <- Response <- Response + * Frame <- <- Frame <- Frame + * <- VideoInDeviceNotify(Detached, DeviceId) + * + * Unsupported requests fail. + * The Device Description received from the client may be used to validate WebCam requests + * in the ConsoleVRDE code, for example filter out unsupported requests. + * + */ + +/* All structures in this file are packed. + * Everything is little-endian. + */ +#pragma pack(1) + +/* + * The interface supports generic video input descriptors, capabilities and controls: + * * Descriptors + * + Interface + * - Input, Camera Terminal + * - Processing Unit + * + Video Streaming + * - Input Header + * - Payload Format + * - Video Frame + * - Still Image Frame + * * Video Control requests + * + Interface + * - Power Mode + * + Unit and Terminal + * camera + * - Scanning Mode (interlaced, progressive) + * - Auto-Exposure Mode + * - Auto-Exposure Priority + * - Exposure Time Absolute, Relative + * - Focus Absolute, Relative, Auto + * - Iris Absolute, Relative + * - Zoom Absolute, Relative + * - PanTilt Absolute, Relative + * - Roll Absolute, Relative + * - Privacy + * processing + * - Backlight Compensation + * - Brightness + * - Contrast + * - Gain + * - Power Line Frequency + * - Hue Manual, Auto + * - Saturation + * - Sharpness + * - Gamma + * - White Balance Temperature Manual, Auto + * - White Balance Component Manual, Auto + * - Digital Multiplier + * - Digital Multiplier Limit + * * Video Streaming requests + * + Interface + * - Synch Delay + * - Still Image Trigger + * - Generate Key Frame + * - Update Frame Segment + * - Stream Error Code + * + * + * Notes: + * * still capture uses a method similar to method 2, because the still frame will + * be send instead of video over the channel. + * Also the method 2 can be in principle emulated by both 1 and 3 on the client. + * However the client can initiate a still frame transfer, similar to hardware button trigger. + * * all control changes are async. + * * probe/commit are not used. The server can select a supported format/frame from the list. + * * no color matching. sRGB is the default. + * * most of constants are the same as in USB Video Class spec, but they are not the same and + * should be always converted. + */ + +/* + * The DEVICEDEC describes the device and provides a list of supported formats: + * VRDEVIDEOINDEVICEDESC + * VRDEVIDEOINFORMATDESC[0]; + * VRDEVIDEOINFRAMEDESC[0..N-1] + * VRDEVIDEOINFORMATDESC[1]; + * VRDEVIDEOINFRAMEDESC[0..M-1] + * ... + */ + +typedef struct VRDEVIDEOINDEVICEDESC +{ + uint16_t u16ObjectiveFocalLengthMin; + uint16_t u16ObjectiveFocalLengthMax; + uint16_t u16OcularFocalLength; + uint16_t u16MaxMultiplier; + uint32_t fu32CameraControls; /* VRDE_VIDEOIN_F_CT_CTRL_* */ + uint32_t fu32ProcessingControls; /* VRDE_VIDEOIN_F_PU_CTRL_* */ + uint8_t fu8DeviceCaps; /* VRDE_VIDEOIN_F_DEV_CAP_* */ + uint8_t u8NumFormats; /* Number of following VRDEVIDEOINFORMATDESC structures. */ + uint16_t cbExt; /* Size of the optional extended description. */ + /* An extended description may follow. */ + /* An array of VRDEVIDEOINFORMATDESC follows. */ +} VRDEVIDEOINDEVICEDESC; + +/* VRDEVIDEOINDEVICEDESC::fu32CameraControls */ +#define VRDE_VIDEOIN_F_CT_CTRL_SCANNING_MODE 0x00000001 /* D0: Scanning Mode */ +#define VRDE_VIDEOIN_F_CT_CTRL_AE_MODE 0x00000002 /* D1: Auto-Exposure Mode */ +#define VRDE_VIDEOIN_F_CT_CTRL_AE_PRIORITY 0x00000004 /* D2: Auto-Exposure Priority */ +#define VRDE_VIDEOIN_F_CT_CTRL_EXPOSURE_TIME_ABSOLUTE 0x00000008 /* D3: Exposure Time (Absolute) */ +#define VRDE_VIDEOIN_F_CT_CTRL_EXPOSURE_TIME_RELATIVE 0x00000010 /* D4: Exposure Time (Relative) */ +#define VRDE_VIDEOIN_F_CT_CTRL_FOCUS_ABSOLUTE 0x00000020 /* D5: Focus (Absolute) */ +#define VRDE_VIDEOIN_F_CT_CTRL_FOCUS_RELATIVE 0x00000040 /* D6: Focus (Relative) */ +#define VRDE_VIDEOIN_F_CT_CTRL_IRIS_ABSOLUTE 0x00000080 /* D7: Iris (Absolute) */ +#define VRDE_VIDEOIN_F_CT_CTRL_IRIS_RELATIVE 0x00000100 /* D8: Iris (Relative) */ +#define VRDE_VIDEOIN_F_CT_CTRL_ZOOM_ABSOLUTE 0x00000200 /* D9: Zoom (Absolute) */ +#define VRDE_VIDEOIN_F_CT_CTRL_ZOOM_RELATIVE 0x00000400 /* D10: Zoom (Relative) */ +#define VRDE_VIDEOIN_F_CT_CTRL_PANTILT_ABSOLUTE 0x00000800 /* D11: PanTilt (Absolute) */ +#define VRDE_VIDEOIN_F_CT_CTRL_PANTILT_RELATIVE 0x00001000 /* D12: PanTilt (Relative) */ +#define VRDE_VIDEOIN_F_CT_CTRL_ROLL_ABSOLUTE 0x00002000 /* D13: Roll (Absolute) */ +#define VRDE_VIDEOIN_F_CT_CTRL_ROLL_RELATIVE 0x00004000 /* D14: Roll (Relative) */ +#define VRDE_VIDEOIN_F_CT_CTRL_RESERVED1 0x00008000 /* D15: Reserved */ +#define VRDE_VIDEOIN_F_CT_CTRL_RESERVED2 0x00010000 /* D16: Reserved */ +#define VRDE_VIDEOIN_F_CT_CTRL_FOCUS_AUTO 0x00020000 /* D17: Focus, Auto */ +#define VRDE_VIDEOIN_F_CT_CTRL_PRIVACY 0x00040000 /* D18: Privacy */ + +/* VRDEVIDEOINDEVICEDESC::fu32ProcessingControls */ +#define VRDE_VIDEOIN_F_PU_CTRL_BRIGHTNESS 0x00000001 /* D0: Brightness */ +#define VRDE_VIDEOIN_F_PU_CTRL_CONTRAST 0x00000002 /* D1: Contrast */ +#define VRDE_VIDEOIN_F_PU_CTRL_HUE 0x00000004 /* D2: Hue */ +#define VRDE_VIDEOIN_F_PU_CTRL_SATURATION 0x00000008 /* D3: Saturation */ +#define VRDE_VIDEOIN_F_PU_CTRL_SHARPNESS 0x00000010 /* D4: Sharpness */ +#define VRDE_VIDEOIN_F_PU_CTRL_GAMMA 0x00000020 /* D5: Gamma */ +#define VRDE_VIDEOIN_F_PU_CTRL_WHITE_BALANCE_TEMPERATURE 0x00000040 /* D6: White Balance Temperature */ +#define VRDE_VIDEOIN_F_PU_CTRL_WHITE_BALANCE_COMPONENT 0x00000080 /* D7: White Balance Component */ +#define VRDE_VIDEOIN_F_PU_CTRL_BACKLIGHT_COMPENSATION 0x00000100 /* D8: Backlight Compensation */ +#define VRDE_VIDEOIN_F_PU_CTRL_GAIN 0x00000200 /* D9: Gain */ +#define VRDE_VIDEOIN_F_PU_CTRL_POWER_LINE_FREQUENCY 0x00000400 /* D10: Power Line Frequency */ +#define VRDE_VIDEOIN_F_PU_CTRL_HUE_AUTO 0x00000800 /* D11: Hue, Auto */ +#define VRDE_VIDEOIN_F_PU_CTRL_WHITE_BALANCE_TEMPERATURE_AUTO 0x00001000 /* D12: White Balance Temperature, Auto */ +#define VRDE_VIDEOIN_F_PU_CTRL_WHITE_BALANCE_COMPONENT_AUTO 0x00002000 /* D13: White Balance Component, Auto */ +#define VRDE_VIDEOIN_F_PU_CTRL_DIGITAL_MULTIPLIER 0x00004000 /* D14: Digital Multiplier */ +#define VRDE_VIDEOIN_F_PU_CTRL_DIGITAL_MULTIPLIER_LIMIT 0x00008000 /* D15: Digital Multiplier Limit */ + +/* VRDEVIDEOINDEVICEDESC::fu8DeviceCaps */ +#define VRDE_VIDEOIN_F_DEV_CAP_DYNAMICCHANGE 0x01 /* Whether dynamic format change is supported. */ +#define VRDE_VIDEOIN_F_DEV_CAP_TRIGGER 0x02 /* Whether hardware triggering is supported. */ +#define VRDE_VIDEOIN_F_DEV_CAP_TRIGGER_USAGE 0x04 /* 0 - still image, 1 - generic button event.*/ + +/* VRDEVIDEOINDEVICEDESC extended description. */ +typedef struct VRDEVIDEOINDEVICEEXT +{ + uint32_t fu32Fields; + /* One or more VRDEVIDEOINDEVICEFIELD follow. */ +} VRDEVIDEOINDEVICEEXT; + +typedef struct VRDEVIDEOINDEVICEFIELDHDR +{ + uint16_t cbField; /* Number of bytes reserved for this field. */ +} VRDEVIDEOINDEVICEFIELDHDR; + +/* VRDEVIDEOINDEVICEDESC::fu32Fields */ +#define VRDE_VIDEOIN_F_DEV_EXT_NAME 0x00000001 /* Utf8 device name. */ +#define VRDE_VIDEOIN_F_DEV_EXT_SERIAL 0x00000002 /* Utf8 device serial number. */ + +/* The video format descriptor. */ +typedef struct VRDEVIDEOINFORMATDESC +{ + uint16_t cbFormat; /* Size of the structure including cbFormat and format specific data. */ + uint8_t u8FormatId; /* The unique identifier of the format on the client. */ + uint8_t u8FormatType; /* MJPEG etc. VRDE_VIDEOIN_FORMAT_* */ + uint8_t u8FormatFlags; /* VRDE_VIDEOIN_F_FMT_* */ + uint8_t u8NumFrames; /* Number of following VRDEVIDEOINFRAMEDESC structures. */ + uint16_t u16Reserved; /* Must be set to 0. */ + /* Other format specific data may follow. */ + /* An array of VRDEVIDEOINFRAMEDESC follows. */ +} VRDEVIDEOINFORMATDESC; + +/* VRDEVIDEOINFORMATDESC::u8FormatType */ +#define VRDE_VIDEOIN_FORMAT_UNCOMPRESSED 0x04 +#define VRDE_VIDEOIN_FORMAT_MJPEG 0x06 +#define VRDE_VIDEOIN_FORMAT_MPEG2TS 0x0A +#define VRDE_VIDEOIN_FORMAT_DV 0x0C +#define VRDE_VIDEOIN_FORMAT_FRAME_BASED 0x10 +#define VRDE_VIDEOIN_FORMAT_STREAM_BASED 0x12 + +/* VRDEVIDEOINFORMATDESC::u8FormatFlags. */ +#define VRDE_VIDEOIN_F_FMT_GENERATEKEYFRAME 0x01 /* Supports Generate Key Frame */ +#define VRDE_VIDEOIN_F_FMT_UPDATEFRAMESEGMENT 0x02 /* Supports Update Frame Segment */ +#define VRDE_VIDEOIN_F_FMT_COPYPROTECT 0x04 /* If duplication should be restricted. */ +#define VRDE_VIDEOIN_F_FMT_COMPQUALITY 0x08 /* If the format supports an adjustable compression quality. */ + +typedef struct VRDEVIDEOINFRAMEDESC +{ + uint16_t cbFrame; /* Size of the structure including cbFrame and frame specific data. */ + uint8_t u8FrameId; /* The unique identifier of the frame for the corresponding format on the client. */ + uint8_t u8FrameFlags; + uint16_t u16Width; + uint16_t u16Height; + uint32_t u32NumFrameIntervals; /* The number of supported frame intervals. */ + uint32_t u32MinFrameInterval; /* Shortest frame interval supported (at highest frame rate), in 100ns units. */ + uint32_t u32MaxFrameInterval; /* Longest frame interval supported (at lowest frame rate), in 100ns units. */ + /* Supported frame intervals (in 100ns units) follow if VRDE_VIDEOIN_F_FRM_DISCRETE_INTERVALS is set. + * uint32_t au32FrameIntervals[u32NumFrameIntervals]; + */ + /* Supported min and max bitrate in bits per second follow if VRDE_VIDEOIN_F_FRM_BITRATE is set. + * uint32_t u32MinBitRate; + * uint32_t u32MaxBitRate; + */ + /* Other frame specific data may follow. */ +} VRDEVIDEOINFRAMEDESC; + +/* VRDEVIDEOINFRAMEDESC::u8FrameFlags. */ +#define VRDE_VIDEOIN_F_FRM_STILL 0x01 /* If still images are supported for this frame. */ +#define VRDE_VIDEOIN_F_FRM_DISCRETE_INTERVALS 0x02 /* If the discrete intervals list is included. */ +#define VRDE_VIDEOIN_F_FRM_BITRATE 0x04 /* If the bitrate fields are included. */ +#define VRDE_VIDEOIN_F_FRM_SIZE_OF_FIELDS 0x08 /* If the all optional fields start with 16 bit field size. */ + +/* + * Controls. + * + * The same structures are used for both SET and GET requests. + * Requests are async. A callback is invoked, when the client returns a reply. + * A control change notification also uses these structures. + * + * If a control request can not be fulfilled, then VRDE_VIDEOIN_CTRLHDR_F_FAIL + * will be set and u8Status contains the error code. This replaces the VC_REQUEST_ERROR_CODE_CONTROL. + * + * If the client receives an unsupported control, then the client must ignore it. + * That is the control request must not affect the client in any way. + * The client may send a VRDEVIDEOINCTRLHDR response for the unsupported control with: + * u16ControlSelector = the received value; + * u16RequestType = the received value; + * u16ParmSize = 0; + * u8Flags = VRDE_VIDEOIN_CTRLHDR_F_FAIL; + * u8Status = VRDE_VIDEOIN_CTRLHDR_STATUS_INVALIDCONTROL; + */ + +typedef struct VRDEVIDEOINCTRLHDR +{ + uint16_t u16ControlSelector; /* VRDE_VIDEOIN_CTRLSEL_* */ + uint16_t u16RequestType; /* VRDE_VIDEOIN_CTRLREQ_* */ + uint16_t u16ParmSize; /* The size of the control specific parameters. */ + uint8_t u8Flags; /* VRDE_VIDEOIN_CTRLHDR_F_* */ + uint8_t u8Status; /* VRDE_VIDEOIN_CTRLHDR_STATUS_* */ + /* Control specific data follows. */ +} VRDEVIDEOINCTRLHDR; + +/* Control request types: VRDEVIDEOINCTRLHDR::u16RequestType. */ +#define VRDE_VIDEOIN_CTRLREQ_UNDEFINED 0x00 +#define VRDE_VIDEOIN_CTRLREQ_SET_CUR 0x01 +#define VRDE_VIDEOIN_CTRLREQ_GET_CUR 0x81 +#define VRDE_VIDEOIN_CTRLREQ_GET_MIN 0x82 +#define VRDE_VIDEOIN_CTRLREQ_GET_MAX 0x83 +#define VRDE_VIDEOIN_CTRLREQ_GET_RES 0x84 +#define VRDE_VIDEOIN_CTRLREQ_GET_LEN 0x85 +#define VRDE_VIDEOIN_CTRLREQ_GET_INFO 0x86 +#define VRDE_VIDEOIN_CTRLREQ_GET_DEF 0x87 + +/* VRDEVIDEOINCTRLHDR::u8Flags */ +#define VRDE_VIDEOIN_CTRLHDR_F_NOTIFY 0x01 /* Control change notification, the attribute is derived from u16RequestType and F_FAIL. */ +#define VRDE_VIDEOIN_CTRLHDR_F_FAIL 0x02 /* The operation failed. Error code is in u8Status. */ + +/* VRDEVIDEOINCTRLHDR::u8Status if the VRDE_VIDEOIN_CTRLHDR_F_FAIL is set. */ +#define VRDE_VIDEOIN_CTRLHDR_STATUS_SUCCESS 0x00 /**/ +#define VRDE_VIDEOIN_CTRLHDR_STATUS_NOTREADY 0x01 /* Not ready */ +#define VRDE_VIDEOIN_CTRLHDR_STATUS_WRONGSTATE 0x02 /* Wrong state */ +#define VRDE_VIDEOIN_CTRLHDR_STATUS_POWER 0x03 /* Power */ +#define VRDE_VIDEOIN_CTRLHDR_STATUS_OUTOFRANGE 0x04 /* Out of range */ +#define VRDE_VIDEOIN_CTRLHDR_STATUS_INVALIDUNIT 0x05 /* Invalid unit */ +#define VRDE_VIDEOIN_CTRLHDR_STATUS_INVALIDCONTROL 0x06 /* Invalid control */ +#define VRDE_VIDEOIN_CTRLHDR_STATUS_INVALIDREQUEST 0x07 /* Invalid request */ +#define VRDE_VIDEOIN_CTRLHDR_STATUS_UNKNOWN 0xFF /* Unknown */ + +/* Control selectors. 16 bit. High byte is the category. Low byte is the identifier.*/ +#ifdef RT_MAKE_U16 +#define VRDE_VIDEOIN_CTRLSEL_MAKE(Lo, Hi) RT_MAKE_U16(Lo, Hi) +#else +#define VRDE_VIDEOIN_CTRLSEL_MAKE(Lo, Hi) ((uint16_t)( (uint16_t)((uint8_t)(Hi)) << 8 | (uint8_t)(Lo) )) +#endif + +#define VRDE_VIDEOIN_CTRLSEL_VC(a) VRDE_VIDEOIN_CTRLSEL_MAKE(a, 0x01) +#define VRDE_VIDEOIN_CTRLSEL_CT(a) VRDE_VIDEOIN_CTRLSEL_MAKE(a, 0x02) +#define VRDE_VIDEOIN_CTRLSEL_PU(a) VRDE_VIDEOIN_CTRLSEL_MAKE(a, 0x03) +#define VRDE_VIDEOIN_CTRLSEL_VS(a) VRDE_VIDEOIN_CTRLSEL_MAKE(a, 0x04) +#define VRDE_VIDEOIN_CTRLSEL_HW(a) VRDE_VIDEOIN_CTRLSEL_MAKE(a, 0x05) +#define VRDE_VIDEOIN_CTRLSEL_PROT(a) VRDE_VIDEOIN_CTRLSEL_MAKE(a, 0x06) + +#define VRDE_VIDEOIN_CTRLSEL_VC_VIDEO_POWER_MODE_CONTROL VRDE_VIDEOIN_CTRLSEL_VC(0x01) + +#define VRDE_VIDEOIN_CTRLSEL_CT_UNDEFINED VRDE_VIDEOIN_CTRLSEL_CT(0x00) +#define VRDE_VIDEOIN_CTRLSEL_CT_SCANNING_MODE VRDE_VIDEOIN_CTRLSEL_CT(0x01) +#define VRDE_VIDEOIN_CTRLSEL_CT_AE_MODE VRDE_VIDEOIN_CTRLSEL_CT(0x02) +#define VRDE_VIDEOIN_CTRLSEL_CT_AE_PRIORITY VRDE_VIDEOIN_CTRLSEL_CT(0x03) +#define VRDE_VIDEOIN_CTRLSEL_CT_EXPOSURE_TIME_ABSOLUTE VRDE_VIDEOIN_CTRLSEL_CT(0x04) +#define VRDE_VIDEOIN_CTRLSEL_CT_EXPOSURE_TIME_RELATIVE VRDE_VIDEOIN_CTRLSEL_CT(0x05) +#define VRDE_VIDEOIN_CTRLSEL_CT_FOCUS_ABSOLUTE VRDE_VIDEOIN_CTRLSEL_CT(0x06) +#define VRDE_VIDEOIN_CTRLSEL_CT_FOCUS_RELATIVE VRDE_VIDEOIN_CTRLSEL_CT(0x07) +#define VRDE_VIDEOIN_CTRLSEL_CT_FOCUS_AUTO VRDE_VIDEOIN_CTRLSEL_CT(0x08) +#define VRDE_VIDEOIN_CTRLSEL_CT_IRIS_ABSOLUTE VRDE_VIDEOIN_CTRLSEL_CT(0x09) +#define VRDE_VIDEOIN_CTRLSEL_CT_IRIS_RELATIVE VRDE_VIDEOIN_CTRLSEL_CT(0x0A) +#define VRDE_VIDEOIN_CTRLSEL_CT_ZOOM_ABSOLUTE VRDE_VIDEOIN_CTRLSEL_CT(0x0B) +#define VRDE_VIDEOIN_CTRLSEL_CT_ZOOM_RELATIVE VRDE_VIDEOIN_CTRLSEL_CT(0x0C) +#define VRDE_VIDEOIN_CTRLSEL_CT_PANTILT_ABSOLUTE VRDE_VIDEOIN_CTRLSEL_CT(0x0D) +#define VRDE_VIDEOIN_CTRLSEL_CT_PANTILT_RELATIVE VRDE_VIDEOIN_CTRLSEL_CT(0x0E) +#define VRDE_VIDEOIN_CTRLSEL_CT_ROLL_ABSOLUTE VRDE_VIDEOIN_CTRLSEL_CT(0x0F) +#define VRDE_VIDEOIN_CTRLSEL_CT_ROLL_RELATIVE VRDE_VIDEOIN_CTRLSEL_CT(0x10) +#define VRDE_VIDEOIN_CTRLSEL_CT_PRIVACY VRDE_VIDEOIN_CTRLSEL_CT(0x11) + +#define VRDE_VIDEOIN_CTRLSEL_PU_UNDEFINED VRDE_VIDEOIN_CTRLSEL_PU(0x00) +#define VRDE_VIDEOIN_CTRLSEL_PU_BACKLIGHT_COMPENSATION VRDE_VIDEOIN_CTRLSEL_PU(0x01) +#define VRDE_VIDEOIN_CTRLSEL_PU_BRIGHTNESS VRDE_VIDEOIN_CTRLSEL_PU(0x02) +#define VRDE_VIDEOIN_CTRLSEL_PU_CONTRAST VRDE_VIDEOIN_CTRLSEL_PU(0x03) +#define VRDE_VIDEOIN_CTRLSEL_PU_GAIN VRDE_VIDEOIN_CTRLSEL_PU(0x04) +#define VRDE_VIDEOIN_CTRLSEL_PU_POWER_LINE_FREQUENCY VRDE_VIDEOIN_CTRLSEL_PU(0x05) +#define VRDE_VIDEOIN_CTRLSEL_PU_HUE VRDE_VIDEOIN_CTRLSEL_PU(0x06) +#define VRDE_VIDEOIN_CTRLSEL_PU_SATURATION VRDE_VIDEOIN_CTRLSEL_PU(0x07) +#define VRDE_VIDEOIN_CTRLSEL_PU_SHARPNESS VRDE_VIDEOIN_CTRLSEL_PU(0x08) +#define VRDE_VIDEOIN_CTRLSEL_PU_GAMMA VRDE_VIDEOIN_CTRLSEL_PU(0x09) +#define VRDE_VIDEOIN_CTRLSEL_PU_WHITE_BALANCE_TEMPERATURE VRDE_VIDEOIN_CTRLSEL_PU(0x0A) +#define VRDE_VIDEOIN_CTRLSEL_PU_WHITE_BALANCE_TEMPERATURE_AUTO VRDE_VIDEOIN_CTRLSEL_PU(0x0B) +#define VRDE_VIDEOIN_CTRLSEL_PU_WHITE_BALANCE_COMPONENT VRDE_VIDEOIN_CTRLSEL_PU(0x0C) +#define VRDE_VIDEOIN_CTRLSEL_PU_WHITE_BALANCE_COMPONENT_AUTO VRDE_VIDEOIN_CTRLSEL_PU(0x0D) +#define VRDE_VIDEOIN_CTRLSEL_PU_DIGITAL_MULTIPLIER VRDE_VIDEOIN_CTRLSEL_PU(0x0E) +#define VRDE_VIDEOIN_CTRLSEL_PU_DIGITAL_MULTIPLIER_LIMIT VRDE_VIDEOIN_CTRLSEL_PU(0x0F) +#define VRDE_VIDEOIN_CTRLSEL_PU_HUE_AUTO VRDE_VIDEOIN_CTRLSEL_PU(0x10) +#define VRDE_VIDEOIN_CTRLSEL_PU_ANALOG_VIDEO_STANDARD VRDE_VIDEOIN_CTRLSEL_PU(0x11) +#define VRDE_VIDEOIN_CTRLSEL_PU_ANALOG_LOCK_STATUS VRDE_VIDEOIN_CTRLSEL_PU(0x12) + +#define VRDE_VIDEOIN_CTRLSEL_VS_UNDEFINED VRDE_VIDEOIN_CTRLSEL_VS(0x00) +#define VRDE_VIDEOIN_CTRLSEL_VS_SETUP VRDE_VIDEOIN_CTRLSEL_VS(0x01) +#define VRDE_VIDEOIN_CTRLSEL_VS_OFF VRDE_VIDEOIN_CTRLSEL_VS(0x02) +#define VRDE_VIDEOIN_CTRLSEL_VS_ON VRDE_VIDEOIN_CTRLSEL_VS(0x03) +#define VRDE_VIDEOIN_CTRLSEL_VS_STILL_IMAGE_TRIGGER VRDE_VIDEOIN_CTRLSEL_VS(0x05) +#define VRDE_VIDEOIN_CTRLSEL_VS_STREAM_ERROR_CODE VRDE_VIDEOIN_CTRLSEL_VS(0x06) +#define VRDE_VIDEOIN_CTRLSEL_VS_GENERATE_KEY_FRAME VRDE_VIDEOIN_CTRLSEL_VS(0x07) +#define VRDE_VIDEOIN_CTRLSEL_VS_UPDATE_FRAME_SEGMENT VRDE_VIDEOIN_CTRLSEL_VS(0x08) +#define VRDE_VIDEOIN_CTRLSEL_VS_SYNCH_DELAY VRDE_VIDEOIN_CTRLSEL_VS(0x09) + +#define VRDE_VIDEOIN_CTRLSEL_HW_BUTTON VRDE_VIDEOIN_CTRLSEL_HW(0x01) + +#define VRDE_VIDEOIN_CTRLSEL_PROT_PING VRDE_VIDEOIN_CTRLSEL_PROT(0x01) +#define VRDE_VIDEOIN_CTRLSEL_PROT_SAMPLING VRDE_VIDEOIN_CTRLSEL_PROT(0x02) +#define VRDE_VIDEOIN_CTRLSEL_PROT_FRAMES VRDE_VIDEOIN_CTRLSEL_PROT(0x03) + +typedef struct VRDEVIDEOINCTRL_VIDEO_POWER_MODE +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8DevicePowerMode; +} VRDEVIDEOINCTRL_VIDEO_POWER_MODE; + +typedef struct VRDEVIDEOINCTRL_CT_SCANNING_MODE +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8ScanningMode; +} VRDEVIDEOINCTRL_CT_SCANNING_MODE; + +typedef struct VRDEVIDEOINCTRL_CT_AE_MODE +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8AutoExposureMode; +} VRDEVIDEOINCTRL_CT_AE_MODE; + +typedef struct VRDEVIDEOINCTRL_CT_AE_PRIORITY +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8AutoExposurePriority; +} VRDEVIDEOINCTRL_CT_AE_PRIORITY; + +typedef struct VRDEVIDEOINCTRL_CT_EXPOSURE_TIME_ABSOLUTE +{ + VRDEVIDEOINCTRLHDR hdr; + uint32_t u32ExposureTimeAbsolute; +} VRDEVIDEOINCTRL_CT_EXPOSURE_TIME_ABSOLUTE; + +typedef struct VRDEVIDEOINCTRL_CT_EXPOSURE_TIME_RELATIVE +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8ExposureTimeRelative; +} VRDEVIDEOINCTRL_CT_EXPOSURE_TIME_RELATIVE; + +typedef struct VRDEVIDEOINCTRL_CT_FOCUS_ABSOLUTE +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16FocusAbsolute; +} VRDEVIDEOINCTRL_CT_FOCUS_ABSOLUTE; + +typedef struct VRDEVIDEOINCTRL_CT_FOCUS_RELATIVE +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8FocusRelative; + uint8_t u8Speed; +} VRDEVIDEOINCTRL_CT_FOCUS_RELATIVE; + +typedef struct VRDEVIDEOINCTRL_CT_FOCUS_AUTO +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8FocusAuto; +} VRDEVIDEOINCTRL_CT_FOCUS_AUTO; + +typedef struct VRDEVIDEOINCTRL_CT_IRIS_ABSOLUTE +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16IrisAbsolute; +} VRDEVIDEOINCTRL_CT_IRIS_ABSOLUTE; + +typedef struct VRDEVIDEOINCTRL_CT_IRIS_RELATIVE +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8IrisRelative; +} VRDEVIDEOINCTRL_CT_IRIS_RELATIVE; + +typedef struct VRDEVIDEOINCTRL_CT_ZOOM_ABSOLUTE +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16ZoomAbsolute; +} VRDEVIDEOINCTRL_CT_ZOOM_ABSOLUTE; + +typedef struct VRDEVIDEOINCTRL_CT_ZOOM_RELATIVE +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8Zoom; + uint8_t u8DigitalZoom; + uint8_t u8Speed; +} VRDEVIDEOINCTRL_CT_ZOOM_RELATIVE; + +typedef struct VRDEVIDEOINCTRL_CT_PANTILT_ABSOLUTE +{ + VRDEVIDEOINCTRLHDR hdr; + uint32_t u32PanAbsolute; + uint32_t u32TiltAbsolute; +} VRDEVIDEOINCTRL_CT_PANTILT_ABSOLUTE; + +typedef struct VRDEVIDEOINCTRL_CT_PANTILT_RELATIVE +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8PanRelative; + uint8_t u8PanSpeed; + uint8_t u8TiltRelative; + uint8_t u8TiltSpeed; +} VRDEVIDEOINCTRL_CT_PANTILT_RELATIVE; + +typedef struct VRDEVIDEOINCTRL_CT_ROLL_ABSOLUTE +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16RollAbsolute; +} VRDEVIDEOINCTRL_CT_ROLL_ABSOLUTE; + +typedef struct VRDEVIDEOINCTRL_CT_ROLL_RELATIVE +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8RollRelative; + uint8_t u8Speed; +} VRDEVIDEOINCTRL_CT_ROLL_RELATIVE; + +typedef struct VRDEVIDEOINCTRL_CT_PRIVACY_MODE +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8Privacy; +} VRDEVIDEOINCTRL_CT_PRIVACY_MODE; + +typedef struct VRDEVIDEOINCTRL_PU_BACKLIGHT_COMPENSATION +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16BacklightCompensation; +} VRDEVIDEOINCTRL_PU_BACKLIGHT_COMPENSATION; + +typedef struct VRDEVIDEOINCTRL_PU_BRIGHTNESS +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16Brightness; +} VRDEVIDEOINCTRL_PU_BRIGHTNESS; + +typedef struct VRDEVIDEOINCTRL_PU_CONTRAST +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16Contrast; +} VRDEVIDEOINCTRL_PU_CONTRAST; + +typedef struct VRDEVIDEOINCTRL_PU_GAIN +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16Gain; +} VRDEVIDEOINCTRL_PU_GAIN; + +typedef struct VRDEVIDEOINCTRL_PU_POWER_LINE_FREQUENCY +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16PowerLineFrequency; +} VRDEVIDEOINCTRL_PU_POWER_LINE_FREQUENCY; + +typedef struct VRDEVIDEOINCTRL_PU_HUE +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16Hue; +} VRDEVIDEOINCTRL_PU_HUE; + +typedef struct VRDEVIDEOINCTRL_PU_HUE_AUTO +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8HueAuto; +} VRDEVIDEOINCTRL_PU_HUE_AUTO; + +typedef struct VRDEVIDEOINCTRL_PU_SATURATION +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16Saturation; +} VRDEVIDEOINCTRL_PU_SATURATION; + +typedef struct VRDEVIDEOINCTRL_PU_SHARPNESS +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16Sharpness; +} VRDEVIDEOINCTRL_PU_SHARPNESS; + +typedef struct VRDEVIDEOINCTRL_PU_GAMMA +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16Gamma; +} VRDEVIDEOINCTRL_PU_GAMMA; + +typedef struct VRDEVIDEOINCTRL_PU_WHITE_BALANCE_TEMPERATURE +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16WhiteBalanceTemperature; +} VRDEVIDEOINCTRL_PU_WHITE_BALANCE_TEMPERATURE; + +typedef struct VRDEVIDEOINCTRL_PU_WHITE_BALANCE_TEMPERATURE_AUTO +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8WhiteBalanceTemperatureAuto; +} VRDEVIDEOINCTRL_PU_WHITE_BALANCE_TEMPERATURE_AUTO; + +typedef struct VRDEVIDEOINCTRL_PU_WHITE_BALANCE_COMPONENT +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16WhiteBalanceBlue; + uint16_t u16WhiteBalanceRed; +} VRDEVIDEOINCTRL_PU_WHITE_BALANCE_COMPONENT; + +typedef struct VRDEVIDEOINCTRL_PU_WHITE_BALANCE_COMPONENT_AUTO +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8WhiteBalanceComponentAuto; +} VRDEVIDEOINCTRL_PU_WHITE_BALANCE_COMPONENT_AUTO; + +typedef struct VRDEVIDEOINCTRL_PU_DIGITAL_MULTIPLIER +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16MultiplierStep; +} VRDEVIDEOINCTRL_PU_DIGITAL_MULTIPLIER; + +typedef struct VRDEVIDEOINCTRL_PU_DIGITAL_MULTIPLIER_LIMIT +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16MultiplierLimit; +} VRDEVIDEOINCTRL_PU_DIGITAL_MULTIPLIER_LIMIT; + +typedef struct VRDEVIDEOINCTRL_PU_ANALOG_VIDEO_STANDARD +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8VideoStandard; +} VRDEVIDEOINCTRL_PU_ANALOG_VIDEO_STANDARD; + +typedef struct VRDEVIDEOINCTRL_PU_ANALOG_LOCK_STATUS +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8Status; +} VRDEVIDEOINCTRL_PU_ANALOG_LOCK_STATUS; + +/* Set streaming parameters. The actual streaming will be enabled by VS_ON. */ +#define VRDEVIDEOINCTRL_F_VS_SETUP_FID 0x01 +#define VRDEVIDEOINCTRL_F_VS_SETUP_EOF 0x02 + +typedef struct VRDEVIDEOINCTRL_VS_SETUP +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8FormatId; /* The format id on the client: VRDEVIDEOINFORMATDESC::u8FormatId. */ + uint8_t u8FramingInfo; /* VRDEVIDEOINCTRL_F_VS_SETUP_*. Set by the client. */ + uint16_t u16Width; + uint16_t u16Height; + uint32_t u32FrameInterval; /* Frame interval in 100 ns units, 0 means a still image capture. + * The client may choose a different interval if this value is + * not supported. + */ + uint16_t u16CompQuality; /* 0 .. 10000 = 0 .. 100%. + * Applicable if the format has VRDE_VIDEOIN_F_FMT_COMPQUALITY, + * otherwise this field is ignored. + */ + uint16_t u16Delay; /* Latency in ms from video data capture to presentation on the channel. + * Set by the client, read by the server. + */ + uint32_t u32ClockFrequency; /* @todo just all clocks in 100ns units? */ +} VRDEVIDEOINCTRL_VS_SETUP; + +/* Stop sending video frames. */ +typedef struct VRDEVIDEOINCTRL_VS_OFF +{ + VRDEVIDEOINCTRLHDR hdr; +} VRDEVIDEOINCTRL_VS_OFF; + +/* Start sending video frames with parameters set by VS_SETUP. */ +typedef struct VRDEVIDEOINCTRL_VS_ON +{ + VRDEVIDEOINCTRLHDR hdr; +} VRDEVIDEOINCTRL_VS_ON; + +typedef struct VRDEVIDEOINCTRL_VS_STILL_IMAGE_TRIGGER +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8Trigger; +} VRDEVIDEOINCTRL_VS_STILL_IMAGE_TRIGGER; + +typedef struct VRDEVIDEOINCTRL_VS_STREAM_ERROR_CODE +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8StreamErrorCode; +} VRDEVIDEOINCTRL_VS_STREAM_ERROR_CODE; + +typedef struct VRDEVIDEOINCTRL_VS_GENERATE_KEY_FRAME +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8GenerateKeyFrame; +} VRDEVIDEOINCTRL_VS_GENERATE_KEY_FRAME; + +typedef struct VRDEVIDEOINCTRL_VS_UPDATE_FRAME_SEGMENT +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8StartFrameSegment; + uint8_t u8EndFrameSegment; +} VRDEVIDEOINCTRL_VS_UPDATE_FRAME_SEGMENT; + +typedef struct VRDEVIDEOINCTRL_VS_SYNCH_DELAY +{ + VRDEVIDEOINCTRLHDR hdr; + uint16_t u16Delay; +} VRDEVIDEOINCTRL_VS_SYNCH_DELAY; + +/* A hardware button was pressed/released on the device. */ +typedef struct VRDEVIDEOINCTRL_HW_BUTTON +{ + VRDEVIDEOINCTRLHDR hdr; + uint8_t u8Pressed; +} VRDEVIDEOINCTRL_HW_BUTTON; + +typedef struct VRDEVIDEOINCTRL_PROT_PING +{ + VRDEVIDEOINCTRLHDR hdr; + uint32_t u32Timestamp; /* Set in the request and the same value must be send back in the response. */ +} VRDEVIDEOINCTRL_PROT_PING; + +typedef struct VRDEVIDEOINCTRL_PROT_SAMPLING +{ + VRDEVIDEOINCTRLHDR hdr; + uint32_t fu32SampleStart; /* Which parameters must be sampled VRDEVIDEOINCTRL_F_PROT_SAMPLING_*. */ + uint32_t fu32SampleStop; /* Which parameters to disable VRDEVIDEOINCTRL_F_PROT_SAMPLING_*. + * If both Start and Stop is set, then restart the sampling. + */ + uint32_t u32PeriodMS; /* Sampling period in milliseconds. Applies to all samples in fu32SampleStart. + * Not mandatory, the actual sampling period may be different. + */ +} VRDEVIDEOINCTRL_PROT_SAMPLING; + +#define VRDEVIDEOINCTRL_F_PROT_SAMPLING_FRAMES_SOURCE 0x00000001 /* Periodic VRDEVIDEOINCTRL_PROT_FRAMES samples */ +#define VRDEVIDEOINCTRL_F_PROT_SAMPLING_FRAMES_CLIENT_OUT 0x00000002 /* Periodic VRDEVIDEOINCTRL_PROT_FRAMES samples */ + +typedef struct VRDEVIDEOINCTRL_PROT_FRAMES +{ + VRDEVIDEOINCTRLHDR hdr; /* Note: the message should be sent as VRDE_VIDEOIN_FN_CONTROL_NOTIFY. */ + uint32_t u32Sample; /* Which sample is this, one of VRDEVIDEOINCTRL_F_PROT_SAMPLING_*. */ + uint32_t u32TimestampMS; /* When the period started, milliseconds since the start of sampling. */ + uint32_t u32PeriodMS; /* Actual period during which the frames were counted in milliseconds. + * This may be different from VRDEVIDEOINCTRL_PROT_SAMPLING::u32PeriodMS. + */ + uint32_t u32FramesCount; /* How many frames per u32PeriodMS milliseconds. */ +} VRDEVIDEOINCTRL_PROT_FRAMES; + + +/* + * Payload transfers. How frames are sent to the server: + * the client send a PAYLOAD packet, which has the already set format. + * The server enables the transfers by sending VRDEVIDEOINCTRL_VS_ON. + */ + +/* Payload header */ +typedef struct VRDEVIDEOINPAYLOADHDR +{ + uint8_t u8HeaderLength; /* Entire header. */ + uint8_t u8HeaderInfo; /* VRDE_VIDEOIN_PAYLOAD_F_* */ + uint32_t u32PresentationTime; /* @todo define this */ + uint32_t u32SourceTimeClock; /* @todo At the moment when the frame was sent to the channel. + * Allows the server to measure clock drift. + */ + uint16_t u16Reserved; /* @todo */ +} VRDEVIDEOINPAYLOADHDR; + +/* VRDEVIDEOINPAYLOADHDR::u8HeaderInfo */ +#define VRDE_VIDEOIN_PAYLOAD_F_FID 0x01 /* Frame ID */ +#define VRDE_VIDEOIN_PAYLOAD_F_EOF 0x02 /* End of Frame */ +#define VRDE_VIDEOIN_PAYLOAD_F_PTS 0x04 /* Presentation Time */ +#define VRDE_VIDEOIN_PAYLOAD_F_SCR 0x08 /* Source Clock Reference */ +#define VRDE_VIDEOIN_PAYLOAD_F_RES 0x10 /* Reserved */ +#define VRDE_VIDEOIN_PAYLOAD_F_STI 0x20 /* Still Image */ +#define VRDE_VIDEOIN_PAYLOAD_F_ERR 0x40 /* Error */ +#define VRDE_VIDEOIN_PAYLOAD_F_EOH 0x80 /* End of header */ + + +/* + * The network channel specification. + */ + +/* + * The protocol uses a dynamic RDP channel. + * Everything is little-endian. + */ + +/* The dynamic RDP channel name. */ +#define VRDE_VIDEOIN_CHANNEL "RVIDEOIN" + +/* Major functions. */ +#define VRDE_VIDEOIN_FN_NEGOTIATE 0x0000 /* Version and capabilities check. */ +#define VRDE_VIDEOIN_FN_NOTIFY 0x0001 /* Device attach/detach from the client. */ +#define VRDE_VIDEOIN_FN_DEVICEDESC 0x0002 /* Query device description. */ +#define VRDE_VIDEOIN_FN_CONTROL 0x0003 /* Control the device and start/stop video input. + * This function is used for sending a request and + * the corresponding response. + */ +#define VRDE_VIDEOIN_FN_CONTROL_NOTIFY 0x0004 /* The client reports a control change, etc. + * This function indicated that the message is + * not a response to a CONTROL request. + */ +#define VRDE_VIDEOIN_FN_FRAME 0x0005 /* Frame from the client. */ + +/* Status codes. */ +#define VRDE_VIDEOIN_STATUS_SUCCESS 0 /* Function completed successfully. */ +#define VRDE_VIDEOIN_STATUS_FAILED 1 /* Failed for some reason. */ + +typedef struct VRDEVIDEOINMSGHDR +{ + uint32_t u32Length; /* The length of the message in bytes, including the header. */ + uint32_t u32DeviceId; /* The client's device id. */ + uint32_t u32MessageId; /* Unique id assigned by the server. The client must send a reply with the same id. + * If the client initiates a request, then this must be set to 0, because there is + * currently no client requests, which would require a response from the server. + */ + uint16_t u16FunctionId; /* VRDE_VIDEOIN_FN_* */ + uint16_t u16Status; /* The result of a request. VRDE_VIDEOIN_STATUS_*. */ +} VRDEVIDEOINMSGHDR; +ASSERTSIZE(VRDEVIDEOINMSGHDR, 16) + +/* + * VRDE_VIDEOIN_FN_NEGOTIATE + * + * Sent by the server when the channel is established and the client replies with its capabilities. + */ +#define VRDE_VIDEOIN_NEGOTIATE_VERSION 1 + +/* VRDEVIDEOINMSG_NEGOTIATE::fu32Capabilities */ +#define VRDE_VIDEOIN_NEGOTIATE_CAP_VOID 0x00000000 +#define VRDE_VIDEOIN_NEGOTIATE_CAP_PROT 0x00000001 /* Supports VRDE_VIDEOIN_CTRLSEL_PROT_* controls. */ + +typedef struct VRDEVIDEOINMSG_NEGOTIATE +{ + VRDEVIDEOINMSGHDR hdr; + uint32_t u32Version; /* VRDE_VIDEOIN_NEGOTIATE_VERSION */ + uint32_t fu32Capabilities; /* VRDE_VIDEOIN_NEGOTIATE_CAP_* */ +} VRDEVIDEOINMSG_NEGOTIATE; + +/* + * VRDE_VIDEOIN_FN_NOTIFY + * + * Sent by the client when a webcam is attached or detached. + * The client must send the ATTACH notification for each webcam, which is + * already connected to the client when the VIDEOIN channel is established. + */ +#define VRDE_VIDEOIN_NOTIFY_EVENT_ATTACH 0 +#define VRDE_VIDEOIN_NOTIFY_EVENT_DETACH 1 +#define VRDE_VIDEOIN_NOTIFY_EVENT_NEGOTIATE 2 /* Negotiate again with the client. */ + +typedef struct VRDEVIDEOINMSG_NOTIFY +{ + VRDEVIDEOINMSGHDR hdr; + uint32_t u32NotifyEvent; /* VRDE_VIDEOIN_NOTIFY_EVENT_* */ + /* Event specific data may follow. The underlying protocol provides the length of the message. */ +} VRDEVIDEOINMSG_NOTIFY; + +/* + * VRDE_VIDEOIN_FN_DEVICEDESC + * + * The server queries the description of a device. + */ +typedef struct VRDEVIDEOINMSG_DEVICEDESC_REQ +{ + VRDEVIDEOINMSGHDR hdr; +} VRDEVIDEOINMSG_DEVICEDESC_REQ; + +typedef struct VRDEVIDEOINMSG_DEVICEDESC_RSP +{ + VRDEVIDEOINMSGHDR hdr; + VRDEVIDEOINDEVICEDESC Device; + /* + * VRDEVIDEOINFORMATDESC[0] + * VRDEVIDEOINFRAMEDESC[0] + * ... + * VRDEVIDEOINFRAMEDESC[n] + * VRDEVIDEOINFORMATDESC[1] + * VRDEVIDEOINFRAMEDESC[0] + * ... + * VRDEVIDEOINFRAMEDESC[m] + * ... + */ +} VRDEVIDEOINMSG_DEVICEDESC_RSP; + +/* + * VRDE_VIDEOIN_FN_CONTROL + * VRDE_VIDEOIN_FN_CONTROL_NOTIFY + * + * Either sent by the server or by the client as a notification/response. + * If sent by the client as a notification, then hdr.u32MessageId must be 0. + */ +typedef struct VRDEVIDEOINMSG_CONTROL +{ + VRDEVIDEOINMSGHDR hdr; + VRDEVIDEOINCTRLHDR Control; + /* Control specific data may follow. */ +} VRDEVIDEOINMSG_CONTROL; + +/* + * VRDE_VIDEOIN_FN_FRAME + * + * The client sends a video/still frame in the already specified format. + * hdr.u32MessageId must be 0. + */ +typedef struct VRDEVIDEOINMSG_FRAME +{ + VRDEVIDEOINMSGHDR hdr; + VRDEVIDEOINPAYLOADHDR Payload; + /* The frame data follow. */ +} VRDEVIDEOINMSG_FRAME; + + +#ifdef VRDE_VIDEOIN_WITH_VRDEINTERFACE +/* + * The application interface between VirtualBox and the VRDE server. + */ + +#define VRDE_VIDEOIN_INTERFACE_NAME "VIDEOIN" + +typedef struct VRDEVIDEOINDEVICEHANDLE +{ + uint32_t u32ClientId; + uint32_t u32DeviceId; +} VRDEVIDEOINDEVICEHANDLE; + +/* The VRDE server video input interface entry points. Interface version 1. */ +typedef struct VRDEVIDEOININTERFACE +{ + /* The header. */ + VRDEINTERFACEHDR header; + + /* Tell the server that this device will be used and associate a context with the device. + * + * @param hServer The VRDE server instance. + * @param pDeviceHandle The device reported by ATTACH notification. + * @param pvDeviceCtx The caller context associated with the pDeviceHandle. + * + * @return IPRT status code. + */ + DECLR3CALLBACKMEMBER(int, VRDEVideoInDeviceAttach, (HVRDESERVER hServer, + const VRDEVIDEOINDEVICEHANDLE *pDeviceHandle, + void *pvDeviceCtx)); + + /* This device will be not be used anymore. The device context must not be used by the server too. + * + * @param hServer The VRDE server instance. + * @param pDeviceHandle The device reported by ATTACH notification. + * + * @return IPRT status code. + */ + DECLR3CALLBACKMEMBER(int, VRDEVideoInDeviceDetach, (HVRDESERVER hServer, + const VRDEVIDEOINDEVICEHANDLE *pDeviceHandle)); + + /* Get a device description. + * + * @param hServer The VRDE server instance. + * @param pvUser The callers context of this request. + * @param pDeviceHandle The device reported by ATTACH notification. + * + * @return IPRT status code. + */ + DECLR3CALLBACKMEMBER(int, VRDEVideoInGetDeviceDesc, (HVRDESERVER hServer, + void *pvUser, + const VRDEVIDEOINDEVICEHANDLE *pDeviceHandle)); + + /* Submit a set/get control request. + * + * @param hServer The VRDE server instance. + * @param pvUser The callers context of this request. + * @param pDeviceHandle The device reported by ATTACH notification. + * @param pReq The request. + * @param cbReq Size of the request. + * + * @return IPRT status code. + */ + DECLR3CALLBACKMEMBER(int, VRDEVideoInControl, (HVRDESERVER hServer, + void *pvUser, + const VRDEVIDEOINDEVICEHANDLE *pDeviceHandle, + const VRDEVIDEOINCTRLHDR *pReq, + uint32_t cbReq)); + +} VRDEVIDEOININTERFACE; + + +/* + * Notifications. + * Data structures: pvData of VRDEVIDEOINCALLBACKS::VRDECallbackVideoInNotify. + */ +typedef struct VRDEVIDEOINNOTIFYATTACH +{ + VRDEVIDEOINDEVICEHANDLE deviceHandle; + uint32_t u32Version; /* VRDE_VIDEOIN_NEGOTIATE_VERSION */ + uint32_t fu32Capabilities; /* VRDE_VIDEOIN_NEGOTIATE_CAP_* */ +} VRDEVIDEOINNOTIFYATTACH; + +typedef struct VRDEVIDEOINNOTIFYDETACH +{ + VRDEVIDEOINDEVICEHANDLE deviceHandle; +} VRDEVIDEOINNOTIFYDETACH; + +/* Notification codes, */ +#define VRDE_VIDEOIN_NOTIFY_ID_ATTACH 0 +#define VRDE_VIDEOIN_NOTIFY_ID_DETACH 1 + + +/* Video input interface callbacks. */ +typedef struct VRDEVIDEOINCALLBACKS +{ + /* The header. */ + VRDEINTERFACEHDR header; + + /* Notifications. + * + * @param pvCallback The callbacks context specified in VRDEGetInterface. + * @param u32EventId The notification identifier: VRDE_VIDEOIN_NOTIFY_*. + * @param pvData The notification specific data. + * @param cbData The size of buffer pointed by pvData. + */ + DECLR3CALLBACKMEMBER(void, VRDECallbackVideoInNotify,(void *pvCallback, + uint32_t u32Id, + const void *pvData, + uint32_t cbData)); + + /* Device description received from the client. + * + * @param pvCallback The callbacks context specified in VRDEGetInterface. + * @param rcRequest The result code of the request. + * @param pDeviceCtx The device context associated with the device in VRDEVideoInGetDeviceDesc. + * @param pvUser The pvUser parameter of VRDEVideoInGetDeviceDesc. + * @param pDeviceDesc The device description. + * @param cbDeviceDesc The size of buffer pointed by pDevice. + */ + DECLR3CALLBACKMEMBER(void, VRDECallbackVideoInDeviceDesc,(void *pvCallback, + int rcRequest, + void *pDeviceCtx, + void *pvUser, + const VRDEVIDEOINDEVICEDESC *pDeviceDesc, + uint32_t cbDeviceDesc)); + + /* Control response or notification. + * + * @param pvCallback The callbacks context specified in VRDEGetInterface. + * @param rcRequest The result code of the request. + * @param pDeviceCtx The device context associated with the device in VRDEVideoInGetDeviceDesc. + * @param pvUser The pvUser parameter of VRDEVideoInControl. NULL if this is a notification. + * @param pControl The control information. + * @param cbControl The size of buffer pointed by pControl. + */ + DECLR3CALLBACKMEMBER(void, VRDECallbackVideoInControl,(void *pvCallback, + int rcRequest, + void *pDeviceCtx, + void *pvUser, + const VRDEVIDEOINCTRLHDR *pControl, + uint32_t cbControl)); + + /* Frame which was received from the client. + * + * @param pvCallback The callbacks context specified in VRDEGetInterface. + * @param rcRequest The result code of the request. + * @param pDeviceCtx The device context associated with the device in VRDEVideoInGetDeviceDesc. + * @param pFrame The frame data. + * @param cbFrame The size of buffer pointed by pFrame. + */ + DECLR3CALLBACKMEMBER(void, VRDECallbackVideoInFrame,(void *pvCallback, + int rcRequest, + void *pDeviceCtx, + const VRDEVIDEOINPAYLOADHDR *pFrame, + uint32_t cbFrame)); + +} VRDEVIDEOINCALLBACKS; +#endif /* VRDE_VIDEOIN_WITH_VRDEINTERFACE */ + +#pragma pack() + +#endif diff --git a/include/VBox/VBoxCrHgsmi.h b/include/VBox/VBoxCrHgsmi.h index 9d25a5df..e79a5c1f 100644 --- a/include/VBox/VBoxCrHgsmi.h +++ b/include/VBox/VBoxCrHgsmi.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/VBoxDrvCfg-win.h b/include/VBox/VBoxDrvCfg-win.h index ac8092a4..abca190f 100644 --- a/include/VBox/VBoxDrvCfg-win.h +++ b/include/VBox/VBoxDrvCfg-win.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/VBoxGL2D.h b/include/VBox/VBoxGL2D.h index ab0f99db..a29c2726 100644 --- a/include/VBox/VBoxGL2D.h +++ b/include/VBox/VBoxGL2D.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2009 Oracle Corporation + * Copyright (C) 2009-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/VBoxGuest.h b/include/VBox/VBoxGuest.h index d23e5a2d..62dfe1f9 100644 --- a/include/VBox/VBoxGuest.h +++ b/include/VBox/VBoxGuest.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2006-2009 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -61,6 +61,9 @@ /** Device name. */ # define VBOXGUEST_DEVICE_NAME_DOS L"\\DosDevices\\VBoxGuest" +#elif defined(RT_OS_HAIKU) +# define VBOXGUEST_DEVICE_NAME "/dev/misc/vboxguest" + #else /* (PORTME) */ # define VBOXGUEST_DEVICE_NAME "/dev/vboxguest" # if defined(RT_OS_LINUX) @@ -146,7 +149,7 @@ typedef const VBGLBIGREQ *PCVBGLBIGREQ; #if defined(RT_OS_WINDOWS) -/* @todo Remove IOCTL_CODE later! Integrate it in VBOXGUEST_IOCTL_CODE below. */ +/** @todo Remove IOCTL_CODE later! Integrate it in VBOXGUEST_IOCTL_CODE below. */ /** @todo r=bird: IOCTL_CODE is supposedly defined in some header included by Windows.h or ntddk.h, which is why it wasn't in the #if 0 earlier. See HostDrivers/Support/SUPDrvIOC.h... */ # define IOCTL_CODE(DeviceType, Function, Method, Access, DataSize_ignored) \ ( ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)) @@ -175,6 +178,13 @@ typedef const VBGLBIGREQ *PCVBGLBIGREQ; # define VBOXGUEST_IOCTL_CODE_FAST_(Function) _IO( 'V', (Function)) # define VBOXGUEST_IOCTL_STRIP_SIZE(Code) VBOXGUEST_IOCTL_CODE_(_IOC_NR((Code)), 0) +#elif defined(RT_OS_HAIKU) + /* No automatic buffering, size not encoded. */ + /** @todo do something better */ +# define VBOXGUEST_IOCTL_CODE_(Function, Size) (0x56420000 | (Function)) +# define VBOXGUEST_IOCTL_CODE_FAST_(Function) (0x56420000 | (Function)) +# define VBOXGUEST_IOCTL_STRIP_SIZE(Code) (Code) + #elif defined(RT_OS_FREEBSD) /** @todo r=bird: Please do it like SUPDRVIOC to keep it as similar as possible. */ # include <sys/ioccom.h> @@ -185,8 +195,8 @@ typedef const VBGLBIGREQ *PCVBGLBIGREQ; #else /* BSD Like */ /* Automatic buffering, size limited to 4KB on *BSD and 8KB on Darwin - commands the limit, 4KB. */ # include <sys/ioccom.h> -# define VBOXGUEST_IOCTL_CODE_(Function, Size) _IOC(IOC_INOUT, 'V', (Function) | VBOXGUEST_IOCTL_FLAG, (Size)) -# define VBOXGUEST_IOCTL_CODE_FAST_(Function) _IO('V', (Function) | VBOXGUEST_IOCTL_FLAG) +# define VBOXGUEST_IOCTL_CODE_(Function, Size) _IOC(IOC_INOUT, 'V', (Function), (Size)) +# define VBOXGUEST_IOCTL_CODE_FAST_(Function) _IO('V', (Function)) # define VBOXGUEST_IOCTL_STRIP_SIZE(uIOCtl) ( (uIOCtl) & ~_IOC(0,0,0,IOCPARM_MASK) ) #endif @@ -321,7 +331,7 @@ typedef struct VBoxGuestWriteCoreDump AssertCompileSize(VBoxGuestWriteCoreDump, 4); /** IOCTL to VBoxGuest to update the mouse status features. */ -# define VBOXGUEST_IOCTL_SET_MOUSE_STATUS VBOXGUEST_IOCTL_CODE_(10, sizeof(uint32_t)) +# define VBOXGUEST_IOCTL_SET_MOUSE_STATUS VBOXGUEST_IOCTL_CODE_(10, sizeof(uint32_t)) #ifdef VBOX_WITH_HGCM /** IOCTL to VBoxGuest to connect to a HGCM service. */ @@ -340,7 +350,7 @@ AssertCompileSize(VBoxGuestWriteCoreDump, 4); /** IOCTL to VBoxGuest passed from the Kernel Mode driver, but containing a user mode data in VBoxGuestHGCMCallInfo * the driver received from the UM. Called in the context of the process passing the data. * @see VBoxGuestHGCMCallInfo */ -# define VBOXGUEST_IOCTL_HGCM_CALL_USERDATA(Size) VBOXGUEST_IOCTL_CODE(21, (Size)) +# define VBOXGUEST_IOCTL_HGCM_CALL_USERDATA(Size) VBOXGUEST_IOCTL_CODE(21, (Size)) # ifdef RT_ARCH_AMD64 /** @name IOCTL numbers that 32-bit clients, like the Windows OpenGL guest @@ -353,10 +363,6 @@ AssertCompileSize(VBoxGuestWriteCoreDump, 4); /** @} */ # endif /* RT_ARCH_AMD64 */ -#ifdef VBOX_WITH_DPC_LATENCY_CHECKER -#define VBOXGUEST_IOCTL_DPC VBOXGUEST_IOCTL_CODE(30, 0) -#endif - /** Get the pointer to the first HGCM parameter. */ # define VBOXGUEST_HGCM_CALL_PARMS(a) ( (HGCMFunctionParameter *)((uint8_t *)(a) + sizeof(VBoxGuestHGCMCallInfo)) ) /** Get the pointer to the first HGCM parameter in a 32-bit request. */ @@ -364,8 +370,56 @@ AssertCompileSize(VBoxGuestWriteCoreDump, 4); #endif /* VBOX_WITH_HGCM */ -/** IOCTL to for setting the mouse driver callback. (kernel only) */ -#define VBOXGUEST_IOCTL_SET_MOUSE_NOTIFY_CALLBACK VBOXGUEST_IOCTL_CODE_(31, sizeof(VBoxGuestMouseSetNotifyCallback)) +#ifdef VBOX_WITH_DPC_LATENCY_CHECKER +/** IOCTL to VBoxGuest to perform DPC latency tests, printing the result in + * the release log on the host. Takes no data, returns no data. */ +# define VBOXGUEST_IOCTL_DPC_LATENCY_CHECKER VBOXGUEST_IOCTL_CODE_(30, 0) +#endif + +/** IOCTL to for setting the mouse driver callback. (kernel only) */ +#define VBOXGUEST_IOCTL_SET_MOUSE_NOTIFY_CALLBACK VBOXGUEST_IOCTL_CODE(31, sizeof(VBoxGuestMouseSetNotifyCallback)) + +typedef enum VBOXGUESTCAPSACQUIRE_FLAGS +{ + VBOXGUESTCAPSACQUIRE_FLAGS_NONE = 0, + /* configures VBoxGuest to use the specified caps in Acquire mode, w/o making any caps acquisition/release. + * so far it is only possible to set acquire mode for caps, but not clear it, + * so u32NotMask is ignored for this request */ + VBOXGUESTCAPSACQUIRE_FLAGS_CONFIG_ACQUIRE_MODE, + /* to ensure enum is 32bit*/ + VBOXGUESTCAPSACQUIRE_FLAGS_32bit = 0x7fffffff +} VBOXGUESTCAPSACQUIRE_FLAGS; + +typedef struct VBoxGuestCapsAquire +{ + /* result status + * VINF_SUCCESS - on success + * VERR_RESOURCE_BUSY - some caps in the u32OrMask are acquired by some other VBoxGuest connection. + * NOTE: no u32NotMask caps are cleaned in this case, i.e. no modifications are done on failure + * VER_INVALID_PARAMETER - invalid Caps are specified with either u32OrMask or u32NotMask. No modifications are done on failure. + */ + int32_t rc; + /* Acquire command */ + VBOXGUESTCAPSACQUIRE_FLAGS enmFlags; + /* caps to acquire, OR-ed VMMDEV_GUEST_SUPPORTS_XXX flags */ + uint32_t u32OrMask; + /* caps to release, OR-ed VMMDEV_GUEST_SUPPORTS_XXX flags */ + uint32_t u32NotMask; +} VBoxGuestCapsAquire; + +/** IOCTL to for Acquiring/Releasing Guest Caps + * This is used for multiple purposes: + * 1. By doing Acquire r3 client application (e.g. VBoxTray) claims it will use + * the given connection for performing operations like Seamles or Auto-resize, + * thus, if the application terminates, the driver will automatically cleanup the caps reported to host, + * so that host knows guest does not support them anymore + * 2. In a multy-user environment this will not allow r3 applications (like VBoxTray) + * running in different user sessions simultaneously to interfere with each other. + * An r3 client application (like VBoxTray) is responsible for Acquiring/Releasing caps properly as needed. + **/ +#define VBOXGUEST_IOCTL_GUEST_CAPS_ACQUIRE VBOXGUEST_IOCTL_CODE(32, sizeof(VBoxGuestCapsAquire)) + + typedef DECLCALLBACK(void) FNVBOXGUESTMOUSENOTIFY(void *pfnUser); typedef FNVBOXGUESTMOUSENOTIFY *PFNVBOXGUESTMOUSENOTIFY; diff --git a/include/VBox/VBoxGuest.inc b/include/VBox/VBoxGuest.inc index 87982549..321f8f8f 100644 --- a/include/VBox/VBoxGuest.inc +++ b/include/VBox/VBoxGuest.inc @@ -3,7 +3,7 @@ ; ;/* -; Copyright (C) 2006-2007 Oracle Corporation +; Copyright (C) 2006-2010 Oracle Corporation ; ; This file is part of VirtualBox Open Source Edition (OSE), as ; available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/VBoxGuest.mac b/include/VBox/VBoxGuest.mac index 9d0cd6a1..0da8aa17 100644 --- a/include/VBox/VBoxGuest.mac +++ b/include/VBox/VBoxGuest.mac @@ -3,7 +3,7 @@ ; ;/* -; Copyright (C) 2006-2007 Oracle Corporation +; Copyright (C) 2006-2010 Oracle Corporation ; ; This file is part of VirtualBox Open Source Edition (OSE), as ; available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/VBoxGuest16.h b/include/VBox/VBoxGuest16.h index 15aa986c..0a431278 100644 --- a/include/VBox/VBoxGuest16.h +++ b/include/VBox/VBoxGuest16.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/VBoxGuest2.h b/include/VBox/VBoxGuest2.h index 4e17b2df..05344c32 100644 --- a/include/VBox/VBoxGuest2.h +++ b/include/VBox/VBoxGuest2.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2009 Oracle Corporation + * Copyright (C) 2006-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/VBoxGuestLib.h b/include/VBox/VBoxGuestLib.h index c860a073..dea1a6a0 100644 --- a/include/VBox/VBoxGuestLib.h +++ b/include/VBox/VBoxGuestLib.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2012 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -86,7 +86,11 @@ RT_C_DECLS_BEGIN /** @def DECLR0VBGL * Declare a VBGL ring-0 API with the right calling convention and visibilitiy. * @param type Return type. */ -# define DECLR0VBGL(type) type VBOXCALL +# ifdef RT_OS_DARWIN /** @todo probably apply to all, but don't want a forest fire on our hands right now. */ +# define DECLR0VBGL(type) DECLHIDDEN(type) VBOXCALL +# else +# define DECLR0VBGL(type) type VBOXCALL +# endif # define DECLVBGL(type) DECLR0VBGL(type) typedef uint32_t VBGLIOPORT; /**< @todo r=bird: We have RTIOPORT (uint16_t) for this. */ @@ -178,7 +182,7 @@ DECLVBGL(int) VbglGRVerify (const VMMDevRequestHeader *pReq, size_t cbReq); * @param pvData VBoxGuest pointer to be passed to callback. * @param u32Data VBoxGuest 32 bit value to be passed to callback. */ -typedef DECLVBGL(int) FNVBGLHGCMCALLBACK(VMMDevHGCMRequestHeader *pHeader, void *pvData, uint32_t u32Data); +typedef DECLCALLBACK(int) FNVBGLHGCMCALLBACK(VMMDevHGCMRequestHeader *pHeader, void *pvData, uint32_t u32Data); /** Pointer to a FNVBGLHGCMCALLBACK. */ typedef FNVBGLHGCMCALLBACK *PFNVBGLHGCMCALLBACK; @@ -379,9 +383,9 @@ DECLVBGL(void *) VbglPhysHeapAlloc (uint32_t cbSize); * * * @param p Virtual address of memory block. - * @return Physical memory block. + * @return Physical address of the memory block. */ -DECLVBGL(RTCCPHYS) VbglPhysHeapGetPhysAddr (void *p); +DECLVBGL(uint32_t) VbglPhysHeapGetPhysAddr (void *p); /** * Free a memory block. @@ -477,6 +481,9 @@ VBGLR3DECL(int) VbglR3SetPointerShapeReq(struct VMMDevReqMousePointer *pReq) /** @name Display * @{ */ VBGLR3DECL(int) VbglR3GetDisplayChangeRequest(uint32_t *pcx, uint32_t *pcy, uint32_t *pcBits, uint32_t *piDisplay, bool fAck); +VBGLR3DECL(int) VbglR3GetDisplayChangeRequestEx(uint32_t *pcx, uint32_t *pcy, uint32_t *pcBits, + uint32_t *piDisplay, uint32_t *pcOriginX, uint32_t *pcOriginY, + bool *pfEnabled, bool fAck); VBGLR3DECL(bool) VbglR3HostLikesVideoMode(uint32_t cx, uint32_t cy, uint32_t cBits); VBGLR3DECL(int) VbglR3SaveVideoMode(const char *pszName, uint32_t cx, uint32_t cy, uint32_t cBits); VBGLR3DECL(int) VbglR3RetrieveVideoMode(const char *pszName, uint32_t *pcx, uint32_t *pcy, uint32_t *pcBits); @@ -523,10 +530,16 @@ VBGLR3DECL(int) VbglR3GuestPropEnum(uint32_t u32ClientId, char const * const VBGLR3DECL(int) VbglR3GuestPropEnumNext(PVBGLR3GUESTPROPENUM pHandle, char const **ppszName, char const **ppszValue, uint64_t *pu64Timestamp, char const **ppszFlags); VBGLR3DECL(void) VbglR3GuestPropEnumFree(PVBGLR3GUESTPROPENUM pHandle); +VBGLR3DECL(int) VbglR3GuestPropDelete(uint32_t u32ClientId, const char *pszName); VBGLR3DECL(int) VbglR3GuestPropDelSet(uint32_t u32ClientId, char const * const *papszPatterns, uint32_t cPatterns); VBGLR3DECL(int) VbglR3GuestPropWait(uint32_t u32ClientId, const char *pszPatterns, void *pvBuf, uint32_t cbBuf, uint64_t u64Timestamp, uint32_t cMillies, char ** ppszName, char **ppszValue, uint64_t *pu64Timestamp, char **ppszFlags, uint32_t *pcbBufActual); /** @} */ +/** @name Guest user handling / reporting. + * @{ */ +VBGLR3DECL(int) VbglR3GuestUserReportState(const char *pszUser, const char *pszDomain, VBoxGuestUserState enmState, uint8_t *puDetails, uint32_t cbDetails); +/** @} */ + /** @name Host version handling * @{ */ VBGLR3DECL(int) VbglR3HostVersionCheckForUpdate(uint32_t u32ClientId, bool *pfUpdate, char **ppszHostVersion, char **ppszGuestVersion); @@ -566,78 +579,79 @@ VBGLR3DECL(int) VbglR3SharedFolderGetMountDir(char **ppszDir); # ifdef VBOX_WITH_GUEST_CONTROL /** @name Guest control * @{ */ -/** @todo Clean this up, uniform formatting. */ -VBGLR3DECL(int) VbglR3GuestCtrlConnect(uint32_t *pu32ClientId); -VBGLR3DECL(int) VbglR3GuestCtrlDisconnect(uint32_t u32ClientId); -VBGLR3DECL(int) VbglR3GuestCtrlWaitForHostMsg(uint32_t u32ClientId, uint32_t *puMsg, uint32_t *puNumParms); -VBGLR3DECL(int) VbglR3GuestCtrlCancelPendingWaits(uint32_t u32ClientId); -/* Process execution. */ -VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdExec(uint32_t u32ClientId, uint32_t cParms, - uint32_t *puContext, - char *pszCmd, uint32_t cbCmd, - uint32_t *puFlags, - char *pszArgs, uint32_t cbArgs, uint32_t *puNumArgs, - char *pszEnv, uint32_t *pcbEnv, uint32_t *puNumEnvVars, - char *pszUser, uint32_t cbUser, - char *pszPassword, uint32_t cbPassword, - uint32_t *puTimeLimit); -VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdInput(uint32_t u32ClientId, uint32_t uNumParms, - uint32_t *puContext, uint32_t *puPID, - uint32_t *puFlags, void *pvData, - uint32_t cbData, uint32_t *pcbSize); -VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdOutput(uint32_t u32ClientId, uint32_t uNumParms, - uint32_t *puContext, uint32_t *puPID, - uint32_t *puHandle, uint32_t *puFlags); -VBGLR3DECL(int) VbglR3GuestCtrlExecReportStatus(uint32_t u32ClientId, - uint32_t u32Context, - uint32_t u32PID, - uint32_t u32Status, - uint32_t u32Flags, - void *pvData, - uint32_t cbData); -VBGLR3DECL(int) VbglR3GuestCtrlExecSendOut(uint32_t u32ClientId, - uint32_t u32Context, - uint32_t u32PID, - uint32_t u32Handle, - uint32_t u32Flags, - void *pvData, - uint32_t cbData); -VBGLR3DECL(int) VbglR3GuestCtrlExecReportStatusIn(uint32_t u32ClientId, - uint32_t u32Context, - uint32_t u32PID, - uint32_t u32Status, - uint32_t u32Flags, - uint32_t cbWritten); -/* Native file handling. */ -VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdOpen(uint32_t uClientId, uint32_t cParms, - uint32_t *puContext, - char *pszFileName, uint32_t cbFileName, - char *pszOpenMode, uint32_t cbOpenMode, - char *pszDisposition, uint32_t cbDisposition, - uint32_t *puCreationMode, - uint64_t *puOffset); -VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdClose(uint32_t uClientId, uint32_t cParms, - uint32_t *puContext, - uint32_t *puHandle); -VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdRead(uint32_t uClientId, uint32_t cParms, - uint32_t *puContext, - uint32_t *puHandle, uint32_t *puToRead); -VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdWrite(uint32_t uClientId, uint32_t cParms, - uint32_t *puContext, - uint32_t *puHandle, - void *pvData, uint32_t cbData, - uint32_t *pcbSize); -VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdSeek(uint32_t uClientId, uint32_t cParms, - uint32_t *puContext, - uint32_t *puHandle, - uint32_t *puSeekMethod, uint64_t *puOffset); -VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdTell(uint32_t uClientId, uint32_t cParms, - uint32_t *puContext, - uint32_t *puHandle); -VBGLR3DECL(int) VbglR3GuestCtrlFileNotify(uint32_t uClientId, - uint32_t uContext, uint32_t uHandle, - uint32_t uType, - void *pvPayload, uint32_t cbPayload); + +/** + * Structure containing the context required for + * either retrieving or sending a HGCM guest control + * command from or to the host. + * + * Note: Do not change parameter order without also + * adapting all structure initializers. + */ +typedef struct VBGLR3GUESTCTRLCMDCTX +{ + /** @todo This struct could be handy if we want to implement + * a second communication channel, e.g. via TCP/IP. + * Use a union for the HGCM stuff then. */ + + /** IN: HGCM client ID to use for + * communication. */ + uint32_t uClientID; + /** IN/OUT: Context ID to retrieve + * or to use. */ + uint32_t uContextID; + /** IN: Protocol version to use. */ + uint32_t uProtocol; + /** OUT: Number of parameters retrieved. */ + uint32_t uNumParms; +} VBGLR3GUESTCTRLCMDCTX, *PVBGLR3GUESTCTRLCMDCTX; + +/* General message handling on the guest. */ +VBGLR3DECL(int) VbglR3GuestCtrlConnect(uint32_t *puClientId); +VBGLR3DECL(int) VbglR3GuestCtrlDisconnect(uint32_t uClientId); +VBGLR3DECL(int) VbglR3GuestCtrlMsgFilterSet(uint32_t uClientId, uint32_t uValue, uint32_t uMaskAdd, uint32_t uMaskRemove); +VBGLR3DECL(int) VbglR3GuestCtrlMsgFilterUnset(uint32_t uClientId); +VBGLR3DECL(int) VbglR3GuestCtrlMsgReply(PVBGLR3GUESTCTRLCMDCTX pCtx, int rc); +VBGLR3DECL(int) VbglR3GuestCtrlMsgReplyEx(PVBGLR3GUESTCTRLCMDCTX pCtx, int rc, uint32_t uType, void *pvPayload, uint32_t cbPayload); +VBGLR3DECL(int) VbglR3GuestCtrlMsgSkip(uint32_t uClientId); +VBGLR3DECL(int) VbglR3GuestCtrlMsgWaitFor(uint32_t uClientId, uint32_t *puMsg, uint32_t *puNumParms); +VBGLR3DECL(int) VbglR3GuestCtrlCancelPendingWaits(uint32_t u32ClientId); +/* Guest session handling. */ +VBGLR3DECL(int) VbglR3GuestCtrlSessionClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uFlags); +VBGLR3DECL(int) VbglR3GuestCtrlSessionNotify(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uType, uint32_t uResult); +VBGLR3DECL(int) VbglR3GuestCtrlSessionGetOpen(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puProtocol, char *pszUser, uint32_t cbUser, char *pszPassword, uint32_t cbPassword, char *pszDomain, uint32_t cbDomain, uint32_t *puFlags, uint32_t *puSessionID); +VBGLR3DECL(int) VbglR3GuestCtrlSessionGetClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puFlags, uint32_t *puSessionID); +/* Guest path handling. */ +VBGLR3DECL(int) VbglR3GuestCtrlPathGetRename(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszSource, uint32_t cbSource, char *pszDest, uint32_t cbDest, uint32_t *puFlags); +/* Guest process execution. */ +VBGLR3DECL(int) VbglR3GuestCtrlProcGetStart(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszCmd, uint32_t cbCmd, uint32_t *puFlags, char *pszArgs, uint32_t cbArgs, uint32_t *puNumArgs, char *pszEnv, uint32_t *pcbEnv, uint32_t *puNumEnvVars, char *pszUser, uint32_t cbUser, char *pszPassword, uint32_t cbPassword, uint32_t *puTimeoutMS, uint32_t *puPriority, uint64_t *puAffinity, uint32_t cbAffinity, uint32_t *pcAffinity); +VBGLR3DECL(int) VbglR3GuestCtrlProcGetTerminate(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puPID); +VBGLR3DECL(int) VbglR3GuestCtrlProcGetInput(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puPID, uint32_t *puFlags, void *pvData, uint32_t cbData, uint32_t *pcbSize); +VBGLR3DECL(int) VbglR3GuestCtrlProcGetOutput(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puPID, uint32_t *puHandle, uint32_t *puFlags); +VBGLR3DECL(int) VbglR3GuestCtrlProcGetWaitFor(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puPID, uint32_t *puWaitFlags, uint32_t *puTimeoutMS); +/* Guest native directory handling. */ +VBGLR3DECL(int) VbglR3GuestCtrlDirGetRemove(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszPath, uint32_t cbPath, uint32_t *puFlags); +/* Guest native file handling. */ +VBGLR3DECL(int) VbglR3GuestCtrlFileGetOpen(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszFileName, uint32_t cbFileName, char *pszOpenMode, uint32_t cbOpenMode, char *pszDisposition, uint32_t cbDisposition, char *pszSharing, uint32_t cbSharing, uint32_t *puCreationMode, uint64_t *puOffset); +VBGLR3DECL(int) VbglR3GuestCtrlFileGetClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle); +VBGLR3DECL(int) VbglR3GuestCtrlFileGetRead(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, uint32_t *puToRead); +VBGLR3DECL(int) VbglR3GuestCtrlFileGetReadAt(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, uint32_t *puToRead, uint64_t *puOffset); +VBGLR3DECL(int) VbglR3GuestCtrlFileGetWrite(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, void *pvData, uint32_t cbData, uint32_t *pcbSize); +VBGLR3DECL(int) VbglR3GuestCtrlFileGetWriteAt(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, void *pvData, uint32_t cbData, uint32_t *pcbSize, uint64_t *puOffset); +VBGLR3DECL(int) VbglR3GuestCtrlFileGetSeek(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, uint32_t *puSeekMethod, uint64_t *puOffset); +VBGLR3DECL(int) VbglR3GuestCtrlFileGetTell(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle); +/* Guest -> Host. */ +VBGLR3DECL(int) VbglR3GuestCtrlFileCbOpen(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint32_t uFileHandle); +VBGLR3DECL(int) VbglR3GuestCtrlFileCbClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc); +VBGLR3DECL(int) VbglR3GuestCtrlFileCbError(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc); +VBGLR3DECL(int) VbglR3GuestCtrlFileCbRead(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, void *pvData, uint32_t cbData); +VBGLR3DECL(int) VbglR3GuestCtrlFileCbWrite(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint32_t uWritten); +VBGLR3DECL(int) VbglR3GuestCtrlFileCbSeek(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint64_t uOffActual); +VBGLR3DECL(int) VbglR3GuestCtrlFileCbTell(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint64_t uOffActual); +VBGLR3DECL(int) VbglR3GuestCtrlProcCbStatus(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uPID, uint32_t uStatus, uint32_t uFlags, void *pvData, uint32_t cbData); +VBGLR3DECL(int) VbglR3GuestCtrlProcCbOutput(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uPID, uint32_t uHandle, uint32_t uFlags, void *pvData, uint32_t cbData); +VBGLR3DECL(int) VbglR3GuestCtrlProcCbStatusInput(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t u32PID, uint32_t uStatus, uint32_t uFlags, uint32_t cbWritten); + /** @} */ # endif /* VBOX_WITH_GUEST_CONTROL defined */ diff --git a/include/VBox/VBoxNetCfg-win.h b/include/VBox/VBoxNetCfg-win.h index 8e327c0d..8dcaa0a4 100644 --- a/include/VBox/VBoxNetCfg-win.h +++ b/include/VBox/VBoxNetCfg-win.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/VBoxTpG.h b/include/VBox/VBoxTpG.h index 260ee6f2..4d23dd34 100644 --- a/include/VBox/VBoxTpG.h +++ b/include/VBox/VBoxTpG.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2012 Oracle Corporation + * Copyright (C) 2012-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -122,8 +122,18 @@ typedef VTGPROBELOC const *PCVTGPROBELOC; # error "Unsupported Darwin compiler!" # endif -#elif defined(RT_OS_OS2) -# error "OS/2 is not supported" +#elif defined(RT_OS_OS2) /** @todo This doesn't actually work, but it makes the code compile. */ +# define VTG_OBJ_SECT "__DATA" +# define VTG_LOC_SECT "__VTGPrLc" +# define VTG_LOC_SET "__VTGPrLcSet" +# ifdef __GNUC__ +# define VTG_DECL_VTGPROBELOC(a_VarName) \ + static VTGPROBELOC a_VarName; \ + __asm__ (".stabs \"__VTGPrLcSet\", 23, 0, 0, _" #a_VarName ); + +# else +# error "Unsupported Darwin compiler!" +# endif #else /* Assume the rest uses ELF. */ # define VTG_OBJ_SECT ".VTGObj" diff --git a/include/VBox/VBoxUhgsmi.h b/include/VBox/VBoxUhgsmi.h index 459c6352..eed8345d 100644 --- a/include/VBox/VBoxUhgsmi.h +++ b/include/VBox/VBoxUhgsmi.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/VBoxVideo.h b/include/VBox/VBoxVideo.h index bbc6d7b5..9d499e53 100644 --- a/include/VBox/VBoxVideo.h +++ b/include/VBox/VBoxVideo.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -852,6 +852,9 @@ typedef struct VBVABUFFER #define VBVA_INFO_CAPS 12 /* informs host about HGSMI caps. see VBVACAPS below */ #define VBVA_SCANLINE_CFG 13 /* configures scanline, see VBVASCANLINECFG below */ #define VBVA_SCANLINE_INFO 14 /* requests scanline info, see VBVASCANLINEINFO below */ +#define VBVA_CMDVBVA_SUBMIT 16 /* inform host about VBVA Command submission */ +#define VBVA_CMDVBVA_FLUSH 17 /* inform host about VBVA Command submission */ +#define VBVA_CMDVBVA_CTL 18 /* G->H DMA command */ /* host->guest commands */ #define VBVAHG_EVENT 1 @@ -945,6 +948,20 @@ typedef struct VBVAFLUSH } VBVAFLUSH; +typedef struct VBVACMDVBVASUBMIT +{ + uint32_t u32Reserved; +} VBVACMDVBVASUBMIT; + +/* flush is requested because due to guest command buffer overflow */ +#define VBVACMDVBVAFLUSH_F_GUEST_BUFFER_OVERFLOW 1 + +typedef struct VBVACMDVBVAFLUSH +{ + uint32_t u32Flags; +} VBVACMDVBVAFLUSH; + + /* VBVAINFOSCREEN::u8Flags */ #define VBVA_SCREEN_F_NONE 0x0000 #define VBVA_SCREEN_F_ACTIVE 0x0001 @@ -1397,8 +1414,7 @@ typedef struct VBOXVDMACMD_CHILD_STATUS_IRQ # pragma pack() #endif /* #ifdef VBOX_WITH_VDMA */ -#ifdef VBOX_WITH_CRHGSMI -# pragma pack(1) +#pragma pack(1) typedef struct VBOXVDMACMD_CHROMIUM_BUFFER { VBOXVIDEOOFFSET offBuffer; @@ -1420,8 +1436,9 @@ typedef enum VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP, VBOXVDMACMD_CHROMIUM_CTL_TYPE_SAVESTATE_BEGIN, VBOXVDMACMD_CHROMIUM_CTL_TYPE_SAVESTATE_END, - VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP_COMPLETION, - VBOXVDMACMD_CHROMIUM_CTL_TYPE_SIZEHACK = 0xfffffffe + VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP_MAINCB, + VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRCONNECT, + VBOXVDMACMD_CHROMIUM_CTL_TYPE_SIZEHACK = 0x7fffffff } VBOXVDMACMD_CHROMIUM_CTL_TYPE; typedef struct VBOXVDMACMD_CHROMIUM_CTL @@ -1430,29 +1447,333 @@ typedef struct VBOXVDMACMD_CHROMIUM_CTL uint32_t cbCmd; } VBOXVDMACMD_CHROMIUM_CTL, *PVBOXVDMACMD_CHROMIUM_CTL; -typedef struct VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP -{ - VBOXVDMACMD_CHROMIUM_CTL Hdr; - union - { - void *pvVRamBase; - uint64_t uAlignment; - }; - uint64_t cbVRam; -} VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP, *PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP; typedef struct PDMIDISPLAYVBVACALLBACKS *HCRHGSMICMDCOMPLETION; typedef DECLCALLBACK(int) FNCRHGSMICMDCOMPLETION(HCRHGSMICMDCOMPLETION hCompletion, PVBOXVDMACMD_CHROMIUM_CMD pCmd, int rc); typedef FNCRHGSMICMDCOMPLETION *PFNCRHGSMICMDCOMPLETION; -typedef struct VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_COMPLETION +typedef DECLCALLBACK(bool) FNCROGLHASDATA(void); +typedef FNCROGLHASDATA *PFNCROGLHASDATA; + +/* callbacks chrogl gives to main */ +typedef struct CR_MAIN_INTERFACE +{ + PFNCROGLHASDATA pfnHasData; +} CR_MAIN_INTERFACE; + +typedef struct VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_MAINCB { VBOXVDMACMD_CHROMIUM_CTL Hdr; + /*in*/ HCRHGSMICMDCOMPLETION hCompletion; PFNCRHGSMICMDCOMPLETION pfnCompletion; -} VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_COMPLETION, *PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_COMPLETION; -# pragma pack() -#endif + /*out*/ + CR_MAIN_INTERFACE MainInterface; +} VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_MAINCB, *PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_MAINCB; + +typedef struct VBOXCRCON_SERVER *HVBOXCRCON_SERVER; +typedef struct PDMIDISPLAYVBVACALLBACKS* HVBOXCRCON_CLIENT; + +typedef struct VBOXCRCON_3DRGN_CLIENT* HVBOXCRCON_3DRGN_CLIENT; +typedef struct VBOXCRCON_3DRGN_ASYNCCLIENT* HVBOXCRCON_3DRGN_ASYNCCLIENT; + +/* server callbacks */ +/* submit chromium cmd */ +typedef DECLCALLBACK(int) FNVBOXCRCON_SVR_CRCMD(HVBOXCRCON_SERVER hServer, PVBOXVDMACMD_CHROMIUM_CMD pCmd, uint32_t cbCmd); +typedef FNVBOXCRCON_SVR_CRCMD *PFNVBOXCRCON_SVR_CRCMD; + +/* submit chromium control cmd */ +typedef DECLCALLBACK(int) FNVBOXCRCON_SVR_CRCTL(HVBOXCRCON_SERVER hServer, PVBOXVDMACMD_CHROMIUM_CTL pCtl, uint32_t cbCmd); +typedef FNVBOXCRCON_SVR_CRCTL *PFNVBOXCRCON_SVR_CRCTL; + +/* request 3D data. + * The protocol is the following: + * 1. if there is no 3D data displayed on screen, returns VINF_EOF immediately w/o calling any PFNVBOXCRCON_3DRGN_XXX callbacks + * 2. otherwise calls PFNVBOXCRCON_3DRGN_ONSUBMIT, submits the "regions get" request to the CrOpenGL server to process it asynchronously and returns VINF_SUCCESS + * 2.a on "regions get" request processing calls PFNVBOXCRCON_3DRGN_BEGIN, + * 2.b then PFNVBOXCRCON_3DRGN_REPORT zero or more times for each 3D region, + * 2.c and then PFNVBOXCRCON_3DRGN_END + * 3. returns VERR_XXX code on failure + * */ +typedef DECLCALLBACK(int) FNVBOXCRCON_SVR_3DRGN_GET(HVBOXCRCON_SERVER hServer, HVBOXCRCON_3DRGN_CLIENT hRgnClient, uint32_t idScreen); +typedef FNVBOXCRCON_SVR_3DRGN_GET *PFNVBOXCRCON_SVR_3DRGN_GET; + +/* 3D Regions Client callbacks */ +/* called from the PFNVBOXCRCON_SVR_3DRGN_GET callback in case server has 3D data and is going to process the request asynchronously, + * see comments for PFNVBOXCRCON_SVR_3DRGN_GET above */ +typedef DECLCALLBACK(int) FNVBOXCRCON_3DRGN_ONSUBMIT(HVBOXCRCON_3DRGN_CLIENT hRgnClient, uint32_t idScreen, HVBOXCRCON_3DRGN_ASYNCCLIENT *phRgnAsyncClient); +typedef FNVBOXCRCON_3DRGN_ONSUBMIT *PFNVBOXCRCON_3DRGN_ONSUBMIT; + +/* called from the "regions get" command processing thread, to indicate that the "regions get" is started. + * see comments for PFNVBOXCRCON_SVR_3DRGN_GET above */ +typedef DECLCALLBACK(int) FNVBOXCRCON_3DRGN_BEGIN(HVBOXCRCON_3DRGN_ASYNCCLIENT hRgnAsyncClient, uint32_t idScreen); +typedef FNVBOXCRCON_3DRGN_BEGIN *PFNVBOXCRCON_3DRGN_BEGIN; + +/* called from the "regions get" command processing thread, to report a 3D region. + * see comments for PFNVBOXCRCON_SVR_3DRGN_GET above */ +typedef DECLCALLBACK(int) FNVBOXCRCON_3DRGN_REPORT(HVBOXCRCON_3DRGN_ASYNCCLIENT hRgnAsyncClient, uint32_t idScreen, void *pvData, uint32_t cbStride, const RTRECT *pRect); +typedef FNVBOXCRCON_3DRGN_REPORT *PFNVBOXCRCON_3DRGN_REPORT; + +/* called from the "regions get" command processing thread, to indicate that the "regions get" is completed. + * see comments for PFNVBOXCRCON_SVR_3DRGN_GET above */ +typedef DECLCALLBACK(int) FNVBOXCRCON_3DRGN_END(HVBOXCRCON_3DRGN_ASYNCCLIENT hRgnAsyncClient, uint32_t idScreen); +typedef FNVBOXCRCON_3DRGN_END *PFNVBOXCRCON_3DRGN_END; + + +/* client callbacks */ +/* complete chromium cmd */ +typedef DECLCALLBACK(int) FNVBOXCRCON_CLT_CRCTL_COMPLETE(HVBOXCRCON_CLIENT hClient, PVBOXVDMACMD_CHROMIUM_CTL pCtl, int rc); +typedef FNVBOXCRCON_CLT_CRCTL_COMPLETE *PFNVBOXCRCON_CLT_CRCTL_COMPLETE; + +/* complete chromium control cmd */ +typedef DECLCALLBACK(int) FNVBOXCRCON_CLT_CRCMD_COMPLETE(HVBOXCRCON_CLIENT hClient, PVBOXVDMACMD_CHROMIUM_CMD pCmd, int rc); +typedef FNVBOXCRCON_CLT_CRCMD_COMPLETE *PFNVBOXCRCON_CLT_CRCMD_COMPLETE; + +typedef struct VBOXCRCON_SERVER_CALLBACKS +{ + HVBOXCRCON_SERVER hServer; + PFNVBOXCRCON_SVR_CRCMD pfnCrCmd; + PFNVBOXCRCON_SVR_CRCTL pfnCrCtl; + PFNVBOXCRCON_SVR_3DRGN_GET pfn3DRgnGet; +} VBOXCRCON_SERVER_CALLBACKS, *PVBOXCRCON_SERVER_CALLBACKS; + +typedef struct VBOXCRCON_CLIENT_CALLBACKS +{ + HVBOXCRCON_CLIENT hClient; + PFNVBOXCRCON_CLT_CRCMD_COMPLETE pfnCrCmdComplete; + PFNVBOXCRCON_CLT_CRCTL_COMPLETE pfnCrCtlComplete; + PFNVBOXCRCON_3DRGN_ONSUBMIT pfn3DRgnOnSubmit; + PFNVBOXCRCON_3DRGN_BEGIN pfn3DRgnBegin; + PFNVBOXCRCON_3DRGN_REPORT pfn3DRgnReport; + PFNVBOXCRCON_3DRGN_END pfn3DRgnEnd; +} VBOXCRCON_CLIENT_CALLBACKS, *PVBOXCRCON_CLIENT_CALLBACKS; + +/* issued by Main to establish connection between Main and CrOpenGL service */ +typedef struct VBOXVDMACMD_CHROMIUM_CTL_CRCONNECT +{ + VBOXVDMACMD_CHROMIUM_CTL Hdr; + /*input (filled by Client) :*/ + /*class VMMDev*/void *pVMMDev; + VBOXCRCON_CLIENT_CALLBACKS ClientCallbacks; + /*output (filled by Server) :*/ + VBOXCRCON_SERVER_CALLBACKS ServerCallbacks; +} VBOXVDMACMD_CHROMIUM_CTL_CRCONNECT, *PVBOXVDMACMD_CHROMIUM_CTL_CRCONNECT; + +/* ring command buffer dr */ +#define VBOXCMDVBVA_STATE_SUBMITTED 1 +#define VBOXCMDVBVA_STATE_CANCELLED 2 +#define VBOXCMDVBVA_STATE_IN_PROGRESS 3 +/* the "completed" state is signalled via the ring buffer values */ + +/* CrHgsmi command */ +#define VBOXCMDVBVA_OPTYPE_CRCMD 1 +/* blit command that does blitting of allocations identified by VRAM offset or host id + * for VRAM-offset ones the size and format are same as primary */ +#define VBOXCMDVBVA_OPTYPE_BLT_OFFPRIMSZFMT_OR_ID 2 +/* flip */ +#define VBOXCMDVBVA_OPTYPE_FLIP 3 +/* ColorFill */ +#define VBOXCMDVBVA_OPTYPE_CLRFILL 4 +/* allocation paging transfer request */ +#define VBOXCMDVBVA_OPTYPE_PAGING_TRANSFER 5 +/* allocation paging fill request */ +#define VBOXCMDVBVA_OPTYPE_PAGING_FILL 6 +/* same as VBOXCMDVBVA_OPTYPE_NOP, but contains VBOXCMDVBVA_HDR data */ +#define VBOXCMDVBVA_OPTYPE_NOPCMD 7 + +/* nop - is a one-bit command. The buffer size to skip is determined by VBVA buffer size */ +#define VBOXCMDVBVA_OPTYPE_NOP 0x80 + +/* u8Flags flags */ +/* source allocation is specified with the host id. if not set - source allocation is specified with VRAM offset */ +#define VBOXCMDVBVA_OPF_ALLOC_SRCID 0x80 +/* destination allocation is specified with the host id. if not set - destination allocation is specified with VRAM offset */ +#define VBOXCMDVBVA_OPF_ALLOC_DSTID 0x40 + +/* transfer from RAM to Allocation */ +#define VBOXCMDVBVA_OPF_PAGING_TRANSFER_IN 0x20 + +/* VBOXCMDVBVA_OPTYPE_BLT_PRIMARY specific flags*/ +/* if set - src is a primary id */ +#define VBOXCMDVBVA_OPF_ALLOC_SRCPRIMARY 0x20 +/* if set - dst is a primary id */ +#define VBOXCMDVBVA_OPF_ALLOC_DSTPRIMARY 0x10 + + +/* trying to make the header as small as possible, + * we'd have pretty few op codes actually, so 8bit is quite enough, + * we will be able to extend it in any way. */ +typedef struct VBOXCMDVBVA_HDR +{ + /* one VBOXCMDVBVA_OPTYPE_XXX, except NOP, see comments above */ + uint8_t u8OpCode; + /* command-specific + * VBOXCMDVBVA_OPTYPE_CRCMD - must be null + * VBOXCMDVBVA_OPTYPE_BLT_PRIMARY - OR-ed VBOXCMDVBVA_OPF_ALLOC_XXX flags + * VBOXCMDVBVA_OPTYPE_BLT_OFFPRIMSZFMT_OR_ID - OR-ed VBOXCMDVBVA_OPF_ALLOC_XXX flags + * VBOXCMDVBVA_OPTYPE_PAGING_TRANSFER - must be null + * VBOXCMDVBVA_OPTYPE_PAGING_FILL - must be null + * VBOXCMDVBVA_OPTYPE_NOPCMD - must be null + * VBOXCMDVBVA_OPTYPE_NOP - not applicable (as the entire VBOXCMDVBVA_HDR is not valid) */ + uint8_t u8Flags; + /* one of VBOXCMDVBVA_STATE_XXX*/ + volatile uint8_t u8State; + union + { + /* result, 0 on success, otherwise contains the failure code TBD */ + int8_t i8Result; + uint8_t u8PrimaryID; + } u; + /* DXGK DDI fence ID */ + volatile uint32_t u32FenceID; +} VBOXCMDVBVA_HDR; + +typedef uint32_t VBOXCMDVBVAOFFSET; +typedef uint64_t VBOXCMDVBVAPHADDR; + +typedef struct VBOXCMDVBVA_CRCMD_BUFFER +{ + uint32_t cbBuffer; + VBOXCMDVBVAOFFSET offBuffer; +} VBOXCMDVBVA_CRCMD_BUFFER; + +typedef struct VBOXCMDVBVA_CRCMD_CMD +{ + uint32_t cBuffers; + VBOXCMDVBVA_CRCMD_BUFFER aBuffers[1]; +} VBOXCMDVBVA_CRCMD_CMD; + +typedef struct VBOXCMDVBVA_CRCMD +{ + VBOXCMDVBVA_HDR Hdr; + VBOXCMDVBVA_CRCMD_CMD Cmd; +} VBOXCMDVBVA_CRCMD; + +typedef struct VBOXCMDVBVA_ALLOCINFO +{ + union + { + VBOXCMDVBVAOFFSET offVRAM; + uint32_t id; + } u; +} VBOXCMDVBVA_ALLOCINFO; + +typedef struct VBOXCMDVBVA_RECT +{ + /** Coordinates of affected rectangle. */ + int16_t xLeft; + int16_t yTop; + int16_t xRight; + int16_t yBottom; +} VBOXCMDVBVA_RECT; + +typedef struct VBOXCMDVBVA_POINT +{ + int16_t x; + int16_t y; +} VBOXCMDVBVA_POINT; + +typedef struct VBOXCMDVBVA_BLT_PRIMARY +{ + VBOXCMDVBVA_HDR Hdr; + VBOXCMDVBVA_ALLOCINFO alloc; + VBOXCMDVBVA_POINT Pos; + /* the rects count is determined from the command size */ + VBOXCMDVBVA_RECT aRects[1]; +} VBOXCMDVBVA_BLT_PRIMARY; + +typedef struct VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID +{ + VBOXCMDVBVA_HDR Hdr; + VBOXCMDVBVA_ALLOCINFO src; + VBOXCMDVBVA_ALLOCINFO dst; + VBOXCMDVBVA_POINT Pos; + /* the rects count is determined from the command size */ + VBOXCMDVBVA_RECT aRects[1]; +} VBOXCMDVBVA_BLT_OFFPRIMSZFMT_OR_ID; + +typedef struct VBOXCMDVBVA_FLIP +{ + VBOXCMDVBVA_HDR Hdr; + VBOXCMDVBVA_ALLOCINFO src; +} VBOXCMDVBVA_FLIP; + +typedef struct VBOXCMDVBVA_CLRFILL +{ + VBOXCMDVBVA_HDR Hdr; + VBOXCMDVBVA_ALLOCINFO dst; + VBOXCMDVBVA_RECT aRects[1]; +} VBOXCMDVBVA_CLRFILL; + +#define VBOXCMDVBVA_SYSMEMEL_CPAGES_MAX 0x1000 + +typedef struct VBOXCMDVBVA_SYSMEMEL +{ + uint32_t cPagesAfterFirst : 12; + uint32_t iPage1 : 20; + uint32_t iPage2; +} VBOXCMDVBVA_SYSMEMEL; + +typedef struct VBOXCMDVBVA_PAGING_TRANSFER +{ + VBOXCMDVBVA_HDR Hdr; + /* for now can only contain offVRAM. + * paging transfer can NOT be initiated for allocations having host 3D object (hostID) associated */ + VBOXCMDVBVA_ALLOCINFO Alloc; + uint32_t cSysMem; + VBOXCMDVBVA_SYSMEMEL aSysMem[1]; +} VBOXCMDVBVA_PAGING_TRANSFER; + +typedef struct VBOXCMDVBVA_PAGING_FILL +{ + VBOXCMDVBVA_HDR Hdr; + uint32_t cbFill; + uint32_t Pattern; + /* paging transfer can NOT be initiated for allocations having host 3D object (hostID) associated */ + VBOXCMDVBVAOFFSET offVRAM; +} VBOXCMDVBVA_PAGING_FILL; + +#define VBOXCMDVBVACTL_TYPE_ENABLE 1 +#define VBOXCMDVBVACTL_TYPE_3DCTL 2 + +typedef struct VBOXCMDVBVA_CTL +{ + uint32_t u32Type; + int32_t i32Result; +} VBOXCMDVBVA_CTL; + +typedef struct VBOXCMDVBVA_CTL_ENABLE +{ + VBOXCMDVBVA_CTL Hdr; + VBVAENABLE Enable; +} VBOXCMDVBVA_CTL_ENABLE; + +#define VBOXCMDVBVA3DCTL_TYPE_CONNECT 1 +#define VBOXCMDVBVA3DCTL_TYPE_DISCONNECT 2 +#define VBOXCMDVBVA3DCTL_TYPE_CMD 3 + +typedef struct VBOXCMDVBVA_3DCTL +{ + uint32_t u32Type; + uint32_t u32CmdClientId; +} VBOXCMDVBVA_3DCTL; + +typedef struct VBOXCMDVBVA_3DCTL_CONNECT +{ + VBOXCMDVBVA_3DCTL Hdr; + uint32_t u32MajorVersion; + uint32_t u32MinorVersion; + uint64_t u64Pid; +} VBOXCMDVBVA_3DCTL_CONNECT; + +typedef struct VBOXCMDVBVA_3DCTL_CMD +{ + VBOXCMDVBVA_3DCTL Hdr; + VBOXCMDVBVA_HDR Cmd; +} VBOXCMDVBVA_3DCTL_CMD; + +#pragma pack() + #ifdef VBOXVDMA_WITH_VBVA # pragma pack(1) diff --git a/include/VBox/VBoxVideo3D.h b/include/VBox/VBoxVideo3D.h index 91c6e306..56196dc0 100644 --- a/include/VBox/VBoxVideo3D.h +++ b/include/VBox/VBoxVideo3D.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -95,6 +95,8 @@ struct VBOXTLSREFDATA_DUMMY VBoxTlsRefAssertImpl(cRefs > 1 || (_p)->enmTlsRefState == VBOXTLSREFDATA_STATE_DESTROYING); \ } while (0) +#define VBoxTlsRefCountGet(_p) (ASMAtomicReadS32(&(_p)->cTlsRefs)) + #define VBoxTlsRefRelease(_p) do { \ int cRefs = ASMAtomicDecS32(&(_p)->cTlsRefs); \ VBoxTlsRefAssertImpl(cRefs >= 0); \ @@ -133,4 +135,10 @@ struct VBOXTLSREFDATA_DUMMY } \ } while (0) + +/* host 3D->Fe[/Qt] notification mechanism defines */ +#define VBOX3D_NOTIFY_EVENT_TYPE_VISIBLE_3DDATA 2 +#define VBOX3D_NOTIFY_EVENT_TYPE_TEST_FUNCTIONAL 3 + + #endif /* #ifndef ___VBox_VBoxVideo3D_h */ diff --git a/include/VBox/VBoxVideoGuest.h b/include/VBox/VBoxVideoGuest.h index b0718231..e88afe6b 100644 --- a/include/VBox/VBoxVideoGuest.h +++ b/include/VBox/VBoxVideoGuest.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2006-2011 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -38,6 +38,8 @@ RT_C_DECLS_BEGIN # include "ntddvdeo.h" # include <Video.h> RT_C_DECLS_END +#elif defined VBOX_GUESTR3XORGMOD +# include <compiler.h> #else # include <iprt/asm-amd64-x86.h> #endif @@ -123,6 +125,8 @@ DECLINLINE(void) VBoxVideoCmnPortWriteUchar(RTIOPORT Port, uint8_t Value) { #ifdef VBOX_XPDM_MINIPORT VideoPortWritePortUchar((PUCHAR)Port, Value); +#elif defined VBOX_GUESTR3XORGMOD + outb(Port, Value); #else /** @todo make these explicit */ ASMOutU8(Port, Value); #endif @@ -133,6 +137,8 @@ DECLINLINE(void) VBoxVideoCmnPortWriteUshort(RTIOPORT Port, uint16_t Value) { #ifdef VBOX_XPDM_MINIPORT VideoPortWritePortUshort((PUSHORT)Port,Value); +#elif defined VBOX_GUESTR3XORGMOD + outw(Port, Value); #else ASMOutU16(Port, Value); #endif @@ -143,6 +149,8 @@ DECLINLINE(void) VBoxVideoCmnPortWriteUlong(RTIOPORT Port, uint32_t Value) { #ifdef VBOX_XPDM_MINIPORT VideoPortWritePortUlong((PULONG)Port,Value); +#elif defined VBOX_GUESTR3XORGMOD + outl(Port, Value); #else ASMOutU32(Port, Value); #endif @@ -153,6 +161,8 @@ DECLINLINE(uint8_t) VBoxVideoCmnPortReadUchar(RTIOPORT Port) { #ifdef VBOX_XPDM_MINIPORT return VideoPortReadPortUchar((PUCHAR)Port); +#elif defined VBOX_GUESTR3XORGMOD + return inb(Port); #else return ASMInU8(Port); #endif @@ -163,6 +173,8 @@ DECLINLINE(uint16_t) VBoxVideoCmnPortReadUshort(RTIOPORT Port) { #ifdef VBOX_XPDM_MINIPORT return VideoPortReadPortUshort((PUSHORT)Port); +#elif defined VBOX_GUESTR3XORGMOD + return inw(Port); #else return ASMInU16(Port); #endif @@ -173,6 +185,8 @@ DECLINLINE(uint32_t) VBoxVideoCmnPortReadUlong(RTIOPORT Port) { #ifdef VBOX_XPDM_MINIPORT return VideoPortReadPortUlong((PULONG)Port); +#elif defined VBOX_GUESTR3XORGMOD + return inl(Port); #else return ASMInU32(Port); #endif diff --git a/include/VBox/VBoxVideoHost3D.h b/include/VBox/VBoxVideoHost3D.h new file mode 100644 index 00000000..21c7da94 --- /dev/null +++ b/include/VBox/VBoxVideoHost3D.h @@ -0,0 +1,128 @@ +/** @file + * + * VirtualBox 3D host inter-components interfaces + */ + +/* + * Copyright (C) 2011-2012 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL) only, as it comes in the "COPYING.CDDL" file of the + * VirtualBox OSE distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + */ +#ifndef ___VBox_VBoxVideoHost3D_h +#define ___VBox_VBoxVideoHost3D_h +#include <iprt/cdefs.h> +#include <VBox/VBoxVideo.h> + +/* screen update instance */ +typedef struct PDMIDISPLAYCONNECTOR *HVBOXCRCMDCLTSCR; +struct VBVACMDHDR; + +typedef struct VBOXCMDVBVA_HDR *PVBOXCMDVBVA_HDR; + +typedef DECLCALLBACKPTR(void, PFNVBOXCRCMD_CLTSCR_UPDATE_BEGIN)(HVBOXCRCMDCLTSCR hClt, unsigned u32Screen); +typedef DECLCALLBACKPTR(void, PFNVBOXCRCMD_CLTSCR_UPDATE_END)(HVBOXCRCMDCLTSCR hClt, unsigned uScreenId, int32_t x, int32_t y, uint32_t cx, uint32_t cy); +typedef DECLCALLBACKPTR(void, PFNVBOXCRCMD_CLTSCR_UPDATE_PROCESS)(HVBOXCRCMDCLTSCR hClt, unsigned u32Screen, struct VBVACMDHDR *pCmd, size_t cbCmd); + +/*client callbacks to be used by the server + * when working in the CrCmd mode */ +typedef struct VBOXCRCMD_SVRENABLE_INFO +{ + HVBOXCRCMDCLTSCR hCltScr; + PFNVBOXCRCMD_CLTSCR_UPDATE_BEGIN pfnCltScrUpdateBegin; + PFNVBOXCRCMD_CLTSCR_UPDATE_PROCESS pfnCltScrUpdateProcess; + PFNVBOXCRCMD_CLTSCR_UPDATE_END pfnCltScrUpdateEnd; +} VBOXCRCMD_SVRENABLE_INFO; + +typedef void * HVBOXCRCMDSVR; + +/* enables the CrCmd interface, thus the hgcm interface gets disabled. + * all subsequent calls will be done in the thread Enable was done, + * until the Disable is called */ +typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_ENABLE)(HVBOXCRCMDSVR hSvr, VBOXCRCMD_SVRENABLE_INFO *pInfo); +/* Opposite to Enable (see above) */ +typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_DISABLE)(HVBOXCRCMDSVR hSvr); +/* process command */ +typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_CMD)(HVBOXCRCMDSVR hSvr, PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd); +/* process host control */ +typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_HOSTCTL)(HVBOXCRCMDSVR hSvr, uint8_t* pCtl, uint32_t cbCmd); +/* process guest control */ +typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_GUESTCTL)(HVBOXCRCMDSVR hSvr, uint8_t* pCtl, uint32_t cbCmd); +/* process SaveState */ +typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_SAVESTATE)(HVBOXCRCMDSVR hSvr, PSSMHANDLE pSSM); +/* process LoadState */ +typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_LOADSTATE)(HVBOXCRCMDSVR hSvr, PSSMHANDLE pSSM, uint32_t u32Version); + + +typedef struct VBOXCRCMD_SVRINFO +{ + HVBOXCRCMDSVR hSvr; + PFNVBOXCRCMD_SVR_ENABLE pfnEnable; + PFNVBOXCRCMD_SVR_DISABLE pfnDisable; + PFNVBOXCRCMD_SVR_CMD pfnCmd; + PFNVBOXCRCMD_SVR_HOSTCTL pfnHostCtl; + PFNVBOXCRCMD_SVR_GUESTCTL pfnGuestCtl; + PFNVBOXCRCMD_SVR_SAVESTATE pfnSaveState; + PFNVBOXCRCMD_SVR_LOADSTATE pfnLoadState; +} VBOXCRCMD_SVRINFO; + + +typedef struct VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP +{ + VBOXVDMACMD_CHROMIUM_CTL Hdr; + union + { + void *pvVRamBase; + uint64_t uAlignment; + }; + uint64_t cbVRam; + /* out */ + struct VBOXCRCMD_SVRINFO CrCmdServerInfo; +} VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP, *PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP; + +typedef enum +{ + VBOXCRCMDCTL_TYPE_HGCM = 1, + VBOXCRCMDCTL_TYPE_DISABLE, + VBOXCRCMDCTL_TYPE_ENABLE, + VBOXCRCMDCTL_TYPE_32bit = 0x7fffffff +} VBOXCRCMDCTL_TYPE; + +typedef struct VBOXCRCMDCTL +{ + VBOXCRCMDCTL_TYPE enmType; + uint32_t u32Function; + /* not to be used by clients */ + union + { + void(*pfnInternal)(); + void* pvInternal; + }; +} VBOXCRCMDCTL; + +typedef struct VBOXVDMAHOST * HVBOXCRCMDCTL_REMAINING_HOST_COMMAND; + +typedef DECLCALLBACKPTR(uint8_t*, PFNVBOXCRCMDCTL_REMAINING_HOST_COMMAND)(HVBOXCRCMDCTL_REMAINING_HOST_COMMAND hClient, uint32_t *pcbCtl, int prevCmdRc); + +typedef struct VBOXCRCMDCTL_ENABLE +{ + VBOXCRCMDCTL Hdr; + HVBOXCRCMDCTL_REMAINING_HOST_COMMAND hRHCmd; + PFNVBOXCRCMDCTL_REMAINING_HOST_COMMAND pfnRHCmd; +} VBOXCRCMDCTL_ENABLE; + +#endif /*#ifndef ___VBox_VBoxVideoHost3D_h*/ diff --git a/include/VBox/VDEPlugSymDefs.h b/include/VBox/VDEPlugSymDefs.h index 483b7834..fd11a8ca 100644 --- a/include/VBox/VDEPlugSymDefs.h +++ b/include/VBox/VDEPlugSymDefs.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2008-2010 Oracle Corporation + * Copyright (C) 2008-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/VMMDev.h b/include/VBox/VMMDev.h index fe81237d..fb850625 100644 --- a/include/VBox/VMMDev.h +++ b/include/VBox/VMMDev.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2011 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -35,8 +35,10 @@ #include <iprt/assert.h> +#pragma pack(4) /* force structure dword packing here. */ RT_C_DECLS_BEGIN + /** @defgroup grp_vmmdev VMM Device * * Note! This interface cannot be changed, it can only be extended! @@ -114,6 +116,10 @@ RT_C_DECLS_BEGIN /** Maximum request packet size. */ #define VMMDEV_MAX_VMMDEVREQ_SIZE _1M +/** Maximum number of HGCM parameters. */ +#define VMMDEV_MAX_HGCM_PARMS 1024 +/** Maximum total size of hgcm buffers in one call. */ +#define VMMDEV_MAX_HGCM_DATA_SIZE UINT32_C(0x7FFFFFFF) /** * VMMDev request types. @@ -138,6 +144,7 @@ typedef enum VMMDevReq_ReportGuestInfo = 50, VMMDevReq_ReportGuestInfo2 = 58, /* since version 3.2.0 */ VMMDevReq_ReportGuestStatus = 59, /* since version 3.2.8 */ + VMMDevReq_ReportGuestUserState = 74, /* since version 4.3 */ /** * Retrieve a display resize request sent by the host using * @a IDisplay:setVideoModeHint. Deprecated. @@ -170,6 +177,7 @@ typedef enum VMMDevReq_ReportGuestCapabilities = 55, VMMDevReq_SetGuestCapabilities = 56, VMMDevReq_VideoModeSupported2 = 57, /* since version 3.2.0 */ + VMMDevReq_GetDisplayChangeRequestEx = 80, /* since version 4.2.4 */ #ifdef VBOX_WITH_HGCM VMMDevReq_HGCMConnect = 60, VMMDevReq_HGCMDisconnect = 61, @@ -231,7 +239,6 @@ typedef enum /** Version of VMMDevRequestHeader structure. */ #define VMMDEV_REQUEST_HEADER_VERSION (0x10001) -#pragma pack(4) /* force structure dword packing here. */ /** * Generic VMMDev request header. @@ -286,8 +293,7 @@ AssertCompileSize(VMMDevReqMouseStatus, 24+12); * cursor itself, the guest installs a hardware mouse driver. Don't ask the * guest to switch to a software cursor then. */ #define VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR RT_BIT(2) -/** The host does NOT provide support for drawing the cursor itself. - * This is for instance the case for the L4 console. */ +/** The host does NOT provide support for drawing the cursor itself. */ #define VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER RT_BIT(3) /** The guest can read VMMDev events to find out about pointer movement */ #define VMMDEV_MOUSE_NEW_PROTOCOL RT_BIT(4) @@ -800,6 +806,73 @@ AssertCompileSize(VMMDevReportGuestStatus, 24+12); /** + * The current status of specific guest user. + * This needs to be kept in sync with GuestUserState of the Main API! + */ +typedef enum VBoxGuestUserState +{ + VBoxGuestUserState_Unknown = 0, + VBoxGuestUserState_LoggedIn = 1, + VBoxGuestUserState_LoggedOut = 2, + VBoxGuestUserState_Locked = 3, + VBoxGuestUserState_Unlocked = 4, + VBoxGuestUserState_Disabled = 5, + VBoxGuestUserState_Idle = 6, + VBoxGuestUserState_InUse = 7, + VBoxGuestUserState_Created = 8, + VBoxGuestUserState_Deleted = 9, + VBoxGuestUserState_SessionChanged = 10, + VBoxGuestUserState_CredentialsChanged = 11, + VBoxGuestUserState_RoleChanged = 12, + VBoxGuestUserState_GroupAdded = 13, + VBoxGuestUserState_GroupRemoved = 14, + VBoxGuestUserState_Elevated = 15, + VBoxGuestUserState_SizeHack = 0x7fffffff +} VBoxGuestUserState; +AssertCompileSize(VBoxGuestUserState, 4); + + +/** + * Guest user status updates. + */ +typedef struct VBoxGuestUserStatus +{ + /** The guest user state to send. */ + VBoxGuestUserState state; + /** Size (in bytes) of szUser. */ + uint32_t cbUser; + /** Size (in bytes) of szDomain. */ + uint32_t cbDomain; + /** Size (in bytes) of aDetails. */ + uint32_t cbDetails; + /** Note: Here begins the dynamically + * allocated region. */ + /** Guest user to report state for. */ + char szUser[1]; + /** Domain the guest user is bound to. */ + char szDomain[1]; + /** Optional details of the state. */ + uint8_t aDetails[1]; +} VBoxGuestUserStatus; +AssertCompileSize(VBoxGuestUserStatus, 20); + + +/** + * Guest user status structure. + * + * Used by VMMDevReq_ReportGuestUserStatus. + */ +typedef struct +{ + /** Header. */ + VMMDevRequestHeader header; + /** Guest user status. */ + VBoxGuestUserStatus status; +} VMMDevReportGuestUserState; +AssertCompileSize(VMMDevReportGuestUserState, 24+20); + + +/** * Guest statistics structure. * * Used by VMMDevReportGuestStats and PDMIVMMDEVCONNECTOR::pfnReportStatistics. @@ -959,7 +1032,6 @@ AssertCompileSize(VMMDevGetStatisticsChangeRequest, 24+8); * * Used by VMMDevReq_QueryCredentials. */ -#pragma pack(4) typedef struct { /** Header. */ @@ -974,7 +1046,6 @@ typedef struct char szDomain[VMMDEV_CREDENTIALS_SZ_SIZE]; } VMMDevCredentials; AssertCompileSize(VMMDevCredentials, 24+4+3*128); -#pragma pack() /** @name Credentials request flag (VMMDevCredentials::u32Flags) * @{ */ @@ -1072,6 +1143,40 @@ AssertCompileSize(VMMDevDisplayChangeRequest2, 24+20); /** + * Display change request structure, version Extended. + * + * Used by VMMDevReq_GetDisplayChangeRequestEx. + */ +typedef struct +{ + /** Header. */ + VMMDevRequestHeader header; + /** Horizontal pixel resolution (0 = do not change). */ + uint32_t xres; + /** Vertical pixel resolution (0 = do not change). */ + uint32_t yres; + /** Bits per pixel (0 = do not change). */ + uint32_t bpp; + /** Setting this to VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST indicates + * that the request is a response to that event. + * (Don't confuse this with VMMDevReq_AcknowledgeEvents.) */ + uint32_t eventAck; + /** 0 for primary display, 1 for the first secondary, etc. */ + uint32_t display; + /** New OriginX of secondary virtual screen */ + uint32_t cxOrigin; + /** New OriginY of secondary virtual screen */ + uint32_t cyOrigin; + /** Change in origin of the secondary virtaul scree is + * required */ + bool fChangeOrigin; + /** secondary virtual screen enabled or disabled */ + bool fEnabled; +} VMMDevDisplayChangeRequestEx; +AssertCompileSize(VMMDevDisplayChangeRequestEx, 24+32); + + +/** * Video mode supported request structure. * * Used by VMMDevReq_VideoModeSupported. @@ -1388,8 +1493,6 @@ typedef struct AssertCompileSize(VMMDevReqWriteCoreDump, 24+4); -#pragma pack() - #ifdef VBOX_WITH_HGCM @@ -1401,8 +1504,6 @@ AssertCompileSize(VMMDevReqWriteCoreDump, 24+4); # define VBOX_HGCM_REQ_CANCELLED (0x2) /** @} */ -# pragma pack(4) - /** * HGCM request header. */ @@ -1745,7 +1846,6 @@ typedef struct } HGCMPageListInfo; AssertCompileSize(HGCMPageListInfo, 4+2+2+8); -# pragma pack() /** Get the pointer to the first parmater of a HGCM call request. */ # define VMMDEV_HGCM_CALL_PARMS(a) ((HGCMFunctionParameter *)((uint8_t *)(a) + sizeof (VMMDevHGCMCall))) @@ -1800,6 +1900,7 @@ AssertCompileSize(VMMDevHGCMCancel2, 24+4); /** * Inline helper to determine the request size for the given operation. + * Returns 0 if the given operation is not handled and/or supported. * * @returns Size. * @param requestType The VMMDev request type. @@ -1835,10 +1936,14 @@ DECLINLINE(size_t) vmmdevGetRequestSize(VMMDevRequestType requestType) return sizeof(VMMDevReportGuestInfo2); case VMMDevReq_ReportGuestStatus: return sizeof(VMMDevReportGuestStatus); + case VMMDevReq_ReportGuestUserState: + return sizeof(VMMDevReportGuestUserState); case VMMDevReq_GetDisplayChangeRequest: return sizeof(VMMDevDisplayChangeRequest); case VMMDevReq_GetDisplayChangeRequest2: return sizeof(VMMDevDisplayChangeRequest2); + case VMMDevReq_GetDisplayChangeRequestEx: + return sizeof(VMMDevDisplayChangeRequestEx); case VMMDevReq_VideoModeSupported: return sizeof(VMMDevVideoModeSupportedRequest); case VMMDevReq_GetHeightReduction: @@ -1907,8 +2012,10 @@ DECLINLINE(size_t) vmmdevGetRequestSize(VMMDevRequestType requestType) case VMMDevReq_GetSessionId: return sizeof(VMMDevReqSessionId); default: - return 0; + break; } + + return 0; } @@ -1944,7 +2051,6 @@ DECLINLINE(int) vmmdevInitRequest(VMMDevRequestHeader *req, VMMDevRequestType ty * * @todo Where does this fit in? */ -#pragma pack(1) /* unnecessary */ typedef struct VBVACMDHDR { /** Coordinates of affected rectangle. */ @@ -1953,7 +2059,7 @@ typedef struct VBVACMDHDR uint16_t w; uint16_t h; } VBVACMDHDR; -#pragma pack() +AssertCompileSize(VBVACMDHDR, 8); /** @name VBVA ring defines. * @@ -1983,6 +2089,8 @@ typedef struct VBVACMDHDR #define VBVA_F_MODE_VRDP_RESET (0x00000004) #define VBVA_F_MODE_VRDP_ORDER_MASK (0x00000008) +#define VBVA_F_STATE_PROCESSING (0x00010000) + #define VBVA_F_RECORD_PARTIAL (0x80000000) /** @} */ @@ -2002,7 +2110,6 @@ AssertCompileSize(VBVARECORD, 4); * * This is a subsection of the VMMDevMemory structure. */ -#pragma pack(1) /* paranoia */ typedef struct VBVAMEMORY { /** VBVA_F_MODE_*. */ @@ -2029,14 +2136,12 @@ typedef struct VBVAMEMORY uint32_t fu32SupportedOrders; } VBVAMEMORY; -#pragma pack() AssertCompileSize(VBVAMEMORY, 12 + (_4M-_1K) + 4*64 + 12); /** * The layout of VMMDEV RAM region that contains information for guest. */ -#pragma pack(1) /* paranoia */ typedef struct VMMDevMemory { /** The size of this structure. */ @@ -2065,13 +2170,15 @@ typedef struct VMMDevMemory } VMMDevMemory; AssertCompileSize(VMMDevMemory, 8+8 + (12 + (_4M-_1K) + 4*64 + 12) ); -#pragma pack() +AssertCompileMemberOffset(VMMDevMemory, vbvaMemory, 16); /** Version of VMMDevMemory structure (VMMDevMemory::u32Version). */ #define VMMDEV_MEMORY_VERSION (1) /** @} */ + RT_C_DECLS_END +#pragma pack() #endif diff --git a/include/VBox/VMMDev2.h b/include/VBox/VMMDev2.h index 3a8ebbed..c8709f72 100644 --- a/include/VBox/VMMDev2.h +++ b/include/VBox/VMMDev2.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2009 Oracle Corporation + * Copyright (C) 2006-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/apic.h b/include/VBox/apic.h index 2d0b8a6f..0b22f11e 100644 --- a/include/VBox/apic.h +++ b/include/VBox/apic.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2010-2011 Oracle Corporation + * Copyright (C) 2010-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -31,28 +31,41 @@ #include <iprt/types.h> #define APIC_REG_VERSION 0x0030 -#define APIC_REG_VERSION_GET_VER(u32) (u32 & 0xff) -#define APIC_REG_VERSION_GET_MAX_LVT(u32) ((u32 & 0xff0000) >> 16) +#define APIC_REG_VERSION_GET_VER(u32) (u32 & 0xff) +#define APIC_REG_VERSION_GET_MAX_LVT(u32) ((u32 & 0xff0000) >> 16) -/* defines according to Figure 10-8 of the Intel Software Developers Manual Vol 3A */ +/* Defines according to Figure 10-8 of the Intel Software Developers Manual Vol 3A */ #define APIC_REG_LVT_LINT0 0x0350 #define APIC_REG_LVT_LINT1 0x0360 #define APIC_REG_LVT_ERR 0x0370 #define APIC_REG_LVT_PC 0x0340 #define APIC_REG_LVT_THMR 0x0330 -#define APIC_REG_LVT_MODE_MASK (RT_BIT(8)|RT_BIT(9)|RT_BIT(10)) -#define APIC_REG_LVT_MODE_FIXED 0 -#define APIC_REG_LVT_MODE_NMI (RT_BIT(10)) -#define APIC_REG_LVT_MODE_EXTINT (RT_BIT(8)|RT_BIT(9)|RT_BIT(10)) -#define APIC_REG_LVT_PIN_POLARIY RT_BIT(13) -#define APIC_REG_LVT_REMOTE_IRR RT_BIT(14) -#define APIC_REG_LVT_LEVEL_TRIGGER RT_BIT(15) -#define APIC_REG_LVT_MASKED RT_BIT(16) +#define APIC_REG_LVT_MODE_MASK (RT_BIT(8) | RT_BIT(9) | RT_BIT(10)) +#define APIC_REG_LVT_MODE_FIXED 0 +#define APIC_REG_LVT_MODE_NMI RT_BIT(10) +#define APIC_REG_LVT_MODE_EXTINT (RT_BIT(8) | RT_BIT(9) | RT_BIT(10)) +#define APIC_REG_LVT_PIN_POLARIY RT_BIT(13) +#define APIC_REG_LVT_REMOTE_IRR RT_BIT(14) +#define APIC_REG_LVT_LEVEL_TRIGGER RT_BIT(15) +#define APIC_REG_LVT_MASKED RT_BIT(16) DECLINLINE(uint32_t) ApicRegRead(void *pvBase, uint32_t offReg) { return *(const volatile uint32_t *)((uintptr_t)pvBase + offReg); } + +#ifdef ___iprt_asm_amd64_x86_h +/** + * Reads an X2APIC register. + * + * @param offReg MMIO offset, APIC_REG_XXX. + */ +DECLINLINE(uint32_t) ApicX2RegRead32(uint32_t offReg) +{ + return ASMRdMsr((offReg >> 4) + MSR_IA32_X2APIC_START); +} #endif +#endif /* ___VBox_apic_h */ + diff --git a/include/VBox/apic.mac b/include/VBox/apic.mac index 57eb7ca8..9f6bea48 100644 --- a/include/VBox/apic.mac +++ b/include/VBox/apic.mac @@ -1,19 +1,21 @@ %ifndef ___VBox_apic_h %define ___VBox_apic_h %define APIC_REG_VERSION 0x0030 -%define APIC_REG_VERSION_GET_VER(u32) (u32 & 0xff) -%define APIC_REG_VERSION_GET_MAX_LVT(u32) ((u32 & 0xff0000) >> 16) +%define APIC_REG_VERSION_GET_VER(u32) (u32 & 0xff) +%define APIC_REG_VERSION_GET_MAX_LVT(u32) ((u32 & 0xff0000) >> 16) %define APIC_REG_LVT_LINT0 0x0350 %define APIC_REG_LVT_LINT1 0x0360 %define APIC_REG_LVT_ERR 0x0370 %define APIC_REG_LVT_PC 0x0340 %define APIC_REG_LVT_THMR 0x0330 -%define APIC_REG_LVT_MODE_MASK (RT_BIT(8)|RT_BIT(9)|RT_BIT(10)) -%define APIC_REG_LVT_MODE_FIXED 0 -%define APIC_REG_LVT_MODE_NMI (RT_BIT(10)) -%define APIC_REG_LVT_MODE_EXTINT (RT_BIT(8)|RT_BIT(9)|RT_BIT(10)) -%define APIC_REG_LVT_PIN_POLARIY RT_BIT(13) -%define APIC_REG_LVT_REMOTE_IRR RT_BIT(14) -%define APIC_REG_LVT_LEVEL_TRIGGER RT_BIT(15) -%define APIC_REG_LVT_MASKED RT_BIT(16) +%define APIC_REG_LVT_MODE_MASK (RT_BIT(8) | RT_BIT(9) | RT_BIT(10)) +%define APIC_REG_LVT_MODE_FIXED 0 +%define APIC_REG_LVT_MODE_NMI RT_BIT(10) +%define APIC_REG_LVT_MODE_EXTINT (RT_BIT(8) | RT_BIT(9) | RT_BIT(10)) +%define APIC_REG_LVT_PIN_POLARIY RT_BIT(13) +%define APIC_REG_LVT_REMOTE_IRR RT_BIT(14) +%define APIC_REG_LVT_LEVEL_TRIGGER RT_BIT(15) +%define APIC_REG_LVT_MASKED RT_BIT(16) +%ifdef ___iprt_asm_amd64_x86_h +%endif %endif diff --git a/include/VBox/asmdefs.mac b/include/VBox/asmdefs.mac index 96b0e52d..b877e632 100644 --- a/include/VBox/asmdefs.mac +++ b/include/VBox/asmdefs.mac @@ -3,7 +3,7 @@ ; ; -; Copyright (C) 2006-2007 Oracle Corporation +; Copyright (C) 2006-2011 Oracle Corporation ; ; This file is part of VirtualBox Open Source Edition (OSE), as ; available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/bioslogo.h b/include/VBox/bioslogo.h index b78d1cae..1c5fd041 100644 --- a/include/VBox/bioslogo.h +++ b/include/VBox/bioslogo.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/cdefs.h b/include/VBox/cdefs.h index 652f7f6b..0744b763 100644 --- a/include/VBox/cdefs.h +++ b/include/VBox/cdefs.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -203,9 +203,17 @@ * @param type The return type of the function declaration. */ #ifdef IN_SUP_R3 -# define SUPR3DECL(type) DECLEXPORT(type) VBOXCALL +# ifdef IN_SUP_STATIC +# define SUPR3DECL(type) DECLHIDDEN(type) VBOXCALL +# else +# define SUPR3DECL(type) DECLEXPORT(type) VBOXCALL +# endif #else -# define SUPR3DECL(type) DECLIMPORT(type) VBOXCALL +# ifdef IN_SUP_STATIC +# define SUPR3DECL(type) DECLHIDDEN(type) VBOXCALL +# else +# define SUPR3DECL(type) DECLIMPORT(type) VBOXCALL +# endif #endif /** @def IN_SUP_R0 @@ -409,7 +417,7 @@ * VMM internal function, ring-0 + raw-mode context. * @param type The return type of the function declaration. */ -#ifdef IN_VMM_RZ +#if defined(IN_VMM_RC) || defined(IN_VMM_R0) # define VMMRZ_INT_DECL(type) DECLHIDDEN(type) VBOXCALL #else # define VMMRZ_INT_DECL(type) DECL_INVALID(type) diff --git a/include/VBox/com/AutoLock.h b/include/VBox/com/AutoLock.h index 9c700dd9..12eeccae 100644 --- a/include/VBox/com/AutoLock.h +++ b/include/VBox/com/AutoLock.h @@ -1,5 +1,4 @@ /** @file - * * Automatic locks, implementation */ @@ -24,8 +23,8 @@ * terms and conditions of either the GPL or the CDDL or both. */ -#ifndef ____H_AUTOLOCK -#define ____H_AUTOLOCK +#ifndef ___VBox_com_AutoLock_h +#define ___VBox_com_AutoLock_h #include <iprt/types.h> @@ -633,6 +632,6 @@ public: } /* namespace util */ -#endif // ____H_AUTOLOCK +#endif /* vi: set tabstop=4 shiftwidth=4 expandtab: */ diff --git a/include/VBox/com/ErrorInfo.h b/include/VBox/com/ErrorInfo.h index 1037b253..869b9983 100644 --- a/include/VBox/com/ErrorInfo.h +++ b/include/VBox/com/ErrorInfo.h @@ -1,10 +1,9 @@ /** @file - * MS COM / XPCOM Abstraction Layer: - * ErrorInfo class declaration + * MS COM / XPCOM Abstraction Layer - ErrorInfo class declaration. */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -174,6 +173,7 @@ public: : mIsBasicAvailable(false), mIsFullAvailable(false), mResultCode(S_OK), + mResultDetail(0), m_pNext(NULL) { init(); @@ -183,6 +183,7 @@ public: : mIsBasicAvailable(false), mIsFullAvailable(false), mResultCode(S_OK), + mResultDetail(0), m_pNext(NULL) { init(pObj, aIID); @@ -191,7 +192,7 @@ public: /** Specialization for the IVirtualBoxErrorInfo smart pointer */ ErrorInfo (const ComPtr <IVirtualBoxErrorInfo> &aPtr) : mIsBasicAvailable (false), mIsFullAvailable (false) - , mResultCode (S_OK) + , mResultCode (S_OK), mResultDetail(0) { init (aPtr); } /** @@ -204,7 +205,7 @@ public: */ ErrorInfo (IVirtualBoxErrorInfo *aInfo) : mIsBasicAvailable (false), mIsFullAvailable (false) - , mResultCode (S_OK) + , mResultCode (S_OK), mResultDetail(0) { init (aInfo); } ErrorInfo(const ErrorInfo &x) @@ -267,6 +268,14 @@ public: } /** + * Returns the (optional) result detail code of the failed operation. + */ + LONG getResultDetail() const + { + return mResultDetail; + } + + /** * Returns the IID of the interface that defined the error. */ const Guid& getInterfaceID() const @@ -330,6 +339,8 @@ public: return mCalleeName; } + HRESULT getVirtualBoxErrorInfo(ComPtr<IVirtualBoxErrorInfo> &pVirtualBoxErrorInfo); + /** * Resets all collected error information. #isBasicAvailable() and * #isFullAvailable will return @c true after this method is called. @@ -359,6 +370,7 @@ protected: bool mIsFullAvailable : 1; HRESULT mResultCode; + LONG mResultDetail; Guid mInterfaceID; Bstr mComponent; Bstr mText; @@ -444,6 +456,19 @@ public: } /** + * Constructs a new instance from an ErrorInfo object, to inject a full + * error info created elsewhere. + * + * @param aInfo @c true to prevent fetching error info and leave + * the instance uninitialized. + */ + ErrorInfoKeeper(const ErrorInfo &aInfo) + : ErrorInfo(false), mForgot(false) + { + copyFrom(aInfo); + } + + /** * Destroys this instance and automatically calls #restore() which will * either restore error info fetched by the constructor or do nothing * if #forget() was called before destruction. diff --git a/include/VBox/com/EventQueue.h b/include/VBox/com/EventQueue.h index 14f4fc84..2f6587ce 100644 --- a/include/VBox/com/EventQueue.h +++ b/include/VBox/com/EventQueue.h @@ -1,10 +1,10 @@ +/* $Id: EventQueue.h $ */ /** @file - * MS COM / XPCOM Abstraction Layer: - * Event and EventQueue class declaration + * Event queue class declaration. */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -27,11 +27,10 @@ #ifndef ___VBox_com_EventQueue_h #define ___VBox_com_EventQueue_h -#ifndef VBOX_WITH_XPCOM -# include <Windows.h> -#else // VBOX_WITH_XPCOM -# include <nsEventQueueUtils.h> -#endif // VBOX_WITH_XPCOM +#include <list> + +#include <iprt/asm.h> +#include <iprt/critsect.h> #include <VBox/com/defs.h> #include <VBox/com/assert.h> @@ -52,8 +51,21 @@ class Event { public: - Event() {} - virtual ~Event() {}; + Event(void) : + mRefCount(0) { } + virtual ~Event(void) { AssertMsg(!mRefCount, + ("Reference count of event=%p not 0 on destruction (is %RU32)\n", + this, mRefCount)); } +public: + + uint32_t AddRef(void) { return ASMAtomicIncU32(&mRefCount); } + void Release(void) + { + Assert(mRefCount); + uint32_t cRefs = ASMAtomicDecU32(&mRefCount); + if (!cRefs) + delete this; + } protected: @@ -63,78 +75,56 @@ protected: * * @return reserved, should be NULL. */ - virtual void *handler() { return NULL; } + virtual void *handler(void) { return NULL; } friend class EventQueue; + +protected: + + /** The event's reference count. */ + uint32_t mRefCount; }; +typedef std::list< Event* > EventQueueList; +typedef std::list< Event* >::iterator EventQueueListIterator; +typedef std::list< Event* >::const_iterator EventQueueListIteratorConst; + /** * Simple event queue. - * - * When using XPCOM, this will map onto the default XPCOM queue for the thread. - * So, if a queue is created on the main thread, it automatically processes - * XPCOM/IPC events while waiting. - * - * When using Windows, Darwin and OS/2, this will map onto the native thread - * queue/runloop. So, windows messages and what not will be processed while - * waiting for events. - * - * @note It is intentional that there is no way to retrieve arbitrary - * events and controlling their processing. There is no use case which - * warrants introducing the complexity of platform independent events. */ class EventQueue { public: - EventQueue(); - ~EventQueue(); + EventQueue(void); + virtual ~EventQueue(void); + +public: BOOL postEvent(Event *event); int processEventQueue(RTMSINTERVAL cMsTimeout); + int processPendingEvents(size_t cNumEvents); int interruptEventQueueProcessing(); - int getSelectFD(); - static int init(); - static int uninit(); - static EventQueue *getMainEventQueue(); - -#ifdef VBOX_WITH_XPCOM - already_AddRefed<nsIEventQueue> getIEventQueue() - { - return mEventQ.get(); - } -#else - static int dispatchMessageOnWindows(MSG const *pMsg, int rc); -#endif private: - static EventQueue *sMainQueue; - -#ifndef VBOX_WITH_XPCOM - - /** The thread which the queue belongs to. */ - DWORD mThreadId; - /** Duplicated thread handle for MsgWaitForMultipleObjects. */ - HANDLE mhThread; -#else // VBOX_WITH_XPCOM - - /** Whether it was created (and thus needs destroying) or if a queue already - * associated with the thread was used. */ - bool mEQCreated; - - /** Whether event processing should be interrupted. */ - bool mInterrupted; - - nsCOMPtr <nsIEventQueue> mEventQ; - nsCOMPtr <nsIEventQueueService> mEventQService; - - static void *PR_CALLBACK plEventHandler(PLEvent *self); - static void PR_CALLBACK plEventDestructor(PLEvent *self); - -#endif // VBOX_WITH_XPCOM + /** Critical section for serializing access to this + * event queue. */ + RTCRITSECT mCritSect; + /** Number of concurrent users. At the moment we + * only support one concurrent user at a time when + calling processEventQueue(). */ + uint32_t mUserCnt; + /** Event semaphore for getting notified on new + * events being handled. */ + RTSEMEVENT mSemEvent; + /** The actual event queue, implemented as a list. */ + EventQueueList mEvents; + /** Shutdown indicator. */ + bool mShutdown; }; } /* namespace com */ #endif + diff --git a/include/VBox/com/Guid.h b/include/VBox/com/Guid.h index c55d69dc..969780b5 100644 --- a/include/VBox/com/Guid.h +++ b/include/VBox/com/Guid.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -47,6 +47,13 @@ namespace com { +typedef enum + { + ZERO_GUID, + NORMAL_GUID, + INVALID_GUID + }GuidState_t; + /** * Helper class that represents the UUID type and hides platform-specific * implementation details. @@ -59,18 +66,27 @@ public: { ::RTUuidClear(&mUuid); refresh(); + mGuidState = ZERO_GUID; } Guid(const Guid &that) { mUuid = that.mUuid; refresh(); + if (isEmpty()) + mGuidState = ZERO_GUID; + else + mGuidState = NORMAL_GUID; } Guid(const RTUUID &that) { mUuid = that; refresh(); + if (isEmpty()) + mGuidState = ZERO_GUID; + else + mGuidState = NORMAL_GUID; } Guid(const GUID &that) @@ -78,6 +94,10 @@ public: AssertCompileSize(GUID, sizeof(RTUUID)); ::memcpy(&mUuid, &that, sizeof(GUID)); refresh(); + if (isEmpty()) + mGuidState = ZERO_GUID; + else + mGuidState = NORMAL_GUID; } /** @@ -91,9 +111,17 @@ public: */ Guid(const char *that) { + mGuidState = NORMAL_GUID; + int rc = ::RTUuidFromStr(&mUuid, that); + if (RT_FAILURE(rc)) + { ::RTUuidClear(&mUuid); + mGuidState = INVALID_GUID; + } + else if(isEmpty()) + mGuidState = ZERO_GUID; refresh(); } @@ -108,49 +136,84 @@ public: */ Guid(const Bstr &that) { - int rc = !that.isEmpty() - ? ::RTUuidFromUtf16(&mUuid, that.raw()) - : VERR_INVALID_UUID_FORMAT; - if (RT_FAILURE(rc)) + mGuidState = NORMAL_GUID; + + if (that.isEmpty()) + { ::RTUuidClear(&mUuid); + mGuidState = ZERO_GUID; + } + else + { + int rc = ::RTUuidFromUtf16(&mUuid, that.raw()); + if (RT_FAILURE(rc)) + { + ::RTUuidClear(&mUuid); + mGuidState = INVALID_GUID; + } + } + refresh(); } Guid& operator=(const Guid &that) { + mGuidState = NORMAL_GUID; ::memcpy(&mUuid, &that.mUuid, sizeof (RTUUID)); + if (isEmpty()) + mGuidState = ZERO_GUID; refresh(); return *this; } Guid& operator=(const GUID &guid) { + mGuidState = NORMAL_GUID; ::memcpy(&mUuid, &guid, sizeof (GUID)); + if (isEmpty()) + mGuidState = ZERO_GUID; refresh(); return *this; } Guid& operator=(const RTUUID &guid) { + mGuidState = NORMAL_GUID; ::memcpy(&mUuid, &guid, sizeof (RTUUID)); + if (isEmpty()) + mGuidState = ZERO_GUID; refresh(); return *this; } Guid& operator=(const char *str) { + mGuidState = NORMAL_GUID; int rc = ::RTUuidFromStr(&mUuid, str); + if (RT_FAILURE(rc)) + { ::RTUuidClear(&mUuid); + mGuidState = INVALID_GUID; + } + else + { + if (isEmpty()) + mGuidState = ZERO_GUID; + } + refresh(); + return *this; } void create() { ::RTUuidCreate(&mUuid); + mGuidState = NORMAL_GUID; refresh(); } void clear() { ::RTUuidClear(&mUuid); + mGuidState = ZERO_GUID; refresh(); } @@ -163,7 +226,18 @@ public: Utf8Str toString() const { char buf[RTUUID_STR_LENGTH]; + + ::memset(buf,0,RTUUID_STR_LENGTH); + + if (mGuidState == INVALID_GUID) + { + /* What to return in case of wrong Guid */ + return Utf8Str("00000000-0000-0000-0000-00000000000"); + } + ::RTUuidToStr(&mUuid, buf, RTUUID_STR_LENGTH); + + return Utf8Str(buf); } @@ -175,10 +249,19 @@ public: */ Utf8Str toStringCurly() const { + + if (mGuidState == INVALID_GUID) + { + /* What to return in case of wrong Guid */ + return Utf8Str("{00000000-0000-0000-0000-00000000000}"); + } + char buf[RTUUID_STR_LENGTH + 2] = "{"; + ::RTUuidToStr(&mUuid, buf + 1, RTUUID_STR_LENGTH); buf[sizeof(buf) - 2] = '}'; buf[sizeof(buf) - 1] = '\0'; + return Utf8Str(buf); } @@ -190,22 +273,26 @@ public: */ Bstr toUtf16() const { - if (isEmpty()) - return Bstr(); + if (mGuidState == INVALID_GUID) + return Bstr("00000000-0000-0000-0000-00000000000"); RTUTF16 buf[RTUUID_STR_LENGTH]; ::RTUuidToUtf16(&mUuid, buf, RTUUID_STR_LENGTH); return Bstr(buf); } - bool isEmpty() const + bool isValid() const { - return ::RTUuidIsNull(&mUuid); + bool res = true; + if (mGuidState == INVALID_GUID) + res = false; + + return res; } - bool isNotEmpty() const + bool isZero() const { - return !::RTUuidIsNull(&mUuid); + return (::RTUuidIsNull(&mUuid) && mGuidState == ZERO_GUID); } bool operator==(const Guid &that) const { return ::RTUuidCompare(&mUuid, &that.mUuid) == 0; } @@ -256,6 +343,7 @@ public: { if (ppGuid) *ppGuid = (nsID *)nsMemory::Clone(&mUuid, sizeof(nsID)); + return *this; } @@ -308,6 +396,18 @@ public: */ static const Guid Empty; +protected: + + bool isEmpty() const + { + return ::RTUuidIsNull(&mUuid); + } + + bool isNotEmpty() const + { + return !::RTUuidIsNull(&mUuid); + } + private: /** * Refresh the debug-only UUID string. @@ -319,14 +419,16 @@ private: inline void refresh() { #ifdef DEBUG - ::RTUuidToStr(&mUuid, mszUuid, RTUUID_STR_LENGTH); - m_pcszUUID = mszUuid; +// ::RTUuidToStr(&mUuid, mszUuid, RTUUID_STR_LENGTH); +// m_pcszUUID = mszUuid; #endif } /** The UUID. */ RTUUID mUuid; + GuidState_t mGuidState; + #ifdef DEBUG /** String representation of mUuid for printing in the debugger. */ char mszUuid[RTUUID_STR_LENGTH]; @@ -334,18 +436,19 @@ private: const char *m_pcszUUID; #endif }; - +/* inline Bstr asGuidStr(const Bstr& str) { Guid guid(str); return guid.isEmpty() ? Bstr() : guid.toUtf16(); } - -inline bool isValidGuid(const Bstr& str) -{ - Guid guid(str); - return !guid.isEmpty(); -} +*/ +//inline bool isValidGuid(const Bstr& str) +//{ +// Guid guid(str); +// return guid.isValid(); +//// return !guid.isEmpty(); +//} } /* namespace com */ diff --git a/include/VBox/com/MultiResult.h b/include/VBox/com/MultiResult.h index 705e1dbe..e8946468 100644 --- a/include/VBox/com/MultiResult.h +++ b/include/VBox/com/MultiResult.h @@ -1,8 +1,6 @@ /* $Id: MultiResult.h $ */ - /** @file - * MS COM / XPCOM Abstraction Layer: - * MultiResult class declarations + * MS COM / XPCOM Abstraction Layer - MultiResult class declarations. */ /* @@ -258,5 +256,5 @@ private: } /* namespace com */ -#endif /* ___VBox_com_MultiResult_h */ +#endif /* !___VBox_com_MultiResult_h */ diff --git a/include/VBox/com/NativeEventQueue.h b/include/VBox/com/NativeEventQueue.h new file mode 100644 index 00000000..96a872f1 --- /dev/null +++ b/include/VBox/com/NativeEventQueue.h @@ -0,0 +1,140 @@ +/** @file + * MS COM / XPCOM Abstraction Layer: + * Event and EventQueue class declaration + */ + +/* + * Copyright (C) 2006-2013 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL) only, as it comes in the "COPYING.CDDL" file of the + * VirtualBox OSE distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + */ + +#ifndef ___VBox_com_EventQueue_h +#define ___VBox_com_EventQueue_h + +#ifndef VBOX_WITH_XPCOM +# include <Windows.h> +#else // VBOX_WITH_XPCOM +# include <nsEventQueueUtils.h> +#endif // VBOX_WITH_XPCOM + +#include <VBox/com/defs.h> +#include <VBox/com/assert.h> + +namespace com +{ + +class MainEventQueue; + +/** + * Base class for all events. Intended to be subclassed to introduce new + * events and handlers for them. + * + * Subclasses usually reimplement virtual #handler() (that does nothing by + * default) and add new data members describing the event. + */ +class NativeEvent +{ +public: + + NativeEvent() {} + virtual ~NativeEvent() {}; + +protected: + + /** + * Event handler. Called in the context of the event queue's thread. + * Always reimplemented by subclasses + * + * @return reserved, should be NULL. + */ + virtual void *handler() { return NULL; } + + friend class NativeEventQueue; +}; + +/** + * Simple event queue. + * + * When using XPCOM, this will map onto the default XPCOM queue for the thread. + * So, if a queue is created on the main thread, it automatically processes + * XPCOM/IPC events while waiting. + * + * When using Windows, Darwin and OS/2, this will map onto the native thread + * queue/runloop. So, windows messages and what not will be processed while + * waiting for events. + * + * @note It is intentional that there is no way to retrieve arbitrary + * events and controlling their processing. There is no use case which + * warrants introducing the complexity of platform independent events. + */ +class NativeEventQueue +{ +public: + + NativeEventQueue(); + virtual ~NativeEventQueue(); + + BOOL postEvent(NativeEvent *event); + int processEventQueue(RTMSINTERVAL cMsTimeout); + int interruptEventQueueProcessing(); + int getSelectFD(); + static int init(); + static int uninit(); + static NativeEventQueue *getMainEventQueue(); + +#ifdef VBOX_WITH_XPCOM + already_AddRefed<nsIEventQueue> getIEventQueue() + { + return mEventQ.get(); + } +#else + static int dispatchMessageOnWindows(MSG const *pMsg, int rc); +#endif + +private: + static NativeEventQueue *sMainQueue; + +#ifndef VBOX_WITH_XPCOM + + /** The thread which the queue belongs to. */ + DWORD mThreadId; + /** Duplicated thread handle for MsgWaitForMultipleObjects. */ + HANDLE mhThread; + +#else // VBOX_WITH_XPCOM + + /** Whether it was created (and thus needs destroying) or if a queue already + * associated with the thread was used. */ + bool mEQCreated; + + /** Whether event processing should be interrupted. */ + bool mInterrupted; + + nsCOMPtr <nsIEventQueue> mEventQ; + nsCOMPtr <nsIEventQueueService> mEventQService; + + static void *PR_CALLBACK plEventHandler(PLEvent *self); + static void PR_CALLBACK plEventDestructor(PLEvent *self); + +#endif // VBOX_WITH_XPCOM +}; + +} /* namespace com */ + +#endif diff --git a/include/VBox/com/VirtualBox.h b/include/VBox/com/VirtualBox.h index 92fe1e84..288ed8ff 100644 --- a/include/VBox/com/VirtualBox.h +++ b/include/VBox/com/VirtualBox.h @@ -1,22 +1,19 @@ /** @file - * MS COM / XPCOM Abstraction Layer: - * VirtualBox COM Library definitions. + * MS COM / XPCOM Abstraction Layer - VirtualBox COM Library definitions. * - * Note: This is the main header file that COM/XPCOM clients - * include; however, it is only a wrapper around another - * platform-dependent include file that contains the real - * COM/XPCOM interface declarations. That other include file - * is generated automatically at build time from - * /src/VBox/Main/idl/VirtualBox.xidl, which contains all - * the VirtualBox interfaces; the include file is called - * VirtualBox.h on Windows hosts and VirtualBox_XPCOM.h - * on Linux hosts. The build process places it in - * out/<platform>/bin/sdk/include, from where it gets - * included by the rest of the VirtualBox code. + * @note This is the main header file that COM/XPCOM clients include; however, + * it is only a wrapper around another platform-dependent include file + * that contains the real COM/XPCOM interface declarations. That other + * include file is generated automatically at build time from + * /src/VBox/Main/idl/VirtualBox.xidl, which contains all the VirtualBox + * interfaces; the include file is called VirtualBox.h on Windows hosts + * and VirtualBox_XPCOM.h on Linux hosts. The build process places it in + * out/<platform>/bin/sdk/include, from where it gets + * included by the rest of the VirtualBox code. */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -53,3 +50,4 @@ #include "VBox/com/ptr.h" #endif + diff --git a/include/VBox/com/array.h b/include/VBox/com/array.h index 7f1796d9..77f9d60b 100644 --- a/include/VBox/com/array.h +++ b/include/VBox/com/array.h @@ -1,10 +1,9 @@ /** @file - * MS COM / XPCOM Abstraction Layer: - * Safe array helper class declaration + * MS COM / XPCOM Abstraction Layer - Safe array helper class declaration. */ /* - * Copyright (C) 2006-2011 Oracle Corporation + * Copyright (C) 2006-2014 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -608,21 +607,18 @@ public: */ SafeArray(ComSafeArrayIn(T, aArg)) { + if (aArg) + { #ifdef VBOX_WITH_XPCOM - AssertReturnVoid(aArg != NULL); - - m.size = aArgSize; - m.arr = aArg; - m.isWeak = true; + m.size = aArgSize; + m.arr = aArg; + m.isWeak = true; #else /* !VBOX_WITH_XPCOM */ - AssertReturnVoid(aArg != NULL); - SAFEARRAY *arg = aArg; + SAFEARRAY *arg = aArg; - if (arg) - { AssertReturnVoid(arg->cDims == 1); VARTYPE vt; @@ -634,12 +630,12 @@ public: rc = SafeArrayAccessData(arg, (void HUGEP **)&m.raw); AssertComRCReturnVoid(rc); - } - m.arr = arg; - m.isWeak = true; + m.arr = arg; + m.isWeak = true; #endif /* !VBOX_WITH_XPCOM */ + } } /** @@ -975,7 +971,7 @@ public: */ virtual SafeArray &detachTo(ComSafeArrayOut(T, aArg)) { - AssertReturn(m.isWeak == false, *this); + AssertReturn(!m.isWeak, *this); #ifdef VBOX_WITH_XPCOM @@ -1243,6 +1239,34 @@ inline void com::SafeArray<BYTE>::initFrom(const BYTE* aPtr, size_t aSize) template<> +inline void com::SafeArray<SHORT>::initFrom(const com::SafeArray<SHORT> & aRef) +{ + size_t sSize = aRef.size(); + resize(sSize); + ::memcpy(raw(), aRef.raw(), sSize * sizeof(SHORT)); +} +template<> +inline void com::SafeArray<SHORT>::initFrom(const SHORT* aPtr, size_t aSize) +{ + resize(aSize); + ::memcpy(raw(), aPtr, aSize * sizeof(SHORT)); +} + +template<> +inline void com::SafeArray<USHORT>::initFrom(const com::SafeArray<USHORT> & aRef) +{ + size_t sSize = aRef.size(); + resize(sSize); + ::memcpy(raw(), aRef.raw(), sSize * sizeof(USHORT)); +} +template<> +inline void com::SafeArray<USHORT>::initFrom(const USHORT* aPtr, size_t aSize) +{ + resize(aSize); + ::memcpy(raw(), aPtr, aSize * sizeof(USHORT)); +} + +template<> inline void com::SafeArray<LONG>::initFrom(const com::SafeArray<LONG> & aRef) { size_t sSize = aRef.size(); @@ -1523,21 +1547,18 @@ public: */ SafeIfaceArray(ComSafeArrayIn(I *, aArg)) { + if (aArg) + { #ifdef VBOX_WITH_XPCOM - AssertReturnVoid(aArg != NULL); - - Base::m.size = aArgSize; - Base::m.arr = aArg; - Base::m.isWeak = true; + Base::m.size = aArgSize; + Base::m.arr = aArg; + Base::m.isWeak = true; #else /* !VBOX_WITH_XPCOM */ - AssertReturnVoid(aArg != NULL); - SAFEARRAY *arg = aArg; + SAFEARRAY *arg = aArg; - if (arg) - { AssertReturnVoid(arg->cDims == 1); VARTYPE vt; @@ -1555,12 +1576,12 @@ public: rc = SafeArrayAccessData(arg, (void HUGEP **)&m.raw); AssertComRCReturnVoid(rc); - } - m.arr = arg; - m.isWeak = true; + m.arr = arg; + m.isWeak = true; #endif /* !VBOX_WITH_XPCOM */ + } } /** @@ -1699,4 +1720,5 @@ public: /** @} */ -#endif /* ___VBox_com_array_h */ +#endif /* !___VBox_com_array_h */ + diff --git a/include/VBox/com/assert.h b/include/VBox/com/assert.h index 0a9b1afd..900ce131 100644 --- a/include/VBox/com/assert.h +++ b/include/VBox/com/assert.h @@ -1,10 +1,9 @@ /** @file - * MS COM / XPCOM Abstraction Layer: - * Assertion macros for COM/XPCOM + * MS COM / XPCOM Abstraction Layer - Assertion macros for COM/XPCOM. */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -106,3 +105,4 @@ if (!SUCCEEDED (rc)) { AssertComRC (rc); throw rc; } else do {} while (0) #endif // !___VBox_com_assert_h + diff --git a/include/VBox/com/com.h b/include/VBox/com/com.h index 524c89c6..92502689 100644 --- a/include/VBox/com/com.h +++ b/include/VBox/com/com.h @@ -1,6 +1,5 @@ /** @file - * MS COM / XPCOM Abstraction Layer: - * COM initialization / shutdown + * MS COM / XPCOM Abstraction Layer - COM initialization / shutdown. */ /* diff --git a/include/VBox/com/defs.h b/include/VBox/com/defs.h index aa9800dd..65db7938 100644 --- a/include/VBox/com/defs.h +++ b/include/VBox/com/defs.h @@ -1,10 +1,9 @@ /** @file - * MS COM / XPCOM Abstraction Layer: - * Common definitions + * MS COM / XPCOM Abstraction Layer - Common definitions. */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2014 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -59,16 +58,16 @@ # define RT_MAX(Value1, Value2) ( (Value1) >= (Value2) ? (Value1) : (Value2) ) # endif -#endif /* defined (RT_OS_OS2) */ +#endif /* defined(RT_OS_OS2) */ /* Include iprt/types.h (which also includes iprt/types.h) now to make sure iprt * gets to stdint.h first, otherwise a system/xpcom header might beat us and * we'll be without the macros that are optional in C++. */ #include <iprt/types.h> -#if !defined (VBOX_WITH_XPCOM) +#if !defined(VBOX_WITH_XPCOM) -#if defined (RT_OS_WINDOWS) +#if defined(RT_OS_WINDOWS) // Windows COM ///////////////////////////////////////////////////////////////////////////// @@ -88,7 +87,7 @@ #define NS_DECL_ISUPPORTS /** Returns @c true if @a rc represents a warning result code */ -#define SUCCEEDED_WARNING(rc) (SUCCEEDED (rc) && (rc) != S_OK) +#define SUCCEEDED_WARNING(rc) (SUCCEEDED(rc) && (rc) != S_OK) /** Tests is a COM result code indicates that the process implementing the * interface is dead. @@ -96,12 +95,18 @@ * COM status codes: * 0x800706ba - RPC_S_SERVER_UNAVAILABLE. Killed before call was made. * 0x800706be - RPC_S_CALL_FAILED. Killed after call was made. - * 0x800706bf - RPC_S_CALL_FAILED_DNE. Not observed, but should be matter of timing. + * 0x800706bf - RPC_S_CALL_FAILED_DNE. Not observed, but should be + * matter of timing. + * 0x80010108 - RPC_E_DISCONNECTED. Observed deregistering + * python event listener. + * 0x800706b5 - RPC_S_UNKNOWN_IF. Observed deregistering python + * event listener */ #define FAILED_DEAD_INTERFACE(rc) \ ( (rc) == HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE) \ || (rc) == HRESULT_FROM_WIN32(RPC_S_CALL_FAILED) \ || (rc) == HRESULT_FROM_WIN32(RPC_S_CALL_FAILED_DNE) \ + || (rc) == RPC_E_DISCONNECTED \ ) /** Immutable BSTR string */ @@ -147,7 +152,7 @@ typedef const OLECHAR *CBSTR; /** * Wraps the given parameter name to generate an expression that is suitable for * passing the parameter to functions that take input safearray parameters - * declared using the ComSafeArrayIn marco. + * declared using the ComSafeArrayIn macro. * * @param aArg Parameter name to wrap. The given parameter must be declared * within the calling function using the ComSafeArrayIn macro. @@ -199,13 +204,13 @@ typedef const OLECHAR *CBSTR; * Version of ComSafeArrayInIsNull for GUID. * @param aArg Parameter name to wrap. */ -#define ComSafeGUIDArrayInIsNull(aArg) ComSafeArrayInIsNull (aArg) +#define ComSafeGUIDArrayInIsNull(aArg) ComSafeArrayInIsNull(aArg) /** * Version of ComSafeArrayInArg for GUID. * @param aArg Parameter name to wrap. */ -#define ComSafeGUIDArrayInArg(aArg) ComSafeArrayInArg (aArg) +#define ComSafeGUIDArrayInArg(aArg) ComSafeArrayInArg(aArg) /** * Version of ComSafeArrayOut for GUID. @@ -217,13 +222,19 @@ typedef const OLECHAR *CBSTR; * Version of ComSafeArrayOutIsNull for GUID. * @param aArg Parameter name to wrap. */ -#define ComSafeGUIDArrayOutIsNull(aArg) ComSafeArrayOutIsNull (aArg) +#define ComSafeGUIDArrayOutIsNull(aArg) ComSafeArrayOutIsNull(aArg) /** * Version of ComSafeArrayOutArg for GUID. * @param aArg Parameter name to wrap. */ -#define ComSafeGUIDArrayOutArg(aArg) ComSafeArrayOutArg (aArg) +#define ComSafeGUIDArrayOutArg(aArg) ComSafeArrayOutArg(aArg) + +/** + * Gets size of safearray parameter. + * @param aArg Parameter name. + */ +#define ComSafeArraySize(aArg) ((aArg) == NULL ? 0 : (aArg)->rgsabound[0].cElements) /** * Returns the const reference to the IID (i.e., |const GUID &|) of the given @@ -242,18 +253,18 @@ typedef const OLECHAR *CBSTR; */ #define COM_STRUCT_OR_CLASS(I) struct I -#else /* defined (RT_OS_WINDOWS) */ +#else /* defined(RT_OS_WINDOWS) */ #error "VBOX_WITH_XPCOM must be defined on a platform other than Windows!" -#endif /* defined (RT_OS_WINDOWS) */ +#endif /* defined(RT_OS_WINDOWS) */ -#else /* !defined (VBOX_WITH_XPCOM) */ +#else /* !defined(VBOX_WITH_XPCOM) */ // XPCOM ///////////////////////////////////////////////////////////////////////////// -#if defined (RT_OS_DARWIN) || (defined (QT_VERSION) && (QT_VERSION >= 0x040000)) +#if defined(RT_OS_DARWIN) || (defined(QT_VERSION) && (QT_VERSION >= 0x040000)) /* CFBase.h defines these & * qglobal.h from Qt4 defines these */ # undef FALSE @@ -278,7 +289,7 @@ typedef const OLECHAR *CBSTR; #define SUCCEEDED NS_SUCCEEDED #define FAILED NS_FAILED -#define SUCCEEDED_WARNING(rc) (NS_SUCCEEDED (rc) && (rc) != NS_OK) +#define SUCCEEDED_WARNING(rc) (NS_SUCCEEDED(rc) && (rc) != NS_OK) #define FAILED_DEAD_INTERFACE(rc) ( (rc) == NS_ERROR_ABORT \ || (rc) == NS_ERROR_CALL_FAILED \ @@ -338,20 +349,23 @@ typedef BSTR *LPBSTR; /* safearray input parameter macros for GUID */ #define ComSafeGUIDArrayIn(aArg) PRUint32 aArg##Size, const nsID **aArg -#define ComSafeGUIDArrayInIsNull(aArg) ComSafeArrayInIsNull (aArg) -#define ComSafeGUIDArrayInArg(aArg) ComSafeArrayInArg (aArg) +#define ComSafeGUIDArrayInIsNull(aArg) ComSafeArrayInIsNull(aArg) +#define ComSafeGUIDArrayInArg(aArg) ComSafeArrayInArg(aArg) /* safearray output parameter macros for GUID */ #define ComSafeGUIDArrayOut(aArg) PRUint32 *aArg##Size, nsID ***aArg -#define ComSafeGUIDArrayOutIsNull(aArg) ComSafeArrayOutIsNull (aArg) -#define ComSafeGUIDArrayOutArg(aArg) ComSafeArrayOutArg (aArg) +#define ComSafeGUIDArrayOutIsNull(aArg) ComSafeArrayOutIsNull(aArg) +#define ComSafeGUIDArrayOutArg(aArg) ComSafeArrayOutArg(aArg) + +/* safearray size */ +#define ComSafeArraySize(aArg) ((aArg) == NULL ? 0 : (aArg##Size)) /* CLSID and IID for compatibility with Win32 */ typedef nsCID CLSID; typedef nsIID IID; /* OLE error codes */ -#define S_OK ((nsresult) NS_OK) +#define S_OK ((nsresult)NS_OK) #define E_UNEXPECTED NS_ERROR_UNEXPECTED #define E_NOTIMPL NS_ERROR_NOT_IMPLEMENTED #define E_OUTOFMEMORY NS_ERROR_OUT_OF_MEMORY @@ -362,10 +376,11 @@ typedef nsIID IID; #define E_FAIL NS_ERROR_FAILURE /* Note: a better analog for E_ACCESSDENIED would probably be * NS_ERROR_NOT_AVAILABLE, but we want binary compatibility for now. */ -#define E_ACCESSDENIED ((nsresult) 0x80070005L) +#define E_ACCESSDENIED ((nsresult)0x80070005L) #define STDMETHOD(a) NS_IMETHOD a #define STDMETHODIMP NS_IMETHODIMP +#define STDMETHOD_(ret, meth) NS_IMETHOD_(ret) meth #define COM_IIDOF(I) NS_GET_IID(I) @@ -394,14 +409,14 @@ public: /* helper functions */ extern "C" { -BSTR SysAllocString (const OLECHAR* sz); -BSTR SysAllocStringByteLen (char *psz, unsigned int len); -BSTR SysAllocStringLen (const OLECHAR *pch, unsigned int cch); -void SysFreeString (BSTR bstr); -int SysReAllocString (BSTR *pbstr, const OLECHAR *psz); -int SysReAllocStringLen (BSTR *pbstr, const OLECHAR *psz, unsigned int cch); -unsigned int SysStringByteLen (BSTR bstr); -unsigned int SysStringLen (BSTR bstr); +BSTR SysAllocString(const OLECHAR* sz); +BSTR SysAllocStringByteLen(char *psz, unsigned int len); +BSTR SysAllocStringLen(const OLECHAR *pch, unsigned int cch); +void SysFreeString(BSTR bstr); +int SysReAllocString(BSTR *pbstr, const OLECHAR *psz); +int SysReAllocStringLen(BSTR *pbstr, const OLECHAR *psz, unsigned int cch); +unsigned int SysStringByteLen(BSTR bstr); +unsigned int SysStringLen(BSTR bstr); } /** @@ -443,7 +458,7 @@ _InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, \ /** * 'Constructor' that uses an existing getter function that gets a singleton. * The getter function must have the following prototype: - * nsresult _GetterProc (_InstanceClass **inst) + * nsresult _GetterProc(_InstanceClass **inst) * This constructor, as opposed to NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR, * lets the getter function return a result code that is passed back to the * caller that tries to instantiate the object. @@ -481,16 +496,16 @@ _InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, \ return rv; \ } -#endif /* !defined (VBOX_WITH_XPCOM) */ +#endif /* !defined(VBOX_WITH_XPCOM) */ /** * Declares a wchar_t string literal from the argument. * Necessary to overcome MSC / GCC differences. * @param s expression to stringify */ -#if defined (_MSC_VER) +#if defined(_MSC_VER) # define WSTR_LITERAL(s) L#s -#elif defined (__GNUC__) +#elif defined(__GNUC__) # define WSTR_LITERAL(s) L""#s #else # error "Unsupported compiler!" @@ -546,4 +561,5 @@ namespace com } /* namespace com */ -#endif /* ___VBox_com_defs_h */ +#endif /* !___VBox_com_defs_h */ + diff --git a/include/VBox/com/errorprint.h b/include/VBox/com/errorprint.h index 2ee11676..f6b49ec0 100644 --- a/include/VBox/com/errorprint.h +++ b/include/VBox/com/errorprint.h @@ -1,11 +1,13 @@ /** @file - * MS COM / XPCOM Abstraction Layer: + * MS COM / XPCOM Abstraction Layer - Error Reporting. + * * Error printing macros using shared functions defined in shared glue code. - * Use these CHECK_* macros for efficient error checking around calling COM methods. + * Use these CHECK_* macros for efficient error checking around calling COM + * methods. */ /* - * Copyright (C) 2009 Oracle Corporation + * Copyright (C) 2009-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -259,3 +261,4 @@ void GlueHandleComErrorProgress(ComPtr<IProgress> progress, if (1) { ASSERT(expr); if (!(expr)) break; } else do {} while (0) } /* namespace com */ + diff --git a/include/VBox/com/list.h b/include/VBox/com/list.h index 11a137b5..5ecf4f16 100644 --- a/include/VBox/com/list.h +++ b/include/VBox/com/list.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -29,8 +29,10 @@ #include <VBox/com/ptr.h> #include <VBox/com/string.h> +#include <VBox/com/array.h> #include <iprt/cpp/list.h> + /** * Specialized list class for using with com::ComPtr<C> * @@ -54,8 +56,8 @@ public: * @param cCapacitiy The initial capacity the list has. * @throws std::bad_alloc */ - RTCList(size_t cCapacity = BASE::DefaultCapacity) - : BASE(cCapacity) {} + RTCList(size_t cCapacity = BASE::kDefaultCapacity) + : BASE(cCapacity) {} /* Define our own new and delete. */ RTMEMEF_NEW_AND_DELETE_OPERATORS(); @@ -84,8 +86,8 @@ public: * @param cCapacitiy The initial capacity the list has. * @throws std::bad_alloc */ - RTCList(size_t cCapacity = BASE::DefaultCapacity) - : BASE(cCapacity) {} + RTCList(size_t cCapacity = BASE::kDefaultCapacity) + : BASE(cCapacity) {} /* Define our own new and delete. */ RTMEMEF_NEW_AND_DELETE_OPERATORS(); @@ -97,10 +99,10 @@ public: * The class offers methods for importing com::SafeArray's of com::Bstr's. */ template <> -class RTCList<Utf8Str>: public RTCListBase<Utf8Str, Utf8Str*, false> +class RTCList<com::Utf8Str>: public RTCListBase<com::Utf8Str, com::Utf8Str*, false> { /* Traits */ - typedef Utf8Str T; + typedef com::Utf8Str T; typedef T *ITYPE; static const bool MT = false; typedef RTCListBase<T, ITYPE, MT> BASE; @@ -114,8 +116,8 @@ public: * @param cCapacitiy The initial capacity the list has. * @throws std::bad_alloc */ - RTCList(size_t cCapacity = BASE::DefaultCapacity) - : BASE(cCapacity) {} + RTCList(size_t cCapacity = BASE::kDefaultCapacity) + : BASE(cCapacity) {} /** * Creates a copy of another list. @@ -130,9 +132,10 @@ public: RTCList(ComSafeArrayIn(IN_BSTR, other)) { com::SafeArray<IN_BSTR> sfaOther(ComSafeArrayInArg(other)); - realloc(sfaOther.size()); - m_cSize = sfaOther.size(); - for (size_t i = 0; i < m_cSize; ++i) + size_t const cElementsOther = sfaOther.size(); + resizeArray(cElementsOther); + m_cElements = cElementsOther; + for (size_t i = 0; i < cElementsOther; ++i) RTCListHelper<T, ITYPE>::set(m_pArray, i, T(sfaOther[i])); } @@ -147,9 +150,9 @@ public: * @throws std::bad_alloc */ RTCList(const com::SafeArray<IN_BSTR> &other) - : BASE(other.size()) + : BASE(other.size()) { - for (size_t i = 0; i < m_cSize; ++i) + for (size_t i = 0; i < m_cElements; ++i) RTCListHelper<T, ITYPE>::set(m_pArray, i, T(other[i])); } @@ -164,16 +167,19 @@ public: RTCListBase<T, ITYPE, MT> &operator=(const com::SafeArray<IN_BSTR> &other) { m_guard.enterWrite(); + /* Values cleanup */ - RTCListHelper<T, ITYPE>::eraseRange(m_pArray, 0, m_cSize); + RTCListHelper<T, ITYPE>::eraseRange(m_pArray, 0, m_cElements); + /* Copy */ - if (other.size() != m_cCapacity) - realloc_no_elements_clean(other.size()); - m_cSize = other.size(); - for (size_t i = 0; i < other.size(); ++i) + size_t cElementsOther = other.size(); + if (cElementsOther != m_cCapacity) + resizeArrayNoErase(cElementsOther); + m_cElements = cElementsOther; + for (size_t i = 0; i < cElementsOther; ++i) RTCListHelper<T, ITYPE>::set(m_pArray, i, T(other[i])); - m_guard.leaveWrite(); + m_guard.leaveWrite(); return *this; } diff --git a/include/VBox/com/listeners.h b/include/VBox/com/listeners.h index 419b18fa..6a55e4ce 100644 --- a/include/VBox/com/listeners.h +++ b/include/VBox/com/listeners.h @@ -1,6 +1,6 @@ /* $Id: listeners.h $ */ /** @file - * Listeners helpers. + * MS COM / XPCOM Abstraction Layer - Listeners helpers. */ /* @@ -169,3 +169,4 @@ public: #endif #endif + diff --git a/include/VBox/com/mtlist.h b/include/VBox/com/mtlist.h index c4142c5f..16b8e8ce 100644 --- a/include/VBox/com/mtlist.h +++ b/include/VBox/com/mtlist.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -29,6 +29,7 @@ #include <VBox/com/ptr.h> #include <VBox/com/string.h> +#include <VBox/com/array.h> #include <iprt/cpp/mtlist.h> /** @@ -54,8 +55,8 @@ public: * @param cCapacitiy The initial capacity the list has. * @throws std::bad_alloc */ - RTCList(size_t cCapacity = BASE::DefaultCapacity) - : BASE(cCapacity) {} + RTCMTList(size_t cCapacity = BASE::kDefaultCapacity) + : BASE(cCapacity) {} /* Define our own new and delete. */ RTMEMEF_NEW_AND_DELETE_OPERATORS(); @@ -84,7 +85,7 @@ public: * @param cCapacitiy The initial capacity the list has. * @throws std::bad_alloc */ - RTCList(size_t cCapacity = BASE::DefaultCapacity) + RTCMTList(size_t cCapacity = BASE::kDefaultCapacity) : BASE(cCapacity) {} /* Define our own new and delete. */ @@ -97,10 +98,10 @@ public: * The class offers methods for importing com::SafeArray's of com::Bstr's. */ template <> -class RTCMTList<Utf8Str>: public RTCListBase<Utf8Str, Utf8Str*, true> +class RTCMTList<com::Utf8Str>: public RTCListBase<com::Utf8Str, com::Utf8Str *, true> { /* Traits */ - typedef Utf8Str T; + typedef com::Utf8Str T; typedef T *ITYPE; static const bool MT = true; typedef RTCListBase<T, ITYPE, MT> BASE; @@ -114,8 +115,8 @@ public: * @param cCapacitiy The initial capacity the list has. * @throws std::bad_alloc */ - RTCMTList(size_t cCapacity = BASE::DefaultCapacity) - : BASE(cCapacity) {} + RTCMTList(size_t cCapacity = BASE::kDefaultCapacity) + : BASE(cCapacity) {} /** * Creates a copy of another list. @@ -130,9 +131,10 @@ public: RTCMTList(ComSafeArrayIn(IN_BSTR, other)) { com::SafeArray<IN_BSTR> sfaOther(ComSafeArrayInArg(other)); - realloc(sfaOther.size()); - m_cSize = sfaOther.size(); - for (size_t i = 0; i < m_cSize; ++i) + size_t const cElementsOther = sfaOther.size(); + resizeArray(cElementsOther); + m_cElements = cElementsOther; + for (size_t i = 0; i < cElementsOther; ++i) RTCListHelper<T, ITYPE>::set(m_pArray, i, T(sfaOther[i])); } @@ -149,7 +151,7 @@ public: RTCMTList(const com::SafeArray<IN_BSTR> &other) : BASE(other.size()) { - for (size_t i = 0; i < m_cSize; ++i) + for (size_t i = 0; i < m_cElements; ++i) RTCListHelper<T, ITYPE>::set(m_pArray, i, T(other[i])); } @@ -165,11 +167,11 @@ public: { m_guard.enterWrite(); /* Values cleanup */ - RTCListHelper<T, ITYPE>::eraseRange(m_pArray, 0, m_cSize); + RTCListHelper<T, ITYPE>::eraseRange(m_pArray, 0, m_cElements); /* Copy */ if (other.size() != m_cCapacity) - realloc_no_elements_clean(other.size()); - m_cSize = other.size(); + resizeArrayNoErase(other.size()); + m_cElements = other.size(); for (size_t i = 0; i < other.size(); ++i) RTCListHelper<T, ITYPE>::set(m_pArray, i, T(other[i])); m_guard.leaveWrite(); diff --git a/include/VBox/com/ptr.h b/include/VBox/com/ptr.h index 1942274b..bb6e5715 100644 --- a/include/VBox/com/ptr.h +++ b/include/VBox/com/ptr.h @@ -1,10 +1,9 @@ /** @file - * MS COM / XPCOM Abstraction Layer: - * Smart COM pointer classes declaration + * MS COM / XPCOM Abstraction Layer - Smart COM pointer classes declaration. */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -491,3 +490,4 @@ public: } }; #endif + diff --git a/include/VBox/com/string.h b/include/VBox/com/string.h index 3462818e..63e08ae9 100644 --- a/include/VBox/com/string.h +++ b/include/VBox/com/string.h @@ -204,15 +204,23 @@ public: } bool operator==(const Bstr &that) const { return !compare(that.m_bstr); } + bool operator==(CBSTR that) const { return !compare(that); } + bool operator==(BSTR that) const { return !compare(that); } bool operator!=(const Bstr &that) const { return !!compare(that.m_bstr); } - bool operator==(CBSTR that) const { return !compare(that); } - bool operator==(BSTR that) const { return !compare(that); } - - bool operator!=(CBSTR that) const { return !!compare(that); } - bool operator!=(BSTR that) const { return !!compare(that); } - bool operator<(const Bstr &that) const { return compare(that.m_bstr) < 0; } - bool operator<(CBSTR that) const { return compare(that) < 0; } - bool operator<(BSTR that) const { return compare(that) < 0; } + bool operator!=(CBSTR that) const { return !!compare(that); } + bool operator!=(BSTR that) const { return !!compare(that); } + bool operator<(const Bstr &that) const { return compare(that.m_bstr) < 0; } + bool operator<(CBSTR that) const { return compare(that) < 0; } + bool operator<(BSTR that) const { return compare(that) < 0; } + bool operator<=(const Bstr &that) const { return compare(that.m_bstr) <= 0; } + bool operator<=(CBSTR that) const { return compare(that) <= 0; } + bool operator<=(BSTR that) const { return compare(that) <= 0; } + bool operator>(const Bstr &that) const { return compare(that.m_bstr) > 0; } + bool operator>(CBSTR that) const { return compare(that) > 0; } + bool operator>(BSTR that) const { return compare(that) > 0; } + bool operator>=(const Bstr &that) const { return compare(that.m_bstr) >= 0; } + bool operator>=(CBSTR that) const { return compare(that) >= 0; } + bool operator>=(BSTR that) const { return compare(that) >= 0; } /** * Returns true if the member string has no length. diff --git a/include/VBox/dbg.h b/include/VBox/dbg.h index 320dac16..7a4a5142 100644 --- a/include/VBox/dbg.h +++ b/include/VBox/dbg.h @@ -7,7 +7,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -477,7 +477,6 @@ typedef struct DBGCCMDHLP * * @returns VBox status code appropriate to return from a command. * @param pCmdHlp Pointer to the command callback structure. - * @param pVM VM handle if GC or physical HC address. * @param pvBuffer Where to store the read data. * @param cbRead Number of bytes to read. * @param pVarPointer DBGC variable specifying where to start reading. @@ -487,14 +486,13 @@ typedef struct DBGCCMDHLP * If not specified not-present failure or end of a HC physical page * will cause failure. */ - DECLCALLBACKMEMBER(int, pfnMemRead)(PDBGCCMDHLP pCmdHlp, PVM pVM, void *pvBuffer, size_t cbRead, PCDBGCVAR pVarPointer, size_t *pcbRead); + DECLCALLBACKMEMBER(int, pfnMemRead)(PDBGCCMDHLP pCmdHlp, void *pvBuffer, size_t cbRead, PCDBGCVAR pVarPointer, size_t *pcbRead); /** * Command helper for writing memory specified by a DBGC variable. * * @returns VBox status code appropriate to return from a command. * @param pCmdHlp Pointer to the command callback structure. - * @param pVM VM handle if GC or physical HC address. * @param pvBuffer What to write. * @param cbWrite Number of bytes to write. * @param pVarPointer DBGC variable specifying where to start reading. @@ -502,7 +500,7 @@ typedef struct DBGCCMDHLP * This is optional. If NULL be aware that some of the buffer * might have been written to the specified address. */ - DECLCALLBACKMEMBER(int, pfnMemWrite)(PDBGCCMDHLP pCmdHlp, PVM pVM, const void *pvBuffer, size_t cbWrite, PCDBGCVAR pVarPointer, size_t *pcbWritten); + DECLCALLBACKMEMBER(int, pfnMemWrite)(PDBGCCMDHLP pCmdHlp, const void *pvBuffer, size_t cbWrite, PCDBGCVAR pVarPointer, size_t *pcbWritten); /** * Executes command an expression. @@ -720,9 +718,9 @@ DECLINLINE(int) DBGCCmdHlpVBoxError(PDBGCCMDHLP pCmdHlp, int rc, const char *psz /** * @copydoc FNDBGCHLPMEMREAD */ -DECLINLINE(int) DBGCCmdHlpMemRead(PDBGCCMDHLP pCmdHlp, PVM pVM, void *pvBuffer, size_t cbRead, PCDBGCVAR pVarPointer, size_t *pcbRead) +DECLINLINE(int) DBGCCmdHlpMemRead(PDBGCCMDHLP pCmdHlp, void *pvBuffer, size_t cbRead, PCDBGCVAR pVarPointer, size_t *pcbRead) { - return pCmdHlp->pfnMemRead(pCmdHlp, pVM, pvBuffer, cbRead, pVarPointer, pcbRead); + return pCmdHlp->pfnMemRead(pCmdHlp, pvBuffer, cbRead, pVarPointer, pcbRead); } /** @@ -817,9 +815,9 @@ DECLINLINE(int) DBGCCmdHlpParserError(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, int i /** Assert+return like macro that the VM handle is present. * Returns with failure if the VM handle is NIL. */ -#define DBGC_CMDHLP_REQ_VM_RET(pCmdHlp, pCmd, pVM) \ +#define DBGC_CMDHLP_REQ_UVM_RET(pCmdHlp, pCmd, pUVM) \ do { \ - if (!(pVM)) \ + if (!(pUVM)) \ return DBGCCmdHlpFail(pCmdHlp, pCmd, "No VM selected"); \ } while (0) @@ -926,11 +924,11 @@ DECLINLINE(CPUMMODE) DBGCCmdHlpGetCpuMode(PDBGCCMDHLP pCmdHlp) * @returns VBox status. * @param pCmd Pointer to the command descriptor (as registered). * @param pCmdHlp Pointer to command helper functions. - * @param pVM Pointer to the current VM (if any). + * @param pUVM The user mode VM handle, can in theory be NULL. * @param paArgs Pointer to (readonly) array of arguments. * @param cArgs Number of arguments in the array. */ -typedef DECLCALLBACK(int) FNDBGCCMD(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs); +typedef DECLCALLBACK(int) FNDBGCCMD(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PUVM pUVM, PCDBGCVAR paArgs, unsigned cArgs); /** Pointer to a FNDBGCCMD() function. */ typedef FNDBGCCMD *PFNDBGCCMD; @@ -975,12 +973,12 @@ typedef struct DBGCCMD * @returns VBox status. * @param pCmd Pointer to the command descriptor (as registered). * @param pCmdHlp Pointer to command helper functions. - * @param pVM Pointer to the current VM (if any). + * @param pUVM The user mode VM handle, can in theory be NULL. * @param paArgs Pointer to (readonly) array of arguments. * @param cArgs Number of arguments in the array. * @param pResult Where to return the result. */ -typedef DECLCALLBACK(int) FNDBGCFUNC(PCDBGCFUNC pFunc, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, +typedef DECLCALLBACK(int) FNDBGCFUNC(PCDBGCFUNC pFunc, PDBGCCMDHLP pCmdHlp, PUVM pUVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); /** Pointer to a FNDBGCFUNC() function. */ typedef FNDBGCFUNC *PFNDBGCFUNC; @@ -1091,67 +1089,11 @@ typedef struct DBGCBACK PFNDBGCBACKSETREADY pfnSetReady; } DBGCBACK; - -/** - * Make a console instance. - * - * This will not return until either an 'exit' command is issued or a error code - * indicating connection loss is encountered. - * - * @returns VINF_SUCCESS if console termination caused by the 'exit' command. - * @returns The VBox status code causing the console termination. - * - * @param pVM VM Handle. - * @param pBack Pointer to the backend structure. This must contain - * a full set of function pointers to service the console. - * @param fFlags Reserved, must be zero. - * @remark A forced termination of the console is easiest done by forcing the - * callbacks to return fatal failures. - */ -DBGDECL(int) DBGCCreate(PVM pVM, PDBGCBACK pBack, unsigned fFlags); - - -/** - * Register one or more external commands. - * - * @returns VBox status. - * @param paCommands Pointer to an array of command descriptors. - * The commands must be unique. It's not possible - * to register the same commands more than once. - * @param cCommands Number of commands. - */ +DBGDECL(int) DBGCCreate(PUVM pUVM, PDBGCBACK pBack, unsigned fFlags); DBGDECL(int) DBGCRegisterCommands(PCDBGCCMD paCommands, unsigned cCommands); - - -/** - * Deregister one or more external commands previously registered by - * DBGCRegisterCommands(). - * - * @returns VBox status. - * @param paCommands Pointer to an array of command descriptors - * as given to DBGCRegisterCommands(). - * @param cCommands Number of commands. - */ DBGDECL(int) DBGCDeregisterCommands(PCDBGCCMD paCommands, unsigned cCommands); - - -/** - * Spawns a new thread with a TCP based debugging console service. - * - * @returns VBox status. - * @param pVM VM handle. - * @param ppvData Where to store the pointer to instance data. - */ -DBGDECL(int) DBGCTcpCreate(PVM pVM, void **ppvUser); - -/** - * Terminates any running TCP base debugger console service. - * - * @returns VBox status. - * @param pVM VM handle. - * @param pvData Instance data set by DBGCTcpCreate(). - */ -DBGDECL(int) DBGCTcpTerminate(PVM pVM, void *pvData); +DBGDECL(int) DBGCTcpCreate(PUVM pUVM, void **ppvUser); +DBGDECL(int) DBGCTcpTerminate(PUVM pUVM, void *pvData); /** @defgroup grp_dbgc_plug_in The DBGC Plug-in Interface @@ -1189,15 +1131,15 @@ typedef enum DBGCPLUGINOP * @returns VBox status code. * * @param enmOperation The operation. - * @param pVM The VM handle. This may be NULL. + * @param pUVM The user mode VM handle. This may be NULL. * @param uArg Extra argument. */ -typedef DECLCALLBACK(int) FNDBGCPLUGIN(DBGCPLUGINOP enmOperation, PVM pVM, uintptr_t uArg); +typedef DECLCALLBACK(int) FNDBGCPLUGIN(DBGCPLUGINOP enmOperation, PUVM pUVM, uintptr_t uArg); /** Pointer to a FNDBGCPLUGIN. */ typedef FNDBGCPLUGIN *PFNDBGCPLUGIN; /** @copydoc FNDBGCPLUGIN */ -DECLEXPORT(int) DBGCPlugInEntry(DBGCPLUGINOP enmOperation, PVM pVM, uintptr_t uArg); +DECLEXPORT(int) DBGCPlugInEntry(DBGCPLUGINOP enmOperation, PUVM pUVM, uintptr_t uArg); #endif /* IN_RING3 */ diff --git a/include/VBox/dbggui.h b/include/VBox/dbggui.h index 59a48dc5..5d83557c 100644 --- a/include/VBox/dbggui.h +++ b/include/VBox/dbggui.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -97,14 +97,14 @@ typedef FNDBGGUICREATE *PFNDBGGUICREATE; * Creates the debugger GUI given a VM handle. * * @returns VBox status code. - * @param pVM The VM handle. + * @param pUVM The VM handle. * @param ppGui Where to store the pointer to the debugger instance. * @param ppGuiVT Where to store the virtual method table pointer. * Optional. */ -DBGDECL(int) DBGGuiCreateForVM(PVM pVM, PDBGGUI *ppGui, PCDBGGUIVT *ppGuiVT); +DBGDECL(int) DBGGuiCreateForVM(PUVM pUVM, PDBGGUI *ppGui, PCDBGGUIVT *ppGuiVT); /** @copydoc DBGGuiCreateForVM. */ -typedef DECLCALLBACK(int) FNDBGGUICREATEFORVM(PVM pVM, PDBGGUI *ppGui, PCDBGGUIVT *ppGuiVT); +typedef DECLCALLBACK(int) FNDBGGUICREATEFORVM(PUVM pUVM, PDBGGUI *ppGui, PCDBGGUIVT *ppGuiVT); /** Pointer to DBGGuiCreateForVM. */ typedef FNDBGGUICREATEFORVM *PFNDBGGUICREATEFORVM; diff --git a/include/VBox/dbus-calls.h b/include/VBox/dbus-calls.h index 16d2be3d..315be672 100644 --- a/include/VBox/dbus-calls.h +++ b/include/VBox/dbus-calls.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2008 Oracle Corporation + * Copyright (C) 2008-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -42,6 +42,8 @@ (DBusBusType type, DBusError *error), (type, error)) \ RT_PROXY_STUB(dbus_error_free, void, (DBusError *error), \ (error)) \ + RT_PROXY_STUB(dbus_free_string_array, void, (char **str_array), \ + (str_array)) \ RT_PROXY_STUB(dbus_connection_unref, void, (DBusConnection *connection), \ (connection)) \ RT_PROXY_STUB(dbus_connection_close, void, (DBusConnection *connection), \ @@ -68,6 +70,12 @@ RT_PROXY_STUB(dbus_message_append_args_valist, dbus_bool_t, \ (DBusMessage *message, int first_arg_type, va_list var_args), \ (message, first_arg_type, var_args)) \ + RT_PROXY_STUB(dbus_message_get_args_valist, dbus_bool_t, \ + (DBusMessage *message, DBusError *error, int first_arg_type, va_list var_args), \ + (message, error, first_arg_type, var_args)) \ + RT_PROXY_STUB(dbus_message_get_type, int, \ + (DBusMessage *message), \ + (message)) \ RT_PROXY_STUB(dbus_message_iter_open_container, dbus_bool_t, \ (DBusMessageIter *iter, int type, const char *contained_signature, DBusMessageIter *sub), \ (iter, type, contained_signature, sub)) \ @@ -123,7 +131,9 @@ const char *string2), \ (message, string1, string2)) \ RT_PROXY_STUB(dbus_connection_pop_message, DBusMessage *, \ - (DBusConnection *connection), (connection)) + (DBusConnection *connection), (connection)) \ + RT_PROXY_STUB(dbus_set_error_from_message, dbus_bool_t, \ + (DBusError *error, DBusMessage *message), (error, message)) #ifdef VBOX_DBUS_GENERATE_HEADER # define RT_RUNTIME_LOADER_GENERATE_HEADER diff --git a/include/VBox/dbus.h b/include/VBox/dbus.h index 316628f4..468525b8 100644 --- a/include/VBox/dbus.h +++ b/include/VBox/dbus.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2008 Oracle Corporation + * Copyright (C) 2008-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -80,14 +80,23 @@ typedef struct DBusMessageIter DBusMessageIter; #define DBUS_ERROR_NO_MEMORY "org.freedesktop.DBus.Error.NoMemory" -/* Primitive types */ +/* Message types. */ +#define DBUS_MESSAGE_TYPE_INVALID 0 +#define DBUS_MESSAGE_TYPE_METHOD_CALL 1 +#define DBUS_MESSAGE_TYPE_METHOD_RETURN 2 +#define DBUS_MESSAGE_TYPE_ERROR 3 +#define DBUS_MESSAGE_TYPE_SIGNAL 4 + +/* Primitive types. */ #define DBUS_TYPE_INVALID ((int) '\0') +#define DBUS_TYPE_BOOLEAN ((int) 'b') #define DBUS_TYPE_INT32 ((int) 'i') #define DBUS_TYPE_UINT32 ((int) 'u') #define DBUS_TYPE_STRING ((int) 's') #define DBUS_TYPE_STRING_AS_STRING "s" -/* Compound types */ +/* Compound types. */ +#define DBUS_TYPE_OBJECT_PATH ((int) 'o') #define DBUS_TYPE_ARRAY ((int) 'a') #define DBUS_TYPE_ARRAY_AS_STRING "a" #define DBUS_TYPE_DICT_ENTRY ((int) 'e') @@ -112,5 +121,4 @@ typedef void (* DBusFreeFunction) (void *); #undef VBOX_DBUS_GENERATE_HEADER #endif /* ___VBox_DBus_h not defined */ -/* vi: set tabstop=4 shiftwidth=4 expandtab: */ diff --git a/include/VBox/dis.h b/include/VBox/dis.h index 09d8a6ea..01886422 100644 --- a/include/VBox/dis.h +++ b/include/VBox/dis.h @@ -59,7 +59,7 @@ RT_C_DECLS_BEGIN * @{ */ #define DISPREFIX_REX_OP_2_FLAGS(a) (a - OP_PARM_REX_START) -#define DISPREFIX_REX_FLAGS DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX) +/*#define DISPREFIX_REX_FLAGS DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX) - 0, which is no flag */ #define DISPREFIX_REX_FLAGS_B DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_B) #define DISPREFIX_REX_FLAGS_X DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_X) #define DISPREFIX_REX_FLAGS_XB DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_XB) @@ -76,6 +76,10 @@ RT_C_DECLS_BEGIN #define DISPREFIX_REX_FLAGS_WRX DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_WRX) #define DISPREFIX_REX_FLAGS_WRXB DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_WRXB) /** @} */ +AssertCompile(RT_IS_POWER_OF_TWO(DISPREFIX_REX_FLAGS_B)); +AssertCompile(RT_IS_POWER_OF_TWO(DISPREFIX_REX_FLAGS_X)); +AssertCompile(RT_IS_POWER_OF_TWO(DISPREFIX_REX_FLAGS_W)); +AssertCompile(RT_IS_POWER_OF_TWO(DISPREFIX_REX_FLAGS_R)); /** @name Operand type (DISOPCODE::fOpType). * @{ @@ -106,6 +110,9 @@ RT_C_DECLS_BEGIN #define DISOPTYPE_REXB_EXTENDS_OPREG RT_BIT_32(23) /**< REX.B extends the register field in the opcode byte */ #define DISOPTYPE_MOD_FIXED_11 RT_BIT_32(24) /**< modrm.mod is always 11b */ #define DISOPTYPE_FORCED_32_OP_SIZE_X86 RT_BIT_32(25) /**< Forced 32 bits operand size; regardless of prefix bytes (only in 16 & 32 bits mode!) */ +#define DISOPTYPE_SSE RT_BIT_32(29) /**< SSE,SSE2,SSE3,AVX,++ instruction. Not implemented yet! */ +#define DISOPTYPE_MMX RT_BIT_32(30) /**< MMX,MMXExt,3DNow,++ instruction. Not implemented yet! */ +#define DISOPTYPE_FPU RT_BIT_32(31) /**< FPU instruction. Not implemented yet! */ #define DISOPTYPE_ALL UINT32_C(0xffffffff) /** @} */ diff --git a/include/VBox/disopcode.h b/include/VBox/disopcode.h index c83f5052..22ca0909 100644 --- a/include/VBox/disopcode.h +++ b/include/VBox/disopcode.h @@ -292,7 +292,7 @@ #define OP_PSRLQ 244 #define OP_PADDQ 245 #define OP_PMULLW 246 -#define OP_PMOVSKB 247 +#define OP_PMOVMSKB 247 #define OP_PSUBUSB 248 #define OP_PSUBUSW 249 #define OP_PMINUB 250 diff --git a/include/VBox/err.h b/include/VBox/err.h index 3fae9bc9..ef999408 100644 --- a/include/VBox/err.h +++ b/include/VBox/err.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -84,6 +84,8 @@ * Returned by pfnInit in VBoxService to indicated a non-fatal error that * should results in the particular service being disabled. */ #define VERR_SERVICE_DISABLED (-1020) +/** The requested feature is not supported in raw-mode. */ +#define VERR_NOT_SUP_IN_RAW_MODE (-1021) /** @} */ @@ -156,7 +158,7 @@ #define VINF_EM_RESCHEDULE_REM 1115 /** Indicating that a rescheduling to vmx-mode execution. * Typically caused by REM detecting that hardware-accelerated raw-mode execution is possible. */ -#define VINF_EM_RESCHEDULE_HWACC 1116 +#define VINF_EM_RESCHEDULE_HM 1116 /** Indicating that a rescheduling to raw-mode execution. * Typically caused by REM detecting that raw-mode execution is possible. * @remarks Important to have a higher priority (lower number) than VINF_EM_RESCHEDULE. */ @@ -235,12 +237,15 @@ /** Start instruction stepping (debug only). */ #define VINF_EM_RAW_EMULATE_DBG_STEP 1151 /** Patch TPR access instruction. */ -#define VINF_EM_HWACCM_PATCH_TPR_INSTR 1152 -/** The EMInterpretDisasOne / EMInterpretDisasOneEx methods failed to - * disassemble the instruction. */ -#define VERR_EM_INTERNAL_DISAS_ERROR (-1153) +#define VINF_EM_HM_PATCH_TPR_INSTR 1152 /** Unexpected guest mapping conflict detected. */ #define VERR_EM_UNEXPECTED_MAPPING_CONFLICT (-1154) +/** Reason for leaving RC: A triple-fault condition. Currently, causes + * a guru meditation. */ +#define VINF_EM_TRIPLE_FAULT 1155 +/** The specified execution engine cannot execute guest code in the current + * state. */ +#define VERR_EM_CANNOT_EXEC_GUEST (-1156) /** @} */ @@ -360,6 +365,8 @@ #define VINF_PATM_SPINLOCK_FAILED (1429) /** Continue execution after patch trap. */ #define VINF_PATCH_CONTINUE (1430) +/** The patch manager is not used because we're using HM and VT-x/AMD-V. */ +#define VERR_PATM_HM_IPE (-1431) /** @} */ @@ -375,6 +382,8 @@ #define VWRN_CSAM_PAGE_NOT_FOUND 1502 /** Reason for leaving RC: CSAM wants perform a task in ring-3. */ #define VINF_CSAM_PENDING_ACTION 1503 +/** The CSAM is not used because we're using HM and VT-x/AMD-V. */ +#define VERR_CSAM_HM_IPE (-1504) /** @} */ @@ -570,6 +579,11 @@ #define VERR_PGM_PHYS_NULL_PAGE_PARAM (-1681) /** PCI passthru is not supported by this build. */ #define VERR_PGM_PCI_PASSTHRU_MISCONFIG (-1682) +/** Too many MMIO2 ranges. */ +#define VERR_PGM_TOO_MANY_MMIO2_RANGES (-1683) +/** Internal processing error in the PGM physial page mapping code dealing + * with MMIO2 pages. */ +#define VERR_PGM_PHYS_PAGE_MAP_MMIO2_IPE (-1684) /** @} */ @@ -596,6 +610,16 @@ /** CPUMR3DisasmInstrCPU unexpectedly failed to determin the hidden * parts of the CS register. */ #define VERR_CPUM_HIDDEN_CS_LOAD_ERROR (-1752) +/** Couldn't find the end of CPUID sub-leaves. */ +#define VERR_CPUM_TOO_MANY_CPUID_SUBLEAVES (-1753) +/** CPUM internal processing error \#1. */ +#define VERR_CPUM_IPE_1 (-1754) +/** CPUM internal processing error \#2. */ +#define VERR_CPUM_IPE_2 (-1755) +/** The specified CPU cannot be found in the CPU database. */ +#define VERR_CPUM_DB_CPU_NOT_FOUND (-1756) +/** Invalid CPUMCPU offset in MSR range. */ +#define VERR_CPUM_MSR_BAD_CPUMCPU_OFFSET (-1757) /** @} */ @@ -968,6 +992,8 @@ #define VERR_TRPM_IPE_2 (-2408) /** Internal processing error \#3 in TRPM. */ #define VERR_TRPM_IPE_3 (-2409) +/** Got into a part of TRPM that is not used when HM (VT-x/AMD-V) is enabled. */ +#define VERR_TRPM_HM_IPE (-2410) /** @} */ @@ -999,6 +1025,8 @@ /** The guest GDT so full that we cannot find free space for our own * selectors. */ #define VERR_SELM_GDT_TOO_FULL (-2508) +/** Got into a part of SELM that is not used when HM (VT-x/AMD-V) is enabled. */ +#define VERR_SELM_HM_IPE (-2509) /** @} */ @@ -1078,6 +1106,8 @@ #define VERR_IOM_MMIO_IPE_2 (-2635) /** Internal processing error \#3 in the MMIO code. */ #define VERR_IOM_MMIO_IPE_3 (-2636) +/** Got into a part of IOM that is not used when HM (VT-x/AMD-V) is enabled. */ +#define VERR_IOM_HM_IPE (-2637) /** @} */ @@ -1117,6 +1147,12 @@ #define VINF_VMM_CALL_TRACER (2712) /** Internal processing error \#1 in the switcher code. */ #define VERR_VMM_SWITCHER_IPE_1 (-2713) +/** Reason for leaving RZ: Unknown call to ring-3. */ +#define VINF_VMM_UNKNOWN_RING3_CALL (2714) +/** Attempted to use stub switcher. */ +#define VERR_VMM_SWITCHER_STUB (-2715) +/** HM returned in the wrong state. */ +#define VERR_VMM_WRONG_HM_VMCPU_STATE (-2716) /** @} */ @@ -1224,13 +1260,9 @@ /** No PCI Bus is available to register the device with. This is usually a * misconfiguration or in rare cases a buggy pci device. */ #define VERR_PDM_NO_PCI_BUS (-2833) -/** PCI physical read with bus mastering disabled. */ -#define VINF_PDM_PCI_PHYS_READ_BM_DISABLED (2833) /** The device is not a registered PCI device and thus cannot * perform any PCI operations. The device forgot to register it self. */ #define VERR_PDM_NOT_PCI_DEVICE (-2834) -/** PCI physical write with bus mastering disabled. */ -#define VINF_PDM_PCI_PHYS_WRITE_BM_DISABLED (2834) /** The version of the device registration structure is unknown * to this VBox version. Either mixing incompatible versions or @@ -1398,6 +1430,11 @@ /** The driver is already removed, not more transformations possible (at * present). */ #define VERR_PDM_CANNOT_TRANSFORM_REMOVED_DRIVER (-2890) +/** The PCI device isn't configured as a busmaster, physical memory access + * rejected. */ +#define VERR_PDM_NOT_PCI_BUS_MASTER (-2891) +/** Got into a part of PDM that is not used when HM (VT-x/AMD-V) is enabled. */ +#define VERR_PDM_HM_IPE (-2892) /** @} */ @@ -1554,6 +1591,10 @@ #define VERR_VD_READ_OUT_OF_RANGE (-3282) /** Block read was marked as free in the image and returned as a zero block. */ #define VINF_VD_NEW_ZEROED_BLOCK 3283 +/** Unable to parse the XML in DMG file. */ +#define VERR_VD_DMG_XML_PARSE_ERROR (-3284) +/** Unable to locate a usable DMG file within the XAR archive. */ +#define VERR_VD_DMG_NOT_FOUND_INSIDE_XAR (-3285) /** @} */ @@ -1851,44 +1892,64 @@ /** @name VBox VMX Status Codes * @{ */ -/** Invalid VMCS index or write to read-only element. */ -#define VERR_VMX_INVALID_VMCS_FIELD (-4000) -/** Invalid VMCS pointer. */ +/** VMXON failed; possibly because it was already run before. */ +#define VERR_VMX_VMXON_FAILED (-4000) +/** Invalid VMCS pointer. + * (Can be OR'ed with VERR_VMX_INVALID_VMCS_FIELD.) */ #define VERR_VMX_INVALID_VMCS_PTR (-4001) +/** Invalid VMCS index or write to read-only element. */ +#define VERR_VMX_INVALID_VMCS_FIELD (-4002) +/** Reserved for future status code that we wish to OR with + * VERR_VMX_INVALID_VMCS_PTR and VERR_VMX_INVALID_VMCS_FIELD. */ +#define VERR_VMX_RESERVED (-4003) /** Invalid VMXON pointer. */ -#define VERR_VMX_INVALID_VMXON_PTR (-4002) -/** Generic VMX failure. */ -#define VERR_VMX_GENERIC (-4003) -/** Invalid CPU mode for VMX execution. */ -#define VERR_VMX_UNSUPPORTED_MODE (-4004) +#define VERR_VMX_INVALID_VMXON_PTR (-4004) /** Unable to start VM execution. */ #define VERR_VMX_UNABLE_TO_START_VM (-4005) -/** Unable to resume VM execution. */ -#define VERR_VMX_UNABLE_TO_RESUME_VM (-4006) /** Unable to switch due to invalid host state. */ -#define VERR_VMX_INVALID_HOST_STATE (-4007) +#define VERR_VMX_INVALID_HOST_STATE (-4006) /** IA32_FEATURE_CONTROL MSR not setup correcty (turn on VMX in the host system BIOS) */ -#define VERR_VMX_ILLEGAL_FEATURE_CONTROL_MSR (-4008) +#define VERR_VMX_ILLEGAL_FEATURE_CONTROL_MSR (-4007) +/** Invalid CPU mode for VMX execution. */ +#define VERR_VMX_UNSUPPORTED_MODE (-4008) /** VMX CPU extension not available */ #define VERR_VMX_NO_VMX (-4009) -/** VMXON failed; possibly because it was already run before */ -#define VERR_VMX_VMXON_FAILED (-4010) /** CPU was incorrectly left in VMX root mode; incompatible with VirtualBox */ #define VERR_VMX_IN_VMX_ROOT_MODE (-4011) /** Somebody cleared X86_CR4_VMXE in the CR4 register. */ #define VERR_VMX_X86_CR4_VMXE_CLEARED (-4012) -/** VT-x features locked or unavailable in MSR. */ -#define VERR_VMX_MSR_LOCKED_OR_DISABLED (-4013) +/** Failed to enable and lock VT-x features. */ +#define VERR_VMX_MSR_LOCKING_FAILED (-4013) /** Unable to switch due to invalid guest state. */ #define VERR_VMX_INVALID_GUEST_STATE (-4014) -/** Unexpected VM exit code. */ -#define VERR_VMX_UNEXPECTED_EXIT_CODE (-4015) -/** Unexpected VM exception code. */ +/** Unexpected VM exit. */ +#define VERR_VMX_UNEXPECTED_EXIT (-4015) +/** Unexpected VM exception. */ #define VERR_VMX_UNEXPECTED_EXCEPTION (-4016) -/** Unexpected interruption exit code. */ -#define VERR_VMX_UNEXPECTED_INTERRUPTION_EXIT_CODE (-4017) -/** CPU is not in VMX root mode; unexpected when leaving VMX root mode */ +/** Unexpected interruption exit type. */ +#define VERR_VMX_UNEXPECTED_INTERRUPTION_EXIT_TYPE (-4017) +/** CPU is not in VMX root mode; unexpected when leaving VMX root mode. */ #define VERR_VMX_NOT_IN_VMX_ROOT_MODE (-4018) +/** Undefined VM exit code. */ +#define VERR_VMX_UNDEFINED_EXIT_CODE (-4019) +/** VMPTRLD failed; possibly because of invalid VMCS launch-state. */ +#define VERR_VMX_VMPTRLD_FAILED (-4021) +/** Invalid VMCS pointer passed to VMLAUNCH/VMRESUME. */ +#define VERR_VMX_INVALID_VMCS_PTR_TO_START_VM (-4022) +/** Internal VMX processing error no 1. */ +#define VERR_HMVMX_IPE_1 (-4023) +/** Internal VMX processing error no 1. */ +#define VERR_HMVMX_IPE_2 (-4024) +/** Internal VMX processing error no 1. */ +#define VERR_HMVMX_IPE_3 (-4025) +/** Internal VMX processing error no 1. */ +#define VERR_HMVMX_IPE_4 (-4026) +/** Internal VMX processing error no 1. */ +#define VERR_HMVMX_IPE_5 (-4027) +/** VT-x features for SMX operation disabled by the BIOS. */ +#define VERR_VMX_MSR_SMX_VMXON_DISABLED (-4028) +/** VT-x features disabled by the BIOS. */ +#define VERR_VMX_MSR_VMXON_DISABLED (-4029) /** @} */ @@ -1905,44 +1966,60 @@ #define VERR_SVM_DISABLED (-4053) /** AMD-V CPU extension in-use. */ #define VERR_SVM_IN_USE (-4054) +/** Invalid pVMCB. */ +#define VERR_SVM_INVALID_PVMCB (-4055) +/** Unexpected SVM exit. */ +#define VERR_SVM_UNEXPECTED_EXIT (-4056) +/** Unexpected SVM exception exit. */ +#define VERR_SVM_UNEXPECTED_XCPT_EXIT (-4057) +/** Unexpected SVM patch type. */ +#define VERR_SVM_UNEXPECTED_PATCH_TYPE (-4058) +/** Unable to start VM execution due to an invalid guest state. */ +#define VERR_SVM_INVALID_GUEST_STATE (-4059) +/** Unknown or unrecognized SVM exit. */ +#define VERR_SVM_UNKNOWN_EXIT (-4060) /** @} */ -/** @name VBox HWACCM Status Codes +/** @name VBox HM Status Codes * @{ */ /** Unable to start VM execution. */ -#define VERR_HWACCM_UNKNOWN_CPU (-4100) +#define VERR_HM_UNKNOWN_CPU (-4100) /** No CPUID support. */ -#define VERR_HWACCM_NO_CPUID (-4101) +#define VERR_HM_NO_CPUID (-4101) /** Host is about to go into suspend mode. */ -#define VERR_HWACCM_SUSPEND_PENDING (-4102) +#define VERR_HM_SUSPEND_PENDING (-4102) /** Conflicting CFGM values. */ -#define VERR_HWACCM_CONFIG_MISMATCH (-4103) +#define VERR_HM_CONFIG_MISMATCH (-4103) /** Internal processing error in the HM init code. */ #define VERR_HM_ALREADY_ENABLED_IPE (-4104) /** Unexpected MSR in the load / restore list. */ #define VERR_HM_UNEXPECTED_LD_ST_MSR (-4105) /** No 32-bit to 64-bit switcher in place. */ #define VERR_HM_NO_32_TO_64_SWITCHER (-4106) -/** Invalid pVMCB. */ -#define VERR_HMSVM_INVALID_PVMCB (-4107) -/** Unexpected SVM exit. */ -#define VERR_HMSVM_UNEXPECTED_EXIT (-4108) -/** Unexpected SVM exception exit. */ -#define VERR_HMSVM_UNEXPECTED_XCPT_EXIT (-4109) -/** Unexpected SVM patch type. */ -#define VERR_HMSVM_UNEXPECTED_PATCH_TYPE (-4110) -/** HWACCMR0Leave was called on the wrong CPU. */ -#define VERR_HM_WRONG_CPU_1 (-4111) +/** HMR0Leave was called on the wrong CPU. */ +#define VERR_HM_WRONG_CPU_1 (-4107) /** Internal processing error \#1 in the HM code. */ -#define VERR_HM_IPE_1 (-4112) +#define VERR_HM_IPE_1 (-4108) /** Internal processing error \#2 in the HM code. */ -#define VERR_HM_IPE_2 (-4113) +#define VERR_HM_IPE_2 (-4109) /** Wrong 32/64-bit switcher. */ -#define VERR_HM_WRONG_SWITCHER (-4114) +#define VERR_HM_WRONG_SWITCHER (-4110) /** Unknown I/O instruction. */ -#define VERR_HM_UNKNOWN_IO_INSTRUCTION (-4115) +#define VERR_HM_UNKNOWN_IO_INSTRUCTION (-4111) +/** Unsupported CPU feature combination. */ +#define VERR_HM_UNSUPPORTED_CPU_FEATURE_COMBO (-4112) +/** Internal processing error \#3 in the HM code. */ +#define VERR_HM_IPE_3 (-4113) +/** Internal processing error \#3 in the HM code. */ +#define VERR_HM_IPE_4 (-4114) +/** Internal processing error \#3 in the HM code. */ +#define VERR_HM_IPE_5 (-4115) +/** Invalid HM64ON32OP value. */ +#define VERR_HM_INVALID_HM64ON32OP (-4116) +/** Resume guest execution after injecting a double-fault. */ +#define VINF_HM_DOUBLE_FAULT 4117 /** @} */ @@ -1959,8 +2036,6 @@ #define VERR_DIS_INVALID_MODRM (-4203) /** Invalid parameter index. */ #define VERR_DIS_INVALID_PARAMETER (-4204) -/** Reading opcode bytes failed. */ -#define VERR_DIS_MEM_READ (-4205) /** The instruction is too long. */ #define VERR_DIS_TOO_LONG_INSTR (-4206) /** @} */ @@ -2090,7 +2165,7 @@ #define VERR_PCI_PASSTHROUGH_NO_RAM_PREALLOC (-5100) /** VT-x/AMD-V not active. * PCI passthrough currently works only if VT-x/AMD-V is active. */ -#define VERR_PCI_PASSTHROUGH_NO_HWACCM (-5101) +#define VERR_PCI_PASSTHROUGH_NO_HM (-5101) /** Nested paging not active. * PCI passthrough currently works only if nested paging is active. */ #define VERR_PCI_PASSTHROUGH_NO_NESTED_PAGING (-5102) @@ -2117,6 +2192,17 @@ * @{ */ /** The instruction is not yet implemented by IEM. */ #define VERR_IEM_INSTR_NOT_IMPLEMENTED (-5300) +/** Invalid operand size passed to an IEM function. */ +#define VERR_IEM_INVALID_OPERAND_SIZE (-5301) +/** Invalid address mode passed to an IEM function. */ +#define VERR_IEM_INVALID_ADDRESS_MODE (-5302) +/** Invalid effective segment register number passed to an IEM function. */ +#define VERR_IEM_INVALID_EFF_SEG (-5303) +/** Invalid instruction length passed to an IEM function. */ +#define VERR_IEM_INVALID_INSTR_LENGTH (-5304) +/** Internal status code for indicating that a selector isn't valid (LAR, LSL, + * VERR, VERW). This is not used outside the instruction implementations. */ +#define VINF_IEM_SELECTOR_NOT_OK (5305) /** This particular aspect of the instruction is not yet implemented by IEM. */ #define VERR_IEM_ASPECT_NOT_IMPLEMENTED (-5391) /** Internal processing error \#1 in the IEM code.. */ @@ -2224,6 +2310,18 @@ /** @} */ +/** @} */ + +/** @name VBox Guest Control Status Codes + * @{ + */ +/** Guest side reported an error. */ +#define VERR_GSTCTL_GUEST_ERROR (-6200) +/** A guest control object has changed its overall status. */ +#define VWRN_GSTCTL_OBJECTSTATE_CHANGED 6220 +/** @} */ + + /* SED-END */ /** @} */ diff --git a/include/VBox/err.mac b/include/VBox/err.mac index 2470d6c0..ac39b103 100644 --- a/include/VBox/err.mac +++ b/include/VBox/err.mac @@ -19,6 +19,7 @@ %define VERR_INVALID_CPU_ID (-1018) %define VERR_TOO_MANY_CPUS (-1019) %define VERR_SERVICE_DISABLED (-1020) +%define VERR_NOT_SUP_IN_RAW_MODE (-1021) %define VINF_EM_FIRST 1100 %define VINF_EM_TERMINATE 1100 %define VINF_EM_DBG_HYPER_STEPPED 1101 @@ -36,7 +37,7 @@ %define VINF_EM_NO_MEMORY 1114 %define VERR_EM_NO_MEMORY (-1114) %define VINF_EM_RESCHEDULE_REM 1115 -%define VINF_EM_RESCHEDULE_HWACC 1116 +%define VINF_EM_RESCHEDULE_HM 1116 %define VINF_EM_RESCHEDULE_RAW 1117 %define VINF_EM_RESCHEDULE 1118 %define VINF_EM_RESCHEDULE_PARAV 1119 @@ -66,9 +67,10 @@ %define VERR_EM_INTERNAL_ERROR (-1149) %define VINF_EM_PENDING_REQUEST 1150 %define VINF_EM_RAW_EMULATE_DBG_STEP 1151 -%define VINF_EM_HWACCM_PATCH_TPR_INSTR 1152 -%define VERR_EM_INTERNAL_DISAS_ERROR (-1153) +%define VINF_EM_HM_PATCH_TPR_INSTR 1152 %define VERR_EM_UNEXPECTED_MAPPING_CONFLICT (-1154) +%define VINF_EM_TRIPLE_FAULT 1155 +%define VERR_EM_CANNOT_EXEC_GUEST (-1156) %define VERR_DBGF_NOT_ATTACHED (-1200) %define VERR_DBGF_ALREADY_ATTACHED (-1201) %define VWRN_DBGF_ALREADY_HALTED 1202 @@ -118,10 +120,12 @@ %define VERR_PATM_ALREADY_PATCHED (-1428) %define VINF_PATM_SPINLOCK_FAILED (1429) %define VINF_PATCH_CONTINUE (1430) +%define VERR_PATM_HM_IPE (-1431) %define VWRN_CSAM_TRAP_NOT_HANDLED 1500 %define VWRN_CSAM_INSTRUCTION_PATCHED 1501 %define VWRN_CSAM_PAGE_NOT_FOUND 1502 %define VINF_CSAM_PENDING_ACTION 1503 +%define VERR_CSAM_HM_IPE (-1504) %define VERR_PGM_MAPPING_CONFLICT (-1600) %define VERR_PGM_HANDLER_PHYSICAL_NO_RAM_RANGE (-1601) %define VERR_PGM_HANDLER_VIRTUAL_CONFLICT (-1602) @@ -203,12 +207,19 @@ %define VERR_PGM_PHYS_PAGE_GET_IPE (-1680) %define VERR_PGM_PHYS_NULL_PAGE_PARAM (-1681) %define VERR_PGM_PCI_PASSTHRU_MISCONFIG (-1682) +%define VERR_PGM_TOO_MANY_MMIO2_RANGES (-1683) +%define VERR_PGM_PHYS_PAGE_MAP_MMIO2_IPE (-1684) %define VERR_MM_RAM_CONFLICT (-1700) %define VERR_MM_HYPER_NO_MEMORY (-1701) %define VERR_MM_BAD_TRAP_TYPE_IPE (-1702) %define VERR_CPUM_RAISE_GP_0 (-1750) %define VERR_CPUM_INCOMPATIBLE_CONFIG (-1751) %define VERR_CPUM_HIDDEN_CS_LOAD_ERROR (-1752) +%define VERR_CPUM_TOO_MANY_CPUID_SUBLEAVES (-1753) +%define VERR_CPUM_IPE_1 (-1754) +%define VERR_CPUM_IPE_2 (-1755) +%define VERR_CPUM_DB_CPU_NOT_FOUND (-1756) +%define VERR_CPUM_MSR_BAD_CPUMCPU_OFFSET (-1757) %define VERR_SSM_UNIT_EXISTS (-1800) %define VERR_SSM_UNIT_NOT_FOUND (-1801) %define VERR_SSM_UNIT_NOT_OWNER (-1802) @@ -355,6 +366,7 @@ %define VERR_TRPM_IPE_1 (-2407) %define VERR_TRPM_IPE_2 (-2408) %define VERR_TRPM_IPE_3 (-2409) +%define VERR_TRPM_HM_IPE (-2410) %define VERR_SELM_SHADOW_GDT_WRITE (-2500) %define VERR_SELM_SHADOW_LDT_WRITE (-2501) %define VERR_SELM_SHADOW_TSS_WRITE (-2502) @@ -364,6 +376,7 @@ %define VERR_SELM_LDT_OUT_OF_BOUNDS (-2506) %define VERR_SELM_GDT_READ_ERROR (-2507) %define VERR_SELM_GDT_TOO_FULL (-2508) +%define VERR_SELM_HM_IPE (-2509) %define VERR_IOM_INVALID_IOPORT_RANGE (-2600) %define VERR_IOM_NO_R3_IOPORT_RANGE (-2601) %define VERR_IOM_IOPORT_RANGE_CONFLICT (-2602) @@ -393,6 +406,7 @@ %define VERR_IOM_MMIO_IPE_1 (-2634) %define VERR_IOM_MMIO_IPE_2 (-2635) %define VERR_IOM_MMIO_IPE_3 (-2636) +%define VERR_IOM_HM_IPE (-2637) %define VINF_VMM_CALL_HOST 2700 %define VERR_VMM_RING0_ASSERTION (-2701) %define VERR_VMM_HYPER_CR3_MISMATCH (-2702) @@ -407,6 +421,9 @@ %define VERR_VMM_RING3_CALL_NO_RC (-2711) %define VINF_VMM_CALL_TRACER (2712) %define VERR_VMM_SWITCHER_IPE_1 (-2713) +%define VINF_VMM_UNKNOWN_RING3_CALL (2714) +%define VERR_VMM_SWITCHER_STUB (-2715) +%define VERR_VMM_WRONG_HM_VMCPU_STATE (-2716) %define VERR_PDM_NO_SUCH_LUN (-2800) %define VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES (-2801) %define VERR_PDM_MISSING_INTERFACE_ABOVE (-2802) @@ -441,9 +458,7 @@ %define VERR_PDM_INVALID_DRIVER_HOST_BITS (-2831) %define VERR_PDM_DRIVER_DETACH_NOT_POSSIBLE (-2832) %define VERR_PDM_NO_PCI_BUS (-2833) -%define VINF_PDM_PCI_PHYS_READ_BM_DISABLED (2833) %define VERR_PDM_NOT_PCI_DEVICE (-2834) -%define VINF_PDM_PCI_PHYS_WRITE_BM_DISABLED (2834) %define VERR_PDM_UNKNOWN_DEVREG_VERSION (-2835) %define VERR_PDM_INVALID_DEVICE_REGISTRATION (-2836) %define VERR_PDM_INVALID_DEVICE_GUEST_BITS (-2837) @@ -501,6 +516,8 @@ %define VERR_PDM_DEV_IPE_1 (-2888) %define VERR_PDM_MISCONFIGURED_DRV_TRANSFORMATION (-2889) %define VERR_PDM_CANNOT_TRANSFORM_REMOVED_DRIVER (-2890) +%define VERR_PDM_NOT_PCI_BUS_MASTER (-2891) +%define VERR_PDM_HM_IPE (-2892) %define VERR_HGCM_SERVICE_NOT_FOUND (-2900) %define VINF_HGCM_CLIENT_REJECTED 2901 %define VERR_HGCM_INVALID_CMD_ADDRESS (-2902) @@ -564,6 +581,8 @@ %define VERR_VD_IMAGE_REPAIR_IMPOSSIBLE (-3281) %define VERR_VD_READ_OUT_OF_RANGE (-3282) %define VINF_VD_NEW_ZEROED_BLOCK 3283 +%define VERR_VD_DMG_XML_PARSE_ERROR (-3284) +%define VERR_VD_DMG_NOT_FOUND_INSIDE_XAR (-3285) %define VERR_VBGL_NOT_INITIALIZED (-3300) %define VERR_VBGL_INVALID_ADDR (-3301) %define VERR_VBGL_IOCTL_FAILED (-3302) @@ -678,52 +697,68 @@ %define VINF_GVM_NOT_BLOCKED 3901 %define VINF_GVM_NOT_BUSY_IN_GC 3902 %define VINF_GVM_YIELDED 3903 -%define VERR_VMX_INVALID_VMCS_FIELD (-4000) +%define VERR_VMX_VMXON_FAILED (-4000) %define VERR_VMX_INVALID_VMCS_PTR (-4001) -%define VERR_VMX_INVALID_VMXON_PTR (-4002) -%define VERR_VMX_GENERIC (-4003) -%define VERR_VMX_UNSUPPORTED_MODE (-4004) +%define VERR_VMX_INVALID_VMCS_FIELD (-4002) +%define VERR_VMX_RESERVED (-4003) +%define VERR_VMX_INVALID_VMXON_PTR (-4004) %define VERR_VMX_UNABLE_TO_START_VM (-4005) -%define VERR_VMX_UNABLE_TO_RESUME_VM (-4006) -%define VERR_VMX_INVALID_HOST_STATE (-4007) -%define VERR_VMX_ILLEGAL_FEATURE_CONTROL_MSR (-4008) +%define VERR_VMX_INVALID_HOST_STATE (-4006) +%define VERR_VMX_ILLEGAL_FEATURE_CONTROL_MSR (-4007) +%define VERR_VMX_UNSUPPORTED_MODE (-4008) %define VERR_VMX_NO_VMX (-4009) -%define VERR_VMX_VMXON_FAILED (-4010) %define VERR_VMX_IN_VMX_ROOT_MODE (-4011) %define VERR_VMX_X86_CR4_VMXE_CLEARED (-4012) -%define VERR_VMX_MSR_LOCKED_OR_DISABLED (-4013) +%define VERR_VMX_MSR_LOCKING_FAILED (-4013) %define VERR_VMX_INVALID_GUEST_STATE (-4014) -%define VERR_VMX_UNEXPECTED_EXIT_CODE (-4015) +%define VERR_VMX_UNEXPECTED_EXIT (-4015) %define VERR_VMX_UNEXPECTED_EXCEPTION (-4016) -%define VERR_VMX_UNEXPECTED_INTERRUPTION_EXIT_CODE (-4017) +%define VERR_VMX_UNEXPECTED_INTERRUPTION_EXIT_TYPE (-4017) %define VERR_VMX_NOT_IN_VMX_ROOT_MODE (-4018) +%define VERR_VMX_UNDEFINED_EXIT_CODE (-4019) +%define VERR_VMX_VMPTRLD_FAILED (-4021) +%define VERR_VMX_INVALID_VMCS_PTR_TO_START_VM (-4022) +%define VERR_HMVMX_IPE_1 (-4023) +%define VERR_HMVMX_IPE_2 (-4024) +%define VERR_HMVMX_IPE_3 (-4025) +%define VERR_HMVMX_IPE_4 (-4026) +%define VERR_HMVMX_IPE_5 (-4027) +%define VERR_VMX_MSR_SMX_VMXON_DISABLED (-4028) +%define VERR_VMX_MSR_VMXON_DISABLED (-4029) %define VERR_SVM_UNABLE_TO_START_VM (-4050) %define VERR_SVM_ILLEGAL_EFER_MSR (-4051) %define VERR_SVM_NO_SVM (-4052) %define VERR_SVM_DISABLED (-4053) %define VERR_SVM_IN_USE (-4054) -%define VERR_HWACCM_UNKNOWN_CPU (-4100) -%define VERR_HWACCM_NO_CPUID (-4101) -%define VERR_HWACCM_SUSPEND_PENDING (-4102) -%define VERR_HWACCM_CONFIG_MISMATCH (-4103) +%define VERR_SVM_INVALID_PVMCB (-4055) +%define VERR_SVM_UNEXPECTED_EXIT (-4056) +%define VERR_SVM_UNEXPECTED_XCPT_EXIT (-4057) +%define VERR_SVM_UNEXPECTED_PATCH_TYPE (-4058) +%define VERR_SVM_INVALID_GUEST_STATE (-4059) +%define VERR_SVM_UNKNOWN_EXIT (-4060) +%define VERR_HM_UNKNOWN_CPU (-4100) +%define VERR_HM_NO_CPUID (-4101) +%define VERR_HM_SUSPEND_PENDING (-4102) +%define VERR_HM_CONFIG_MISMATCH (-4103) %define VERR_HM_ALREADY_ENABLED_IPE (-4104) %define VERR_HM_UNEXPECTED_LD_ST_MSR (-4105) %define VERR_HM_NO_32_TO_64_SWITCHER (-4106) -%define VERR_HMSVM_INVALID_PVMCB (-4107) -%define VERR_HMSVM_UNEXPECTED_EXIT (-4108) -%define VERR_HMSVM_UNEXPECTED_XCPT_EXIT (-4109) -%define VERR_HMSVM_UNEXPECTED_PATCH_TYPE (-4110) -%define VERR_HM_WRONG_CPU_1 (-4111) -%define VERR_HM_IPE_1 (-4112) -%define VERR_HM_IPE_2 (-4113) -%define VERR_HM_WRONG_SWITCHER (-4114) -%define VERR_HM_UNKNOWN_IO_INSTRUCTION (-4115) +%define VERR_HM_WRONG_CPU_1 (-4107) +%define VERR_HM_IPE_1 (-4108) +%define VERR_HM_IPE_2 (-4109) +%define VERR_HM_WRONG_SWITCHER (-4110) +%define VERR_HM_UNKNOWN_IO_INSTRUCTION (-4111) +%define VERR_HM_UNSUPPORTED_CPU_FEATURE_COMBO (-4112) +%define VERR_HM_IPE_3 (-4113) +%define VERR_HM_IPE_4 (-4114) +%define VERR_HM_IPE_5 (-4115) +%define VERR_HM_INVALID_HM64ON32OP (-4116) +%define VINF_HM_DOUBLE_FAULT 4117 %define VERR_DIS_INVALID_OPCODE (-4200) %define VERR_DIS_GEN_FAILURE (-4201) %define VERR_DIS_NO_READ_CALLBACK (-4202) %define VERR_DIS_INVALID_MODRM (-4203) %define VERR_DIS_INVALID_PARAMETER (-4204) -%define VERR_DIS_MEM_READ (-4205) %define VERR_DIS_TOO_LONG_INSTR (-4206) %define VERR_WEB_NOT_AUTHENTICATED (-4300) %define VERR_WEB_INVALID_MANAGED_OBJECT_REFERENCE (-4301) @@ -759,7 +794,7 @@ %define VERR_FAM_MONITOR_DIRECTORY_FAILED (-5002) %define VERR_FAM_CONNECTION_LOST (-5003) %define VERR_PCI_PASSTHROUGH_NO_RAM_PREALLOC (-5100) -%define VERR_PCI_PASSTHROUGH_NO_HWACCM (-5101) +%define VERR_PCI_PASSTHROUGH_NO_HM (-5101) %define VERR_PCI_PASSTHROUGH_NO_NESTED_PAGING (-5102) %define VERR_GVMM_INSTANCE (-5200) %define VERR_GVMM_HOST_CPU_RANGE (-5201) @@ -767,6 +802,11 @@ %define VERR_GVMM_IPE_1 (-5203) %define VERR_GVMM_IPE_2 (-5204) %define VERR_IEM_INSTR_NOT_IMPLEMENTED (-5300) +%define VERR_IEM_INVALID_OPERAND_SIZE (-5301) +%define VERR_IEM_INVALID_ADDRESS_MODE (-5302) +%define VERR_IEM_INVALID_EFF_SEG (-5303) +%define VERR_IEM_INVALID_INSTR_LENGTH (-5304) +%define VINF_IEM_SELECTOR_NOT_OK (5305) %define VERR_IEM_ASPECT_NOT_IMPLEMENTED (-5391) %define VERR_IEM_IPE_1 (-5392) %define VERR_IEM_IPE_2 (-5393) @@ -809,4 +849,6 @@ %define VERR_DBGC_PARSE_BUG (VERR_DBGC_PARSE_LOWEST + 25) %define VERR_EXTPACK_UNSUPPORTED_HOST_UNINSTALL (-6000) %define VERR_EXTPACK_VBOX_VERSION_MISMATCH (-6001) +%define VERR_GSTCTL_GUEST_ERROR (-6200) +%define VWRN_GSTCTL_OBJECTSTATE_CHANGED 6220 %include "iprt/err.mac" diff --git a/include/VBox/err.sed b/include/VBox/err.sed index b9c18489..52bb3626 100644 --- a/include/VBox/err.sed +++ b/include/VBox/err.sed @@ -3,7 +3,7 @@ # SED script for converting VBox/err.h to .mac. # -# Copyright (C) 2006-2009 Oracle Corporation +# Copyright (C) 2006-2010 Oracle Corporation # # This file is part of VirtualBox Open Source Edition (OSE), as # available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/hgcmsvc.h b/include/VBox/hgcmsvc.h index c3480a73..9442bb7d 100644 --- a/include/VBox/hgcmsvc.h +++ b/include/VBox/hgcmsvc.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/intnet.h b/include/VBox/intnet.h index dc439ea5..e032baf1 100644 --- a/include/VBox/intnet.h +++ b/include/VBox/intnet.h @@ -213,11 +213,11 @@ typedef INTNETIFHANDLE *PINTNETIFHANDLE; */ typedef struct INTNETHDR { + /** The size of the frame. */ + uint32_t cbFrame : 24; /** Header type. This is currently serving as a magic, it * can be extended later to encode special command frames and stuff. */ - uint16_t u16Type; - /** The size of the frame. */ - uint16_t cbFrame; + uint32_t u8Type : 8; /** The offset from the start of this header to where the actual frame starts. * This is used to keep the frame it self contiguous in virtual memory and * thereby both simplify access as well as the descriptor. */ @@ -235,16 +235,16 @@ typedef INTNETHDR const *PCINTNETHDR; AssertCompile(sizeof(INTNETHDR) == INTNETHDR_ALIGNMENT); AssertCompile(INTNETHDR_ALIGNMENT <= INTNETRINGBUF_ALIGNMENT); -/** @name Frame types (INTNETHDR::u16Type). +/** @name Frame types (INTNETHDR::u8Type). * @{ */ /** Normal frames. */ -#define INTNETHDR_TYPE_FRAME 0x2442 +#define INTNETHDR_TYPE_FRAME 0x42 /** Padding frames. */ -#define INTNETHDR_TYPE_PADDING 0x3553 +#define INTNETHDR_TYPE_PADDING 0x53 /** Generic segment offload frames. * The frame starts with a PDMNETWORKGSO structure which is followed by the * header template and data. */ -#define INTNETHDR_TYPE_GSO 0x4664 +#define INTNETHDR_TYPE_GSO 0x64 AssertCompileSize(PDMNETWORKGSO, 8); /** @} */ @@ -257,9 +257,9 @@ AssertCompileSize(PDMNETWORKGSO, 8); { \ AssertPtr(pHdr); \ Assert(RT_ALIGN_PT(pHdr, INTNETHDR_ALIGNMENT, INTNETHDR *) == pHdr); \ - Assert( (pHdr)->u16Type == INTNETHDR_TYPE_FRAME \ - || (pHdr)->u16Type == INTNETHDR_TYPE_GSO \ - || (pHdr)->u16Type == INTNETHDR_TYPE_PADDING); \ + Assert( (pHdr)->u8Type == INTNETHDR_TYPE_FRAME \ + || (pHdr)->u8Type == INTNETHDR_TYPE_GSO \ + || (pHdr)->u8Type == INTNETHDR_TYPE_PADDING); \ { \ uintptr_t const offHdr = (uintptr_t)pHdr - (uintptr_t)pRingBuf; \ uintptr_t const offFrame = offHdr + (pHdr)->offFrame; \ diff --git a/include/VBox/intnetinline.h b/include/VBox/intnetinline.h index bcc42f1a..77d8dbb2 100644 --- a/include/VBox/intnetinline.h +++ b/include/VBox/intnetinline.h @@ -8,7 +8,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -43,13 +43,13 @@ * Valid internal networking frame type. * * @returns true / false. - * @param u16Type The frame type to check. + * @param u8Type The frame type to check. */ -DECLINLINE(bool) IntNetIsValidFrameType(uint16_t u16Type) +DECLINLINE(bool) IntNetIsValidFrameType(uint8_t u8Type) { - if (RT_LIKELY( u16Type == INTNETHDR_TYPE_FRAME - || u16Type == INTNETHDR_TYPE_GSO - || u16Type == INTNETHDR_TYPE_PADDING)) + if (RT_LIKELY( u8Type == INTNETHDR_TYPE_FRAME + || u8Type == INTNETHDR_TYPE_GSO + || u8Type == INTNETHDR_TYPE_PADDING)) return true; return false; } @@ -327,7 +327,7 @@ DECLINLINE(void *) IntNetHdrGetFramePtr(PCINTNETHDR pHdr, PCINTNETBUF pBuf) uint8_t *pu8 = (uint8_t *)pHdr + pHdr->offFrame; #ifdef VBOX_STRICT const uintptr_t off = (uintptr_t)pu8 - (uintptr_t)pBuf; - Assert(IntNetIsValidFrameType(pHdr->u16Type)); + Assert(IntNetIsValidFrameType(pHdr->u8Type)); Assert(off < pBuf->cbBuf); Assert(off + pHdr->cbFrame <= pBuf->cbBuf); #endif @@ -353,7 +353,7 @@ DECLINLINE(PPDMNETWORKGSO) IntNetHdrGetGsoContext(PCINTNETHDR pHdr, PCINTNETBUF PPDMNETWORKGSO pGso = (PPDMNETWORKGSO)((uint8_t *)pHdr + pHdr->offFrame); #ifdef VBOX_STRICT const uintptr_t off = (uintptr_t)pGso - (uintptr_t)pBuf; - Assert(pHdr->u16Type == INTNETHDR_TYPE_GSO); + Assert(pHdr->u8Type == INTNETHDR_TYPE_GSO); Assert(off < pBuf->cbBuf); Assert(off + pHdr->cbFrame <= pBuf->cbBuf); #endif @@ -374,7 +374,7 @@ DECLINLINE(void) IntNetRingSkipFrame(PINTNETRINGBUF pRingBuf) Assert(offReadOld >= pRingBuf->offStart); Assert(offReadOld < pRingBuf->offEnd); Assert(RT_ALIGN_PT(pHdr, INTNETHDR_ALIGNMENT, INTNETHDR *) == pHdr); - Assert(IntNetIsValidFrameType(pHdr->u16Type)); + Assert(IntNetIsValidFrameType(pHdr->u8Type)); /* skip the frame */ uint32_t offReadNew = offReadOld + pHdr->offFrame + pHdr->cbFrame; @@ -401,7 +401,7 @@ DECLINLINE(void) IntNetRingSkipFrame(PINTNETRINGBUF pRingBuf) * Don't touch this! * @param ppvFrame Where to return the frame pointer. */ -DECLINLINE(int) intnetRingAllocateFrameInternal(PINTNETRINGBUF pRingBuf, uint32_t cbFrame, uint16_t u16Type, +DECLINLINE(int) intnetRingAllocateFrameInternal(PINTNETRINGBUF pRingBuf, uint32_t cbFrame, uint8_t u8Type, PINTNETHDR *ppHdr, void **ppvFrame) { /* @@ -425,11 +425,11 @@ DECLINLINE(int) intnetRingAllocateFrameInternal(PINTNETRINGBUF pRingBuf, uint32_ offNew = pRingBuf->offStart; if (RT_UNLIKELY(!ASMAtomicCmpXchgU32(&pRingBuf->offWriteInt, offNew, offWriteInt))) return VERR_WRONG_ORDER; /* race */ - Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (1) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u16Type, cbFrame)); + Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (1) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u8Type, cbFrame)); PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt); - pHdr->u16Type = u16Type; - pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame); + pHdr->u8Type = u8Type; + pHdr->cbFrame = cbFrame; Assert(pHdr->cbFrame == cbFrame); pHdr->offFrame = sizeof(INTNETHDR); *ppHdr = pHdr; @@ -446,11 +446,11 @@ DECLINLINE(int) intnetRingAllocateFrameInternal(PINTNETRINGBUF pRingBuf, uint32_ uint32_t offNew = pRingBuf->offStart + cb; if (RT_UNLIKELY(!ASMAtomicCmpXchgU32(&pRingBuf->offWriteInt, offNew, offWriteInt))) return VERR_WRONG_ORDER; /* race */ - Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (2) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u16Type, cbFrame)); + Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (2) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u8Type, cbFrame)); PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt); - pHdr->u16Type = u16Type; - pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame); + pHdr->u8Type = u8Type; + pHdr->cbFrame = cbFrame; Assert(pHdr->cbFrame == cbFrame); pHdr->offFrame = pRingBuf->offStart - offWriteInt; *ppHdr = pHdr; @@ -466,11 +466,11 @@ DECLINLINE(int) intnetRingAllocateFrameInternal(PINTNETRINGBUF pRingBuf, uint32_ uint32_t offNew = offWriteInt + cb + sizeof(INTNETHDR); if (RT_UNLIKELY(!ASMAtomicCmpXchgU32(&pRingBuf->offWriteInt, offNew, offWriteInt))) return VERR_WRONG_ORDER; /* race */ - Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (3) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u16Type, cbFrame)); + Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (3) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u8Type, cbFrame)); PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt); - pHdr->u16Type = u16Type; - pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame); + pHdr->u8Type = u8Type; + pHdr->cbFrame = cbFrame; Assert(pHdr->cbFrame == cbFrame); pHdr->offFrame = sizeof(INTNETHDR); *ppHdr = pHdr; @@ -560,7 +560,7 @@ DECLINLINE(void) IntNetRingCommitFrame(PINTNETRINGBUF pRingBuf, PINTNETHDR pHdr) Assert(offWriteCom == pRingBuf->offEnd); offWriteCom = pRingBuf->offStart; } - Log2(("IntNetRingCommitFrame: offWriteCom: %#x -> %#x (R=%#x T=%#x S=%#x)\n", pRingBuf->offWriteCom, offWriteCom, pRingBuf->offReadX, pHdr->u16Type, cbFrame)); + Log2(("IntNetRingCommitFrame: offWriteCom: %#x -> %#x (R=%#x T=%#x S=%#x)\n", pRingBuf->offWriteCom, offWriteCom, pRingBuf->offReadX, pHdr->u8Type, cbFrame)); ASMAtomicWriteU32(&pRingBuf->offWriteCom, offWriteCom); STAM_REL_COUNTER_ADD(&pRingBuf->cbStatWritten, cbFrame); STAM_REL_COUNTER_INC(&pRingBuf->cStatFrames); @@ -588,7 +588,7 @@ DECLINLINE(void) IntNetRingCommitFrameEx(PINTNETRINGBUF pRingBuf, PINTNETHDR pHd INTNETHDR_ASSERT_SANITY(pHdr, pRingBuf); Assert(pRingBuf->offWriteCom == ((uintptr_t)pHdr - (uintptr_t)pRingBuf)); - if (pHdr->u16Type == INTNETHDR_TYPE_GSO) + if (pHdr->u8Type == INTNETHDR_TYPE_GSO) cbUsed += sizeof(PDMNETWORKGSO); /* @@ -612,13 +612,14 @@ DECLINLINE(void) IntNetRingCommitFrameEx(PINTNETRINGBUF pRingBuf, PINTNETHDR pHd { /** @todo Later: Try unallocate the extra memory. */ PINTNETHDR pHdrPadding = (PINTNETHDR)((uint8_t *)pHdr + pHdr->offFrame + cbAlignedUsed); - pHdrPadding->u16Type = INTNETHDR_TYPE_PADDING; - pHdrPadding->cbFrame = (uint16_t)(cbAlignedFrame - cbAlignedUsed - sizeof(INTNETHDR)); + pHdrPadding->u8Type = INTNETHDR_TYPE_PADDING; + pHdrPadding->cbFrame = cbAlignedFrame - cbAlignedUsed - sizeof(INTNETHDR); + Assert(pHdrPadding->cbFrame == cbAlignedFrame - cbAlignedUsed - sizeof(INTNETHDR)); pHdrPadding->offFrame = sizeof(INTNETHDR); - pHdr->cbFrame = (uint16_t)cbUsed; + pHdr->cbFrame = cbUsed; Assert(pHdr->cbFrame == cbUsed); } - Log2(("IntNetRingCommitFrameEx: offWriteCom: %#x -> %#x (R=%#x T=%#x S=%#x P=%#x)\n", pRingBuf->offWriteCom, offWriteCom, pRingBuf->offReadX, pHdr->u16Type, pHdr->cbFrame, cbAlignedFrame - cbAlignedUsed)); + Log2(("IntNetRingCommitFrameEx: offWriteCom: %#x -> %#x (R=%#x T=%#x S=%#x P=%#x)\n", pRingBuf->offWriteCom, offWriteCom, pRingBuf->offReadX, pHdr->u8Type, pHdr->cbFrame, cbAlignedFrame - cbAlignedUsed)); ASMAtomicWriteU32(&pRingBuf->offWriteCom, offWriteCom); STAM_REL_COUNTER_ADD(&pRingBuf->cbStatWritten, cbUsed); STAM_REL_COUNTER_INC(&pRingBuf->cStatFrames); @@ -664,8 +665,8 @@ DECLINLINE(int) IntNetRingWriteFrame(PINTNETRINGBUF pRingBuf, const void *pvFram Log2(("IntNetRingWriteFrame: offWriteInt: %#x -> %#x (1)\n", offWriteInt, offNew)); PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt); - pHdr->u16Type = INTNETHDR_TYPE_FRAME; - pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame); + pHdr->u8Type = INTNETHDR_TYPE_FRAME; + pHdr->cbFrame = cbFrame; Assert(pHdr->cbFrame == cbFrame); pHdr->offFrame = sizeof(INTNETHDR); memcpy(pHdr + 1, pvFrame, cbFrame); @@ -689,8 +690,8 @@ DECLINLINE(int) IntNetRingWriteFrame(PINTNETRINGBUF pRingBuf, const void *pvFram Log2(("IntNetRingWriteFrame: offWriteInt: %#x -> %#x (2)\n", offWriteInt, offNew)); PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt); - pHdr->u16Type = INTNETHDR_TYPE_FRAME; - pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame); + pHdr->u8Type = INTNETHDR_TYPE_FRAME; + pHdr->cbFrame = cbFrame; Assert(pHdr->cbFrame == cbFrame); pHdr->offFrame = pRingBuf->offStart - offWriteInt; memcpy((uint8_t *)pRingBuf + pRingBuf->offStart, pvFrame, cbFrame); @@ -713,8 +714,8 @@ DECLINLINE(int) IntNetRingWriteFrame(PINTNETRINGBUF pRingBuf, const void *pvFram Log2(("IntNetRingWriteFrame: offWriteInt: %#x -> %#x (3)\n", offWriteInt, offNew)); PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt); - pHdr->u16Type = INTNETHDR_TYPE_FRAME; - pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame); + pHdr->u8Type = INTNETHDR_TYPE_FRAME; + pHdr->cbFrame = cbFrame; Assert(pHdr->cbFrame == cbFrame); pHdr->offFrame = sizeof(INTNETHDR); memcpy(pHdr + 1, pvFrame, cbFrame); diff --git a/include/VBox/log.h b/include/VBox/log.h index 05d53b7b..276caa5d 100644 --- a/include/VBox/log.h +++ b/include/VBox/log.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2012 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -147,6 +147,8 @@ typedef enum LOGGROUP LOG_GROUP_DEV_VMM_BACKDOOR, /** VMM Device group for logging guest backdoor logging to stderr. */ LOG_GROUP_DEV_VMM_STDERR, + /** VMSVGA Device group. */ + LOG_GROUP_DEV_VMSVGA, /** Disassembler group. */ LOG_GROUP_DIS, /** Generic driver group. */ @@ -229,16 +231,362 @@ typedef enum LOGGROUP LOG_GROUP_HGCM, /** HGSMI group */ LOG_GROUP_HGSMI, - /** HWACCM group. */ - LOG_GROUP_HWACCM, + /** HM group. */ + LOG_GROUP_HM, /** IEM group. */ LOG_GROUP_IEM, /** IOM group. */ LOG_GROUP_IOM, /** XPCOM IPC group. */ LOG_GROUP_IPC, + /** lwIP group. */ + LOG_GROUP_LWIP, + /** lwIP group, api_lib.c API_LIB_DEBUG */ + LOG_GROUP_LWIP_API_LIB, + /** lwIP group, api_msg.c API_MSG_DEBUG */ + LOG_GROUP_LWIP_API_MSG, + /** lwIP group, etharp.c ETHARP_DEBUG */ + LOG_GROUP_LWIP_ETHARP, + /** lwIP group, icmp.c ICMP_DEBUG */ + LOG_GROUP_LWIP_ICMP, + /** lwIP group, igmp.c IGMP_DEBUG */ + LOG_GROUP_LWIP_IGMP, + /** lwIP group, inet.c INET_DEBUG */ + LOG_GROUP_LWIP_INET, + /** lwIP group, IP_DEBUG (sic!) */ + LOG_GROUP_LWIP_IP4, + /** lwIP group, ip_frag.c IP_REASS_DEBUG (sic!) */ + LOG_GROUP_LWIP_IP4_REASS, + /** lwIP group, IP6_DEBUG */ + LOG_GROUP_LWIP_IP6, + /** lwIP group, mem.c MEM_DEBUG */ + LOG_GROUP_LWIP_MEM, + /** lwIP group, memp.c MEMP_DEBUG */ + LOG_GROUP_LWIP_MEMP, + /** lwIP group, netif.c NETIF_DEBUG */ + LOG_GROUP_LWIP_NETIF, + /** lwIP group, pbuf.c PBUF_DEBUG */ + LOG_GROUP_LWIP_PBUF, + /** lwIP group, raw.c RAW_DEBUG */ + LOG_GROUP_LWIP_RAW, + /** lwIP group, sockets.c SOCKETS_DEBUG */ + LOG_GROUP_LWIP_SOCKETS, + /** lwIP group, SYS_DEBUG */ + LOG_GROUP_LWIP_SYS, + /** lwIP group, TCP_DEBUG */ + LOG_GROUP_LWIP_TCP, + /** lwIP group, tcpip.c TCPIP_DEBUG */ + LOG_GROUP_LWIP_TCPIP, + /** lwIP group, TCP_CWND_DEBUG (congestion window) */ + LOG_GROUP_LWIP_TCP_CWND, + /** lwIP group, tcp_in.c TCP_FR_DEBUG (fast retransmit) */ + LOG_GROUP_LWIP_TCP_FR, + /** lwIP group, tcp_in.c TCP_INPUT_DEBUG */ + LOG_GROUP_LWIP_TCP_INPUT, + /** lwIP group, tcp_out.c TCP_OUTPUT_DEBUG */ + LOG_GROUP_LWIP_TCP_OUTPUT, + /** lwIP group, TCP_QLEN_DEBUG */ + LOG_GROUP_LWIP_TCP_QLEN, + /** lwIP group, TCP_RST_DEBUG */ + LOG_GROUP_LWIP_TCP_RST, + /** lwIP group, TCP_RTO_DEBUG (retransmit) */ + LOG_GROUP_LWIP_TCP_RTO, + /** lwIP group, tcp_in.c TCP_WND_DEBUG (window updates) */ + LOG_GROUP_LWIP_TCP_WND, + /** lwIP group, timers.c TIMERS_DEBUG */ + LOG_GROUP_LWIP_TIMERS, + /** lwIP group, udp.c UDP_DEBUG */ + LOG_GROUP_LWIP_UDP, /** Main group. */ LOG_GROUP_MAIN, + /** Main group, IAdditionsFacility. */ + LOG_GROUP_MAIN_ADDITIONSFACILITY, + /** Main group, IAdditionsStateChangedEvent. */ + LOG_GROUP_MAIN_ADDITIONSSTATECHANGEDEVENT, + /** Main group, IAppliance. */ + LOG_GROUP_MAIN_APPLIANCE, + /** Main group, IAudioAdapter. */ + LOG_GROUP_MAIN_AUDIOADAPTER, + /** Main group, IBandwidthControl. */ + LOG_GROUP_MAIN_BANDWIDTHCONTROL, + /** Main group, IBandwidthGroup. */ + LOG_GROUP_MAIN_BANDWIDTHGROUP, + /** Main group, IBandwidthGroupChangedEvent. */ + LOG_GROUP_MAIN_BANDWIDTHGROUPCHANGEDEVENT, + /** Main group, IBIOSSettings. */ + LOG_GROUP_MAIN_BIOSSETTINGS, + /** Main group, ICanShowWindowEvent. */ + LOG_GROUP_MAIN_CANSHOWWINDOWEVENT, + /** Main group, IClipboardModeChangedEvent. */ + LOG_GROUP_MAIN_CLIPBOARDMODECHANGEDEVENT, + /** Main group, IConsole. */ + LOG_GROUP_MAIN_CONSOLE, + /** Main group, ICPUChangedEvent. */ + LOG_GROUP_MAIN_CPUCHANGEDEVENT, + /** Main group, ICPUExecutionCapChangedEvent. */ + LOG_GROUP_MAIN_CPUEXECUTIONCAPCHANGEDEVENT, + /** Main group, IDHCPServer. */ + LOG_GROUP_MAIN_DHCPSERVER, + /** Main group, IDirectory. */ + LOG_GROUP_MAIN_DIRECTORY, + /** Main group, IDisplay. */ + LOG_GROUP_MAIN_DISPLAY, + /** Main group, IDragAndDropModeChangedEvent. */ + LOG_GROUP_MAIN_DRAGANDDROPMODECHANGEDEVENT, + /** Main group, IEmulatedUSB. */ + LOG_GROUP_MAIN_EMULATEDUSB, + /** Main group, IEvent. */ + LOG_GROUP_MAIN_EVENT, + /** Main group, IEventListener. */ + LOG_GROUP_MAIN_EVENTLISTENER, + /** Main group, IEventSource. */ + LOG_GROUP_MAIN_EVENTSOURCE, + /** Main group, IEventSourceChangedEvent. */ + LOG_GROUP_MAIN_EVENTSOURCECHANGEDEVENT, + /** Main group, IExtPack. */ + LOG_GROUP_MAIN_EXTPACK, + /** Main group, IExtPackBase. */ + LOG_GROUP_MAIN_EXTPACKBASE, + /** Main group, IExtPackFile. */ + LOG_GROUP_MAIN_EXTPACKFILE, + /** Main group, IExtPackManager. */ + LOG_GROUP_MAIN_EXTPACKMANAGER, + /** Main group, IExtPackPlugIn. */ + LOG_GROUP_MAIN_EXTPACKPLUGIN, + /** Main group, IExtraDataCanChangeEvent. */ + LOG_GROUP_MAIN_EXTRADATACANCHANGEEVENT, + /** Main group, IExtraDataChangedEvent. */ + LOG_GROUP_MAIN_EXTRADATACHANGEDEVENT, + /** Main group, IFile. */ + LOG_GROUP_MAIN_FILE, + /** Main group, IFramebuffer. */ + LOG_GROUP_MAIN_FRAMEBUFFER, + /** Main group, IFramebufferOverlay. */ + LOG_GROUP_MAIN_FRAMEBUFFEROVERLAY, + /** Main group, IFsObjInfo. */ + LOG_GROUP_MAIN_FSOBJINFO, + /** Main group, IGuest. */ + LOG_GROUP_MAIN_GUEST, + /** Main group, IGuestDirectory. */ + LOG_GROUP_MAIN_GUESTDIRECTORY, + /** Main group, IGuestErrorInfo. */ + LOG_GROUP_MAIN_GUESTERRORINFO, + /** Main group, IGuestFile. */ + LOG_GROUP_MAIN_GUESTFILE, + /** Main group, IGuestFileEvent. */ + LOG_GROUP_MAIN_GUESTFILEEVENT, + /** Main group, IGuestFileIOEvent. */ + LOG_GROUP_MAIN_GUESTFILEIOEVENT, + /** Main group, IGuestFileOffsetChangedEvent. */ + LOG_GROUP_MAIN_GUESTFILEOFFSETCHANGEDEVENT, + /** Main group, IGuestFileReadEvent. */ + LOG_GROUP_MAIN_GUESTFILEREADEVENT, + /** Main group, IGuestFileRegisteredEvent. */ + LOG_GROUP_MAIN_GUESTFILEREGISTEREDEVENT, + /** Main group, IGuestFileStateChangedEvent. */ + LOG_GROUP_MAIN_GUESTFILESTATECHANGEDEVENT, + /** Main group, IGuestFileWriteEvent. */ + LOG_GROUP_MAIN_GUESTFILEWRITEEVENT, + /** Main group, IGuestFsObjInfo. */ + LOG_GROUP_MAIN_GUESTFSOBJINFO, + /** Main group, IGuestKeyboardEvent. */ + LOG_GROUP_MAIN_GUESTKEYBOARDEVENT, + /** Main group, IGuestMonitorChangedEvent. */ + LOG_GROUP_MAIN_GUESTMONITORCHANGEDEVENT, + /** Main group, IGuestMouseEvent. */ + LOG_GROUP_MAIN_GUESTMOUSEEVENT, + /** Main group, IGuestMultiTouchEvent. */ + LOG_GROUP_MAIN_GUESTMULTITOUCHEVENT, + /** Main group, IGuestOSType. */ + LOG_GROUP_MAIN_GUESTOSTYPE, + /** Main group, IGuestProcess. */ + LOG_GROUP_MAIN_GUESTPROCESS, + /** Main group, IGuestProcessEvent. */ + LOG_GROUP_MAIN_GUESTPROCESSEVENT, + /** Main group, IGuestProcessInputNotifyEvent. */ + LOG_GROUP_MAIN_GUESTPROCESSINPUTNOTIFYEVENT, + /** Main group, IGuestProcessIOEvent. */ + LOG_GROUP_MAIN_GUESTPROCESSIOEVENT, + /** Main group, IGuestProcessOutputEvent. */ + LOG_GROUP_MAIN_GUESTPROCESSOUTPUTEVENT, + /** Main group, IGuestProcessRegisteredEvent. */ + LOG_GROUP_MAIN_GUESTPROCESSREGISTEREDEVENT, + /** Main group, IGuestProcessStateChangedEvent. */ + LOG_GROUP_MAIN_GUESTPROCESSSTATECHANGEDEVENT, + /** Main group, IGuestPropertyChangedEvent. */ + LOG_GROUP_MAIN_GUESTPROPERTYCHANGEDEVENT, + /** Main group, IGuestSession. */ + LOG_GROUP_MAIN_GUESTSESSION, + /** Main group, IGuestSessionEvent. */ + LOG_GROUP_MAIN_GUESTSESSIONEVENT, + /** Main group, IGuestSessionRegisteredEvent. */ + LOG_GROUP_MAIN_GUESTSESSIONREGISTEREDEVENT, + /** Main group, IGuestSessionStateChangedEvent. */ + LOG_GROUP_MAIN_GUESTSESSIONSTATECHANGEDEVENT, + /** Main group, IGuestUserStateChangedEvent. */ + LOG_GROUP_MAIN_GUESTUSERSTATECHANGEDEVENT, + /** Main group, IHost. */ + LOG_GROUP_MAIN_HOST, + /** Main group, IHostNameResolutionConfigurationChangeEvent. */ + LOG_GROUP_MAIN_HOSTNAMERESOLUTIONCONFIGURATIONCHANGEEVENT, + /** Main group, IHostNetworkInterface. */ + LOG_GROUP_MAIN_HOSTNETWORKINTERFACE, + /** Main group, IHostPCIDevicePlugEvent. */ + LOG_GROUP_MAIN_HOSTPCIDEVICEPLUGEVENT, + /** Main group, IHostUSBDevice. */ + LOG_GROUP_MAIN_HOSTUSBDEVICE, + /** Main group, IHostUSBDeviceFilter. */ + LOG_GROUP_MAIN_HOSTUSBDEVICEFILTER, + /** Main group, IHostVideoInputDevice. */ + LOG_GROUP_MAIN_HOSTVIDEOINPUTDEVICE, + /** Main group, IInternalMachineControl. */ + LOG_GROUP_MAIN_INTERNALMACHINECONTROL, + /** Main group, IInternalSessionControl. */ + LOG_GROUP_MAIN_INTERNALSESSIONCONTROL, + /** Main group, IKeyboard. */ + LOG_GROUP_MAIN_KEYBOARD, + /** Main group, IKeyboardLedsChangedEvent. */ + LOG_GROUP_MAIN_KEYBOARDLEDSCHANGEDEVENT, + /** Main group, IMachine. */ + LOG_GROUP_MAIN_MACHINE, + /** Main group, IMachineDataChangedEvent. */ + LOG_GROUP_MAIN_MACHINEDATACHANGEDEVENT, + /** Main group, IMachineDebugger. */ + LOG_GROUP_MAIN_MACHINEDEBUGGER, + /** Main group, IMachineEvent. */ + LOG_GROUP_MAIN_MACHINEEVENT, + /** Main group, IMachineRegisteredEvent. */ + LOG_GROUP_MAIN_MACHINEREGISTEREDEVENT, + /** Main group, IMachineStateChangedEvent. */ + LOG_GROUP_MAIN_MACHINESTATECHANGEDEVENT, + /** Main group, IMedium. */ + LOG_GROUP_MAIN_MEDIUM, + /** Main group, IMediumAttachment. */ + LOG_GROUP_MAIN_MEDIUMATTACHMENT, + /** Main group, IMediumChangedEvent. */ + LOG_GROUP_MAIN_MEDIUMCHANGEDEVENT, + /** Main group, IMediumFormat. */ + LOG_GROUP_MAIN_MEDIUMFORMAT, + /** Main group, IMediumRegisteredEvent. */ + LOG_GROUP_MAIN_MEDIUMREGISTEREDEVENT, + /** Main group, IMouse. */ + LOG_GROUP_MAIN_MOUSE, + /** Main group, IMouseCapabilityChangedEvent. */ + LOG_GROUP_MAIN_MOUSECAPABILITYCHANGEDEVENT, + /** Main group, IMousePointerShapeChangedEvent. */ + LOG_GROUP_MAIN_MOUSEPOINTERSHAPECHANGEDEVENT, + /** Main group, INATEngine. */ + LOG_GROUP_MAIN_NATENGINE, + /** Main group, INATNetwork. */ + LOG_GROUP_MAIN_NATNETWORK, + /** Main group, INATNetworkAlterEvent. */ + LOG_GROUP_MAIN_NATNETWORKALTEREVENT, + /** Main group, INATNetworkChangedEvent. */ + LOG_GROUP_MAIN_NATNETWORKCHANGEDEVENT, + /** Main group, INATNetworkCreationDeletionEvent. */ + LOG_GROUP_MAIN_NATNETWORKCREATIONDELETIONEVENT, + /** Main group, INATNetworkPortForwardEvent. */ + LOG_GROUP_MAIN_NATNETWORKPORTFORWARDEVENT, + /** Main group, INATNetworkSettingEvent. */ + LOG_GROUP_MAIN_NATNETWORKSETTINGEVENT, + /** Main group, INATNetworkStartStopEvent. */ + LOG_GROUP_MAIN_NATNETWORKSTARTSTOPEVENT, + /** Main group, INATRedirectEvent. */ + LOG_GROUP_MAIN_NATREDIRECTEVENT, + /** Main group, INetworkAdapter. */ + LOG_GROUP_MAIN_NETWORKADAPTER, + /** Main group, INetworkAdapterChangedEvent. */ + LOG_GROUP_MAIN_NETWORKADAPTERCHANGEDEVENT, + /** Main group, IParallelPort. */ + LOG_GROUP_MAIN_PARALLELPORT, + /** Main group, IParallelPortChangedEvent. */ + LOG_GROUP_MAIN_PARALLELPORTCHANGEDEVENT, + /** Main group, IPCIAddress. */ + LOG_GROUP_MAIN_PCIADDRESS, + /** Main group, IPCIDeviceAttachment. */ + LOG_GROUP_MAIN_PCIDEVICEATTACHMENT, + /** Main group, IPerformanceCollector. */ + LOG_GROUP_MAIN_PERFORMANCECOLLECTOR, + /** Main group, IPerformanceMetric. */ + LOG_GROUP_MAIN_PERFORMANCEMETRIC, + /** Main group, IProcess. */ + LOG_GROUP_MAIN_PROCESS, + /** Main group, IProgress. */ + LOG_GROUP_MAIN_PROGRESS, + /** Main group, IReusableEvent. */ + LOG_GROUP_MAIN_REUSABLEEVENT, + /** Main group, IRuntimeErrorEvent. */ + LOG_GROUP_MAIN_RUNTIMEERROREVENT, + /** Main group, ISerialPort. */ + LOG_GROUP_MAIN_SERIALPORT, + /** Main group, ISerialPortChangedEvent. */ + LOG_GROUP_MAIN_SERIALPORTCHANGEDEVENT, + /** Main group, ISession. */ + LOG_GROUP_MAIN_SESSION, + /** Main group, ISessionStateChangedEvent. */ + LOG_GROUP_MAIN_SESSIONSTATECHANGEDEVENT, + /** Main group, ISharedFolder. */ + LOG_GROUP_MAIN_SHAREDFOLDER, + /** Main group, ISharedFolderChangedEvent. */ + LOG_GROUP_MAIN_SHAREDFOLDERCHANGEDEVENT, + /** Main group, IShowWindowEvent. */ + LOG_GROUP_MAIN_SHOWWINDOWEVENT, + /** Main group, ISnapshot. */ + LOG_GROUP_MAIN_SNAPSHOT, + /** Main group, ISnapshotChangedEvent. */ + LOG_GROUP_MAIN_SNAPSHOTCHANGEDEVENT, + /** Main group, ISnapshotDeletedEvent. */ + LOG_GROUP_MAIN_SNAPSHOTDELETEDEVENT, + /** Main group, ISnapshotEvent. */ + LOG_GROUP_MAIN_SNAPSHOTEVENT, + /** Main group, ISnapshotTakenEvent. */ + LOG_GROUP_MAIN_SNAPSHOTTAKENEVENT, + /** Main group, IStateChangedEvent. */ + LOG_GROUP_MAIN_STATECHANGEDEVENT, + /** Main group, IStorageController. */ + LOG_GROUP_MAIN_STORAGECONTROLLER, + /** Main group, IStorageControllerChangedEvent. */ + LOG_GROUP_MAIN_STORAGECONTROLLERCHANGEDEVENT, + /** Main group, IStorageDeviceChangedEvent. */ + LOG_GROUP_MAIN_STORAGEDEVICECHANGEDEVENT, + /** Main group, ISystemProperties. */ + LOG_GROUP_MAIN_SYSTEMPROPERTIES, + /** Main group, IToken. */ + LOG_GROUP_MAIN_TOKEN, + /** Main group, IUSBController. */ + LOG_GROUP_MAIN_USBCONTROLLER, + /** Main group, IUSBControllerChangedEvent. */ + LOG_GROUP_MAIN_USBCONTROLLERCHANGEDEVENT, + /** Main group, IUSBDevice. */ + LOG_GROUP_MAIN_USBDEVICE, + /** Main group, IUSBDeviceFilter. */ + LOG_GROUP_MAIN_USBDEVICEFILTER, + /** Main group, IUSBDeviceFilters. */ + LOG_GROUP_MAIN_USBDEVICEFILTERS, + /** Main group, IUSBDeviceStateChangedEvent. */ + LOG_GROUP_MAIN_USBDEVICESTATECHANGEDEVENT, + /** Main group, IVBoxSVCAvailabilityChangedEvent. */ + LOG_GROUP_MAIN_VBOXSVCAVAILABILITYCHANGEDEVENT, + /** Main group, IVetoEvent. */ + LOG_GROUP_MAIN_VETOEVENT, + /** Main group, IVFSExplorer. */ + LOG_GROUP_MAIN_VFSEXPLORER, + /** Main group, IVideoCaptureChangedEvent. */ + LOG_GROUP_MAIN_VIDEOCAPTURECHANGEDEVENT, + /** Main group, IVirtualBox. */ + LOG_GROUP_MAIN_VIRTUALBOX, + /** Main group, IVirtualBoxClient. */ + LOG_GROUP_MAIN_VIRTUALBOXCLIENT, + /** Main group, IVirtualSystemDescription. */ + LOG_GROUP_MAIN_VIRTUALSYSTEMDESCRIPTION, + /** Main group, IVRDEServer. */ + LOG_GROUP_MAIN_VRDESERVER, + /** Main group, IVRDEServerChangedEvent. */ + LOG_GROUP_MAIN_VRDESERVERCHANGEDEVENT, + /** Main group, IVRDEServerInfo. */ + LOG_GROUP_MAIN_VRDESERVERINFO, + /** Main group, IVRDEServerInfoChangedEvent. */ + LOG_GROUP_MAIN_VRDESERVERINFOCHANGEDEVENT, /** Misc. group intended for external use only. */ LOG_GROUP_MISC, /** MM group. */ @@ -337,10 +685,16 @@ typedef enum LOGGROUP LOG_GROUP_USB_FILTER, /** USB keyboard device group. */ LOG_GROUP_USB_KBD, + /** USB mouse/tablet device group. */ + LOG_GROUP_USB_MOUSE, /** MSD USB device group. */ LOG_GROUP_USB_MSD, /** USB webcam. */ LOG_GROUP_USB_WEBCAM, + /** VBox Guest Additions Driver (VBoxGuest). */ + LOG_GROUP_VBGD, + /** VBox Guest Additions Library. */ + LOG_GROUP_VBGL, /** Generic virtual disk layer. */ LOG_GROUP_VD, /** DMG virtual disk backend. */ @@ -437,7 +791,8 @@ typedef enum LOGGROUP "DEV_VIRTIO_NET", \ "DEV_VMM", \ "DEV_VMM_BACKDOOR", \ - "DEV_VMM_STDERR",\ + "DEV_VMM_STDERR", \ + "DEV_VMSVGA", \ "DIS", \ "DRV", \ "DRV_ACPI", \ @@ -456,12 +811,12 @@ typedef enum LOGGROUP "DRV_KBD_QUEUE", \ "DRV_LWIP", \ "DRV_MINIPORT", \ - "DRV_MOUSE", \ + "DRV_MOUSE", \ "DRV_MOUSE_QUEUE", \ "DRV_NAMEDPIPE", \ "DRV_NAT", \ "DRV_RAW_IMAGE", \ - "DRV_SCSI", \ + "DRV_SCSI", \ "DRV_SCSIHOST", \ "DRV_TRANSPORT_ASYNC", \ "DRV_TUN", \ @@ -479,11 +834,184 @@ typedef enum LOGGROUP "GVMM", \ "HGCM", \ "HGSMI", \ - "HWACCM", \ + "HM", \ "IEM", \ "IOM", \ "IPC", \ + "LWIP", \ + "LWIP_API_LIB", \ + "LWIP_API_MSG", \ + "LWIP_ETHARP", \ + "LWIP_ICMP", \ + "LWIP_IGMP", \ + "LWIP_INET", \ + "LWIP_IP4", \ + "LWIP_IP4_REASS", \ + "LWIP_IP6", \ + "LWIP_MEM", \ + "LWIP_MEMP", \ + "LWIP_NETIF", \ + "LWIP_PBUF", \ + "LWIP_RAW", \ + "LWIP_SOCKETS", \ + "LWIP_SYS", \ + "LWIP_TCP", \ + "LWIP_TCPIP", \ + "LWIP_TCP_CWND", \ + "LWIP_TCP_FR", \ + "LWIP_TCP_INPUT", \ + "LWIP_TCP_OUTPUT", \ + "LWIP_TCP_QLEN", \ + "LWIP_TCP_RST", \ + "LWIP_TCP_RTO", \ + "LWIP_TCP_WND", \ + "LWIP_TIMERS", \ + "LWIP_UDP", \ "MAIN", \ + "MAIN_ADDITIONSFACILITY", \ + "MAIN_ADDITIONSSTATECHANGEDEVENT", \ + "MAIN_APPLIANCE", \ + "MAIN_AUDIOADAPTER", \ + "MAIN_BANDWIDTHCONTROL", \ + "MAIN_BANDWIDTHGROUP", \ + "MAIN_BANDWIDTHGROUPCHANGEDEVENT", \ + "MAIN_BIOSSETTINGS", \ + "MAIN_CANSHOWWINDOWEVENT", \ + "MAIN_CLIPBOARDMODECHANGEDEVENT", \ + "MAIN_CONSOLE", \ + "MAIN_CPUCHANGEDEVENT", \ + "MAIN_CPUEXECUTIONCAPCHANGEDEVENT", \ + "MAIN_DHCPSERVER", \ + "MAIN_DIRECTORY", \ + "MAIN_DISPLAY", \ + "MAIN_DRAGANDDROPMODECHANGEDEVENT", \ + "MAIN_EMULATEDUSB", \ + "MAIN_EVENT", \ + "MAIN_EVENTLISTENER", \ + "MAIN_EVENTSOURCE", \ + "MAIN_EVENTSOURCECHANGEDEVENT", \ + "MAIN_EXTPACK", \ + "MAIN_EXTPACKBASE", \ + "MAIN_EXTPACKFILE", \ + "MAIN_EXTPACKMANAGER", \ + "MAIN_EXTPACKPLUGIN", \ + "MAIN_EXTRADATACANCHANGEEVENT", \ + "MAIN_EXTRADATACHANGEDEVENT", \ + "MAIN_FILE", \ + "MAIN_FRAMEBUFFER", \ + "MAIN_FRAMEBUFFEROVERLAY", \ + "MAIN_FSOBJINFO", \ + "MAIN_GUEST", \ + "MAIN_GUESTDIRECTORY", \ + "MAIN_GUESTERRORINFO", \ + "MAIN_GUESTFILE", \ + "MAIN_GUESTFILEEVENT", \ + "MAIN_GUESTFILEIOEVENT", \ + "MAIN_GUESTFILEOFFSETCHANGEDEVENT", \ + "MAIN_GUESTFILEREADEVENT", \ + "MAIN_GUESTFILEREGISTEREDEVENT", \ + "MAIN_GUESTFILESTATECHANGEDEVENT", \ + "MAIN_GUESTFILEWRITEEVENT", \ + "MAIN_GUESTFSOBJINFO", \ + "MAIN_GUESTKEYBOARDEVENT", \ + "MAIN_GUESTMONITORCHANGEDEVENT", \ + "MAIN_GUESTMOUSEEVENT", \ + "MAIN_GUESTMULTITOUCHEVENT", \ + "MAIN_GUESTOSTYPE", \ + "MAIN_GUESTPROCESS", \ + "MAIN_GUESTPROCESSEVENT", \ + "MAIN_GUESTPROCESSINPUTNOTIFYEVENT", \ + "MAIN_GUESTPROCESSIOEVENT", \ + "MAIN_GUESTPROCESSOUTPUTEVENT", \ + "MAIN_GUESTPROCESSREGISTEREDEVENT", \ + "MAIN_GUESTPROCESSSTATECHANGEDEVENT", \ + "MAIN_GUESTPROPERTYCHANGEDEVENT", \ + "MAIN_GUESTSESSION", \ + "MAIN_GUESTSESSIONEVENT", \ + "MAIN_GUESTSESSIONREGISTEREDEVENT", \ + "MAIN_GUESTSESSIONSTATECHANGEDEVENT", \ + "MAIN_GUESTUSERSTATECHANGEDEVENT", \ + "MAIN_HOST", \ + "MAIN_HOSTNAMERESOLUTIONCONFIGURATIONCHANGEEVENT", \ + "MAIN_HOSTNETWORKINTERFACE", \ + "MAIN_HOSTPCIDEVICEPLUGEVENT", \ + "MAIN_HOSTUSBDEVICE", \ + "MAIN_HOSTUSBDEVICEFILTER", \ + "MAIN_HOSTVIDEOINPUTDEVICE", \ + "MAIN_INTERNALMACHINECONTROL", \ + "MAIN_INTERNALSESSIONCONTROL", \ + "MAIN_KEYBOARD", \ + "MAIN_KEYBOARDLEDSCHANGEDEVENT", \ + "MAIN_MACHINE", \ + "MAIN_MACHINEDATACHANGEDEVENT", \ + "MAIN_MACHINEDEBUGGER", \ + "MAIN_MACHINEEVENT", \ + "MAIN_MACHINEREGISTEREDEVENT", \ + "MAIN_MACHINESTATECHANGEDEVENT", \ + "MAIN_MEDIUM", \ + "MAIN_MEDIUMATTACHMENT", \ + "MAIN_MEDIUMCHANGEDEVENT", \ + "MAIN_MEDIUMFORMAT", \ + "MAIN_MEDIUMREGISTEREDEVENT", \ + "MAIN_MOUSE", \ + "MAIN_MOUSECAPABILITYCHANGEDEVENT", \ + "MAIN_MOUSEPOINTERSHAPECHANGEDEVENT", \ + "MAIN_NATENGINE", \ + "MAIN_NATNETWORK", \ + "MAIN_NATNETWORKALTEREVENT", \ + "MAIN_NATNETWORKCHANGEDEVENT", \ + "MAIN_NATNETWORKCREATIONDELETIONEVENT", \ + "MAIN_NATNETWORKPORTFORWARDEVENT", \ + "MAIN_NATNETWORKSETTINGEVENT", \ + "MAIN_NATNETWORKSTARTSTOPEVENT", \ + "MAIN_NATREDIRECTEVENT", \ + "MAIN_NETWORKADAPTER", \ + "MAIN_NETWORKADAPTERCHANGEDEVENT", \ + "MAIN_PARALLELPORT", \ + "MAIN_PARALLELPORTCHANGEDEVENT", \ + "MAIN_PCIADDRESS", \ + "MAIN_PCIDEVICEATTACHMENT", \ + "MAIN_PERFORMANCECOLLECTOR", \ + "MAIN_PERFORMANCEMETRIC", \ + "MAIN_PROCESS", \ + "MAIN_PROGRESS", \ + "MAIN_REUSABLEEVENT", \ + "MAIN_RUNTIMEERROREVENT", \ + "MAIN_SERIALPORT", \ + "MAIN_SERIALPORTCHANGEDEVENT", \ + "MAIN_SESSION", \ + "MAIN_SESSIONSTATECHANGEDEVENT", \ + "MAIN_SHAREDFOLDER", \ + "MAIN_SHAREDFOLDERCHANGEDEVENT", \ + "MAIN_SHOWWINDOWEVENT", \ + "MAIN_SNAPSHOT", \ + "MAIN_SNAPSHOTCHANGEDEVENT", \ + "MAIN_SNAPSHOTDELETEDEVENT", \ + "MAIN_SNAPSHOTEVENT", \ + "MAIN_SNAPSHOTTAKENEVENT", \ + "MAIN_STATECHANGEDEVENT", \ + "MAIN_STORAGECONTROLLER", \ + "MAIN_STORAGECONTROLLERCHANGEDEVENT", \ + "MAIN_STORAGEDEVICECHANGEDEVENT", \ + "MAIN_SYSTEMPROPERTIES", \ + "MAIN_TOKEN", \ + "MAIN_USBCONTROLLER", \ + "MAIN_USBCONTROLLERCHANGEDEVENT", \ + "MAIN_USBDEVICE", \ + "MAIN_USBDEVICEFILTER", \ + "MAIN_USBDEVICEFILTERS", \ + "MAIN_USBDEVICESTATECHANGEDEVENT", \ + "MAIN_VBOXSVCAVAILABILITYCHANGEDEVENT", \ + "MAIN_VETOEVENT", \ + "MAIN_VFSEXPLORER", \ + "MAIN_VIDEOCAPTURECHANGEDEVENT", \ + "MAIN_VIRTUALBOX", \ + "MAIN_VIRTUALBOXCLIENT", \ + "MAIN_VIRTUALSYSTEMDESCRIPTION", \ + "MAIN_VRDESERVER", \ + "MAIN_VRDESERVERCHANGEDEVENT", \ + "MAIN_VRDESERVERINFO", \ + "MAIN_VRDESERVERINFOCHANGEDEVENT", \ "MISC", \ "MM", \ "MM_HEAP", \ @@ -533,8 +1061,11 @@ typedef enum LOGGROUP "USB_DRV", \ "USB_FILTER", \ "USB_KBD", \ + "USB_MOUSE", \ "USB_MSD", \ "USB_WEBCAM", \ + "VBGD", \ + "VBGL", \ "VD", \ "VD_DMG", \ "VD_ISCSI", \ diff --git a/include/VBox/nasm.mac b/include/VBox/nasm.mac index 416a72f6..a8010a67 100644 --- a/include/VBox/nasm.mac +++ b/include/VBox/nasm.mac @@ -5,7 +5,7 @@ ; ; -; Copyright (C) 2006-2007 Oracle Corporation +; Copyright (C) 2006-2010 Oracle Corporation ; ; This file is part of VirtualBox Open Source Edition (OSE), as ; available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/ostypes.h b/include/VBox/ostypes.h index cbc0b739..890c2be4 100644 --- a/include/VBox/ostypes.h +++ b/include/VBox/ostypes.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2011 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -43,6 +43,7 @@ RT_C_DECLS_BEGIN typedef enum VBOXOSTYPE { VBOXOSTYPE_Unknown = 0, + VBOXOSTYPE_Unknown_x64 = 0x00100, VBOXOSTYPE_DOS = 0x10000, VBOXOSTYPE_Win31 = 0x15000, VBOXOSTYPE_Win9x = 0x20000, @@ -50,6 +51,7 @@ typedef enum VBOXOSTYPE VBOXOSTYPE_Win98 = 0x22000, VBOXOSTYPE_WinMe = 0x23000, VBOXOSTYPE_WinNT = 0x30000, + VBOXOSTYPE_WinNT_x64 = 0x30100, VBOXOSTYPE_WinNT4 = 0x31000, VBOXOSTYPE_Win2k = 0x32000, VBOXOSTYPE_WinXP = 0x33000, @@ -65,6 +67,8 @@ typedef enum VBOXOSTYPE VBOXOSTYPE_Win8 = 0x38000, VBOXOSTYPE_Win8_x64 = 0x38100, VBOXOSTYPE_Win2k12_x64 = 0x39100, + VBOXOSTYPE_Win81 = 0x3A000, + VBOXOSTYPE_Win81_x64 = 0x3A100, VBOXOSTYPE_OS2 = 0x40000, VBOXOSTYPE_OS2Warp3 = 0x41000, VBOXOSTYPE_OS2Warp4 = 0x42000, @@ -115,7 +119,14 @@ typedef enum VBOXOSTYPE VBOXOSTYPE_QNX = 0xA0000, VBOXOSTYPE_MacOS = 0xB0000, VBOXOSTYPE_MacOS_x64 = 0xB0100, + VBOXOSTYPE_MacOS106 = 0xB2000, + VBOXOSTYPE_MacOS106_x64 = 0xB2100, + VBOXOSTYPE_MacOS107_x64 = 0xB3100, + VBOXOSTYPE_MacOS108_x64 = 0xB4100, + VBOXOSTYPE_MacOS109_x64 = 0xB5100, VBOXOSTYPE_JRockitVE = 0xC0000, + VBOXOSTYPE_Haiku = 0xD0000, + VBOXOSTYPE_Haiku_x64 = 0xD0100, /** The bit number which indicates 64-bit or 32-bit. */ #define VBOXOSTYPE_x64_BIT 8 /** The mask which indicates 64-bit. */ diff --git a/include/VBox/param.h b/include/VBox/param.h index 0f94967c..86a5c118 100644 --- a/include/VBox/param.h +++ b/include/VBox/param.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2006-2009 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/pci.h b/include/VBox/pci.h index 526c7298..4c6b5fd6 100644 --- a/include/VBox/pci.h +++ b/include/VBox/pci.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2012 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -87,6 +87,8 @@ typedef enum PCIADDRESSSPACE * * @param enmType One of the PCI_ADDRESS_SPACE_* values. * + * @remarks Called with the PDM lock held. The device lock is NOT take because + * that is very likely be a lock order violation. */ typedef DECLCALLBACK(int) FNPCIIOREGIONMAP(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType); /** Pointer to a FNPCIIOREGIONMAP() function. */ @@ -470,6 +472,9 @@ typedef FNPCIIOREGIONMAP *PFNPCIIOREGIONMAP; * @param pPciDev Pointer to PCI device. Use pPciDev->pDevIns to get the device instance. * @param Address The configuration space register address. [0..4096] * @param cb The register size. [1,2,4] + * + * @remarks Called with the PDM lock held. The device lock is NOT take because + * that is very likely be a lock order violation. */ typedef DECLCALLBACK(uint32_t) FNPCICONFIGREAD(PPCIDEVICE pPciDev, uint32_t Address, unsigned cb); /** Pointer to a FNPCICONFIGREAD() function. */ @@ -485,6 +490,9 @@ typedef PFNPCICONFIGREAD *PPFNPCICONFIGREAD; * @param u32Value The value that's being written. The number of bits actually used from * this value is determined by the cb parameter. * @param cb The register size. [1,2,4] + * + * @remarks Called with the PDM lock held. The device lock is NOT take because + * that is very likely be a lock order violation. */ typedef DECLCALLBACK(void) FNPCICONFIGWRITE(PPCIDEVICE pPciDev, uint32_t Address, uint32_t u32Value, unsigned cb); /** Pointer to a FNPCICONFIGWRITE() function. */ @@ -537,47 +545,48 @@ typedef struct PCIDevice /** @} */ } PCIDEVICE; -/* @todo: handle extended space access */ -DECLINLINE(void) PCIDevSetByte(PPCIDEVICE pPciDev, uint32_t uOffset, uint8_t u8Value) +/** @todo handle extended space access. */ + +DECLINLINE(void) PCIDevSetByte(PPCIDEVICE pPciDev, uint32_t offReg, uint8_t u8Value) { - pPciDev->config[uOffset] = u8Value; + pPciDev->config[offReg] = u8Value; } -DECLINLINE(uint8_t) PCIDevGetByte(PPCIDEVICE pPciDev, uint32_t uOffset) +DECLINLINE(uint8_t) PCIDevGetByte(PPCIDEVICE pPciDev, uint32_t offReg) { - return pPciDev->config[uOffset]; + return pPciDev->config[offReg]; } -DECLINLINE(void) PCIDevSetWord(PPCIDEVICE pPciDev, uint32_t uOffset, uint16_t u16Value) +DECLINLINE(void) PCIDevSetWord(PPCIDEVICE pPciDev, uint32_t offReg, uint16_t u16Value) { - *(uint16_t*)&pPciDev->config[uOffset] = RT_H2LE_U16(u16Value); + *(uint16_t*)&pPciDev->config[offReg] = RT_H2LE_U16(u16Value); } -DECLINLINE(uint16_t) PCIDevGetWord(PPCIDEVICE pPciDev, uint32_t uOffset) +DECLINLINE(uint16_t) PCIDevGetWord(PPCIDEVICE pPciDev, uint32_t offReg) { - uint16_t u16Value = *(uint16_t*)&pPciDev->config[uOffset]; + uint16_t u16Value = *(uint16_t*)&pPciDev->config[offReg]; return RT_H2LE_U16(u16Value); } -DECLINLINE(void) PCIDevSetDWord(PPCIDEVICE pPciDev, uint32_t uOffset, uint32_t u32Value) +DECLINLINE(void) PCIDevSetDWord(PPCIDEVICE pPciDev, uint32_t offReg, uint32_t u32Value) { - *(uint32_t*)&pPciDev->config[uOffset] = RT_H2LE_U32(u32Value); + *(uint32_t*)&pPciDev->config[offReg] = RT_H2LE_U32(u32Value); } -DECLINLINE(uint32_t) PCIDevGetDWord(PPCIDEVICE pPciDev, uint32_t uOffset) +DECLINLINE(uint32_t) PCIDevGetDWord(PPCIDEVICE pPciDev, uint32_t offReg) { - uint32_t u32Value = *(uint32_t*)&pPciDev->config[uOffset]; + uint32_t u32Value = *(uint32_t*)&pPciDev->config[offReg]; return RT_H2LE_U32(u32Value); } -DECLINLINE(void) PCIDevSetQWord(PPCIDEVICE pPciDev, uint32_t uOffset, uint64_t u64Value) +DECLINLINE(void) PCIDevSetQWord(PPCIDEVICE pPciDev, uint32_t offReg, uint64_t u64Value) { - *(uint64_t*)&pPciDev->config[uOffset] = RT_H2LE_U64(u64Value); + *(uint64_t*)&pPciDev->config[offReg] = RT_H2LE_U64(u64Value); } -DECLINLINE(uint64_t) PCIDevGetQWord(PPCIDEVICE pPciDev, uint32_t uOffset) +DECLINLINE(uint64_t) PCIDevGetQWord(PPCIDEVICE pPciDev, uint32_t offReg) { - uint64_t u64Value = *(uint64_t*)&pPciDev->config[uOffset]; + uint64_t u64Value = *(uint64_t*)&pPciDev->config[offReg]; return RT_H2LE_U64(u64Value); } diff --git a/include/VBox/scsi.h b/include/VBox/scsi.h index 20bcd5e1..c0ab641c 100644 --- a/include/VBox/scsi.h +++ b/include/VBox/scsi.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -90,6 +90,7 @@ typedef enum SCSICMD SCSI_SET_READ_AHEAD = 0xa7, SCSI_SET_STREAMING = 0xb6, SCSI_START_STOP_UNIT = 0x1b, + SCSI_LOAD_UNLOAD = 0x1b, SCSI_STOP_PLAY_SCAN = 0x4e, /** Synchronize Cache command. */ SCSI_SYNCHRONIZE_CACHE = 0x35, @@ -110,13 +111,19 @@ typedef enum SCSICMD SCSI_REPORT_DENSITY = 0x44, /** Rezero Unit command. Obsolete for ages now, but used by cdrecord. */ SCSI_REZERO_UNIT = 0x01, + SCSI_REWIND = 0x01, SCSI_SERVICE_ACTION_IN_16 = 0x9e, SCSI_READ_16 = 0x88, SCSI_WRITE_16 = 0x8a, SCSI_READ_6 = 0x08, SCSI_WRITE_6 = 0x0a, SCSI_LOG_SENSE = 0x4d, - SCSI_UNMAP = 0x42 + SCSI_UNMAP = 0x42, + SCSI_RESERVE_6 = 0x16, + SCSI_RELEASE_6 = 0x17, + SCSI_RESERVE_10 = 0x56, + SCSI_RELEASE_10 = 0x57, + SCSI_READ_BLOCK_LIMITS = 0x05 } SCSICMD; /** @@ -176,8 +183,12 @@ typedef enum SCSISVCACTIONIN #define SCSI_SENSE_VOLUME_OVERFLOW 13 #define SCSI_SENSE_MISCOMPARE 14 +/* Additional sense bit flags (to be ORed with sense key). */ +#define SCSI_SENSE_FLAG_FILEMARK 0x80 +#define SCSI_SENSE_FLAG_EOM 0x40 +#define SCSI_SENSE_FLAG_ILI 0x20 -/* additional sense keys */ +/* Additional sense keys */ #define SCSI_ASC_NONE 0x00 #define SCSI_ASC_WRITE_ERROR 0x0c #define SCSI_ASC_READ_ERROR 0x11 @@ -186,6 +197,7 @@ typedef enum SCSISVCACTIONIN #define SCSI_ASC_INV_FIELD_IN_CMD_PACKET 0x24 #define SCSI_ASC_WRITE_PROTECTED 0x27 #define SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED 0x28 +#define SCSI_ASC_POWER_ON_RESET_BUS_DEVICE_RESET_OCCURRED 0x29 #define SCSI_ASC_MEDIUM_NOT_PRESENT 0x3a #define SCSI_ASC_SAVING_PARAMETERS_NOT_SUPPORTED 0x39 #define SCSI_ASC_INVALID_MESSAGE 0x49 @@ -194,7 +206,14 @@ typedef enum SCSISVCACTIONIN #define SCSI_ASC_SYSTEM_RESOURCE_FAILURE 0x55 /** Additional sense code qualifiers (ASCQ). */ +/* NB: The ASC/ASCQ combination determines the full meaning. */ #define SCSI_ASCQ_SYSTEM_BUFFER_FULL 0x01 +#define SCSI_ASCQ_POWER_ON_RESET_BUS_DEVICE_RESET_OCCURRED 0x00 +#define SCSI_ASCQ_END_OF_DATA_DETECTED 0x05 +#define SCSI_ASCQ_FILEMARK_DETECTED 0x01 +#define SCSI_ASCQ_EOP_EOM_DETECTED 0x02 +#define SCSI_ASCQ_SETMARK_DETECTED 0x03 +#define SCSI_ASCQ_BOP_BOM_DETECTED 0x04 /** @name SCSI_INQUIRY * @{ diff --git a/include/VBox/settings.h b/include/VBox/settings.h index 4c69a0e2..eb931d68 100644 --- a/include/VBox/settings.h +++ b/include/VBox/settings.h @@ -17,7 +17,7 @@ */ /* - * Copyright (C) 2007-2012 Oracle Corporation + * Copyright (C) 2007-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -50,6 +50,14 @@ #include <list> #include <map> +/** + * Maximum depth of the snapshot tree, to prevent stack overflows. + * XPCOM has a relatively low stack size for its workers, and we have + * to avoid crashes due to exceeding the limit both on reading and + * writing config files. + */ +#define SETTINGS_SNAPSHOT_DEPTH_MAX 250 + namespace xml { class ElementNode; @@ -154,6 +162,54 @@ struct MediaRegistry }; /** + * + */ +struct NATRule +{ + NATRule() + : proto(NATProtocol_TCP), + u16HostPort(0), + u16GuestPort(0) + {} + + bool operator==(const NATRule &r) const + { + return strName == r.strName + && proto == r.proto + && u16HostPort == r.u16HostPort + && strHostIP == r.strHostIP + && u16GuestPort == r.u16GuestPort + && strGuestIP == r.strGuestIP; + } + + com::Utf8Str strName; + NATProtocol_T proto; + uint16_t u16HostPort; + com::Utf8Str strHostIP; + uint16_t u16GuestPort; + com::Utf8Str strGuestIP; +}; +typedef std::list<NATRule> NATRuleList; + + +struct NATHostLoopbackOffset +{ + /** Note: 128/8 is only acceptable */ + com::Utf8Str strLoopbackHostAddress; + uint32_t u32Offset; + bool operator == (const com::Utf8Str& strAddr) + { + return (strLoopbackHostAddress == strAddr); + } + + bool operator == (uint32_t off) + { + return (this->u32Offset == off); + } +}; +typedef std::list<NATHostLoopbackOffset> NATLoopbackOffsetList; + +/** * Common base class for both MainConfigFile and MachineConfigFile * which contains some common logic for both. */ @@ -186,6 +242,8 @@ protected: typedef enum {Error, HardDisk, DVDImage, FloppyImage} MediaType; void readMedium(MediaType t, const xml::ElementNode &elmMedium, MediaList &llMedia); void readMediaRegistry(const xml::ElementNode &elmMediaRegistry, MediaRegistry &mr); + void readNATForwardRuleList(const xml::ElementNode &elmParent, NATRuleList &llRules); + void readNATLoopbacks(const xml::ElementNode &elmParent, NATLoopbackOffsetList &llLoopBacks); void setVersionAttribute(xml::ElementNode &elm); void createStubDocument(); @@ -200,6 +258,8 @@ protected: uint32_t level); void buildMediaRegistry(xml::ElementNode &elmParent, const MediaRegistry &mr); + void buildNATForwardRuleList(xml::ElementNode &elmParent, const NATRuleList &natRuleList); + void buildNATLoopbacks(xml::ElementNode &elmParent, const NATLoopbackOffsetList &natLoopbackList); void clearDocument(); struct Data; @@ -223,6 +283,11 @@ struct SystemProperties { SystemProperties() : ulLogHistoryCount(3) +#if defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS) + , fExclusiveHwVirt(false) +#else + , fExclusiveHwVirt(true) +#endif {} com::Utf8Str strDefaultMachineFolder; @@ -233,7 +298,10 @@ struct SystemProperties com::Utf8Str strDefaultVRDEExtPack; com::Utf8Str strAutostartDatabasePath; com::Utf8Str strDefaultAdditionsISO; + com::Utf8Str strDefaultFrontend; + com::Utf8Str strLoggingLevel; uint32_t ulLogHistoryCount; + bool fExclusiveHwVirt; }; struct MachineRegistryEntry @@ -243,6 +311,29 @@ struct MachineRegistryEntry }; typedef std::list<MachineRegistryEntry> MachinesRegistry; +typedef std::map<DhcpOpt_T, com::Utf8Str> DhcpOptionMap; +typedef DhcpOptionMap::value_type DhcpOptValuePair; +typedef DhcpOptionMap::iterator DhcpOptIterator; +typedef DhcpOptionMap::const_iterator DhcpOptConstIterator; + +typedef struct VmNameSlotKey +{ + VmNameSlotKey(const com::Utf8Str& aVmName, LONG aSlot): VmName(aVmName), + Slot(aSlot){} + const com::Utf8Str VmName; + LONG Slot; + bool operator< (const VmNameSlotKey& that) const + { + if (VmName == that.VmName) + return Slot < that.Slot; + else return VmName < that.VmName; + } +} VmNameSlotKey; +typedef std::map<VmNameSlotKey, DhcpOptionMap> VmSlot2OptionsMap; +typedef VmSlot2OptionsMap::value_type VmSlot2OptionsPair; +typedef VmSlot2OptionsMap::iterator VmSlot2OptionsIterator; +typedef VmSlot2OptionsMap::const_iterator VmSlot2OptionsConstIterator; + struct DHCPServer { DHCPServer() @@ -251,13 +342,45 @@ struct DHCPServer com::Utf8Str strNetworkName, strIPAddress, - strIPNetworkMask, strIPLower, strIPUpper; bool fEnabled; + std::map<DhcpOpt_T, com::Utf8Str> GlobalDhcpOptions; + VmSlot2OptionsMap VmSlot2OptionsM; }; typedef std::list<DHCPServer> DHCPServersList; + +/** + * Nat Networking settings (NAT service). + */ +struct NATNetwork +{ + com::Utf8Str strNetworkName; + bool fEnabled; + com::Utf8Str strNetwork; + bool fIPv6; + com::Utf8Str strIPv6Prefix; + uint32_t u32HostLoopback6Offset; + NATLoopbackOffsetList llHostLoopbackOffsetList; + bool fAdvertiseDefaultIPv6Route; + bool fNeedDhcpServer; + NATRuleList llPortForwardRules4; + NATRuleList llPortForwardRules6; + NATNetwork():fEnabled(true), + fAdvertiseDefaultIPv6Route(false), + fNeedDhcpServer(true) + {} + bool operator==(const NATNetwork &n) const + { + return strNetworkName == n.strNetworkName + && strNetwork == n.strNetwork; + } + +}; +typedef std::list<NATNetwork> NATNetworksList; + + class MainConfigFile : public ConfigFileBase { public: @@ -265,6 +388,8 @@ public: void readMachineRegistry(const xml::ElementNode &elmMachineRegistry); void readDHCPServers(const xml::ElementNode &elmDHCPServers); + void readDhcpOptions(DhcpOptionMap& map, const xml::ElementNode& options); + void readNATNetworks(const xml::ElementNode &elmNATNetworks); void write(const com::Utf8Str strFilename); @@ -273,7 +398,11 @@ public: MediaRegistry mediaRegistry; MachinesRegistry llMachines; DHCPServersList llDhcpServers; + NATNetworksList llNATNetworks; StringsMap mapExtraDataItems; + +private: + void bumpSettingsVersionIfNeeded(); }; //////////////////////////////////////////////////////////////////////////////// @@ -348,43 +477,27 @@ struct BIOSSettings struct USBController { USBController() - : fEnabled(false), - fEnabledEHCI(false) + : enmType(USBControllerType_Null) {} bool operator==(const USBController &u) const; - bool fEnabled; - bool fEnabledEHCI; - USBDeviceFiltersList llDeviceFilters; + com::Utf8Str strName; + USBControllerType_T enmType; }; +typedef std::list<USBController> USBControllerList; - struct NATRule - { - NATRule() - : proto(NATProtocol_TCP), - u16HostPort(0), - u16GuestPort(0) - {} +struct USB +{ + USB() {} - bool operator==(const NATRule &r) const - { - return strName == r.strName - && proto == r.proto - && u16HostPort == r.u16HostPort - && strHostIP == r.strHostIP - && u16GuestPort == r.u16GuestPort - && strGuestIP == r.strGuestIP; - } + bool operator==(const USB &u) const; - com::Utf8Str strName; - NATProtocol_T proto; - uint16_t u16HostPort; - com::Utf8Str strHostIP; - uint16_t u16GuestPort; - com::Utf8Str strGuestIP; - }; - typedef std::list<NATRule> NATRuleList; + /** List of USB controllers present. */ + USBControllerList llUSBControllers; + /** List of USB device filters. */ + USBDeviceFiltersList llDeviceFilters; +}; struct NAT { @@ -441,6 +554,7 @@ struct USBController bool fAliasUseSamePorts; NATRuleList llRules; }; + /** * NOTE: If you add any fields in here, you must update a) the constructor and b) * the operator== which is used by MachineConfigFile::operator==(), or otherwise @@ -480,6 +594,7 @@ struct NetworkAdapter com::Utf8Str strInternalNetworkName; com::Utf8Str strGenericDriver; StringsMap genericProperties; + com::Utf8Str strNATNetworkName; uint32_t ulBootPriority; com::Utf8Str strBandwidthGroup; // requires settings version 1.13 (VirtualBox 4.2) }; @@ -754,13 +869,16 @@ struct Hardware com::Guid uuid; // hardware uuid, optional (null). bool fHardwareVirt, - fHardwareVirtExclusive, fNestedPaging, fLargePages, fVPID, + fUnrestrictedExecution, fHardwareVirtForce, fSyntheticCpu, + fTripleFaultReset, fPAE; + typedef enum LongModeType { LongMode_Enabled, LongMode_Disabled, LongMode_Legacy } LongModeType; + LongModeType enmLongMode; uint32_t cCPUs; bool fCpuHotPlug; // requires settings version 1.10 (VirtualBox 3.2) CpuList llCpus; // requires settings version 1.10 (VirtualBox 3.2) @@ -773,14 +891,20 @@ struct Hardware BootOrderMap mapBootOrder; // item 0 has highest priority + GraphicsControllerType_T graphicsControllerType; uint32_t ulVRAMSizeMB; uint32_t cMonitors; bool fAccelerate3D, fAccelerate2DVideo; // requires settings version 1.8 (VirtualBox 3.1) - uint32_t ulVideoCaptureHorzRes; - uint32_t ulVideoCaptureVertRes; - bool fVideoCaptureEnabled; - com::Utf8Str strVideoCaptureFile; + + uint32_t ulVideoCaptureHorzRes; // requires settings version 1.14 (VirtualBox 4.3) + uint32_t ulVideoCaptureVertRes; // requires settings version 1.14 (VirtualBox 4.3) + uint32_t ulVideoCaptureRate; // requires settings version 1.14 (VirtualBox 4.3) + uint32_t ulVideoCaptureFPS; // requires settings version 1.14 (VirtualBox 4.3) + bool fVideoCaptureEnabled; // requires settings version 1.14 (VirtualBox 4.3) + uint64_t u64VideoCaptureScreens; // requires settings version 1.14 (VirtualBox 4.3) + com::Utf8Str strVideoCaptureFile; // requires settings version 1.14 (VirtualBox 4.3) + FirmwareType_T firmwareType; // requires settings version 1.9 (VirtualBox 3.1) PointingHIDType_T pointingHIDType; // requires settings version 1.10 (VirtualBox 3.2) @@ -793,7 +917,7 @@ struct Hardware VRDESettings vrdeSettings; BIOSSettings biosSettings; - USBController usbController; + USB usbSettings; NetworkAdaptersList llNetworkAdapters; SerialPortsList llSerialPorts; ParallelPortsList llParallelPorts; @@ -813,6 +937,8 @@ struct Hardware IOSettings ioSettings; // requires settings version 1.10 (VirtualBox 3.2) HostPCIDeviceAttachmentList pciAttachments; // requires settings version 1.12 (VirtualBox 4.1) + + com::Utf8Str strDefaultFrontend; // requires settings version 1.14 (VirtualBox 4.3) }; /** @@ -853,6 +979,9 @@ struct AttachedDevice // Whether the medium supports discarding unused blocks: bool fDiscard; + // Whether the medium is hot-pluggable: + bool fHotPluggable; + int32_t lPort; int32_t lDevice; @@ -1045,7 +1174,8 @@ struct MachineUserData && (uFaultToleranceInterval == c.uFaultToleranceInterval) && (strFaultToleranceAddress == c.strFaultToleranceAddress) && (strFaultTolerancePassword == c.strFaultTolerancePassword) - && (fRTCUseUTC == c.fRTCUseUTC); + && (fRTCUseUTC == c.fRTCUseUTC) + && (ovIcon == c.ovIcon); } com::Utf8Str strName; @@ -1065,6 +1195,7 @@ struct MachineUserData com::Utf8Str strFaultTolerancePassword; uint32_t uFaultToleranceInterval; bool fRTCUseUTC; + com::Utf8Str ovIcon; }; /** @@ -1112,7 +1243,7 @@ public: enum { BuildMachineXML_IncludeSnapshots = 0x01, - BuildMachineXML_WriteVboxVersionAttribute = 0x02, + BuildMachineXML_WriteVBoxVersionAttribute = 0x02, BuildMachineXML_SkipRemovableMedia = 0x04, BuildMachineXML_MediaRegistry = 0x08, BuildMachineXML_SuppressSavedState = 0x10 @@ -1142,7 +1273,7 @@ private: void readDebugging(const xml::ElementNode *pElmDbg, Debugging *pDbg); void readAutostart(const xml::ElementNode *pElmAutostart, Autostart *pAutostart); void readGroups(const xml::ElementNode *elmGroups, StringsList *pllGroups); - void readSnapshot(const xml::ElementNode &elmSnapshot, Snapshot &snap); + bool readSnapshot(const com::Guid &curSnapshotUuid, uint32_t depth, const xml::ElementNode &elmSnapshot, Snapshot &snap); void convertOldOSType_pre1_5(com::Utf8Str &str); void readMachine(const xml::ElementNode &elmMachine); @@ -1155,7 +1286,7 @@ private: void buildDebuggingXML(xml::ElementNode *pElmParent, const Debugging *pDbg); void buildAutostartXML(xml::ElementNode *pElmParent, const Autostart *pAutostart); void buildGroupsXML(xml::ElementNode *pElmParent, const StringsList *pllGroups); - void buildSnapshotXML(xml::ElementNode &elmParent, const Snapshot &snap); + void buildSnapshotXML(uint32_t depth, xml::ElementNode &elmParent, const Snapshot &snap); void bumpSettingsVersionIfNeeded(); }; diff --git a/include/VBox/shflsvc.h b/include/VBox/shflsvc.h index 923e25a7..8d2d7344 100644 --- a/include/VBox/shflsvc.h +++ b/include/VBox/shflsvc.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -219,6 +219,12 @@ DECLINLINE(bool) ShflStringIsValid(PCSHFLSTRING pString, uint32_t cbBuf) return false; if (RT_UNLIKELY(pString->u16Length >= pString->u16Size)) return false; + /** @todo r=bird: Check that u16Length is a multiple of two if UTF-16 input? */ + /** @todo r=bird: Do we require the string to have a NUL terminator char, if + * so check for it!! (Just had a problem with too small (/2) u16Length + * and code behaving incorrectly because it worked up to the terminator + * instead of the length.) */ + /** @todo r=bird: Who checks for valid UTF-8 encoding of strings? */ return true; } @@ -1338,9 +1344,14 @@ typedef struct _VBoxSFSymlink * Host call, no guest structure is used. */ +/** mapping is writable */ #define SHFL_ADD_MAPPING_F_WRITABLE (RT_BIT_32(0)) +/** mapping is automounted by the guest */ #define SHFL_ADD_MAPPING_F_AUTOMOUNT (RT_BIT_32(1)) +/** allow the guest to create symlinks */ #define SHFL_ADD_MAPPING_F_CREATE_SYMLINKS (RT_BIT_32(2)) +/** mapping is actually missing on the host */ +#define SHFL_ADD_MAPPING_F_MISSING (RT_BIT_32(3)) #define SHFL_CPARMS_ADD_MAPPING (3) diff --git a/include/VBox/sup.h b/include/VBox/sup.h index 5913ff9c..7f94ccab 100644 --- a/include/VBox/sup.h +++ b/include/VBox/sup.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -423,8 +423,8 @@ typedef SUPVMMR0REQHDR *PSUPVMMR0REQHDR; */ /** @see VMMR0_DO_RAW_RUN. */ #define SUP_VMMR0_DO_RAW_RUN 0 -/** @see VMMR0_DO_HWACC_RUN. */ -#define SUP_VMMR0_DO_HWACC_RUN 1 +/** @see VMMR0_DO_HM_RUN. */ +#define SUP_VMMR0_DO_HM_RUN 1 /** @see VMMR0_DO_NOP */ #define SUP_VMMR0_DO_NOP 2 /** @} */ @@ -745,7 +745,8 @@ DECLHIDDEN(int) SUPR3HardenedMain(const char *pszProgName, uint32_t fFlags, int /** * Initializes the support library. - * Each successful call to SUPR3Init() must be countered by a + * + * Each successful call to SUPR3Init() or SUPR3InitEx must be countered by a * call to SUPR3Term(false). * * @returns VBox status code. @@ -753,6 +754,19 @@ DECLHIDDEN(int) SUPR3HardenedMain(const char *pszProgName, uint32_t fFlags, int */ SUPR3DECL(int) SUPR3Init(PSUPDRVSESSION *ppSession); + +/** + * Initializes the support library, extended version. + * + * Each successful call to SUPR3Init() or SUPR3InitEx must be countered by a + * call to SUPR3Term(false). + * + * @returns VBox status code. + * @param fUnrestricted The desired access. + * @param ppSession Where to store the session handle. Defaults to NULL. + */ +SUPR3DECL(int) SUPR3InitEx(bool fUnrestricted, PSUPDRVSESSION *ppSession); + /** * Terminates the support library. * @@ -1280,6 +1294,13 @@ SUPR3DECL(int) SUPR3TracerDeregisterModule(struct VTGOBJHDR *pVtgHdr); */ SUPDECL(void) SUPTracerFireProbe(struct VTGPROBELOC *pVtgProbeLoc, uintptr_t uArg0, uintptr_t uArg1, uintptr_t uArg2, uintptr_t uArg3, uintptr_t uArg4); +/** + * Resume built-in keyboard on MacBook Air and Pro hosts. + * + * @returns VBox status code. + */ +SUPR3DECL(int) SUPR3ResumeSuspendedKeyboards(void); + /** @} */ #endif /* IN_RING3 */ @@ -1362,6 +1383,8 @@ SUPR0DECL(int) SUPR0GipUnmap(PSUPDRVSESSION pSession); SUPR0DECL(int) SUPR0Printf(const char *pszFormat, ...); SUPR0DECL(SUPPAGINGMODE) SUPR0GetPagingMode(void); SUPR0DECL(int) SUPR0EnableVTx(bool fEnable); +SUPR0DECL(bool) SUPR0SuspendVTxOnCpu(void); +SUPR0DECL(void) SUPR0ResumeVTxOnCpu(bool fSuspended); /** @name Absolute symbols * Take the address of these, don't try call them. diff --git a/include/VBox/types.h b/include/VBox/types.h index 9abf5b6b..4caa5821 100644 --- a/include/VBox/types.h +++ b/include/VBox/types.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -348,6 +348,11 @@ typedef union PDMCRITSECT *PPDMCRITSECT; /** Pointer to a const PDM critical section. */ typedef const union PDMCRITSECT *PCPDMCRITSECT; +/** Pointer to a PDM read/write critical section. */ +typedef union PDMCRITSECTRW *PPDMCRITSECTRW; +/** Pointer to a const PDM read/write critical section. */ +typedef union PDMCRITSECTRW const *PCPDMCRITSECTRW; + /** R3 pointer to a timer. */ typedef R3PTRTYPE(struct TMTIMER *) PTMTIMERR3; /** Pointer to a R3 pointer to a timer. */ diff --git a/include/VBox/usb.h b/include/VBox/usb.h index db648c7a..4ab531a0 100644 --- a/include/VBox/usb.h +++ b/include/VBox/usb.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/usbfilter.h b/include/VBox/usbfilter.h index 1ed209fd..45c3151c 100644 --- a/include/VBox/usbfilter.h +++ b/include/VBox/usbfilter.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2007 Oracle Corporation + * Copyright (C) 2007-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/usblib-darwin.h b/include/VBox/usblib-darwin.h index db43e743..d46a9e28 100644 --- a/include/VBox/usblib-darwin.h +++ b/include/VBox/usblib-darwin.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2007 Oracle Corporation + * Copyright (C) 2007-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/usblib-solaris.h b/include/VBox/usblib-solaris.h index f8c4b4c2..053c326a 100644 --- a/include/VBox/usblib-solaris.h +++ b/include/VBox/usblib-solaris.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2008 Oracle Corporation + * Copyright (C) 2008-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -126,6 +126,7 @@ typedef struct VUSBXFERTYPE enmType; /* Xfer type */ VUSBDIRECTION enmDir; /* Xfer direction */ VUSBSTATUS enmStatus; /* URB status */ + bool fShortOk; /* Whether receiving less data than requested is acceptable. */ size_t cbData; /* Size of the data */ void *pvData; /* Pointer to the data */ uint32_t cIsocPkts; /* Number of Isoc packets */ @@ -153,8 +154,11 @@ typedef struct typedef enum { - VBOXUSB_RESET_LEVEL_NONE = 0, + /** Close device not a reset. */ + VBOXUSB_RESET_LEVEL_CLOSE = 0, + /** Hard reset resulting in device replug behaviour. */ VBOXUSB_RESET_LEVEL_REATTACH = 2, + /** Device-level reset. */ VBOXUSB_RESET_LEVEL_SOFT = 4 } VBOXUSB_RESET_LEVEL; diff --git a/include/VBox/usblib-win.h b/include/VBox/usblib-win.h index ed8885bb..193bde75 100644 --- a/include/VBox/usblib-win.h +++ b/include/VBox/usblib-win.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/usblib.h b/include/VBox/usblib.h index 21d46419..5d00af68 100644 --- a/include/VBox/usblib.h +++ b/include/VBox/usblib.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/various.sed b/include/VBox/various.sed index fb3507f1..3cbb69a7 100644 --- a/include/VBox/various.sed +++ b/include/VBox/various.sed @@ -3,6 +3,13 @@ /ASM-INC/basm-inc /ASM-NOINC/basm-noinc +# Newline escapes. +:check-newline-escape +/\\$/!bno-more-newline-escapes +N +b check-newline-escape +:no-more-newline-escapes + # Strip comments and trailing space. s/[[:space:]][[:space:]]*\/\*.*$//g s/[[:space:]][[:space:]]*\/\/.*$//g diff --git a/include/VBox/vd-cache-plugin.h b/include/VBox/vd-cache-plugin.h index af185680..c8a37535 100644 --- a/include/VBox/vd-cache-plugin.h +++ b/include/VBox/vd-cache-plugin.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -131,43 +131,63 @@ typedef struct VDCACHEBACKEND DECLR3CALLBACKMEMBER(int, pfnClose, (void *pBackendData, bool fDelete)); /** - * Read data from a cache image. The area read never crosses a block - * boundary. + * Start a read request. * * @returns VBox status code. - * @returns VERR_VD_BLOCK_FREE if this image contains no data for this block. * @param pBackendData Opaque state data for this image. - * @param uOffset Offset to start reading from. - * @param pvBuf Where to store the read bits. - * @param cbRead Number of bytes to read. + * @param uOffset The offset of the virtual disk to read from. + * @param cbRead How many bytes to read. + * @param pIoCtx I/O context associated with this request. * @param pcbActuallyRead Pointer to returned number of bytes read. */ - DECLR3CALLBACKMEMBER(int, pfnRead, (void *pBackendData, uint64_t uOffset, void *pvBuf, - size_t cbRead, size_t *pcbActuallyRead)); + DECLR3CALLBACKMEMBER(int, pfnRead, (void *pBackendData, uint64_t uOffset, size_t cbRead, + PVDIOCTX pIoCtx, size_t *pcbActuallyRead)); /** - * Write data to a cache image. The area written never crosses a block - * boundary. + * Start a write request. * * @returns VBox status code. * @param pBackendData Opaque state data for this image. - * @param uOffset Offset to start writing to. - * @param pvBuf Where to retrieve the written bits. - * @param cbWrite Number of bytes to write. + * @param uOffset The offset of the virtual disk to write to. + * @param cbWrite How many bytes to write. + * @param pIoCtx I/O context associated with this request. * @param pcbWriteProcess Pointer to returned number of bytes that could - * be processed. + * be processed. In case the function returned + * VERR_VD_BLOCK_FREE this is the number of bytes + * that could be written in a full block write, + * when prefixed/postfixed by the appropriate + * amount of (previously read) padding data. */ - DECLR3CALLBACKMEMBER(int, pfnWrite, (void *pBackendData, uint64_t uOffset, - const void *pvBuf, size_t cbWrite, - size_t *pcbWriteProcess)); + DECLR3CALLBACKMEMBER(int, pfnWrite, (void *pBackendData, uint64_t uOffset, size_t cbWrite, + PVDIOCTX pIoCtx, size_t *pcbWriteProcess)); /** * Flush data to disk. * * @returns VBox status code. * @param pBackendData Opaque state data for this image. + * @param pIoCtx I/O context associated with this request. */ - DECLR3CALLBACKMEMBER(int, pfnFlush, (void *pBackendData)); + DECLR3CALLBACKMEMBER(int, pfnFlush, (void *pBackendData, PVDIOCTX pIoCtx)); + + /** + * Discards the given amount of bytes from the cache. + * + * @returns VBox status code. + * @retval VERR_VD_DISCARD_ALIGNMENT_NOT_MET if the range doesn't meet the required alignment + * for the discard. + * @param pBackendData Opaque state data for this image. + * @param pIoCtx I/O context associated with this request. + * @param uOffset The offset of the first byte to discard. + * @param cbDiscard How many bytes to discard. + */ + DECLR3CALLBACKMEMBER(int, pfnDiscard, (void *pBackendData, PVDIOCTX pIoCtx, + uint64_t uOffset, size_t cbDiscard, + size_t *pcbPreAllocated, + size_t *pcbPostAllocated, + size_t *pcbActuallyDiscarded, + void **ppbmAllocationBitmap, + unsigned fDiscard)); /** * Get the version of a cache image. @@ -283,46 +303,6 @@ typedef struct VDCACHEBACKEND */ DECLR3CALLBACKMEMBER(void, pfnDump, (void *pBackendData)); - /** - * Start an asynchronous read request. - * - * @returns VBox status code. - * @param pBackendData Opaque state data for this image. - * @param uOffset The offset of the virtual disk to read from. - * @param cbRead How many bytes to read. - * @param pIoCtx I/O context associated with this request. - * @param pcbActuallyRead Pointer to returned number of bytes read. - */ - DECLR3CALLBACKMEMBER(int, pfnAsyncRead, (void *pBackendData, uint64_t uOffset, size_t cbRead, - PVDIOCTX pIoCtx, size_t *pcbActuallyRead)); - - /** - * Start an asynchronous write request. - * - * @returns VBox status code. - * @param pBackendData Opaque state data for this image. - * @param uOffset The offset of the virtual disk to write to. - * @param cbWrite How many bytes to write. - * @param pIoCtx I/O context associated with this request. - * @param pcbWriteProcess Pointer to returned number of bytes that could - * be processed. In case the function returned - * VERR_VD_BLOCK_FREE this is the number of bytes - * that could be written in a full block write, - * when prefixed/postfixed by the appropriate - * amount of (previously read) padding data. - */ - DECLR3CALLBACKMEMBER(int, pfnAsyncWrite, (void *pBackendData, uint64_t uOffset, size_t cbWrite, - PVDIOCTX pIoCtx, size_t *pcbWriteProcess)); - - /** - * Flush data to disk. - * - * @returns VBox status code. - * @param pBackendData Opaque state data for this image. - * @param pIoCtx I/O context associated with this request. - */ - DECLR3CALLBACKMEMBER(int, pfnAsyncFlush, (void *pBackendData, PVDIOCTX pIoCtx)); - /** Returns a human readable hard disk location string given a * set of hard disk configuration keys. The returned string is an * equivalent of the full file path for image-based hard disks. diff --git a/include/VBox/vd-ifs-internal.h b/include/VBox/vd-ifs-internal.h index 5b5ae5ad..41c551f2 100644 --- a/include/VBox/vd-ifs-internal.h +++ b/include/VBox/vd-ifs-internal.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -209,84 +209,39 @@ typedef struct VDINTERFACEIOINT uint64_t cbSize)); /** - * Synchronous write callback. - * - * @return VBox status code. - * @param pvUser The opaque data passed on container creation. - * @param pStorage The storage handle to use. - * @param uOffset The offset to start from. - * @param pvBuffer Pointer to the bits need to be written. - * @param cbBuffer How many bytes to write. - * @param pcbWritten Where to store how many bytes were actually written. - * - * @notes Do not use in code called from the async read/write entry points in the backends. - * This should be only used during open/close of images and for the support functions - * which are not called while a VM is running (pfnCompact). - */ - DECLR3CALLBACKMEMBER(int, pfnWriteSync, (void *pvUser, PVDIOSTORAGE pStorage, uint64_t uOffset, - const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten)); - - /** - * Synchronous read callback. - * - * @return VBox status code. - * @param pvUser The opaque data passed on container creation. - * @param pStorage The storage handle to use. - * @param uOffset The offset to start from. - * @param pvBuffer Where to store the read bits. - * @param cbBuffer How many bytes to read. - * @param pcbRead Where to store how many bytes were actually read. - * - * @notes See pfnWriteSync() - */ - DECLR3CALLBACKMEMBER(int, pfnReadSync, (void *pvUser, PVDIOSTORAGE pStorage, uint64_t uOffset, - void *pvBuffer, size_t cbBuffer, size_t *pcbRead)); - - /** - * Flush data to the storage backend. - * - * @return VBox status code. - * @param pvUser The opaque data passed on container creation. - * @param pStorage The storage handle to flush. - * - * @notes See pfnWriteSync() - */ - DECLR3CALLBACKMEMBER(int, pfnFlushSync, (void *pvUser, PVDIOSTORAGE pStorage)); - - /** - * Initiate an asynchronous read request for user data. + * Initiate a read request for user data. * * @return VBox status code. * @param pvUser The opaque user data passed on container creation. * @param pStorage The storage handle. * @param uOffset The offset to start reading from. - * @param pIoCtx I/O context passed in VDAsyncRead/Write. + * @param pIoCtx I/O context passed in the read/write callback. * @param cbRead How many bytes to read. */ - DECLR3CALLBACKMEMBER(int, pfnReadUserAsync, (void *pvUser, PVDIOSTORAGE pStorage, - uint64_t uOffset, PVDIOCTX pIoCtx, - size_t cbRead)); + DECLR3CALLBACKMEMBER(int, pfnReadUser, (void *pvUser, PVDIOSTORAGE pStorage, + uint64_t uOffset, PVDIOCTX pIoCtx, + size_t cbRead)); /** - * Initiate an asynchronous write request for user data. + * Initiate a write request for user data. * * @return VBox status code. * @param pvUser The opaque user data passed on container creation. * @param pStorage The storage handle. * @param uOffset The offset to start writing to. - * @param pIoCtx I/O context passed in VDAsyncRead/Write + * @param pIoCtx I/O context passed in the read/write callback. * @param cbWrite How many bytes to write. * @param pfnCompleted Completion callback. * @param pvCompleteUser Opaque user data passed in the completion callback. */ - DECLR3CALLBACKMEMBER(int, pfnWriteUserAsync, (void *pvUser, PVDIOSTORAGE pStorage, - uint64_t uOffset, PVDIOCTX pIoCtx, - size_t cbWrite, - PFNVDXFERCOMPLETED pfnComplete, - void *pvCompleteUser)); + DECLR3CALLBACKMEMBER(int, pfnWriteUser, (void *pvUser, PVDIOSTORAGE pStorage, + uint64_t uOffset, PVDIOCTX pIoCtx, + size_t cbWrite, + PFNVDXFERCOMPLETED pfnComplete, + void *pvCompleteUser)); /** - * Reads metadata asynchronously from storage. + * Reads metadata from storage. * The current I/O context will be halted. * * @returns VBox status code. @@ -299,16 +254,23 @@ typedef struct VDINTERFACEIOINT * @param ppMetaXfer Where to store the metadata transfer handle on success. * @param pfnCompleted Completion callback. * @param pvCompleteUser Opaque user data passed in the completion callback. + * + * @notes If pIoCtx is NULL the metadata read is handled synchronously + * i.e. the call returns only if the data is available in the given + * buffer. ppMetaXfer, pfnCompleted and pvCompleteUser are ignored in that case. + * Use the synchronous version only when opening/closing the image + * or when doing certain operations like resizing, compacting or repairing + * the disk. */ - DECLR3CALLBACKMEMBER(int, pfnReadMetaAsync, (void *pvUser, PVDIOSTORAGE pStorage, - uint64_t uOffset, void *pvBuffer, - size_t cbBuffer, PVDIOCTX pIoCtx, - PPVDMETAXFER ppMetaXfer, - PFNVDXFERCOMPLETED pfnComplete, - void *pvCompleteUser)); + DECLR3CALLBACKMEMBER(int, pfnReadMeta, (void *pvUser, PVDIOSTORAGE pStorage, + uint64_t uOffset, void *pvBuffer, + size_t cbBuffer, PVDIOCTX pIoCtx, + PPVDMETAXFER ppMetaXfer, + PFNVDXFERCOMPLETED pfnComplete, + void *pvCompleteUser)); /** - * Writes metadata asynchronously to storage. + * Writes metadata to storage. * * @returns VBox status code. * @param pvUser The opaque user data passed on container creation. @@ -319,12 +281,14 @@ typedef struct VDINTERFACEIOINT * @param pIoCtx The I/O context which triggered the write. * @param pfnCompleted Completion callback. * @param pvCompleteUser Opaque user data passed in the completion callback. + * + * @notes See pfnReadMeta(). */ - DECLR3CALLBACKMEMBER(int, pfnWriteMetaAsync, (void *pvUser, PVDIOSTORAGE pStorage, - uint64_t uOffset, void *pvBuffer, - size_t cbBuffer, PVDIOCTX pIoCtx, - PFNVDXFERCOMPLETED pfnComplete, - void *pvCompleteUser)); + DECLR3CALLBACKMEMBER(int, pfnWriteMeta, (void *pvUser, PVDIOSTORAGE pStorage, + uint64_t uOffset, const void *pvBuffer, + size_t cbBuffer, PVDIOCTX pIoCtx, + PFNVDXFERCOMPLETED pfnComplete, + void *pvCompleteUser)); /** * Releases a metadata transfer handle. @@ -337,7 +301,7 @@ typedef struct VDINTERFACEIOINT DECLR3CALLBACKMEMBER(void, pfnMetaXferRelease, (void *pvUser, PVDMETAXFER pMetaXfer)); /** - * Initiates an async flush request. + * Initiates a flush request. * * @return VBox status code. * @param pvUser The opaque data passed on container creation. @@ -345,11 +309,13 @@ typedef struct VDINTERFACEIOINT * @param pIoCtx I/O context which triggered the flush. * @param pfnCompleted Completion callback. * @param pvCompleteUser Opaque user data passed in the completion callback. + * + * @notes See pfnReadMeta(). */ - DECLR3CALLBACKMEMBER(int, pfnFlushAsync, (void *pvUser, PVDIOSTORAGE pStorage, - PVDIOCTX pIoCtx, - PFNVDXFERCOMPLETED pfnComplete, - void *pvCompleteUser)); + DECLR3CALLBACKMEMBER(int, pfnFlush, (void *pvUser, PVDIOSTORAGE pStorage, + PVDIOCTX pIoCtx, + PFNVDXFERCOMPLETED pfnComplete, + void *pvCompleteUser)); /** * Copies a buffer into the I/O context. @@ -361,7 +327,7 @@ typedef struct VDINTERFACEIOINT * @param cbBuffer Number of bytes to copy. */ DECLR3CALLBACKMEMBER(size_t, pfnIoCtxCopyTo, (void *pvUser, PVDIOCTX pIoCtx, - void *pvBuffer, size_t cbBuffer)); + const void *pvBuffer, size_t cbBuffer)); /** * Copies data from the I/O context into a buffer. @@ -414,6 +380,32 @@ typedef struct VDINTERFACEIOINT */ DECLR3CALLBACKMEMBER(void, pfnIoCtxCompleted, (void *pvUser, PVDIOCTX pIoCtx, int rcReq, size_t cbCompleted)); + + /** + * Returns whether the given I/O context must be treated synchronously. + * + * @returns true if the I/O context must be processed synchronously + * false otherwise. + * @param pvUser The opaque user data passed on container creation. + * @param pIoCtx The I/O context. + */ + DECLR3CALLBACKMEMBER(bool, pfnIoCtxIsSynchronous, (void *pvUser, PVDIOCTX pIoCtx)); + + /** + * Returns whether the user buffer of the I/O context is complete zero + * from to current position upto the given number of bytes. + * + * @returns true if the I/O context user buffer consists solely of zeros + * false otherwise. + * @param pvUser The opaque user data passed on container creation. + * @param pIoCtx The I/O context. + * @param cbCheck Number of bytes to check for zeros. + * @param fAdvance Flag whether to advance the buffer pointer if true + * is returned. + */ + DECLR3CALLBACKMEMBER(bool, pfnIoCtxIsZero, (void *pvUser, PVDIOCTX pIoCtx, + size_t cbCheck, bool fAdvance)); + } VDINTERFACEIOINT, *PVDINTERFACEIOINT; /** @@ -483,64 +475,64 @@ DECLINLINE(int) vdIfIoIntFileSetSize(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pS } DECLINLINE(int) vdIfIoIntFileWriteSync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, - uint64_t uOffset, const void *pvBuffer, size_t cbBuffer, - size_t *pcbWritten) + uint64_t uOffset, const void *pvBuffer, size_t cbBuffer) { - return pIfIoInt->pfnWriteSync(pIfIoInt->Core.pvUser, pStorage, uOffset, - pvBuffer, cbBuffer, pcbWritten); + return pIfIoInt->pfnWriteMeta(pIfIoInt->Core.pvUser, pStorage, + uOffset, pvBuffer, cbBuffer, NULL, + NULL, NULL); } DECLINLINE(int) vdIfIoIntFileReadSync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, - uint64_t uOffset, void *pvBuffer, size_t cbBuffer, - size_t *pcbRead) + uint64_t uOffset, void *pvBuffer, size_t cbBuffer) { - return pIfIoInt->pfnReadSync(pIfIoInt->Core.pvUser, pStorage, uOffset, - pvBuffer, cbBuffer, pcbRead); + return pIfIoInt->pfnReadMeta(pIfIoInt->Core.pvUser, pStorage, + uOffset, pvBuffer, cbBuffer, NULL, + NULL, NULL, NULL); } DECLINLINE(int) vdIfIoIntFileFlushSync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage) { - return pIfIoInt->pfnFlushSync(pIfIoInt->Core.pvUser, pStorage); + return pIfIoInt->pfnFlush(pIfIoInt->Core.pvUser, pStorage, NULL, NULL, NULL); } -DECLINLINE(int) vdIfIoIntFileReadUserAsync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, - uint64_t uOffset, PVDIOCTX pIoCtx, size_t cbRead) +DECLINLINE(int) vdIfIoIntFileReadUser(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, + uint64_t uOffset, PVDIOCTX pIoCtx, size_t cbRead) { - return pIfIoInt->pfnReadUserAsync(pIfIoInt->Core.pvUser, pStorage, - uOffset, pIoCtx, cbRead); + return pIfIoInt->pfnReadUser(pIfIoInt->Core.pvUser, pStorage, + uOffset, pIoCtx, cbRead); } -DECLINLINE(int) vdIfIoIntFileWriteUserAsync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, - uint64_t uOffset, PVDIOCTX pIoCtx, size_t cbWrite, - PFNVDXFERCOMPLETED pfnComplete, - void *pvCompleteUser) +DECLINLINE(int) vdIfIoIntFileWriteUser(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, + uint64_t uOffset, PVDIOCTX pIoCtx, size_t cbWrite, + PFNVDXFERCOMPLETED pfnComplete, + void *pvCompleteUser) { - return pIfIoInt->pfnWriteUserAsync(pIfIoInt->Core.pvUser, pStorage, - uOffset, pIoCtx, cbWrite, pfnComplete, - pvCompleteUser); + return pIfIoInt->pfnWriteUser(pIfIoInt->Core.pvUser, pStorage, + uOffset, pIoCtx, cbWrite, pfnComplete, + pvCompleteUser); } -DECLINLINE(int) vdIfIoIntFileReadMetaAsync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, - uint64_t uOffset, void *pvBuffer, - size_t cbBuffer, PVDIOCTX pIoCtx, - PPVDMETAXFER ppMetaXfer, - PFNVDXFERCOMPLETED pfnComplete, - void *pvCompleteUser) +DECLINLINE(int) vdIfIoIntFileReadMeta(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, + uint64_t uOffset, void *pvBuffer, + size_t cbBuffer, PVDIOCTX pIoCtx, + PPVDMETAXFER ppMetaXfer, + PFNVDXFERCOMPLETED pfnComplete, + void *pvCompleteUser) { - return pIfIoInt->pfnReadMetaAsync(pIfIoInt->Core.pvUser, pStorage, - uOffset, pvBuffer, cbBuffer, pIoCtx, - ppMetaXfer, pfnComplete, pvCompleteUser); + return pIfIoInt->pfnReadMeta(pIfIoInt->Core.pvUser, pStorage, + uOffset, pvBuffer, cbBuffer, pIoCtx, + ppMetaXfer, pfnComplete, pvCompleteUser); } -DECLINLINE(int) vdIfIoIntFileWriteMetaAsync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, - uint64_t uOffset, void *pvBuffer, - size_t cbBuffer, PVDIOCTX pIoCtx, - PFNVDXFERCOMPLETED pfnComplete, - void *pvCompleteUser) +DECLINLINE(int) vdIfIoIntFileWriteMeta(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, + uint64_t uOffset, void *pvBuffer, + size_t cbBuffer, PVDIOCTX pIoCtx, + PFNVDXFERCOMPLETED pfnComplete, + void *pvCompleteUser) { - return pIfIoInt->pfnWriteMetaAsync(pIfIoInt->Core.pvUser, pStorage, - uOffset, pvBuffer, cbBuffer, pIoCtx, - pfnComplete, pvCompleteUser); + return pIfIoInt->pfnWriteMeta(pIfIoInt->Core.pvUser, pStorage, + uOffset, pvBuffer, cbBuffer, pIoCtx, + pfnComplete, pvCompleteUser); } DECLINLINE(void) vdIfIoIntMetaXferRelease(PVDINTERFACEIOINT pIfIoInt, PVDMETAXFER pMetaXfer) @@ -548,12 +540,24 @@ DECLINLINE(void) vdIfIoIntMetaXferRelease(PVDINTERFACEIOINT pIfIoInt, PVDMETAXFE pIfIoInt->pfnMetaXferRelease(pIfIoInt->Core.pvUser, pMetaXfer); } -DECLINLINE(int) vdIfIoIntFileFlushAsync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, - PVDIOCTX pIoCtx, PFNVDXFERCOMPLETED pfnComplete, - void *pvCompleteUser) +DECLINLINE(int) vdIfIoIntFileFlush(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage, + PVDIOCTX pIoCtx, PFNVDXFERCOMPLETED pfnComplete, + void *pvCompleteUser) +{ + return pIfIoInt->pfnFlush(pIfIoInt->Core.pvUser, pStorage, pIoCtx, pfnComplete, + pvCompleteUser); +} + +DECLINLINE(size_t) vdIfIoIntIoCtxCopyTo(PVDINTERFACEIOINT pIfIoInt, PVDIOCTX pIoCtx, + const void *pvBuffer, size_t cbBuffer) +{ + return pIfIoInt->pfnIoCtxCopyTo(pIfIoInt->Core.pvUser, pIoCtx, pvBuffer, cbBuffer); +} + +DECLINLINE(size_t) vdIfIoIntIoCtxCopyFrom(PVDINTERFACEIOINT pIfIoInt, PVDIOCTX pIoCtx, + void *pvBuffer, size_t cbBuffer) { - return pIfIoInt->pfnFlushAsync(pIfIoInt->Core.pvUser, pStorage, pIoCtx, pfnComplete, - pvCompleteUser); + return pIfIoInt->pfnIoCtxCopyFrom(pIfIoInt->Core.pvUser, pIoCtx, pvBuffer, cbBuffer); } DECLINLINE(size_t) vdIfIoIntIoCtxSet(PVDINTERFACEIOINT pIfIoInt, PVDIOCTX pIoCtx, @@ -562,6 +566,25 @@ DECLINLINE(size_t) vdIfIoIntIoCtxSet(PVDINTERFACEIOINT pIfIoInt, PVDIOCTX pIoCtx return pIfIoInt->pfnIoCtxSet(pIfIoInt->Core.pvUser, pIoCtx, ch, cbSet); } +DECLINLINE(size_t) vdIfIoIntIoCtxSegArrayCreate(PVDINTERFACEIOINT pIfIoInt, PVDIOCTX pIoCtx, + PRTSGSEG paSeg, unsigned *pcSeg, + size_t cbData) +{ + return pIfIoInt->pfnIoCtxSegArrayCreate(pIfIoInt->Core.pvUser, pIoCtx, paSeg, pcSeg, cbData); +} + +DECLINLINE(bool) vdIfIoIntIoCtxIsSynchronous(PVDINTERFACEIOINT pIfIoInt, PVDIOCTX pIoCtx) +{ + return pIfIoInt->pfnIoCtxIsSynchronous(pIfIoInt->Core.pvUser, pIoCtx); +} + +DECLINLINE(bool) vdIfIoIntIoCtxIsZero(PVDINTERFACEIOINT pIfIoInt, PVDIOCTX pIoCtx, + size_t cbCheck, bool fAdvance) +{ + return pIfIoInt->pfnIoCtxIsZero(pIfIoInt->Core.pvUser, pIoCtx, cbCheck, fAdvance); +} + + RT_C_DECLS_END /** @} */ diff --git a/include/VBox/vd-ifs.h b/include/VBox/vd-ifs.h index d3167a41..9d2d4e43 100644 --- a/include/VBox/vd-ifs.h +++ b/include/VBox/vd-ifs.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -307,7 +307,7 @@ DECLINLINE(int) vdIfErrorMessage(PVDINTERFACEERROR pIfError, const char *pszForm int rc = VINF_SUCCESS; va_list va; va_start(va, pszFormat); - if (pIfError) + if (pIfError && pIfError->pfnMessage) rc = pIfError->pfnMessage(pIfError->Core.pvUser, pszFormat, va); va_end(va); return rc; @@ -605,6 +605,43 @@ DECLINLINE(int) vdIfIoFileFlushSync(PVDINTERFACEIO pIfIo, void *pStorage) } /** + * Create a VFS stream handle around a VD I/O interface. + * + * The I/O interface will not be closed or free by the stream, the caller will + * do so after it is done with the stream and has released the instances of the + * I/O stream object returned by this API. + * + * @return VBox status code. + * @param pVDIfsIo Pointer to the VD I/O interface. + * @param pvStorage The storage argument to pass to the interface + * methods. + * @param fFlags RTFILE_O_XXX, access mask requied. + * @param phVfsIos Where to return the VFS I/O stream handle on + * success. + */ +VBOXDDU_DECL(int) VDIfCreateVfsStream(PVDINTERFACEIO pVDIfsIo, void *pvStorage, uint32_t fFlags, PRTVFSIOSTREAM phVfsIos); + +/** + * Create a VFS file handle around a VD I/O interface. + * + * The I/O interface will not be closed or free by the VFS file, the caller will + * do so after it is done with the VFS file and has released the instances of + * the VFS object returned by this API. + * + * @return VBox status code. + * @param pVDIfs Pointer to the VD I/O interface. If NULL, then @a + * pVDIfsInt must be specified. + * @param pVDIfsInt Pointer to the internal VD I/O interface. If NULL, + * then @ pVDIfs must be specified. + * @param pvStorage The storage argument to pass to the interface + * methods. + * @param fFlags RTFILE_O_XXX, access mask requied. + * @param phVfsFile Where to return the VFS file handle on success. + */ +VBOXDDU_DECL(int) VDIfCreateVfsFile(PVDINTERFACEIO pVDIfs, struct VDINTERFACEIOINT *pVDIfsInt, void *pvStorage, uint32_t fFlags, PRTVFSFILE phVfsFile); + + +/** * Callback which provides progress information about a currently running * lengthy operation. * diff --git a/include/VBox/vd-plugin.h b/include/VBox/vd-plugin.h index 46f1d9a9..1a0ca12d 100644 --- a/include/VBox/vd-plugin.h +++ b/include/VBox/vd-plugin.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2011 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -174,35 +174,26 @@ typedef struct VBOXHDDBACKEND DECLR3CALLBACKMEMBER(int, pfnClose, (void *pBackendData, bool fDelete)); /** - * Read data from a disk image. The area read never crosses a block - * boundary. + * Start a read request. * * @returns VBox status code. - * @returns VERR_VD_BLOCK_FREE if this image contains no data for this block. * @param pBackendData Opaque state data for this image. - * @param uOffset Offset to start reading from. - * @param pvBuf Where to store the read bits. - * @param cbRead Number of bytes to read. + * @param uOffset The offset of the virtual disk to read from. + * @param cbRead How many bytes to read. + * @param pIoCtx I/O context associated with this request. * @param pcbActuallyRead Pointer to returned number of bytes read. */ - DECLR3CALLBACKMEMBER(int, pfnRead, (void *pBackendData, uint64_t uOffset, void *pvBuf, - size_t cbRead, size_t *pcbActuallyRead)); + DECLR3CALLBACKMEMBER(int, pfnRead, (void *pBackendData, uint64_t uOffset, size_t cbRead, + PVDIOCTX pIoCtx, size_t *pcbActuallyRead)); /** - * Write data to a disk image. The area written never crosses a block - * boundary. + * Start a write request. * * @returns VBox status code. - * @returns VERR_VD_BLOCK_FREE if this image contains no data for this block and - * this is not a full-block write. The write must be repeated with - * the correct amount of prefix/postfix data read from the images below - * in the image stack. This might not be the most convenient interface, - * but it works with arbitrary block sizes, especially when the image - * stack uses different block sizes. * @param pBackendData Opaque state data for this image. - * @param uOffset Offset to start writing to. - * @param pvBuf Where to retrieve the written bits. - * @param cbWrite Number of bytes to write. + * @param uOffset The offset of the virtual disk to write to. + * @param cbWrite How many bytes to write. + * @param pIoCtx I/O context associated with this request. * @param pcbWriteProcess Pointer to returned number of bytes that could * be processed. In case the function returned * VERR_VD_BLOCK_FREE this is the number of bytes @@ -216,8 +207,8 @@ typedef struct VBOXHDDBACKEND * @param fWrite Flags which affect write behavior. Combination * of the VD_WRITE_* flags. */ - DECLR3CALLBACKMEMBER(int, pfnWrite, (void *pBackendData, uint64_t uOffset, - const void *pvBuf, size_t cbWrite, + DECLR3CALLBACKMEMBER(int, pfnWrite, (void *pBackendData, uint64_t uOffset, size_t cbWrite, + PVDIOCTX pIoCtx, size_t *pcbWriteProcess, size_t *pcbPreRead, size_t *pcbPostRead, unsigned fWrite)); @@ -226,8 +217,41 @@ typedef struct VBOXHDDBACKEND * * @returns VBox status code. * @param pBackendData Opaque state data for this image. + * @param pIoCtx I/O context associated with this request. */ - DECLR3CALLBACKMEMBER(int, pfnFlush, (void *pBackendData)); + DECLR3CALLBACKMEMBER(int, pfnFlush, (void *pBackendData, PVDIOCTX pIoCtx)); + + /** + * Discards the given amount of bytes decreasing the size of the image if possible + * + * @returns VBox status code. + * @retval VERR_VD_DISCARD_ALIGNMENT_NOT_MET if the range doesn't meet the required alignment + * for the discard. + * @param pBackendData Opaque state data for this image. + * @param pIoCtx I/O context associated with this request. + * @param uOffset The offset of the first byte to discard. + * @param cbDiscard How many bytes to discard. + * @param pcbPreAllocated Pointer to the returned amount of bytes that must + * be discarded before the range to perform a full + * block discard. + * @param pcbPostAllocated Pointer to the returned amount of bytes that must + * be discarded after the range to perform a full + * block discard. + * @param pcbActuallyDiscarded Pointer to the returned amount of bytes which + * could be actually discarded. + * @param ppbmAllocationBitmap Where to store the pointer to the allocation bitmap + * if VERR_VD_DISCARD_ALIGNMENT_NOT_MET is returned or NULL + * if the allocation bitmap should be returned. + * @param fDiscard Flags which affect discard behavior. Combination + * of the VD_DISCARD_* flags. + */ + DECLR3CALLBACKMEMBER(int, pfnDiscard, (void *pBackendData, PVDIOCTX pIoCtx, + uint64_t uOffset, size_t cbDiscard, + size_t *pcbPreAllocated, + size_t *pcbPostAllocated, + size_t *pcbActuallyDiscarded, + void **ppbmAllocationBitmap, + unsigned fDiscard)); /** * Get the version of a disk image. @@ -238,6 +262,14 @@ typedef struct VBOXHDDBACKEND DECLR3CALLBACKMEMBER(unsigned, pfnGetVersion, (void *pBackendData)); /** + * Get the sector size of a disk image. + * + * @returns size of disk image in bytes. + * @param pBackendData Opaque state data for this image. + */ + DECLR3CALLBACKMEMBER(uint32_t, pfnGetSectorSize, (void *pBackendData)); + + /** * Get the capacity of a disk image. * * @returns size of disk image in bytes. @@ -464,54 +496,6 @@ typedef struct VBOXHDDBACKEND */ DECLR3CALLBACKMEMBER(int, pfnSetParentFilename, (void *pBackendData, const char *pszParentFilename)); - /** - * Start an asynchronous read request. - * - * @returns VBox status code. - * @param pBackendData Opaque state data for this image. - * @param uOffset The offset of the virtual disk to read from. - * @param cbRead How many bytes to read. - * @param pIoCtx I/O context associated with this request. - * @param pcbActuallyRead Pointer to returned number of bytes read. - */ - DECLR3CALLBACKMEMBER(int, pfnAsyncRead, (void *pBackendData, uint64_t uOffset, size_t cbRead, - PVDIOCTX pIoCtx, size_t *pcbActuallyRead)); - - /** - * Start an asynchronous write request. - * - * @returns VBox status code. - * @param pBackendData Opaque state data for this image. - * @param uOffset The offset of the virtual disk to write to. - * @param cbWrite How many bytes to write. - * @param pIoCtx I/O context associated with this request. - * @param pcbWriteProcess Pointer to returned number of bytes that could - * be processed. In case the function returned - * VERR_VD_BLOCK_FREE this is the number of bytes - * that could be written in a full block write, - * when prefixed/postfixed by the appropriate - * amount of (previously read) padding data. - * @param pcbPreRead Pointer to the returned amount of data that must - * be prefixed to perform a full block write. - * @param pcbPostRead Pointer to the returned amount of data that must - * be postfixed to perform a full block write. - * @param fWrite Flags which affect write behavior. Combination - * of the VD_WRITE_* flags. - */ - DECLR3CALLBACKMEMBER(int, pfnAsyncWrite, (void *pBackendData, uint64_t uOffset, size_t cbWrite, - PVDIOCTX pIoCtx, - size_t *pcbWriteProcess, size_t *pcbPreRead, - size_t *pcbPostRead, unsigned fWrite)); - - /** - * Flush data to disk. - * - * @returns VBox status code. - * @param pBackendData Opaque state data for this image. - * @param pIoCtx I/O context associated with this request. - */ - DECLR3CALLBACKMEMBER(int, pfnAsyncFlush, (void *pBackendData, PVDIOCTX pIoCtx)); - /** Returns a human readable hard disk location string given a * set of hard disk configuration keys. The returned string is an * equivalent of the full file path for image-based hard disks. @@ -570,70 +554,6 @@ typedef struct VBOXHDDBACKEND PVDINTERFACE pVDIfsOperation)); /** - * Discards the given amount of bytes decreasing the size of the image if possible. - * - * @returns VBox status code. - * @retval VERR_VD_DISCARD_ALIGNMENT_NOT_MET if the range doesn't meet the required alignment - * for the discard. - * @param pBackendData Opaque state data for this image. - * @param uOffset The offset of the first byte to discard. - * @param cbDiscard How many bytes to discard. - * @param pcbPreAllocated Pointer to the returned amount of bytes that must - * be discarded before the range to perform a full - * block discard. - * @param pcbPostAllocated Pointer to the returned amount of bytes that must - * be discarded after the range to perform a full - * block discard. - * @param pcbActuallyDiscarded Pointer to the returned amount of bytes which - * could be actually discarded. - * @param ppbmAllocationBitmap Where to store the pointer to the allocation bitmap - * if VERR_VD_DISCARD_ALIGNMENT_NOT_MET is returned or NULL - * if the allocation bitmap should be returned. - * @param fDiscard Flags which affect discard behavior. Combination - * of the VD_DISCARD_* flags. - */ - DECLR3CALLBACKMEMBER(int, pfnDiscard, (void *pBackendData, - uint64_t uOffset, size_t cbDiscard, - size_t *pcbPreAllocated, - size_t *pcbPostAllocated, - size_t *pcbActuallyDiscarded, - void **ppbmAllocationBitmap, - unsigned fDiscard)); - - /** - * Discards the given amount of bytes decreasing the size of the image if possible - * callback version for asynchronous I/O. - * - * @returns VBox status code. - * @retval VERR_VD_DISCARD_ALIGNMENT_NOT_MET if the range doesn't meet the required alignment - * for the discard. - * @param pBackendData Opaque state data for this image. - * @param pIoCtx I/O context associated with this request. - * @param uOffset The offset of the first byte to discard. - * @param cbDiscard How many bytes to discard. - * @param pcbPreAllocated Pointer to the returned amount of bytes that must - * be discarded before the range to perform a full - * block discard. - * @param pcbPostAllocated Pointer to the returned amount of bytes that must - * be discarded after the range to perform a full - * block discard. - * @param pcbActuallyDiscarded Pointer to the returned amount of bytes which - * could be actually discarded. - * @param ppbmAllocationBitmap Where to store the pointer to the allocation bitmap - * if VERR_VD_DISCARD_ALIGNMENT_NOT_MET is returned or NULL - * if the allocation bitmap should be returned. - * @param fDiscard Flags which affect discard behavior. Combination - * of the VD_DISCARD_* flags. - */ - DECLR3CALLBACKMEMBER(int, pfnAsyncDiscard, (void *pBackendData, PVDIOCTX pIoCtx, - uint64_t uOffset, size_t cbDiscard, - size_t *pcbPreAllocated, - size_t *pcbPostAllocated, - size_t *pcbActuallyDiscarded, - void **ppbmAllocationBitmap, - unsigned fDiscard)); - - /** * Try to repair the given image. * * @returns VBox status code. diff --git a/include/VBox/vd.h b/include/VBox/vd.h index 86589bbf..ba0768eb 100644 --- a/include/VBox/vd.h +++ b/include/VBox/vd.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2011 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -151,14 +151,14 @@ typedef struct VBOXHDDRAWPARTDESC } VBOXHDDRAWPARTDESC, *PVBOXHDDRAWPARTDESC; /** - * Auxiliary data structure for difference between GPT and MBR - * disks. + * Auxiliary data structure for difference between GPT and MBR + * disks. */ -enum PARTITIONING_TYPE +typedef enum VBOXHDDPARTTYPE { MBR, GPT -}; +} VBOXHDDPARTTYPE; /** * Auxiliary data structure for creating raw disks. @@ -178,8 +178,8 @@ typedef struct VBOXHDDRAW unsigned cPartDescs; /** Pointer to the partition descriptor array. */ PVBOXHDDRAWPARTDESC pPartDescs; - /**partitioning type of the disk */ - PARTITIONING_TYPE uPartitioningType; + /** Partitioning type of the disk */ + VBOXHDDPARTTYPE uPartitioningType; } VBOXHDDRAW, *PVBOXHDDRAW; @@ -230,8 +230,14 @@ typedef struct VBOXHDDRAW * sector at a time is the safest solution. */ #define VD_OPEN_FLAGS_INFORM_ABOUT_ZERO_BLOCKS RT_BIT(9) +/** + * Don't do unnecessary consistency checks when opening the image. + * Only valid when the image is opened in readonly because inconsistencies + * can lead to corrupted images in read-write mode. + */ +#define VD_OPEN_FLAGS_SKIP_CONSISTENCY_CHECKS RT_BIT(10) /** Mask of valid flags. */ -#define VD_OPEN_FLAGS_MASK (VD_OPEN_FLAGS_NORMAL | VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_HONOR_ZEROES | VD_OPEN_FLAGS_HONOR_SAME | VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_ASYNC_IO | VD_OPEN_FLAGS_SHAREABLE | VD_OPEN_FLAGS_SEQUENTIAL | VD_OPEN_FLAGS_DISCARD | VD_OPEN_FLAGS_IGNORE_FLUSH | VD_OPEN_FLAGS_INFORM_ABOUT_ZERO_BLOCKS) +#define VD_OPEN_FLAGS_MASK (VD_OPEN_FLAGS_NORMAL | VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_HONOR_ZEROES | VD_OPEN_FLAGS_HONOR_SAME | VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_ASYNC_IO | VD_OPEN_FLAGS_SHAREABLE | VD_OPEN_FLAGS_SEQUENTIAL | VD_OPEN_FLAGS_DISCARD | VD_OPEN_FLAGS_IGNORE_FLUSH | VD_OPEN_FLAGS_INFORM_ABOUT_ZERO_BLOCKS | VD_OPEN_FLAGS_SKIP_CONSISTENCY_CHECKS) /** @}*/ /** @@ -789,7 +795,9 @@ VBOXDDU_DECL(int) VDCompact(PVBOXHDD pDisk, unsigned nImage, PVDINTERFACE pVDIfsOperation); /** - * Resizes the given disk image to the given size. + * Resizes the given disk image to the given size. It is OK if there are + * multiple images open in the container. In this case the last disk image + * will be resized. * * @return VBox status * @return VERR_VD_IMAGE_READ_ONLY if image is not writable. @@ -892,6 +900,16 @@ VBOXDDU_DECL(unsigned) VDGetCount(PVBOXHDD pDisk); VBOXDDU_DECL(bool) VDIsReadOnly(PVBOXHDD pDisk); /** + * Get sector size of an image in HDD container. + * + * @return Virtual disk sector size in bytes. + * @return 0 if image with specified number was not opened. + * @param pDisk Pointer to HDD container. + * @param nImage Image number, counts from 0. 0 is always base image of container. + */ +VBOXDDU_DECL(uint32_t) VDGetSectorSize(PVBOXHDD pDisk, unsigned nImage); + +/** * Get total capacity of an image in HDD container. * * @return Virtual disk size in bytes. @@ -1239,7 +1257,8 @@ VBOXDDU_DECL(int) VDRepair(PVDINTERFACE pVDIfsDisk, PVDINTERFACE pVDIfsImage, * @return VBox status code. * @param pDisk Pointer to HDD container. * @param fFlags Combination of the VD_VFSFILE_* flags. - * @param phVfsFile Where to stoer the handle to the VFS file on success. + * @param phVfsFile Where to store the handle to the VFS file on + * success. */ VBOXDDU_DECL(int) VDCreateVfsFileFromDisk(PVBOXHDD pDisk, uint32_t fFlags, PRTVFSFILE phVfsFile); diff --git a/include/VBox/version.h b/include/VBox/version.h index 8a48c1f6..defa3219 100644 --- a/include/VBox/version.h +++ b/include/VBox/version.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/vmm/cfgm.h b/include/VBox/vmm/cfgm.h index 9b4e47ab..dbc8e527 100644 --- a/include/VBox/vmm/cfgm.h +++ b/include/VBox/vmm/cfgm.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -74,19 +74,20 @@ typedef enum CFGMCONFIGTYPE * can make any necessary per-thread initializations at this point. * * @returns VBox status code. - * @param pVM VM handle. + * @param pUVM The user mode VM handle. + * @param pVM The shared VM handle. * @param pvUser The argument supplied to VMR3Create(). */ -typedef DECLCALLBACK(int) FNCFGMCONSTRUCTOR(PVM pVM, void *pvUser); +typedef DECLCALLBACK(int) FNCFGMCONSTRUCTOR(PUVM pUVM, PVM pVM, void *pvUser); /** Pointer to a FNCFGMCONSTRUCTOR(). */ typedef FNCFGMCONSTRUCTOR *PFNCFGMCONSTRUCTOR; VMMR3DECL(int) CFGMR3Init(PVM pVM, PFNCFGMCONSTRUCTOR pfnCFGMConstructor, void *pvUser); VMMR3DECL(int) CFGMR3Term(PVM pVM); - - -VMMR3DECL(PCFGMNODE) CFGMR3CreateTree(PVM pVM); VMMR3DECL(int) CFGMR3ConstructDefaultTree(PVM pVM); + +VMMR3DECL(PCFGMNODE) CFGMR3CreateTree(PUVM pUVM); +VMMR3DECL(int) CFGMR3DestroyTree(PCFGMNODE pRoot); VMMR3DECL(void) CFGMR3Dump(PCFGMNODE pRoot); VMMR3DECL(int) CFGMR3DuplicateSubTree(PCFGMNODE pRoot, PCFGMNODE *ppCopy); VMMR3DECL(int) CFGMR3ReplaceSubTree(PCFGMNODE pRoot, PCFGMNODE pNewRoot); @@ -185,6 +186,7 @@ VMMR3DECL(int) CFGMR3QueryStringAllocDef(PCFGMNODE pNode, const char *p * @{ */ VMMR3DECL(PCFGMNODE) CFGMR3GetRoot(PVM pVM); +VMMR3DECL(PCFGMNODE) CFGMR3GetRootU(PUVM pUVM); VMMR3DECL(PCFGMNODE) CFGMR3GetParent(PCFGMNODE pNode); VMMR3DECL(PCFGMNODE) CFGMR3GetParentEx(PVM pVM, PCFGMNODE pNode); VMMR3DECL(PCFGMNODE) CFGMR3GetChild(PCFGMNODE pNode, const char *pszPath); diff --git a/include/VBox/vmm/cpum.h b/include/VBox/vmm/cpum.h index 0b4abf33..d3ca4c02 100644 --- a/include/VBox/vmm/cpum.h +++ b/include/VBox/vmm/cpum.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2012 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -77,13 +77,259 @@ typedef enum CPUMCPUVENDOR CPUMCPUVENDOR_INTEL, CPUMCPUVENDOR_AMD, CPUMCPUVENDOR_VIA, + CPUMCPUVENDOR_CYRIX, CPUMCPUVENDOR_UNKNOWN, - CPUMCPUVENDOR_SYNTHETIC, /** 32bit hackishness. */ CPUMCPUVENDOR_32BIT_HACK = 0x7fffffff } CPUMCPUVENDOR; +/** + * X86 and AMD64 CPU microarchitectures and in processor generations. + * + * @remarks The separation here is sometimes a little bit too finely grained, + * and the differences is more like processor generation than micro + * arch. This can be useful, so we'll provide functions for getting at + * more coarse grained info. + */ +typedef enum CPUMMICROARCH +{ + kCpumMicroarch_Invalid = 0, + + kCpumMicroarch_Intel_First, + + kCpumMicroarch_Intel_8086 = kCpumMicroarch_Intel_First, + kCpumMicroarch_Intel_80186, + kCpumMicroarch_Intel_80286, + kCpumMicroarch_Intel_80386, + kCpumMicroarch_Intel_80486, + kCpumMicroarch_Intel_P5, + + kCpumMicroarch_Intel_P6_Core_Atom_First, + kCpumMicroarch_Intel_P6 = kCpumMicroarch_Intel_P6_Core_Atom_First, + kCpumMicroarch_Intel_P6_II, + kCpumMicroarch_Intel_P6_III, + + kCpumMicroarch_Intel_P6_M_Banias, + kCpumMicroarch_Intel_P6_M_Dothan, + kCpumMicroarch_Intel_Core_Yonah, /**< Core, also known as Enhanced Pentium M. */ + + kCpumMicroarch_Intel_Core2_First, + kCpumMicroarch_Intel_Core2_Merom = kCpumMicroarch_Intel_Core2_First, + kCpumMicroarch_Intel_Core2_Penryn, + + kCpumMicroarch_Intel_Core7_First, + kCpumMicroarch_Intel_Core7_Nehalem = kCpumMicroarch_Intel_Core7_First, + kCpumMicroarch_Intel_Core7_Westmere, + kCpumMicroarch_Intel_Core7_SandyBridge, + kCpumMicroarch_Intel_Core7_IvyBridge, + kCpumMicroarch_Intel_Core7_Haswell, + kCpumMicroarch_Intel_Core7_Broadwell, + kCpumMicroarch_Intel_Core7_Skylake, + kCpumMicroarch_Intel_Core7_Cannonlake, + kCpumMicroarch_Intel_Core7_End, + + kCpumMicroarch_Intel_Atom_First, + kCpumMicroarch_Intel_Atom_Bonnell = kCpumMicroarch_Intel_Atom_First, + kCpumMicroarch_Intel_Atom_Lincroft, /**< Second generation bonnell (44nm). */ + kCpumMicroarch_Intel_Atom_Saltwell, /**< 32nm shrink of Bonnell. */ + kCpumMicroarch_Intel_Atom_Silvermont, /**< 22nm */ + kCpumMicroarch_Intel_Atom_Airmount, /**< 14nm */ + kCpumMicroarch_Intel_Atom_Goldmont, /**< 14nm */ + kCpumMicroarch_Intel_Atom_Unknown, + kCpumMicroarch_Intel_Atom_End, + + kCpumMicroarch_Intel_P6_Core_Atom_End, + + kCpumMicroarch_Intel_NB_First, + kCpumMicroarch_Intel_NB_Willamette = kCpumMicroarch_Intel_NB_First, /**< 180nm */ + kCpumMicroarch_Intel_NB_Northwood, /**< 130nm */ + kCpumMicroarch_Intel_NB_Prescott, /**< 90nm */ + kCpumMicroarch_Intel_NB_Prescott2M, /**< 90nm */ + kCpumMicroarch_Intel_NB_CedarMill, /**< 65nm */ + kCpumMicroarch_Intel_NB_Gallatin, /**< 90nm Xeon, Pentium 4 Extreme Edition ("Emergency Edition"). */ + kCpumMicroarch_Intel_NB_Unknown, + kCpumMicroarch_Intel_NB_End, + + kCpumMicroarch_Intel_Unknown, + kCpumMicroarch_Intel_End, + + kCpumMicroarch_AMD_First, + kCpumMicroarch_AMD_Am286 = kCpumMicroarch_AMD_First, + kCpumMicroarch_AMD_Am386, + kCpumMicroarch_AMD_Am486, + kCpumMicroarch_AMD_Am486Enh, /**< Covers Am5x86 as well. */ + kCpumMicroarch_AMD_K5, + kCpumMicroarch_AMD_K6, + + kCpumMicroarch_AMD_K7_First, + kCpumMicroarch_AMD_K7_Palomino = kCpumMicroarch_AMD_K7_First, + kCpumMicroarch_AMD_K7_Spitfire, + kCpumMicroarch_AMD_K7_Thunderbird, + kCpumMicroarch_AMD_K7_Morgan, + kCpumMicroarch_AMD_K7_Thoroughbred, + kCpumMicroarch_AMD_K7_Barton, + kCpumMicroarch_AMD_K7_Unknown, + kCpumMicroarch_AMD_K7_End, + + kCpumMicroarch_AMD_K8_First, + kCpumMicroarch_AMD_K8_130nm = kCpumMicroarch_AMD_K8_First, /**< 130nm Clawhammer, Sledgehammer, Newcastle, Paris, Odessa, Dublin */ + kCpumMicroarch_AMD_K8_90nm, /**< 90nm shrink */ + kCpumMicroarch_AMD_K8_90nm_DualCore, /**< 90nm with two cores. */ + kCpumMicroarch_AMD_K8_90nm_AMDV, /**< 90nm with AMD-V (usually) and two cores (usually). */ + kCpumMicroarch_AMD_K8_65nm, /**< 65nm shrink. */ + kCpumMicroarch_AMD_K8_End, + + kCpumMicroarch_AMD_K10, + kCpumMicroarch_AMD_K10_Lion, + kCpumMicroarch_AMD_K10_Llano, + kCpumMicroarch_AMD_Bobcat, + kCpumMicroarch_AMD_Jaguar, + + kCpumMicroarch_AMD_15h_First, + kCpumMicroarch_AMD_15h_Bulldozer = kCpumMicroarch_AMD_15h_First, + kCpumMicroarch_AMD_15h_Piledriver, + kCpumMicroarch_AMD_15h_Steamroller, /**< Yet to be released, might have different family. */ + kCpumMicroarch_AMD_15h_Excavator, /**< Yet to be released, might have different family. */ + kCpumMicroarch_AMD_15h_Unknown, + kCpumMicroarch_AMD_15h_End, + + kCpumMicroarch_AMD_16h_First, + kCpumMicroarch_AMD_16h_End, + + kCpumMicroarch_AMD_Unknown, + kCpumMicroarch_AMD_End, + + kCpumMicroarch_VIA_First, + kCpumMicroarch_Centaur_C6 = kCpumMicroarch_VIA_First, + kCpumMicroarch_Centaur_C2, + kCpumMicroarch_Centaur_C3, + kCpumMicroarch_VIA_C3_M2, + kCpumMicroarch_VIA_C3_C5A, /**< 180nm Samuel - Cyrix III, C3, 1GigaPro. */ + kCpumMicroarch_VIA_C3_C5B, /**< 150nm Samuel 2 - Cyrix III, C3, 1GigaPro, Eden ESP, XP 2000+. */ + kCpumMicroarch_VIA_C3_C5C, /**< 130nm Ezra - C3, Eden ESP. */ + kCpumMicroarch_VIA_C3_C5N, /**< 130nm Ezra-T - C3. */ + kCpumMicroarch_VIA_C3_C5XL, /**< 130nm Nehemiah - C3, Eden ESP, Eden-N. */ + kCpumMicroarch_VIA_C3_C5P, /**< 130nm Nehemiah+ - C3. */ + kCpumMicroarch_VIA_C7_C5J, /**< 90nm Esther - C7, C7-D, C7-M, Eden, Eden ULV. */ + kCpumMicroarch_VIA_Isaiah, + kCpumMicroarch_VIA_Unknown, + kCpumMicroarch_VIA_End, + + kCpumMicroarch_Cyrix_First, + kCpumMicroarch_Cyrix_5x86 = kCpumMicroarch_Cyrix_First, + kCpumMicroarch_Cyrix_M1, + kCpumMicroarch_Cyrix_MediaGX, + kCpumMicroarch_Cyrix_MediaGXm, + kCpumMicroarch_Cyrix_M2, + kCpumMicroarch_Cyrix_Unknown, + kCpumMicroarch_Cyrix_End, + + kCpumMicroarch_Unknown, + + kCpumMicroarch_32BitHack = 0x7fffffff +} CPUMMICROARCH; + + +/** Predicate macro for catching netburst CPUs. */ +#define CPUMMICROARCH_IS_INTEL_NETBURST(a_enmMicroarch) \ + ((a_enmMicroarch) >= kCpumMicroarch_Intel_NB_First && (a_enmMicroarch) <= kCpumMicroarch_Intel_NB_End) + +/** Predicate macro for catching Core7 CPUs. */ +#define CPUMMICROARCH_IS_INTEL_CORE7(a_enmMicroarch) \ + ((a_enmMicroarch) >= kCpumMicroarch_Intel_Core7_First && (a_enmMicroarch) <= kCpumMicroarch_Intel_Core7_End) + +/** Predicate macro for catching AMD Family OFh CPUs (aka K8). */ +#define CPUMMICROARCH_IS_AMD_FAM_0FH(a_enmMicroarch) \ + ((a_enmMicroarch) >= kCpumMicroarch_AMD_K8_First && (a_enmMicroarch) <= kCpumMicroarch_AMD_K8_End) + +/** Predicate macro for catching AMD Family 10H CPUs (aka K10). */ +#define CPUMMICROARCH_IS_AMD_FAM_10H(a_enmMicroarch) ((a_enmMicroarch) == kCpumMicroarch_AMD_K10) + +/** Predicate macro for catching AMD Family 11H CPUs (aka Lion). */ +#define CPUMMICROARCH_IS_AMD_FAM_11H(a_enmMicroarch) ((a_enmMicroarch) == kCpumMicroarch_AMD_K10_Lion) + +/** Predicate macro for catching AMD Family 12H CPUs (aka Llano). */ +#define CPUMMICROARCH_IS_AMD_FAM_12H(a_enmMicroarch) ((a_enmMicroarch) == kCpumMicroarch_AMD_K10_Llano) + +/** Predicate macro for catching AMD Family 14H CPUs (aka Bobcat). */ +#define CPUMMICROARCH_IS_AMD_FAM_14H(a_enmMicroarch) ((a_enmMicroarch) == kCpumMicroarch_AMD_Bobcat) + +/** Predicate macro for catching AMD Family 15H CPUs (bulldozer and it's + * decendants). */ +#define CPUMMICROARCH_IS_AMD_FAM_15H(a_enmMicroarch) \ + ((a_enmMicroarch) >= kCpumMicroarch_AMD_15h_First && (a_enmMicroarch) <= kCpumMicroarch_AMD_15h_End) + +/** Predicate macro for catching AMD Family 16H CPUs. */ +#define CPUMMICROARCH_IS_AMD_FAM_16H(a_enmMicroarch) \ + ((a_enmMicroarch) >= kCpumMicroarch_AMD_16h_First && (a_enmMicroarch) <= kCpumMicroarch_AMD_16h_End) + + + +/** + * CPUID leaf. + */ +typedef struct CPUMCPUIDLEAF +{ + /** The leaf number. */ + uint32_t uLeaf; + /** The sub-leaf number. */ + uint32_t uSubLeaf; + /** Sub-leaf mask. This is 0 when sub-leaves aren't used. */ + uint32_t fSubLeafMask; + + /** The EAX value. */ + uint32_t uEax; + /** The EBX value. */ + uint32_t uEbx; + /** The ECX value. */ + uint32_t uEcx; + /** The EDX value. */ + uint32_t uEdx; + + /** Flags. */ + uint32_t fFlags; +} CPUMCPUIDLEAF; +/** Pointer to a CPUID leaf. */ +typedef CPUMCPUIDLEAF *PCPUMCPUIDLEAF; +/** Pointer to a const CPUID leaf. */ +typedef CPUMCPUIDLEAF const *PCCPUMCPUIDLEAF; + +/** @name CPUMCPUIDLEAF::fFlags + * @{ */ +/** Indicates that ECX (the sub-leaf indicator) doesn't change when + * requesting the final leaf and all undefined leaves that follows it. + * Observed for 0x0000000b on Intel. */ +#define CPUMCPUIDLEAF_F_SUBLEAVES_ECX_UNCHANGED RT_BIT_32(0) +/** @} */ + +/** + * Method used to deal with unknown CPUID leafs. + */ +typedef enum CPUMUKNOWNCPUID +{ + /** Invalid zero value. */ + CPUMUKNOWNCPUID_INVALID = 0, + /** Use given default values (DefCpuId). */ + CPUMUKNOWNCPUID_DEFAULTS, + /** Return the last standard leaf. + * Intel Sandy Bridge has been observed doing this. */ + CPUMUKNOWNCPUID_LAST_STD_LEAF, + /** Return the last standard leaf, with ecx observed. + * Intel Sandy Bridge has been observed doing this. */ + CPUMUKNOWNCPUID_LAST_STD_LEAF_WITH_ECX, + /** The register values are passed thru unmodified. */ + CPUMUKNOWNCPUID_PASSTHRU, + /** End of valid value. */ + CPUMUKNOWNCPUID_END, + /** Ensure 32-bit type. */ + CPUMUKNOWNCPUID_32BIT_HACK = 0x7fffffff +} CPUMUKNOWNCPUID; +/** Pointer to unknown CPUID leaf method. */ +typedef CPUMUKNOWNCPUID *PCPUMUKNOWNCPUID; + + + /** @name Guest Register Getters. * @{ */ VMMDECL(void) CPUMGetGuestGDTR(PVMCPU pVCpu, PVBOXGDTR pGDTR); @@ -172,6 +418,8 @@ VMMDECL(bool) CPUMGetGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeatur VMMDECL(void) CPUMSetGuestCtx(PVMCPU pVCpu, const PCPUMCTX pCtx); VMM_INT_DECL(void) CPUMGuestLazyLoadHiddenCsAndSs(PVMCPU pVCpu); VMM_INT_DECL(void) CPUMGuestLazyLoadHiddenSelectorReg(PVMCPU pVCpu, PCPUMSELREG pSReg); +VMMR0_INT_DECL(void) CPUMR0SetGuestTscAux(PVMCPU pVCpu, uint64_t uValue); +VMMR0_INT_DECL(uint64_t) CPUMR0GetGuestTscAux(PVMCPU pVCpu); /** @} */ @@ -215,7 +463,18 @@ DECLINLINE(bool) CPUMIsGuestInRealModeEx(PCPUMCTX pCtx) DECLINLINE(bool) CPUMIsGuestInRealOrV86ModeEx(PCPUMCTX pCtx) { return !(pCtx->cr0 & X86_CR0_PE) - || pCtx->eflags.Bits.u1VM; /** @todo verify that this cannot be set in long mode. */ + || pCtx->eflags.Bits.u1VM; /* Cannot be set in long mode. Intel spec 2.3.1 "System Flags and Fields in IA-32e Mode". */ +} + +/** + * Tests if the guest is running in virtual 8086 mode. + * + * @returns @c true if it is, @c false if not. + * @param pCtx Current CPU context + */ +DECLINLINE(bool) CPUMIsGuestInV86ModeEx(PCPUMCTX pCtx) +{ + return (pCtx->eflags.Bits.u1VM == 1); } /** @@ -259,6 +518,17 @@ DECLINLINE(bool) CPUMIsGuestIn64BitCodeEx(PCPUMCTX pCtx) } /** + * Tests if the guest has paging enabled or not. + * + * @returns true if paging is enabled, otherwise false. + * @param pCtx Current CPU context + */ +DECLINLINE(bool) CPUMIsGuestPagingEnabledEx(PCPUMCTX pCtx) +{ + return !!(pCtx->cr0 & X86_CR0_PG); +} + +/** * Tests if the guest is running in PAE mode or not. * * @returns true if in PAE mode, otherwise false. @@ -266,9 +536,11 @@ DECLINLINE(bool) CPUMIsGuestIn64BitCodeEx(PCPUMCTX pCtx) */ DECLINLINE(bool) CPUMIsGuestInPAEModeEx(PCPUMCTX pCtx) { - return ( (pCtx->cr4 & X86_CR4_PAE) - && CPUMIsGuestInPagedProtectedModeEx(pCtx) - && !CPUMIsGuestInLongModeEx(pCtx)); + /* Intel mentions EFER.LMA and EFER.LME in different parts of their spec. We shall use EFER.LMA rather + than EFER.LME as it reflects if the CPU has entered paging with EFER.LME set. */ + return ( (pCtx->cr4 & X86_CR4_PAE) + && CPUMIsGuestPagingEnabledEx(pCtx) + && !(pCtx->msrEFER & MSR_K6_EFER_LMA)); } #endif /* VBOX_WITHOUT_UNNAMED_UNIONS */ @@ -341,7 +613,7 @@ VMMDECL(void) CPUMSetHyperDR3(PVMCPU pVCpu, RTGCUINTREG uDr3); VMMDECL(void) CPUMSetHyperDR6(PVMCPU pVCpu, RTGCUINTREG uDr6); VMMDECL(void) CPUMSetHyperDR7(PVMCPU pVCpu, RTGCUINTREG uDr7); VMMDECL(void) CPUMSetHyperCtx(PVMCPU pVCpu, const PCPUMCTX pCtx); -VMMDECL(int) CPUMRecalcHyperDRx(PVMCPU pVCpu); +VMMDECL(int) CPUMRecalcHyperDRx(PVMCPU pVCpu, uint8_t iGstReg, bool fForceHyper); /** @} */ VMMDECL(void) CPUMPushHyper(PVMCPU pVCpu, uint32_t u32); @@ -350,11 +622,10 @@ VMMDECL(PCPUMCTX) CPUMGetHyperCtxPtr(PVMCPU pVCpu); VMMDECL(PCCPUMCTXCORE) CPUMGetHyperCtxCore(PVMCPU pVCpu); VMMDECL(PCPUMCTX) CPUMQueryGuestCtxPtr(PVMCPU pVCpu); VMMDECL(PCCPUMCTXCORE) CPUMGetGuestCtxCore(PVMCPU pVCpu); -VMMR3DECL(int) CPUMR3RawEnter(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore); -VMMR3DECL(int) CPUMR3RawLeave(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, int rc); +VMM_INT_DECL(int) CPUMRawEnter(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore); +VMM_INT_DECL(int) CPUMRawLeave(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, int rc); VMMDECL(uint32_t) CPUMRawGetEFlags(PVMCPU pVCpu); VMMDECL(void) CPUMRawSetEFlags(PVMCPU pVCpu, uint32_t fEfl); -VMMDECL(int) CPUMHandleLazyFPU(PVMCPU pVCpu); /** @name Changed flags. * These flags are used to keep track of which important register that @@ -394,16 +665,32 @@ VMMR3DECL(void) CPUMR3RemLeave(PVMCPU pVCpu, bool fNoOutOfSyncSels); VMMDECL(bool) CPUMSupportsFXSR(PVM pVM); VMMDECL(bool) CPUMIsHostUsingSysEnter(PVM pVM); VMMDECL(bool) CPUMIsHostUsingSysCall(PVM pVM); -VMMDECL(bool) CPUMIsGuestFPUStateActive(PVMCPU pVCPU); +VMMDECL(bool) CPUMIsGuestFPUStateActive(PVMCPU pVCpu); VMMDECL(void) CPUMDeactivateGuestFPUState(PVMCPU pVCpu); VMMDECL(bool) CPUMIsGuestDebugStateActive(PVMCPU pVCpu); +VMMDECL(bool) CPUMIsGuestDebugStateActivePending(PVMCPU pVCpu); VMMDECL(void) CPUMDeactivateGuestDebugState(PVMCPU pVCpu); VMMDECL(bool) CPUMIsHyperDebugStateActive(PVMCPU pVCpu); -VMMDECL(void) CPUMDeactivateHyperDebugState(PVMCPU pVCpu); +VMMDECL(bool) CPUMIsHyperDebugStateActivePending(PVMCPU pVCpu); VMMDECL(uint32_t) CPUMGetGuestCPL(PVMCPU pVCpu); VMMDECL(CPUMMODE) CPUMGetGuestMode(PVMCPU pVCpu); VMMDECL(uint32_t) CPUMGetGuestCodeBits(PVMCPU pVCpu); VMMDECL(DISCPUMODE) CPUMGetGuestDisMode(PVMCPU pVCpu); +VMMDECL(uint64_t) CPUMGetGuestScalableBusFrequency(PVM pVM); + +/** @name Typical scalable bus frequency values. + * @{ */ +/** Special internal value indicating that we don't know the frequency. + * @internal */ +#define CPUM_SBUSFREQ_UNKNOWN UINT64_C(1) +#define CPUM_SBUSFREQ_100MHZ UINT64_C(100000000) +#define CPUM_SBUSFREQ_133MHZ UINT64_C(133333333) +#define CPUM_SBUSFREQ_167MHZ UINT64_C(166666666) +#define CPUM_SBUSFREQ_200MHZ UINT64_C(200000000) +#define CPUM_SBUSFREQ_267MHZ UINT64_C(266666666) +#define CPUM_SBUSFREQ_333MHZ UINT64_C(333333333) +#define CPUM_SBUSFREQ_400MHZ UINT64_C(400000000) +/** @} */ #ifdef IN_RING3 @@ -413,10 +700,12 @@ VMMDECL(DISCPUMODE) CPUMGetGuestDisMode(PVMCPU pVCpu); */ VMMR3DECL(int) CPUMR3Init(PVM pVM); +VMMR3DECL(int) CPUMR3InitCompleted(PVM pVM); +VMMR3DECL(void) CPUMR3LogCpuIds(PVM pVM); VMMR3DECL(void) CPUMR3Relocate(PVM pVM); VMMR3DECL(int) CPUMR3Term(PVM pVM); VMMR3DECL(void) CPUMR3Reset(PVM pVM); -VMMR3DECL(void) CPUMR3ResetCpu(PVMCPU pVCpu); +VMMR3DECL(void) CPUMR3ResetCpu(PVM pVM, PVMCPU pVCpu); VMMDECL(bool) CPUMR3IsStateRestorePending(PVM pVM); VMMR3DECL(void) CPUMR3SetHWVirtEx(PVM pVM, bool fHWVirtExEnabled); VMMR3DECL(int) CPUMR3SetCR4Feature(PVM pVM, RTHCUINTREG fOr, RTHCUINTREG fAnd); @@ -425,6 +714,15 @@ VMMR3DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdExtRCPtr(PVM pVM); VMMR3DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdCentaurRCPtr(PVM pVM); VMMR3DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdDefRCPtr(PVM pVM); +VMMR3DECL(CPUMMICROARCH) CPUMR3CpuIdDetermineMicroarchEx(CPUMCPUVENDOR enmVendor, uint8_t bFamily, + uint8_t bModel, uint8_t bStepping); +VMMR3DECL(const char *) CPUMR3MicroarchName(CPUMMICROARCH enmMicroarch); +VMMR3DECL(int) CPUMR3CpuIdCollectLeaves(PCPUMCPUIDLEAF *ppaLeaves, uint32_t *pcLeaves); +VMMR3DECL(int) CPUMR3CpuIdDetectUnknownLeafMethod(PCPUMUKNOWNCPUID penmUnknownMethod, PCPUMCPUID pDefUnknown); +VMMR3DECL(const char *) CPUMR3CpuIdUnknownLeafMethodName(CPUMUKNOWNCPUID enmUnknownMethod); +VMMR3DECL(CPUMCPUVENDOR) CPUMR3CpuIdDetectVendorEx(uint32_t uEAX, uint32_t uEBX, uint32_t uECX, uint32_t uEDX); +VMMR3DECL(const char *) CPUMR3CpuVendorName(CPUMCPUVENDOR enmVendor); + /** @} */ #endif /* IN_RING3 */ @@ -459,6 +757,12 @@ DECLASM(void) CPUMGCCallGuestTrapHandler(PCPUMCTXCORE pRegFrame, uint3 */ DECLASM(void) CPUMGCCallV86Code(PCPUMCTXCORE pRegFrame); +VMMDECL(int) CPUMHandleLazyFPU(PVMCPU pVCpu); +VMMDECL(uint32_t) CPUMRCGetGuestCPL(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); +#ifdef VBOX_WITH_RAW_RING1 +VMMDECL(void) CPUMRCRecheckRawState(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore); +#endif + /** @} */ #endif /* IN_RC */ @@ -467,18 +771,20 @@ DECLASM(void) CPUMGCCallV86Code(PCPUMCTXCORE pRegFrame); * @ingroup grp_cpum * @{ */ -VMMR0DECL(int) CPUMR0ModuleInit(void); -VMMR0DECL(int) CPUMR0ModuleTerm(void); -VMMR0DECL(int) CPUMR0Init(PVM pVM); -VMMR0DECL(int) CPUMR0LoadGuestFPU(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); -VMMR0DECL(int) CPUMR0SaveGuestFPU(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); -VMMR0DECL(int) CPUMR0SaveGuestDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, bool fDR6); -VMMR0DECL(int) CPUMR0LoadGuestDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, bool fDR6); -VMMR0DECL(int) CPUMR0LoadHostDebugState(PVM pVM, PVMCPU pVCpu); -VMMR0DECL(int) CPUMR0SaveHostDebugState(PVM pVM, PVMCPU pVCpu); -VMMR0DECL(int) CPUMR0LoadHyperDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, bool fDR6); +VMMR0_INT_DECL(int) CPUMR0ModuleInit(void); +VMMR0_INT_DECL(int) CPUMR0ModuleTerm(void); +VMMR0_INT_DECL(int) CPUMR0InitVM(PVM pVM); +VMMR0_INT_DECL(int) CPUMR0Trap07Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); +VMMR0_INT_DECL(int) CPUMR0LoadGuestFPU(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); +VMMR0_INT_DECL(int) CPUMR0SaveGuestFPU(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); +VMMR0_INT_DECL(int) CPUMR0SaveHostDebugState(PVM pVM, PVMCPU pVCpu); +VMMR0_INT_DECL(bool) CPUMR0DebugStateMaybeSaveGuestAndRestoreHost(PVMCPU pVCpu, bool fDr6); +VMMR0_INT_DECL(bool) CPUMR0DebugStateMaybeSaveGuest(PVMCPU pVCpu, bool fDr6); + +VMMR0_INT_DECL(void) CPUMR0LoadGuestDebugState(PVMCPU pVCpu, bool fDr6); +VMMR0_INT_DECL(void) CPUMR0LoadHyperDebugState(PVMCPU pVCpu, bool fDr6); #ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI -VMMR0DECL(void) CPUMR0SetLApic(PVM pVM, RTCPUID idHostCpu); +VMMR0_INT_DECL(void) CPUMR0SetLApic(PVMCPU pVCpu, RTCPUID idHostCpu); #endif /** @} */ diff --git a/include/VBox/vmm/cpum.mac b/include/VBox/vmm/cpum.mac index 8f906d06..48d3eb70 100644 --- a/include/VBox/vmm/cpum.mac +++ b/include/VBox/vmm/cpum.mac @@ -3,7 +3,7 @@ ; ; -; Copyright (C) 2006-2010 Oracle Corporation +; Copyright (C) 2006-2012 Oracle Corporation ; ; This file is part of VirtualBox Open Source Edition (OSE), as ; available from http://www.virtualbox.org. This file is free software; @@ -193,7 +193,8 @@ struc CPUMCTX .msrCSTAR resb 8 .msrSFMASK resb 8 .msrKERNELGSBASE resb 8 - .au32SizePadding resb 32 + .msrApicBase resb 8 + .au32SizePadding resb 24 endstruc @@ -205,3 +206,4 @@ endstruc %endif + diff --git a/include/VBox/vmm/cpumctx.h b/include/VBox/vmm/cpumctx.h index 35861823..c4c9df3b 100644 --- a/include/VBox/vmm/cpumctx.h +++ b/include/VBox/vmm/cpumctx.h @@ -135,7 +135,8 @@ typedef struct CPUMSYSENTER /** * CPU context core. * - * @todo eliminate this structure! + * @todo Eliminate this structure! + * @deprecated We don't push any context cores any more in TRPM. */ #pragma pack(1) typedef struct CPUMCTXCORE @@ -399,10 +400,11 @@ typedef struct CPUMCTX uint64_t msrCSTAR; /**< Compatibility mode syscall rip. */ uint64_t msrSFMASK; /**< syscall flag mask. */ uint64_t msrKERNELGSBASE; /**< swapgs exchange value. */ + uint64_t msrApicBase; /**< The local APIC base (IA32_APIC_BASE MSR). */ /** @} */ /** Size padding. */ - uint32_t au32SizePadding[8]; + uint32_t au32SizePadding[6]; } CPUMCTX; #pragma pack() @@ -414,6 +416,11 @@ typedef struct CPUMCTX # define CPUMCTX2CORE(pCtx) ((PCPUMCTXCORE)(void *)&(pCtx)->rax) /** + * Gets the CPUMCTXCORE part of a CPUMCTX. + */ +# define CPUMCTX_FROM_CORE(a_pCtxCore) RT_FROM_MEMBER(a_pCtxCore, CPUMCTX, rax) + +/** * Gets the first selector register of a CPUMCTX. * * Use this with X86_SREG_COUNT to loop thru the selector registers. @@ -446,6 +453,7 @@ typedef union CPUMCTXMSRS uint64_t MtrrFix4K_E8000; /**< IA32_MTRR_FIX4K_E8000 */ uint64_t MtrrFix4K_F0000; /**< IA32_MTRR_FIX4K_F0000 */ uint64_t MtrrFix4K_F8000; /**< IA32_MTRR_FIX4K_F8000 */ + uint64_t PkgCStateCfgCtrl; /**< MSR_PKG_CST_CONFIG_CONTROL */ } msr; uint64_t au64[64]; } CPUMCTXMSRS; diff --git a/include/VBox/vmm/cpumdis.h b/include/VBox/vmm/cpumdis.h index 9aa509a3..dab556a8 100644 --- a/include/VBox/vmm/cpumdis.h +++ b/include/VBox/vmm/cpumdis.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/vmm/csam.h b/include/VBox/vmm/csam.h index 675cac7f..99a68563 100644 --- a/include/VBox/vmm/csam.h +++ b/include/VBox/vmm/csam.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -28,13 +28,14 @@ #include <VBox/types.h> +#if defined(VBOX_WITH_RAW_MODE) || defined(DOXYGEN_RUNNING) /** @defgroup grp_csam The Code Scanning and Analysis API * @{ */ /** - * CSAM monitoring tag + * CSAM monitoring tag. * For use with CSAMR3MonitorPage */ typedef enum CSAMTAG @@ -51,98 +52,22 @@ RT_C_DECLS_BEGIN /** - * Check if this page needs to be analysed by CSAM. - * - * This function should only be called for supervisor pages and - * only when CSAM is enabled. Leaving these selection criteria - * to the caller simplifies the interface (PTE passing). - * - * Note the the page has not yet been synced, so the TLB trick - * (which wasn't ever active anyway) cannot be applied. - * - * @returns true if the page should be marked not present because - * CSAM want need to scan it. - * @returns false if the page was already scanned. - * @param pVM The VM to operate on. - * @param GCPtr GC pointer of page table entry - */ -VMMDECL(bool) CSAMDoesPageNeedScanning(PVM pVM, RTRCUINTPTR GCPtr); - -/** - * Check if this page was previously scanned by CSAM - * - * @returns true -> scanned, false -> not scanned - * @param pVM The VM to operate on. - * @param pPage GC page address - */ -VMMDECL(bool) CSAMIsPageScanned(PVM pVM, RTRCPTR pPage); - -/** - * Mark a page as scanned/not scanned - * - * @note: we always mark it as scanned, even if we haven't completely done so - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pPage GC page address (not necessarily aligned) - * @param fScanned Mark as scanned or not scanned - * - */ -VMMDECL(int) CSAMMarkPage(PVM pVM, RTRCUINTPTR pPage, bool fScanned); - - -/** - * Remember a possible code page for later inspection - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param GCPtr GC pointer of page - */ -VMMDECL(void) CSAMMarkPossibleCodePage(PVM pVM, RTRCPTR GCPtr); - -/** * Query CSAM state (enabled/disabled) * - * @returns 0 - disabled, 1 - enabled - * @param pVM The VM to operate on. - */ -#define CSAMIsEnabled(pVM) (pVM->fCSAMEnabled && EMIsRawRing0Enabled(pVM)) - -/** - * Turn on code scanning - * - * @returns VBox status code. (trap handled or not) - * @param pVM The VM to operate on. + * @returns true / false. + * @param a_pVM The shared VM handle. + * @internal */ -VMMDECL(int) CSAMEnableScanning(PVM pVM); - -/** - * Turn off code scanning - * - * @returns VBox status code. (trap handled or not) - * @param pVM The VM to operate on. - */ -VMMDECL(int) CSAMDisableScanning(PVM pVM); +#define CSAMIsEnabled(a_pVM) ((a_pVM)->fCSAMEnabled && EMIsRawRing0Enabled(a_pVM)) - -/** - * Check if this page needs to be analysed by CSAM - * - * @returns 0 - disabled, 1 - enabled - * @param pVM The VM to operate on. - * @param pvFault Fault address - */ -VMMDECL(int) CSAMExecFault(PVM pVM, RTRCPTR pvFault); - -/** - * Check if we've scanned this instruction before. If true, then we can emulate - * it instead of returning to ring 3. - * - * @returns boolean - * @param pVM The VM to operate on. - * @param GCPtr GC pointer of page table entry - */ -VMMDECL(bool) CSAMIsKnownDangerousInstr(PVM pVM, RTRCUINTPTR GCPtr); +VMM_INT_DECL(bool) CSAMDoesPageNeedScanning(PVM pVM, RTRCUINTPTR GCPtr); +VMM_INT_DECL(bool) CSAMIsPageScanned(PVM pVM, RTRCPTR pPage); +VMM_INT_DECL(int) CSAMMarkPage(PVM pVM, RTRCUINTPTR pPage, bool fScanned); +VMM_INT_DECL(void) CSAMMarkPossibleCodePage(PVM pVM, RTRCPTR GCPtr); +VMM_INT_DECL(int) CSAMEnableScanning(PVM pVM); +VMM_INT_DECL(int) CSAMDisableScanning(PVM pVM); +VMM_INT_DECL(int) CSAMExecFault(PVM pVM, RTRCPTR pvFault); +VMM_INT_DECL(bool) CSAMIsKnownDangerousInstr(PVM pVM, RTRCUINTPTR GCPtr); #ifdef IN_RING3 @@ -151,149 +76,25 @@ VMMDECL(bool) CSAMIsKnownDangerousInstr(PVM pVM, RTRCUINTPTR GCPtr); * @{ */ -/** - * Query CSAM state (enabled/disabled) - * - * @returns 0 - disabled, 1 - enabled - * @param pVM The VM to operate on. - */ -VMMR3DECL(int) CSAMR3IsEnabled(PVM pVM); +VMMR3DECL(bool) CSAMR3IsEnabled(PUVM pUVM); +VMMR3DECL(int) CSAMR3SetScanningEnabled(PUVM pUVM, bool fEnabled); -/** - * Initializes the csam. - * - * @returns VBox status code. - * @param pVM The VM to operate on. - */ -VMMR3DECL(int) CSAMR3Init(PVM pVM); +VMMR3_INT_DECL(int) CSAMR3Init(PVM pVM); +VMMR3_INT_DECL(void) CSAMR3Relocate(PVM pVM, RTGCINTPTR offDelta); +VMMR3_INT_DECL(int) CSAMR3Term(PVM pVM); +VMMR3_INT_DECL(int) CSAMR3Reset(PVM pVM); -/** - * Applies relocations to data and code managed by this - * component. This function will be called at init and - * whenever the VMM need to relocate it self inside the GC. - * - * The csam will update the addresses used by the switcher. - * - * @param pVM The VM. - * @param offDelta Relocation delta. - */ -VMMR3DECL(void) CSAMR3Relocate(PVM pVM, RTGCINTPTR offDelta); - -/** - * Terminates the csam. - * - * Termination means cleaning up and freeing all resources, - * the VM it self is at this point powered off or suspended. - * - * @returns VBox status code. - * @param pVM The VM to operate on. - */ -VMMR3DECL(int) CSAMR3Term(PVM pVM); - -/** - * CSAM reset callback. - * - * @returns VBox status code. - * @param pVM The VM which is reset. - */ -VMMR3DECL(int) CSAMR3Reset(PVM pVM); +VMMR3_INT_DECL(int) CSAMR3FlushPage(PVM pVM, RTRCPTR addr); +VMMR3_INT_DECL(int) CSAMR3RemovePage(PVM pVM, RTRCPTR addr); +VMMR3_INT_DECL(int) CSAMR3CheckCode(PVM pVM, RTRCPTR pInstrGC); +VMMR3_INT_DECL(int) CSAMR3CheckCodeEx(PVM pVM, PCPUMCTXCORE pCtxCore, RTRCPTR pInstrGC); +VMMR3_INT_DECL(int) CSAMR3MarkCode(PVM pVM, RTRCPTR pInstr, uint32_t cbInstr, bool fScanned); +VMMR3_INT_DECL(int) CSAMR3DoPendingAction(PVM pVM, PVMCPU pVCpu); +VMMR3_INT_DECL(int) CSAMR3CheckGates(PVM pVM, uint32_t iGate, uint32_t cGates); - -/** - * Notify CSAM of a page flush - * - * @returns VBox status code - * @param pVM The VM to operate on. - * @param addr GC address of the page to flush - */ -VMMR3DECL(int) CSAMR3FlushPage(PVM pVM, RTRCPTR addr); - -/** - * Remove a CSAM monitored page. Use with care! - * - * @returns VBox status code - * @param pVM The VM to operate on. - * @param addr GC address of the page to flush - */ -VMMR3DECL(int) CSAMR3RemovePage(PVM pVM, RTRCPTR addr); - -/** - * Scan and analyse code - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pCtxCore CPU context - * @param pInstrGC Instruction pointer - */ -VMMR3DECL(int) CSAMR3CheckCodeEx(PVM pVM, PCPUMCTXCORE pCtxCore, RTRCPTR pInstrGC); - -/** - * Scan and analyse code - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pInstrGC Instruction pointer (0:32 virtual address) - */ -VMMR3DECL(int) CSAMR3CheckCode(PVM pVM, RTRCPTR pInstrGC); - -/** - * Mark an instruction in a page as scanned/not scanned - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pInstr Instruction pointer - * @param cbInstr Instruction size - * @param fScanned Mark as scanned or not - */ -VMMR3DECL(int) CSAMR3MarkCode(PVM pVM, RTRCPTR pInstr, uint32_t cbInstr, bool fScanned); - -/** - * Perform any pending actions - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pVCpu The VMCPU to operate on. - */ -VMMR3DECL(int) CSAMR3DoPendingAction(PVM pVM, PVMCPU pVCpu); - -/** - * Monitors a code page (if not already monitored) - * - * @returns VBox status code - * @param pVM The VM to operate on. - * @param pPageAddrGC The page to monitor - * @param enmTag Monitor tag - */ -VMMR3DECL(int) CSAMR3MonitorPage(PVM pVM, RTRCPTR pPageAddrGC, CSAMTAG enmTag); - -/** - * Unmonitors a code page - * - * @returns VBox status code - * @param pVM The VM to operate on. - * @param pPageAddrGC The page to monitor - * @param enmTag Monitor tag - */ -VMMR3DECL(int) CSAMR3UnmonitorPage(PVM pVM, RTRCPTR pPageAddrGC, CSAMTAG enmTag); - -/** - * Analyse interrupt and trap gates - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param iGate Start gate - * @param cGates Number of gates to check - */ -VMMR3DECL(int) CSAMR3CheckGates(PVM pVM, uint32_t iGate, uint32_t cGates); - -/** - * Record previous call instruction addresses - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param GCPtrCall Call address - */ -VMMR3DECL(int) CSAMR3RecordCallAddress(PVM pVM, RTRCPTR GCPtrCall); +VMMR3DECL(int) CSAMR3MonitorPage(PVM pVM, RTRCPTR pPageAddrGC, CSAMTAG enmTag); +VMMR3DECL(int) CSAMR3UnmonitorPage(PVM pVM, RTRCPTR pPageAddrGC, CSAMTAG enmTag); +VMMR3DECL(int) CSAMR3RecordCallAddress(PVM pVM, RTRCPTR GCPtrCall); /** @} */ #endif @@ -302,4 +103,7 @@ VMMR3DECL(int) CSAMR3RecordCallAddress(PVM pVM, RTRCPTR GCPtrCall); /** @} */ RT_C_DECLS_END +#endif /* VBOX_WITH_RAW_MODE */ + #endif + diff --git a/include/VBox/vmm/dbgf.h b/include/VBox/vmm/dbgf.h index 65bb94c7..9aa4be5b 100644 --- a/include/VBox/vmm/dbgf.h +++ b/include/VBox/vmm/dbgf.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -46,8 +46,8 @@ RT_C_DECLS_BEGIN * @ingroup grp_dbgf * @{ */ -VMMRZDECL(int) DBGFRZTrap01Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCUINTREG uDr6); -VMMRZDECL(int) DBGFRZTrap03Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); +VMMRZ_INT_DECL(int) DBGFRZTrap01Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCUINTREG uDr6, bool fAltStepping); +VMMRZ_INT_DECL(int) DBGFRZTrap03Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); /** @} */ #endif @@ -114,14 +114,14 @@ typedef const DBGFADDRESS *PCDBGFADDRESS; #define DBGFADDRESS_IS_HMA(pAddress) ( !!((pAddress)->fFlags & DBGFADDRESS_FLAGS_HMA) ) /** @} */ -VMMR3DECL(int) DBGFR3AddrFromSelOff(PVM pVM, VMCPUID idCpu, PDBGFADDRESS pAddress, RTSEL Sel, RTUINTPTR off); -VMMR3DECL(int) DBGFR3AddrFromSelInfoOff(PVM pVM, PDBGFADDRESS pAddress, PCDBGFSELINFO pSelInfo, RTUINTPTR off); -VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromFlat(PVM pVM, PDBGFADDRESS pAddress, RTGCUINTPTR FlatPtr); -VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromPhys(PVM pVM, PDBGFADDRESS pAddress, RTGCPHYS PhysAddr); -VMMR3DECL(bool) DBGFR3AddrIsValid(PVM pVM, PCDBGFADDRESS pAddress); -VMMR3DECL(int) DBGFR3AddrToPhys(PVM pVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTGCPHYS pGCPhys); -VMMR3DECL(int) DBGFR3AddrToHostPhys(PVM pVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTHCPHYS pHCPhys); -VMMR3DECL(int) DBGFR3AddrToVolatileR3Ptr(PVM pVM, VMCPUID idCpu, PDBGFADDRESS pAddress, bool fReadOnly, void **ppvR3Ptr); +VMMR3DECL(int) DBGFR3AddrFromSelOff(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, RTSEL Sel, RTUINTPTR off); +VMMR3DECL(int) DBGFR3AddrFromSelInfoOff(PUVM pUVM, PDBGFADDRESS pAddress, PCDBGFSELINFO pSelInfo, RTUINTPTR off); +VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromFlat(PUVM pUVM, PDBGFADDRESS pAddress, RTGCUINTPTR FlatPtr); +VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromPhys(PUVM pUVM, PDBGFADDRESS pAddress, RTGCPHYS PhysAddr); +VMMR3DECL(bool) DBGFR3AddrIsValid(PUVM pUVM, PCDBGFADDRESS pAddress); +VMMR3DECL(int) DBGFR3AddrToPhys(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTGCPHYS pGCPhys); +VMMR3DECL(int) DBGFR3AddrToHostPhys(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTHCPHYS pHCPhys); +VMMR3DECL(int) DBGFR3AddrToVolatileR3Ptr(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, bool fReadOnly, void **ppvR3Ptr); VMMR3DECL(PDBGFADDRESS) DBGFR3AddrAdd(PDBGFADDRESS pAddress, RTGCUINTPTR uAddend); VMMR3DECL(PDBGFADDRESS) DBGFR3AddrSub(PDBGFADDRESS pAddress, RTGCUINTPTR uSubtrahend); @@ -179,10 +179,10 @@ typedef enum DBGFEVENTTYPE * to bring up the debugger at a specific place. */ DBGFEVENT_DEV_STOP, - /** The VM is terminating. + /** The VM is powering off. * When this notification is received, the debugger thread should detach ASAP. */ - DBGFEVENT_TERMINATING, + DBGFEVENT_POWERING_OFF, /** The usual 32-bit hack. */ DBGFEVENT_32BIT_HACK = 0x7fffffff @@ -201,7 +201,7 @@ typedef enum DBGFEVENTCTX /** Recompiled mode. */ DBGFEVENTCTX_REM, /** VMX / AVT mode. */ - DBGFEVENTCTX_HWACCL, + DBGFEVENTCTX_HM, /** Hypervisor context. */ DBGFEVENTCTX_HYPER, /** Other mode */ @@ -281,24 +281,29 @@ typedef const DBGFEVENT *PCDBGFEVENT; # define DBGFSTOP(pVM) VINF_SUCCESS # endif -VMMR3DECL(int) DBGFR3Init(PVM pVM); -VMMR3DECL(int) DBGFR3Term(PVM pVM); -VMMR3DECL(void) DBGFR3Relocate(PVM pVM, RTGCINTPTR offDelta); -VMMR3DECL(int) DBGFR3VMMForcedAction(PVM pVM); -VMMR3DECL(int) DBGFR3Event(PVM pVM, DBGFEVENTTYPE enmEvent); -VMMR3DECL(int) DBGFR3EventSrc(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine, const char *pszFunction, const char *pszFormat, ...); -VMMR3DECL(int) DBGFR3EventSrcV(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine, const char *pszFunction, const char *pszFormat, va_list args); -VMMR3DECL(int) DBGFR3EventAssertion(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszMsg1, const char *pszMsg2); -VMMR3DECL(int) DBGFR3EventBreakpoint(PVM pVM, DBGFEVENTTYPE enmEvent); -VMMR3DECL(int) DBGFR3Attach(PVM pVM); -VMMR3DECL(int) DBGFR3Detach(PVM pVM); -VMMR3DECL(int) DBGFR3EventWait(PVM pVM, RTMSINTERVAL cMillies, PCDBGFEVENT *ppEvent); -VMMR3DECL(int) DBGFR3Halt(PVM pVM); -VMMR3DECL(bool) DBGFR3IsHalted(PVM pVM); -VMMR3DECL(bool) DBGFR3CanWait(PVM pVM); -VMMR3DECL(int) DBGFR3Resume(PVM pVM); -VMMR3DECL(int) DBGFR3Step(PVM pVM, VMCPUID idCpu); -VMMR3DECL(int) DBGFR3PrgStep(PVMCPU pVCpu); +VMMR3_INT_DECL(int) DBGFR3Init(PVM pVM); +VMMR3_INT_DECL(int) DBGFR3Term(PVM pVM); +VMMR3_INT_DECL(void) DBGFR3PowerOff(PVM pVM); +VMMR3_INT_DECL(void) DBGFR3Relocate(PVM pVM, RTGCINTPTR offDelta); +VMMR3_INT_DECL(int) DBGFR3VMMForcedAction(PVM pVM); +VMMR3DECL(int) DBGFR3Event(PVM pVM, DBGFEVENTTYPE enmEvent); +VMMR3DECL(int) DBGFR3EventSrc(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine, + const char *pszFunction, const char *pszFormat, ...); +VMMR3DECL(int) DBGFR3EventSrcV(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine, + const char *pszFunction, const char *pszFormat, va_list args); +VMMR3_INT_DECL(int) DBGFR3EventAssertion(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszMsg1, const char *pszMsg2); +VMMR3_INT_DECL(int) DBGFR3EventBreakpoint(PVM pVM, DBGFEVENTTYPE enmEvent); +VMMR3_INT_DECL(int) DBGFR3PrgStep(PVMCPU pVCpu); + +VMMR3DECL(int) DBGFR3Attach(PUVM pUVM); +VMMR3DECL(int) DBGFR3Detach(PUVM pUVM); +VMMR3DECL(int) DBGFR3EventWait(PUVM pUVM, RTMSINTERVAL cMillies, PCDBGFEVENT *ppEvent); +VMMR3DECL(int) DBGFR3Halt(PUVM pUVM); +VMMR3DECL(bool) DBGFR3IsHalted(PUVM pUVM); +VMMR3DECL(int) DBGFR3QueryWaitable(PUVM pUVM); +VMMR3DECL(int) DBGFR3Resume(PUVM pUVM); +VMMR3DECL(int) DBGFR3Step(PUVM pUVM, VMCPUID idCpu); +VMMR3DECL(int) DBGFR3InjectNMI(PUVM pUVM, VMCPUID idCpu); #endif /* IN_RING3 */ @@ -384,39 +389,44 @@ typedef DBGFBP *PDBGFBP; typedef const DBGFBP *PCDBGFBP; #ifdef IN_RING3 /* The breakpoint management API is only available in ring-3. */ -VMMR3DECL(int) DBGFR3BpSet(PVM pVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp); -VMMR3DECL(int) DBGFR3BpSetReg(PVM pVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, +VMMR3DECL(int) DBGFR3BpSet(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp); +VMMR3DECL(int) DBGFR3BpSetReg(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint8_t fType, uint8_t cb, uint32_t *piBp); -VMMR3DECL(int) DBGFR3BpSetREM(PVM pVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp); -VMMR3DECL(int) DBGFR3BpClear(PVM pVM, uint32_t iBp); -VMMR3DECL(int) DBGFR3BpEnable(PVM pVM, uint32_t iBp); -VMMR3DECL(int) DBGFR3BpDisable(PVM pVM, uint32_t iBp); +VMMR3DECL(int) DBGFR3BpSetREM(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp); +VMMR3DECL(int) DBGFR3BpClear(PUVM pUVM, uint32_t iBp); +VMMR3DECL(int) DBGFR3BpEnable(PUVM pUVM, uint32_t iBp); +VMMR3DECL(int) DBGFR3BpDisable(PUVM pUVM, uint32_t iBp); /** * Breakpoint enumeration callback function. * * @returns VBox status code. Any failure will stop the enumeration. - * @param pVM The VM handle. + * @param pUVM The user mode VM handle. * @param pvUser The user argument. * @param pBp Pointer to the breakpoint information. (readonly) */ -typedef DECLCALLBACK(int) FNDBGFBPENUM(PVM pVM, void *pvUser, PCDBGFBP pBp); +typedef DECLCALLBACK(int) FNDBGFBPENUM(PUVM pUVM, void *pvUser, PCDBGFBP pBp); /** Pointer to a breakpoint enumeration callback function. */ typedef FNDBGFBPENUM *PFNDBGFBPENUM; -VMMR3DECL(int) DBGFR3BpEnum(PVM pVM, PFNDBGFBPENUM pfnCallback, void *pvUser); +VMMR3DECL(int) DBGFR3BpEnum(PUVM pUVM, PFNDBGFBPENUM pfnCallback, void *pvUser); #endif /* IN_RING3 */ -VMMDECL(RTGCUINTREG) DBGFBpGetDR7(PVM pVM); -VMMDECL(RTGCUINTREG) DBGFBpGetDR0(PVM pVM); -VMMDECL(RTGCUINTREG) DBGFBpGetDR1(PVM pVM); -VMMDECL(RTGCUINTREG) DBGFBpGetDR2(PVM pVM); -VMMDECL(RTGCUINTREG) DBGFBpGetDR3(PVM pVM); -VMMDECL(bool) DBGFIsStepping(PVMCPU pVCpu); +VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR7(PVM pVM); +VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR0(PVM pVM); +VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR1(PVM pVM); +VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR2(PVM pVM); +VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR3(PVM pVM); +VMM_INT_DECL(bool) DBGFBpIsHwArmed(PVM pVM); +VMM_INT_DECL(bool) DBGFBpIsHwIoArmed(PVM pVM); +VMM_INT_DECL(bool) DBGFIsStepping(PVMCPU pVCpu); +VMM_INT_DECL(VBOXSTRICTRC) DBGFBpCheckIo(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, RTIOPORT uIoPort, uint8_t cbValue); #ifdef IN_RING3 /* The CPU mode API only works in ring-3. */ -VMMR3DECL(CPUMMODE) DBGFR3CpuGetMode(PVM pVM, VMCPUID idCpu); +VMMR3DECL(CPUMMODE) DBGFR3CpuGetMode(PUVM pUVM, VMCPUID idCpu); +VMMR3DECL(VMCPUID) DBGFR3CpuGetCount(PUVM pUVM); +VMMR3DECL(bool) DBGFR3CpuIsIn64BitCode(PUVM pUVM, VMCPUID idCpu); #endif @@ -510,37 +520,37 @@ typedef FNDBGFHANDLEREXT *PFNDBGFHANDLEREXT; #define DBGFINFO_FLAGS_RUN_ON_EMT RT_BIT(0) /** @} */ -VMMR3DECL(int) DBGFR3InfoRegisterDevice(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler, PPDMDEVINS pDevIns); -VMMR3DECL(int) DBGFR3InfoRegisterDriver(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDRV pfnHandler, PPDMDRVINS pDrvIns); -VMMR3DECL(int) DBGFR3InfoRegisterInternal(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler); -VMMR3DECL(int) DBGFR3InfoRegisterInternalEx(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler, uint32_t fFlags); -VMMR3DECL(int) DBGFR3InfoRegisterExternal(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLEREXT pfnHandler, void *pvUser); -VMMR3DECL(int) DBGFR3InfoDeregisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName); -VMMR3DECL(int) DBGFR3InfoDeregisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName); -VMMR3DECL(int) DBGFR3InfoDeregisterInternal(PVM pVM, const char *pszName); -VMMR3DECL(int) DBGFR3InfoDeregisterExternal(PVM pVM, const char *pszName); -VMMR3DECL(int) DBGFR3Info(PVM pVM, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp); -VMMR3DECL(int) DBGFR3InfoEx(PVM pVM, VMCPUID idCpu, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp); -VMMR3DECL(int) DBGFR3InfoLogRel(PVM pVM, const char *pszName, const char *pszArgs); -VMMR3DECL(int) DBGFR3InfoStdErr(PVM pVM, const char *pszName, const char *pszArgs); -VMMR3DECL(int) DBGFR3InfoMulti(PVM pVM, const char *pszIncludePat, const char *pszExcludePat, - const char *pszSepFmt, PCDBGFINFOHLP pHlp); +VMMR3_INT_DECL(int) DBGFR3InfoRegisterDevice(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler, PPDMDEVINS pDevIns); +VMMR3_INT_DECL(int) DBGFR3InfoRegisterDriver(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDRV pfnHandler, PPDMDRVINS pDrvIns); +VMMR3_INT_DECL(int) DBGFR3InfoRegisterInternal(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler); +VMMR3_INT_DECL(int) DBGFR3InfoRegisterInternalEx(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler, uint32_t fFlags); +VMMR3DECL(int) DBGFR3InfoRegisterExternal(PUVM pUVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLEREXT pfnHandler, void *pvUser); +VMMR3_INT_DECL(int) DBGFR3InfoDeregisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName); +VMMR3_INT_DECL(int) DBGFR3InfoDeregisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName); +VMMR3_INT_DECL(int) DBGFR3InfoDeregisterInternal(PVM pVM, const char *pszName); +VMMR3DECL(int) DBGFR3InfoDeregisterExternal(PUVM pUVM, const char *pszName); +VMMR3DECL(int) DBGFR3Info(PUVM pUVM, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp); +VMMR3DECL(int) DBGFR3InfoEx(PUVM pUVM, VMCPUID idCpu, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp); +VMMR3DECL(int) DBGFR3InfoLogRel(PUVM pUVM, const char *pszName, const char *pszArgs); +VMMR3DECL(int) DBGFR3InfoStdErr(PUVM pUVM, const char *pszName, const char *pszArgs); +VMMR3_INT_DECL(int) DBGFR3InfoMulti(PVM pVM, const char *pszIncludePat, const char *pszExcludePat, + const char *pszSepFmt, PCDBGFINFOHLP pHlp); /** @def DBGFR3InfoLog * Display a piece of info writing to the log if enabled. * - * @param pVM VM handle. - * @param pszName The identifier of the info to display. - * @param pszArgs Arguments to the info handler. + * @param a_pVM The shared VM handle. + * @param a_pszName The identifier of the info to display. + * @param a_pszArgs Arguments to the info handler. */ #ifdef LOG_ENABLED -#define DBGFR3InfoLog(pVM, pszName, pszArgs) \ +# define DBGFR3_INFO_LOG(a_pVM, a_pszName, a_pszArgs) \ do { \ if (LogIsEnabled()) \ - DBGFR3Info(pVM, pszName, pszArgs, NULL); \ + DBGFR3Info((a_pVM)->pUVM, a_pszName, a_pszArgs, NULL); \ } while (0) #else -#define DBGFR3InfoLog(pVM, pszName, pszArgs) do { } while (0) +# define DBGFR3_INFO_LOG(a_pVM, a_pszName, a_pszArgs) do { } while (0) #endif /** @@ -549,15 +559,15 @@ VMMR3DECL(int) DBGFR3InfoMulti(PVM pVM, const char *pszIncludePat, const char *p * @returns VBox status code. * A status code indicating failure will end the enumeration * and DBGFR3InfoEnum will return with that status code. - * @param pVM VM handle. + * @param pUVM The user mode VM handle. * @param pszName Info identifier name. * @param pszDesc The description. */ -typedef DECLCALLBACK(int) FNDBGFINFOENUM(PVM pVM, const char *pszName, const char *pszDesc, void *pvUser); +typedef DECLCALLBACK(int) FNDBGFINFOENUM(PUVM pUVM, const char *pszName, const char *pszDesc, void *pvUser); /** Pointer to a FNDBGFINFOENUM function. */ typedef FNDBGFINFOENUM *PFNDBGFINFOENUM; -VMMR3DECL(int) DBGFR3InfoEnum(PVM pVM, PFNDBGFINFOENUM pfnCallback, void *pvUser); +VMMR3DECL(int) DBGFR3InfoEnum(PUVM pUVM, PFNDBGFINFOENUM pfnCallback, void *pvUser); VMMR3DECL(PCDBGFINFOHLP) DBGFR3InfoLogHlp(void); VMMR3DECL(PCDBGFINFOHLP) DBGFR3InfoLogRelHlp(void); @@ -565,9 +575,9 @@ VMMR3DECL(PCDBGFINFOHLP) DBGFR3InfoLogRelHlp(void); #ifdef IN_RING3 /* The log contrl API only works in ring-3. */ -VMMR3DECL(int) DBGFR3LogModifyGroups(PVM pVM, const char *pszGroupSettings); -VMMR3DECL(int) DBGFR3LogModifyFlags(PVM pVM, const char *pszFlagSettings); -VMMR3DECL(int) DBGFR3LogModifyDestinations(PVM pVM, const char *pszDestSettings); +VMMR3DECL(int) DBGFR3LogModifyGroups(PUVM pUVM, const char *pszGroupSettings); +VMMR3DECL(int) DBGFR3LogModifyFlags(PUVM pUVM, const char *pszFlagSettings); +VMMR3DECL(int) DBGFR3LogModifyDestinations(PUVM pUVM, const char *pszDestSettings); #endif /* IN_RING3 */ #ifdef IN_RING3 /* The debug information management APIs only works in ring-3. */ @@ -650,33 +660,32 @@ typedef const DBGFLINE *PCDBGFLINE; /** @} */ -VMMR3DECL(int) DBGFR3AsAdd(PVM pVM, RTDBGAS hDbgAs, RTPROCESS ProcId); -VMMR3DECL(int) DBGFR3AsDelete(PVM pVM, RTDBGAS hDbgAs); -VMMR3DECL(int) DBGFR3AsSetAlias(PVM pVM, RTDBGAS hAlias, RTDBGAS hAliasFor); -VMMR3DECL(RTDBGAS) DBGFR3AsResolve(PVM pVM, RTDBGAS hAlias); -VMMR3DECL(RTDBGAS) DBGFR3AsResolveAndRetain(PVM pVM, RTDBGAS hAlias); -VMMR3DECL(RTDBGAS) DBGFR3AsQueryByName(PVM pVM, const char *pszName); -VMMR3DECL(RTDBGAS) DBGFR3AsQueryByPid(PVM pVM, RTPROCESS ProcId); - -VMMR3DECL(int) DBGFR3AsLoadImage(PVM pVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags); -VMMR3DECL(int) DBGFR3AsLoadMap(PVM pVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, RTGCUINTPTR uSubtrahend, uint32_t fFlags); -VMMR3DECL(int) DBGFR3AsLinkModule(PVM pVM, RTDBGAS hDbgAs, RTDBGMOD hMod, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags); - -VMMR3DECL(int) DBGFR3AsSymbolByAddr(PVM pVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, PRTGCINTPTR poffDisp, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod); -VMMR3DECL(PRTDBGSYMBOL) DBGFR3AsSymbolByAddrA(PVM pVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, PRTGCINTPTR poffDisp, PRTDBGMOD phMod); -VMMR3DECL(int) DBGFR3AsSymbolByName(PVM pVM, RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod); - -/* The following are soon to be obsoleted: */ -VMMR3DECL(int) DBGFR3ModuleLoad(PVM pVM, const char *pszFilename, RTGCUINTPTR AddressDelta, const char *pszName, RTGCUINTPTR ModuleAddress, unsigned cbImage); -VMMR3DECL(void) DBGFR3ModuleRelocate(PVM pVM, RTGCUINTPTR OldImageBase, RTGCUINTPTR NewImageBase, RTGCUINTPTR cbImage, - const char *pszFilename, const char *pszName); -VMMR3DECL(int) DBGFR3SymbolAdd(PVM pVM, RTGCUINTPTR ModuleAddress, RTGCUINTPTR SymbolAddress, RTUINT cbSymbol, const char *pszSymbol); -VMMR3DECL(int) DBGFR3SymbolByAddr(PVM pVM, RTGCUINTPTR Address, PRTGCINTPTR poffDisplacement, PDBGFSYMBOL pSymbol); -VMMR3DECL(int) DBGFR3SymbolByName(PVM pVM, const char *pszSymbol, PDBGFSYMBOL pSymbol); - -VMMR3DECL(int) DBGFR3LineByAddr(PVM pVM, RTGCUINTPTR Address, PRTGCINTPTR poffDisplacement, PDBGFLINE pLine); -VMMR3DECL(PDBGFLINE) DBGFR3LineByAddrAlloc(PVM pVM, RTGCUINTPTR Address, PRTGCINTPTR poffDisplacement); -VMMR3DECL(void) DBGFR3LineFree(PDBGFLINE pLine); +VMMR3DECL(RTDBGCFG) DBGFR3AsGetConfig(PUVM pUVM); + +VMMR3DECL(int) DBGFR3AsAdd(PUVM pUVM, RTDBGAS hDbgAs, RTPROCESS ProcId); +VMMR3DECL(int) DBGFR3AsDelete(PUVM pUVM, RTDBGAS hDbgAs); +VMMR3DECL(int) DBGFR3AsSetAlias(PUVM pUVM, RTDBGAS hAlias, RTDBGAS hAliasFor); +VMMR3DECL(RTDBGAS) DBGFR3AsResolve(PUVM pUVM, RTDBGAS hAlias); +VMMR3DECL(RTDBGAS) DBGFR3AsResolveAndRetain(PUVM pUVM, RTDBGAS hAlias); +VMMR3DECL(RTDBGAS) DBGFR3AsQueryByName(PUVM pUVM, const char *pszName); +VMMR3DECL(RTDBGAS) DBGFR3AsQueryByPid(PUVM pUVM, RTPROCESS ProcId); + +VMMR3DECL(int) DBGFR3AsLoadImage(PUVM pUVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName, + RTLDRARCH enmArch, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags); +VMMR3DECL(int) DBGFR3AsLoadMap(PUVM pUVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, RTGCUINTPTR uSubtrahend, uint32_t fFlags); +VMMR3DECL(int) DBGFR3AsLinkModule(PUVM pUVM, RTDBGAS hDbgAs, RTDBGMOD hMod, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags); +VMMR3DECL(int) DBGFR3AsUnlinkModuleByName(PUVM pUVM, RTDBGAS hDbgAs, const char *pszModName); + +VMMR3DECL(int) DBGFR3AsSymbolByAddr(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, uint32_t fFlags, + PRTGCINTPTR poffDisp, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod); +VMMR3DECL(PRTDBGSYMBOL) DBGFR3AsSymbolByAddrA(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, uint32_t Flags, + PRTGCINTPTR poffDisp, PRTDBGMOD phMod); +VMMR3DECL(int) DBGFR3AsSymbolByName(PUVM pUVM, RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod); + +VMMR3DECL(int) DBGFR3AsLineByAddr(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, + PRTGCINTPTR poffDisp, PRTDBGLINE pLine, PRTDBGMOD phMod); +VMMR3DECL(PRTDBGLINE) DBGFR3AsLineByAddrA(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, + PRTGCINTPTR poffDisp, PRTDBGMOD phMod); #endif /* IN_RING3 */ @@ -769,7 +778,7 @@ typedef struct DBGFSTACKFRAME /** Pointer to the symbol nearest the program counter (PC). NULL if not found. */ PRTDBGSYMBOL pSymPC; /** Pointer to the linnumber nearest the program counter (PC). NULL if not found. */ - PDBGFLINE pLinePC; + PRTDBGLINE pLinePC; /** The return frame address. * The off member is [e|r]bp and the Sel member is ss. */ @@ -786,7 +795,7 @@ typedef struct DBGFSTACKFRAME /** Pointer to the symbol nearest the return PC. NULL if not found. */ PRTDBGSYMBOL pSymReturnPC; /** Pointer to the linnumber nearest the return PC. NULL if not found. */ - PDBGFLINE pLineReturnPC; + PRTDBGLINE pLineReturnPC; /** 32-bytes of stack arguments. */ union @@ -846,8 +855,9 @@ typedef enum DBGFCODETYPE } DBGFCODETYPE; /** @} */ -VMMR3DECL(int) DBGFR3StackWalkBegin(PVM pVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFSTACKFRAME *ppFirstFrame); -VMMR3DECL(int) DBGFR3StackWalkBeginEx(PVM pVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFADDRESS pAddrFrame, +VMMR3DECL(int) DBGFR3StackWalkBegin(PUVM pUVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, + PCDBGFSTACKFRAME *ppFirstFrame); +VMMR3DECL(int) DBGFR3StackWalkBeginEx(PUVM pUVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFADDRESS pAddrFrame, PCDBGFADDRESS pAddrStack,PCDBGFADDRESS pAddrPC, DBGFRETURNTYPE enmReturnType, PCDBGFSTACKFRAME *ppFirstFrame); VMMR3DECL(PCDBGFSTACKFRAME) DBGFR3StackWalkNext(PCDBGFSTACKFRAME pCurrent); @@ -872,6 +882,12 @@ VMMR3DECL(void) DBGFR3StackWalkEnd(PCDBGFSTACKFRAME pFirstFrame); #define DBGF_DISAS_FLAGS_NO_BYTES RT_BIT(4) /** No address in the output. */ #define DBGF_DISAS_FLAGS_NO_ADDRESS RT_BIT(5) +/** Probably a hypervisor instruction. */ +#define DBGF_DISAS_FLAGS_HYPER RT_BIT(6) +/** Disassemble original unpatched bytes (PATM). */ +#define DBGF_DISAS_FLAGS_UNPATCHED_BYTES RT_BIT(7) +/** Annotate patched instructions. */ +#define DBGF_DISAS_FLAGS_ANNOTATE_PATCHED RT_BIT(8) /** Disassemble in the default mode of the specific context. */ #define DBGF_DISAS_FLAGS_DEFAULT_MODE UINT32_C(0x00000000) /** Disassemble in 16-bit mode. */ @@ -885,29 +901,29 @@ VMMR3DECL(void) DBGFR3StackWalkEnd(PCDBGFSTACKFRAME pFirstFrame); /** The disassembly mode mask. */ #define DBGF_DISAS_FLAGS_MODE_MASK UINT32_C(0x70000000) /** Mask containing the valid flags. */ -#define DBGF_DISAS_FLAGS_VALID_MASK UINT32_C(0x7000007f) +#define DBGF_DISAS_FLAGS_VALID_MASK UINT32_C(0x700001ff) /** @} */ /** Special flat selector. */ #define DBGF_SEL_FLAT 1 -VMMR3DECL(int) DBGFR3DisasInstrEx(PVM pVM, VMCPUID idCpu, RTSEL Sel, RTGCPTR GCPtr, uint32_t fFlags, - char *pszOutput, uint32_t cbOutput, uint32_t *pcbInstr); -VMMR3DECL(int) DBGFR3DisasInstrCurrent(PVMCPU pVCpu, char *pszOutput, uint32_t cbOutput); -VMMR3DECL(int) DBGFR3DisasInstrCurrentLogInternal(PVMCPU pVCpu, const char *pszPrefix); +VMMR3DECL(int) DBGFR3DisasInstrEx(PUVM pUVM, VMCPUID idCpu, RTSEL Sel, RTGCPTR GCPtr, uint32_t fFlags, + char *pszOutput, uint32_t cbOutput, uint32_t *pcbInstr); +VMMR3_INT_DECL(int) DBGFR3DisasInstrCurrent(PVMCPU pVCpu, char *pszOutput, uint32_t cbOutput); +VMMR3DECL(int) DBGFR3DisasInstrCurrentLogInternal(PVMCPU pVCpu, const char *pszPrefix); /** @def DBGFR3DisasInstrCurrentLog * Disassembles the current guest context instruction and writes it to the log. * All registers and data will be displayed. Addresses will be attempted resolved to symbols. */ #ifdef LOG_ENABLED -# define DBGFR3DisasInstrCurrentLog(pVCpu, pszPrefix) \ +# define DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, pszPrefix) \ do { \ if (LogIsEnabled()) \ DBGFR3DisasInstrCurrentLogInternal(pVCpu, pszPrefix); \ } while (0) #else -# define DBGFR3DisasInstrCurrentLog(pVCpu, pszPrefix) do { } while (0) +# define DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, pszPrefix) do { } while (0) #endif VMMR3DECL(int) DBGFR3DisasInstrLogInternal(PVMCPU pVCpu, RTSEL Sel, RTGCPTR GCPtr, const char *pszPrefix); @@ -918,23 +934,23 @@ VMMR3DECL(int) DBGFR3DisasInstrLogInternal(PVMCPU pVCpu, RTSEL Sel, RTGCPTR GCPt * @thread Any EMT. */ # ifdef LOG_ENABLED -# define DBGFR3DisasInstrLog(pVCpu, Sel, GCPtr, pszPrefix) \ +# define DBGFR3_DISAS_INSTR_LOG(pVCpu, Sel, GCPtr, pszPrefix) \ do { \ if (LogIsEnabled()) \ DBGFR3DisasInstrLogInternal(pVCpu, Sel, GCPtr, pszPrefix); \ } while (0) # else -# define DBGFR3DisasInstrLog(pVCpu, Sel, GCPtr, pszPrefix) do { } while (0) +# define DBGFR3_DISAS_INSTR_LOG(pVCpu, Sel, GCPtr, pszPrefix) do { } while (0) # endif #endif #ifdef IN_RING3 -VMMR3DECL(int) DBGFR3MemScan(PVM pVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, RTGCUINTPTR cbRange, RTGCUINTPTR uAlign, +VMMR3DECL(int) DBGFR3MemScan(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, RTGCUINTPTR cbRange, RTGCUINTPTR uAlign, const void *pvNeedle, size_t cbNeedle, PDBGFADDRESS pHitAddress); -VMMR3DECL(int) DBGFR3MemRead(PVM pVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void *pvBuf, size_t cbRead); -VMMR3DECL(int) DBGFR3MemReadString(PVM pVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, char *pszBuf, size_t cbBuf); -VMMR3DECL(int) DBGFR3MemWrite(PVM pVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void const *pvBuf, size_t cbRead); +VMMR3DECL(int) DBGFR3MemRead(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void *pvBuf, size_t cbRead); +VMMR3DECL(int) DBGFR3MemReadString(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, char *pszBuf, size_t cbBuf); +VMMR3DECL(int) DBGFR3MemWrite(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void const *pvBuf, size_t cbRead); #endif @@ -979,7 +995,7 @@ VMMR3DECL(int) DBGFR3MemWrite(PVM pVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, vo /** The mask of bits controlling the paging mode. */ #define DBGFPGDMP_FLAGS_MODE_MASK UINT32_C(0x00000f32) /** @} */ -VMMDECL(int) DBGFR3PagingDumpEx(PVM pVM, VMCPUID idCpu, uint32_t fFlags, uint64_t cr3, uint64_t u64FirstAddr, +VMMDECL(int) DBGFR3PagingDumpEx(PUVM pUVM, VMCPUID idCpu, uint32_t fFlags, uint64_t cr3, uint64_t u64FirstAddr, uint64_t u64LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp); @@ -993,7 +1009,7 @@ VMMDECL(int) DBGFR3PagingDumpEx(PVM pVM, VMCPUID idCpu, uint32_t fFlags, uint64_ /** If currently executing in in 64-bit mode, blow up data selectors. */ #define DBGFSELQI_FLAGS_DT_ADJ_64BIT_MODE UINT32_C(2) /** @} */ -VMMR3DECL(int) DBGFR3SelQueryInfo(PVM pVM, VMCPUID idCpu, RTSEL Sel, uint32_t fFlags, PDBGFSELINFO pSelInfo); +VMMR3DECL(int) DBGFR3SelQueryInfo(PUVM pUVM, VMCPUID idCpu, RTSEL Sel, uint32_t fFlags, PDBGFSELINFO pSelInfo); /** @@ -1269,6 +1285,11 @@ typedef DBGFREGVALTYPE *PDBGFREGVALTYPE; */ typedef union DBGFREGVAL { + uint64_t au64[2]; /**< The 64-bit array view. First because of the initializer. */ + uint32_t au32[4]; /**< The 32-bit array view. */ + uint16_t au16[8]; /**< The 16-bit array view. */ + uint8_t au8[16]; /**< The 8-bit array view. */ + uint8_t u8; /**< The 8-bit view. */ uint16_t u16; /**< The 16-bit view. */ uint32_t u32; /**< The 32-bit view. */ @@ -1285,10 +1306,6 @@ typedef union DBGFREGVAL uint32_t u32Limit; } dtr; - uint8_t au8[16]; /**< The 8-bit array view. */ - uint16_t au16[8]; /**< The 16-bit array view. */ - uint32_t au32[4]; /**< The 32-bit array view. */ - uint64_t au64[2]; /**< The 64-bit array view. */ RTUINT128U u; } DBGFREGVAL; /** Pointer to a generic register value type. */ @@ -1296,6 +1313,12 @@ typedef DBGFREGVAL *PDBGFREGVAL; /** Pointer to a const generic register value type. */ typedef DBGFREGVAL const *PCDBGFREGVAL; +/** Initialize a DBGFREGVAL variable to all zeros. */ +#define DBGFREGVAL_INITIALIZE_ZERO { { 0, 0 } } +/** Initialize a DBGFREGVAL variable to all bits set . */ +#define DBGFREGVAL_INITIALIZE_FFFF { { UINT64_MAX, UINT64_MAX } } + + VMMDECL(ssize_t) DBGFR3RegFormatValue(char *pszBuf, size_t cbBuf, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType, bool fSpecial); VMMDECL(ssize_t) DBGFR3RegFormatValueEx(char *pszBuf, size_t cbBuf, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType, unsigned uBase, signed int cchWidth, signed int cchPrecision, uint32_t fFlags); @@ -1316,9 +1339,13 @@ typedef struct DBGFREGSUBFIELD int8_t cShift; /** Sub-field flags, DBGFREGSUBFIELD_FLAGS_XXX. */ uint8_t fFlags; - /** Getter (optional). */ + /** Getter (optional). + * @remarks Does not take the device lock or anything like that. + */ DECLCALLBACKMEMBER(int, pfnGet)(void *pvUser, struct DBGFREGSUBFIELD const *pSubField, PRTUINT128U puValue); - /** Setter (optional). */ + /** Setter (optional). + * @remarks Does not take the device lock or anything like that. + */ DECLCALLBACKMEMBER(int, pfnSet)(void *pvUser, struct DBGFREGSUBFIELD const *pSubField, RTUINT128U uValue, RTUINT128U fMask); } DBGFREGSUBFIELD; /** Pointer to a const register sub-field descriptor. */ @@ -1336,6 +1363,9 @@ typedef DBGFREGSUBFIELD const *PCDBGFREGSUBFIELD; /** Macro for creating a read-write sub-field entry with getters. */ #define DBGFREGSUBFIELD_RW_SG(a_szName, a_cBits, a_cShift, a_pfnGet, a_pfnSet) \ { a_szName, 0 /*iFirstBit*/, a_cBits, a_cShift, 0 /*fFlags*/, a_pfnGet, a_pfnSet } +/** Macro for creating a read-only sub-field entry without getters. */ +#define DBGFREGSUBFIELD_RO(a_szName, a_iFirstBit, a_cBits, a_cShift) \ + { a_szName, a_iFirstBit, a_cBits, a_cShift, DBGFREGSUBFIELD_FLAGS_READ_ONLY, NULL /*pfnGet*/, NULL /*pfnSet*/ } /** Macro for creating a terminator sub-field entry. */ #define DBGFREGSUBFIELD_TERMINATOR() \ { NULL, 0, 0, 0, 0, NULL, NULL } @@ -1370,9 +1400,13 @@ typedef struct DBGFREGDESC * For CPU registers this is the offset into the CPUMCTX structure, * thuse the 'off' prefix. */ uint32_t offRegister; - /** Getter. */ + /** Getter. + * @remarks Does not take the device lock or anything like that. + */ DECLCALLBACKMEMBER(int, pfnGet)(void *pvUser, struct DBGFREGDESC const *pDesc, PDBGFREGVAL pValue); - /** Setter. */ + /** Setter. + * @remarks Does not take the device lock or anything like that. + */ DECLCALLBACKMEMBER(int, pfnSet)(void *pvUser, struct DBGFREGDESC const *pDesc, PCDBGFREGVAL pValue, PCDBGFREGVAL pfMask); /** Aliases (optional). */ PCDBGFREGALIAS paAliases; @@ -1430,30 +1464,31 @@ typedef DBGFREGENTRY const *PCDBGFREGENTRY; * guest. */ #define DBGFREG_HYPER_VMCPUID UINT32_C(0x01000000) -VMMR3DECL(int) DBGFR3RegCpuQueryU8( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t *pu8); -VMMR3DECL(int) DBGFR3RegCpuQueryU16( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t *pu16); -VMMR3DECL(int) DBGFR3RegCpuQueryU32( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t *pu32); -VMMR3DECL(int) DBGFR3RegCpuQueryU64( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64); -VMMR3DECL(int) DBGFR3RegCpuQueryU128(PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint128_t *pu128); -VMMR3DECL(int) DBGFR3RegCpuQueryLrd( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, long double *plrd); -VMMR3DECL(int) DBGFR3RegCpuQueryXdtr(PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64Base, uint16_t *pu16Limit); +VMMR3DECL(int) DBGFR3RegCpuQueryU8( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t *pu8); +VMMR3DECL(int) DBGFR3RegCpuQueryU16( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t *pu16); +VMMR3DECL(int) DBGFR3RegCpuQueryU32( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t *pu32); +VMMR3DECL(int) DBGFR3RegCpuQueryU64( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64); +VMMR3DECL(int) DBGFR3RegCpuQueryU128(PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint128_t *pu128); +VMMR3DECL(int) DBGFR3RegCpuQueryLrd( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, long double *plrd); +VMMR3DECL(int) DBGFR3RegCpuQueryXdtr(PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64Base, uint16_t *pu16Limit); #if 0 -VMMR3DECL(int) DBGFR3RegCpuQueryBatch(PVM pVM,VMCPUID idCpu, PDBGFREGENTRY paRegs, size_t cRegs); -VMMR3DECL(int) DBGFR3RegCpuQueryAll( PVM pVM, VMCPUID idCpu, PDBGFREGENTRY paRegs, size_t cRegs); - -VMMR3DECL(int) DBGFR3RegCpuSetU8( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t u8); -VMMR3DECL(int) DBGFR3RegCpuSetU16( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t u16); -VMMR3DECL(int) DBGFR3RegCpuSetU32( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t u32); -VMMR3DECL(int) DBGFR3RegCpuSetU64( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t u64); -VMMR3DECL(int) DBGFR3RegCpuSetU128( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint128_t u128); -VMMR3DECL(int) DBGFR3RegCpuSetLrd( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, long double lrd); -VMMR3DECL(int) DBGFR3RegCpuSetBatch( PVM pVM, VMCPUID idCpu, PCDBGFREGENTRY paRegs, size_t cRegs); +VMMR3DECL(int) DBGFR3RegCpuQueryBatch(PUVM pUVM,VMCPUID idCpu, PDBGFREGENTRY paRegs, size_t cRegs); +VMMR3DECL(int) DBGFR3RegCpuQueryAll( PUVM pUVM, VMCPUID idCpu, PDBGFREGENTRY paRegs, size_t cRegs); + +VMMR3DECL(int) DBGFR3RegCpuSetU8( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t u8); +VMMR3DECL(int) DBGFR3RegCpuSetU16( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t u16); +VMMR3DECL(int) DBGFR3RegCpuSetU32( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t u32); +VMMR3DECL(int) DBGFR3RegCpuSetU64( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t u64); +VMMR3DECL(int) DBGFR3RegCpuSetU128( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint128_t u128); +VMMR3DECL(int) DBGFR3RegCpuSetLrd( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, long double lrd); +VMMR3DECL(int) DBGFR3RegCpuSetBatch( PUVM pUVM, VMCPUID idCpu, PCDBGFREGENTRY paRegs, size_t cRegs); #endif -VMMR3DECL(const char *) DBGFR3RegCpuName(PVM pVM, DBGFREG enmReg, DBGFREGVALTYPE enmType); +VMMR3DECL(const char *) DBGFR3RegCpuName(PUVM pUVM, DBGFREG enmReg, DBGFREGVALTYPE enmType); VMMR3_INT_DECL(int) DBGFR3RegRegisterCpu(PVM pVM, PVMCPU pVCpu, PCDBGFREGDESC paRegisters, bool fGuestRegs); -VMMR3DECL(int) DBGFR3RegRegisterDevice(PVM pVM, PCDBGFREGDESC paRegisters, PPDMDEVINS pDevIns, const char *pszPrefix, uint32_t iInstance); +VMMR3_INT_DECL(int) DBGFR3RegRegisterDevice(PVM pVM, PCDBGFREGDESC paRegisters, PPDMDEVINS pDevIns, + const char *pszPrefix, uint32_t iInstance); /** * Entry in a named batch query or set operation. @@ -1472,33 +1507,33 @@ typedef DBGFREGENTRYNM *PDBGFREGENTRYNM; /** Pointer to a const named register entry in a batch operation. */ typedef DBGFREGENTRYNM const *PCDBGFREGENTRYNM; -VMMR3DECL(int) DBGFR3RegNmValidate( PVM pVM, VMCPUID idDefCpu, const char *pszReg); - -VMMR3DECL(int) DBGFR3RegNmQuery( PVM pVM, VMCPUID idDefCpu, const char *pszReg, PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType); -VMMR3DECL(int) DBGFR3RegNmQueryU8( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint8_t *pu8); -VMMR3DECL(int) DBGFR3RegNmQueryU16( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint16_t *pu16); -VMMR3DECL(int) DBGFR3RegNmQueryU32( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint32_t *pu32); -VMMR3DECL(int) DBGFR3RegNmQueryU64( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64); -VMMR3DECL(int) DBGFR3RegNmQueryU128(PVM pVM, VMCPUID idDefCpu, const char *pszReg, PRTUINT128U pu128); -/*VMMR3DECL(int) DBGFR3RegNmQueryLrd( PVM pVM, VMCPUID idDefCpu, const char *pszReg, long double *plrd);*/ -VMMR3DECL(int) DBGFR3RegNmQueryXdtr(PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64Base, uint16_t *pu16Limit); -VMMR3DECL(int) DBGFR3RegNmQueryBatch(PVM pVM,VMCPUID idDefCpu, PDBGFREGENTRYNM paRegs, size_t cRegs); -VMMR3DECL(int) DBGFR3RegNmQueryAllCount(PVM pVM, size_t *pcRegs); -VMMR3DECL(int) DBGFR3RegNmQueryAll( PVM pVM, PDBGFREGENTRYNM paRegs, size_t cRegs); - -VMMR3DECL(int) DBGFR3RegNmSet( PVM pVM, VMCPUID idDefCpu, const char *pszReg, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType); -VMMR3DECL(int) DBGFR3RegNmSetU8( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint8_t u8); -VMMR3DECL(int) DBGFR3RegNmSetU16( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint16_t u16); -VMMR3DECL(int) DBGFR3RegNmSetU32( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint32_t u32); -VMMR3DECL(int) DBGFR3RegNmSetU64( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint64_t u64); -VMMR3DECL(int) DBGFR3RegNmSetU128( PVM pVM, VMCPUID idDefCpu, const char *pszReg, RTUINT128U u128); -VMMR3DECL(int) DBGFR3RegNmSetLrd( PVM pVM, VMCPUID idDefCpu, const char *pszReg, long double lrd); -VMMR3DECL(int) DBGFR3RegNmSetBatch( PVM pVM, VMCPUID idDefCpu, PCDBGFREGENTRYNM paRegs, size_t cRegs); +VMMR3DECL(int) DBGFR3RegNmValidate( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg); + +VMMR3DECL(int) DBGFR3RegNmQuery( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType); +VMMR3DECL(int) DBGFR3RegNmQueryU8( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint8_t *pu8); +VMMR3DECL(int) DBGFR3RegNmQueryU16( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint16_t *pu16); +VMMR3DECL(int) DBGFR3RegNmQueryU32( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint32_t *pu32); +VMMR3DECL(int) DBGFR3RegNmQueryU64( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64); +VMMR3DECL(int) DBGFR3RegNmQueryU128(PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PRTUINT128U pu128); +/*VMMR3DECL(int) DBGFR3RegNmQueryLrd( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, long double *plrd);*/ +VMMR3DECL(int) DBGFR3RegNmQueryXdtr(PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64Base, uint16_t *pu16Limit); +VMMR3DECL(int) DBGFR3RegNmQueryBatch(PUVM pUVM,VMCPUID idDefCpu, PDBGFREGENTRYNM paRegs, size_t cRegs); +VMMR3DECL(int) DBGFR3RegNmQueryAllCount(PUVM pUVM, size_t *pcRegs); +VMMR3DECL(int) DBGFR3RegNmQueryAll( PUVM pUVM, PDBGFREGENTRYNM paRegs, size_t cRegs); + +VMMR3DECL(int) DBGFR3RegNmSet( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType); +VMMR3DECL(int) DBGFR3RegNmSetU8( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint8_t u8); +VMMR3DECL(int) DBGFR3RegNmSetU16( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint16_t u16); +VMMR3DECL(int) DBGFR3RegNmSetU32( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint32_t u32); +VMMR3DECL(int) DBGFR3RegNmSetU64( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint64_t u64); +VMMR3DECL(int) DBGFR3RegNmSetU128( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, RTUINT128U u128); +VMMR3DECL(int) DBGFR3RegNmSetLrd( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, long double lrd); +VMMR3DECL(int) DBGFR3RegNmSetBatch( PUVM pUVM, VMCPUID idDefCpu, PCDBGFREGENTRYNM paRegs, size_t cRegs); /** @todo add enumeration methods. */ -VMMR3DECL(int) DBGFR3RegPrintf( PVM pVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, ...); -VMMR3DECL(int) DBGFR3RegPrintfV(PVM pVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, va_list va); +VMMR3DECL(int) DBGFR3RegPrintf( PUVM pUVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, ...); +VMMR3DECL(int) DBGFR3RegPrintfV(PUVM pUVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, va_list va); /** @@ -1546,18 +1581,18 @@ typedef struct DBGFOSREG * Constructs the instance. * * @returns VBox status code. - * @param pVM Pointer to the shared VM structure. + * @param pUVM The user mode VM handle. * @param pvData Pointer to the instance data. */ - DECLCALLBACKMEMBER(int, pfnConstruct)(PVM pVM, void *pvData); + DECLCALLBACKMEMBER(int, pfnConstruct)(PUVM pUVM, void *pvData); /** * Destroys the instance. * - * @param pVM Pointer to the shared VM structure. + * @param pUVM The user mode VM handle. * @param pvData Pointer to the instance data. */ - DECLCALLBACKMEMBER(void, pfnDestruct)(PVM pVM, void *pvData); + DECLCALLBACKMEMBER(void, pfnDestruct)(PUVM pUVM, void *pvData); /** * Probes the guest memory for OS finger prints. @@ -1566,10 +1601,10 @@ typedef struct DBGFOSREG * or pfnRefresh that should take care of that. * * @returns true if is an OS handled by this module, otherwise false. - * @param pVM Pointer to the shared VM structure. + * @param pUVM The user mode VM handle. * @param pvData Pointer to the instance data. */ - DECLCALLBACKMEMBER(bool, pfnProbe)(PVM pVM, void *pvData); + DECLCALLBACKMEMBER(bool, pfnProbe)(PUVM pUVM, void *pvData); /** * Initializes a fresly detected guest, loading symbols and such useful stuff. @@ -1577,10 +1612,10 @@ typedef struct DBGFOSREG * This is called after pfnProbe. * * @returns VBox status code. - * @param pVM Pointer to the shared VM structure. + * @param pUVM The user mode VM handle. * @param pvData Pointer to the instance data. */ - DECLCALLBACKMEMBER(int, pfnInit)(PVM pVM, void *pvData); + DECLCALLBACKMEMBER(int, pfnInit)(PUVM pUVM, void *pvData); /** * Refreshes symbols and stuff following a redetection of the same OS. @@ -1588,10 +1623,10 @@ typedef struct DBGFOSREG * This is called after pfnProbe. * * @returns VBox status code. - * @param pVM Pointer to the shared VM structure. + * @param pUVM The user mode VM handle. * @param pvData Pointer to the instance data. */ - DECLCALLBACKMEMBER(int, pfnRefresh)(PVM pVM, void *pvData); + DECLCALLBACKMEMBER(int, pfnRefresh)(PUVM pUVM, void *pvData); /** * Terminates an OS when a new (or none) OS has been detected, @@ -1599,10 +1634,10 @@ typedef struct DBGFOSREG * * This is called after pfnProbe and if needed before pfnDestruct. * - * @param pVM Pointer to the shared VM structure. + * @param pUVM The user mode VM handle. * @param pvData Pointer to the instance data. */ - DECLCALLBACKMEMBER(void, pfnTerm)(PVM pVM, void *pvData); + DECLCALLBACKMEMBER(void, pfnTerm)(PUVM pUVM, void *pvData); /** * Queries the version of the running OS. @@ -1610,12 +1645,12 @@ typedef struct DBGFOSREG * This is only called after pfnInit(). * * @returns VBox status code. - * @param pVM Pointer to the shared VM structure. + * @param pUVM The user mode VM handle. * @param pvData Pointer to the instance data. * @param pszVersion Where to store the version string. * @param cchVersion The size of the version string buffer. */ - DECLCALLBACKMEMBER(int, pfnQueryVersion)(PVM pVM, void *pvData, char *pszVersion, size_t cchVersion); + DECLCALLBACKMEMBER(int, pfnQueryVersion)(PUVM pUVM, void *pvData, char *pszVersion, size_t cchVersion); /** * Queries the pointer to a interface. @@ -1623,11 +1658,11 @@ typedef struct DBGFOSREG * This is called after pfnProbe. * * @returns Pointer to the interface if available, NULL if not available. - * @param pVM Pointer to the shared VM structure. + * @param pUVM The user mode VM handle. * @param pvData Pointer to the instance data. * @param enmIf The interface identifier. */ - DECLCALLBACKMEMBER(void *, pfnQueryInterface)(PVM pVM, void *pvData, DBGFOSINTERFACE enmIf); + DECLCALLBACKMEMBER(void *, pfnQueryInterface)(PUVM pUVM, void *pvData, DBGFOSINTERFACE enmIf); /** Trailing magic (DBGFOSREG_MAGIC). */ uint32_t u32EndMagic; @@ -1640,14 +1675,14 @@ typedef DBGFOSREG const *PCDBGFOSREG; /** Magic value for DBGFOSREG::u32Magic and DBGFOSREG::u32EndMagic. (Hitomi Kanehara) */ #define DBGFOSREG_MAGIC 0x19830808 -VMMR3DECL(int) DBGFR3OSRegister(PVM pVM, PCDBGFOSREG pReg); -VMMR3DECL(int) DBGFR3OSDeregister(PVM pVM, PCDBGFOSREG pReg); -VMMR3DECL(int) DBGFR3OSDetect(PVM pVM, char *pszName, size_t cchName); -VMMR3DECL(int) DBGFR3OSQueryNameAndVersion(PVM pVM, char *pszName, size_t cchName, char *pszVersion, size_t cchVersion); -VMMR3DECL(void *) DBGFR3OSQueryInterface(PVM pVM, DBGFOSINTERFACE enmIf); +VMMR3DECL(int) DBGFR3OSRegister(PUVM pUVM, PCDBGFOSREG pReg); +VMMR3DECL(int) DBGFR3OSDeregister(PUVM pUVM, PCDBGFOSREG pReg); +VMMR3DECL(int) DBGFR3OSDetect(PUVM pUVM, char *pszName, size_t cchName); +VMMR3DECL(int) DBGFR3OSQueryNameAndVersion(PUVM pUVM, char *pszName, size_t cchName, char *pszVersion, size_t cchVersion); +VMMR3DECL(void *) DBGFR3OSQueryInterface(PUVM pUVM, DBGFOSINTERFACE enmIf); -VMMR3DECL(int) DBGFR3CoreWrite(PVM pVM, const char *pszFilename, bool fReplaceFile); +VMMR3DECL(int) DBGFR3CoreWrite(PUVM pUVM, const char *pszFilename, bool fReplaceFile); /** @} */ diff --git a/include/VBox/vmm/dbgfsel.h b/include/VBox/vmm/dbgfsel.h index 708666bf..2be4ee84 100644 --- a/include/VBox/vmm/dbgfsel.h +++ b/include/VBox/vmm/dbgfsel.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/vmm/em.h b/include/VBox/vmm/em.h index a0efe5fc..d492ecf4 100644 --- a/include/VBox/vmm/em.h +++ b/include/VBox/vmm/em.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -51,9 +51,9 @@ typedef enum EMSTATE /** Raw-mode execution. */ EMSTATE_RAW, /** Hardware accelerated raw-mode execution. */ - EMSTATE_HWACC, - /** Value reserved for future use (used to be PARAV). */ - EMSTATE_RESERVED, + EMSTATE_HM, + /** Executing in IEM. */ + EMSTATE_IEM, /** Recompiled mode execution. */ EMSTATE_REM, /** Execution is halted. (waiting for interrupt) */ @@ -67,13 +67,18 @@ typedef enum EMSTATE /** Guest debug event from raw-mode is being processed. */ EMSTATE_DEBUG_GUEST_RAW, /** Guest debug event from hardware accelerated mode is being processed. */ - EMSTATE_DEBUG_GUEST_HWACC, + EMSTATE_DEBUG_GUEST_HM, + /** Guest debug event from interpreted execution mode is being processed. */ + EMSTATE_DEBUG_GUEST_IEM, /** Guest debug event from recompiled-mode is being processed. */ EMSTATE_DEBUG_GUEST_REM, /** Hypervisor debug event being processed. */ EMSTATE_DEBUG_HYPER, /** The VM has encountered a fatal error. (And everyone is panicing....) */ EMSTATE_GURU_MEDITATION, + /** Executing in IEM, falling back on REM if we cannot switch back to HM or + * RAW after a short while. */ + EMSTATE_IEM_THEN_REM, /** Just a hack to ensure that we get a 32-bit integer. */ EMSTATE_MAKE_32BIT_HACK = 0x7fffffff } EMSTATE; @@ -94,8 +99,8 @@ typedef enum EMCODETYPE_32BIT_HACK = 0x7fffffff } EMCODETYPE; -VMMDECL(EMSTATE) EMGetState(PVMCPU pVCpu); -VMMDECL(void) EMSetState(PVMCPU pVCpu, EMSTATE enmNewState); +VMM_INT_DECL(EMSTATE) EMGetState(PVMCPU pVCpu); +VMM_INT_DECL(void) EMSetState(PVMCPU pVCpu, EMSTATE enmNewState); /** @name Callback handlers for instruction emulation functions. * These are placed here because IOM wants to use them as well. @@ -121,7 +126,7 @@ typedef FNEMULATELOCKPARAM3 *PFNEMULATELOCKPARAM3; * @returns false if disabled. * @param pVM The VM to operate on. */ -#define EMIsRawRing3Enabled(pVM) (!(pVM)->fRecompileUser) +#define EMIsRawRing3Enabled(pVM) (!(pVM)->fRecompileUser) /** * Checks if raw ring-0 execute mode is enabled. @@ -130,7 +135,20 @@ typedef FNEMULATELOCKPARAM3 *PFNEMULATELOCKPARAM3; * @returns false if disabled. * @param pVM The VM to operate on. */ -#define EMIsRawRing0Enabled(pVM) (!(pVM)->fRecompileSupervisor) +#define EMIsRawRing0Enabled(pVM) (!(pVM)->fRecompileSupervisor) + +#ifdef VBOX_WITH_RAW_RING1 +/** + * Checks if raw ring-1 execute mode is enabled. + * + * @returns true if enabled. + * @returns false if disabled. + * @param pVM The VM to operate on. + */ +# define EMIsRawRing1Enabled(pVM) ((pVM)->fRawRing1Enabled) +#else +# define EMIsRawRing1Enabled(pVM) false +#endif /** * Checks if execution with hardware assisted virtualization is enabled. @@ -139,7 +157,7 @@ typedef FNEMULATELOCKPARAM3 *PFNEMULATELOCKPARAM3; * @returns false if disabled. * @param pVM The VM to operate on. */ -#define EMIsHwVirtExecutionEnabled(pVM) (!(pVM)->fRecompileSupervisor && !(pVM)->fRecompileUser) +#define EMIsHwVirtExecutionEnabled(pVM) (!(pVM)->fRecompileSupervisor && !(pVM)->fRecompileUser) /** * Checks if execution of supervisor code should be done in the @@ -151,39 +169,39 @@ typedef FNEMULATELOCKPARAM3 *PFNEMULATELOCKPARAM3; */ #define EMIsSupervisorCodeRecompiled(pVM) ((pVM)->fRecompileSupervisor) -VMMDECL(void) EMSetInhibitInterruptsPC(PVMCPU pVCpu, RTGCUINTPTR PC); -VMMDECL(RTGCUINTPTR) EMGetInhibitInterruptsPC(PVMCPU pVCpu); -VMMDECL(int) EMInterpretDisasCurrent(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pCpu, unsigned *pcbInstr); -VMMDECL(int) EMInterpretDisasOneEx(PVM pVM, PVMCPU pVCpu, RTGCUINTPTR GCPtrInstr, PCCPUMCTXCORE pCtxCore, - PDISCPUSTATE pDISState, unsigned *pcbInstr); -VMMDECL(VBOXSTRICTRC) EMInterpretInstruction(PVMCPU pVCpu, PCPUMCTXCORE pCoreCtx, RTGCPTR pvFault); -VMMDECL(VBOXSTRICTRC) EMInterpretInstructionEx(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbWritten); -VMMDECL(VBOXSTRICTRC) EMInterpretInstructionDisasState(PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCORE pCoreCtx, RTGCPTR pvFault, EMCODETYPE enmCodeType); +VMMDECL(void) EMSetInhibitInterruptsPC(PVMCPU pVCpu, RTGCUINTPTR PC); +VMMDECL(RTGCUINTPTR) EMGetInhibitInterruptsPC(PVMCPU pVCpu); +VMM_INT_DECL(int) EMInterpretDisasCurrent(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pCpu, unsigned *pcbInstr); +VMM_INT_DECL(int) EMInterpretDisasOneEx(PVM pVM, PVMCPU pVCpu, RTGCUINTPTR GCPtrInstr, PCCPUMCTXCORE pCtxCore, + PDISCPUSTATE pDISState, unsigned *pcbInstr); +VMM_INT_DECL(VBOXSTRICTRC) EMInterpretInstruction(PVMCPU pVCpu, PCPUMCTXCORE pCoreCtx, RTGCPTR pvFault); +VMM_INT_DECL(VBOXSTRICTRC) EMInterpretInstructionEx(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbWritten); +VMM_INT_DECL(VBOXSTRICTRC) EMInterpretInstructionDisasState(PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCORE pCoreCtx, + RTGCPTR pvFault, EMCODETYPE enmCodeType); #ifdef IN_RC -VMMDECL(int) EMInterpretIretV86ForPatm(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); +VMM_INT_DECL(int) EMInterpretIretV86ForPatm(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); #endif -VMMDECL(int) EMInterpretCpuId(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); -VMMDECL(int) EMInterpretRdtsc(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); -VMMDECL(int) EMInterpretRdpmc(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); -VMMDECL(int) EMInterpretRdtscp(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); -VMMDECL(VBOXSTRICTRC) EMInterpretInvlpg(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pAddrGC); -VMMDECL(VBOXSTRICTRC) EMInterpretMWait(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); -VMMDECL(int) EMInterpretMonitor(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); -VMMDECL(int) EMInterpretDRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegDrx, uint32_t SrcRegGen); -VMMDECL(int) EMInterpretDRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegDrx); -VMMDECL(int) EMInterpretCRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegCrx, uint32_t SrcRegGen); -VMMDECL(int) EMInterpretCRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegCrx); -VMMDECL(int) EMInterpretLMSW(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint16_t u16Data); -VMMDECL(int) EMInterpretCLTS(PVM pVM, PVMCPU pVCpu); -#ifndef VBOX_WITH_IEM -VMMDECL(int) EMInterpretRdmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); -VMMDECL(int) EMInterpretWrmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); -#endif /* !VBOX_WITH_IEM */ -VMM_INT_DECL(bool) EMShouldContinueAfterHalt(PVMCPU pVCpu, PCPUMCTX pCtx); -VMM_INT_DECL(int) EMMonitorWaitPrepare(PVMCPU pVCpu, uint64_t rax, uint64_t rcx, uint64_t rdx); -VMM_INT_DECL(int) EMMonitorWaitPerform(PVMCPU pVCpu, uint64_t rax, uint64_t rcx); +VMM_INT_DECL(int) EMInterpretCpuId(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); +VMM_INT_DECL(int) EMInterpretRdtsc(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); +VMM_INT_DECL(int) EMInterpretRdpmc(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); +VMM_INT_DECL(int) EMInterpretRdtscp(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); +VMM_INT_DECL(VBOXSTRICTRC) EMInterpretInvlpg(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pAddrGC); +VMM_INT_DECL(VBOXSTRICTRC) EMInterpretMWait(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); +VMM_INT_DECL(int) EMInterpretMonitor(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); +VMM_INT_DECL(int) EMInterpretDRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegDrx, uint32_t SrcRegGen); +VMM_INT_DECL(int) EMInterpretDRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegDrx); +VMM_INT_DECL(int) EMInterpretCRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegCrx, uint32_t SrcRegGen); +VMM_INT_DECL(int) EMInterpretCRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegCrx); +VMM_INT_DECL(int) EMInterpretLMSW(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint16_t u16Data); +VMM_INT_DECL(int) EMInterpretCLTS(PVM pVM, PVMCPU pVCpu); +VMM_INT_DECL(int) EMInterpretRdmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); +VMM_INT_DECL(int) EMInterpretWrmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); +VMM_INT_DECL(bool) EMShouldContinueAfterHalt(PVMCPU pVCpu, PCPUMCTX pCtx); +VMM_INT_DECL(bool) EMMonitorWaitShouldContinue(PVMCPU pVCpu, PCPUMCTX pCtx); +VMM_INT_DECL(int) EMMonitorWaitPrepare(PVMCPU pVCpu, uint64_t rax, uint64_t rcx, uint64_t rdx, RTGCPHYS GCPhys); +VMM_INT_DECL(int) EMMonitorWaitPerform(PVMCPU pVCpu, uint64_t rax, uint64_t rcx); /** @name Assembly routines * @{ */ @@ -213,26 +231,28 @@ VMMDECL(uint32_t) EMEmulateLockXAdd(void *pvParam1, void *pvParam2, size_t cbO /** @name REM locking routines * @{ */ -VMMDECL(void) EMRemUnlock(PVM pVM); -VMMDECL(void) EMRemLock(PVM pVM); -VMMDECL(bool) EMRemIsLockOwner(PVM pVM); -VMMDECL(int) EMRemTryLock(PVM pVM); +VMMDECL(void) EMRemUnlock(PVM pVM); +VMMDECL(void) EMRemLock(PVM pVM); +VMMDECL(bool) EMRemIsLockOwner(PVM pVM); +VMM_INT_DECL(int) EMRemTryLock(PVM pVM); /** @} */ + +/** @name EM_ONE_INS_FLAGS_XXX - flags for EMR3HmSingleInstruction (et al). + * @{ */ +/** Return when CS:RIP changes or some other important event happens. + * This means running whole REP and LOOP $ sequences for instance. */ +#define EM_ONE_INS_FLAGS_RIP_CHANGE RT_BIT_32(0) +/** Mask of valid flags. */ +#define EM_ONE_INS_FLAGS_MASK UINT32_C(0x00000001) +/** @} */ + + #ifdef IN_RING3 /** @defgroup grp_em_r3 The EM Host Context Ring-3 API * @ingroup grp_em * @{ */ -VMMR3DECL(int) EMR3Init(PVM pVM); -VMMR3DECL(void) EMR3Relocate(PVM pVM); -VMMR3DECL(void) EMR3ResetCpu(PVMCPU pVCpu); -VMMR3DECL(void) EMR3Reset(PVM pVM); -VMMR3DECL(int) EMR3Term(PVM pVM); -VMMR3DECL(DECLNORETURN(void)) EMR3FatalError(PVMCPU pVCpu, int rc); -VMMR3DECL(int) EMR3ExecuteVM(PVM pVM, PVMCPU pVCpu); -VMMR3DECL(int) EMR3CheckRawForcedActions(PVM pVM, PVMCPU pVCpu); -VMMR3DECL(int) EMR3Interpret(PVM pVM); /** * Command argument for EMR3RawSetMode(). @@ -248,25 +268,30 @@ typedef enum EMEXECPOLICY EMEXECPOLICY_RECOMPILE_RING0, /** Whether to recompile ring-3 code or execute it in raw/hm. */ EMEXECPOLICY_RECOMPILE_RING3, + /** Whether to only use IEM for execution. */ + EMEXECPOLICY_IEM_ALL, /** End of valid value (not included). */ EMEXECPOLICY_END, /** The customary 32-bit type blowup. */ EMEXECPOLICY_32BIT_HACK = 0x7fffffff } EMEXECPOLICY; +VMMR3DECL(int) EMR3SetExecutionPolicy(PUVM pUVM, EMEXECPOLICY enmPolicy, bool fEnforce); +VMMR3DECL(int) EMR3QueryExecutionPolicy(PUVM pUVM, EMEXECPOLICY enmPolicy, bool *pfEnforced); -VMMR3DECL(int) EMR3SetExecutionPolicy(PVM pVM, EMEXECPOLICY enmPolicy, bool fEnforce); -/** @} */ -#endif /* IN_RING3 */ - +VMMR3_INT_DECL(int) EMR3Init(PVM pVM); +VMMR3_INT_DECL(void) EMR3Relocate(PVM pVM); +VMMR3_INT_DECL(void) EMR3ResetCpu(PVMCPU pVCpu); +VMMR3_INT_DECL(void) EMR3Reset(PVM pVM); +VMMR3_INT_DECL(int) EMR3Term(PVM pVM); +VMMR3DECL(DECLNORETURN(void)) EMR3FatalError(PVMCPU pVCpu, int rc); +VMMR3_INT_DECL(int) EMR3ExecuteVM(PVM pVM, PVMCPU pVCpu); +VMMR3_INT_DECL(int) EMR3CheckRawForcedActions(PVM pVM, PVMCPU pVCpu); +VMMR3_INT_DECL(int) EMR3NotifyResume(PVM pVM); +VMMR3_INT_DECL(int) EMR3NotifySuspend(PVM pVM); +VMMR3_INT_DECL(VBOXSTRICTRC) EMR3HmSingleInstruction(PVM pVM, PVMCPU pVCpu, uint32_t fFlags); -#ifdef IN_RC -/** @defgroup grp_em_gc The EM Guest Context API - * @ingroup grp_em - * @{ - */ -VMMRCDECL(int) EMGCTrap(PVM pVM, unsigned uTrap, PCPUMCTXCORE pRegFrame); /** @} */ -#endif /* IN_RC */ +#endif /* IN_RING3 */ /** @} */ diff --git a/include/VBox/vmm/ftm.h b/include/VBox/vmm/ftm.h index 2fc1ccfe..e8702d67 100644 --- a/include/VBox/vmm/ftm.h +++ b/include/VBox/vmm/ftm.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -40,24 +40,27 @@ RT_C_DECLS_BEGIN */ typedef enum FTMCHECKPOINTTYPE { + FTMCHECKPOINTTYPE_INVALID = 0, FTMCHECKPOINTTYPE_NETWORK, FTMCHECKPOINTTYPE_STORAGE, + FTMCHECKPOINTTYPE_END, FTMCHECKPOINTTYPE_32BIT_HACK = 0x7fffffff } FTMCHECKPOINTTYPE; -VMMDECL(bool) FTMIsDeltaLoadSaveActive(PVM pVM); -VMMDECL(int) FTMSetCheckpoint(PVM pVM, FTMCHECKPOINTTYPE enmType); +VMM_INT_DECL(bool) FTMIsDeltaLoadSaveActive(PVM pVM); +VMM_INT_DECL(int) FTMSetCheckpoint(PVM pVM, FTMCHECKPOINTTYPE enmType); #ifdef IN_RING3 /** @defgroup grp_ftm_r3 The FTM Host Context Ring-3 API * @ingroup grp_ftm * @{ */ -VMMR3DECL(int) FTMR3PowerOn(PVM pVM, bool fMaster, unsigned uInterval, const char *pszAddress, unsigned uPort, const char *pszPassword); -VMMR3DECL(int) FTMR3Init(PVM pVM); -VMMR3DECL(int) FTMR3Term(PVM pVM); -VMMR3DECL(int) FTMR3CancelStandby(PVM pVM); -VMMR3DECL(int) FTMR3SetCheckpoint(PVM pVM, FTMCHECKPOINTTYPE enmType); +VMMR3DECL(int) FTMR3PowerOn(PUVM pUVM, bool fMaster, unsigned uInterval, const char *pszAddress, unsigned uPort, const char *pszPassword); +VMMR3DECL(int) FTMR3CancelStandby(PUVM pUVM); + +VMMR3_INT_DECL(int) FTMR3Init(PVM pVM); +VMMR3_INT_DECL(int) FTMR3Term(PVM pVM); +VMMR3_INT_DECL(int) FTMR3SetCheckpoint(PVM pVM, FTMCHECKPOINTTYPE enmType); #endif /* IN_RING3 */ diff --git a/include/VBox/vmm/gmm.h b/include/VBox/vmm/gmm.h index 0f93c94a..e5db104c 100644 --- a/include/VBox/vmm/gmm.h +++ b/include/VBox/vmm/gmm.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2007-2010 Oracle Corporation + * Copyright (C) 2007-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/vmm/gvm.h b/include/VBox/vmm/gvm.h index b0d607de..0fe406b0 100644 --- a/include/VBox/vmm/gvm.h +++ b/include/VBox/vmm/gvm.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2007-2010 Oracle Corporation + * Copyright (C) 2007-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/vmm/gvmm.h b/include/VBox/vmm/gvmm.h index e78d181b..eb86f9b2 100644 --- a/include/VBox/vmm/gvmm.h +++ b/include/VBox/vmm/gvmm.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2007-2010 Oracle Corporation + * Copyright (C) 2007-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/vmm/hm.h b/include/VBox/vmm/hm.h new file mode 100644 index 00000000..12b94167 --- /dev/null +++ b/include/VBox/vmm/hm.h @@ -0,0 +1,265 @@ +/** @file + * HM - Intel/AMD VM Hardware Assisted Virtualization Manager (VMM) + */ + +/* + * Copyright (C) 2006-2013 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL) only, as it comes in the "COPYING.CDDL" file of the + * VirtualBox OSE distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + */ + +#ifndef ___VBox_vmm_hm_h +#define ___VBox_vmm_hm_h + +#include <VBox/vmm/pgm.h> +#include <VBox/vmm/cpum.h> +#include <VBox/vmm/vmm.h> +#include <iprt/mp.h> + + +/** @defgroup grp_hm The VM Hardware Manager API + * @{ + */ + +RT_C_DECLS_BEGIN + +/** + * Checks whether HM (VT-x/AMD-V) is being used by this VM. + * + * @retval @c true if used. + * @retval @c false if software virtualization (raw-mode) is used. + * + * @param a_pVM The cross context VM structure. + * @sa HMIsEnabledNotMacro, HMR3IsEnabled + * @internal + */ +#if defined(VBOX_STRICT) && defined(IN_RING3) +# define HMIsEnabled(a_pVM) HMIsEnabledNotMacro(a_pVM) +#else +# define HMIsEnabled(a_pVM) ((a_pVM)->fHMEnabled) +#endif + +/** + * Checks whether raw-mode context is required for any purpose. + * + * @retval @c true if required either by raw-mode itself or by HM for doing + * switching the cpu to 64-bit mode. + * @retval @c false if not required. + * + * @param a_pVM The cross context VM structure. + * @internal + */ +#if HC_ARCH_BITS == 64 +# define HMIsRawModeCtxNeeded(a_pVM) (!HMIsEnabled(a_pVM)) +#else +# define HMIsRawModeCtxNeeded(a_pVM) (!HMIsEnabled(a_pVM) || (a_pVM)->fHMNeedRawModeCtx) +#endif + + /** + * Check if the current CPU state is valid for emulating IO blocks in the recompiler + * + * @returns boolean + * @param a_pVCpu Pointer to the shared virtual CPU structure. + * @internal + */ +#define HMCanEmulateIoBlock(a_pVCpu) (!CPUMIsGuestInPagedProtectedMode(a_pVCpu)) + + /** + * Check if the current CPU state is valid for emulating IO blocks in the recompiler + * + * @returns boolean + * @param a_pCtx Pointer to the CPU context (within PVM). + * @internal + */ +#define HMCanEmulateIoBlockEx(a_pCtx) (!CPUMIsGuestInPagedProtectedModeEx(a_pCtx)) + +/** + * Checks whether we're in the special hardware virtualization context. + * @returns true / false. + * @param a_pVCpu The caller's cross context virtual CPU structure. + * @thread EMT + */ +#ifdef IN_RING0 +# define HMIsInHwVirtCtx(a_pVCpu) (VMCPU_GET_STATE(a_pVCpu) == VMCPUSTATE_STARTED_HM) +#else +# define HMIsInHwVirtCtx(a_pVCpu) (false) +#endif + +/** + * Checks whether we're in the special hardware virtualization context and we + * cannot perform long jump without guru meditating and possibly messing up the + * host and/or guest state. + * + * This is after we've turned interrupts off and such. + * + * @returns true / false. + * @param a_pVCpu The caller's cross context virtual CPU structure. + * @thread EMT + */ +#ifdef IN_RING0 +# define HMIsInHwVirtNoLongJmpCtx(a_pVCpu) (VMCPU_GET_STATE(a_pVCpu) == VMCPUSTATE_STARTED_EXEC) +#else +# define HMIsInHwVirtNoLongJmpCtx(a_pVCpu) (false) +#endif + +/** + * 64-bit raw-mode (intermediate memory context) operations. + * + * These are special hypervisor eip values used when running 64-bit guests on + * 32-bit hosts. Each operation corresponds to a routine. + * + * @note Duplicated in the assembly code! + */ +typedef enum HM64ON32OP +{ + HM64ON32OP_INVALID = 0, + HM64ON32OP_VMXRCStartVM64, + HM64ON32OP_SVMRCVMRun64, + HM64ON32OP_HMRCSaveGuestFPU64, + HM64ON32OP_HMRCSaveGuestDebug64, + HM64ON32OP_HMRCTestSwitcher64, + HM64ON32OP_END, + HM64ON32OP_32BIT_HACK = 0x7fffffff +} HM64ON32OP; + +VMMDECL(bool) HMIsEnabledNotMacro(PVM pVM); +VMM_INT_DECL(int) HMInvalidatePage(PVMCPU pVCpu, RTGCPTR GCVirt); +VMM_INT_DECL(bool) HMHasPendingIrq(PVM pVM); +VMM_INT_DECL(PX86PDPE) HMGetPaePdpes(PVMCPU pVCpu); +VMM_INT_DECL(int) HMAmdIsSubjectToErratum170(uint32_t *pu32Family, uint32_t *pu32Model, uint32_t *pu32Stepping); +VMM_INT_DECL(bool) HMSetSingleInstruction(PVMCPU pVCpu, bool fEnable); + +#ifndef IN_RC +VMM_INT_DECL(int) HMFlushTLB(PVMCPU pVCpu); +VMM_INT_DECL(int) HMFlushTLBOnAllVCpus(PVM pVM); +VMM_INT_DECL(int) HMInvalidatePageOnAllVCpus(PVM pVM, RTGCPTR GCVirt); +VMM_INT_DECL(int) HMInvalidatePhysPage(PVM pVM, RTGCPHYS GCPhys); +VMM_INT_DECL(bool) HMIsNestedPagingActive(PVM pVM); +VMM_INT_DECL(PGMMODE) HMGetShwPagingMode(PVM pVM); +#else /* Nops in RC: */ +# define HMFlushTLB(pVCpu) do { } while (0) +# define HMIsNestedPagingActive(pVM) false +# define HMFlushTLBOnAllVCpus(pVM) do { } while (0) +#endif + +#ifdef IN_RING0 +/** @defgroup grp_hm_r0 The VM Hardware Manager API + * @ingroup grp_hm + * @{ + */ +VMMR0_INT_DECL(int) HMR0Init(void); +VMMR0_INT_DECL(int) HMR0Term(void); +VMMR0_INT_DECL(int) HMR0InitVM(PVM pVM); +VMMR0_INT_DECL(int) HMR0TermVM(PVM pVM); +VMMR0_INT_DECL(int) HMR0EnableAllCpus(PVM pVM); +VMMR0_INT_DECL(int) HMR0EnterSwitcher(PVM pVM, VMMSWITCHER enmSwitcher, bool *pfVTxDisabled); +VMMR0_INT_DECL(void) HMR0LeaveSwitcher(PVM pVM, bool fVTxDisabled); + +VMMR0_INT_DECL(void) HMR0SavePendingIOPortWrite(PVMCPU pVCpu, RTGCPTR GCPtrRip, RTGCPTR GCPtrRipNext, + unsigned uPort, unsigned uAndVal, unsigned cbSize); +VMMR0_INT_DECL(void) HMR0SavePendingIOPortRead(PVMCPU pVCpu, RTGCPTR GCPtrRip, RTGCPTR GCPtrRipNext, + unsigned uPort, unsigned uAndVal, unsigned cbSize); + +/** @} */ +#endif /* IN_RING0 */ + + +#ifdef IN_RING3 +/** @defgroup grp_hm_r3 The VM Hardware Manager API + * @ingroup grp_hm + * @{ + */ +VMMR3DECL(bool) HMR3IsEnabled(PUVM pUVM); +VMMR3DECL(bool) HMR3IsNestedPagingActive(PUVM pUVM); +VMMR3DECL(bool) HMR3IsVpidActive(PUVM pVUM); +VMMR3DECL(bool) HMR3IsUXActive(PUVM pVUM); +VMMR3DECL(bool) HMR3IsSvmEnabled(PUVM pUVM); +VMMR3DECL(bool) HMR3IsVmxEnabled(PUVM pUVM); + +VMMR3_INT_DECL(bool) HMR3IsEventPending(PVMCPU pVCpu); +VMMR3_INT_DECL(int) HMR3Init(PVM pVM); +VMMR3_INT_DECL(int) HMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat); +VMMR3_INT_DECL(void) HMR3Relocate(PVM pVM); +VMMR3_INT_DECL(int) HMR3Term(PVM pVM); +VMMR3_INT_DECL(void) HMR3Reset(PVM pVM); +VMMR3_INT_DECL(void) HMR3ResetCpu(PVMCPU pVCpu); +VMMR3_INT_DECL(void) HMR3CheckError(PVM pVM, int iStatusCode); +VMMR3DECL(bool) HMR3CanExecuteGuest(PVM pVM, PCPUMCTX pCtx); +VMMR3_INT_DECL(void) HMR3NotifyScheduled(PVMCPU pVCpu); +VMMR3_INT_DECL(void) HMR3NotifyEmulated(PVMCPU pVCpu); +VMMR3_INT_DECL(bool) HMR3IsActive(PVMCPU pVCpu); +VMMR3_INT_DECL(void) HMR3PagingModeChanged(PVM pVM, PVMCPU pVCpu, PGMMODE enmShadowMode, PGMMODE enmGuestMode); +VMMR3_INT_DECL(int) HMR3EmulateIoBlock(PVM pVM, PCPUMCTX pCtx); +VMMR3_INT_DECL(VBOXSTRICTRC) HMR3RestartPendingIOInstr(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); +VMMR3_INT_DECL(int) HMR3EnablePatching(PVM pVM, RTGCPTR pPatchMem, unsigned cbPatchMem); +VMMR3_INT_DECL(int) HMR3DisablePatching(PVM pVM, RTGCPTR pPatchMem, unsigned cbPatchMem); +VMMR3_INT_DECL(int) HMR3PatchTprInstr(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); +VMMR3_INT_DECL(bool) HMR3IsRescheduleRequired(PVM pVM, PCPUMCTX pCtx); +VMMR3_INT_DECL(bool) HMR3IsVmxPreemptionTimerUsed(PVM pVM); + +/** @} */ +#endif /* IN_RING3 */ + +#ifdef IN_RING0 +/** @addtogroup grp_hm_r0 + * @{ + */ +/** Disables preemption if required. */ +# define HM_DISABLE_PREEMPT_IF_NEEDED() \ + RTTHREADPREEMPTSTATE PreemptStateInternal = RTTHREADPREEMPTSTATE_INITIALIZER; \ + bool fPreemptDisabledInternal = false; \ + if (RTThreadPreemptIsEnabled(NIL_RTTHREAD)) \ + { \ + Assert(VMMR0ThreadCtxHooksAreRegistered(pVCpu)); \ + RTThreadPreemptDisable(&PreemptStateInternal); \ + fPreemptDisabledInternal = true; \ + } + +/** Restores preemption if previously disabled by HM_DISABLE_PREEMPT(). */ +# define HM_RESTORE_PREEMPT_IF_NEEDED() \ + do \ + { \ + if (fPreemptDisabledInternal) \ + RTThreadPreemptRestore(&PreemptStateInternal); \ + } while (0) + +VMMR0_INT_DECL(int) HMR0SetupVM(PVM pVM); +VMMR0_INT_DECL(int) HMR0RunGuestCode(PVM pVM, PVMCPU pVCpu); +VMMR0_INT_DECL(int) HMR0Enter(PVM pVM, PVMCPU pVCpu); +VMMR0_INT_DECL(int) HMR0Leave(PVM pVM, PVMCPU pVCpu); +VMMR0_INT_DECL(int) HMR0EnterCpu(PVMCPU pVCpu); +VMMR0_INT_DECL(int) HMR0LeaveCpu(PVMCPU pVCpu); +VMMR0_INT_DECL(void) HMR0ThreadCtxCallback(RTTHREADCTXEVENT enmEvent, void *pvUser); +VMMR0_INT_DECL(bool) HMR0SuspendPending(void); + +# if HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS) +VMMR0_INT_DECL(int) HMR0SaveFPUState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); +VMMR0_INT_DECL(int) HMR0SaveDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); +VMMR0_INT_DECL(int) HMR0TestSwitcher3264(PVM pVM); +# endif + +/** @} */ +#endif /* IN_RING0 */ + + +/** @} */ +RT_C_DECLS_END + + +#endif + diff --git a/include/VBox/vmm/hwacc_svm.h b/include/VBox/vmm/hm_svm.h index 8912e378..7a67c387 100644 --- a/include/VBox/vmm/hwacc_svm.h +++ b/include/VBox/vmm/hm_svm.h @@ -1,9 +1,9 @@ /** @file - * HWACCM - SVM Structures and Definitions. (VMM) + * HM - SVM Structures and Definitions. (VMM) */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -32,7 +32,7 @@ #include <iprt/asm.h> /** @defgroup grp_svm svm Types and Definitions - * @ingroup grp_hwaccm + * @ingroup grp_hm * @{ */ @@ -56,13 +56,13 @@ #define AMD_CPUID_SVM_FEATURE_EDX_FLUSH_BY_ASID RT_BIT(6) /** Bit 7 - DecodeAssist - Indicate decode assist is supported. */ #define AMD_CPUID_SVM_FEATURE_EDX_DECODE_ASSIST RT_BIT(7) -/** Where did we get this from? */ -#define AMD_CPUID_SVM_FEATURE_EDX_SSE_3_5_DISABLE RT_BIT(9) /** Bit 10 - PauseFilter - Indicates support for the PAUSE intercept filter. */ #define AMD_CPUID_SVM_FEATURE_EDX_PAUSE_FILTER RT_BIT(10) /** Bit 12 - PauseFilterThreshold - Indicates support for the PAUSE * intercept filter cycle count threshold. */ #define AMD_CPUID_SVM_FEATURE_EDX_PAUSE_FILTER_THRESHOLD RT_BIT(12) +/** Bit 13 - AVIC - Advanced Virtual Interrupt Controller. */ +#define AMD_CPUID_SVM_FEATURE_EDX_AVIC RT_BIT(13) /** @} */ @@ -70,7 +70,7 @@ * @{ */ /** Invalid guest state in VMCB. */ -#define SVM_EXIT_INVALID -1 +#define SVM_EXIT_INVALID (-1) /** Read from CR0-CR15. */ #define SVM_EXIT_READ_CR0 0x0 #define SVM_EXIT_READ_CR1 0x1 @@ -258,17 +258,24 @@ #define SVM_EXIT_WBINVD 0x89 /** MONITOR instruction. */ #define SVM_EXIT_MONITOR 0x8A -/** MWAIT instruction uncond. */ -#define SVM_EXIT_MWAIT_UNCOND 0x8B -/** MWAIT instruction when armed. */ +/** MWAIT instruction. */ +#define SVM_EXIT_MWAIT 0x8B +/** MWAIT instruction, when armed. */ #define SVM_EXIT_MWAIT_ARMED 0x8C /** Nested paging: host-level page fault occurred (EXITINFO1 contains fault errorcode; EXITINFO2 contains the guest physical address causing the fault). */ #define SVM_EXIT_NPF 0x400 - +/** AVIC: Virtual IPI delivery not completed. */ +#define SVM_EXIT_AVIC_INCOMPLETE_IPI 0x401 +/** AVIC: Attempted access by guest to a vAPIC register not handled by AVIC + * hardware. */ +#define SVM_EXIT_AVIC_NOACCEL 0x402 + +/** The maximum possible exit value. */ +#define SVM_EXIT_MAX (SVM_EXIT_AVIC_NOACCEL) /** @} */ -/** @name SVM_VMCB.u64ExitInfo2 +/** @name SVMVMCB.u64ExitInfo2 for task switches * @{ */ /** Set to 1 if the task switch was caused by an IRET; else cleared to 0. */ @@ -281,7 +288,16 @@ #define SVM_EXIT2_TASK_SWITCH_EFLAGS_RF RT_BIT_64(48) /** @} */ -/** @name SVM_VMCB.ctrl.u32InterceptCtrl1 +/** @name SVMVMCB.u64ExitInfo1 for MSR accesses + * @{ + */ +/** The access was a read MSR. */ +#define SVM_EXIT1_MSR_READ 0x0 +/** The access was a write MSR. */ +#define SVM_EXIT1_MSR_WRITE 0x1 +/** @} */ + +/** @name SVMVMCB.ctrl.u32InterceptCtrl1 * @{ */ /** 0 Intercept INTR (physical maskable interrupt). */ @@ -351,7 +367,7 @@ /** @} */ -/** @name SVM_VMCB.ctrl.u32InterceptCtrl2 +/** @name SVMVMCB.ctrl.u32InterceptCtrl2 * @{ */ /** 0 Intercept VMRUN instruction. */ @@ -377,27 +393,27 @@ /** 10 Intercept MONITOR instruction. */ #define SVM_CTRL2_INTERCEPT_MONITOR RT_BIT(10) /** 11 Intercept MWAIT instruction unconditionally. */ -#define SVM_CTRL2_INTERCEPT_MWAIT_UNCOND RT_BIT(11) +#define SVM_CTRL2_INTERCEPT_MWAIT RT_BIT(11) /** 12 Intercept MWAIT instruction when armed. */ #define SVM_CTRL2_INTERCEPT_MWAIT_ARMED RT_BIT(12) /** 13 Intercept XSETBV instruction. */ #define SVM_CTRL2_INTERCEPT_XSETBV RT_BIT(13) /** @} */ -/** @name SVM_VMCB.ctrl.u64NestedPaging +/** @name SVMVMCB.ctrl.u64NestedPaging * @{ */ #define SVM_NESTED_PAGING_ENABLE RT_BIT(0) /** @} */ -/** @name SVM_VMCB.ctrl.u64IntShadow +/** @name SVMVMCB.ctrl.u64IntShadow * @{ */ #define SVM_INTERRUPT_SHADOW_ACTIVE RT_BIT(0) /** @} */ -/** @name SVM_INTCTRL.u3Type +/** @name SVMINTCTRL.u3Type * @{ */ /** External or virtual interrupt. */ @@ -411,7 +427,7 @@ /** @} */ -/** @name SVM_VMCB.ctrl.TLBCtrl.n.u8TLBFlush +/** @name SVMVMCB.ctrl.TLBCtrl.n.u8TLBFlush * @{ */ /** Flush nothing. */ @@ -450,13 +466,11 @@ typedef struct uint64_t u64Base; } SVMGDTR; #pragma pack() - typedef SVMGDTR SVMIDTR; /** - * SVM Event injection structure. + * SVM Event injection structure (EVENTINJ and EXITINTINFO). */ -#pragma pack(1) typedef union { struct @@ -468,15 +482,14 @@ typedef union uint32_t u1Valid : 1; uint32_t u32ErrorCode : 32; } n; - uint64_t au64[1]; -} SVM_EVENT; -#pragma pack() - + uint64_t u; +} SVMEVENT; +/** Pointer to the SVMEVENT union. */ +typedef SVMEVENT *PSVMEVENT; /** - * SVM Interrupt control structure. + * SVM Interrupt control structure (Virtual Interrupt Control). */ -#pragma pack(1) typedef union { struct @@ -488,19 +501,17 @@ typedef union uint32_t u1IgnoreTPR : 1; uint32_t u3Reserved : 3; uint32_t u1VIrqMasking : 1; - uint32_t u7Reserved2 : 7; + uint32_t u6Reserved : 6; + uint32_t u1AvicEnable : 1; uint32_t u8VIrqVector : 8; uint32_t u24Reserved : 24; } n; - uint64_t au64[1]; -} SVM_INTCTRL; -#pragma pack() - + uint64_t u; +} SVMINTCTRL; /** * SVM TLB control structure. */ -#pragma pack(1) typedef union { struct @@ -509,15 +520,12 @@ typedef union uint32_t u8TLBFlush : 8; uint32_t u24Reserved : 24; } n; - uint64_t au64[1]; -} SVM_TLBCTRL; -#pragma pack() - + uint64_t u; +} SVMTLBCTRL; /** - * SVM IOIO exit structure. + * SVM IOIO exit structure (EXITINFO1 for IOIO intercepts). */ -#pragma pack(1) typedef union { struct @@ -535,29 +543,65 @@ typedef union uint32_t u6Reserved : 6; uint32_t u16Port : 16; } n; - uint32_t au32[1]; -} SVM_IOIO_EXIT; -#pragma pack() + uint32_t u; +} SVMIOIOEXIT; + +/** @name SVMIOIOEXIT.u1Type + * @{ */ +/** IO write. */ +#define SVM_IOIO_WRITE 0 +/** IO read. */ +#define SVM_IOIO_READ 1 +/** @}*/ /** * SVM nested paging structure. */ -#pragma pack(1) typedef union { struct { - uint32_t u1NestedPaging : 1; /**< enabled/disabled */ + uint32_t u1NestedPaging : 1; /**< enabled/disabled */ } n; - uint64_t au64[1]; -} SVM_NPCTRL; -#pragma pack() + uint64_t u; +} SVMNPCTRL; + +/** + * SVM AVIC. + */ +typedef union +{ + struct + { + uint64_t u12Reserved1 : 12; + uint64_t u40Addr : 40; + uint64_t u12Reserved2 : 12; + } n; + uint64_t u; +} SVMAVIC; +AssertCompileSize(SVMAVIC, 8); + +/** + * SVM AVIC PHYSICAL_TABLE pointer. + */ +typedef union +{ + struct + { + uint64_t u8LastGuestCoreId : 8; + uint64_t u4Reserved : 4; + uint64_t u40Addr : 40; + uint64_t u12Reserved : 12; + } n; + uint64_t u; +} SVMAVICPHYS; +AssertCompileSize(SVMAVICPHYS, 8); /** * SVM VM Control Block. (VMCB) */ #pragma pack(1) -typedef struct _SVM_VMCB +typedef struct SVMVMCB { /** Control Area. */ struct @@ -577,7 +621,9 @@ typedef struct _SVM_VMCB /** Offset 0x0C - Intercept control field 2. */ uint32_t u32InterceptCtrl2; /** Offset 0x14-0x3F - Reserved. */ - uint8_t u8Reserved[0x3e - 0x14]; + uint8_t u8Reserved[0x3c - 0x14]; + /** Offset 0x3c - PAUSE filter threshold. */ + uint16_t u16PauseFilterThreshold; /** Offset 0x3e - PAUSE intercept filter count. */ uint16_t u16PauseFilterCount; /** Offset 0x40 - Physical address of IOPM. */ @@ -587,9 +633,9 @@ typedef struct _SVM_VMCB /** Offset 0x50 - TSC Offset. */ uint64_t u64TSCOffset; /** Offset 0x58 - TLB control field. */ - SVM_TLBCTRL TLBCtrl; + SVMTLBCTRL TLBCtrl; /** Offset 0x60 - Interrupt control field. */ - SVM_INTCTRL IntCtrl; + SVMINTCTRL IntCtrl; /** Offset 0x68 - Interrupt shadow. */ uint64_t u64IntShadow; /** Offset 0x70 - Exit code. */ @@ -599,29 +645,39 @@ typedef struct _SVM_VMCB /** Offset 0x80 - Exit info 2. */ uint64_t u64ExitInfo2; /** Offset 0x88 - Exit Interrupt info. */ - SVM_EVENT ExitIntInfo; + SVMEVENT ExitIntInfo; /** Offset 0x90 - Nested Paging. */ - SVM_NPCTRL NestedPaging; - /** Offset 0x98-0xA7 - Reserved. */ - uint8_t u8Reserved2[0xA8-0x98]; + SVMNPCTRL NestedPaging; + /** Offset 0x98 - AVIC APIC BAR. */ + SVMAVIC AvicBar; + /** Offset 0xA0-0xA7 - Reserved. */ + uint8_t u8Reserved2[0xA8-0xA0]; /** Offset 0xA8 - Event injection. */ - SVM_EVENT EventInject; + SVMEVENT EventInject; /** Offset 0xB0 - Host CR3 for nested paging. */ uint64_t u64NestedPagingCR3; /** Offset 0xB8 - LBR Virtualization. */ uint64_t u64LBRVirt; /** Offset 0xC0 - VMCB Clean Bits. */ - uint64_t u64VMCBCleanBits; + uint64_t u64VmcbCleanBits; /** Offset 0xC8 - Next sequential instruction pointer. */ uint64_t u64NextRIP; /** Offset 0xD0 - Number of bytes fetched. */ uint8_t cbInstrFetched; /** Offset 0xD1 - Number of bytes fetched. */ uint8_t abInstr[15]; + /** Offset 0xE0 - AVIC APIC_BACKING_PAGE pointer. */ + SVMAVIC AvicBackingPagePtr; + /** Offset 0xE8-0xEF - Reserved. */ + uint8_t u8Reserved3[0xF0 - 0xE8]; + /** Offset 0xF0 - AVIC LOGICAL_TABLE pointer. */ + SVMAVIC AvicLogicalTablePtr; + /** Offset 0xF8 - AVIC PHYSICAL_TABLE pointer. */ + SVMAVICPHYS AvicPhysicalTablePtr; } ctrl; - /** Offset 0xC0-0x3FF - Reserved. */ - uint8_t u8Reserved3[0x400-0xE0]; + /** Offset 0x100-0x3FF - Reserved. */ + uint8_t u8Reserved3[0x400-0x100]; /** State Save Area. Starts at offset 0x400. */ struct @@ -714,25 +770,36 @@ typedef struct _SVM_VMCB /** Offset 0x698-0xFFF- Reserved. */ uint8_t u8Reserved10[0x1000-0x698]; -} SVM_VMCB; +} SVMVMCB; #pragma pack() -AssertCompileSize(SVM_VMCB, 0x1000); -AssertCompileMemberOffset(SVM_VMCB, ctrl.u16InterceptRdCRx, 0x000); -AssertCompileMemberOffset(SVM_VMCB, ctrl.u16PauseFilterCount,0x03e); -AssertCompileMemberOffset(SVM_VMCB, ctrl.TLBCtrl, 0x058); -AssertCompileMemberOffset(SVM_VMCB, ctrl.ExitIntInfo, 0x088); -AssertCompileMemberOffset(SVM_VMCB, ctrl.EventInject, 0x0A8); -AssertCompileMemberOffset(SVM_VMCB, ctrl.abInstr, 0x0D1); -AssertCompileMemberOffset(SVM_VMCB, guest, 0x400); -AssertCompileMemberOffset(SVM_VMCB, guest.ES, 0x400); -AssertCompileMemberOffset(SVM_VMCB, guest.u8Reserved4, 0x4A0); -AssertCompileMemberOffset(SVM_VMCB, guest.u8CPL, 0x4CB); -AssertCompileMemberOffset(SVM_VMCB, guest.u8Reserved6, 0x4D8); -AssertCompileMemberOffset(SVM_VMCB, guest.u8Reserved7, 0x580); -AssertCompileMemberOffset(SVM_VMCB, guest.u8Reserved9, 0x648); -AssertCompileMemberOffset(SVM_VMCB, guest.u64GPAT, 0x668); -AssertCompileMemberOffset(SVM_VMCB, guest.u64LASTEXCPTO, 0x690); -AssertCompileMemberOffset(SVM_VMCB, u8Reserved10, 0x698); +/** Pointer to the SVMVMCB structure. */ +typedef SVMVMCB *PSVMVMCB; +AssertCompileMemberOffset(SVMVMCB, ctrl.u16InterceptRdCRx, 0x000); +AssertCompileMemberOffset(SVMVMCB, ctrl.u16PauseFilterCount, 0x03e); +AssertCompileMemberOffset(SVMVMCB, ctrl.TLBCtrl, 0x058); +AssertCompileMemberOffset(SVMVMCB, ctrl.ExitIntInfo, 0x088); +AssertCompileMemberOffset(SVMVMCB, ctrl.EventInject, 0x0A8); +AssertCompileMemberOffset(SVMVMCB, ctrl.abInstr, 0x0D1); +AssertCompileMemberOffset(SVMVMCB, ctrl.AvicBackingPagePtr, 0x0E0); +AssertCompileMemberOffset(SVMVMCB, ctrl.AvicLogicalTablePtr, 0x0F0); +AssertCompileMemberOffset(SVMVMCB, ctrl.AvicPhysicalTablePtr, 0x0F8); +AssertCompileMemberOffset(SVMVMCB, guest, 0x400); +AssertCompileMemberOffset(SVMVMCB, guest.ES, 0x400); +AssertCompileMemberOffset(SVMVMCB, guest.TR, 0x490); +AssertCompileMemberOffset(SVMVMCB, guest.u64EFER, 0x4D0); +AssertCompileMemberOffset(SVMVMCB, guest.u64CR4, 0x548); +AssertCompileMemberOffset(SVMVMCB, guest.u64RIP, 0x578); +AssertCompileMemberOffset(SVMVMCB, guest.u64RSP, 0x5D8); +AssertCompileMemberOffset(SVMVMCB, guest.u64CR2, 0x640); +AssertCompileMemberOffset(SVMVMCB, guest.u8Reserved4, 0x4A0); +AssertCompileMemberOffset(SVMVMCB, guest.u8CPL, 0x4CB); +AssertCompileMemberOffset(SVMVMCB, guest.u8Reserved6, 0x4D8); +AssertCompileMemberOffset(SVMVMCB, guest.u8Reserved7, 0x580); +AssertCompileMemberOffset(SVMVMCB, guest.u8Reserved9, 0x648); +AssertCompileMemberOffset(SVMVMCB, guest.u64GPAT, 0x668); +AssertCompileMemberOffset(SVMVMCB, guest.u64LASTEXCPTO, 0x690); +AssertCompileMemberOffset(SVMVMCB, u8Reserved10, 0x698); +AssertCompileSize(SVMVMCB, 0x1000); #ifdef IN_RING0 VMMR0DECL(int) SVMR0InvalidatePage(PVM pVM, PVMCPU pVCpu, RTGCPTR GCVirt); diff --git a/include/VBox/vmm/hm_vmx.h b/include/VBox/vmm/hm_vmx.h new file mode 100644 index 00000000..a84b01ca --- /dev/null +++ b/include/VBox/vmm/hm_vmx.h @@ -0,0 +1,2343 @@ +/** @file + * HM - VMX Structures and Definitions. (VMM) + */ + +/* + * Copyright (C) 2006-2013 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL) only, as it comes in the "COPYING.CDDL" file of the + * VirtualBox OSE distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + */ + +#ifndef ___VBox_vmm_vmx_h +#define ___VBox_vmm_vmx_h + +#include <VBox/types.h> +#include <VBox/err.h> +#include <iprt/x86.h> +#include <iprt/assert.h> + +/* In Visual C++ versions prior to 2012, the vmx intrinsics are only available + when targeting AMD64. */ +#if RT_INLINE_ASM_USES_INTRIN >= 16 && defined(RT_ARCH_AMD64) +# include <intrin.h> +/* We always want them as intrinsics, no functions. */ +# pragma intrinsic(__vmx_on) +# pragma intrinsic(__vmx_off) +# pragma intrinsic(__vmx_vmclear) +# pragma intrinsic(__vmx_vmptrld) +# pragma intrinsic(__vmx_vmread) +# pragma intrinsic(__vmx_vmwrite) +# define VMX_USE_MSC_INTRINSICS 1 +#else +# define VMX_USE_MSC_INTRINSICS 0 +#endif + + +/** @defgroup grp_vmx vmx Types and Definitions + * @ingroup grp_hm + * @{ + */ + +/** @def HMVMXCPU_GST_SET_UPDATED + * Sets a guest-state-updated flag. + * + * @param pVCpu Pointer to the VMCPU. + * @param fFlag The flag to set. + */ +#define HMVMXCPU_GST_SET_UPDATED(pVCpu, fFlag) (ASMAtomicUoOrU32(&(pVCpu)->hm.s.vmx.fUpdatedGuestState, (fFlag))) + +/** @def HMVMXCPU_GST_IS_SET + * Checks if all the flags in the specified guest-state-updated set is pending. + * + * @param pVCpu Pointer to the VMCPU. + * @param fFlag The flag to check. + */ +#define HMVMXCPU_GST_IS_SET(pVCpu, fFlag) ((ASMAtomicUoReadU32(&(pVCpu)->hm.s.vmx.fUpdatedGuestState) & (fFlag)) == (fFlag)) + +/** @def HMVMXCPU_GST_IS_UPDATED + * Checks if one or more of the flags in the specified guest-state-updated set + * is updated. + * + * @param pVCpu Pointer to the VMCPU. + * @param fFlags The flags to check for. + */ +#define HMVMXCPU_GST_IS_UPDATED(pVCpu, fFlags) RT_BOOL(ASMAtomicUoReadU32(&(pVCpu)->hm.s.vmx.fUpdatedGuestState) & (fFlags)) + +/** @def HMVMXCPU_GST_RESET_TO + * Resets the guest-state-updated flags to the specified value. + * + * @param pVCpu Pointer to the VMCPU. + * @param fFlags The new value. + */ +#define HMVMXCPU_GST_RESET_TO(pVCpu, fFlags) (ASMAtomicUoWriteU32(&(pVCpu)->hm.s.vmx.fUpdatedGuestState, (fFlags))) + +/** @def HMVMXCPU_GST_VALUE + * Returns the current guest-state-updated flags value. + * + * @param pVCpu Pointer to the VMCPU. + */ +#define HMVMXCPU_GST_VALUE(pVCpu) (ASMAtomicUoReadU32(&(pVCpu)->hm.s.vmx.fUpdatedGuestState)) + +/** @name Host-state restoration flags. + * @{ + */ +/* If you change these values don't forget to update the assembly defines as well! */ +#define VMX_RESTORE_HOST_SEL_DS RT_BIT(0) +#define VMX_RESTORE_HOST_SEL_ES RT_BIT(1) +#define VMX_RESTORE_HOST_SEL_FS RT_BIT(2) +#define VMX_RESTORE_HOST_SEL_GS RT_BIT(3) +#define VMX_RESTORE_HOST_SEL_TR RT_BIT(4) +#define VMX_RESTORE_HOST_GDTR RT_BIT(5) +#define VMX_RESTORE_HOST_IDTR RT_BIT(6) +#define VMX_RESTORE_HOST_REQUIRED RT_BIT(7) +/** @} */ + +/** + * Host-state restoration structure. + * This holds host-state fields that require manual restoration. + * Assembly version found in hm_vmx.mac (should be automatically verified). + */ +typedef struct VMXRESTOREHOST +{ + RTSEL uHostSelDS; /* 0x00 */ + RTSEL uHostSelES; /* 0x02 */ + RTSEL uHostSelFS; /* 0x04 */ + RTSEL uHostSelGS; /* 0x06 */ + RTSEL uHostSelTR; /* 0x08 */ + uint8_t abPadding0[4]; + X86XDTR64 HostGdtr; /**< 0x0e - should be aligned by it's 64-bit member. */ + uint8_t abPadding1[6]; + X86XDTR64 HostIdtr; /**< 0x1e - should be aligned by it's 64-bit member. */ + uint64_t uHostFSBase; /* 0x28 */ + uint64_t uHostGSBase; /* 0x30 */ +} VMXRESTOREHOST; +/** Pointer to VMXRESTOREHOST. */ +typedef VMXRESTOREHOST *PVMXRESTOREHOST; +AssertCompileSize(X86XDTR64, 10); +AssertCompileMemberOffset(VMXRESTOREHOST, HostGdtr.uAddr, 16); +AssertCompileMemberOffset(VMXRESTOREHOST, HostIdtr.uAddr, 32); +AssertCompileMemberOffset(VMXRESTOREHOST, uHostFSBase, 40); +AssertCompileSize(VMXRESTOREHOST, 56); + +/** @name VMX HM-error codes for VERR_HM_UNSUPPORTED_CPU_FEATURE_COMBO. + * UFC = Unsupported Feature Combination. + * @{ + */ +/** Unsupported pin-based VM-execution controls combo. */ +#define VMX_UFC_CTRL_PIN_EXEC 0 +/** Unsupported processor-based VM-execution controls combo. */ +#define VMX_UFC_CTRL_PROC_EXEC 1 +/** Unsupported pin-based VM-execution controls combo. */ +#define VMX_UFC_CTRL_PROC_MOV_DRX_EXIT 2 +/** Unsupported VM-entry controls combo. */ +#define VMX_UFC_CTRL_ENTRY 3 +/** Unsupported VM-exit controls combo. */ +#define VMX_UFC_CTRL_EXIT 4 +/** MSR storage capacity of the VMCS autoload/store area is not sufficient + * for storing host MSRs. */ +#define VMX_UFC_INSUFFICIENT_HOST_MSR_STORAGE 5 +/** MSR storage capacity of the VMCS autoload/store area is not sufficient + * for storing guest MSRs. */ +#define VMX_UFC_INSUFFICIENT_GUEST_MSR_STORAGE 6 +/** Invalid VMCS size. */ +#define VMX_UFC_INVALID_VMCS_SIZE 7 +/** @} */ + +/** @name VMX HM-error codes for VERR_VMX_INVALID_GUEST_STATE. + * IGS = Invalid Guest State. + * @{ + */ +/** An error occurred while checking invalid-guest-state. */ +#define VMX_IGS_ERROR 0 +/** The invalid guest-state checks did not find any reason why. */ +#define VMX_IGS_REASON_NOT_FOUND 1 +/** CR0 fixed1 bits invalid. */ +#define VMX_IGS_CR0_FIXED1 2 +/** CR0 fixed0 bits invalid. */ +#define VMX_IGS_CR0_FIXED0 3 +/** CR0.PE and CR0.PE invalid VT-x/host combination. */ +#define VMX_IGS_CR0_PG_PE_COMBO 4 +/** CR4 fixed1 bits invalid. */ +#define VMX_IGS_CR4_FIXED1 5 +/** CR4 fixed0 bits invalid. */ +#define VMX_IGS_CR4_FIXED0 6 +/** Reserved bits in VMCS' DEBUGCTL MSR field not set to 0 when + * VMX_VMCS_CTRL_ENTRY_LOAD_DEBUG is used. */ +#define VMX_IGS_DEBUGCTL_MSR_RESERVED 7 +/** CR0.PG not set for long-mode when not using unrestricted guest. */ +#define VMX_IGS_CR0_PG_LONGMODE 8 +/** CR4.PAE not set for long-mode guest when not using unrestricted guest. */ +#define VMX_IGS_CR4_PAE_LONGMODE 9 +/** CR4.PCIDE set for 32-bit guest. */ +#define VMX_IGS_CR4_PCIDE 10 +/** VMCS' DR7 reserved bits not set to 0. */ +#define VMX_IGS_DR7_RESERVED 11 +/** VMCS' PERF_GLOBAL MSR reserved bits not set to 0. */ +#define VMX_IGS_PERF_GLOBAL_MSR_RESERVED 12 +/** VMCS' EFER MSR reserved bits not set to 0. */ +#define VMX_IGS_EFER_MSR_RESERVED 13 +/** VMCS' EFER MSR.LMA does not match the IA32e mode guest control. */ +#define VMX_IGS_EFER_LMA_GUEST_MODE_MISMATCH 14 +/** VMCS' EFER MSR.LMA does not match CR0.PG of the guest when not using + * unrestricted guest. */ +#define VMX_IGS_EFER_LMA_PG_MISMATCH 15 +/** CS.Attr.P bit invalid. */ +#define VMX_IGS_CS_ATTR_P_INVALID 16 +/** CS.Attr reserved bits not set to 0. */ +#define VMX_IGS_CS_ATTR_RESERVED 17 +/** CS.Attr.G bit invalid. */ +#define VMX_IGS_CS_ATTR_G_INVALID 18 +/** CS is unusable. */ +#define VMX_IGS_CS_ATTR_UNUSABLE 19 +/** CS and SS DPL unequal. */ +#define VMX_IGS_CS_SS_ATTR_DPL_UNEQUAL 20 +/** CS and SS DPL mismatch. */ +#define VMX_IGS_CS_SS_ATTR_DPL_MISMATCH 21 +/** CS Attr.Type invalid. */ +#define VMX_IGS_CS_ATTR_TYPE_INVALID 22 +/** CS and SS RPL unequal. */ +#define VMX_IGS_SS_CS_RPL_UNEQUAL 23 +/** SS.Attr.DPL and SS RPL unequal. */ +#define VMX_IGS_SS_ATTR_DPL_RPL_UNEQUAL 24 +/** SS.Attr.DPL invalid for segment type. */ +#define VMX_IGS_SS_ATTR_DPL_INVALID 25 +/** SS.Attr.Type invalid. */ +#define VMX_IGS_SS_ATTR_TYPE_INVALID 26 +/** SS.Attr.P bit invalid. */ +#define VMX_IGS_SS_ATTR_P_INVALID 27 +/** SS.Attr reserved bits not set to 0. */ +#define VMX_IGS_SS_ATTR_RESERVED 28 +/** SS.Attr.G bit invalid. */ +#define VMX_IGS_SS_ATTR_G_INVALID 29 +/** DS.Attr.A bit invalid. */ +#define VMX_IGS_DS_ATTR_A_INVALID 30 +/** DS.Attr.P bit invalid. */ +#define VMX_IGS_DS_ATTR_P_INVALID 31 +/** DS.Attr.DPL and DS RPL unequal. */ +#define VMX_IGS_DS_ATTR_DPL_RPL_UNEQUAL 32 +/** DS.Attr reserved bits not set to 0. */ +#define VMX_IGS_DS_ATTR_RESERVED 33 +/** DS.Attr.G bit invalid. */ +#define VMX_IGS_DS_ATTR_G_INVALID 34 +/** DS.Attr.Type invalid. */ +#define VMX_IGS_DS_ATTR_TYPE_INVALID 35 +/** ES.Attr.A bit invalid. */ +#define VMX_IGS_ES_ATTR_A_INVALID 36 +/** ES.Attr.P bit invalid. */ +#define VMX_IGS_ES_ATTR_P_INVALID 37 +/** ES.Attr.DPL and DS RPL unequal. */ +#define VMX_IGS_ES_ATTR_DPL_RPL_UNEQUAL 38 +/** ES.Attr reserved bits not set to 0. */ +#define VMX_IGS_ES_ATTR_RESERVED 39 +/** ES.Attr.G bit invalid. */ +#define VMX_IGS_ES_ATTR_G_INVALID 40 +/** ES.Attr.Type invalid. */ +#define VMX_IGS_ES_ATTR_TYPE_INVALID 41 +/** FS.Attr.A bit invalid. */ +#define VMX_IGS_FS_ATTR_A_INVALID 42 +/** FS.Attr.P bit invalid. */ +#define VMX_IGS_FS_ATTR_P_INVALID 43 +/** FS.Attr.DPL and DS RPL unequal. */ +#define VMX_IGS_FS_ATTR_DPL_RPL_UNEQUAL 44 +/** FS.Attr reserved bits not set to 0. */ +#define VMX_IGS_FS_ATTR_RESERVED 45 +/** FS.Attr.G bit invalid. */ +#define VMX_IGS_FS_ATTR_G_INVALID 46 +/** FS.Attr.Type invalid. */ +#define VMX_IGS_FS_ATTR_TYPE_INVALID 47 +/** GS.Attr.A bit invalid. */ +#define VMX_IGS_GS_ATTR_A_INVALID 48 +/** GS.Attr.P bit invalid. */ +#define VMX_IGS_GS_ATTR_P_INVALID 49 +/** GS.Attr.DPL and DS RPL unequal. */ +#define VMX_IGS_GS_ATTR_DPL_RPL_UNEQUAL 50 +/** GS.Attr reserved bits not set to 0. */ +#define VMX_IGS_GS_ATTR_RESERVED 51 +/** GS.Attr.G bit invalid. */ +#define VMX_IGS_GS_ATTR_G_INVALID 52 +/** GS.Attr.Type invalid. */ +#define VMX_IGS_GS_ATTR_TYPE_INVALID 53 +/** V86 mode CS.Base invalid. */ +#define VMX_IGS_V86_CS_BASE_INVALID 54 +/** V86 mode CS.Limit invalid. */ +#define VMX_IGS_V86_CS_LIMIT_INVALID 55 +/** V86 mode CS.Attr invalid. */ +#define VMX_IGS_V86_CS_ATTR_INVALID 56 +/** V86 mode SS.Base invalid. */ +#define VMX_IGS_V86_SS_BASE_INVALID 57 +/** V86 mode SS.Limit invalid. */ +#define VMX_IGS_V86_SS_LIMIT_INVALID 59 +/** V86 mode SS.Attr invalid. */ +#define VMX_IGS_V86_SS_ATTR_INVALID 59 +/** V86 mode DS.Base invalid. */ +#define VMX_IGS_V86_DS_BASE_INVALID 60 +/** V86 mode DS.Limit invalid. */ +#define VMX_IGS_V86_DS_LIMIT_INVALID 61 +/** V86 mode DS.Attr invalid. */ +#define VMX_IGS_V86_DS_ATTR_INVALID 62 +/** V86 mode ES.Base invalid. */ +#define VMX_IGS_V86_ES_BASE_INVALID 63 +/** V86 mode ES.Limit invalid. */ +#define VMX_IGS_V86_ES_LIMIT_INVALID 64 +/** V86 mode ES.Attr invalid. */ +#define VMX_IGS_V86_ES_ATTR_INVALID 65 +/** V86 mode FS.Base invalid. */ +#define VMX_IGS_V86_FS_BASE_INVALID 66 +/** V86 mode FS.Limit invalid. */ +#define VMX_IGS_V86_FS_LIMIT_INVALID 67 +/** V86 mode FS.Attr invalid. */ +#define VMX_IGS_V86_FS_ATTR_INVALID 68 +/** V86 mode GS.Base invalid. */ +#define VMX_IGS_V86_GS_BASE_INVALID 69 +/** V86 mode GS.Limit invalid. */ +#define VMX_IGS_V86_GS_LIMIT_INVALID 70 +/** V86 mode GS.Attr invalid. */ +#define VMX_IGS_V86_GS_ATTR_INVALID 71 +/** Longmode CS.Base invalid. */ +#define VMX_IGS_LONGMODE_CS_BASE_INVALID 72 +/** Longmode SS.Base invalid. */ +#define VMX_IGS_LONGMODE_SS_BASE_INVALID 73 +/** Longmode DS.Base invalid. */ +#define VMX_IGS_LONGMODE_DS_BASE_INVALID 74 +/** Longmode ES.Base invalid. */ +#define VMX_IGS_LONGMODE_ES_BASE_INVALID 75 +/** SYSENTER ESP is not canonical. */ +#define VMX_IGS_SYSENTER_ESP_NOT_CANONICAL 76 +/** SYSENTER EIP is not canonical. */ +#define VMX_IGS_SYSENTER_EIP_NOT_CANONICAL 77 +/** PAT MSR invalid. */ +#define VMX_IGS_PAT_MSR_INVALID 78 +/** PAT MSR reserved bits not set to 0. */ +#define VMX_IGS_PAT_MSR_RESERVED 79 +/** GDTR.Base is not canonical. */ +#define VMX_IGS_GDTR_BASE_NOT_CANONICAL 80 +/** IDTR.Base is not canonical. */ +#define VMX_IGS_IDTR_BASE_NOT_CANONICAL 81 +/** GDTR.Limit invalid. */ +#define VMX_IGS_GDTR_LIMIT_INVALID 82 +/** IDTR.Limit invalid. */ +#define VMX_IGS_IDTR_LIMIT_INVALID 83 +/** Longmode RIP is invalid. */ +#define VMX_IGS_LONGMODE_RIP_INVALID 84 +/** RFLAGS reserved bits not set to 0. */ +#define VMX_IGS_RFLAGS_RESERVED 85 +/** RFLAGS RA1 reserved bits not set to 1. */ +#define VMX_IGS_RFLAGS_RESERVED1 86 +/** RFLAGS.VM (V86 mode) invalid. */ +#define VMX_IGS_RFLAGS_VM_INVALID 87 +/** RFLAGS.IF invalid. */ +#define VMX_IGS_RFLAGS_IF_INVALID 88 +/** Activity state invalid. */ +#define VMX_IGS_ACTIVITY_STATE_INVALID 89 +/** Activity state HLT invalid when SS.Attr.DPL is not zero. */ +#define VMX_IGS_ACTIVITY_STATE_HLT_INVALID 90 +/** Activity state ACTIVE invalid when block-by-STI or MOV SS. */ +#define VMX_IGS_ACTIVITY_STATE_ACTIVE_INVALID 91 +/** Activity state SIPI WAIT invalid. */ +#define VMX_IGS_ACTIVITY_STATE_SIPI_WAIT_INVALID 92 +/** Interruptibility state reserved bits not set to 0. */ +#define VMX_IGS_INTERRUPTIBILITY_STATE_RESERVED 93 +/** Interruptibility state cannot be block-by-STI -and- MOV SS. */ +#define VMX_IGS_INTERRUPTIBILITY_STATE_STI_MOVSS_INVALID 94 +/** Interruptibility state block-by-STI invalid for EFLAGS. */ +#define VMX_IGS_INTERRUPTIBILITY_STATE_STI_EFL_INVALID 95 +/** Interruptibility state invalid while trying to deliver external + * interrupt. */ +#define VMX_IGS_INTERRUPTIBILITY_STATE_EXT_INT_INVALID 96 +/** Interruptibility state block-by-MOVSS invalid while trying to deliver an + * NMI. */ +#define VMX_IGS_INTERRUPTIBILITY_STATE_MOVSS_INVALID 97 +/** Interruptibility state block-by-SMI invalid when CPU is not in SMM. */ +#define VMX_IGS_INTERRUPTIBILITY_STATE_SMI_INVALID 98 +/** Interruptibility state block-by-SMI invalid when trying to enter SMM. */ +#define VMX_IGS_INTERRUPTIBILITY_STATE_SMI_SMM_INVALID 99 +/** Interruptibilty state block-by-STI (maybe) invalid when trying to deliver + * an NMI. */ +#define VMX_IGS_INTERRUPTIBILITY_STATE_STI_INVALID 100 +/** Interruptibility state block-by-NMI invalid when virtual-NMIs control is + * active. */ +#define VMX_IGS_INTERRUPTIBILITY_STATE_NMI_INVALID 101 +/** Pending debug exceptions reserved bits not set to 0. */ +#define VMX_IGS_PENDING_DEBUG_RESERVED 102 +/** Longmode pending debug exceptions reserved bits not set to 0. */ +#define VMX_IGS_LONGMODE_PENDING_DEBUG_RESERVED 103 +/** Pending debug exceptions.BS bit is not set when it should be. */ +#define VMX_IGS_PENDING_DEBUG_XCPT_BS_NOT_SET 104 +/** Pending debug exceptions.BS bit is not clear when it should be. */ +#define VMX_IGS_PENDING_DEBUG_XCPT_BS_NOT_CLEAR 105 +/** VMCS link pointer reserved bits not set to 0. */ +#define VMX_IGS_VMCS_LINK_PTR_RESERVED 106 +/** TR cannot index into LDT, TI bit MBZ. */ +#define VMX_IGS_TR_TI_INVALID 107 +/** LDTR cannot index into LDT. TI bit MBZ. */ +#define VMX_IGS_LDTR_TI_INVALID 108 +/** TR.Base is not canonical. */ +#define VMX_IGS_TR_BASE_NOT_CANONICAL 109 +/** FS.Base is not canonical. */ +#define VMX_IGS_FS_BASE_NOT_CANONICAL 110 +/** GS.Base is not canonical. */ +#define VMX_IGS_GS_BASE_NOT_CANONICAL 111 +/** LDTR.Base is not canonical. */ +#define VMX_IGS_LDTR_BASE_NOT_CANONICAL 112 +/** TR is unusable. */ +#define VMX_IGS_TR_ATTR_UNUSABLE 113 +/** TR.Attr.S bit invalid. */ +#define VMX_IGS_TR_ATTR_S_INVALID 114 +/** TR is not present. */ +#define VMX_IGS_TR_ATTR_P_INVALID 115 +/** TR.Attr reserved bits not set to 0. */ +#define VMX_IGS_TR_ATTR_RESERVED 116 +/** TR.Attr.G bit invalid. */ +#define VMX_IGS_TR_ATTR_G_INVALID 117 +/** Longmode TR.Attr.Type invalid. */ +#define VMX_IGS_LONGMODE_TR_ATTR_TYPE_INVALID 118 +/** TR.Attr.Type invalid. */ +#define VMX_IGS_TR_ATTR_TYPE_INVALID 119 +/** CS.Attr.S invalid. */ +#define VMX_IGS_CS_ATTR_S_INVALID 120 +/** CS.Attr.DPL invalid. */ +#define VMX_IGS_CS_ATTR_DPL_INVALID 121 +/** PAE PDPTE reserved bits not set to 0. */ +#define VMX_IGS_PAE_PDPTE_RESERVED 123 +/** @} */ + +/** @name VMX VMCS-Read cache indices. + * @{ + */ +# define VMX_VMCS_GUEST_ES_BASE_CACHE_IDX 0 +# define VMX_VMCS_GUEST_CS_BASE_CACHE_IDX 1 +# define VMX_VMCS_GUEST_SS_BASE_CACHE_IDX 2 +# define VMX_VMCS_GUEST_DS_BASE_CACHE_IDX 3 +# define VMX_VMCS_GUEST_FS_BASE_CACHE_IDX 4 +# define VMX_VMCS_GUEST_GS_BASE_CACHE_IDX 5 +# define VMX_VMCS_GUEST_LDTR_BASE_CACHE_IDX 6 +# define VMX_VMCS_GUEST_TR_BASE_CACHE_IDX 7 +# define VMX_VMCS_GUEST_GDTR_BASE_CACHE_IDX 8 +# define VMX_VMCS_GUEST_IDTR_BASE_CACHE_IDX 9 +# define VMX_VMCS_GUEST_RSP_CACHE_IDX 10 +# define VMX_VMCS_GUEST_RIP_CACHE_IDX 11 +# define VMX_VMCS_GUEST_SYSENTER_ESP_CACHE_IDX 12 +# define VMX_VMCS_GUEST_SYSENTER_EIP_CACHE_IDX 13 +# define VMX_VMCS_RO_EXIT_QUALIFICATION_CACHE_IDX 14 +# define VMX_VMCS_MAX_CACHE_IDX (VMX_VMCS_RO_EXIT_QUALIFICATION_CACHE_IDX + 1) +# define VMX_VMCS_GUEST_CR3_CACHE_IDX 15 +# define VMX_VMCS_MAX_NESTED_PAGING_CACHE_IDX (VMX_VMCS_GUEST_CR3_CACHE_IDX + 1) +/** @} */ + +/** @name VMX EPT paging structures + * @{ + */ + +/** + * Number of page table entries in the EPT. (PDPTE/PDE/PTE) + */ +#define EPT_PG_ENTRIES X86_PG_PAE_ENTRIES + +/** + * EPT Page Directory Pointer Entry. Bit view. + * @todo uint64_t isn't safe for bitfields (gcc pedantic warnings, and IIRC, + * this did cause trouble with one compiler/version). + */ +#pragma pack(1) +typedef struct EPTPML4EBITS +{ + /** Present bit. */ + uint64_t u1Present : 1; + /** Writable bit. */ + uint64_t u1Write : 1; + /** Executable bit. */ + uint64_t u1Execute : 1; + /** Reserved (must be 0). */ + uint64_t u5Reserved : 5; + /** Available for software. */ + uint64_t u4Available : 4; + /** Physical address of the next level (PD). Restricted by maximum physical address width of the cpu. */ + uint64_t u40PhysAddr : 40; + /** Availabe for software. */ + uint64_t u12Available : 12; +} EPTPML4EBITS; +#pragma pack() +AssertCompileSize(EPTPML4EBITS, 8); + +/** Bits 12-51 - - EPT - Physical Page number of the next level. */ +#define EPT_PML4E_PG_MASK X86_PML4E_PG_MASK +/** The page shift to get the PML4 index. */ +#define EPT_PML4_SHIFT X86_PML4_SHIFT +/** The PML4 index mask (apply to a shifted page address). */ +#define EPT_PML4_MASK X86_PML4_MASK + +/** + * EPT PML4E. + */ +#pragma pack(1) +typedef union EPTPML4E +{ + /** Normal view. */ + EPTPML4EBITS n; + /** Unsigned integer view. */ + X86PGPAEUINT u; + /** 64 bit unsigned integer view. */ + uint64_t au64[1]; + /** 32 bit unsigned integer view. */ + uint32_t au32[2]; +} EPTPML4E; +#pragma pack() +/** Pointer to a PML4 table entry. */ +typedef EPTPML4E *PEPTPML4E; +/** Pointer to a const PML4 table entry. */ +typedef const EPTPML4E *PCEPTPML4E; +AssertCompileSize(EPTPML4E, 8); + +/** + * EPT PML4 Table. + */ +#pragma pack(1) +typedef struct EPTPML4 +{ + EPTPML4E a[EPT_PG_ENTRIES]; +} EPTPML4; +#pragma pack() +/** Pointer to an EPT PML4 Table. */ +typedef EPTPML4 *PEPTPML4; +/** Pointer to a const EPT PML4 Table. */ +typedef const EPTPML4 *PCEPTPML4; + +/** + * EPT Page Directory Pointer Entry. Bit view. + */ +#pragma pack(1) +typedef struct EPTPDPTEBITS +{ + /** Present bit. */ + uint64_t u1Present : 1; + /** Writable bit. */ + uint64_t u1Write : 1; + /** Executable bit. */ + uint64_t u1Execute : 1; + /** Reserved (must be 0). */ + uint64_t u5Reserved : 5; + /** Available for software. */ + uint64_t u4Available : 4; + /** Physical address of the next level (PD). Restricted by maximum physical address width of the cpu. */ + uint64_t u40PhysAddr : 40; + /** Availabe for software. */ + uint64_t u12Available : 12; +} EPTPDPTEBITS; +#pragma pack() +AssertCompileSize(EPTPDPTEBITS, 8); + +/** Bits 12-51 - - EPT - Physical Page number of the next level. */ +#define EPT_PDPTE_PG_MASK X86_PDPE_PG_MASK +/** The page shift to get the PDPT index. */ +#define EPT_PDPT_SHIFT X86_PDPT_SHIFT +/** The PDPT index mask (apply to a shifted page address). */ +#define EPT_PDPT_MASK X86_PDPT_MASK_AMD64 + +/** + * EPT Page Directory Pointer. + */ +#pragma pack(1) +typedef union EPTPDPTE +{ + /** Normal view. */ + EPTPDPTEBITS n; + /** Unsigned integer view. */ + X86PGPAEUINT u; + /** 64 bit unsigned integer view. */ + uint64_t au64[1]; + /** 32 bit unsigned integer view. */ + uint32_t au32[2]; +} EPTPDPTE; +#pragma pack() +/** Pointer to an EPT Page Directory Pointer Entry. */ +typedef EPTPDPTE *PEPTPDPTE; +/** Pointer to a const EPT Page Directory Pointer Entry. */ +typedef const EPTPDPTE *PCEPTPDPTE; +AssertCompileSize(EPTPDPTE, 8); + +/** + * EPT Page Directory Pointer Table. + */ +#pragma pack(1) +typedef struct EPTPDPT +{ + EPTPDPTE a[EPT_PG_ENTRIES]; +} EPTPDPT; +#pragma pack() +/** Pointer to an EPT Page Directory Pointer Table. */ +typedef EPTPDPT *PEPTPDPT; +/** Pointer to a const EPT Page Directory Pointer Table. */ +typedef const EPTPDPT *PCEPTPDPT; + + +/** + * EPT Page Directory Table Entry. Bit view. + */ +#pragma pack(1) +typedef struct EPTPDEBITS +{ + /** Present bit. */ + uint64_t u1Present : 1; + /** Writable bit. */ + uint64_t u1Write : 1; + /** Executable bit. */ + uint64_t u1Execute : 1; + /** Reserved (must be 0). */ + uint64_t u4Reserved : 4; + /** Big page (must be 0 here). */ + uint64_t u1Size : 1; + /** Available for software. */ + uint64_t u4Available : 4; + /** Physical address of page table. Restricted by maximum physical address width of the cpu. */ + uint64_t u40PhysAddr : 40; + /** Availabe for software. */ + uint64_t u12Available : 12; +} EPTPDEBITS; +#pragma pack() +AssertCompileSize(EPTPDEBITS, 8); + +/** Bits 12-51 - - EPT - Physical Page number of the next level. */ +#define EPT_PDE_PG_MASK X86_PDE_PAE_PG_MASK +/** The page shift to get the PD index. */ +#define EPT_PD_SHIFT X86_PD_PAE_SHIFT +/** The PD index mask (apply to a shifted page address). */ +#define EPT_PD_MASK X86_PD_PAE_MASK + +/** + * EPT 2MB Page Directory Table Entry. Bit view. + */ +#pragma pack(1) +typedef struct EPTPDE2MBITS +{ + /** Present bit. */ + uint64_t u1Present : 1; + /** Writable bit. */ + uint64_t u1Write : 1; + /** Executable bit. */ + uint64_t u1Execute : 1; + /** EPT Table Memory Type. MBZ for non-leaf nodes. */ + uint64_t u3EMT : 3; + /** Ignore PAT memory type */ + uint64_t u1IgnorePAT : 1; + /** Big page (must be 1 here). */ + uint64_t u1Size : 1; + /** Available for software. */ + uint64_t u4Available : 4; + /** Reserved (must be 0). */ + uint64_t u9Reserved : 9; + /** Physical address of the 2MB page. Restricted by maximum physical address width of the cpu. */ + uint64_t u31PhysAddr : 31; + /** Availabe for software. */ + uint64_t u12Available : 12; +} EPTPDE2MBITS; +#pragma pack() +AssertCompileSize(EPTPDE2MBITS, 8); + +/** Bits 21-51 - - EPT - Physical Page number of the next level. */ +#define EPT_PDE2M_PG_MASK X86_PDE2M_PAE_PG_MASK + +/** + * EPT Page Directory Table Entry. + */ +#pragma pack(1) +typedef union EPTPDE +{ + /** Normal view. */ + EPTPDEBITS n; + /** 2MB view (big). */ + EPTPDE2MBITS b; + /** Unsigned integer view. */ + X86PGPAEUINT u; + /** 64 bit unsigned integer view. */ + uint64_t au64[1]; + /** 32 bit unsigned integer view. */ + uint32_t au32[2]; +} EPTPDE; +#pragma pack() +/** Pointer to an EPT Page Directory Table Entry. */ +typedef EPTPDE *PEPTPDE; +/** Pointer to a const EPT Page Directory Table Entry. */ +typedef const EPTPDE *PCEPTPDE; +AssertCompileSize(EPTPDE, 8); + +/** + * EPT Page Directory Table. + */ +#pragma pack(1) +typedef struct EPTPD +{ + EPTPDE a[EPT_PG_ENTRIES]; +} EPTPD; +#pragma pack() +/** Pointer to an EPT Page Directory Table. */ +typedef EPTPD *PEPTPD; +/** Pointer to a const EPT Page Directory Table. */ +typedef const EPTPD *PCEPTPD; + + +/** + * EPT Page Table Entry. Bit view. + */ +#pragma pack(1) +typedef struct EPTPTEBITS +{ + /** 0 - Present bit. + * @remark This is a convenience "misnomer". The bit actually indicates + * read access and the CPU will consider an entry with any of the + * first three bits set as present. Since all our valid entries + * will have this bit set, it can be used as a present indicator + * and allow some code sharing. */ + uint64_t u1Present : 1; + /** 1 - Writable bit. */ + uint64_t u1Write : 1; + /** 2 - Executable bit. */ + uint64_t u1Execute : 1; + /** 5:3 - EPT Memory Type. MBZ for non-leaf nodes. */ + uint64_t u3EMT : 3; + /** 6 - Ignore PAT memory type */ + uint64_t u1IgnorePAT : 1; + /** 11:7 - Available for software. */ + uint64_t u5Available : 5; + /** 51:12 - Physical address of page. Restricted by maximum physical + * address width of the cpu. */ + uint64_t u40PhysAddr : 40; + /** 63:52 - Available for software. */ + uint64_t u12Available : 12; +} EPTPTEBITS; +#pragma pack() +AssertCompileSize(EPTPTEBITS, 8); + +/** Bits 12-51 - - EPT - Physical Page number of the next level. */ +#define EPT_PTE_PG_MASK X86_PTE_PAE_PG_MASK +/** The page shift to get the EPT PTE index. */ +#define EPT_PT_SHIFT X86_PT_PAE_SHIFT +/** The EPT PT index mask (apply to a shifted page address). */ +#define EPT_PT_MASK X86_PT_PAE_MASK + +/** + * EPT Page Table Entry. + */ +#pragma pack(1) +typedef union EPTPTE +{ + /** Normal view. */ + EPTPTEBITS n; + /** Unsigned integer view. */ + X86PGPAEUINT u; + /** 64 bit unsigned integer view. */ + uint64_t au64[1]; + /** 32 bit unsigned integer view. */ + uint32_t au32[2]; +} EPTPTE; +#pragma pack() +/** Pointer to an EPT Page Directory Table Entry. */ +typedef EPTPTE *PEPTPTE; +/** Pointer to a const EPT Page Directory Table Entry. */ +typedef const EPTPTE *PCEPTPTE; +AssertCompileSize(EPTPTE, 8); + +/** + * EPT Page Table. + */ +#pragma pack(1) +typedef struct EPTPT +{ + EPTPTE a[EPT_PG_ENTRIES]; +} EPTPT; +#pragma pack() +/** Pointer to an extended page table. */ +typedef EPTPT *PEPTPT; +/** Pointer to a const extended table. */ +typedef const EPTPT *PCEPTPT; + +/** + * VPID flush types. + */ +typedef enum +{ + /** Invalidate a specific page. */ + VMX_FLUSH_VPID_INDIV_ADDR = 0, + /** Invalidate one context (specific VPID). */ + VMX_FLUSH_VPID_SINGLE_CONTEXT = 1, + /** Invalidate all contexts (all VPIDs). */ + VMX_FLUSH_VPID_ALL_CONTEXTS = 2, + /** Invalidate a single VPID context retaining global mappings. */ + VMX_FLUSH_VPID_SINGLE_CONTEXT_RETAIN_GLOBALS = 3, + /** Unsupported by VirtualBox. */ + VMX_FLUSH_VPID_NOT_SUPPORTED = 0xbad, + /** Unsupported by CPU. */ + VMX_FLUSH_VPID_NONE = 0xb00, + /** 32bit hackishness. */ + VMX_FLUSH_VPID_32BIT_HACK = 0x7fffffff +} VMX_FLUSH_VPID; + +/** + * EPT flush types. + */ +typedef enum +{ + /** Invalidate one context (specific EPT). */ + VMX_FLUSH_EPT_SINGLE_CONTEXT = 1, + /* Invalidate all contexts (all EPTs) */ + VMX_FLUSH_EPT_ALL_CONTEXTS = 2, + /** Unsupported by VirtualBox. */ + VMX_FLUSH_EPT_NOT_SUPPORTED = 0xbad, + /** Unsupported by CPU. */ + VMX_FLUSH_EPT_NONE = 0xb00, + /** 32bit hackishness. */ + VMX_FLUSH_EPT_32BIT_HACK = 0x7fffffff +} VMX_FLUSH_EPT; +/** @} */ + +/** @name MSR autoload/store elements + * @{ + */ +#pragma pack(1) +typedef struct +{ + uint32_t u32Msr; + uint32_t u32Reserved; + uint64_t u64Value; +} VMXAUTOMSR; +#pragma pack() +/** Pointer to an MSR load/store element. */ +typedef VMXAUTOMSR *PVMXAUTOMSR; +/** Pointer to a const MSR load/store element. */ +typedef const VMXAUTOMSR *PCVMXAUTOMSR; +/** @} */ + +/** @name VMX-capability qword + * @{ + */ +#pragma pack(1) +typedef union +{ + struct + { + /** Bits set here -must- be set in the correpsonding VM-execution controls. */ + uint32_t disallowed0; + /** Bits cleared here -must- be cleared in the corresponding VM-execution + * controls. */ + uint32_t allowed1; + } n; + uint64_t u; +} VMX_CAPABILITY; +#pragma pack() +/** @} */ + +/** @name VMX MSRs. + * @{ + */ +typedef struct VMXMSRS +{ + uint64_t u64FeatureCtrl; + uint64_t u64BasicInfo; + VMX_CAPABILITY VmxPinCtls; + VMX_CAPABILITY VmxProcCtls; + VMX_CAPABILITY VmxProcCtls2; + VMX_CAPABILITY VmxExit; + VMX_CAPABILITY VmxEntry; + uint64_t u64Misc; + uint64_t u64Cr0Fixed0; + uint64_t u64Cr0Fixed1; + uint64_t u64Cr4Fixed0; + uint64_t u64Cr4Fixed1; + uint64_t u64VmcsEnum; + uint64_t u64Vmfunc; + uint64_t u64EptVpidCaps; +} VMXMSRS; +/** Pointer to a VMXMSRS struct. */ +typedef VMXMSRS *PVMXMSRS; +/** @} */ + +/** @name VMX EFLAGS reserved bits. + * @{ + */ +/** And-mask for setting reserved bits to zero */ +#define VMX_EFLAGS_RESERVED_0 (~0xffc08028) +/** Or-mask for setting reserved bits to 1 */ +#define VMX_EFLAGS_RESERVED_1 0x00000002 +/** @} */ + +/** @name VMX Basic Exit Reasons. + * @{ + */ +/** -1 Invalid exit code */ +#define VMX_EXIT_INVALID -1 +/** 0 Exception or non-maskable interrupt (NMI). */ +#define VMX_EXIT_XCPT_OR_NMI 0 +/** 1 External interrupt. */ +#define VMX_EXIT_EXT_INT 1 +/** 2 Triple fault. */ +#define VMX_EXIT_TRIPLE_FAULT 2 +/** 3 INIT signal. */ +#define VMX_EXIT_INIT_SIGNAL 3 +/** 4 Start-up IPI (SIPI). */ +#define VMX_EXIT_SIPI 4 +/** 5 I/O system-management interrupt (SMI). */ +#define VMX_EXIT_IO_SMI 5 +/** 6 Other SMI. */ +#define VMX_EXIT_SMI 6 +/** 7 Interrupt window exiting. */ +#define VMX_EXIT_INT_WINDOW 7 +/** 8 NMI window exiting. */ +#define VMX_EXIT_NMI_WINDOW 8 +/** 9 Task switch. */ +#define VMX_EXIT_TASK_SWITCH 9 +/** 10 Guest software attempted to execute CPUID. */ +#define VMX_EXIT_CPUID 10 +/** 10 Guest software attempted to execute GETSEC. */ +#define VMX_EXIT_GETSEC 11 +/** 12 Guest software attempted to execute HLT. */ +#define VMX_EXIT_HLT 12 +/** 13 Guest software attempted to execute INVD. */ +#define VMX_EXIT_INVD 13 +/** 14 Guest software attempted to execute INVLPG. */ +#define VMX_EXIT_INVLPG 14 +/** 15 Guest software attempted to execute RDPMC. */ +#define VMX_EXIT_RDPMC 15 +/** 16 Guest software attempted to execute RDTSC. */ +#define VMX_EXIT_RDTSC 16 +/** 17 Guest software attempted to execute RSM in SMM. */ +#define VMX_EXIT_RSM 17 +/** 18 Guest software executed VMCALL. */ +#define VMX_EXIT_VMCALL 18 +/** 19 Guest software executed VMCLEAR. */ +#define VMX_EXIT_VMCLEAR 19 +/** 20 Guest software executed VMLAUNCH. */ +#define VMX_EXIT_VMLAUNCH 20 +/** 21 Guest software executed VMPTRLD. */ +#define VMX_EXIT_VMPTRLD 21 +/** 22 Guest software executed VMPTRST. */ +#define VMX_EXIT_VMPTRST 22 +/** 23 Guest software executed VMREAD. */ +#define VMX_EXIT_VMREAD 23 +/** 24 Guest software executed VMRESUME. */ +#define VMX_EXIT_VMRESUME 24 +/** 25 Guest software executed VMWRITE. */ +#define VMX_EXIT_VMWRITE 25 +/** 26 Guest software executed VMXOFF. */ +#define VMX_EXIT_VMXOFF 26 +/** 27 Guest software executed VMXON. */ +#define VMX_EXIT_VMXON 27 +/** 28 Control-register accesses. */ +#define VMX_EXIT_MOV_CRX 28 +/** 29 Debug-register accesses. */ +#define VMX_EXIT_MOV_DRX 29 +/** 30 I/O instruction. */ +#define VMX_EXIT_IO_INSTR 30 +/** 31 RDMSR. Guest software attempted to execute RDMSR. */ +#define VMX_EXIT_RDMSR 31 +/** 32 WRMSR. Guest software attempted to execute WRMSR. */ +#define VMX_EXIT_WRMSR 32 +/** 33 VM-entry failure due to invalid guest state. */ +#define VMX_EXIT_ERR_INVALID_GUEST_STATE 33 +/** 34 VM-entry failure due to MSR loading. */ +#define VMX_EXIT_ERR_MSR_LOAD 34 +/** 36 Guest software executed MWAIT. */ +#define VMX_EXIT_MWAIT 36 +/** 37 VM exit due to monitor trap flag. */ +#define VMX_EXIT_MTF 37 +/** 39 Guest software attempted to execute MONITOR. */ +#define VMX_EXIT_MONITOR 39 +/** 40 Guest software attempted to execute PAUSE. */ +#define VMX_EXIT_PAUSE 40 +/** 41 VM-entry failure due to machine-check. */ +#define VMX_EXIT_ERR_MACHINE_CHECK 41 +/** 43 TPR below threshold. Guest software executed MOV to CR8. */ +#define VMX_EXIT_TPR_BELOW_THRESHOLD 43 +/** 44 APIC access. Guest software attempted to access memory at a physical address on the APIC-access page. */ +#define VMX_EXIT_APIC_ACCESS 44 +/** 46 Access to GDTR or IDTR. Guest software attempted to execute LGDT, LIDT, SGDT, or SIDT. */ +#define VMX_EXIT_XDTR_ACCESS 46 +/** 47 Access to LDTR or TR. Guest software attempted to execute LLDT, LTR, SLDT, or STR. */ +#define VMX_EXIT_TR_ACCESS 47 +/** 48 EPT violation. An attempt to access memory with a guest-physical address was disallowed by the configuration of the EPT paging structures. */ +#define VMX_EXIT_EPT_VIOLATION 48 +/** 49 EPT misconfiguration. An attempt to access memory with a guest-physical address encountered a misconfigured EPT paging-structure entry. */ +#define VMX_EXIT_EPT_MISCONFIG 49 +/** 50 INVEPT. Guest software attempted to execute INVEPT. */ +#define VMX_EXIT_INVEPT 50 +/** 51 RDTSCP. Guest software attempted to execute RDTSCP. */ +#define VMX_EXIT_RDTSCP 51 +/** 52 VMX-preemption timer expired. The preemption timer counted down to zero. */ +#define VMX_EXIT_PREEMPT_TIMER 52 +/** 53 INVVPID. Guest software attempted to execute INVVPID. */ +#define VMX_EXIT_INVVPID 53 +/** 54 WBINVD. Guest software attempted to execute WBINVD. */ +#define VMX_EXIT_WBINVD 54 +/** 55 XSETBV. Guest software attempted to execute XSETBV. */ +#define VMX_EXIT_XSETBV 55 +/** 57 RDRAND. Guest software attempted to execute RDRAND. */ +#define VMX_EXIT_RDRAND 57 +/** 58 INVPCID. Guest software attempted to execute INVPCID. */ +#define VMX_EXIT_INVPCID 58 +/** 59 VMFUNC. Guest software attempted to execute VMFUNC. */ +#define VMX_EXIT_VMFUNC 59 +/** The maximum exit value (inclusive). */ +#define VMX_EXIT_MAX (VMX_EXIT_VMFUNC) +/** @} */ + + +/** @name VM Instruction Errors + * @{ + */ +/** VMCALL executed in VMX root operation. */ +#define VMX_ERROR_VMCALL 1 +/** VMCLEAR with invalid physical address. */ +#define VMX_ERROR_VMCLEAR_INVALID_PHYS_ADDR 2 +/** VMCLEAR with VMXON pointer. */ +#define VMX_ERROR_VMCLEAR_INVALID_VMXON_PTR 3 +/** VMLAUNCH with non-clear VMCS. */ +#define VMX_ERROR_VMLAUCH_NON_CLEAR_VMCS 4 +/** VMRESUME with non-launched VMCS. */ +#define VMX_ERROR_VMRESUME_NON_LAUNCHED_VMCS 5 +/** VMRESUME with a corrupted VMCS (indicates corruption of the current VMCS). */ +#define VMX_ERROR_VMRESUME_CORRUPTED_VMCS 6 +/** VM-entry with invalid control field(s). */ +#define VMX_ERROR_VMENTRY_INVALID_CONTROL_FIELDS 7 +/** VM-entry with invalid host-state field(s). */ +#define VMX_ERROR_VMENTRY_INVALID_HOST_STATE 8 +/** VMPTRLD with invalid physical address. */ +#define VMX_ERROR_VMPTRLD_INVALID_PHYS_ADDR 9 +/** VMPTRLD with VMXON pointer. */ +#define VMX_ERROR_VMPTRLD_VMXON_PTR 10 +/** VMPTRLD with incorrect VMCS revision identifier. */ +#define VMX_ERROR_VMPTRLD_WRONG_VMCS_REVISION 11 +/** VMREAD/VMWRITE from/to unsupported VMCS component. */ +#define VMX_ERROR_VMREAD_INVALID_COMPONENT 12 +#define VMX_ERROR_VMWRITE_INVALID_COMPONENT VMX_ERROR_VMREAD_INVALID_COMPONENT +/** VMWRITE to read-only VMCS component. */ +#define VMX_ERROR_VMWRITE_READONLY_COMPONENT 13 +/** VMXON executed in VMX root operation. */ +#define VMX_ERROR_VMXON_IN_VMX_ROOT_OP 15 +/** VM entry with invalid executive-VMCS pointer. */ +#define VMX_ERROR_VMENTRY_INVALID_VMCS_EXEC_PTR 16 +/** VM entry with non-launched executive VMCS. */ +#define VMX_ERROR_VMENTRY_NON_LAUNCHED_EXEC_VMCS 17 +/** VM entry with executive-VMCS pointer not VMXON pointer. */ +#define VMX_ERROR_VMENTRY_EXEC_VMCS_PTR 18 +/** VMCALL with non-clear VMCS. */ +#define VMX_ERROR_VMCALL_NON_CLEAR_VMCS 19 +/** VMCALL with invalid VM-exit control fields. */ +#define VMX_ERROR_VMCALL_INVALID_VMEXIT_FIELDS 20 +/** VMCALL with incorrect MSEG revision identifier. */ +#define VMX_ERROR_VMCALL_INVALID_MSEG_REVISION 22 +/** VMXOFF under dual-monitor treatment of SMIs and SMM. */ +#define VMX_ERROR_VMXOFF_DUAL_MONITOR 23 +/** VMCALL with invalid SMM-monitor features. */ +#define VMX_ERROR_VMCALL_INVALID_SMM_MONITOR 24 +/** VM entry with invalid VM-execution control fields in executive VMCS. */ +#define VMX_ERROR_VMENTRY_INVALID_VM_EXEC_CTRL 25 +/** VM entry with events blocked by MOV SS. */ +#define VMX_ERROR_VMENTRY_MOV_SS 26 +/** Invalid operand to INVEPT/INVVPID. */ +#define VMX_ERROR_INVEPTVPID_INVALID_OPERAND 28 + +/** @} */ + + +/** @name VMX MSRs - Basic VMX information. + * @{ + */ +/** VMCS revision identifier used by the processor. */ +#define MSR_IA32_VMX_BASIC_INFO_VMCS_ID(a) ((a) & 0x7FFFFFFF) +/** Size of the VMCS. */ +#define MSR_IA32_VMX_BASIC_INFO_VMCS_SIZE(a) (((a) >> 32) & 0x1FFF) +/** Width of physical address used for the VMCS. + * 0 -> limited to the available amount of physical ram + * 1 -> within the first 4 GB + */ +#define MSR_IA32_VMX_BASIC_INFO_VMCS_PHYS_WIDTH(a) (((a) >> 48) & 1) +/** Whether the processor supports the dual-monitor treatment of system-management interrupts and system-management code. (always 1) */ +#define MSR_IA32_VMX_BASIC_INFO_VMCS_DUAL_MON(a) (((a) >> 49) & 1) +/** Memory type that must be used for the VMCS. */ +#define MSR_IA32_VMX_BASIC_INFO_VMCS_MEM_TYPE(a) (((a) >> 50) & 0xF) +/** Whether the processor provides additional information for exits due to INS/OUTS. */ +#define MSR_IA32_VMX_BASIC_INFO_VMCS_INS_OUTS(a) RT_BOOL((a) & RT_BIT_64(54)) +/** @} */ + + +/** @name VMX MSRs - Misc VMX info. + * @{ + */ +/** Relationship between the preemption timer and tsc; count down every time bit x of the tsc changes. */ +#define MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(a) ((a) & 0x1f) +/** Whether VM-exit stores EFER.LMA into the "IA32e mode guest" field. */ +#define MSR_IA32_VMX_MISC_STORE_EFERLMA_VMEXIT(a) (((a) >> 5) & 1) +/** Activity states supported by the implementation. */ +#define MSR_IA32_VMX_MISC_ACTIVITY_STATES(a) (((a) >> 6) & 0x7) +/** Number of CR3 target values supported by the processor. (0-256) */ +#define MSR_IA32_VMX_MISC_CR3_TARGET(a) (((a) >> 16) & 0x1FF) +/** Maximum nr of MSRs in the VMCS. (N+1)*512. */ +#define MSR_IA32_VMX_MISC_MAX_MSR(a) (((((a) >> 25) & 0x7) + 1) * 512) +/** Whether RDMSR can be used to read IA32_SMBASE_MSR in SMM. */ +#define MSR_IA32_VMX_MISC_RDMSR_SMBASE_MSR_SMM(a) (((a) >> 15) & 1) +/** Whether bit 2 of IA32_SMM_MONITOR_CTL can be set to 1. */ +#define MSR_IA32_VMX_MISC_SMM_MONITOR_CTL_B2(a) (((a) >> 28) & 1) +/** Whether VMWRITE can be used to write VM-exit information fields. */ +#define MSR_IA32_VMX_MISC_VMWRITE_VMEXIT_INFO(a) (((a) >> 29) & 1) +/** MSEG revision identifier used by the processor. */ +#define MSR_IA32_VMX_MISC_MSEG_ID(a) ((a) >> 32) +/** @} */ + + +/** @name VMX MSRs - VMCS enumeration field info + * @{ + */ +/** Highest field index. */ +#define MSR_IA32_VMX_VMCS_ENUM_HIGHEST_INDEX(a) (((a) >> 1) & 0x1FF) +/** @} */ + + +/** @name MSR_IA32_VMX_EPT_VPID_CAPS; EPT capabilities MSR + * @{ + */ +#define MSR_IA32_VMX_EPT_VPID_CAP_RWX_X_ONLY RT_BIT_64(0) +#define MSR_IA32_VMX_EPT_VPID_CAP_RWX_W_ONLY RT_BIT_64(1) +#define MSR_IA32_VMX_EPT_VPID_CAP_RWX_WX_ONLY RT_BIT_64(2) +#define MSR_IA32_VMX_EPT_VPID_CAP_GAW_21_BITS RT_BIT_64(3) +#define MSR_IA32_VMX_EPT_VPID_CAP_GAW_30_BITS RT_BIT_64(4) +#define MSR_IA32_VMX_EPT_VPID_CAP_GAW_39_BITS RT_BIT_64(5) +#define MSR_IA32_VMX_EPT_VPID_CAP_GAW_48_BITS RT_BIT_64(6) +#define MSR_IA32_VMX_EPT_VPID_CAP_GAW_57_BITS RT_BIT_64(7) +#define MSR_IA32_VMX_EPT_VPID_CAP_EMT_UC RT_BIT_64(8) +#define MSR_IA32_VMX_EPT_VPID_CAP_EMT_WC RT_BIT_64(9) +#define MSR_IA32_VMX_EPT_VPID_CAP_EMT_WT RT_BIT_64(12) +#define MSR_IA32_VMX_EPT_VPID_CAP_EMT_WP RT_BIT_64(13) +#define MSR_IA32_VMX_EPT_VPID_CAP_EMT_WB RT_BIT_64(14) +#define MSR_IA32_VMX_EPT_VPID_CAP_SP_21_BITS RT_BIT_64(16) +#define MSR_IA32_VMX_EPT_VPID_CAP_SP_30_BITS RT_BIT_64(17) +#define MSR_IA32_VMX_EPT_VPID_CAP_SP_39_BITS RT_BIT_64(18) +#define MSR_IA32_VMX_EPT_VPID_CAP_SP_48_BITS RT_BIT_64(19) +#define MSR_IA32_VMX_EPT_VPID_CAP_INVEPT RT_BIT_64(20) +#define MSR_IA32_VMX_EPT_VPID_CAP_INVEPT_SINGLE_CONTEXT RT_BIT_64(25) +#define MSR_IA32_VMX_EPT_VPID_CAP_INVEPT_ALL_CONTEXTS RT_BIT_64(26) +#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID RT_BIT_64(32) +#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_INDIV_ADDR RT_BIT_64(40) +#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_SINGLE_CONTEXT RT_BIT_64(41) +#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_ALL_CONTEXTS RT_BIT_64(42) +#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_SINGLE_CONTEXT_RETAIN_GLOBALS RT_BIT_64(43) + +/** @} */ + +/** @name Extended Page Table Pointer (EPTP) + * @{ + */ +/** Uncachable EPT paging structure memory type. */ +#define VMX_EPT_MEMTYPE_UC 0 +/** Write-back EPT paging structure memory type. */ +#define VMX_EPT_MEMTYPE_WB 6 +/** Shift value to get the EPT page walk length (bits 5-3) */ +#define VMX_EPT_PAGE_WALK_LENGTH_SHIFT 3 +/** Mask value to get the EPT page walk length (bits 5-3) */ +#define VMX_EPT_PAGE_WALK_LENGTH_MASK 7 +/** Default EPT page-walk length (1 less than the actual EPT page-walk + * length) */ +#define VMX_EPT_PAGE_WALK_LENGTH_DEFAULT 3 +/** @} */ + + +/** @name VMCS field encoding - 16 bits guest fields + * @{ + */ +#define VMX_VMCS16_GUEST_FIELD_VPID 0x0 +#define VMX_VMCS16_GUEST_FIELD_ES 0x800 +#define VMX_VMCS16_GUEST_FIELD_CS 0x802 +#define VMX_VMCS16_GUEST_FIELD_SS 0x804 +#define VMX_VMCS16_GUEST_FIELD_DS 0x806 +#define VMX_VMCS16_GUEST_FIELD_FS 0x808 +#define VMX_VMCS16_GUEST_FIELD_GS 0x80A +#define VMX_VMCS16_GUEST_FIELD_LDTR 0x80C +#define VMX_VMCS16_GUEST_FIELD_TR 0x80E +/** @} */ + +/** @name VMCS field encoding - 16 bits host fields + * @{ + */ +#define VMX_VMCS16_HOST_FIELD_ES 0xC00 +#define VMX_VMCS16_HOST_FIELD_CS 0xC02 +#define VMX_VMCS16_HOST_FIELD_SS 0xC04 +#define VMX_VMCS16_HOST_FIELD_DS 0xC06 +#define VMX_VMCS16_HOST_FIELD_FS 0xC08 +#define VMX_VMCS16_HOST_FIELD_GS 0xC0A +#define VMX_VMCS16_HOST_FIELD_TR 0xC0C +/** @} */ + +/** @name VMCS field encoding - 64 bits host fields + * @{ + */ +#define VMX_VMCS64_HOST_FIELD_PAT_FULL 0x2C00 +#define VMX_VMCS64_HOST_FIELD_PAT_HIGH 0x2C01 +#define VMX_VMCS64_HOST_FIELD_EFER_FULL 0x2C02 +#define VMX_VMCS64_HOST_FIELD_EFER_HIGH 0x2C03 +#define VMX_VMCS64_HOST_PERF_GLOBAL_CTRL_FULL 0x2C04 /**< MSR IA32_PERF_GLOBAL_CTRL */ +#define VMX_VMCS64_HOST_PERF_GLOBAL_CTRL_HIGH 0x2C05 /**< MSR IA32_PERF_GLOBAL_CTRL */ +/** @} */ + + +/** @name VMCS field encoding - 64 Bits control fields + * @{ + */ +#define VMX_VMCS64_CTRL_IO_BITMAP_A_FULL 0x2000 +#define VMX_VMCS64_CTRL_IO_BITMAP_A_HIGH 0x2001 +#define VMX_VMCS64_CTRL_IO_BITMAP_B_FULL 0x2002 +#define VMX_VMCS64_CTRL_IO_BITMAP_B_HIGH 0x2003 + +/* Optional */ +#define VMX_VMCS64_CTRL_MSR_BITMAP_FULL 0x2004 +#define VMX_VMCS64_CTRL_MSR_BITMAP_HIGH 0x2005 + +#define VMX_VMCS64_CTRL_EXIT_MSR_STORE_FULL 0x2006 +#define VMX_VMCS64_CTRL_EXIT_MSR_STORE_HIGH 0x2007 +#define VMX_VMCS64_CTRL_EXIT_MSR_LOAD_FULL 0x2008 +#define VMX_VMCS64_CTRL_EXIT_MSR_LOAD_HIGH 0x2009 + +#define VMX_VMCS64_CTRL_ENTRY_MSR_LOAD_FULL 0x200A +#define VMX_VMCS64_CTRL_ENTRY_MSR_LOAD_HIGH 0x200B + +#define VMX_VMCS64_CTRL_EXEC_VMCS_PTR_FULL 0x200C +#define VMX_VMCS64_CTRL_EXEC_VMCS_PTR_HIGH 0x200D + +#define VMX_VMCS64_CTRL_TSC_OFFSET_FULL 0x2010 +#define VMX_VMCS64_CTRL_TSC_OFFSET_HIGH 0x2011 + +/** Optional (VMX_VMCS_CTRL_PROC_EXEC_USE_TPR_SHADOW) */ +#define VMX_VMCS64_CTRL_VAPIC_PAGEADDR_FULL 0x2012 +#define VMX_VMCS64_CTRL_VAPIC_PAGEADDR_HIGH 0x2013 + +/** Optional (VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC) */ +#define VMX_VMCS64_CTRL_APIC_ACCESSADDR_FULL 0x2014 +#define VMX_VMCS64_CTRL_APIC_ACCESSADDR_HIGH 0x2015 + +/** Optional (VMX_VMCS_CTRL_PROC_EXEC2_VMFUNC) */ +#define VMX_VMCS64_CTRL_VMFUNC_CTRLS_FULL 0x2018 +#define VMX_VMCS64_CTRL_VMFUNC_CTRLS_HIGH 0x2019 + +/** Extended page table pointer. */ +#define VMX_VMCS64_CTRL_EPTP_FULL 0x201a +#define VMX_VMCS64_CTRL_EPTP_HIGH 0x201b + +/** Extended page table pointer lists. */ +#define VMX_VMCS64_CTRL_EPTP_LIST_FULL 0x2024 +#define VMX_VMCS64_CTRL_EPTP_LIST_HIGH 0x2025 + +/** VM-exit guest phyiscal address. */ +#define VMX_VMCS64_EXIT_GUEST_PHYS_ADDR_FULL 0x2400 +#define VMX_VMCS64_EXIT_GUEST_PHYS_ADDR_HIGH 0x2401 +/** @} */ + + +/** @name VMCS field encoding - 64 Bits guest fields + * @{ + */ +#define VMX_VMCS64_GUEST_VMCS_LINK_PTR_FULL 0x2800 +#define VMX_VMCS64_GUEST_VMCS_LINK_PTR_HIGH 0x2801 +#define VMX_VMCS64_GUEST_DEBUGCTL_FULL 0x2802 /**< MSR IA32_DEBUGCTL */ +#define VMX_VMCS64_GUEST_DEBUGCTL_HIGH 0x2803 /**< MSR IA32_DEBUGCTL */ +#define VMX_VMCS64_GUEST_PAT_FULL 0x2804 +#define VMX_VMCS64_GUEST_PAT_HIGH 0x2805 +#define VMX_VMCS64_GUEST_EFER_FULL 0x2806 +#define VMX_VMCS64_GUEST_EFER_HIGH 0x2807 +#define VMX_VMCS64_GUEST_PERF_GLOBAL_CTRL_FULL 0x2808 /**< MSR IA32_PERF_GLOBAL_CTRL */ +#define VMX_VMCS64_GUEST_PERF_GLOBAL_CTRL_HIGH 0x2809 /**< MSR IA32_PERF_GLOBAL_CTRL */ +#define VMX_VMCS64_GUEST_PDPTE0_FULL 0x280A +#define VMX_VMCS64_GUEST_PDPTE0_HIGH 0x280B +#define VMX_VMCS64_GUEST_PDPTE1_FULL 0x280C +#define VMX_VMCS64_GUEST_PDPTE1_HIGH 0x280D +#define VMX_VMCS64_GUEST_PDPTE2_FULL 0x280E +#define VMX_VMCS64_GUEST_PDPTE2_HIGH 0x280F +#define VMX_VMCS64_GUEST_PDPTE3_FULL 0x2810 +#define VMX_VMCS64_GUEST_PDPTE3_HIGH 0x2811 +/** @} */ + + +/** @name VMCS field encoding - 32 Bits control fields + * @{ + */ +#define VMX_VMCS32_CTRL_PIN_EXEC 0x4000 +#define VMX_VMCS32_CTRL_PROC_EXEC 0x4002 +#define VMX_VMCS32_CTRL_EXCEPTION_BITMAP 0x4004 +#define VMX_VMCS32_CTRL_PAGEFAULT_ERROR_MASK 0x4006 +#define VMX_VMCS32_CTRL_PAGEFAULT_ERROR_MATCH 0x4008 +#define VMX_VMCS32_CTRL_CR3_TARGET_COUNT 0x400A +#define VMX_VMCS32_CTRL_EXIT 0x400C +#define VMX_VMCS32_CTRL_EXIT_MSR_STORE_COUNT 0x400E +#define VMX_VMCS32_CTRL_EXIT_MSR_LOAD_COUNT 0x4010 +#define VMX_VMCS32_CTRL_ENTRY 0x4012 +#define VMX_VMCS32_CTRL_ENTRY_MSR_LOAD_COUNT 0x4014 +#define VMX_VMCS32_CTRL_ENTRY_INTERRUPTION_INFO 0x4016 +#define VMX_VMCS32_CTRL_ENTRY_EXCEPTION_ERRCODE 0x4018 +#define VMX_VMCS32_CTRL_ENTRY_INSTR_LENGTH 0x401A +#define VMX_VMCS32_CTRL_TPR_THRESHOLD 0x401C +#define VMX_VMCS32_CTRL_PROC_EXEC2 0x401E +/** @} */ + + +/** @name VMX_VMCS_CTRL_PIN_EXEC + * @{ + */ +/** External interrupts cause VM exits if set; otherwise dispatched through the guest's IDT. */ +#define VMX_VMCS_CTRL_PIN_EXEC_EXT_INT_EXIT RT_BIT(0) +/** Non-maskable interrupts cause VM exits if set; otherwise dispatched through the guest's IDT. */ +#define VMX_VMCS_CTRL_PIN_EXEC_NMI_EXIT RT_BIT(3) +/** Virtual NMIs. */ +#define VMX_VMCS_CTRL_PIN_EXEC_VIRTUAL_NMI RT_BIT(5) +/** Activate VMX preemption timer. */ +#define VMX_VMCS_CTRL_PIN_EXEC_PREEMPT_TIMER RT_BIT(6) +/* All other bits are reserved and must be set according to MSR IA32_VMX_PROCBASED_CTLS. */ +/** @} */ + +/** @name VMX_VMCS_CTRL_PROC_EXEC + * @{ + */ +/** VM Exit as soon as RFLAGS.IF=1 and no blocking is active. */ +#define VMX_VMCS_CTRL_PROC_EXEC_INT_WINDOW_EXIT RT_BIT(2) +/** Use timestamp counter offset. */ +#define VMX_VMCS_CTRL_PROC_EXEC_USE_TSC_OFFSETTING RT_BIT(3) +/** VM Exit when executing the HLT instruction. */ +#define VMX_VMCS_CTRL_PROC_EXEC_HLT_EXIT RT_BIT(7) +/** VM Exit when executing the INVLPG instruction. */ +#define VMX_VMCS_CTRL_PROC_EXEC_INVLPG_EXIT RT_BIT(9) +/** VM Exit when executing the MWAIT instruction. */ +#define VMX_VMCS_CTRL_PROC_EXEC_MWAIT_EXIT RT_BIT(10) +/** VM Exit when executing the RDPMC instruction. */ +#define VMX_VMCS_CTRL_PROC_EXEC_RDPMC_EXIT RT_BIT(11) +/** VM Exit when executing the RDTSC/RDTSCP instruction. */ +#define VMX_VMCS_CTRL_PROC_EXEC_RDTSC_EXIT RT_BIT(12) +/** VM Exit when executing the MOV to CR3 instruction. (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */ +#define VMX_VMCS_CTRL_PROC_EXEC_CR3_LOAD_EXIT RT_BIT(15) +/** VM Exit when executing the MOV from CR3 instruction. (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */ +#define VMX_VMCS_CTRL_PROC_EXEC_CR3_STORE_EXIT RT_BIT(16) +/** VM Exit on CR8 loads. */ +#define VMX_VMCS_CTRL_PROC_EXEC_CR8_LOAD_EXIT RT_BIT(19) +/** VM Exit on CR8 stores. */ +#define VMX_VMCS_CTRL_PROC_EXEC_CR8_STORE_EXIT RT_BIT(20) +/** Use TPR shadow. */ +#define VMX_VMCS_CTRL_PROC_EXEC_USE_TPR_SHADOW RT_BIT(21) +/** VM Exit when virtual nmi blocking is disabled. */ +#define VMX_VMCS_CTRL_PROC_EXEC_NMI_WINDOW_EXIT RT_BIT(22) +/** VM Exit when executing a MOV DRx instruction. */ +#define VMX_VMCS_CTRL_PROC_EXEC_MOV_DR_EXIT RT_BIT(23) +/** VM Exit when executing IO instructions. */ +#define VMX_VMCS_CTRL_PROC_EXEC_UNCOND_IO_EXIT RT_BIT(24) +/** Use IO bitmaps. */ +#define VMX_VMCS_CTRL_PROC_EXEC_USE_IO_BITMAPS RT_BIT(25) +/** Monitor trap flag. */ +#define VMX_VMCS_CTRL_PROC_EXEC_MONITOR_TRAP_FLAG RT_BIT(27) +/** Use MSR bitmaps. */ +#define VMX_VMCS_CTRL_PROC_EXEC_USE_MSR_BITMAPS RT_BIT(28) +/** VM Exit when executing the MONITOR instruction. */ +#define VMX_VMCS_CTRL_PROC_EXEC_MONITOR_EXIT RT_BIT(29) +/** VM Exit when executing the PAUSE instruction. */ +#define VMX_VMCS_CTRL_PROC_EXEC_PAUSE_EXIT RT_BIT(30) +/** Determines whether the secondary processor based VM-execution controls are used. */ +#define VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL RT_BIT(31) +/** @} */ + +/** @name VMX_VMCS_CTRL_PROC_EXEC2 + * @{ + */ +/** Virtualize APIC access. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC RT_BIT(0) +/** EPT supported/enabled. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_EPT RT_BIT(1) +/** Descriptor table instructions cause VM-exits. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_DESCRIPTOR_TABLE_EXIT RT_BIT(2) +/** RDTSCP supported/enabled. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP RT_BIT(3) +/** Virtualize x2APIC mode. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_VIRT_X2APIC RT_BIT(4) +/** VPID supported/enabled. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_VPID RT_BIT(5) +/** VM Exit when executing the WBINVD instruction. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_WBINVD_EXIT RT_BIT(6) +/** Unrestricted guest execution. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_UNRESTRICTED_GUEST RT_BIT(7) +/** A specified nr of pause loops cause a VM-exit. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_PAUSE_LOOP_EXIT RT_BIT(10) +/** VM Exit when executing RDRAND instructions. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_RDRAND_EXIT RT_BIT(11) +/** Enables INVPCID instructions. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_INVPCID RT_BIT(12) +/** Enables VMFUNC instructions. */ +#define VMX_VMCS_CTRL_PROC_EXEC2_VMFUNC RT_BIT(13) +/** @} */ + + +/** @name VMX_VMCS_CTRL_ENTRY + * @{ + */ +/** Load guest debug controls (dr7 & IA32_DEBUGCTL_MSR) (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */ +#define VMX_VMCS_CTRL_ENTRY_LOAD_DEBUG RT_BIT(2) +/** 64 bits guest mode. Must be 0 for CPUs that don't support AMD64. */ +#define VMX_VMCS_CTRL_ENTRY_IA32E_MODE_GUEST RT_BIT(9) +/** In SMM mode after VM-entry. */ +#define VMX_VMCS_CTRL_ENTRY_ENTRY_SMM RT_BIT(10) +/** Disable dual treatment of SMI and SMM; must be zero for VM-entry outside of SMM. */ +#define VMX_VMCS_CTRL_ENTRY_DEACTIVATE_DUALMON RT_BIT(11) +/** Whether the guest IA32_PERF_GLOBAL_CTRL MSR is loaded on VM entry. */ +#define VMX_VMCS_CTRL_ENTRY_LOAD_GUEST_PERF_MSR RT_BIT(13) +/** Whether the guest IA32_PAT MSR is loaded on VM entry. */ +#define VMX_VMCS_CTRL_ENTRY_LOAD_GUEST_PAT_MSR RT_BIT(14) +/** Whether the guest IA32_EFER MSR is loaded on VM entry. */ +#define VMX_VMCS_CTRL_ENTRY_LOAD_GUEST_EFER_MSR RT_BIT(15) +/** @} */ + + +/** @name VMX_VMCS_CTRL_EXIT + * @{ + */ +/** Save guest debug controls (dr7 & IA32_DEBUGCTL_MSR) (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */ +#define VMX_VMCS_CTRL_EXIT_SAVE_DEBUG RT_BIT(2) +/** Return to long mode after a VM-exit. */ +#define VMX_VMCS_CTRL_EXIT_HOST_ADDR_SPACE_SIZE RT_BIT(9) +/** Whether the IA32_PERF_GLOBAL_CTRL MSR is loaded on VM exit. */ +#define VMX_VMCS_CTRL_EXIT_LOAD_PERF_MSR RT_BIT(12) +/** Acknowledge external interrupts with the irq controller if one caused a VM-exit. */ +#define VMX_VMCS_CTRL_EXIT_ACK_EXT_INT RT_BIT(15) +/** Whether the guest IA32_PAT MSR is saved on VM exit. */ +#define VMX_VMCS_CTRL_EXIT_SAVE_GUEST_PAT_MSR RT_BIT(18) +/** Whether the host IA32_PAT MSR is loaded on VM exit. */ +#define VMX_VMCS_CTRL_EXIT_LOAD_HOST_PAT_MSR RT_BIT(19) +/** Whether the guest IA32_EFER MSR is saved on VM exit. */ +#define VMX_VMCS_CTRL_EXIT_SAVE_GUEST_EFER_MSR RT_BIT(20) +/** Whether the host IA32_EFER MSR is loaded on VM exit. */ +#define VMX_VMCS_CTRL_EXIT_LOAD_HOST_EFER_MSR RT_BIT(21) +/** Whether the value of the VMX preemption timer is saved on every VM exit. */ +#define VMX_VMCS_CTRL_EXIT_SAVE_VMX_PREEMPT_TIMER RT_BIT(22) +/** @} */ + + +/** @name VMX_VMCS_CTRL_VMFUNC + * @{ + */ +/** EPTP-switching function changes the value of the EPTP to one chosen from the EPTP list. */ +#define VMX_VMCS_CTRL_VMFUNC_EPTP_SWITCHING RT_BIT_64(0) +/** @} */ + + +/** @name VMCS field encoding - 32 Bits read-only fields + * @{ + */ +#define VMX_VMCS32_RO_VM_INSTR_ERROR 0x4400 +#define VMX_VMCS32_RO_EXIT_REASON 0x4402 +#define VMX_VMCS32_RO_EXIT_INTERRUPTION_INFO 0x4404 +#define VMX_VMCS32_RO_EXIT_INTERRUPTION_ERROR_CODE 0x4406 +#define VMX_VMCS32_RO_IDT_INFO 0x4408 +#define VMX_VMCS32_RO_IDT_ERROR_CODE 0x440A +#define VMX_VMCS32_RO_EXIT_INSTR_LENGTH 0x440C +#define VMX_VMCS32_RO_EXIT_INSTR_INFO 0x440E +/** @} */ + +/** @name VMX_VMCS32_RO_EXIT_REASON + * @{ + */ +#define VMX_EXIT_REASON_BASIC(a) ((a) & 0xffff) +/** @} */ + +/** @name VMX_VMCS32_CTRL_ENTRY_INTERRUPTION_INFO + * @{ + */ +#define VMX_ENTRY_INTERRUPTION_INFO_IS_VALID(a) RT_BOOL((a) & RT_BIT(31)) +#define VMX_ENTRY_INTERRUPTION_INFO_TYPE_SHIFT 8 +#define VMX_ENTRY_INTERRUPTION_INFO_TYPE(a) ((a >> VMX_ENTRY_INTERRUPTION_INFO_TYPE_SHIFT) & 7) +/** @} */ + + +/** @name VMX_VMCS32_RO_EXIT_INTERRUPTION_INFO + * @{ + */ +#define VMX_EXIT_INTERRUPTION_INFO_VECTOR(a) ((a) & 0xff) +#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT 8 +#define VMX_EXIT_INTERRUPTION_INFO_TYPE(a) (((a) >> VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT) & 7) +#define VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID RT_BIT(11) +#define VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_IS_VALID(a) RT_BOOL((a) & VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID) +#define VMX_EXIT_INTERRUPTION_INFO_NMI_UNBLOCK(a) ((a) & RT_BIT(12)) +#define VMX_EXIT_INTERRUPTION_INFO_VALID RT_BIT(31) +#define VMX_EXIT_INTERRUPTION_INFO_IS_VALID(a) RT_BOOL((a) & RT_BIT(31)) +/** Construct an irq event injection value from the exit interruption info value (same except that bit 12 is reserved). */ +#define VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(a) ((a) & ~RT_BIT(12)) +/** @} */ + +/** @name VMX_VMCS_RO_EXIT_INTERRUPTION_INFO_TYPE + * @{ + */ +#define VMX_EXIT_INTERRUPTION_INFO_TYPE_EXT_INT 0 +#define VMX_EXIT_INTERRUPTION_INFO_TYPE_NMI 2 +#define VMX_EXIT_INTERRUPTION_INFO_TYPE_HW_XCPT 3 +#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SW_INT 4 +#define VMX_EXIT_INTERRUPTION_INFO_TYPE_PRIV_SW_XCPT 5 +#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SW_XCPT 6 +/** @} */ + +/** @name VMX_VMCS32_RO_IDT_VECTORING_INFO + * @{ + */ +#define VMX_IDT_VECTORING_INFO_VECTOR(a) ((a) & 0xff) +#define VMX_IDT_VECTORING_INFO_TYPE_SHIFT 8 +#define VMX_IDT_VECTORING_INFO_TYPE(a) (((a) >> VMX_IDT_VECTORING_INFO_TYPE_SHIFT) & 7) +#define VMX_IDT_VECTORING_INFO_ERROR_CODE_VALID RT_BIT(11) +#define VMX_IDT_VECTORING_INFO_ERROR_CODE_IS_VALID(a) RT_BOOL((a) & VMX_IDT_VECTORING_INFO_ERROR_CODE_VALID) +#define VMX_IDT_VECTORING_INFO_VALID(a) ((a) & RT_BIT(31)) +#define VMX_ENTRY_INT_INFO_FROM_EXIT_IDT_INFO(a) ((a) & ~RT_BIT(12)) +/** @} */ + +/** @name VMX_VMCS_RO_IDT_VECTORING_INFO_TYPE + * @{ + */ +#define VMX_IDT_VECTORING_INFO_TYPE_EXT_INT 0 +#define VMX_IDT_VECTORING_INFO_TYPE_NMI 2 +#define VMX_IDT_VECTORING_INFO_TYPE_HW_XCPT 3 +#define VMX_IDT_VECTORING_INFO_TYPE_SW_INT 4 +#define VMX_IDT_VECTORING_INFO_TYPE_PRIV_SW_XCPT 5 +#define VMX_IDT_VECTORING_INFO_TYPE_SW_XCPT 6 +/** @} */ + + +/** @name VMCS field encoding - 32 Bits guest state fields + * @{ + */ +#define VMX_VMCS32_GUEST_ES_LIMIT 0x4800 +#define VMX_VMCS32_GUEST_CS_LIMIT 0x4802 +#define VMX_VMCS32_GUEST_SS_LIMIT 0x4804 +#define VMX_VMCS32_GUEST_DS_LIMIT 0x4806 +#define VMX_VMCS32_GUEST_FS_LIMIT 0x4808 +#define VMX_VMCS32_GUEST_GS_LIMIT 0x480A +#define VMX_VMCS32_GUEST_LDTR_LIMIT 0x480C +#define VMX_VMCS32_GUEST_TR_LIMIT 0x480E +#define VMX_VMCS32_GUEST_GDTR_LIMIT 0x4810 +#define VMX_VMCS32_GUEST_IDTR_LIMIT 0x4812 +#define VMX_VMCS32_GUEST_ES_ACCESS_RIGHTS 0x4814 +#define VMX_VMCS32_GUEST_CS_ACCESS_RIGHTS 0x4816 +#define VMX_VMCS32_GUEST_SS_ACCESS_RIGHTS 0x4818 +#define VMX_VMCS32_GUEST_DS_ACCESS_RIGHTS 0x481A +#define VMX_VMCS32_GUEST_FS_ACCESS_RIGHTS 0x481C +#define VMX_VMCS32_GUEST_GS_ACCESS_RIGHTS 0x481E +#define VMX_VMCS32_GUEST_LDTR_ACCESS_RIGHTS 0x4820 +#define VMX_VMCS32_GUEST_TR_ACCESS_RIGHTS 0x4822 +#define VMX_VMCS32_GUEST_INTERRUPTIBILITY_STATE 0x4824 +#define VMX_VMCS32_GUEST_ACTIVITY_STATE 0x4826 +#define VMX_VMCS32_GUEST_SYSENTER_CS 0x482A /**< MSR IA32_SYSENTER_CS */ +#define VMX_VMCS32_GUEST_PREEMPT_TIMER_VALUE 0x482E +/** @} */ + + +/** @name VMX_VMCS_GUEST_ACTIVITY_STATE + * @{ + */ +/** The logical processor is active. */ +#define VMX_VMCS_GUEST_ACTIVITY_ACTIVE 0x0 +/** The logical processor is inactive, because executed a HLT instruction. */ +#define VMX_VMCS_GUEST_ACTIVITY_HLT 0x1 +/** The logical processor is inactive, because of a triple fault or other serious error. */ +#define VMX_VMCS_GUEST_ACTIVITY_SHUTDOWN 0x2 +/** The logical processor is inactive, because it's waiting for a startup-IPI */ +#define VMX_VMCS_GUEST_ACTIVITY_SIPI_WAIT 0x3 +/** @} */ + + +/** @name VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE + * @{ + */ +#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_STI RT_BIT(0) +#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_MOVSS RT_BIT(1) +#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_SMI RT_BIT(2) +#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_NMI RT_BIT(3) +/** @} */ + + +/** @name VMCS field encoding - 32 Bits host state fields + * @{ + */ +#define VMX_VMCS32_HOST_SYSENTER_CS 0x4C00 +/** @} */ + +/** @name Natural width control fields + * @{ + */ +#define VMX_VMCS_CTRL_CR0_MASK 0x6000 +#define VMX_VMCS_CTRL_CR4_MASK 0x6002 +#define VMX_VMCS_CTRL_CR0_READ_SHADOW 0x6004 +#define VMX_VMCS_CTRL_CR4_READ_SHADOW 0x6006 +#define VMX_VMCS_CTRL_CR3_TARGET_VAL0 0x6008 +#define VMX_VMCS_CTRL_CR3_TARGET_VAL1 0x600A +#define VMX_VMCS_CTRL_CR3_TARGET_VAL2 0x600C +#define VMX_VMCS_CTRL_CR3_TARGET_VAL31 0x600E +/** @} */ + + +/** @name Natural width read-only data fields + * @{ + */ +#define VMX_VMCS_RO_EXIT_QUALIFICATION 0x6400 +#define VMX_VMCS_RO_IO_RCX 0x6402 +#define VMX_VMCS_RO_IO_RSX 0x6404 +#define VMX_VMCS_RO_IO_RDI 0x6406 +#define VMX_VMCS_RO_IO_RIP 0x6408 +#define VMX_VMCS_RO_EXIT_GUEST_LINEAR_ADDR 0x640A +/** @} */ + + +/** @name VMX_VMCS_RO_EXIT_QUALIFICATION + * @{ + */ +/** 0-2: Debug register number */ +#define VMX_EXIT_QUALIFICATION_DRX_REGISTER(a) ((a) & 7) +/** 3: Reserved; cleared to 0. */ +#define VMX_EXIT_QUALIFICATION_DRX_RES1(a) (((a) >> 3) & 1) +/** 4: Direction of move (0 = write, 1 = read) */ +#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION(a) (((a) >> 4) & 1) +/** 5-7: Reserved; cleared to 0. */ +#define VMX_EXIT_QUALIFICATION_DRX_RES2(a) (((a) >> 5) & 7) +/** 8-11: General purpose register number. */ +#define VMX_EXIT_QUALIFICATION_DRX_GENREG(a) (((a) >> 8) & 0xF) +/** Rest: reserved. */ +/** @} */ + +/** @name VMX_EXIT_QUALIFICATION_DRX_DIRECTION values + * @{ + */ +#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION_WRITE 0 +#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION_READ 1 +/** @} */ + + + +/** @name CRx accesses + * @{ + */ +/** 0-3: Control register number (0 for CLTS & LMSW) */ +#define VMX_EXIT_QUALIFICATION_CRX_REGISTER(a) ((a) & 0xF) +/** 4-5: Access type. */ +#define VMX_EXIT_QUALIFICATION_CRX_ACCESS(a) (((a) >> 4) & 3) +/** 6: LMSW operand type */ +#define VMX_EXIT_QUALIFICATION_CRX_LMSW_OP(a) (((a) >> 6) & 1) +/** 7: Reserved; cleared to 0. */ +#define VMX_EXIT_QUALIFICATION_CRX_RES1(a) (((a) >> 7) & 1) +/** 8-11: General purpose register number (0 for CLTS & LMSW). */ +#define VMX_EXIT_QUALIFICATION_CRX_GENREG(a) (((a) >> 8) & 0xF) +/** 12-15: Reserved; cleared to 0. */ +#define VMX_EXIT_QUALIFICATION_CRX_RES2(a) (((a) >> 12) & 0xF) +/** 16-31: LMSW source data (else 0). */ +#define VMX_EXIT_QUALIFICATION_CRX_LMSW_DATA(a) (((a) >> 16) & 0xFFFF) +/** Rest: reserved. */ +/** @} */ + +/** @name VMX_EXIT_QUALIFICATION_CRX_ACCESS + * @{ + */ +#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_WRITE 0 +#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_READ 1 +#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_CLTS 2 +#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_LMSW 3 +/** @} */ + +/** @name VMX_EXIT_QUALIFICATION_TASK_SWITCH + * @{ + */ +#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_SELECTOR(a) ((a) & 0xffff) +#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE(a) (((a) >> 30) & 0x3) +/** Task switch caused by a call instruction. */ +#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_CALL 0 +/** Task switch caused by an iret instruction. */ +#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_IRET 1 +/** Task switch caused by a jmp instruction. */ +#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_JMP 2 +/** Task switch caused by an interrupt gate. */ +#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_IDT 3 +/** @} */ + + +/** @name VMX_EXIT_EPT_VIOLATION + * @{ + */ +/** Set if the violation was caused by a data read. */ +#define VMX_EXIT_QUALIFICATION_EPT_DATA_READ RT_BIT(0) +/** Set if the violation was caused by a data write. */ +#define VMX_EXIT_QUALIFICATION_EPT_DATA_WRITE RT_BIT(1) +/** Set if the violation was caused by an insruction fetch. */ +#define VMX_EXIT_QUALIFICATION_EPT_INSTR_FETCH RT_BIT(2) +/** AND of the present bit of all EPT structures. */ +#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_PRESENT RT_BIT(3) +/** AND of the write bit of all EPT structures. */ +#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_WRITE RT_BIT(4) +/** AND of the execute bit of all EPT structures. */ +#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_EXECUTE RT_BIT(5) +/** Set if the guest linear address field contains the faulting address. */ +#define VMX_EXIT_QUALIFICATION_EPT_GUEST_ADDR_VALID RT_BIT(7) +/** If bit 7 is one: (reserved otherwise) + * 1 - violation due to physical address access. + * 0 - violation caused by page walk or access/dirty bit updates + */ +#define VMX_EXIT_QUALIFICATION_EPT_TRANSLATED_ACCESS RT_BIT(8) +/** @} */ + + +/** @name VMX_EXIT_PORT_IO + * @{ + */ +/** 0-2: IO operation width. */ +#define VMX_EXIT_QUALIFICATION_IO_WIDTH(a) ((a) & 7) +/** 3: IO operation direction. */ +#define VMX_EXIT_QUALIFICATION_IO_DIRECTION(a) (((a) >> 3) & 1) +/** 4: String IO operation (INS / OUTS). */ +#define VMX_EXIT_QUALIFICATION_IO_IS_STRING(a) RT_BOOL((a) & RT_BIT_64(4)) +/** 5: Repeated IO operation. */ +#define VMX_EXIT_QUALIFICATION_IO_IS_REP(a) RT_BOOL((a) & RT_BIT_64(5)) +/** 6: Operand encoding. */ +#define VMX_EXIT_QUALIFICATION_IO_ENCODING(a) (((a) >> 6) & 1) +/** 16-31: IO Port (0-0xffff). */ +#define VMX_EXIT_QUALIFICATION_IO_PORT(a) (((a) >> 16) & 0xffff) +/* Rest reserved. */ +/** @} */ + +/** @name VMX_EXIT_QUALIFICATION_IO_DIRECTION + * @{ + */ +#define VMX_EXIT_QUALIFICATION_IO_DIRECTION_OUT 0 +#define VMX_EXIT_QUALIFICATION_IO_DIRECTION_IN 1 +/** @} */ + + +/** @name VMX_EXIT_QUALIFICATION_IO_ENCODING + * @{ + */ +#define VMX_EXIT_QUALIFICATION_IO_ENCODING_DX 0 +#define VMX_EXIT_QUALIFICATION_IO_ENCODING_IMM 1 +/** @} */ + +/** @name VMX_EXIT_APIC_ACCESS + * @{ + */ +/** 0-11: If the APIC-access VM exit is due to a linear access, the offset of access within the APIC page. */ +#define VMX_EXIT_QUALIFICATION_APIC_ACCESS_OFFSET(a) ((a) & 0xfff) +/** 12-15: Access type. */ +#define VMX_EXIT_QUALIFICATION_APIC_ACCESS_TYPE(a) ((a) & 0xf000) +/* Rest reserved. */ +/** @} */ + + +/** @name VMX_EXIT_QUALIFICATION_APIC_ACCESS_TYPE; access types + * @{ + */ +/** Linear read access. */ +#define VMX_APIC_ACCESS_TYPE_LINEAR_READ 0 +/** Linear write access. */ +#define VMX_APIC_ACCESS_TYPE_LINEAR_WRITE 1 +/** Linear instruction fetch access. */ +#define VMX_APIC_ACCESS_TYPE_LINEAR_INSTR_FETCH 2 +/** Linear read/write access during event delivery. */ +#define VMX_APIC_ACCESS_TYPE_LINEAR_EVENT_DELIVERY 3 +/** Physical read/write access during event delivery. */ +#define VMX_APIC_ACCESS_TYPE_PHYSICAL_EVENT_DELIVERY 10 +/** Physical access for an instruction fetch or during instruction execution. */ +#define VMX_APIC_ACCESS_TYPE_PHYSICAL_INSTR 15 +/** @} */ + +/** @} */ + +/** @name VMCS field encoding - Natural width guest state fields + * @{ + */ +#define VMX_VMCS_GUEST_CR0 0x6800 +#define VMX_VMCS_GUEST_CR3 0x6802 +#define VMX_VMCS_GUEST_CR4 0x6804 +#define VMX_VMCS_GUEST_ES_BASE 0x6806 +#define VMX_VMCS_GUEST_CS_BASE 0x6808 +#define VMX_VMCS_GUEST_SS_BASE 0x680A +#define VMX_VMCS_GUEST_DS_BASE 0x680C +#define VMX_VMCS_GUEST_FS_BASE 0x680E +#define VMX_VMCS_GUEST_GS_BASE 0x6810 +#define VMX_VMCS_GUEST_LDTR_BASE 0x6812 +#define VMX_VMCS_GUEST_TR_BASE 0x6814 +#define VMX_VMCS_GUEST_GDTR_BASE 0x6816 +#define VMX_VMCS_GUEST_IDTR_BASE 0x6818 +#define VMX_VMCS_GUEST_DR7 0x681A +#define VMX_VMCS_GUEST_RSP 0x681C +#define VMX_VMCS_GUEST_RIP 0x681E +#define VMX_VMCS_GUEST_RFLAGS 0x6820 +#define VMX_VMCS_GUEST_PENDING_DEBUG_EXCEPTIONS 0x6822 +#define VMX_VMCS_GUEST_SYSENTER_ESP 0x6824 /**< MSR IA32_SYSENTER_ESP */ +#define VMX_VMCS_GUEST_SYSENTER_EIP 0x6826 /**< MSR IA32_SYSENTER_EIP */ +/** @} */ + + +/** @name VMX_VMCS_GUEST_DEBUG_EXCEPTIONS + * @{ + */ +/** Hardware breakpoint 0 was met. */ +#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B0 RT_BIT(0) +/** Hardware breakpoint 1 was met. */ +#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B1 RT_BIT(1) +/** Hardware breakpoint 2 was met. */ +#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B2 RT_BIT(2) +/** Hardware breakpoint 3 was met. */ +#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B3 RT_BIT(3) +/** At least one data or IO breakpoint was hit. */ +#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BREAKPOINT_ENABLED RT_BIT(12) +/** A debug exception would have been triggered by single-step execution mode. */ +#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BS RT_BIT(14) +/** Bits 4-11, 13 and 15-63 are reserved. */ + +/** @} */ + +/** @name VMCS field encoding - Natural width host state fields + * @{ + */ +#define VMX_VMCS_HOST_CR0 0x6C00 +#define VMX_VMCS_HOST_CR3 0x6C02 +#define VMX_VMCS_HOST_CR4 0x6C04 +#define VMX_VMCS_HOST_FS_BASE 0x6C06 +#define VMX_VMCS_HOST_GS_BASE 0x6C08 +#define VMX_VMCS_HOST_TR_BASE 0x6C0A +#define VMX_VMCS_HOST_GDTR_BASE 0x6C0C +#define VMX_VMCS_HOST_IDTR_BASE 0x6C0E +#define VMX_VMCS_HOST_SYSENTER_ESP 0x6C10 +#define VMX_VMCS_HOST_SYSENTER_EIP 0x6C12 +#define VMX_VMCS_HOST_RSP 0x6C14 +#define VMX_VMCS_HOST_RIP 0x6C16 +/** @} */ + +/** @} */ + + +/** @defgroup grp_vmx_asm vmx assembly helpers + * @ingroup grp_vmx + * @{ + */ + +/** + * Restores some host-state fields that need not be done on every VM-exit. + * + * @returns VBox status code. + * @param fRestoreHostFlags Flags of which host registers needs to be + * restored. + * @param pRestoreHost Pointer to the host-restore structure. + */ +DECLASM(int) VMXRestoreHostState(uint32_t fRestoreHostFlags, PVMXRESTOREHOST pRestoreHost); + + +/** + * Dispatches an NMI to the host. + */ +DECLASM(int) VMXDispatchHostNmi(void); + + +/** + * Executes VMXON + * + * @returns VBox status code + * @param pVMXOn Physical address of VMXON structure + */ +#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) +DECLASM(int) VMXEnable(RTHCPHYS pVMXOn); +#else +DECLINLINE(int) VMXEnable(RTHCPHYS pVMXOn) +{ +# if RT_INLINE_ASM_GNU_STYLE + int rc = VINF_SUCCESS; + __asm__ __volatile__ ( + "push %3 \n\t" + "push %2 \n\t" + ".byte 0xF3, 0x0F, 0xC7, 0x34, 0x24 # VMXON [esp] \n\t" + "ja 2f \n\t" + "je 1f \n\t" + "movl $"RT_XSTR(VERR_VMX_INVALID_VMXON_PTR)", %0 \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl $"RT_XSTR(VERR_VMX_VMXON_FAILED)", %0 \n\t" + "2: \n\t" + "add $8, %%esp \n\t" + :"=rm"(rc) + :"0"(VINF_SUCCESS), + "ir"((uint32_t)pVMXOn), /* don't allow direct memory reference here, */ + "ir"((uint32_t)(pVMXOn >> 32)) /* this would not work with -fomit-frame-pointer */ + :"memory" + ); + return rc; + +# elif VMX_USE_MSC_INTRINSICS + unsigned char rcMsc = __vmx_on(&pVMXOn); + if (RT_LIKELY(rcMsc == 0)) + return VINF_SUCCESS; + return rcMsc == 2 ? VERR_VMX_INVALID_VMXON_PTR : VERR_VMX_VMXON_FAILED; + +# else + int rc = VINF_SUCCESS; + __asm + { + push dword ptr [pVMXOn+4] + push dword ptr [pVMXOn] + _emit 0xF3 + _emit 0x0F + _emit 0xC7 + _emit 0x34 + _emit 0x24 /* VMXON [esp] */ + jnc vmxon_good + mov dword ptr [rc], VERR_VMX_INVALID_VMXON_PTR + jmp the_end + +vmxon_good: + jnz the_end + mov dword ptr [rc], VERR_VMX_VMXON_FAILED +the_end: + add esp, 8 + } + return rc; +# endif +} +#endif + + +/** + * Executes VMXOFF + */ +#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) +DECLASM(void) VMXDisable(void); +#else +DECLINLINE(void) VMXDisable(void) +{ +# if RT_INLINE_ASM_GNU_STYLE + __asm__ __volatile__ ( + ".byte 0x0F, 0x01, 0xC4 # VMXOFF \n\t" + ); + +# elif VMX_USE_MSC_INTRINSICS + __vmx_off(); + +# else + __asm + { + _emit 0x0F + _emit 0x01 + _emit 0xC4 /* VMXOFF */ + } +# endif +} +#endif + + +/** + * Executes VMCLEAR + * + * @returns VBox status code + * @param pVMCS Physical address of VM control structure + */ +#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) +DECLASM(int) VMXClearVmcs(RTHCPHYS pVMCS); +#else +DECLINLINE(int) VMXClearVmcs(RTHCPHYS pVMCS) +{ +# if RT_INLINE_ASM_GNU_STYLE + int rc = VINF_SUCCESS; + __asm__ __volatile__ ( + "push %3 \n\t" + "push %2 \n\t" + ".byte 0x66, 0x0F, 0xC7, 0x34, 0x24 # VMCLEAR [esp] \n\t" + "jnc 1f \n\t" + "movl $"RT_XSTR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t" + "1: \n\t" + "add $8, %%esp \n\t" + :"=rm"(rc) + :"0"(VINF_SUCCESS), + "ir"((uint32_t)pVMCS), /* don't allow direct memory reference here, */ + "ir"((uint32_t)(pVMCS >> 32)) /* this would not work with -fomit-frame-pointer */ + :"memory" + ); + return rc; + +# elif VMX_USE_MSC_INTRINSICS + unsigned char rcMsc = __vmx_vmclear(&pVMCS); + if (RT_LIKELY(rcMsc == 0)) + return VINF_SUCCESS; + return VERR_VMX_INVALID_VMCS_PTR; + +# else + int rc = VINF_SUCCESS; + __asm + { + push dword ptr [pVMCS+4] + push dword ptr [pVMCS] + _emit 0x66 + _emit 0x0F + _emit 0xC7 + _emit 0x34 + _emit 0x24 /* VMCLEAR [esp] */ + jnc success + mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR +success: + add esp, 8 + } + return rc; +# endif +} +#endif + + +/** + * Executes VMPTRLD + * + * @returns VBox status code + * @param pVMCS Physical address of VMCS structure + */ +#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) +DECLASM(int) VMXActivateVmcs(RTHCPHYS pVMCS); +#else +DECLINLINE(int) VMXActivateVmcs(RTHCPHYS pVMCS) +{ +# if RT_INLINE_ASM_GNU_STYLE + int rc = VINF_SUCCESS; + __asm__ __volatile__ ( + "push %3 \n\t" + "push %2 \n\t" + ".byte 0x0F, 0xC7, 0x34, 0x24 # VMPTRLD [esp] \n\t" + "jnc 1f \n\t" + "movl $"RT_XSTR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t" + "1: \n\t" + "add $8, %%esp \n\t" + :"=rm"(rc) + :"0"(VINF_SUCCESS), + "ir"((uint32_t)pVMCS), /* don't allow direct memory reference here, */ + "ir"((uint32_t)(pVMCS >> 32)) /* this will not work with -fomit-frame-pointer */ + ); + return rc; + +# elif VMX_USE_MSC_INTRINSICS + unsigned char rcMsc = __vmx_vmptrld(&pVMCS); + if (RT_LIKELY(rcMsc == 0)) + return VINF_SUCCESS; + return VERR_VMX_INVALID_VMCS_PTR; + +# else + int rc = VINF_SUCCESS; + __asm + { + push dword ptr [pVMCS+4] + push dword ptr [pVMCS] + _emit 0x0F + _emit 0xC7 + _emit 0x34 + _emit 0x24 /* VMPTRLD [esp] */ + jnc success + mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR + +success: + add esp, 8 + } + return rc; +# endif +} +#endif + +/** + * Executes VMPTRST + * + * @returns VBox status code + * @param pVMCS Address that will receive the current pointer + */ +DECLASM(int) VMXGetActivatedVmcs(RTHCPHYS *pVMCS); + +/** + * Executes VMWRITE + * + * @returns VBox status code + * @retval VINF_SUCCESS + * @retval VERR_VMX_INVALID_VMCS_PTR + * @retval VERR_VMX_INVALID_VMCS_FIELD + * + * @param idxField VMCS index + * @param u32Val 32 bits value + * + * @remarks The values of the two status codes can be ORed together, the result + * will be VERR_VMX_INVALID_VMCS_PTR. + */ +#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) +DECLASM(int) VMXWriteVmcs32(uint32_t idxField, uint32_t u32Val); +#else +DECLINLINE(int) VMXWriteVmcs32(uint32_t idxField, uint32_t u32Val) +{ +# if RT_INLINE_ASM_GNU_STYLE + int rc = VINF_SUCCESS; + __asm__ __volatile__ ( + ".byte 0x0F, 0x79, 0xC2 # VMWRITE eax, edx \n\t" + "ja 2f \n\t" + "je 1f \n\t" + "movl $"RT_XSTR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl $"RT_XSTR(VERR_VMX_INVALID_VMCS_FIELD)", %0 \n\t" + "2: \n\t" + :"=rm"(rc) + :"0"(VINF_SUCCESS), + "a"(idxField), + "d"(u32Val) + ); + return rc; + +# elif VMX_USE_MSC_INTRINSICS + unsigned char rcMsc = __vmx_vmwrite(idxField, u32Val); + if (RT_LIKELY(rcMsc == 0)) + return VINF_SUCCESS; + return rcMsc == 2 ? VERR_VMX_INVALID_VMCS_PTR : VERR_VMX_INVALID_VMCS_FIELD; + +#else + int rc = VINF_SUCCESS; + __asm + { + push dword ptr [u32Val] + mov eax, [idxField] + _emit 0x0F + _emit 0x79 + _emit 0x04 + _emit 0x24 /* VMWRITE eax, [esp] */ + jnc valid_vmcs + mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR + jmp the_end + +valid_vmcs: + jnz the_end + mov dword ptr [rc], VERR_VMX_INVALID_VMCS_FIELD +the_end: + add esp, 4 + } + return rc; +# endif +} +#endif + +/** + * Executes VMWRITE + * + * @returns VBox status code + * @retval VINF_SUCCESS + * @retval VERR_VMX_INVALID_VMCS_PTR + * @retval VERR_VMX_INVALID_VMCS_FIELD + * + * @param idxField VMCS index + * @param u64Val 16, 32 or 64 bits value + * + * @remarks The values of the two status codes can be ORed together, the result + * will be VERR_VMX_INVALID_VMCS_PTR. + */ +#if !defined(RT_ARCH_X86) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) +# if !VMX_USE_MSC_INTRINSICS || ARCH_BITS != 64 +DECLASM(int) VMXWriteVmcs64(uint32_t idxField, uint64_t u64Val); +# else /* VMX_USE_MSC_INTRINSICS */ +DECLINLINE(int) VMXWriteVmcs64(uint32_t idxField, uint64_t u64Val) +{ + unsigned char rcMsc = __vmx_vmwrite(idxField, u64Val); + if (RT_LIKELY(rcMsc == 0)) + return VINF_SUCCESS; + return rcMsc == 2 ? VERR_VMX_INVALID_VMCS_PTR : VERR_VMX_INVALID_VMCS_FIELD; +} +# endif /* VMX_USE_MSC_INTRINSICS */ +#else +# define VMXWriteVmcs64(idxField, u64Val) VMXWriteVmcs64Ex(pVCpu, idxField, u64Val) /** @todo dead ugly, picking up pVCpu like this */ +VMMR0DECL(int) VMXWriteVmcs64Ex(PVMCPU pVCpu, uint32_t idxField, uint64_t u64Val); +#endif + +#ifdef VBOX_WITH_HYBRID_32BIT_KERNEL +# define VMXWriteVmcsHstN(idxField, uVal) HMVMX_IS_64BIT_HOST_MODE() ? \ + VMXWriteVmcs64(idxField, uVal) \ + : VMXWriteVmcs32(idxField, uVal) +# define VMXWriteVmcsGstN(idxField, u64Val) (pVCpu->CTX_SUFF(pVM)->hm.s.fAllow64BitGuests) ? \ + VMXWriteVmcs64(idxField, u64Val) \ + : VMXWriteVmcs32(idxField, u64Val) +#elif ARCH_BITS == 32 +# define VMXWriteVmcsHstN VMXWriteVmcs32 +# define VMXWriteVmcsGstN(idxField, u64Val) VMXWriteVmcs64Ex(pVCpu, idxField, u64Val) +# else /* ARCH_BITS == 64 */ +# define VMXWriteVmcsHstN VMXWriteVmcs64 +# define VMXWriteVmcsGstN VMXWriteVmcs64 +# endif + + +/** + * Invalidate a page using invept + * @returns VBox status code + * @param enmFlush Type of flush + * @param pDescriptor Descriptor + */ +DECLASM(int) VMXR0InvEPT(VMX_FLUSH_EPT enmFlush, uint64_t *pDescriptor); + +/** + * Invalidate a page using invvpid + * @returns VBox status code + * @param enmFlush Type of flush + * @param pDescriptor Descriptor + */ +DECLASM(int) VMXR0InvVPID(VMX_FLUSH_VPID enmFlush, uint64_t *pDescriptor); + +/** + * Executes VMREAD + * + * @returns VBox status code + * @retval VINF_SUCCESS + * @retval VERR_VMX_INVALID_VMCS_PTR + * @retval VERR_VMX_INVALID_VMCS_FIELD + * + * @param idxField VMCS index + * @param pData Ptr to store VM field value + * + * @remarks The values of the two status codes can be ORed together, the result + * will be VERR_VMX_INVALID_VMCS_PTR. + */ +#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) +DECLASM(int) VMXReadVmcs32(uint32_t idxField, uint32_t *pData); +#else +DECLINLINE(int) VMXReadVmcs32(uint32_t idxField, uint32_t *pData) +{ +# if RT_INLINE_ASM_GNU_STYLE + int rc = VINF_SUCCESS; + __asm__ __volatile__ ( + "movl $"RT_XSTR(VINF_SUCCESS)", %0 \n\t" + ".byte 0x0F, 0x78, 0xc2 # VMREAD eax, edx \n\t" + "ja 2f \n\t" + "je 1f \n\t" + "movl $"RT_XSTR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl $"RT_XSTR(VERR_VMX_INVALID_VMCS_FIELD)", %0 \n\t" + "2: \n\t" + :"=&r"(rc), + "=d"(*pData) + :"a"(idxField), + "d"(0) + ); + return rc; + +# elif VMX_USE_MSC_INTRINSICS + unsigned char rcMsc; +# if ARCH_BITS == 32 + rcMsc = __vmx_vmread(idxField, pData); +# else + uint64_t u64Tmp; + rcMsc = __vmx_vmread(idxField, &u64Tmp); + *pData = (uint32_t)u64Tmp; +# endif + if (RT_LIKELY(rcMsc == 0)) + return VINF_SUCCESS; + return rcMsc == 2 ? VERR_VMX_INVALID_VMCS_PTR : VERR_VMX_INVALID_VMCS_FIELD; + +#else + int rc = VINF_SUCCESS; + __asm + { + sub esp, 4 + mov dword ptr [esp], 0 + mov eax, [idxField] + _emit 0x0F + _emit 0x78 + _emit 0x04 + _emit 0x24 /* VMREAD eax, [esp] */ + mov edx, pData + pop dword ptr [edx] + jnc valid_vmcs + mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR + jmp the_end + +valid_vmcs: + jnz the_end + mov dword ptr [rc], VERR_VMX_INVALID_VMCS_FIELD +the_end: + } + return rc; +# endif +} +#endif + +/** + * Executes VMREAD + * + * @returns VBox status code + * @retval VINF_SUCCESS + * @retval VERR_VMX_INVALID_VMCS_PTR + * @retval VERR_VMX_INVALID_VMCS_FIELD + * + * @param idxField VMCS index + * @param pData Ptr to store VM field value + * + * @remarks The values of the two status codes can be ORed together, the result + * will be VERR_VMX_INVALID_VMCS_PTR. + */ +#if (!defined(RT_ARCH_X86) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) +DECLASM(int) VMXReadVmcs64(uint32_t idxField, uint64_t *pData); +#else +DECLINLINE(int) VMXReadVmcs64(uint32_t idxField, uint64_t *pData) +{ +# if VMX_USE_MSC_INTRINSICS + unsigned char rcMsc; +# if ARCH_BITS == 32 + size_t uLow; + size_t uHigh; + rcMsc = __vmx_vmread(idxField, &uLow); + rcMsc |= __vmx_vmread(idxField + 1, &uHigh); + *pData = RT_MAKE_U64(uLow, uHigh); +# else + rcMsc = __vmx_vmread(idxField, pData); +# endif + if (RT_LIKELY(rcMsc == 0)) + return VINF_SUCCESS; + return rcMsc == 2 ? VERR_VMX_INVALID_VMCS_PTR : VERR_VMX_INVALID_VMCS_FIELD; + +# elif ARCH_BITS == 32 + int rc; + uint32_t val_hi, val; + rc = VMXReadVmcs32(idxField, &val); + rc |= VMXReadVmcs32(idxField + 1, &val_hi); + AssertRC(rc); + *pData = RT_MAKE_U64(val, val_hi); + return rc; + +# else +# error "Shouldn't be here..." +# endif +} +#endif + +/** + * Gets the last instruction error value from the current VMCS + * + * @returns error value + */ +DECLINLINE(uint32_t) VMXGetLastError(void) +{ +#if ARCH_BITS == 64 + uint64_t uLastError = 0; + int rc = VMXReadVmcs64(VMX_VMCS32_RO_VM_INSTR_ERROR, &uLastError); + AssertRC(rc); + return (uint32_t)uLastError; + +#else /* 32-bit host: */ + uint32_t uLastError = 0; + int rc = VMXReadVmcs32(VMX_VMCS32_RO_VM_INSTR_ERROR, &uLastError); + AssertRC(rc); + return uLastError; +#endif +} + +#ifdef IN_RING0 +VMMR0DECL(int) VMXR0InvalidatePage(PVM pVM, PVMCPU pVCpu, RTGCPTR GCVirt); +VMMR0DECL(int) VMXR0InvalidatePhysPage(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys); +#endif /* IN_RING0 */ + +/** @} */ + +#endif + diff --git a/include/VBox/vmm/hwacc_vmx.mac b/include/VBox/vmm/hm_vmx.mac index 3fc11b43..3a3a1c7b 100644 --- a/include/VBox/vmm/hwacc_vmx.mac +++ b/include/VBox/vmm/hm_vmx.mac @@ -1,9 +1,9 @@ ;; @file -; HWACCM - VMX Structures and Definitions. +; HM - VMX Structures and Definitions. ; ; -; Copyright (C) 2006-2010 Oracle Corporation +; Copyright (C) 2006-2013 Oracle Corporation ; ; This file is part of VirtualBox Open Source Edition (OSE), as ; available from http://www.virtualbox.org. This file is free software; @@ -60,16 +60,16 @@ %define VMX_VMCS_GUEST_LINK_PTR_HIGH 02801h %define VMX_VMCS_GUEST_DEBUGCTL_FULL 02802h %define VMX_VMCS_GUEST_DEBUGCTL_HIGH 02803h -%define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS 04000h -%define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS 04002h +%define VMX_VMCS_CTRL_PIN_EXEC 04000h +%define VMX_VMCS_CTRL_PROC_EXEC 04002h %define VMX_VMCS_CTRL_EXCEPTION_BITMAP 04004h %define VMX_VMCS_CTRL_PAGEFAULT_ERROR_MASK 04006h %define VMX_VMCS_CTRL_PAGEFAULT_ERROR_MATCH 04008h %define VMX_VMCS_CTRL_CR3_TARGET_COUNT 0400Ah -%define VMX_VMCS_CTRL_EXIT_CONTROLS 0400Ch +%define VMX_VMCS_CTRL_EXIT 0400Ch %define VMX_VMCS_CTRL_EXIT_MSR_STORE_COUNT 0400Eh %define VMX_VMCS_CTRL_EXIT_MSR_LOAD_COUNT 04010h -%define VMX_VMCS_CTRL_ENTRY_CONTROLS 04012h +%define VMX_VMCS_CTRL_ENTRY 04012h %define VMX_VMCS_CTRL_ENTRY_MSR_LOAD_COUNT 04014h %define VMX_VMCS_CTRL_ENTRY_IRQ_INFO 04016h %define VMX_VMCS_CTRL_ENTRY_EXCEPTION_ERRCODE 04018h @@ -118,26 +118,26 @@ %define VMX_VMCS_RO_IO_RDI 06406h %define VMX_VMCS_RO_IO_RIP 06408h %define VMX_VMCS_GUEST_LINEAR_ADDR 0640Ah -%define VMX_VMCS64_GUEST_CR0 06800h -%define VMX_VMCS64_GUEST_CR3 06802h -%define VMX_VMCS64_GUEST_CR4 06804h -%define VMX_VMCS64_GUEST_ES_BASE 06806h -%define VMX_VMCS64_GUEST_CS_BASE 06808h -%define VMX_VMCS64_GUEST_SS_BASE 0680Ah -%define VMX_VMCS64_GUEST_DS_BASE 0680Ch -%define VMX_VMCS64_GUEST_FS_BASE 0680Eh -%define VMX_VMCS64_GUEST_GS_BASE 06810h -%define VMX_VMCS64_GUEST_LDTR_BASE 06812h -%define VMX_VMCS64_GUEST_TR_BASE 06814h -%define VMX_VMCS64_GUEST_GDTR_BASE 06816h -%define VMX_VMCS64_GUEST_IDTR_BASE 06818h -%define VMX_VMCS64_GUEST_DR7 0681Ah -%define VMX_VMCS64_GUEST_RSP 0681Ch -%define VMX_VMCS64_GUEST_RIP 0681Eh -%define VMX_VMCS64_GUEST_RFLAGS 06820h +%define VMX_VMCS64_GUEST_CR0 06800h +%define VMX_VMCS64_GUEST_CR3 06802h +%define VMX_VMCS64_GUEST_CR4 06804h +%define VMX_VMCS64_GUEST_ES_BASE 06806h +%define VMX_VMCS64_GUEST_CS_BASE 06808h +%define VMX_VMCS64_GUEST_SS_BASE 0680Ah +%define VMX_VMCS64_GUEST_DS_BASE 0680Ch +%define VMX_VMCS64_GUEST_FS_BASE 0680Eh +%define VMX_VMCS64_GUEST_GS_BASE 06810h +%define VMX_VMCS64_GUEST_LDTR_BASE 06812h +%define VMX_VMCS64_GUEST_TR_BASE 06814h +%define VMX_VMCS64_GUEST_GDTR_BASE 06816h +%define VMX_VMCS64_GUEST_IDTR_BASE 06818h +%define VMX_VMCS64_GUEST_DR7 0681Ah +%define VMX_VMCS64_GUEST_RSP 0681Ch +%define VMX_VMCS64_GUEST_RIP 0681Eh +%define VMX_VMCS64_GUEST_RFLAGS 06820h %define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS 06822h -%define VMX_VMCS64_GUEST_SYSENTER_ESP 06824h -%define VMX_VMCS64_GUEST_SYSENTER_EIP 06826h +%define VMX_VMCS64_GUEST_SYSENTER_ESP 06824h +%define VMX_VMCS64_GUEST_SYSENTER_EIP 06826h %define VMX_VMCS_HOST_CR0 06C00h %define VMX_VMCS_HOST_CR3 06C02h %define VMX_VMCS_HOST_CR4 06C04h @@ -151,4 +151,31 @@ %define VMX_VMCS_HOST_RSP 06C14h %define VMX_VMCS_HOST_RIP 06C16h -%define VMX_VMCS_CTRL_EXIT_CONTROLS_HOST_AMD64 RT_BIT(9) +%define VMX_RESTORE_HOST_SEL_DS 1h ;RT_BIT(0) +%define VMX_RESTORE_HOST_SEL_ES 2h ;RT_BIT(1) +%define VMX_RESTORE_HOST_SEL_FS 4h ;RT_BIT(2) +%define VMX_RESTORE_HOST_SEL_GS 8h ;RT_BIT(3) +%define VMX_RESTORE_HOST_SEL_TR 10h ;RT_BIT(4) +%define VMX_RESTORE_HOST_GDTR 20h ;RT_BIT(5) +%define VMX_RESTORE_HOST_IDTR 40h ;RT_BIT(6) +%define VMX_RESTORE_HOST_REQUIRED 80h ;RT_BIT(7) + +;; C version hm_vmx.h. +struc VMXRESTOREHOST + .uHostSelDS resw 1 + .uHostSelES resw 1 + .uHostSelFS resw 1 + .uHostSelGS resw 1 + .uHostSelTR resw 1 + .abPadding0 resb 4 + .HostGdtr resb 10 + .abPadding1 resb 6 + .HostIdtr resb 10 + .uHostFSBase resq 1 + .uHostGSBase resq 1 +endstruc +AssertCompileMemberOffset(VMXRESTOREHOST, HostGdtr, 16-2) +AssertCompileMemberOffset(VMXRESTOREHOST, HostIdtr, 32-2) +AssertCompileMemberOffset(VMXRESTOREHOST, uHostFSBase, 40) +AssertCompileSize(VMXRESTOREHOST, 56) + diff --git a/include/VBox/vmm/hwacc_vmx.h b/include/VBox/vmm/hwacc_vmx.h deleted file mode 100644 index a96f587e..00000000 --- a/include/VBox/vmm/hwacc_vmx.h +++ /dev/null @@ -1,1708 +0,0 @@ -/** @file - * HWACCM - VMX Structures and Definitions. (VMM) - */ - -/* - * Copyright (C) 2006-2010 Oracle Corporation - * - * This file is part of VirtualBox Open Source Edition (OSE), as - * available from http://www.virtualbox.org. This file is free software; - * you can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) as published by the Free Software - * Foundation, in version 2 as it comes in the "COPYING" file of the - * VirtualBox OSE distribution. VirtualBox OSE is distributed in the - * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. - * - * The contents of this file may alternatively be used under the terms - * of the Common Development and Distribution License Version 1.0 - * (CDDL) only, as it comes in the "COPYING.CDDL" file of the - * VirtualBox OSE distribution, in which case the provisions of the - * CDDL are applicable instead of those of the GPL. - * - * You may elect to license modified versions of this file under the - * terms and conditions of either the GPL or the CDDL or both. - */ - -#ifndef ___VBox_vmm_vmx_h -#define ___VBox_vmm_vmx_h - -#include <VBox/types.h> -#include <VBox/err.h> -#include <iprt/x86.h> -#include <iprt/assert.h> - -/** @defgroup grp_vmx vmx Types and Definitions - * @ingroup grp_hwaccm - * @{ - */ - -/** @name VMX EPT paging structures - * @{ - */ - -/** - * Number of page table entries in the EPT. (PDPTE/PDE/PTE) - */ -#define EPT_PG_ENTRIES X86_PG_PAE_ENTRIES - -/** - * EPT Page Directory Pointer Entry. Bit view. - * @todo uint64_t isn't safe for bitfields (gcc pedantic warnings, and IIRC, - * this did cause trouble with one compiler/version). - */ -#pragma pack(1) -typedef struct EPTPML4EBITS -{ - /** Present bit. */ - uint64_t u1Present : 1; - /** Writable bit. */ - uint64_t u1Write : 1; - /** Executable bit. */ - uint64_t u1Execute : 1; - /** Reserved (must be 0). */ - uint64_t u5Reserved : 5; - /** Available for software. */ - uint64_t u4Available : 4; - /** Physical address of the next level (PD). Restricted by maximum physical address width of the cpu. */ - uint64_t u40PhysAddr : 40; - /** Availabe for software. */ - uint64_t u12Available : 12; -} EPTPML4EBITS; -#pragma pack() -AssertCompileSize(EPTPML4EBITS, 8); - -/** Bits 12-51 - - EPT - Physical Page number of the next level. */ -#define EPT_PML4E_PG_MASK X86_PML4E_PG_MASK -/** The page shift to get the PML4 index. */ -#define EPT_PML4_SHIFT X86_PML4_SHIFT -/** The PML4 index mask (apply to a shifted page address). */ -#define EPT_PML4_MASK X86_PML4_MASK - -/** - * EPT PML4E. - */ -#pragma pack(1) -typedef union EPTPML4E -{ - /** Normal view. */ - EPTPML4EBITS n; - /** Unsigned integer view. */ - X86PGPAEUINT u; - /** 64 bit unsigned integer view. */ - uint64_t au64[1]; - /** 32 bit unsigned integer view. */ - uint32_t au32[2]; -} EPTPML4E; -#pragma pack() -/** Pointer to a PML4 table entry. */ -typedef EPTPML4E *PEPTPML4E; -/** Pointer to a const PML4 table entry. */ -typedef const EPTPML4E *PCEPTPML4E; -AssertCompileSize(EPTPML4E, 8); - -/** - * EPT PML4 Table. - */ -#pragma pack(1) -typedef struct EPTPML4 -{ - EPTPML4E a[EPT_PG_ENTRIES]; -} EPTPML4; -#pragma pack() -/** Pointer to an EPT PML4 Table. */ -typedef EPTPML4 *PEPTPML4; -/** Pointer to a const EPT PML4 Table. */ -typedef const EPTPML4 *PCEPTPML4; - -/** - * EPT Page Directory Pointer Entry. Bit view. - */ -#pragma pack(1) -typedef struct EPTPDPTEBITS -{ - /** Present bit. */ - uint64_t u1Present : 1; - /** Writable bit. */ - uint64_t u1Write : 1; - /** Executable bit. */ - uint64_t u1Execute : 1; - /** Reserved (must be 0). */ - uint64_t u5Reserved : 5; - /** Available for software. */ - uint64_t u4Available : 4; - /** Physical address of the next level (PD). Restricted by maximum physical address width of the cpu. */ - uint64_t u40PhysAddr : 40; - /** Availabe for software. */ - uint64_t u12Available : 12; -} EPTPDPTEBITS; -#pragma pack() -AssertCompileSize(EPTPDPTEBITS, 8); - -/** Bits 12-51 - - EPT - Physical Page number of the next level. */ -#define EPT_PDPTE_PG_MASK X86_PDPE_PG_MASK -/** The page shift to get the PDPT index. */ -#define EPT_PDPT_SHIFT X86_PDPT_SHIFT -/** The PDPT index mask (apply to a shifted page address). */ -#define EPT_PDPT_MASK X86_PDPT_MASK_AMD64 - -/** - * EPT Page Directory Pointer. - */ -#pragma pack(1) -typedef union EPTPDPTE -{ - /** Normal view. */ - EPTPDPTEBITS n; - /** Unsigned integer view. */ - X86PGPAEUINT u; - /** 64 bit unsigned integer view. */ - uint64_t au64[1]; - /** 32 bit unsigned integer view. */ - uint32_t au32[2]; -} EPTPDPTE; -#pragma pack() -/** Pointer to an EPT Page Directory Pointer Entry. */ -typedef EPTPDPTE *PEPTPDPTE; -/** Pointer to a const EPT Page Directory Pointer Entry. */ -typedef const EPTPDPTE *PCEPTPDPTE; -AssertCompileSize(EPTPDPTE, 8); - -/** - * EPT Page Directory Pointer Table. - */ -#pragma pack(1) -typedef struct EPTPDPT -{ - EPTPDPTE a[EPT_PG_ENTRIES]; -} EPTPDPT; -#pragma pack() -/** Pointer to an EPT Page Directory Pointer Table. */ -typedef EPTPDPT *PEPTPDPT; -/** Pointer to a const EPT Page Directory Pointer Table. */ -typedef const EPTPDPT *PCEPTPDPT; - - -/** - * EPT Page Directory Table Entry. Bit view. - */ -#pragma pack(1) -typedef struct EPTPDEBITS -{ - /** Present bit. */ - uint64_t u1Present : 1; - /** Writable bit. */ - uint64_t u1Write : 1; - /** Executable bit. */ - uint64_t u1Execute : 1; - /** Reserved (must be 0). */ - uint64_t u4Reserved : 4; - /** Big page (must be 0 here). */ - uint64_t u1Size : 1; - /** Available for software. */ - uint64_t u4Available : 4; - /** Physical address of page table. Restricted by maximum physical address width of the cpu. */ - uint64_t u40PhysAddr : 40; - /** Availabe for software. */ - uint64_t u12Available : 12; -} EPTPDEBITS; -#pragma pack() -AssertCompileSize(EPTPDEBITS, 8); - -/** Bits 12-51 - - EPT - Physical Page number of the next level. */ -#define EPT_PDE_PG_MASK X86_PDE_PAE_PG_MASK -/** The page shift to get the PD index. */ -#define EPT_PD_SHIFT X86_PD_PAE_SHIFT -/** The PD index mask (apply to a shifted page address). */ -#define EPT_PD_MASK X86_PD_PAE_MASK - -/** - * EPT 2MB Page Directory Table Entry. Bit view. - */ -#pragma pack(1) -typedef struct EPTPDE2MBITS -{ - /** Present bit. */ - uint64_t u1Present : 1; - /** Writable bit. */ - uint64_t u1Write : 1; - /** Executable bit. */ - uint64_t u1Execute : 1; - /** EPT Table Memory Type. MBZ for non-leaf nodes. */ - uint64_t u3EMT : 3; - /** Ignore PAT memory type */ - uint64_t u1IgnorePAT : 1; - /** Big page (must be 1 here). */ - uint64_t u1Size : 1; - /** Available for software. */ - uint64_t u4Available : 4; - /** Reserved (must be 0). */ - uint64_t u9Reserved : 9; - /** Physical address of the 2MB page. Restricted by maximum physical address width of the cpu. */ - uint64_t u31PhysAddr : 31; - /** Availabe for software. */ - uint64_t u12Available : 12; -} EPTPDE2MBITS; -#pragma pack() -AssertCompileSize(EPTPDE2MBITS, 8); - -/** Bits 21-51 - - EPT - Physical Page number of the next level. */ -#define EPT_PDE2M_PG_MASK X86_PDE2M_PAE_PG_MASK - -/** - * EPT Page Directory Table Entry. - */ -#pragma pack(1) -typedef union EPTPDE -{ - /** Normal view. */ - EPTPDEBITS n; - /** 2MB view (big). */ - EPTPDE2MBITS b; - /** Unsigned integer view. */ - X86PGPAEUINT u; - /** 64 bit unsigned integer view. */ - uint64_t au64[1]; - /** 32 bit unsigned integer view. */ - uint32_t au32[2]; -} EPTPDE; -#pragma pack() -/** Pointer to an EPT Page Directory Table Entry. */ -typedef EPTPDE *PEPTPDE; -/** Pointer to a const EPT Page Directory Table Entry. */ -typedef const EPTPDE *PCEPTPDE; -AssertCompileSize(EPTPDE, 8); - -/** - * EPT Page Directory Table. - */ -#pragma pack(1) -typedef struct EPTPD -{ - EPTPDE a[EPT_PG_ENTRIES]; -} EPTPD; -#pragma pack() -/** Pointer to an EPT Page Directory Table. */ -typedef EPTPD *PEPTPD; -/** Pointer to a const EPT Page Directory Table. */ -typedef const EPTPD *PCEPTPD; - - -/** - * EPT Page Table Entry. Bit view. - */ -#pragma pack(1) -typedef struct EPTPTEBITS -{ - /** 0 - Present bit. - * @remark This is a convenience "misnomer". The bit actually indicates - * read access and the CPU will consider an entry with any of the - * first three bits set as present. Since all our valid entries - * will have this bit set, it can be used as a present indicator - * and allow some code sharing. */ - uint64_t u1Present : 1; - /** 1 - Writable bit. */ - uint64_t u1Write : 1; - /** 2 - Executable bit. */ - uint64_t u1Execute : 1; - /** 5:3 - EPT Memory Type. MBZ for non-leaf nodes. */ - uint64_t u3EMT : 3; - /** 6 - Ignore PAT memory type */ - uint64_t u1IgnorePAT : 1; - /** 11:7 - Available for software. */ - uint64_t u5Available : 5; - /** 51:12 - Physical address of page. Restricted by maximum physical - * address width of the cpu. */ - uint64_t u40PhysAddr : 40; - /** 63:52 - Available for software. */ - uint64_t u12Available : 12; -} EPTPTEBITS; -#pragma pack() -AssertCompileSize(EPTPTEBITS, 8); - -/** Bits 12-51 - - EPT - Physical Page number of the next level. */ -#define EPT_PTE_PG_MASK X86_PTE_PAE_PG_MASK -/** The page shift to get the EPT PTE index. */ -#define EPT_PT_SHIFT X86_PT_PAE_SHIFT -/** The EPT PT index mask (apply to a shifted page address). */ -#define EPT_PT_MASK X86_PT_PAE_MASK - -/** - * EPT Page Table Entry. - */ -#pragma pack(1) -typedef union EPTPTE -{ - /** Normal view. */ - EPTPTEBITS n; - /** Unsigned integer view. */ - X86PGPAEUINT u; - /** 64 bit unsigned integer view. */ - uint64_t au64[1]; - /** 32 bit unsigned integer view. */ - uint32_t au32[2]; -} EPTPTE; -#pragma pack() -/** Pointer to an EPT Page Directory Table Entry. */ -typedef EPTPTE *PEPTPTE; -/** Pointer to a const EPT Page Directory Table Entry. */ -typedef const EPTPTE *PCEPTPTE; -AssertCompileSize(EPTPTE, 8); - -/** - * EPT Page Table. - */ -#pragma pack(1) -typedef struct EPTPT -{ - EPTPTE a[EPT_PG_ENTRIES]; -} EPTPT; -#pragma pack() -/** Pointer to an extended page table. */ -typedef EPTPT *PEPTPT; -/** Pointer to a const extended table. */ -typedef const EPTPT *PCEPTPT; - -/** - * VPID flush types. - */ -typedef enum -{ - /** Invalidate a specific page. */ - VMX_FLUSH_VPID_INDIV_ADDR = 0, - /** Invalidate one context (specific VPID). */ - VMX_FLUSH_VPID_SINGLE_CONTEXT = 1, - /** Invalidate all contexts (all VPIDs). */ - VMX_FLUSH_VPID_ALL_CONTEXTS = 2, - /** Invalidate a single VPID context retaining global mappings. */ - VMX_FLUSH_VPID_SINGLE_CONTEXT_RETAIN_GLOBALS = 3, - /** Unsupported by VirtualBox. */ - VMX_FLUSH_VPID_NOT_SUPPORTED = 0xbad, - /** Unsupported by CPU. */ - VMX_FLUSH_VPID_NONE = 0xb00, - /** 32bit hackishness. */ - VMX_FLUSH_VPID_32BIT_HACK = 0x7fffffff -} VMX_FLUSH_VPID; - -/** - * EPT flush types. - */ -typedef enum -{ - /** Invalidate one context (specific EPT). */ - VMX_FLUSH_EPT_SINGLE_CONTEXT = 1, - /* Invalidate all contexts (all EPTs) */ - VMX_FLUSH_EPT_ALL_CONTEXTS = 2, - /** Unsupported by VirtualBox. */ - VMX_FLUSH_EPT_NOT_SUPPORTED = 0xbad, - /** Unsupported by CPU. */ - VMX_FLUSH_EPT_NONE = 0xb00, - /** 32bit hackishness. */ - VMX_FLUSH_EPT_32BIT_HACK = 0x7fffffff -} VMX_FLUSH_EPT; -/** @} */ - -/** @name MSR load/store elements - * @{ - */ -#pragma pack(1) -typedef struct -{ - uint32_t u32IndexMSR; - uint32_t u32Reserved; - uint64_t u64Value; -} VMXMSR; -#pragma pack() -/** Pointer to an MSR load/store element. */ -typedef VMXMSR *PVMXMSR; -/** Pointer to a const MSR load/store element. */ -typedef const VMXMSR *PCVMXMSR; - -/** @} */ - - -/** @name VT-x capability qword - * @{ - */ -#pragma pack(1) -typedef union -{ - struct - { - uint32_t disallowed0; - uint32_t allowed1; - } n; - uint64_t u; -} VMX_CAPABILITY; -#pragma pack() -/** @} */ - -/** @name VMX Basic Exit Reasons. - * @{ - */ -/** And-mask for setting reserved bits to zero */ -#define VMX_EFLAGS_RESERVED_0 (~0xffc08028) -/** Or-mask for setting reserved bits to 1 */ -#define VMX_EFLAGS_RESERVED_1 0x00000002 -/** @} */ - -/** @name VMX Basic Exit Reasons. - * @{ - */ -/** -1 Invalid exit code */ -#define VMX_EXIT_INVALID -1 -/** 0 Exception or non-maskable interrupt (NMI). */ -#define VMX_EXIT_EXCEPTION 0 -/** 1 External interrupt. */ -#define VMX_EXIT_EXTERNAL_IRQ 1 -/** 2 Triple fault. */ -#define VMX_EXIT_TRIPLE_FAULT 2 -/** 3 INIT signal. */ -#define VMX_EXIT_INIT_SIGNAL 3 -/** 4 Start-up IPI (SIPI). */ -#define VMX_EXIT_SIPI 4 -/** 5 I/O system-management interrupt (SMI). */ -#define VMX_EXIT_IO_SMI_IRQ 5 -/** 6 Other SMI. */ -#define VMX_EXIT_SMI_IRQ 6 -/** 7 Interrupt window. */ -#define VMX_EXIT_IRQ_WINDOW 7 -/** 9 Task switch. */ -#define VMX_EXIT_TASK_SWITCH 9 -/** 10 Guest software attempted to execute CPUID. */ -#define VMX_EXIT_CPUID 10 -/** 12 Guest software attempted to execute HLT. */ -#define VMX_EXIT_HLT 12 -/** 13 Guest software attempted to execute INVD. */ -#define VMX_EXIT_INVD 13 -/** 14 Guest software attempted to execute INVLPG. */ -#define VMX_EXIT_INVLPG 14 -/** 15 Guest software attempted to execute RDPMC. */ -#define VMX_EXIT_RDPMC 15 -/** 16 Guest software attempted to execute RDTSC. */ -#define VMX_EXIT_RDTSC 16 -/** 17 Guest software attempted to execute RSM in SMM. */ -#define VMX_EXIT_RSM 17 -/** 18 Guest software executed VMCALL. */ -#define VMX_EXIT_VMCALL 18 -/** 19 Guest software executed VMCLEAR. */ -#define VMX_EXIT_VMCLEAR 19 -/** 20 Guest software executed VMLAUNCH. */ -#define VMX_EXIT_VMLAUNCH 20 -/** 21 Guest software executed VMPTRLD. */ -#define VMX_EXIT_VMPTRLD 21 -/** 22 Guest software executed VMPTRST. */ -#define VMX_EXIT_VMPTRST 22 -/** 23 Guest software executed VMREAD. */ -#define VMX_EXIT_VMREAD 23 -/** 24 Guest software executed VMRESUME. */ -#define VMX_EXIT_VMRESUME 24 -/** 25 Guest software executed VMWRITE. */ -#define VMX_EXIT_VMWRITE 25 -/** 26 Guest software executed VMXOFF. */ -#define VMX_EXIT_VMXOFF 26 -/** 27 Guest software executed VMXON. */ -#define VMX_EXIT_VMXON 27 -/** 28 Control-register accesses. */ -#define VMX_EXIT_CRX_MOVE 28 -/** 29 Debug-register accesses. */ -#define VMX_EXIT_DRX_MOVE 29 -/** 30 I/O instruction. */ -#define VMX_EXIT_PORT_IO 30 -/** 31 RDMSR. Guest software attempted to execute RDMSR. */ -#define VMX_EXIT_RDMSR 31 -/** 32 WRMSR. Guest software attempted to execute WRMSR. */ -#define VMX_EXIT_WRMSR 32 -/** 33 VM-entry failure due to invalid guest state. */ -#define VMX_EXIT_ERR_INVALID_GUEST_STATE 33 -/** 34 VM-entry failure due to MSR loading. */ -#define VMX_EXIT_ERR_MSR_LOAD 34 -/** 36 Guest software executed MWAIT. */ -#define VMX_EXIT_MWAIT 36 -/** 37 VM exit due to monitor trap flag. */ -#define VMX_EXIT_MTF 37 -/** 39 Guest software attempted to execute MONITOR. */ -#define VMX_EXIT_MONITOR 39 -/** 40 Guest software attempted to execute PAUSE. */ -#define VMX_EXIT_PAUSE 40 -/** 41 VM-entry failure due to machine-check. */ -#define VMX_EXIT_ERR_MACHINE_CHECK 41 -/** 43 TPR below threshold. Guest software executed MOV to CR8. */ -#define VMX_EXIT_TPR 43 -/** 44 APIC access. Guest software attempted to access memory at a physical address on the APIC-access page. */ -#define VMX_EXIT_APIC_ACCESS 44 -/** 46 Access to GDTR or IDTR. Guest software attempted to execute LGDT, LIDT, SGDT, or SIDT. */ -#define VMX_EXIT_XDTR_ACCESS 46 -/** 47 Access to LDTR or TR. Guest software attempted to execute LLDT, LTR, SLDT, or STR. */ -#define VMX_EXIT_TR_ACCESS 47 -/** 48 EPT violation. An attempt to access memory with a guest-physical address was disallowed by the configuration of the EPT paging structures. */ -#define VMX_EXIT_EPT_VIOLATION 48 -/** 49 EPT misconfiguration. An attempt to access memory with a guest-physical address encountered a misconfigured EPT paging-structure entry. */ -#define VMX_EXIT_EPT_MISCONFIG 49 -/** 50 INVEPT. Guest software attempted to execute INVEPT. */ -#define VMX_EXIT_INVEPT 50 -/** 51 RDTSCP. Guest software attempted to execute RDTSCP. */ -#define VMX_EXIT_RDTSCP 51 -/** 52 VMX-preemption timer expired. The preemption timer counted down to zero. */ -#define VMX_EXIT_PREEMPTION_TIMER 52 -/** 53 INVVPID. Guest software attempted to execute INVVPID. */ -#define VMX_EXIT_INVVPID 53 -/** 54 WBINVD. Guest software attempted to execute WBINVD. */ -#define VMX_EXIT_WBINVD 54 -/** 55 XSETBV. Guest software attempted to execute XSETBV. */ -#define VMX_EXIT_XSETBV 55 -/** @} */ - - -/** @name VM Instruction Errors - * @{ - */ -/** 1 VMCALL executed in VMX root operation. */ -#define VMX_ERROR_VMCALL 1 -/** 2 VMCLEAR with invalid physical address. */ -#define VMX_ERROR_VMCLEAR_INVALID_PHYS_ADDR 2 -/** 3 VMCLEAR with VMXON pointer. */ -#define VMX_ERROR_VMCLEAR_INVALID_VMXON_PTR 3 -/** 4 VMLAUNCH with non-clear VMCS. */ -#define VMX_ERROR_VMLAUCH_NON_CLEAR_VMCS 4 -/** 5 VMRESUME with non-launched VMCS. */ -#define VMX_ERROR_VMRESUME_NON_LAUNCHED_VMCS 5 -/** 6 VMRESUME with a corrupted VMCS (indicates corruption of the current VMCS). */ -#define VMX_ERROR_VMRESUME_CORRUPTED_VMCS 6 -/** 7 VM entry with invalid control field(s). */ -#define VMX_ERROR_VMENTRY_INVALID_CONTROL_FIELDS 7 -/** 8 VM entry with invalid host-state field(s). */ -#define VMX_ERROR_VMENTRY_INVALID_HOST_STATE 8 -/** 9 VMPTRLD with invalid physical address. */ -#define VMX_ERROR_VMPTRLD_INVALID_PHYS_ADDR 9 -/** 10 VMPTRLD with VMXON pointer. */ -#define VMX_ERROR_VMPTRLD_VMXON_PTR 10 -/** 11 VMPTRLD with incorrect VMCS revision identifier. */ -#define VMX_ERROR_VMPTRLD_WRONG_VMCS_REVISION 11 -/** 12 VMREAD/VMWRITE from/to unsupported VMCS component. */ -#define VMX_ERROR_VMREAD_INVALID_COMPONENT 12 -#define VMX_ERROR_VMWRITE_INVALID_COMPONENT VMX_ERROR_VMREAD_INVALID_COMPONENT -/** 13 VMWRITE to read-only VMCS component. */ -#define VMX_ERROR_VMWRITE_READONLY_COMPONENT 13 -/** 15 VMXON executed in VMX root operation. */ -#define VMX_ERROR_VMXON_IN_VMX_ROOT_OP 15 -/** 16 VM entry with invalid executive-VMCS pointer. */ -#define VMX_ERROR_VMENTRY_INVALID_VMCS_EXEC_PTR 16 -/** 17 VM entry with non-launched executive VMCS. */ -#define VMX_ERROR_VMENTRY_NON_LAUNCHED_EXEC_VMCS 17 -/** 18 VM entry with executive-VMCS pointer not VMXON pointer. */ -#define VMX_ERROR_VMENTRY_EXEC_VMCS_PTR 18 -/** 19 VMCALL with non-clear VMCS. */ -#define VMX_ERROR_VMCALL_NON_CLEAR_VMCS 19 -/** 20 VMCALL with invalid VM-exit control fields. */ -#define VMX_ERROR_VMCALL_INVALID_VMEXIT_FIELDS 20 -/** 22 VMCALL with incorrect MSEG revision identifier. */ -#define VMX_ERROR_VMCALL_INVALID_MSEG_REVISION 22 -/** 23 VMXOFF under dual-monitor treatment of SMIs and SMM. */ -#define VMX_ERROR_VMXOFF_DUAL_MONITOR 23 -/** 24 VMCALL with invalid SMM-monitor features. */ -#define VMX_ERROR_VMCALL_INVALID_SMM_MONITOR 24 -/** 25 VM entry with invalid VM-execution control fields in executive VMCS. */ -#define VMX_ERROR_VMENTRY_INVALID_VM_EXEC_CTRL 25 -/** 26 VM entry with events blocked by MOV SS. */ -#define VMX_ERROR_VMENTRY_MOV_SS 26 -/** 26 Invalid operand to INVEPT/INVVPID. */ -#define VMX_ERROR_INVEPTVPID_INVALID_OPERAND 28 - -/** @} */ - - -/** @name VMX MSRs - Basic VMX information. - * @{ - */ -/** VMCS revision identifier used by the processor. */ -#define MSR_IA32_VMX_BASIC_INFO_VMCS_ID(a) (a & 0x7FFFFFFF) -/** Size of the VMCS. */ -#define MSR_IA32_VMX_BASIC_INFO_VMCS_SIZE(a) (((a) >> 32) & 0xFFF) -/** Width of physical address used for the VMCS. - * 0 -> limited to the available amount of physical ram - * 1 -> within the first 4 GB - */ -#define MSR_IA32_VMX_BASIC_INFO_VMCS_PHYS_WIDTH(a) (((a) >> 48) & 1) -/** Whether the processor supports the dual-monitor treatment of system-management interrupts and system-management code. (always 1) */ -#define MSR_IA32_VMX_BASIC_INFO_VMCS_DUAL_MON(a) (((a) >> 49) & 1) -/** Memory type that must be used for the VMCS. */ -#define MSR_IA32_VMX_BASIC_INFO_VMCS_MEM_TYPE(a) (((a) >> 50) & 0xF) -/** @} */ - - -/** @name VMX MSRs - Misc VMX info. - * @{ - */ -/** Relationship between the preemption timer and tsc; count down every time bit x of the tsc changes. */ -#define MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(a) ((a) & 0x1f) -/** Activity states supported by the implementation. */ -#define MSR_IA32_VMX_MISC_ACTIVITY_STATES(a) (((a) >> 6) & 0x7) -/** Number of CR3 target values supported by the processor. (0-256) */ -#define MSR_IA32_VMX_MISC_CR3_TARGET(a) (((a) >> 16) & 0x1FF) -/** Maximum nr of MSRs in the VMCS. (N+1)*512. */ -#define MSR_IA32_VMX_MISC_MAX_MSR(a) (((((a) >> 25) & 0x7) + 1) * 512) -/** MSEG revision identifier used by the processor. */ -#define MSR_IA32_VMX_MISC_MSEG_ID(a) ((a) >> 32) -/** @} */ - - -/** @name VMX MSRs - VMCS enumeration field info - * @{ - */ -/** Highest field index. */ -#define MSR_IA32_VMX_VMCS_ENUM_HIGHEST_INDEX(a) (((a) >> 1) & 0x1FF) - -/** @} */ - - -/** @name MSR_IA32_VMX_EPT_CAPS; EPT capabilities MSR - * @{ - */ -#define MSR_IA32_VMX_EPT_CAPS_RWX_X_ONLY RT_BIT_64(0) -#define MSR_IA32_VMX_EPT_CAPS_RWX_W_ONLY RT_BIT_64(1) -#define MSR_IA32_VMX_EPT_CAPS_RWX_WX_ONLY RT_BIT_64(2) -#define MSR_IA32_VMX_EPT_CAPS_GAW_21_BITS RT_BIT_64(3) -#define MSR_IA32_VMX_EPT_CAPS_GAW_30_BITS RT_BIT_64(4) -#define MSR_IA32_VMX_EPT_CAPS_GAW_39_BITS RT_BIT_64(5) -#define MSR_IA32_VMX_EPT_CAPS_GAW_48_BITS RT_BIT_64(6) -#define MSR_IA32_VMX_EPT_CAPS_GAW_57_BITS RT_BIT_64(7) -#define MSR_IA32_VMX_EPT_CAPS_EMT_UC RT_BIT_64(8) -#define MSR_IA32_VMX_EPT_CAPS_EMT_WC RT_BIT_64(9) -#define MSR_IA32_VMX_EPT_CAPS_EMT_WT RT_BIT_64(12) -#define MSR_IA32_VMX_EPT_CAPS_EMT_WP RT_BIT_64(13) -#define MSR_IA32_VMX_EPT_CAPS_EMT_WB RT_BIT_64(14) -#define MSR_IA32_VMX_EPT_CAPS_SP_21_BITS RT_BIT_64(16) -#define MSR_IA32_VMX_EPT_CAPS_SP_30_BITS RT_BIT_64(17) -#define MSR_IA32_VMX_EPT_CAPS_SP_39_BITS RT_BIT_64(18) -#define MSR_IA32_VMX_EPT_CAPS_SP_48_BITS RT_BIT_64(19) -#define MSR_IA32_VMX_EPT_CAPS_INVEPT RT_BIT_64(20) -#define MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_SINGLE_CONTEXT RT_BIT_64(25) -#define MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_ALL_CONTEXTS RT_BIT_64(26) -#define MSR_IA32_VMX_EPT_CAPS_INVVPID RT_BIT_64(32) -#define MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_INDIV_ADDR RT_BIT_64(40) -#define MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT RT_BIT_64(41) -#define MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_ALL_CONTEXTS RT_BIT_64(42) -#define MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT_RETAIN_GLOBALS RT_BIT_64(43) - -/** @} */ - -/** @name Extended Page Table Pointer (EPTP) - * @{ - */ -/** Uncachable EPT paging structure memory type. */ -#define VMX_EPT_MEMTYPE_UC 0 -/** Write-back EPT paging structure memory type. */ -#define VMX_EPT_MEMTYPE_WB 6 -/** Shift value to get the EPT page walk length (bits 5-3) */ -#define VMX_EPT_PAGE_WALK_LENGTH_SHIFT 3 -/** Mask value to get the EPT page walk length (bits 5-3) */ -#define VMX_EPT_PAGE_WALK_LENGTH_MASK 7 -/** Default EPT page walk length */ -#define VMX_EPT_PAGE_WALK_LENGTH_DEFAULT 3 -/** @} */ - - -/** @name VMCS field encoding - 16 bits guest fields - * @{ - */ -#define VMX_VMCS16_GUEST_FIELD_VPID 0x0 -#define VMX_VMCS16_GUEST_FIELD_ES 0x800 -#define VMX_VMCS16_GUEST_FIELD_CS 0x802 -#define VMX_VMCS16_GUEST_FIELD_SS 0x804 -#define VMX_VMCS16_GUEST_FIELD_DS 0x806 -#define VMX_VMCS16_GUEST_FIELD_FS 0x808 -#define VMX_VMCS16_GUEST_FIELD_GS 0x80A -#define VMX_VMCS16_GUEST_FIELD_LDTR 0x80C -#define VMX_VMCS16_GUEST_FIELD_TR 0x80E -/** @} */ - -/** @name VMCS field encoding - 16 bits host fields - * @{ - */ -#define VMX_VMCS16_HOST_FIELD_ES 0xC00 -#define VMX_VMCS16_HOST_FIELD_CS 0xC02 -#define VMX_VMCS16_HOST_FIELD_SS 0xC04 -#define VMX_VMCS16_HOST_FIELD_DS 0xC06 -#define VMX_VMCS16_HOST_FIELD_FS 0xC08 -#define VMX_VMCS16_HOST_FIELD_GS 0xC0A -#define VMX_VMCS16_HOST_FIELD_TR 0xC0C -/** @} */ - -/** @name VMCS field encoding - 64 bits host fields - * @{ - */ -#define VMX_VMCS_HOST_FIELD_PAT_FULL 0x2C00 -#define VMX_VMCS_HOST_FIELD_PAT_HIGH 0x2C01 -#define VMX_VMCS_HOST_FIELD_EFER_FULL 0x2C02 -#define VMX_VMCS_HOST_FIELD_EFER_HIGH 0x2C03 -#define VMX_VMCS_HOST_PERF_GLOBAL_CTRL_FULL 0x2C04 /**< MSR IA32_PERF_GLOBAL_CTRL */ -#define VMX_VMCS_HOST_PERF_GLOBAL_CTRL_HIGH 0x2C05 /**< MSR IA32_PERF_GLOBAL_CTRL */ -/** @} */ - - -/** @name VMCS field encoding - 64 Bits control fields - * @{ - */ -#define VMX_VMCS_CTRL_IO_BITMAP_A_FULL 0x2000 -#define VMX_VMCS_CTRL_IO_BITMAP_A_HIGH 0x2001 -#define VMX_VMCS_CTRL_IO_BITMAP_B_FULL 0x2002 -#define VMX_VMCS_CTRL_IO_BITMAP_B_HIGH 0x2003 - -/* Optional */ -#define VMX_VMCS_CTRL_MSR_BITMAP_FULL 0x2004 -#define VMX_VMCS_CTRL_MSR_BITMAP_HIGH 0x2005 - -#define VMX_VMCS_CTRL_VMEXIT_MSR_STORE_FULL 0x2006 -#define VMX_VMCS_CTRL_VMEXIT_MSR_STORE_HIGH 0x2007 -#define VMX_VMCS_CTRL_VMEXIT_MSR_LOAD_FULL 0x2008 -#define VMX_VMCS_CTRL_VMEXIT_MSR_LOAD_HIGH 0x2009 - -#define VMX_VMCS_CTRL_VMENTRY_MSR_LOAD_FULL 0x200A -#define VMX_VMCS_CTRL_VMENTRY_MSR_LOAD_HIGH 0x200B - -#define VMX_VMCS_CTRL_EXEC_VMCS_PTR_FULL 0x200C -#define VMX_VMCS_CTRL_EXEC_VMCS_PTR_HIGH 0x200D - -#define VMX_VMCS_CTRL_TSC_OFFSET_FULL 0x2010 -#define VMX_VMCS_CTRL_TSC_OFFSET_HIGH 0x2011 - -/** Optional (VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW) */ -#define VMX_VMCS_CTRL_VAPIC_PAGEADDR_FULL 0x2012 -#define VMX_VMCS_CTRL_VAPIC_PAGEADDR_HIGH 0x2013 - -/** Optional (VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC) */ -#define VMX_VMCS_CTRL_APIC_ACCESSADDR_FULL 0x2014 -#define VMX_VMCS_CTRL_APIC_ACCESSADDR_HIGH 0x2015 - -/** Extended page table pointer. */ -#define VMX_VMCS_CTRL_EPTP_FULL 0x201a -#define VMX_VMCS_CTRL_EPTP_HIGH 0x201b - -/** VM-exit phyiscal address. */ -#define VMX_VMCS_EXIT_PHYS_ADDR_FULL 0x2400 -#define VMX_VMCS_EXIT_PHYS_ADDR_HIGH 0x2401 -/** @} */ - - -/** @name VMCS field encoding - 64 Bits guest fields - * @{ - */ -#define VMX_VMCS_GUEST_LINK_PTR_FULL 0x2800 -#define VMX_VMCS_GUEST_LINK_PTR_HIGH 0x2801 -#define VMX_VMCS_GUEST_DEBUGCTL_FULL 0x2802 /**< MSR IA32_DEBUGCTL */ -#define VMX_VMCS_GUEST_DEBUGCTL_HIGH 0x2803 /**< MSR IA32_DEBUGCTL */ -#define VMX_VMCS_GUEST_PAT_FULL 0x2804 -#define VMX_VMCS_GUEST_PAT_HIGH 0x2805 -#define VMX_VMCS_GUEST_EFER_FULL 0x2806 -#define VMX_VMCS_GUEST_EFER_HIGH 0x2807 -#define VMX_VMCS_GUEST_PERF_GLOBAL_CTRL_FULL 0x2808 /**< MSR IA32_PERF_GLOBAL_CTRL */ -#define VMX_VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH 0x2809 /**< MSR IA32_PERF_GLOBAL_CTRL */ -#define VMX_VMCS_GUEST_PDPTR0_FULL 0x280A -#define VMX_VMCS_GUEST_PDPTR0_HIGH 0x280B -#define VMX_VMCS_GUEST_PDPTR1_FULL 0x280C -#define VMX_VMCS_GUEST_PDPTR1_HIGH 0x280D -#define VMX_VMCS_GUEST_PDPTR2_FULL 0x280E -#define VMX_VMCS_GUEST_PDPTR2_HIGH 0x280F -#define VMX_VMCS_GUEST_PDPTR3_FULL 0x2810 -#define VMX_VMCS_GUEST_PDPTR3_HIGH 0x2811 -/** @} */ - - -/** @name VMCS field encoding - 32 Bits control fields - * @{ - */ -#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS 0x4000 -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS 0x4002 -#define VMX_VMCS_CTRL_EXCEPTION_BITMAP 0x4004 -#define VMX_VMCS_CTRL_PAGEFAULT_ERROR_MASK 0x4006 -#define VMX_VMCS_CTRL_PAGEFAULT_ERROR_MATCH 0x4008 -#define VMX_VMCS_CTRL_CR3_TARGET_COUNT 0x400A -#define VMX_VMCS_CTRL_EXIT_CONTROLS 0x400C -#define VMX_VMCS_CTRL_EXIT_MSR_STORE_COUNT 0x400E -#define VMX_VMCS_CTRL_EXIT_MSR_LOAD_COUNT 0x4010 -#define VMX_VMCS_CTRL_ENTRY_CONTROLS 0x4012 -#define VMX_VMCS_CTRL_ENTRY_MSR_LOAD_COUNT 0x4014 -#define VMX_VMCS_CTRL_ENTRY_IRQ_INFO 0x4016 -#define VMX_VMCS_CTRL_ENTRY_EXCEPTION_ERRCODE 0x4018 -#define VMX_VMCS_CTRL_ENTRY_INSTR_LENGTH 0x401A -/** This field exists only on processors that support the 1-setting of the “use TPR shadow” VM-execution control. */ -#define VMX_VMCS_CTRL_TPR_THRESHOLD 0x401C -/** This field exists only on processors that support the 1-setting of the “activate secondary controls” VM-execution control. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS2 0x401E -/** @} */ - - -/** @name VMX_VMCS_CTRL_PIN_EXEC_CONTROLS - * @{ - */ -/** External interrupts cause VM exits if set; otherwise dispatched through the guest's IDT. */ -#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_EXT_INT_EXIT RT_BIT(0) -/** Non-maskable interrupts cause VM exits if set; otherwise dispatched through the guest's IDT. */ -#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_NMI_EXIT RT_BIT(3) -/** Virtual NMIs. */ -#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_VIRTUAL_NMI RT_BIT(5) -/** Activate VMX preemption timer. */ -#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER RT_BIT(6) -/* All other bits are reserved and must be set according to MSR IA32_VMX_PROCBASED_CTLS. */ -/** @} */ - -/** @name VMX_VMCS_CTRL_PROC_EXEC_CONTROLS - * @{ - */ -/** VM Exit as soon as RFLAGS.IF=1 and no blocking is active. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT RT_BIT(2) -/** Use timestamp counter offset. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_TSC_OFFSET RT_BIT(3) -/** VM Exit when executing the HLT instruction. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_HLT_EXIT RT_BIT(7) -/** VM Exit when executing the INVLPG instruction. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_INVLPG_EXIT RT_BIT(9) -/** VM Exit when executing the MWAIT instruction. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MWAIT_EXIT RT_BIT(10) -/** VM Exit when executing the RDPMC instruction. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDPMC_EXIT RT_BIT(11) -/** VM Exit when executing the RDTSC/RDTSCP instruction. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT RT_BIT(12) -/** VM Exit when executing the MOV to CR3 instruction. (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_LOAD_EXIT RT_BIT(15) -/** VM Exit when executing the MOV from CR3 instruction. (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_STORE_EXIT RT_BIT(16) -/** VM Exit on CR8 loads. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_LOAD_EXIT RT_BIT(19) -/** VM Exit on CR8 stores. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_STORE_EXIT RT_BIT(20) -/** Use TPR shadow. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW RT_BIT(21) -/** VM Exit when virtual nmi blocking is disabled. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_NMI_WINDOW_EXIT RT_BIT(22) -/** VM Exit when executing a MOV DRx instruction. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT RT_BIT(23) -/** VM Exit when executing IO instructions. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_UNCOND_IO_EXIT RT_BIT(24) -/** Use IO bitmaps. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_IO_BITMAPS RT_BIT(25) -/** Monitor trap flag. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_TRAP_FLAG RT_BIT(27) -/** Use MSR bitmaps. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS RT_BIT(28) -/** VM Exit when executing the MONITOR instruction. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_EXIT RT_BIT(29) -/** VM Exit when executing the PAUSE instruction. */ -#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_PAUSE_EXIT RT_BIT(30) -/** Determines whether the secondary processor based VM-execution controls are used. */ -#define VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL RT_BIT(31) -/** @} */ - -/** @name VMX_VMCS_CTRL_PROC_EXEC_CONTROLS2 - * @{ - */ -/** Virtualize APIC access. */ -#define VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC RT_BIT(0) -/** EPT supported/enabled. */ -#define VMX_VMCS_CTRL_PROC_EXEC2_EPT RT_BIT(1) -/** Descriptor table instructions cause VM-exits. */ -#define VMX_VMCS_CTRL_PROC_EXEC2_DESCRIPTOR_INSTR_EXIT RT_BIT(2) -/** RDTSCP supported/enabled. */ -#define VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP RT_BIT(3) -/** Virtualize x2APIC mode. */ -#define VMX_VMCS_CTRL_PROC_EXEC2_X2APIC RT_BIT(4) -/** VPID supported/enabled. */ -#define VMX_VMCS_CTRL_PROC_EXEC2_VPID RT_BIT(5) -/** VM Exit when executing the WBINVD instruction. */ -#define VMX_VMCS_CTRL_PROC_EXEC2_WBINVD_EXIT RT_BIT(6) -/** Unrestricted guest execution. */ -#define VMX_VMCS_CTRL_PROC_EXEC2_REAL_MODE RT_BIT(7) -/** A specified nr of pause loops cause a VM-exit. */ -#define VMX_VMCS_CTRL_PROC_EXEC2_PAUSE_LOOP_EXIT RT_BIT(10) -/** @} */ - - -/** @name VMX_VMCS_CTRL_ENTRY_CONTROLS - * @{ - */ -/** Load guest debug controls (dr7 & IA32_DEBUGCTL_MSR) (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */ -#define VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_DEBUG RT_BIT(2) -/** 64 bits guest mode. Must be 0 for CPUs that don't support AMD64. */ -#define VMX_VMCS_CTRL_ENTRY_CONTROLS_IA64_MODE RT_BIT(9) -/** In SMM mode after VM-entry. */ -#define VMX_VMCS_CTRL_ENTRY_CONTROLS_ENTRY_SMM RT_BIT(10) -/** Disable dual treatment of SMI and SMM; must be zero for VM-entry outside of SMM. */ -#define VMX_VMCS_CTRL_ENTRY_CONTROLS_DEACTIVATE_DUALMON RT_BIT(11) -/** This control determines whether the guest IA32_PERF_GLOBAL_CTRL MSR is loaded on VM entry. */ -#define VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PERF_MSR RT_BIT(13) -/** This control determines whether the guest IA32_PAT MSR is loaded on VM entry. */ -#define VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PAT_MSR RT_BIT(14) -/** This control determines whether the guest IA32_EFER MSR is loaded on VM entry. */ -#define VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_EFER_MSR RT_BIT(15) -/** @} */ - - -/** @name VMX_VMCS_CTRL_EXIT_CONTROLS - * @{ - */ -/** Save guest debug controls (dr7 & IA32_DEBUGCTL_MSR) (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */ -#define VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_DEBUG RT_BIT(2) -/** Return to long mode after a VM-exit. */ -#define VMX_VMCS_CTRL_EXIT_CONTROLS_HOST_AMD64 RT_BIT(9) -/** This control determines whether the IA32_PERF_GLOBAL_CTRL MSR is loaded on VM exit. */ -#define VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_PERF_MSR RT_BIT(12) -/** Acknowledge external interrupts with the irq controller if one caused a VM-exit. */ -#define VMX_VMCS_CTRL_EXIT_CONTROLS_ACK_EXTERNAL_IRQ RT_BIT(15) -/** This control determines whether the guest IA32_PAT MSR is saved on VM exit. */ -#define VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_PAT_MSR RT_BIT(18) -/** This control determines whether the host IA32_PAT MSR is loaded on VM exit. */ -#define VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_PAT_MSR RT_BIT(19) -/** This control determines whether the guest IA32_EFER MSR is saved on VM exit. */ -#define VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_EFER_MSR RT_BIT(20) -/** This control determines whether the host IA32_EFER MSR is loaded on VM exit. */ -#define VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_EFER_MSR RT_BIT(21) -/** This control determines whether the value of the VMX preemption timer is saved on VM exit. */ -#define VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_VMX_PREEMPT_TIMER RT_BIT(22) -/** @} */ - -/** @name VMCS field encoding - 32 Bits read-only fields - * @{ - */ -#define VMX_VMCS32_RO_VM_INSTR_ERROR 0x4400 -#define VMX_VMCS32_RO_EXIT_REASON 0x4402 -#define VMX_VMCS32_RO_EXIT_INTERRUPTION_INFO 0x4404 -#define VMX_VMCS32_RO_EXIT_INTERRUPTION_ERRCODE 0x4406 -#define VMX_VMCS32_RO_IDT_INFO 0x4408 -#define VMX_VMCS32_RO_IDT_ERRCODE 0x440A -#define VMX_VMCS32_RO_EXIT_INSTR_LENGTH 0x440C -#define VMX_VMCS32_RO_EXIT_INSTR_INFO 0x440E -/** @} */ - -/** @name VMX_VMCS_RO_EXIT_INTERRUPTION_INFO - * @{ - */ -#define VMX_EXIT_INTERRUPTION_INFO_VECTOR(a) (a & 0xff) -#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT 8 -#define VMX_EXIT_INTERRUPTION_INFO_TYPE(a) ((a >> VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT) & 7) -#define VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID RT_BIT(11) -#define VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_IS_VALID(a) (a & VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID) -#define VMX_EXIT_INTERRUPTION_INFO_NMI_UNBLOCK(a) (a & RT_BIT(12)) -#define VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT 31 -#define VMX_EXIT_INTERRUPTION_INFO_VALID(a) (a & RT_BIT(31)) -/** Construct an irq event injection value from the exit interruption info value (same except that bit 12 is reserved). */ -#define VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(a) (a & ~RT_BIT(12)) -/** @} */ - -/** @name VMX_VMCS_RO_EXIT_INTERRUPTION_INFO_TYPE - * @{ - */ -#define VMX_EXIT_INTERRUPTION_INFO_TYPE_EXT 0 -#define VMX_EXIT_INTERRUPTION_INFO_TYPE_NMI 2 -#define VMX_EXIT_INTERRUPTION_INFO_TYPE_HWEXCPT 3 -#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SW 4 /**< int xx */ -#define VMX_EXIT_INTERRUPTION_INFO_TYPE_DBEXCPT 5 /**< Why are we getting this one?? */ -#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SWEXCPT 6 -/** @} */ - - -/** @name VMCS field encoding - 32 Bits guest state fields - * @{ - */ -#define VMX_VMCS32_GUEST_ES_LIMIT 0x4800 -#define VMX_VMCS32_GUEST_CS_LIMIT 0x4802 -#define VMX_VMCS32_GUEST_SS_LIMIT 0x4804 -#define VMX_VMCS32_GUEST_DS_LIMIT 0x4806 -#define VMX_VMCS32_GUEST_FS_LIMIT 0x4808 -#define VMX_VMCS32_GUEST_GS_LIMIT 0x480A -#define VMX_VMCS32_GUEST_LDTR_LIMIT 0x480C -#define VMX_VMCS32_GUEST_TR_LIMIT 0x480E -#define VMX_VMCS32_GUEST_GDTR_LIMIT 0x4810 -#define VMX_VMCS32_GUEST_IDTR_LIMIT 0x4812 -#define VMX_VMCS32_GUEST_ES_ACCESS_RIGHTS 0x4814 -#define VMX_VMCS32_GUEST_CS_ACCESS_RIGHTS 0x4816 -#define VMX_VMCS32_GUEST_SS_ACCESS_RIGHTS 0x4818 -#define VMX_VMCS32_GUEST_DS_ACCESS_RIGHTS 0x481A -#define VMX_VMCS32_GUEST_FS_ACCESS_RIGHTS 0x481C -#define VMX_VMCS32_GUEST_GS_ACCESS_RIGHTS 0x481E -#define VMX_VMCS32_GUEST_LDTR_ACCESS_RIGHTS 0x4820 -#define VMX_VMCS32_GUEST_TR_ACCESS_RIGHTS 0x4822 -#define VMX_VMCS32_GUEST_INTERRUPTIBILITY_STATE 0x4824 -#define VMX_VMCS32_GUEST_ACTIVITY_STATE 0x4826 -#define VMX_VMCS32_GUEST_SYSENTER_CS 0x482A /**< MSR IA32_SYSENTER_CS */ -#define VMX_VMCS32_GUEST_PREEMPTION_TIMER_VALUE 0x482E -/** @} */ - - -/** @name VMX_VMCS_GUEST_ACTIVITY_STATE - * @{ - */ -/** The logical processor is active. */ -#define VMX_CMS_GUEST_ACTIVITY_ACTIVE 0x0 -/** The logical processor is inactive, because executed a HLT instruction. */ -#define VMX_CMS_GUEST_ACTIVITY_HLT 0x1 -/** The logical processor is inactive, because of a triple fault or other serious error. */ -#define VMX_CMS_GUEST_ACTIVITY_SHUTDOWN 0x2 -/** The logical processor is inactive, because it's waiting for a startup-IPI */ -#define VMX_CMS_GUEST_ACTIVITY_SIPI_WAIT 0x3 -/** @} */ - - -/** @name VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE - * @{ - */ -#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_STI RT_BIT(0) -#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_MOVSS RT_BIT(1) -#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_SMI RT_BIT(2) -#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_NMI RT_BIT(3) -/** @} */ - - -/** @name VMCS field encoding - 32 Bits host state fields - * @{ - */ -#define VMX_VMCS32_HOST_SYSENTER_CS 0x4C00 -/** @} */ - -/** @name Natural width control fields - * @{ - */ -#define VMX_VMCS_CTRL_CR0_MASK 0x6000 -#define VMX_VMCS_CTRL_CR4_MASK 0x6002 -#define VMX_VMCS_CTRL_CR0_READ_SHADOW 0x6004 -#define VMX_VMCS_CTRL_CR4_READ_SHADOW 0x6006 -#define VMX_VMCS_CTRL_CR3_TARGET_VAL0 0x6008 -#define VMX_VMCS_CTRL_CR3_TARGET_VAL1 0x600A -#define VMX_VMCS_CTRL_CR3_TARGET_VAL2 0x600C -#define VMX_VMCS_CTRL_CR3_TARGET_VAL31 0x600E -/** @} */ - - -/** @name Natural width read-only data fields - * @{ - */ -#define VMX_VMCS_RO_EXIT_QUALIFICATION 0x6400 -#define VMX_VMCS_RO_IO_RCX 0x6402 -#define VMX_VMCS_RO_IO_RSX 0x6404 -#define VMX_VMCS_RO_IO_RDI 0x6406 -#define VMX_VMCS_RO_IO_RIP 0x6408 -#define VMX_VMCS_EXIT_GUEST_LINEAR_ADDR 0x640A -/** @} */ - - -/** @name VMX_VMCS_RO_EXIT_QUALIFICATION - * @{ - */ -/** 0-2: Debug register number */ -#define VMX_EXIT_QUALIFICATION_DRX_REGISTER(a) (a & 7) -/** 3: Reserved; cleared to 0. */ -#define VMX_EXIT_QUALIFICATION_DRX_RES1(a) ((a >> 3) & 1) -/** 4: Direction of move (0 = write, 1 = read) */ -#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION(a) ((a >> 4) & 1) -/** 5-7: Reserved; cleared to 0. */ -#define VMX_EXIT_QUALIFICATION_DRX_RES2(a) ((a >> 5) & 7) -/** 8-11: General purpose register number. */ -#define VMX_EXIT_QUALIFICATION_DRX_GENREG(a) ((a >> 8) & 0xF) -/** Rest: reserved. */ -/** @} */ - -/** @name VMX_EXIT_QUALIFICATION_DRX_DIRECTION values - * @{ - */ -#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION_WRITE 0 -#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION_READ 1 -/** @} */ - - - -/** @name CRx accesses - * @{ - */ -/** 0-3: Control register number (0 for CLTS & LMSW) */ -#define VMX_EXIT_QUALIFICATION_CRX_REGISTER(a) (a & 0xF) -/** 4-5: Access type. */ -#define VMX_EXIT_QUALIFICATION_CRX_ACCESS(a) ((a >> 4) & 3) -/** 6: LMSW operand type */ -#define VMX_EXIT_QUALIFICATION_CRX_LMSW_OP(a) ((a >> 6) & 1) -/** 7: Reserved; cleared to 0. */ -#define VMX_EXIT_QUALIFICATION_CRX_RES1(a) ((a >> 7) & 1) -/** 8-11: General purpose register number (0 for CLTS & LMSW). */ -#define VMX_EXIT_QUALIFICATION_CRX_GENREG(a) ((a >> 8) & 0xF) -/** 12-15: Reserved; cleared to 0. */ -#define VMX_EXIT_QUALIFICATION_CRX_RES2(a) ((a >> 12) & 0xF) -/** 16-31: LMSW source data (else 0). */ -#define VMX_EXIT_QUALIFICATION_CRX_LMSW_DATA(a) ((a >> 16) & 0xFFFF) -/** Rest: reserved. */ -/** @} */ - -/** @name VMX_EXIT_QUALIFICATION_CRX_ACCESS - * @{ - */ -#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_WRITE 0 -#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_READ 1 -#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_CLTS 2 -#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_LMSW 3 -/** @} */ - -/** @name VMX_EXIT_QUALIFICATION_TASK_SWITCH - * @{ - */ -#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_SELECTOR(a) (a & 0xffff) -#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE(a) ((a >> 30)& 0x3) -/** Task switch caused by a call instruction. */ -#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_CALL 0 -/** Task switch caused by an iret instruction. */ -#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_IRET 1 -/** Task switch caused by a jmp instruction. */ -#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_JMP 2 -/** Task switch caused by an interrupt gate. */ -#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_IDT 3 - -/** @} */ - - -/** @name VMX_EXIT_EPT_VIOLATION - * @{ - */ -/** Set if the violation was caused by a data read. */ -#define VMX_EXIT_QUALIFICATION_EPT_DATA_READ RT_BIT(0) -/** Set if the violation was caused by a data write. */ -#define VMX_EXIT_QUALIFICATION_EPT_DATA_WRITE RT_BIT(1) -/** Set if the violation was caused by an insruction fetch. */ -#define VMX_EXIT_QUALIFICATION_EPT_INSTR_FETCH RT_BIT(2) -/** AND of the present bit of all EPT structures. */ -#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_PRESENT RT_BIT(3) -/** AND of the write bit of all EPT structures. */ -#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_WRITE RT_BIT(4) -/** AND of the execute bit of all EPT structures. */ -#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_EXECUTE RT_BIT(5) -/** Set if the guest linear address field contains the faulting address. */ -#define VMX_EXIT_QUALIFICATION_EPT_GUEST_ADDR_VALID RT_BIT(7) -/** If bit 7 is one: (reserved otherwise) - * 1 - violation due to physical address access. - * 0 - violation caused by page walk or access/dirty bit updates - */ -#define VMX_EXIT_QUALIFICATION_EPT_TRANSLATED_ACCESS RT_BIT(8) -/** @} */ - - -/** @name VMX_EXIT_PORT_IO - * @{ - */ -/** 0-2: IO operation width. */ -#define VMX_EXIT_QUALIFICATION_IO_WIDTH(a) (a & 7) -/** 3: IO operation direction. */ -#define VMX_EXIT_QUALIFICATION_IO_DIRECTION(a) ((a >> 3) & 1) -/** 4: String IO operation. */ -#define VMX_EXIT_QUALIFICATION_IO_STRING(a) ((a >> 4) & 1) -/** 5: Repeated IO operation. */ -#define VMX_EXIT_QUALIFICATION_IO_REP(a) ((a >> 5) & 1) -/** 6: Operand encoding. */ -#define VMX_EXIT_QUALIFICATION_IO_ENCODING(a) ((a >> 6) & 1) -/** 16-31: IO Port (0-0xffff). */ -#define VMX_EXIT_QUALIFICATION_IO_PORT(a) ((a >> 16) & 0xffff) -/* Rest reserved. */ -/** @} */ - -/** @name VMX_EXIT_QUALIFICATION_IO_DIRECTION - * @{ - */ -#define VMX_EXIT_QUALIFICATION_IO_DIRECTION_OUT 0 -#define VMX_EXIT_QUALIFICATION_IO_DIRECTION_IN 1 -/** @} */ - - -/** @name VMX_EXIT_QUALIFICATION_IO_ENCODING - * @{ - */ -#define VMX_EXIT_QUALIFICATION_IO_ENCODING_DX 0 -#define VMX_EXIT_QUALIFICATION_IO_ENCODING_IMM 1 -/** @} */ - -/** @name VMX_EXIT_APIC_ACCESS - * @{ - */ -/** 0-11: If the APIC-access VM exit is due to a linear access, the offset of access within the APIC page. */ -#define VMX_EXIT_QUALIFICATION_APIC_ACCESS_OFFSET(a) (a & 0xfff) -/** 12-15: Access type. */ -#define VMX_EXIT_QUALIFICATION_APIC_ACCESS_TYPE(a) ((a >> 12) & 0xf) -/* Rest reserved. */ -/** @} */ - - -/** @name VMX_EXIT_QUALIFICATION_APIC_ACCESS_TYPE; access types - * @{ - */ -/** Linear read access. */ -#define VMX_APIC_ACCESS_TYPE_LINEAR_READ 0 -/** Linear write access. */ -#define VMX_APIC_ACCESS_TYPE_LINEAR_WRITE 1 -/** Linear instruction fetch access. */ -#define VMX_APIC_ACCESS_TYPE_LINEAR_INSTR_FETCH 2 -/** Linear read/write access during event delivery. */ -#define VMX_APIC_ACCESS_TYPE_LINEAR_EVENT_DELIVERY 3 -/** Physical read/write access during event delivery. */ -#define VMX_APIC_ACCESS_TYPE_PHYSICAL_EVENT_DELIVERY 10 -/** Physical access for an instruction fetch or during instruction execution. */ -#define VMX_APIC_ACCESS_TYPE_PHYSICAL_INSTR 15 -/** @} */ - -/** @} */ - -/** @name VMCS field encoding - Natural width guest state fields - * @{ - */ -#define VMX_VMCS64_GUEST_CR0 0x6800 -#define VMX_VMCS64_GUEST_CR3 0x6802 -#define VMX_VMCS64_GUEST_CR4 0x6804 -#define VMX_VMCS64_GUEST_ES_BASE 0x6806 -#define VMX_VMCS64_GUEST_CS_BASE 0x6808 -#define VMX_VMCS64_GUEST_SS_BASE 0x680A -#define VMX_VMCS64_GUEST_DS_BASE 0x680C -#define VMX_VMCS64_GUEST_FS_BASE 0x680E -#define VMX_VMCS64_GUEST_GS_BASE 0x6810 -#define VMX_VMCS64_GUEST_LDTR_BASE 0x6812 -#define VMX_VMCS64_GUEST_TR_BASE 0x6814 -#define VMX_VMCS64_GUEST_GDTR_BASE 0x6816 -#define VMX_VMCS64_GUEST_IDTR_BASE 0x6818 -#define VMX_VMCS64_GUEST_DR7 0x681A -#define VMX_VMCS64_GUEST_RSP 0x681C -#define VMX_VMCS64_GUEST_RIP 0x681E -#define VMX_VMCS_GUEST_RFLAGS 0x6820 -#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS 0x6822 -#define VMX_VMCS64_GUEST_SYSENTER_ESP 0x6824 /**< MSR IA32_SYSENTER_ESP */ -#define VMX_VMCS64_GUEST_SYSENTER_EIP 0x6826 /**< MSR IA32_SYSENTER_EIP */ -/** @} */ - - -/** @name VMX_VMCS_GUEST_DEBUG_EXCEPTIONS - * @{ - */ -/** Hardware breakpoint 0 was met. */ -#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B0 RT_BIT(0) -/** Hardware breakpoint 1 was met. */ -#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B1 RT_BIT(1) -/** Hardware breakpoint 2 was met. */ -#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B2 RT_BIT(2) -/** Hardware breakpoint 3 was met. */ -#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B3 RT_BIT(3) -/** At least one data or IO breakpoint was hit. */ -#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BREAKPOINT_ENABLED RT_BIT(12) -/** A debug exception would have been triggered by single-step execution mode. */ -#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BS RT_BIT(14) -/** Bits 4-11, 13 and 15-63 are reserved. */ - -/** @} */ - -/** @name VMCS field encoding - Natural width host state fields - * @{ - */ -#define VMX_VMCS_HOST_CR0 0x6C00 -#define VMX_VMCS_HOST_CR3 0x6C02 -#define VMX_VMCS_HOST_CR4 0x6C04 -#define VMX_VMCS_HOST_FS_BASE 0x6C06 -#define VMX_VMCS_HOST_GS_BASE 0x6C08 -#define VMX_VMCS_HOST_TR_BASE 0x6C0A -#define VMX_VMCS_HOST_GDTR_BASE 0x6C0C -#define VMX_VMCS_HOST_IDTR_BASE 0x6C0E -#define VMX_VMCS_HOST_SYSENTER_ESP 0x6C10 -#define VMX_VMCS_HOST_SYSENTER_EIP 0x6C12 -#define VMX_VMCS_HOST_RSP 0x6C14 -#define VMX_VMCS_HOST_RIP 0x6C16 -/** @} */ - -/** @} */ - - -#if RT_INLINE_ASM_GNU_STYLE -# define __STR(x) #x -# define STR(x) __STR(x) -#endif - - -/** @defgroup grp_vmx_asm vmx assembly helpers - * @ingroup grp_vmx - * @{ - */ - -/** - * Executes VMXON - * - * @returns VBox status code - * @param pVMXOn Physical address of VMXON structure - */ -#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) -DECLASM(int) VMXEnable(RTHCPHYS pVMXOn); -#else -DECLINLINE(int) VMXEnable(RTHCPHYS pVMXOn) -{ - int rc = VINF_SUCCESS; -# if RT_INLINE_ASM_GNU_STYLE - __asm__ __volatile__ ( - "push %3 \n\t" - "push %2 \n\t" - ".byte 0xF3, 0x0F, 0xC7, 0x34, 0x24 # VMXON [esp] \n\t" - "ja 2f \n\t" - "je 1f \n\t" - "movl $"STR(VERR_VMX_INVALID_VMXON_PTR)", %0 \n\t" - "jmp 2f \n\t" - "1: \n\t" - "movl $"STR(VERR_VMX_GENERIC)", %0 \n\t" - "2: \n\t" - "add $8, %%esp \n\t" - :"=rm"(rc) - :"0"(VINF_SUCCESS), - "ir"((uint32_t)pVMXOn), /* don't allow direct memory reference here, */ - "ir"((uint32_t)(pVMXOn >> 32)) /* this would not work with -fomit-frame-pointer */ - :"memory" - ); -# else - __asm - { - push dword ptr [pVMXOn+4] - push dword ptr [pVMXOn] - _emit 0xF3 - _emit 0x0F - _emit 0xC7 - _emit 0x34 - _emit 0x24 /* VMXON [esp] */ - jnc vmxon_good - mov dword ptr [rc], VERR_VMX_INVALID_VMXON_PTR - jmp the_end - -vmxon_good: - jnz the_end - mov dword ptr [rc], VERR_VMX_GENERIC -the_end: - add esp, 8 - } -# endif - return rc; -} -#endif - - -/** - * Executes VMXOFF - */ -#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) -DECLASM(void) VMXDisable(void); -#else -DECLINLINE(void) VMXDisable(void) -{ -# if RT_INLINE_ASM_GNU_STYLE - __asm__ __volatile__ ( - ".byte 0x0F, 0x01, 0xC4 # VMXOFF \n\t" - ); -# else - __asm - { - _emit 0x0F - _emit 0x01 - _emit 0xC4 /* VMXOFF */ - } -# endif -} -#endif - - -/** - * Executes VMCLEAR - * - * @returns VBox status code - * @param pVMCS Physical address of VM control structure - */ -#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) -DECLASM(int) VMXClearVMCS(RTHCPHYS pVMCS); -#else -DECLINLINE(int) VMXClearVMCS(RTHCPHYS pVMCS) -{ - int rc = VINF_SUCCESS; -# if RT_INLINE_ASM_GNU_STYLE - __asm__ __volatile__ ( - "push %3 \n\t" - "push %2 \n\t" - ".byte 0x66, 0x0F, 0xC7, 0x34, 0x24 # VMCLEAR [esp] \n\t" - "jnc 1f \n\t" - "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t" - "1: \n\t" - "add $8, %%esp \n\t" - :"=rm"(rc) - :"0"(VINF_SUCCESS), - "ir"((uint32_t)pVMCS), /* don't allow direct memory reference here, */ - "ir"((uint32_t)(pVMCS >> 32)) /* this would not work with -fomit-frame-pointer */ - :"memory" - ); -# else - __asm - { - push dword ptr [pVMCS+4] - push dword ptr [pVMCS] - _emit 0x66 - _emit 0x0F - _emit 0xC7 - _emit 0x34 - _emit 0x24 /* VMCLEAR [esp] */ - jnc success - mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR -success: - add esp, 8 - } -# endif - return rc; -} -#endif - - -/** - * Executes VMPTRLD - * - * @returns VBox status code - * @param pVMCS Physical address of VMCS structure - */ -#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) -DECLASM(int) VMXActivateVMCS(RTHCPHYS pVMCS); -#else -DECLINLINE(int) VMXActivateVMCS(RTHCPHYS pVMCS) -{ - int rc = VINF_SUCCESS; -# if RT_INLINE_ASM_GNU_STYLE - __asm__ __volatile__ ( - "push %3 \n\t" - "push %2 \n\t" - ".byte 0x0F, 0xC7, 0x34, 0x24 # VMPTRLD [esp] \n\t" - "jnc 1f \n\t" - "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t" - "1: \n\t" - "add $8, %%esp \n\t" - :"=rm"(rc) - :"0"(VINF_SUCCESS), - "ir"((uint32_t)pVMCS), /* don't allow direct memory reference here, */ - "ir"((uint32_t)(pVMCS >> 32)) /* this will not work with -fomit-frame-pointer */ - ); -# else - __asm - { - push dword ptr [pVMCS+4] - push dword ptr [pVMCS] - _emit 0x0F - _emit 0xC7 - _emit 0x34 - _emit 0x24 /* VMPTRLD [esp] */ - jnc success - mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR - -success: - add esp, 8 - } -# endif - return rc; -} -#endif - -/** - * Executes VMPTRST - * - * @returns VBox status code - * @param pVMCS Address that will receive the current pointer - */ -DECLASM(int) VMXGetActivateVMCS(RTHCPHYS *pVMCS); - -/** - * Executes VMWRITE - * - * @returns VBox status code - * @param idxField VMCS index - * @param u32Val 32 bits value - */ -#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) -DECLASM(int) VMXWriteVMCS32(uint32_t idxField, uint32_t u32Val); -#else -DECLINLINE(int) VMXWriteVMCS32(uint32_t idxField, uint32_t u32Val) -{ - int rc = VINF_SUCCESS; -# if RT_INLINE_ASM_GNU_STYLE - __asm__ __volatile__ ( - ".byte 0x0F, 0x79, 0xC2 # VMWRITE eax, edx \n\t" - "ja 2f \n\t" - "je 1f \n\t" - "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t" - "jmp 2f \n\t" - "1: \n\t" - "movl $"STR(VERR_VMX_INVALID_VMCS_FIELD)", %0 \n\t" - "2: \n\t" - :"=rm"(rc) - :"0"(VINF_SUCCESS), - "a"(idxField), - "d"(u32Val) - ); -# else - __asm - { - push dword ptr [u32Val] - mov eax, [idxField] - _emit 0x0F - _emit 0x79 - _emit 0x04 - _emit 0x24 /* VMWRITE eax, [esp] */ - jnc valid_vmcs - mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR - jmp the_end - -valid_vmcs: - jnz the_end - mov dword ptr [rc], VERR_VMX_INVALID_VMCS_FIELD -the_end: - add esp, 4 - } -# endif - return rc; -} -#endif - -/** - * Executes VMWRITE - * - * @returns VBox status code - * @param idxField VMCS index - * @param u64Val 16, 32 or 64 bits value - */ -#if HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) -DECLASM(int) VMXWriteVMCS64(uint32_t idxField, uint64_t u64Val); -#else -VMMR0DECL(int) VMXWriteVMCS64Ex(PVMCPU pVCpu, uint32_t idxField, uint64_t u64Val); - -#define VMXWriteVMCS64(idxField, u64Val) VMXWriteVMCS64Ex(pVCpu, idxField, u64Val) -#endif - -#if HC_ARCH_BITS == 64 -#define VMXWriteVMCS VMXWriteVMCS64 -#else -#define VMXWriteVMCS VMXWriteVMCS32 -#endif /* HC_ARCH_BITS == 64 */ - - -/** - * Invalidate a page using invept - * @returns VBox status code - * @param enmFlush Type of flush - * @param pDescriptor Descriptor - */ -DECLASM(int) VMXR0InvEPT(VMX_FLUSH_EPT enmFlush, uint64_t *pDescriptor); - -/** - * Invalidate a page using invvpid - * @returns VBox status code - * @param enmFlush Type of flush - * @param pDescriptor Descriptor - */ -DECLASM(int) VMXR0InvVPID(VMX_FLUSH_VPID enmFlush, uint64_t *pDescriptor); - -/** - * Executes VMREAD - * - * @returns VBox status code - * @param idxField VMCS index - * @param pData Ptr to store VM field value - */ -#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) -DECLASM(int) VMXReadVMCS32(uint32_t idxField, uint32_t *pData); -#else -DECLINLINE(int) VMXReadVMCS32(uint32_t idxField, uint32_t *pData) -{ - int rc = VINF_SUCCESS; -# if RT_INLINE_ASM_GNU_STYLE - __asm__ __volatile__ ( - "movl $"STR(VINF_SUCCESS)", %0 \n\t" - ".byte 0x0F, 0x78, 0xc2 # VMREAD eax, edx \n\t" - "ja 2f \n\t" - "je 1f \n\t" - "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t" - "jmp 2f \n\t" - "1: \n\t" - "movl $"STR(VERR_VMX_INVALID_VMCS_FIELD)", %0 \n\t" - "2: \n\t" - :"=&r"(rc), - "=d"(*pData) - :"a"(idxField), - "d"(0) - ); -# else - __asm - { - sub esp, 4 - mov dword ptr [esp], 0 - mov eax, [idxField] - _emit 0x0F - _emit 0x78 - _emit 0x04 - _emit 0x24 /* VMREAD eax, [esp] */ - mov edx, pData - pop dword ptr [edx] - jnc valid_vmcs - mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR - jmp the_end - -valid_vmcs: - jnz the_end - mov dword ptr [rc], VERR_VMX_INVALID_VMCS_FIELD -the_end: - } -# endif - return rc; -} -#endif - -/** - * Executes VMREAD - * - * @returns VBox status code - * @param idxField VMCS index - * @param pData Ptr to store VM field value - */ -#if HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) -DECLASM(int) VMXReadVMCS64(uint32_t idxField, uint64_t *pData); -#else -DECLINLINE(int) VMXReadVMCS64(uint32_t idxField, uint64_t *pData) -{ - int rc; - - uint32_t val_hi, val; - rc = VMXReadVMCS32(idxField, &val); - rc |= VMXReadVMCS32(idxField + 1, &val_hi); - AssertRC(rc); - *pData = RT_MAKE_U64(val, val_hi); - return rc; -} -#endif - -#if HC_ARCH_BITS == 64 -# define VMXReadVMCS VMXReadVMCS64 -#else -# define VMXReadVMCS VMXReadVMCS32 -#endif /* HC_ARCH_BITS == 64 */ - -/** - * Gets the last instruction error value from the current VMCS - * - * @returns error value - */ -DECLINLINE(uint32_t) VMXGetLastError(void) -{ -#if HC_ARCH_BITS == 64 - uint64_t uLastError = 0; - int rc = VMXReadVMCS(VMX_VMCS32_RO_VM_INSTR_ERROR, &uLastError); - AssertRC(rc); - return (uint32_t)uLastError; - -#else /* 32-bit host: */ - uint32_t uLastError = 0; - int rc = VMXReadVMCS32(VMX_VMCS32_RO_VM_INSTR_ERROR, &uLastError); - AssertRC(rc); - return uLastError; -#endif -} - -#ifdef IN_RING0 -VMMR0DECL(int) VMXR0InvalidatePage(PVM pVM, PVMCPU pVCpu, RTGCPTR GCVirt); -VMMR0DECL(int) VMXR0InvalidatePhysPage(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys); -#endif /* IN_RING0 */ - -/** @} */ - -#endif - diff --git a/include/VBox/vmm/hwaccm.h b/include/VBox/vmm/hwaccm.h deleted file mode 100644 index 98a7d02e..00000000 --- a/include/VBox/vmm/hwaccm.h +++ /dev/null @@ -1,154 +0,0 @@ -/** @file - * HWACCM - Intel/AMD VM Hardware Support Manager (VMM) - */ - -/* - * Copyright (C) 2006-2010 Oracle Corporation - * - * This file is part of VirtualBox Open Source Edition (OSE), as - * available from http://www.virtualbox.org. This file is free software; - * you can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) as published by the Free Software - * Foundation, in version 2 as it comes in the "COPYING" file of the - * VirtualBox OSE distribution. VirtualBox OSE is distributed in the - * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. - * - * The contents of this file may alternatively be used under the terms - * of the Common Development and Distribution License Version 1.0 - * (CDDL) only, as it comes in the "COPYING.CDDL" file of the - * VirtualBox OSE distribution, in which case the provisions of the - * CDDL are applicable instead of those of the GPL. - * - * You may elect to license modified versions of this file under the - * terms and conditions of either the GPL or the CDDL or both. - */ - -#ifndef ___VBox_vmm_hwaccm_h -#define ___VBox_vmm_hwaccm_h - -#include <VBox/vmm/pgm.h> -#include <VBox/vmm/cpum.h> -#include <iprt/mp.h> - - -/** @defgroup grp_hwaccm The VM Hardware Manager API - * @{ - */ - -RT_C_DECLS_BEGIN - -/** - * Query HWACCM state (enabled/disabled) - * - * @returns 0 - disabled, 1 - enabled - * @param pVM The VM to operate on. - */ -#define HWACCMIsEnabled(pVM) ((pVM)->fHWACCMEnabled) - - /** - * Check if the current CPU state is valid for emulating IO blocks in the recompiler - * - * @returns boolean - * @param pCtx CPU context - */ -#define HWACCMCanEmulateIoBlock(pVCpu) (!CPUMIsGuestInPagedProtectedMode(pVCpu)) -#define HWACCMCanEmulateIoBlockEx(pCtx) (!CPUMIsGuestInPagedProtectedModeEx(pCtx)) - -VMMDECL(int) HWACCMInvalidatePage(PVMCPU pVCpu, RTGCPTR GCVirt); -VMMDECL(bool) HWACCMHasPendingIrq(PVM pVM); - -#ifndef IN_RC -VMMDECL(int) HWACCMFlushTLB(PVMCPU pVCpu); -VMMDECL(int) HWACCMFlushTLBOnAllVCpus(PVM pVM); -VMMDECL(int) HWACCMInvalidatePageOnAllVCpus(PVM pVM, RTGCPTR GCVirt); -VMMDECL(int) HWACCMInvalidatePhysPage(PVM pVM, RTGCPHYS GCPhys); -VMMDECL(bool) HWACCMIsNestedPagingActive(PVM pVM); -VMMDECL(PGMMODE) HWACCMGetShwPagingMode(PVM pVM); -#else -/* Nop in GC */ -# define HWACCMFlushTLB(pVCpu) do { } while (0) -# define HWACCMIsNestedPagingActive(pVM) false -# define HWACCMFlushTLBOnAllVCpus(pVM) do { } while (0) -#endif - -#ifdef IN_RING0 -/** @defgroup grp_hwaccm_r0 The VM Hardware Manager API - * @ingroup grp_hwaccm - * @{ - */ -VMMR0DECL(int) HWACCMR0Init(void); -VMMR0DECL(int) HWACCMR0Term(void); -VMMR0DECL(int) HWACCMR0InitVM(PVM pVM); -VMMR0DECL(int) HWACCMR0TermVM(PVM pVM); -VMMR0DECL(int) HWACCMR0EnableAllCpus(PVM pVM); -VMMR0DECL(int) HWACCMR0EnterSwitcher(PVM pVM, bool *pfVTxDisabled); -VMMR0DECL(int) HWACCMR0LeaveSwitcher(PVM pVM, bool fVTxDisabled); - -VMMR0DECL(void) HWACCMR0SavePendingIOPortWrite(PVMCPU pVCpu, RTGCPTR GCPtrRip, RTGCPTR GCPtrRipNext, unsigned uPort, unsigned uAndVal, unsigned cbSize); -VMMR0DECL(void) HWACCMR0SavePendingIOPortRead(PVMCPU pVCpu, RTGCPTR GCPtrRip, RTGCPTR GCPtrRipNext, unsigned uPort, unsigned uAndVal, unsigned cbSize); - -/** @} */ -#endif /* IN_RING0 */ - - -#ifdef IN_RING3 -/** @defgroup grp_hwaccm_r3 The VM Hardware Manager API - * @ingroup grp_hwaccm - * @{ - */ -VMMR3DECL(bool) HWACCMR3IsEventPending(PVMCPU pVCpu); -VMMR3DECL(int) HWACCMR3Init(PVM pVM); -VMMR3_INT_DECL(int) HWACCMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat); -VMMR3DECL(void) HWACCMR3Relocate(PVM pVM); -VMMR3DECL(int) HWACCMR3Term(PVM pVM); -VMMR3DECL(void) HWACCMR3Reset(PVM pVM); -VMMR3DECL(void) HWACCMR3ResetCpu(PVMCPU pVCpu); -VMMR3DECL(void) HWACCMR3CheckError(PVM pVM, int iStatusCode); -VMMR3DECL(bool) HWACCMR3CanExecuteGuest(PVM pVM, PCPUMCTX pCtx); -VMMR3DECL(void) HWACCMR3NotifyScheduled(PVMCPU pVCpu); -VMMR3DECL(void) HWACCMR3NotifyEmulated(PVMCPU pVCpu); -VMMR3DECL(bool) HWACCMR3IsActive(PVMCPU pVCpu); -VMMR3DECL(bool) HWACCMR3IsNestedPagingActive(PVM pVM); -VMMR3DECL(bool) HWACCMR3IsAllowed(PVM pVM); -VMMR3DECL(void) HWACCMR3PagingModeChanged(PVM pVM, PVMCPU pVCpu, PGMMODE enmShadowMode, PGMMODE enmGuestMode); -VMMR3DECL(bool) HWACCMR3IsVPIDActive(PVM pVM); -VMMR3DECL(int) HWACCMR3InjectNMI(PVM pVM); -VMMR3DECL(int) HWACCMR3EmulateIoBlock(PVM pVM, PCPUMCTX pCtx); -VMMR3DECL(VBOXSTRICTRC) HWACCMR3RestartPendingIOInstr(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); -VMMR3DECL(int) HWACMMR3EnablePatching(PVM pVM, RTGCPTR pPatchMem, unsigned cbPatchMem); -VMMR3DECL(int) HWACMMR3DisablePatching(PVM pVM, RTGCPTR pPatchMem, unsigned cbPatchMem); -VMMR3DECL(int) HWACCMR3PatchTprInstr(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); -VMMR3DECL(bool) HWACCMR3IsRescheduleRequired(PVM pVM, PCPUMCTX pCtx); -VMMR3DECL(bool) HWACCMR3IsVmxPreemptionTimerUsed(PVM pVM); - -/** @} */ -#endif /* IN_RING3 */ - -#ifdef IN_RING0 -/** @addtogroup grp_hwaccm_r0 - * @{ - */ -VMMR0DECL(int) HWACCMR0SetupVM(PVM pVM); -VMMR0DECL(int) HWACCMR0RunGuestCode(PVM pVM, PVMCPU pVCpu); -VMMR0DECL(int) HWACCMR0Enter(PVM pVM, PVMCPU pVCpu); -VMMR0DECL(int) HWACCMR0Leave(PVM pVM, PVMCPU pVCpu); -VMMR0DECL(int) HWACCMR0InvalidatePage(PVM pVM, PVMCPU pVCpu); -VMMR0DECL(int) HWACCMR0FlushTLB(PVM pVM); -VMMR0DECL(bool) HWACCMR0SuspendPending(void); - -# if HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS) -VMMR0DECL(int) HWACCMR0SaveFPUState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); -VMMR0DECL(int) HWACCMR0SaveDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); -VMMR0DECL(int) HWACCMR0TestSwitcher3264(PVM pVM); -# endif - -/** @} */ -#endif /* IN_RING0 */ - - -/** @} */ -RT_C_DECLS_END - - -#endif - diff --git a/include/VBox/vmm/iem.h b/include/VBox/vmm/iem.h index 617a05a6..32168660 100644 --- a/include/VBox/vmm/iem.h +++ b/include/VBox/vmm/iem.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -28,6 +28,7 @@ #include <VBox/types.h> #include <VBox/vmm/trpm.h> +#include <iprt/assert.h> RT_C_DECLS_BEGIN @@ -37,6 +38,17 @@ RT_C_DECLS_BEGIN */ +/** + * Operand or addressing mode. + */ +typedef enum IEMMODE +{ + IEMMODE_16BIT = 0, + IEMMODE_32BIT, + IEMMODE_64BIT +} IEMMODE; +AssertCompileSize(IEMMODE, 4); + VMMDECL(VBOXSTRICTRC) IEMExecOne(PVMCPU pVCpu); VMMDECL(VBOXSTRICTRC) IEMExecOneEx(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint32_t *pcbWritten); @@ -53,7 +65,10 @@ VMM_INT_DECL(int) IEMBreakpointClear(PVM pVM, RTGCPTR GCPtrBp); /** @name Given Instruction Interpreters * @{ */ - +VMM_INT_DECL(VBOXSTRICTRC) IEMExecStringIoWrite(PVMCPU pVCpu, uint8_t cbValue, IEMMODE enmAddrMode, + bool fRepPrefix, uint8_t cbInstr, uint8_t iEffSeg); +VMM_INT_DECL(VBOXSTRICTRC) IEMExecStringIoRead(PVMCPU pVCpu, uint8_t cbValue, IEMMODE enmAddrMode, + bool fRepPrefix, uint8_t cbInstr); /** @} */ #if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3) diff --git a/include/VBox/vmm/iom.h b/include/VBox/vmm/iom.h index a7e552c9..a69ac4cd 100644 --- a/include/VBox/vmm/iom.h +++ b/include/VBox/vmm/iom.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -57,13 +57,11 @@ RT_C_DECLS_BEGIN * more than once! * * @remark To avoid making assumptions about the layout of the - * VINF_EM_FIRST...VINF_EM_LAST range we're checking - * explicitly for each for exach the exceptions. - * However, for efficieny we ASSUME that the - * VINF_EM_LAST is smaller than most of the relevant - * status codes. We also ASSUME that the - * VINF_EM_RESCHEDULE_REM status code is the most - * frequent status code we'll enounter in this range. + * VINF_EM_FIRST...VINF_EM_LAST range we're checking explicitly for + * each exact exception. However, for efficiency we ASSUME that the + * VINF_EM_LAST is smaller than most of the relevant status codes. We + * also ASSUME that the VINF_EM_RESCHEDULE_REM status code is the + * most frequent status code we'll enounter in this range. * * @todo Will have to add VINF_EM_DBG_HYPER_BREAKPOINT if the * I/O port and MMIO breakpoints should trigger before @@ -75,7 +73,7 @@ RT_C_DECLS_BEGIN && (rc) != VINF_EM_RESCHEDULE_REM \ && (rc) >= VINF_EM_FIRST \ && (rc) != VINF_EM_RESCHEDULE_RAW \ - && (rc) != VINF_EM_RESCHEDULE_HWACC \ + && (rc) != VINF_EM_RESCHEDULE_HM \ ) \ ) @@ -116,6 +114,16 @@ RT_C_DECLS_BEGIN * simplifications of devices where reads doesn't change the device * state in any way. */ #define IOMMMIO_FLAGS_WRITE_DWORD_QWORD_READ_MISSING UINT32_C(0x00000040) +/** All write accesses are DWORD (32-bit) sized and aligned, attempts at other + * accesses are ignored. + * @remarks E1000, APIC */ +#define IOMMMIO_FLAGS_WRITE_ONLY_DWORD UINT32_C(0x00000050) +/** All write accesses are DWORD (32-bit) or QWORD (64-bit) sized and aligned, + * attempts at other accesses are ignored. + * @remarks Seemingly required by AHCI (although I doubt it's _really_ + * required as EM/REM doesn't do the right thing in ring-3 anyway, + * esp. not in raw-mode). */ +#define IOMMMIO_FLAGS_WRITE_ONLY_DWORD_QWORD UINT32_C(0x00000060) /** The read access mode mask. */ #define IOMMMIO_FLAGS_WRITE_MODE UINT32_C(0x00000070) @@ -132,6 +140,14 @@ RT_C_DECLS_BEGIN #define IOMMMIO_FLAGS_VALID_MASK UINT32_C(0x00000373) /** @} */ +/** + * Checks whether the write mode allows aligned QWORD accesses to be passed + * thru to the device handler. + * @param a_fFlags The MMIO handler flags. + * @remarks The current implementation makes ASSUMPTIONS about the mode values! + */ +#define IOMMMIO_DOES_WRITE_MODE_ALLOW_QWORD(a_fFlags) RT_BOOL((a_fFlags) & UINT32_C(0x00000020)) + /** * Port I/O Handler for IN operations. @@ -145,6 +161,7 @@ RT_C_DECLS_BEGIN * @param pu32 Where to store the result. This is always a 32-bit * variable regardless of what @a cb might say. * @param cb Number of bytes read. + * @remarks Caller enters the device critical section. */ typedef DECLCALLBACK(int) FNIOMIOPORTIN(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb); /** Pointer to a FNIOMIOPORTIN(). */ @@ -162,6 +179,7 @@ typedef FNIOMIOPORTIN *PFNIOMIOPORTIN; * @param pGCPtrDst Pointer to the destination buffer (GC, incremented appropriately). * @param pcTransfers Pointer to the number of transfer units to read, on return remaining transfer units. * @param cb Size of the transfer unit (1, 2 or 4 bytes). + * @remarks Caller enters the device critical section. */ typedef DECLCALLBACK(int) FNIOMIOPORTINSTRING(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst, PRTGCUINTREG pcTransfers, unsigned cb); /** Pointer to a FNIOMIOPORTINSTRING(). */ @@ -177,6 +195,7 @@ typedef FNIOMIOPORTINSTRING *PFNIOMIOPORTINSTRING; * @param uPort Port number used for the OUT operation. * @param u32 The value to output. * @param cb The value size in bytes. + * @remarks Caller enters the device critical section. */ typedef DECLCALLBACK(int) FNIOMIOPORTOUT(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb); /** Pointer to a FNIOMIOPORTOUT(). */ @@ -193,6 +212,7 @@ typedef FNIOMIOPORTOUT *PFNIOMIOPORTOUT; * @param pGCPtrSrc Pointer to the source buffer (GC, incremented appropriately). * @param pcTransfers Pointer to the number of transfer units to write, on return remaining transfer units. * @param cb Size of the transfer unit (1, 2 or 4 bytes). + * @remarks Caller enters the device critical section. */ typedef DECLCALLBACK(int) FNIOMIOPORTOUTSTRING(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc, PRTGCUINTREG pcTransfers, unsigned cb); /** Pointer to a FNIOMIOPORTOUTSTRING(). */ @@ -209,6 +229,7 @@ typedef FNIOMIOPORTOUTSTRING *PFNIOMIOPORTOUTSTRING; * @param GCPhysAddr Physical address (in GC) where the read starts. * @param pv Where to store the result. * @param cb Number of bytes read. + * @remarks Caller enters the device critical section. */ typedef DECLCALLBACK(int) FNIOMMMIOREAD(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb); /** Pointer to a FNIOMMMIOREAD(). */ @@ -224,6 +245,7 @@ typedef FNIOMMMIOREAD *PFNIOMMMIOREAD; * @param GCPhysAddr Physical address (in GC) where the read starts. * @param pv Where to fetch the result. * @param cb Number of bytes to write. + * @remarks Caller enters the device critical section. */ typedef DECLCALLBACK(int) FNIOMMMIOWRITE(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb); /** Pointer to a FNIOMMMIOWRITE(). */ @@ -240,36 +262,37 @@ typedef FNIOMMMIOWRITE *PFNIOMMMIOWRITE; * @param u32Item Byte/Word/Dword data to fill. * @param cbItem Size of data in u32Item parameter, restricted to 1/2/4 bytes. * @param cItems Number of iterations. + * @remarks Caller enters the device critical section. */ typedef DECLCALLBACK(int) FNIOMMMIOFILL(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, uint32_t u32Item, unsigned cbItem, unsigned cItems); /** Pointer to a FNIOMMMIOFILL(). */ typedef FNIOMMMIOFILL *PFNIOMMMIOFILL; -VMMDECL(VBOXSTRICTRC) IOMIOPortRead(PVM pVM, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue); -VMMDECL(VBOXSTRICTRC) IOMIOPortWrite(PVM pVM, RTIOPORT Port, uint32_t u32Value, size_t cbValue); -VMMDECL(VBOXSTRICTRC) IOMInterpretOUT(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); -VMMDECL(VBOXSTRICTRC) IOMInterpretIN(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); -VMMDECL(VBOXSTRICTRC) IOMIOPortReadString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCPtrDst, PRTGCUINTREG pcTransfers, unsigned cb); -VMMDECL(VBOXSTRICTRC) IOMIOPortWriteString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCPtrSrc, PRTGCUINTREG pcTransfers, unsigned cb); -VMMDECL(VBOXSTRICTRC) IOMInterpretINS(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); -VMMDECL(VBOXSTRICTRC) IOMInterpretINSEx(PVM pVM, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix, DISCPUMODE enmAddrMode, uint32_t cbTransfer); -VMMDECL(VBOXSTRICTRC) IOMInterpretOUTS(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); -VMMDECL(VBOXSTRICTRC) IOMInterpretOUTSEx(PVM pVM, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix, DISCPUMODE enmAddrMode, uint32_t cbTransfer); -VMMDECL(VBOXSTRICTRC) IOMMMIORead(PVM pVM, RTGCPHYS GCPhys, uint32_t *pu32Value, size_t cbValue); -VMMDECL(VBOXSTRICTRC) IOMMMIOWrite(PVM pVM, RTGCPHYS GCPhys, uint32_t u32Value, size_t cbValue); -VMMDECL(VBOXSTRICTRC) IOMMMIOPhysHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pCtxCore, RTGCPHYS GCPhysFault); +VMMDECL(VBOXSTRICTRC) IOMIOPortRead(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue); +VMMDECL(VBOXSTRICTRC) IOMIOPortWrite(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, uint32_t u32Value, size_t cbValue); +VMMDECL(VBOXSTRICTRC) IOMInterpretOUT(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); +VMMDECL(VBOXSTRICTRC) IOMInterpretIN(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); +VMMDECL(VBOXSTRICTRC) IOMIOPortReadString(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, PRTGCPTR pGCPtrDst, PRTGCUINTREG pcTransfers, unsigned cb); +VMMDECL(VBOXSTRICTRC) IOMIOPortWriteString(PVM pVM, PVMCPU pVCpu, RTIOPORT Port, PRTGCPTR pGCPtrSrc, PRTGCUINTREG pcTransfers, unsigned cb); +VMMDECL(VBOXSTRICTRC) IOMInterpretINS(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); +VMMDECL(VBOXSTRICTRC) IOMInterpretINSEx(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix, DISCPUMODE enmAddrMode, uint32_t cbTransfer); +VMMDECL(VBOXSTRICTRC) IOMInterpretOUTS(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); +VMMDECL(VBOXSTRICTRC) IOMInterpretOUTSEx(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix, DISCPUMODE enmAddrMode, uint32_t cbTransfer); +VMMDECL(VBOXSTRICTRC) IOMMMIORead(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, uint32_t *pu32Value, size_t cbValue); +VMMDECL(VBOXSTRICTRC) IOMMMIOWrite(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, uint32_t u32Value, size_t cbValue); +VMMDECL(VBOXSTRICTRC) IOMMMIOPhysHandler(PVM pVM, PVMCPU pVCpu, RTGCUINT uErrorCode, PCPUMCTXCORE pCtxCore, RTGCPHYS GCPhysFault); VMMDECL(VBOXSTRICTRC) IOMInterpretCheckPortIOAccess(PVM pVM, PCPUMCTXCORE pCtxCore, RTIOPORT Port, unsigned cb); VMMDECL(int) IOMMMIOMapMMIO2Page(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysRemapped, uint64_t fPageFlags); -VMMDECL(int) IOMMMIOMapMMIOHCPage(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint64_t fPageFlags); +VMMDECL(int) IOMMMIOMapMMIOHCPage(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint64_t fPageFlags); VMMDECL(int) IOMMMIOResetRegion(PVM pVM, RTGCPHYS GCPhys); -VMMDECL(bool) IOMIsLockOwner(PVM pVM); +VMMDECL(bool) IOMIsLockWriteOwner(PVM pVM); #ifdef IN_RC /** @defgroup grp_iom_rc The IOM Raw-Mode Context API * @ingroup grp_iom * @{ */ -VMMRCDECL(VBOXSTRICTRC) IOMRCIOPortHandler(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); +VMMRCDECL(VBOXSTRICTRC) IOMRCIOPortHandler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); /** @} */ #endif /* IN_RC */ diff --git a/include/VBox/vmm/mm.h b/include/VBox/vmm/mm.h index 66490fce..bcb55c14 100644 --- a/include/VBox/vmm/mm.h +++ b/include/VBox/vmm/mm.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -58,6 +58,8 @@ typedef enum MMTAG MM_TAG_CSAM_PATCH, MM_TAG_CPUM_CTX, + MM_TAG_CPUM_CPUID, + MM_TAG_CPUM_MSRS, MM_TAG_DBGF, MM_TAG_DBGF_AS, @@ -130,7 +132,7 @@ typedef enum MMTAG MM_TAG_VMM, - MM_TAG_HWACCM, + MM_TAG_HM, MM_TAG_32BIT_HACK = 0x7fffffff } MMTAG; @@ -205,6 +207,7 @@ DECLINLINE(RTRCPTR) MMHyperCCToRC(PVM pVM, void *pv) VMMDECL(int) MMHyperAlloc(PVM pVM, size_t cb, uint32_t uAlignment, MMTAG enmTag, void **ppv); +VMMDECL(int) MMHyperDupMem(PVM pVM, const void *pvSrc, size_t cb, unsigned uAlignment, MMTAG enmTag, void **ppv); VMMDECL(int) MMHyperFree(PVM pVM, void *pv); VMMDECL(void) MMHyperHeapCheck(PVM pVM); VMMDECL(int) MMR3LockCall(PVM pVM); diff --git a/include/VBox/vmm/patm.h b/include/VBox/vmm/patm.h index 70b7fa55..6f9adca0 100644 --- a/include/VBox/vmm/patm.h +++ b/include/VBox/vmm/patm.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -29,6 +29,7 @@ #include <VBox/types.h> #include <VBox/dis.h> +#if defined(VBOX_WITH_RAW_MODE) || defined(DOXYGEN_RUNNING) RT_C_DECLS_BEGIN @@ -41,18 +42,18 @@ RT_C_DECLS_BEGIN * Flags for specifying the type of patch to install with PATMR3InstallPatch * @{ */ -#define PATMFL_CODE32 RT_BIT_64(0) -#define PATMFL_INTHANDLER RT_BIT_64(1) -#define PATMFL_SYSENTER RT_BIT_64(2) -#define PATMFL_GUEST_SPECIFIC RT_BIT_64(3) -#define PATMFL_USER_MODE RT_BIT_64(4) -#define PATMFL_IDTHANDLER RT_BIT_64(5) -#define PATMFL_TRAPHANDLER RT_BIT_64(6) -#define PATMFL_DUPLICATE_FUNCTION RT_BIT_64(7) -#define PATMFL_REPLACE_FUNCTION_CALL RT_BIT_64(8) +#define PATMFL_CODE32 RT_BIT_64(0) +#define PATMFL_INTHANDLER RT_BIT_64(1) +#define PATMFL_SYSENTER RT_BIT_64(2) +#define PATMFL_GUEST_SPECIFIC RT_BIT_64(3) +#define PATMFL_USER_MODE RT_BIT_64(4) +#define PATMFL_IDTHANDLER RT_BIT_64(5) +#define PATMFL_TRAPHANDLER RT_BIT_64(6) +#define PATMFL_DUPLICATE_FUNCTION RT_BIT_64(7) +#define PATMFL_REPLACE_FUNCTION_CALL RT_BIT_64(8) #define PATMFL_TRAPHANDLER_WITH_ERRORCODE RT_BIT_64(9) #define PATMFL_INTHANDLER_WITH_ERRORCODE (PATMFL_TRAPHANDLER_WITH_ERRORCODE) -#define PATMFL_MMIO_ACCESS RT_BIT_64(10) +#define PATMFL_MMIO_ACCESS RT_BIT_64(10) /* no more room -> change PATMInternal.h if more is needed!! */ /* @@ -70,32 +71,32 @@ RT_C_DECLS_BEGIN typedef struct PATMGCSTATE { - /* Virtual Flags register (IF + more later on) */ + /** Virtual Flags register (IF + more later on) */ uint32_t uVMFlags; - /* Pending PATM actions (internal use only) */ + /** Pending PATM actions (internal use only) */ uint32_t uPendingAction; - /* Records the number of times all patches are called (indicating how many exceptions we managed to avoid) */ + /** Records the number of times all patches are called (indicating how many exceptions we managed to avoid) */ uint32_t uPatchCalls; - /* Scratchpad dword */ + /** Scratchpad dword */ uint32_t uScratch; - /* Debugging info */ + /** Debugging info */ uint32_t uIretEFlags, uIretCS, uIretEIP; - /* PATM stack pointer */ + /** PATM stack pointer */ uint32_t Psp; - /* PATM interrupt flag */ + /** PATM interrupt flag */ uint32_t fPIF; - /* PATM inhibit irq address (used by sti) */ + /** PATM inhibit irq address (used by sti) */ RTRCPTR GCPtrInhibitInterrupts; - /* Scratch room for call patch */ + /** Scratch room for call patch */ RTRCPTR GCCallPatchTargetAddr; RTRCPTR GCCallReturnAddr; - /* Temporary storage for guest registers. */ + /** Temporary storage for guest registers. */ struct { uint32_t uEAX; @@ -108,11 +109,11 @@ typedef struct PATMGCSTATE typedef struct PATMTRAPREC { - /* pointer to original guest code instruction (for emulation) */ + /** pointer to original guest code instruction (for emulation) */ RTRCPTR pNewEIP; - /* pointer to the next guest code instruction */ + /** pointer to the next guest code instruction */ RTRCPTR pNextInstr; - /* pointer to the corresponding next instruction in the patch block */ + /** pointer to the corresponding next instruction in the patch block */ RTRCPTR pNextPatchInstr; } PATMTRAPREC, *PPATMTRAPREC; @@ -122,198 +123,50 @@ typedef struct PATMTRAPREC */ typedef enum { - PATMTRANS_FAILED, - PATMTRANS_SAFE, /* Safe translation */ - PATMTRANS_PATCHSTART, /* Instruction starts a patch block */ - PATMTRANS_OVERWRITTEN, /* Instruction overwritten by patchjump */ - PATMTRANS_INHIBITIRQ /* Instruction must be executed due to instruction fusing */ + PATMTRANS_FAILED, + PATMTRANS_SAFE, /**< Safe translation */ + PATMTRANS_PATCHSTART, /**< Instruction starts a patch block */ + PATMTRANS_OVERWRITTEN, /**< Instruction overwritten by patchjump */ + PATMTRANS_INHIBITIRQ /**< Instruction must be executed due to instruction fusing */ } PATMTRANSSTATE; -/** - * Load virtualized flags. - * - * This function is called from CPUMRawEnter(). It doesn't have to update the - * IF and IOPL eflags bits, the caller will enforce those to set and 0 respectively. - * - * @param pVM VM handle. - * @param pCtxCore The cpu context core. - * @see pg_raw - */ -VMMDECL(void) PATMRawEnter(PVM pVM, PCPUMCTXCORE pCtxCore); - -/** - * Restores virtualized flags. - * - * This function is called from CPUMRawLeave(). It will update the eflags register. - * - * @param pVM VM handle. - * @param pCtxCore The cpu context core. - * @param rawRC Raw mode return code - * @see @ref pg_raw - */ -VMMDECL(void) PATMRawLeave(PVM pVM, PCPUMCTXCORE pCtxCore, int rawRC); - -/** - * Get the EFLAGS. - * This is a worker for CPUMRawGetEFlags(). - * - * @returns The eflags. - * @param pVM The VM handle. - * @param pCtxCore The context core. - */ -VMMDECL(uint32_t) PATMRawGetEFlags(PVM pVM, PCCPUMCTXCORE pCtxCore); - -/** - * Updates the EFLAGS. - * This is a worker for CPUMRawSetEFlags(). - * - * @param pVM The VM handle. - * @param pCtxCore The context core. - * @param efl The new EFLAGS value. - */ -VMMDECL(void) PATMRawSetEFlags(PVM pVM, PCPUMCTXCORE pCtxCore, uint32_t efl); - -/** - * Returns the guest context pointer of the GC context structure - * - * @returns VBox status code. - * @param pVM The VM to operate on. - */ -VMMDECL(RCPTRTYPE(PPATMGCSTATE)) PATMQueryGCState(PVM pVM); - -/** - * Checks whether the GC address is part of our patch region - * - * @returns true -> yes, false -> no - * @param pVM The VM to operate on. - * @param pAddr Guest context address - */ -VMMDECL(bool) PATMIsPatchGCAddr(PVM pVM, RTRCUINTPTR pAddr); - -/** - * Check if we must use raw mode (patch code being executed or marked safe for IF=0) - * - * @param pVM VM handle. - * @param pAddrGC Guest context address - */ -VMMDECL(bool) PATMShouldUseRawMode(PVM pVM, RTRCPTR pAddrGC); /** * Query PATM state (enabled/disabled) * * @returns 0 - disabled, 1 - enabled * @param pVM The VM to operate on. + * @internal */ -#define PATMIsEnabled(pVM) (pVM->fPATMEnabled) +#define PATMIsEnabled(a_pVM) ((a_pVM)->fPATMEnabled) -/** - * Set parameters for pending MMIO patch operation - * - * @returns VBox status code. - * @param pDevIns Device instance. - * @param GCPhys MMIO physical address - * @param pCachedData GC pointer to cached data - */ -VMMDECL(int) PATMSetMMIOPatchInfo(PVM pVM, RTGCPHYS GCPhys, RTRCPTR pCachedData); - - -/** - * Adds branch pair to the lookup cache of the particular branch instruction - * - * @returns VBox status - * @param pVM The VM to operate on. - * @param pJumpTableGC Pointer to branch instruction lookup cache - * @param pBranchTarget Original branch target - * @param pRelBranchPatch Relative duplicated function address - */ -VMMDECL(int) PATMAddBranchToLookupCache(PVM pVM, RTRCPTR pJumpTableGC, RTRCPTR pBranchTarget, RTRCUINTPTR pRelBranchPatch); - - -/** - * Checks if the int 3 was caused by a patched instruction - * - * @returns VBox status - * - * @param pVM The VM handle. - * @param pCtxCore The relevant core context. - */ -VMMRCDECL(int) PATMRCHandleInt3PatchTrap(PVM pVM, PCPUMCTXCORE pRegFrame); - -/** - * Checks if the int 3 was caused by a patched instruction - * - * @returns VBox status - * - * @param pVM The VM handle. - * @param pInstrGC Instruction pointer - * @param pOpcode Original instruction opcode (out, optional) - * @param pSize Original instruction size (out, optional) - */ -VMMDECL(bool) PATMIsInt3Patch(PVM pVM, RTRCPTR pInstrGC, uint32_t *pOpcode, uint32_t *pSize); - - -/** - * Checks if the interrupt flag is enabled or not. - * - * @returns true if it's enabled. - * @returns false if it's disabled. - * - * @param pVM The VM handle. - */ -VMMDECL(bool) PATMAreInterruptsEnabled(PVM pVM); +VMMDECL(bool) PATMIsPatchGCAddr(PVM pVM, RTRCUINTPTR pAddr); +VMM_INT_DECL(int) PATMReadPatchCode(PVM pVM, RTGCPTR GCPtrPatchCode, void *pvDst, size_t cbToRead, size_t *pcbRead); -/** - * Checks if the interrupt flag is enabled or not. - * - * @returns true if it's enabled. - * @returns false if it's disabled. - * - * @param pVM The VM handle. - * @param pCtxCore CPU context - */ -VMMDECL(bool) PATMAreInterruptsEnabledByCtxCore(PVM pVM, PCPUMCTXCORE pCtxCore); +VMM_INT_DECL(void) PATMRawEnter(PVM pVM, PCPUMCTXCORE pCtxCore); +VMM_INT_DECL(void) PATMRawLeave(PVM pVM, PCPUMCTXCORE pCtxCore, int rawRC); +VMM_INT_DECL(uint32_t) PATMRawGetEFlags(PVM pVM, PCCPUMCTXCORE pCtxCore); +VMM_INT_DECL(void) PATMRawSetEFlags(PVM pVM, PCPUMCTXCORE pCtxCore, uint32_t efl); +VMM_INT_DECL(RCPTRTYPE(PPATMGCSTATE)) PATMGetGCState(PVM pVM); +VMM_INT_DECL(bool) PATMShouldUseRawMode(PVM pVM, RTRCPTR pAddrGC); +VMM_INT_DECL(int) PATMSetMMIOPatchInfo(PVM pVM, RTGCPHYS GCPhys, RTRCPTR pCachedData); +VMM_INT_DECL(bool) PATMIsInt3Patch(PVM pVM, RTRCPTR pInstrGC, uint32_t *pOpcode, uint32_t *pSize); +VMM_INT_DECL(bool) PATMAreInterruptsEnabled(PVM pVM); +VMM_INT_DECL(bool) PATMAreInterruptsEnabledByCtxCore(PVM pVM, PCPUMCTXCORE pCtxCore); #ifdef PATM_EMULATE_SYSENTER -/** - * Emulate sysenter, sysexit and syscall instructions - * - * @returns VBox status - * - * @param pVM The VM handle. - * @param pCtxCore The relevant core context. - * @param pCpu Disassembly context - */ -VMMDECL(int) PATMSysCall(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); +VMM_INT_DECL(int) PATMSysCall(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu); #endif #ifdef IN_RC -/** @defgroup grp_patm_gc The Patch Manager API +/** @defgroup grp_patm_rc The Patch Manager RC API * @ingroup grp_patm * @{ */ -/** - * Checks if the write is located on a page with was patched before. - * (if so, then we are not allowed to turn on r/w) - * - * @returns VBox status - * @param pVM The VM to operate on. - * @param pRegFrame CPU context - * @param GCPtr GC pointer to write address - * @param cbWrite Nr of bytes to write - * - */ -VMMRCDECL(int) PATMGCHandleWriteToPatchPage(PVM pVM, PCPUMCTXCORE pRegFrame, RTRCPTR GCPtr, uint32_t cbWrite); - -/** - * Checks if the illegal instruction was caused by a patched instruction - * - * @returns VBox status - * - * @param pVM The VM handle. - * @param pCtxCore The relevant core context. - */ -VMMDECL(int) PATMRCHandleIllegalInstrTrap(PVM pVM, PCPUMCTXCORE pRegFrame); +VMMRC_INT_DECL(int) PATMRCHandleInt3PatchTrap(PVM pVM, PCPUMCTXCORE pRegFrame); +VMMRC_INT_DECL(int) PATMRCHandleWriteToPatchPage(PVM pVM, PCPUMCTXCORE pRegFrame, RTRCPTR GCPtr, uint32_t cbWrite); +VMMRC_INT_DECL(int) PATMRCHandleIllegalInstrTrap(PVM pVM, PCPUMCTXCORE pRegFrame); /** @} */ @@ -325,341 +178,41 @@ VMMDECL(int) PATMRCHandleIllegalInstrTrap(PVM pVM, PCPUMCTXCORE pRegFrame); * @{ */ -/** - * Query PATM state (enabled/disabled) - * - * @returns 0 - disabled, 1 - enabled - * @param pVM The VM to operate on. - */ -VMMR3DECL(int) PATMR3IsEnabled(PVM pVM); - -/** - * Initializes the PATM. - * - * @returns VBox status code. - * @param pVM The VM to operate on. - */ -VMMR3DECL(int) PATMR3Init(PVM pVM); - -/** - * Finalizes HMA page attributes. - * - * @returns VBox status code. - * @param pVM The VM handle. - */ -VMMR3DECL(int) PATMR3InitFinalize(PVM pVM); - -/** - * Applies relocations to data and code managed by this - * component. This function will be called at init and - * whenever the VMM need to relocate it self inside the GC. - * - * The PATM will update the addresses used by the switcher. - * - * @param pVM The VM. - */ -VMMR3DECL(void) PATMR3Relocate(PVM pVM); - -/** - * Terminates the PATM. - * - * Termination means cleaning up and freeing all resources, - * the VM it self is at this point powered off or suspended. - * - * @returns VBox status code. - * @param pVM The VM to operate on. - */ -VMMR3DECL(int) PATMR3Term(PVM pVM); - -/** - * PATM reset callback. - * - * @returns VBox status code. - * @param pVM The VM which is reset. - */ -VMMR3DECL(int) PATMR3Reset(PVM pVM); - -/** - * Returns the host context pointer and size of the patch memory block - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pcb Size of the patch memory block - */ -VMMR3DECL(void *) PATMR3QueryPatchMemHC(PVM pVM, uint32_t *pcb); - -/** - * Returns the guest context pointer and size of the patch memory block - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pcb Size of the patch memory block - */ -VMMR3DECL(RTRCPTR) PATMR3QueryPatchMemGC(PVM pVM, uint32_t *pcb); - -/** - * Checks whether the GC address is inside a generated patch jump - * - * @returns true -> yes, false -> no - * @param pVM The VM to operate on. - * @param pAddr Guest context address - * @param pPatchAddr Guest context patch address (if true) - */ -VMMR3DECL(bool) PATMR3IsInsidePatchJump(PVM pVM, RTRCPTR pAddr, PRTGCPTR32 pPatchAddr); - - -/** - * Returns the GC pointer of the patch for the specified GC address - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pAddrGC Guest context address - */ -VMMR3DECL(RTRCPTR) PATMR3QueryPatchGCPtr(PVM pVM, RTRCPTR pAddrGC); - -/** - * Checks whether the HC address is part of our patch region - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pAddrGC Guest context address - */ -VMMR3DECL(bool) PATMR3IsPatchHCAddr(PVM pVM, R3PTRTYPE(uint8_t *) pAddrHC); - -/** - * Convert a GC patch block pointer to a HC patch pointer - * - * @returns HC pointer or NULL if it's not a GC patch pointer - * @param pVM The VM to operate on. - * @param pAddrGC GC pointer - */ -VMMR3DECL(R3PTRTYPE(void *)) PATMR3GCPtrToHCPtr(PVM pVM, RTRCPTR pAddrGC); - - -/** - * Returns the host context pointer and size of the GC context structure - * - * @returns VBox status code. - * @param pVM The VM to operate on. - */ -VMMR3DECL(PPATMGCSTATE) PATMR3QueryGCStateHC(PVM pVM); - -/** - * Handle trap inside patch code - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pCtx CPU context - * @param pEip GC pointer of trapping instruction - * @param pNewEip GC pointer to new instruction - */ -VMMR3DECL(int) PATMR3HandleTrap(PVM pVM, PCPUMCTX pCtx, RTRCPTR pEip, RTGCPTR *ppNewEip); - -/** - * Handle page-fault in monitored page - * - * @returns VBox status code. - * @param pVM The VM to operate on. - */ -VMMR3DECL(int) PATMR3HandleMonitoredPage(PVM pVM); - -/** - * Notifies PATM about a (potential) write to code that has been patched. - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param GCPtr GC pointer to write address - * @param cbWrite Nr of bytes to write - * - */ -VMMR3DECL(int) PATMR3PatchWrite(PVM pVM, RTRCPTR GCPtr, uint32_t cbWrite); - -/** - * Notify PATM of a page flush - * - * @returns VBox status code - * @param pVM The VM to operate on. - * @param addr GC address of the page to flush - */ -VMMR3DECL(int) PATMR3FlushPage(PVM pVM, RTRCPTR addr); - -/** - * Allows or disallow patching of privileged instructions executed by the guest OS - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param fAllowPatching Allow/disallow patching - */ -VMMR3DECL(int) PATMR3AllowPatching(PVM pVM, uint32_t fAllowPatching); - -/** - * Patch privileged instruction at specified location - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pInstr Guest context point to privileged instruction (0:32 flat address) - * @param flags Patch flags - * - * @note returns failure if patching is not allowed or possible - */ -VMMR3DECL(int) PATMR3InstallPatch(PVM pVM, RTRCPTR pInstrGC, uint64_t flags); - -/** - * Gives hint to PATM about supervisor guest instructions - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pInstr Guest context point to privileged instruction - * @param flags Patch flags - */ -VMMR3DECL(int) PATMR3AddHint(PVM pVM, RTRCPTR pInstrGC, uint32_t flags); - -/** - * Patch branch target function for call/jump at specified location. - * (in responds to a VINF_PATM_DUPLICATE_FUNCTION GC exit reason) - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pCtx Guest context - * - */ -VMMR3DECL(int) PATMR3DuplicateFunctionRequest(PVM pVM, PCPUMCTX pCtx); - -/** - * Query the corresponding GC instruction pointer from a pointer inside the patch block itself - * - * @returns original GC instruction pointer or 0 if not found - * @param pVM The VM to operate on. - * @param pPatchGC GC address in patch block - * @param pEnmState State of the translated address (out) - * - */ -VMMR3DECL(RTRCPTR) PATMR3PatchToGCPtr(PVM pVM, RTRCPTR pPatchGC, PATMTRANSSTATE *pEnmState); - -/** - * Converts Guest code GC ptr to Patch code GC ptr (if found) - * - * @returns corresponding GC pointer in patch block - * @param pVM The VM to operate on. - * @param pInstrGC Guest context pointer to privileged instruction - * - */ -VMMR3DECL(RTRCPTR) PATMR3GuestGCPtrToPatchGCPtr(PVM pVM, RCPTRTYPE(uint8_t*) pInstrGC); - -/** - * Query the opcode of the original code that was overwritten by the 5 bytes patch jump - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pInstrGC GC address of instr - * @param pByte opcode byte pointer (OUT) - * @returns VBOX error code - * - */ -VMMR3DECL(int) PATMR3QueryOpcode(PVM pVM, RTRCPTR pInstrGC, uint8_t *pByte); -VMMR3DECL(int) PATMR3ReadOrgInstr(PVM pVM, RTGCPTR32 GCPtrInstr, uint8_t *pbDst, size_t cbToRead, size_t *pcbRead); - -/** - * Disable patch for privileged instruction at specified location - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pInstr Guest context point to privileged instruction - * - * @note returns failure if patching is not allowed or possible - * - */ -VMMR3DECL(int) PATMR3DisablePatch(PVM pVM, RTRCPTR pInstrGC); - - -/** - * Enable patch for privileged instruction at specified location - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pInstr Guest context point to privileged instruction - * - * @note returns failure if patching is not allowed or possible - * - */ -VMMR3DECL(int) PATMR3EnablePatch(PVM pVM, RTRCPTR pInstrGC); - - -/** - * Remove patch for privileged instruction at specified location - * - * @returns VBox status code. - * @param pVM The VM to operate on. - * @param pInstr Guest context point to privileged instruction - * - * @note returns failure if patching is not allowed or possible - * - */ -VMMR3DECL(int) PATMR3RemovePatch(PVM pVM, RTRCPTR pInstrGC); - - -/** - * Detects it the specified address falls within a 5 byte jump generated for an active patch. - * If so, this patch is permanently disabled. - * - * @param pVM The VM to operate on. - * @param pInstrGC Guest context pointer to instruction - * @param pConflictGC Guest context pointer to check - */ -VMMR3DECL(int) PATMR3DetectConflict(PVM pVM, RTRCPTR pInstrGC, RTRCPTR pConflictGC); - - -/** - * Checks if the instructions at the specified address has been patched already. - * - * @returns boolean, patched or not - * @param pVM The VM to operate on. - * @param pInstrGC Guest context pointer to instruction - */ -VMMR3DECL(bool) PATMR3HasBeenPatched(PVM pVM, RTRCPTR pInstrGC); - - -/** - * Install Linux 2.6 spinlock patch - * - * @returns VBox status code. - * @param pVM The VM to operate on - * @param pCallAcquireSpinlockGC GC pointer of call instruction - * @param cbAcquireSpinlockCall Instruction size - * - */ -VMMR3DECL(int) PATMInstallSpinlockPatch(PVM pVM, RTRCPTR pCallAcquireSpinlockGC, uint32_t cbAcquireSpinlockCall); - - -/** - * Check if supplied call target is the Linux 2.6 spinlock acquire function - * - * @returns boolean - * @param pVM The VM to operate on - * @param pCallAcquireSpinlockGC Call target GC address - * - */ -VMMR3DECL(bool) PATMIsSpinlockAcquire(PVM pVM, RTRCPTR pCallTargetGC); - -/** - * Check if supplied call target is the Linux 2.6 spinlock release function - * - * @returns boolean - * @param pVM The VM to operate on - * @param pCallTargetGC Call target GC address - * - */ -VMMR3DECL(bool) PATMIsSpinlockRelease(PVM pVM, RTRCPTR pCallTargetGC); - -/** - * Check if supplied call target is the Linux 2.6 spinlock release function (patched equivalent) - * - * @returns boolean - * @param pVM The VM to operate on - * @param pCallTargetGC Call target GC address - * - */ -VMMR3DECL(bool) PATMIsSpinlockReleasePatch(PVM pVM, RTRCPTR pCallTargetGC); +VMMR3DECL(int) PATMR3AllowPatching(PUVM pUVM, bool fAllowPatching); +VMMR3DECL(bool) PATMR3IsEnabled(PUVM pUVM); + +VMMR3_INT_DECL(int) PATMR3Init(PVM pVM); +VMMR3_INT_DECL(int) PATMR3InitFinalize(PVM pVM); +VMMR3_INT_DECL(void) PATMR3Relocate(PVM pVM); +VMMR3_INT_DECL(int) PATMR3Term(PVM pVM); +VMMR3_INT_DECL(int) PATMR3Reset(PVM pVM); + +VMMR3_INT_DECL(void *) PATMR3QueryPatchMemHC(PVM pVM, uint32_t *pcb); +VMMR3_INT_DECL(RTRCPTR) PATMR3QueryPatchMemGC(PVM pVM, uint32_t *pcb); +VMMR3_INT_DECL(bool) PATMR3IsInsidePatchJump(PVM pVM, RTRCPTR pAddr, PRTGCPTR32 pPatchAddr); +VMMR3_INT_DECL(RTRCPTR) PATMR3QueryPatchGCPtr(PVM pVM, RTRCPTR pAddrGC); +VMMR3_INT_DECL(bool) PATMR3IsPatchHCAddr(PVM pVM, void *pAddrHC); +VMMR3_INT_DECL(void *) PATMR3GCPtrToHCPtr(PVM pVM, RTRCPTR pAddrGC); +VMMR3_INT_DECL(PPATMGCSTATE) PATMR3QueryGCStateHC(PVM pVM); +VMMR3_INT_DECL(int) PATMR3HandleTrap(PVM pVM, PCPUMCTX pCtx, RTRCPTR pEip, RTGCPTR *ppNewEip); +VMMR3_INT_DECL(int) PATMR3HandleMonitoredPage(PVM pVM); +VMMR3_INT_DECL(int) PATMR3PatchWrite(PVM pVM, RTRCPTR GCPtr, uint32_t cbWrite); +VMMR3_INT_DECL(int) PATMR3FlushPage(PVM pVM, RTRCPTR addr); +VMMR3_INT_DECL(int) PATMR3InstallPatch(PVM pVM, RTRCPTR pInstrGC, uint64_t flags); +VMMR3_INT_DECL(int) PATMR3AddHint(PVM pVM, RTRCPTR pInstrGC, uint32_t flags); +VMMR3_INT_DECL(int) PATMR3DuplicateFunctionRequest(PVM pVM, PCPUMCTX pCtx); +VMMR3_INT_DECL(RTRCPTR) PATMR3PatchToGCPtr(PVM pVM, RTRCPTR pPatchGC, PATMTRANSSTATE *pEnmState); +VMMR3DECL(int) PATMR3QueryOpcode(PVM pVM, RTRCPTR pInstrGC, uint8_t *pByte); +VMMR3_INT_DECL(int) PATMR3ReadOrgInstr(PVM pVM, RTGCPTR32 GCPtrInstr, uint8_t *pbDst, size_t cbToRead, size_t *pcbRead); +VMMR3_INT_DECL(int) PATMR3DisablePatch(PVM pVM, RTRCPTR pInstrGC); +VMMR3_INT_DECL(int) PATMR3EnablePatch(PVM pVM, RTRCPTR pInstrGC); +VMMR3_INT_DECL(int) PATMR3RemovePatch(PVM pVM, RTRCPTR pInstrGC); +VMMR3_INT_DECL(int) PATMR3DetectConflict(PVM pVM, RTRCPTR pInstrGC, RTRCPTR pConflictGC); +VMMR3_INT_DECL(bool) PATMR3HasBeenPatched(PVM pVM, RTRCPTR pInstrGC); + +VMMR3_INT_DECL(void) PATMR3DbgPopulateAddrSpace(PVM pVM, RTDBGAS hDbgAs); +VMMR3_INT_DECL(void) PATMR3DbgAnnotatePatchedInstruction(PVM pVM, RTRCPTR RCPtr, uint8_t cbInstr, + char *pszBuf, size_t cbBuf); /** @} */ #endif @@ -668,5 +221,6 @@ VMMR3DECL(bool) PATMIsSpinlockReleasePatch(PVM pVM, RTRCPTR pCallTargetGC); /** @} */ RT_C_DECLS_END +#endif /* VBOX_WITH_RAW_MODE */ #endif diff --git a/include/VBox/vmm/pdm.h b/include/VBox/vmm/pdm.h index ff95ea82..527d3d14 100644 --- a/include/VBox/vmm/pdm.h +++ b/include/VBox/vmm/pdm.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -29,6 +29,7 @@ #include <VBox/vmm/pdmapi.h> #include <VBox/vmm/pdmqueue.h> #include <VBox/vmm/pdmcritsect.h> +#include <VBox/vmm/pdmcritsectrw.h> #include <VBox/vmm/pdmthread.h> #include <VBox/vmm/pdmifs.h> #include <VBox/vmm/pdmdrv.h> diff --git a/include/VBox/vmm/pdmapi.h b/include/VBox/vmm/pdmapi.h index 1fb8aef6..321865a1 100644 --- a/include/VBox/vmm/pdmapi.h +++ b/include/VBox/vmm/pdmapi.h @@ -7,7 +7,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -40,20 +40,21 @@ RT_C_DECLS_BEGIN * @{ */ -VMMDECL(int) PDMGetInterrupt(PVMCPU pVCpu, uint8_t *pu8Interrupt); -VMMDECL(int) PDMIsaSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level, uint32_t uTagSrc); -VMM_INT_DECL(int) PDMIoApicSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level, uint32_t uTagSrc); -VMM_INT_DECL(int) PDMIoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue, uint32_t uTagSrc); -VMMDECL(bool) PDMHasIoApic(PVM pVM); -VMMDECL(int) PDMApicHasPendingIrq(PVM pVM, bool *pfPending); -VMMDECL(int) PDMApicSetBase(PVM pVM, uint64_t u64Base); -VMMDECL(int) PDMApicGetBase(PVM pVM, uint64_t *pu64Base); -VMMDECL(int) PDMApicSetTPR(PVMCPU pVCpu, uint8_t u8TPR); -VMMDECL(int) PDMApicGetTPR(PVMCPU pVCpu, uint8_t *pu8TPR, bool *pfPending); -VMMDECL(int) PDMApicWriteMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t u64Value); -VMMDECL(int) PDMApicReadMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu64Value); -VMMDECL(int) PDMVMMDevHeapR3ToGCPhys(PVM pVM, RTR3PTR pv, RTGCPHYS *pGCPhys); -VMMDECL(bool) PDMVMMDevHeapIsEnabled(PVM pVM); +VMMDECL(int) PDMGetInterrupt(PVMCPU pVCpu, uint8_t *pu8Interrupt); +VMMDECL(int) PDMIsaSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level, uint32_t uTagSrc); +VMM_INT_DECL(bool) PDMHasIoApic(PVM pVM); +VMM_INT_DECL(int) PDMIoApicSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level, uint32_t uTagSrc); +VMM_INT_DECL(int) PDMIoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue, uint32_t uTagSrc); +VMM_INT_DECL(bool) PDMHasApic(PVM pVM); +VMM_INT_DECL(int) PDMApicHasPendingIrq(PVM pVM, bool *pfPending); +VMMDECL(int) PDMApicSetBase(PVMCPU pVCpu, uint64_t u64Base); +VMMDECL(int) PDMApicGetBase(PVMCPU pVCpu, uint64_t *pu64Base); +VMMDECL(int) PDMApicSetTPR(PVMCPU pVCpu, uint8_t u8TPR); +VMMDECL(int) PDMApicGetTPR(PVMCPU pVCpu, uint8_t *pu8TPR, bool *pfPending, uint8_t *pu8PendingIrq); +VMM_INT_DECL(int) PDMApicWriteMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t u64Value); +VMM_INT_DECL(int) PDMApicReadMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu64Value); +VMM_INT_DECL(int) PDMVmmDevHeapR3ToGCPhys(PVM pVM, RTR3PTR pv, RTGCPHYS *pGCPhys); +VMM_INT_DECL(bool) PDMVmmDevHeapIsEnabled(PVM pVM); /** @defgroup grp_pdm_r3 The PDM Host Context Ring-3 API @@ -61,18 +62,36 @@ VMMDECL(bool) PDMVMMDevHeapIsEnabled(PVM pVM); * @{ */ -VMMR3DECL(int) PDMR3InitUVM(PUVM pUVM); -VMMR3DECL(int) PDMR3LdrLoadVMMR0U(PUVM pUVM); -VMMR3DECL(int) PDMR3Init(PVM pVM); -VMMR3DECL(void) PDMR3PowerOn(PVM pVM); -VMMR3DECL(void) PDMR3ResetCpu(PVMCPU pVCpu); -VMMR3DECL(void) PDMR3Reset(PVM pVM); -VMMR3DECL(void) PDMR3Suspend(PVM pVM); -VMMR3DECL(void) PDMR3Resume(PVM pVM); -VMMR3DECL(void) PDMR3PowerOff(PVM pVM); -VMMR3DECL(void) PDMR3Relocate(PVM pVM, RTGCINTPTR offDelta); -VMMR3DECL(int) PDMR3Term(PVM pVM); -VMMR3DECL(void) PDMR3TermUVM(PUVM pUVM); +VMMR3_INT_DECL(int) PDMR3InitUVM(PUVM pUVM); +VMMR3_INT_DECL(int) PDMR3LdrLoadVMMR0U(PUVM pUVM); +VMMR3_INT_DECL(int) PDMR3Init(PVM pVM); +VMMR3DECL(void) PDMR3PowerOn(PVM pVM); +VMMR3_INT_DECL(void) PDMR3ResetCpu(PVMCPU pVCpu); +VMMR3_INT_DECL(void) PDMR3Reset(PVM pVM); +VMMR3_INT_DECL(void) PDMR3MemSetup(PVM pVM, bool fAtReset); +VMMR3_INT_DECL(void) PDMR3Suspend(PVM pVM); +VMMR3_INT_DECL(void) PDMR3Resume(PVM pVM); +VMMR3DECL(void) PDMR3PowerOff(PVM pVM); +VMMR3_INT_DECL(void) PDMR3Relocate(PVM pVM, RTGCINTPTR offDelta); +VMMR3_INT_DECL(int) PDMR3Term(PVM pVM); +VMMR3_INT_DECL(void) PDMR3TermUVM(PUVM pUVM); + +/** PDM loader context indicator. */ +typedef enum PDMLDRCTX +{ + /** Invalid zero value. */ + PDMLDRCTX_INVALID = 0, + /** Ring-0 context. */ + PDMLDRCTX_RING_0, + /** Ring-3 context. */ + PDMLDRCTX_RING_3, + /** Raw-mode context. */ + PDMLDRCTX_RAW_MODE, + /** End of valid context values. */ + PDMLDRCTX_END, + /** 32-bit type hack. */ + PDMLDRCTX_32BIT_HACK = 0x7fffffff +} PDMLDRCTX; /** * Module enumeration callback function. @@ -85,54 +104,57 @@ VMMR3DECL(void) PDMR3TermUVM(PUVM pUVM); * @param pszName Module name. (short and unique) * @param ImageBase Address where to executable image is loaded. * @param cbImage Size of the executable image. - * @param fRC Set if raw-mode context, clear if host context. + * @param enmCtx The context the module is loaded into. * @param pvArg User argument. */ typedef DECLCALLBACK(int) FNPDMR3ENUM(PVM pVM, const char *pszFilename, const char *pszName, - RTUINTPTR ImageBase, size_t cbImage, bool fRC, void *pvArg); + RTUINTPTR ImageBase, size_t cbImage, PDMLDRCTX enmCtx, void *pvArg); /** Pointer to a FNPDMR3ENUM() function. */ typedef FNPDMR3ENUM *PFNPDMR3ENUM; -VMMR3DECL(int) PDMR3LdrEnumModules(PVM pVM, PFNPDMR3ENUM pfnCallback, void *pvArg); -VMMR3DECL(void) PDMR3LdrRelocateU(PUVM pUVM, RTGCINTPTR offDelta); -VMMR3DECL(int) PDMR3LdrGetSymbolR3(PVM pVM, const char *pszModule, const char *pszSymbol, void **ppvValue); -VMMR3DECL(int) PDMR3LdrGetSymbolR0(PVM pVM, const char *pszModule, const char *pszSymbol, PRTR0PTR ppvValue); -VMMR3DECL(int) PDMR3LdrGetSymbolR0Lazy(PVM pVM, const char *pszModule, const char *pszSearchPath, const char *pszSymbol, PRTR0PTR ppvValue); -VMMR3DECL(int) PDMR3LdrLoadRC(PVM pVM, const char *pszFilename, const char *pszName); -VMMR3DECL(int) PDMR3LdrGetSymbolRC(PVM pVM, const char *pszModule, const char *pszSymbol, PRTRCPTR pRCPtrValue); -VMMR3DECL(int) PDMR3LdrGetSymbolRCLazy(PVM pVM, const char *pszModule, const char *pszSearchPath, const char *pszSymbol, PRTRCPTR pRCPtrValue); -VMMR3DECL(int) PDMR3LdrQueryRCModFromPC(PVM pVM, RTRCPTR uPC, - char *pszModName, size_t cchModName, PRTRCPTR pMod, - char *pszNearSym1, size_t cchNearSym1, PRTRCPTR pNearSym1, - char *pszNearSym2, size_t cchNearSym2, PRTRCPTR pNearSym2); -VMMR3DECL(int) PDMR3LdrQueryR0ModFromPC(PVM pVM, RTR0PTR uPC, - char *pszModName, size_t cchModName, PRTR0PTR pMod, - char *pszNearSym1, size_t cchNearSym1, PRTR0PTR pNearSym1, - char *pszNearSym2, size_t cchNearSym2, PRTR0PTR pNearSym2); -VMMR3DECL(int) PDMR3LdrGetInterfaceSymbols(PVM pVM, - void *pvInterface, size_t cbInterface, - const char *pszModule, const char *pszSearchPath, - const char *pszSymPrefix, const char *pszSymList, - bool fRing0OrRC); - -VMMR3DECL(int) PDMR3QueryDevice(PVM pVM, const char *pszDevice, unsigned iInstance, PPPDMIBASE ppBase); -VMMR3DECL(int) PDMR3QueryDeviceLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPPDMIBASE ppBase); -VMMR3DECL(int) PDMR3QueryLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPPDMIBASE ppBase); -VMMR3DECL(int) PDMR3QueryDriverOnLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, const char *pszDriver, - PPPDMIBASE ppBase); -VMMR3DECL(int) PDMR3DeviceAttach(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, uint32_t fFlags, PPDMIBASE *ppBase); -VMMR3DECL(int) PDMR3DeviceDetach(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, uint32_t fFlags); +VMMR3DECL(int) PDMR3LdrEnumModules(PVM pVM, PFNPDMR3ENUM pfnCallback, void *pvArg); +VMMR3_INT_DECL(void) PDMR3LdrRelocateU(PUVM pUVM, RTGCINTPTR offDelta); +VMMR3_INT_DECL(int) PDMR3LdrGetSymbolR3(PVM pVM, const char *pszModule, const char *pszSymbol, void **ppvValue); +VMMR3DECL(int) PDMR3LdrGetSymbolR0(PVM pVM, const char *pszModule, const char *pszSymbol, PRTR0PTR ppvValue); +VMMR3DECL(int) PDMR3LdrGetSymbolR0Lazy(PVM pVM, const char *pszModule, const char *pszSearchPath, const char *pszSymbol, PRTR0PTR ppvValue); +VMMR3DECL(int) PDMR3LdrLoadRC(PVM pVM, const char *pszFilename, const char *pszName); +VMMR3DECL(int) PDMR3LdrGetSymbolRC(PVM pVM, const char *pszModule, const char *pszSymbol, PRTRCPTR pRCPtrValue); +VMMR3DECL(int) PDMR3LdrGetSymbolRCLazy(PVM pVM, const char *pszModule, const char *pszSearchPath, const char *pszSymbol, + PRTRCPTR pRCPtrValue); +VMMR3_INT_DECL(int) PDMR3LdrQueryRCModFromPC(PVM pVM, RTRCPTR uPC, + char *pszModName, size_t cchModName, PRTRCPTR pMod, + char *pszNearSym1, size_t cchNearSym1, PRTRCPTR pNearSym1, + char *pszNearSym2, size_t cchNearSym2, PRTRCPTR pNearSym2); +VMMR3_INT_DECL(int) PDMR3LdrQueryR0ModFromPC(PVM pVM, RTR0PTR uPC, + char *pszModName, size_t cchModName, PRTR0PTR pMod, + char *pszNearSym1, size_t cchNearSym1, PRTR0PTR pNearSym1, + char *pszNearSym2, size_t cchNearSym2, PRTR0PTR pNearSym2); +VMMR3_INT_DECL(int) PDMR3LdrGetInterfaceSymbols(PVM pVM, void *pvInterface, size_t cbInterface, + const char *pszModule, const char *pszSearchPath, + const char *pszSymPrefix, const char *pszSymList, + bool fRing0OrRC); + +VMMR3DECL(int) PDMR3QueryDevice(PUVM pUVM, const char *pszDevice, unsigned iInstance, PPPDMIBASE ppBase); +VMMR3DECL(int) PDMR3QueryDeviceLun(PUVM pUVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPPDMIBASE ppBase); +VMMR3DECL(int) PDMR3QueryLun(PUVM pUVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPPDMIBASE ppBase); +VMMR3DECL(int) PDMR3QueryDriverOnLun(PUVM pUVM, const char *pszDevice, unsigned iInstance, unsigned iLun, + const char *pszDriver, PPPDMIBASE ppBase); +VMMR3DECL(int) PDMR3DeviceAttach(PUVM pUVM, const char *pszDevice, unsigned iInstance, unsigned iLun, uint32_t fFlags, + PPDMIBASE *ppBase); +VMMR3DECL(int) PDMR3DeviceDetach(PUVM pUVM, const char *pszDevice, unsigned iInstance, unsigned iLun, uint32_t fFlags); VMMR3_INT_DECL(PPDMCRITSECT) PDMR3DevGetCritSect(PVM pVM, PPDMDEVINS pDevIns); -VMMR3DECL(int) PDMR3DriverAttach(PVM pVM, const char *pszDevice, unsigned iDevIns, unsigned iLun, uint32_t fFlags, PPPDMIBASE ppBase); -VMMR3DECL(int) PDMR3DriverDetach(PVM pVM, const char *pszDevice, unsigned iDevIns, unsigned iLun, - const char *pszDriver, unsigned iOccurance, uint32_t fFlags); -VMMR3DECL(int) PDMR3DriverReattach(PVM pVM, const char *pszDevice, unsigned iDevIns, unsigned iLun, - const char *pszDriver, unsigned iOccurance, uint32_t fFlags, PCFGMNODE pCfg, PPPDMIBASE ppBase); -VMMR3DECL(void) PDMR3DmaRun(PVM pVM); -VMMR3DECL(int) PDMR3LockCall(PVM pVM); -VMMR3DECL(int) PDMR3RegisterVMMDevHeap(PVM pVM, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize); -VMMR3DECL(int) PDMR3VMMDevHeapAlloc(PVM pVM, unsigned cbSize, RTR3PTR *ppv); -VMMR3DECL(int) PDMR3VMMDevHeapFree(PVM pVM, RTR3PTR pv); -VMMR3DECL(int) PDMR3UnregisterVMMDevHeap(PVM pVM, RTGCPHYS GCPhys); +VMMR3DECL(int) PDMR3DriverAttach(PUVM pUVM, const char *pszDevice, unsigned iDevIns, unsigned iLun, uint32_t fFlags, + PPPDMIBASE ppBase); +VMMR3DECL(int) PDMR3DriverDetach(PUVM pUVM, const char *pszDevice, unsigned iDevIns, unsigned iLun, + const char *pszDriver, unsigned iOccurance, uint32_t fFlags); +VMMR3DECL(int) PDMR3DriverReattach(PUVM pVM, const char *pszDevice, unsigned iDevIns, unsigned iLun, + const char *pszDriver, unsigned iOccurance, uint32_t fFlags, PCFGMNODE pCfg, + PPPDMIBASE ppBase); +VMMR3DECL(void) PDMR3DmaRun(PVM pVM); +VMMR3_INT_DECL(int) PDMR3LockCall(PVM pVM); +VMMR3_INT_DECL(int) PDMR3VmmDevHeapRegister(PVM pVM, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize); +VMMR3_INT_DECL(int) PDMR3VmmDevHeapUnregister(PVM pVM, RTGCPHYS GCPhys); +VMMR3_INT_DECL(int) PDMR3VmmDevHeapAlloc(PVM pVM, size_t cbSize, RTR3PTR *ppv); +VMMR3_INT_DECL(int) PDMR3VmmDevHeapFree(PVM pVM, RTR3PTR pv); VMMR3_INT_DECL(int) PDMR3TracingConfig(PVM pVM, const char *pszName, size_t cchName, bool fEnable, bool fApply); VMMR3_INT_DECL(bool) PDMR3TracingAreAll(PVM pVM, bool fEnabled); VMMR3_INT_DECL(int) PDMR3TracingQueryConfig(PVM pVM, char *pszConfig, size_t cbConfig); diff --git a/include/VBox/vmm/pdmasynccompletion.h b/include/VBox/vmm/pdmasynccompletion.h index 1d1af265..74285945 100644 --- a/include/VBox/vmm/pdmasynccompletion.h +++ b/include/VBox/vmm/pdmasynccompletion.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2007-2010 Oracle Corporation + * Copyright (C) 2007-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -104,122 +104,8 @@ typedef DECLCALLBACK(void) FNPDMASYNCCOMPLETEINT(PVM pVM, void *pvUser, void *pv /** Pointer to a FNPDMASYNCCOMPLETEINT(). */ typedef FNPDMASYNCCOMPLETEINT *PFNPDMASYNCCOMPLETEINT; - -/** - * Creates an async completion template for a device instance. - * - * The template is used when creating new completion tasks. - * - * @returns VBox status code. - * @param pVM Pointer to the shared VM structure. - * @param pDevIns The device instance. - * @param ppTemplate Where to store the template pointer on success. - * @param pfnCompleted The completion callback routine. - * @param pszDesc Description. - */ -VMMR3DECL(int) PDMR3AsyncCompletionTemplateCreateDevice(PVM pVM, PPDMDEVINS pDevIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEDEV pfnCompleted, const char *pszDesc); - -/** - * Creates an async completion template for a driver instance. - * - * The template is used when creating new completion tasks. - * - * @returns VBox status code. - * @param pVM Pointer to the shared VM structure. - * @param pDrvIns The driver instance. - * @param ppTemplate Where to store the template pointer on success. - * @param pfnCompleted The completion callback routine. - * @param pvTemplateUser Template user argument. - * @param pszDesc Description. - */ -VMMR3DECL(int) PDMR3AsyncCompletionTemplateCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEDRV pfnCompleted, void *pvTemplateUser, const char *pszDesc); - -/** - * Creates an async completion template for a USB device instance. - * - * The template is used when creating new completion tasks. - * - * @returns VBox status code. - * @param pVM Pointer to the shared VM structure. - * @param pUsbIns The USB device instance. - * @param ppTemplate Where to store the template pointer on success. - * @param pfnCompleted The completion callback routine. - * @param pszDesc Description. - */ -VMMR3DECL(int) PDMR3AsyncCompletionTemplateCreateUsb(PVM pVM, PPDMUSBINS pUsbIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEUSB pfnCompleted, const char *pszDesc); - -/** - * Creates an async completion template for internally by the VMM. - * - * The template is used when creating new completion tasks. - * - * @returns VBox status code. - * @param pVM Pointer to the shared VM structure. - * @param ppTemplate Where to store the template pointer on success. - * @param pfnCompleted The completion callback routine. - * @param pvUser2 The 2nd user argument for the callback. - * @param pszDesc Description. - */ VMMR3DECL(int) PDMR3AsyncCompletionTemplateCreateInternal(PVM pVM, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEINT pfnCompleted, void *pvUser2, const char *pszDesc); - -/** - * Destroys the specified async completion template. - * - * @returns VBox status codes: - * @retval VINF_SUCCESS on success. - * @retval VERR_PDM_ASYNC_TEMPLATE_BUSY if the template is still in use. - * - * @param pTemplate The template in question. - */ VMMR3DECL(int) PDMR3AsyncCompletionTemplateDestroy(PPDMASYNCCOMPLETIONTEMPLATE pTemplate); - -/** - * Destroys all the specified async completion templates for the given device instance. - * - * @returns VBox status codes: - * @retval VINF_SUCCESS on success. - * @retval VERR_PDM_ASYNC_TEMPLATE_BUSY if one or more of the templates are still in use. - * - * @param pVM Pointer to the shared VM structure. - * @param pDevIns The device instance. - */ -VMMR3DECL(int) PDMR3AsyncCompletionTemplateDestroyDevice(PVM pVM, PPDMDEVINS pDevIns); - -/** - * Destroys all the specified async completion templates for the given driver instance. - * - * @returns VBox status codes: - * @retval VINF_SUCCESS on success. - * @retval VERR_PDM_ASYNC_TEMPLATE_BUSY if one or more of the templates are still in use. - * - * @param pVM Pointer to the shared VM structure. - * @param pDrvIns The driver instance. - */ -VMMR3DECL(int) PDMR3AsyncCompletionTemplateDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns); - -/** - * Destroys all the specified async completion templates for the given USB device instance. - * - * @returns VBox status codes: - * @retval VINF_SUCCESS on success. - * @retval VERR_PDM_ASYNC_TEMPLATE_BUSY if one or more of the templates are still in use. - * - * @param pVM Pointer to the shared VM structure. - * @param pUsbIns The USB device instance. - */ -VMMR3DECL(int) PDMR3AsyncCompletionTemplateDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns); - - -/** - * Opens a file as an async completion endpoint. - * - * @returns VBox status code. - * @param ppEndpoint Where to store the opaque endpoint handle on success. - * @param pszFilename Path to the file which is to be opened. (UTF-8) - * @param fFlags Open flags, see grp_pdmacep_file_flags. - * @param pTemplate Handle to the completion callback template to use - * for this end point. - */ VMMR3DECL(int) PDMR3AsyncCompletionEpCreateForFile(PPPDMASYNCCOMPLETIONENDPOINT ppEndpoint, const char *pszFilename, uint32_t fFlags, PPDMASYNCCOMPLETIONTEMPLATE pTemplate); @@ -238,127 +124,21 @@ VMMR3DECL(int) PDMR3AsyncCompletionEpCreateForFile(PPPDMASYNCCOMPLETIONENDPOINT #define PDMACEP_FILE_FLAGS_HOST_CACHE_ENABLED RT_BIT_32(3) /** @} */ -/** - * Closes a endpoint waiting for any pending tasks to finish. - * - * @returns nothing. - * @param pEndpoint Handle of the endpoint. - */ VMMR3DECL(void) PDMR3AsyncCompletionEpClose(PPDMASYNCCOMPLETIONENDPOINT pEndpoint); - -/** - * Creates a read task on the given endpoint. - * - * @returns VBox status code. - * @param pEndpoint The file endpoint to read from. - * @param off Where to start reading from. - * @param paSegments Scatter gather list to store the data in. - * @param cSegments Number of segments in the list. - * @param cbRead The overall number of bytes to read. - * @param pvUser Opaque user data returned in the completion callback - * upon completion of the task. - * @param ppTask Where to store the task handle on success. - */ VMMR3DECL(int) PDMR3AsyncCompletionEpRead(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, RTFOFF off, PCRTSGSEG paSegments, unsigned cSegments, size_t cbRead, void *pvUser, PPPDMASYNCCOMPLETIONTASK ppTask); - -/** - * Creates a write task on the given endpoint. - * - * @returns VBox status code. - * @param pEndpoint The file endpoint to write to. - * @param off Where to start writing at. - * @param paSegments Scatter gather list of the data to write. - * @param cSegments Number of segments in the list. - * @param cbWrite The overall number of bytes to write. - * @param pvUser Opaque user data returned in the completion callback - * upon completion of the task. - * @param ppTask Where to store the task handle on success. - */ VMMR3DECL(int) PDMR3AsyncCompletionEpWrite(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, RTFOFF off, PCRTSGSEG paSegments, unsigned cSegments, size_t cbWrite, void *pvUser, PPPDMASYNCCOMPLETIONTASK ppTask); - -/** - * Creates a flush task on the given endpoint. - * - * Every read and write task initiated before the flush task is - * finished upon completion of this task. - * - * @returns VBox status code. - * @param pEndpoint The file endpoint to flush. - * @param pvUser Opaque user data returned in the completion callback - * upon completion of the task. - * @param ppTask Where to store the task handle on success. - */ -VMMR3DECL(int) PDMR3AsyncCompletionEpFlush(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, - void *pvUser, - PPPDMASYNCCOMPLETIONTASK ppTask); - -/** - * Queries the size of an endpoint. - * Not that some endpoints may not support this and will return an error - * (sockets for example). - * - * @returns VBox status code. - * @retval VERR_NOT_SUPPORTED if the endpoint does not support this operation. - * @param pEndpoint The file endpoint. - * @param pcbSize Where to store the size of the endpoint. - */ -VMMR3DECL(int) PDMR3AsyncCompletionEpGetSize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, - uint64_t *pcbSize); - -/** - * Sets the size of an endpoint. - * Not that some endpoints may not support this and will return an error - * (sockets for example). - * - * @returns VBox status code. - * @retval VERR_NOT_SUPPORTED if the endpoint does not support this operation. - * @param pEndpoint The file endpoint. - * @param cbSize The size to set. - * - * @note PDMR3AsyncCompletionEpFlush should be called before this operation is executed. - */ -VMMR3DECL(int) PDMR3AsyncCompletionEpSetSize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, - uint64_t cbSize); - -/** - * Assigns or removes a bandwidth control manager to/from the endpoint. - * - * @returns VBox status code. - * @param pEndpoint The endpoint. - * @param pcszBwMgr The identifer of the new bandwidth manager to assign - * or NULL to remove the current one. - */ -VMMR3DECL(int) PDMR3AsyncCompletionEpSetBwMgr(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, - const char *pcszBwMgr); - -/** - * Cancels an async completion task. - * - * If you want to use this method, you have to take great create to make sure - * you will never attempt cancel a task which has been completed. Since there is - * no reference counting or anything on the task it self, you have to serialize - * the cancelation and completion paths such that the aren't racing one another. - * - * @returns VBox status code - * @param pTask The Task to cancel. - */ +VMMR3DECL(int) PDMR3AsyncCompletionEpFlush(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, void *pvUser, PPPDMASYNCCOMPLETIONTASK ppTask); +VMMR3DECL(int) PDMR3AsyncCompletionEpGetSize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, uint64_t *pcbSize); +VMMR3DECL(int) PDMR3AsyncCompletionEpSetSize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, uint64_t cbSize); +VMMR3DECL(int) PDMR3AsyncCompletionEpSetBwMgr(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, const char *pszBwMgr); VMMR3DECL(int) PDMR3AsyncCompletionTaskCancel(PPDMASYNCCOMPLETIONTASK pTask); - -/** - * Changes the limit of a bandwidth manager for file endpoints to the given value. - * - * @returns VBox status code. - * @param pVM Pointer to the shared VM structure. - * @param pcszBwMgr The identifer of the bandwidth manager to change. - * @param cbMaxNew The new maximum for the bandwidth manager in bytes/sec. - */ -VMMR3DECL(int) PDMR3AsyncCompletionBwMgrSetMaxForFile(PVM pVM, const char *pcszBwMgr, uint32_t cbMaxNew); +VMMR3DECL(int) PDMR3AsyncCompletionBwMgrSetMaxForFile(PUVM pUVM, const char *pszBwMgr, uint32_t cbMaxNew); /** @} */ diff --git a/include/VBox/vmm/pdmblkcache.h b/include/VBox/vmm/pdmblkcache.h index fc92bc4f..14d85f67 100644 --- a/include/VBox/vmm/pdmblkcache.h +++ b/include/VBox/vmm/pdmblkcache.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2007-2010 Oracle Corporation + * Copyright (C) 2007-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/vmm/pdmcardreaderinfs.h b/include/VBox/vmm/pdmcardreaderinfs.h index e1ad5a2d..7cb3ca75 100644 --- a/include/VBox/vmm/pdmcardreaderinfs.h +++ b/include/VBox/vmm/pdmcardreaderinfs.h @@ -1,5 +1,4 @@ /* $Id: pdmcardreaderinfs.h $ */ - /** @file * cardreaderinfs - interface between Usb Card Reader device and its driver. */ @@ -26,11 +25,10 @@ */ #ifndef ___VBox_vmm_pdmcardreaderinfs_h -# define ___VBox_vmm_pdmcardreaderinfs_h +#define ___VBox_vmm_pdmcardreaderinfs_h #include <VBox/types.h> -#define PDMICARDREADERDOWN_IID "78d65378-889c-4418-8bc2-7a89a5af2817" typedef struct PDMICARDREADER_IO_REQUEST { @@ -49,41 +47,41 @@ typedef struct PDMICARDREADER_READERSTATE } PDMICARDREADER_READERSTATE; +#define PDMICARDREADERDOWN_IID "78d65378-889c-4418-8bc2-7a89a5af2817" typedef struct PDMICARDREADERDOWN PDMICARDREADERDOWN; typedef PDMICARDREADERDOWN *PPDMICARDREADERDOWN; struct PDMICARDREADERDOWN { - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownEstablishContext,(PPDMICARDREADERDOWN pInterface)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownConnect,(PPDMICARDREADERDOWN pInterface, void *pvUser, const char *pszCardReaderName, - uint32_t u32ShareMode, uint32_t u32PreferredProtocols)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownDisconnect,(PPDMICARDREADERDOWN pInterface, void *pvUser, - uint32_t u32Disposition)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownStatus,(PPDMICARDREADERDOWN pInterface, void *pvUser, - uint32_t cchReaderName, uint32_t cbAtrLen)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownReleaseContext,(PPDMICARDREADERDOWN pInterface, void *pvUser)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownGetStatusChange,(PPDMICARDREADERDOWN pInterface, void *pvUser, - uint32_t u32Timeout, PDMICARDREADER_READERSTATE *paReaderStats, uint32_t cReaderStats)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownBeginTransaction,(PPDMICARDREADERDOWN pInterface, void *pvUser)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownEndTransaction,(PPDMICARDREADERDOWN pInterface, void *pvUser, - uint32_t u32Disposition)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownTransmit,(PPDMICARDREADERDOWN pInterface, void *pvUser, - const PDMICARDREADER_IO_REQUEST *pioSendRequest, - const uint8_t *pu8SendBuffer, uint32_t cbSendBuffer, uint32_t cbRecvBuffer)); + DECLR3CALLBACKMEMBER(int, pfnEstablishContext,(PPDMICARDREADERDOWN pInterface)); + DECLR3CALLBACKMEMBER(int, pfnConnect,(PPDMICARDREADERDOWN pInterface, void *pvUser, const char *pszCardReaderName, + uint32_t u32ShareMode, uint32_t u32PreferredProtocols)); + DECLR3CALLBACKMEMBER(int, pfnDisconnect,(PPDMICARDREADERDOWN pInterface, void *pvUser, uint32_t u32Disposition)); + DECLR3CALLBACKMEMBER(int, pfnStatus,(PPDMICARDREADERDOWN pInterface, void *pvUser, uint32_t cchReaderName, uint32_t cbAtrLen)); + DECLR3CALLBACKMEMBER(int, pfnReleaseContext,(PPDMICARDREADERDOWN pInterface, void *pvUser)); + DECLR3CALLBACKMEMBER(int, pfnGetStatusChange,(PPDMICARDREADERDOWN pInterface, void *pvUser, uint32_t u32Timeout, + PDMICARDREADER_READERSTATE *paReaderStats, uint32_t cReaderStats)); + DECLR3CALLBACKMEMBER(int, pfnBeginTransaction,(PPDMICARDREADERDOWN pInterface, void *pvUser)); + DECLR3CALLBACKMEMBER(int, pfnEndTransaction,(PPDMICARDREADERDOWN pInterface, void *pvUser, uint32_t u32Disposition)); + DECLR3CALLBACKMEMBER(int, pfnTransmit,(PPDMICARDREADERDOWN pInterface, void *pvUser, + const PDMICARDREADER_IO_REQUEST *pioSendRequest, + const uint8_t *pu8SendBuffer, uint32_t cbSendBuffer, uint32_t cbRecvBuffer)); /** * Up level provides pvInBuffer of cbInBuffer bytes to call SCardControl, also it specify bytes it expects to receive - * @note: device/driver implementation should copy buffers before execution in async mode, and both layers shouldn't - * expect permanent storage for the buffer. + * @note Device/driver implementation should copy buffers before execution in + * async mode, and both layers shouldn't expect permanent storage for the + * buffer. */ - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownControl,(PPDMICARDREADERDOWN pInterface, void *pvUser, - uint32_t u32ControlCode, const void *pvInBuffer, uint32_t cbInBuffer, uint32_t cbOutBuffer)); + DECLR3CALLBACKMEMBER(int, pfnControl,(PPDMICARDREADERDOWN pInterface, void *pvUser, + uint32_t u32ControlCode, const void *pvInBuffer, + uint32_t cbInBuffer, uint32_t cbOutBuffer)); /** * This function ask driver to provide attribute (dwAttribId) and provide limit (cbAttrib) of buffer size for attribute value, * Callback UpGetAttrib returns buffer containing the value and altered size of the buffer. */ - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownGetAttr,(PPDMICARDREADERDOWN pInterface, void *pvUser, - uint32_t u32AttribId, uint32_t cbAttrib)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderDownSetAttr,(PPDMICARDREADERDOWN pInterface, void *pvUser, - uint32_t u32AttribId, const void *pvAttrib, uint32_t cbAttrib)); + DECLR3CALLBACKMEMBER(int, pfnGetAttr,(PPDMICARDREADERDOWN pInterface, void *pvUser, + uint32_t u32AttribId, uint32_t cbAttrib)); + DECLR3CALLBACKMEMBER(int, pfnSetAttr,(PPDMICARDREADERDOWN pInterface, void *pvUser, + uint32_t u32AttribId, const void *pvAttrib, uint32_t cbAttrib)); }; #define PDMICARDREADERUP_IID "c0d7498e-0635-48ca-aab1-b11b6a55cf7d" @@ -91,26 +89,27 @@ typedef struct PDMICARDREADERUP PDMICARDREADERUP; typedef PDMICARDREADERUP *PPDMICARDREADERUP; struct PDMICARDREADERUP { - DECLR3CALLBACKMEMBER(int, pfnCardReaderUpEstablishContext,(PPDMICARDREADERUP pInterface, int32_t lSCardRc)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderUpStatus,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, - char *pszReaderName, uint32_t cchReaderName, uint32_t u32CardState, - uint32_t u32Protocol, uint8_t *pu8Atr, uint32_t cbAtr)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderUpConnect,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, - uint32_t u32ActiveProtocol)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderUpDisconnect,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderUpSetStatusChange,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, - PDMICARDREADER_READERSTATE *paReaderStats, uint32_t cReaderStats)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderUpBeginTransaction,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderUpEndTransaction,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc)); + DECLR3CALLBACKMEMBER(int, pfnEstablishContext,(PPDMICARDREADERUP pInterface, int32_t lSCardRc)); + DECLR3CALLBACKMEMBER(int, pfnStatus,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, + char *pszReaderName, uint32_t cchReaderName, uint32_t u32CardState, + uint32_t u32Protocol, uint8_t *pu8Atr, uint32_t cbAtr)); + DECLR3CALLBACKMEMBER(int, pfnConnect,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, + uint32_t u32ActiveProtocol)); + DECLR3CALLBACKMEMBER(int, pfnDisconnect,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc)); + DECLR3CALLBACKMEMBER(int, pfnSetStatusChange,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, + PDMICARDREADER_READERSTATE *paReaderStats, uint32_t cReaderStats)); + DECLR3CALLBACKMEMBER(int, pfnBeginTransaction,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc)); + DECLR3CALLBACKMEMBER(int, pfnEndTransaction,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc)); /* Note: pioRecvPci stack variable */ - DECLR3CALLBACKMEMBER(int, pfnCardReaderUpTransmit,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, - const PDMICARDREADER_IO_REQUEST *pioRecvPci, uint8_t *pu8RecvBuffer, uint32_t cbRecvBuffer)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderUpControl,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, - uint32_t u32ControlCode, void *pvOutBuffer, uint32_t cbOutBuffer)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderUpGetAttrib,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, - uint32_t u32AttribId, void *pvAttrib, uint32_t cbAttrib)); - DECLR3CALLBACKMEMBER(int, pfnCardReaderUpSetAttrib,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, - uint32_t u32AttribId)); + DECLR3CALLBACKMEMBER(int, pfnTransmit,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, + const PDMICARDREADER_IO_REQUEST *pioRecvPci, + uint8_t *pu8RecvBuffer, uint32_t cbRecvBuffer)); + DECLR3CALLBACKMEMBER(int, pfnControl,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, + uint32_t u32ControlCode, void *pvOutBuffer, uint32_t cbOutBuffer)); + DECLR3CALLBACKMEMBER(int, pfnGetAttrib,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, + uint32_t u32AttribId, void *pvAttrib, uint32_t cbAttrib)); + DECLR3CALLBACKMEMBER(int, pfnSetAttrib,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc, uint32_t u32AttribId)); }; #endif + diff --git a/include/VBox/vmm/pdmcommon.h b/include/VBox/vmm/pdmcommon.h index c4e1be26..d62210a0 100644 --- a/include/VBox/vmm/pdmcommon.h +++ b/include/VBox/vmm/pdmcommon.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -109,7 +109,7 @@ typedef FNPDMUSBASYNCNOTIFY *PFNPDMUSBASYNCNOTIFY; * @returns true if done, false if more work to be done. * * @param pDevIns The device instance. - * + * @remarks The caller will enter the device critical section. * @thread EMT(0) */ typedef DECLCALLBACK(bool) FNPDMDEVASYNCNOTIFY(PPDMDEVINS pDevIns); diff --git a/include/VBox/vmm/pdmcritsect.h b/include/VBox/vmm/pdmcritsect.h index 02d7924d..0895b52b 100644 --- a/include/VBox/vmm/pdmcritsect.h +++ b/include/VBox/vmm/pdmcritsect.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -51,26 +51,31 @@ typedef union PDMCRITSECT #endif } PDMCRITSECT; +VMMR3_INT_DECL(int) PDMR3CritSectBothTerm(PVM pVM); +VMMR3_INT_DECL(void) PDMR3CritSectLeaveAll(PVM pVM); +VMM_INT_DECL(void) PDMCritSectBothFF(PVMCPU pVCpu); + + +VMMR3DECL(uint32_t) PDMR3CritSectCountOwned(PVM pVM, char *pszNames, size_t cbNames); + VMMR3DECL(int) PDMR3CritSectInit(PVM pVM, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, ...); +VMMR3DECL(int) PDMR3CritSectEnterEx(PPDMCRITSECT pCritSect, bool fCallRing3); +VMMR3DECL(bool) PDMR3CritSectYield(PPDMCRITSECT pCritSect); +VMMR3DECL(const char *) PDMR3CritSectName(PCPDMCRITSECT pCritSect); +VMMR3DECL(int) PDMR3CritSectScheduleExitEvent(PPDMCRITSECT pCritSect, RTSEMEVENT EventToSignal); +VMMR3DECL(int) PDMR3CritSectDelete(PPDMCRITSECT pCritSect); + VMMDECL(int) PDMCritSectEnter(PPDMCRITSECT pCritSect, int rcBusy); VMMDECL(int) PDMCritSectEnterDebug(PPDMCRITSECT pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL); VMMDECL(int) PDMCritSectTryEnter(PPDMCRITSECT pCritSect); VMMDECL(int) PDMCritSectTryEnterDebug(PPDMCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL); -VMMR3DECL(int) PDMR3CritSectEnterEx(PPDMCRITSECT pCritSect, bool fCallRing3); VMMDECL(int) PDMCritSectLeave(PPDMCRITSECT pCritSect); + VMMDECL(bool) PDMCritSectIsOwner(PCPDMCRITSECT pCritSect); VMMDECL(bool) PDMCritSectIsOwnerEx(PCPDMCRITSECT pCritSect, PVMCPU pVCpu); VMMDECL(bool) PDMCritSectIsInitialized(PCPDMCRITSECT pCritSect); VMMDECL(bool) PDMCritSectHasWaiters(PCPDMCRITSECT pCritSect); VMMDECL(uint32_t) PDMCritSectGetRecursion(PCPDMCRITSECT pCritSect); -VMMR3DECL(bool) PDMR3CritSectYield(PPDMCRITSECT pCritSect); -VMMR3DECL(const char *) PDMR3CritSectName(PCPDMCRITSECT pCritSect); -VMMR3DECL(int) PDMR3CritSectScheduleExitEvent(PPDMCRITSECT pCritSect, RTSEMEVENT EventToSignal); -VMMR3DECL(int) PDMR3CritSectDelete(PPDMCRITSECT pCritSect); -VMMDECL(int) PDMR3CritSectTerm(PVM pVM); -VMMDECL(void) PDMCritSectFF(PVMCPU pVCpu); -VMMR3DECL(uint32_t) PDMR3CritSectCountOwned(PVM pVM, char *pszNames, size_t cbNames); -VMMR3DECL(void) PDMR3CritSectLeaveAll(PVM pVM); VMMR3DECL(PPDMCRITSECT) PDMR3CritSectGetNop(PVM pVM); VMMR3DECL(R0PTRTYPE(PPDMCRITSECT)) PDMR3CritSectGetNopR0(PVM pVM); diff --git a/include/VBox/vmm/pdmcritsectrw.h b/include/VBox/vmm/pdmcritsectrw.h new file mode 100644 index 00000000..9c922017 --- /dev/null +++ b/include/VBox/vmm/pdmcritsectrw.h @@ -0,0 +1,97 @@ +/** @file + * PDM - Pluggable Device Manager, Read/Write Critical Section. + */ + +/* + * Copyright (C) 2006-2013 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL) only, as it comes in the "COPYING.CDDL" file of the + * VirtualBox OSE distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + */ + +#ifndef ___VBox_vmm_pdmcritsectrw_h +#define ___VBox_vmm_pdmcritsectrw_h + +#include <VBox/types.h> + + +RT_C_DECLS_BEGIN + +/** @defgroup grp_pdm_critsectrw The PDM Read/Write Critical Section API + * @ingroup grp_pdm + * @{ + */ + +/** + * A PDM read/write critical section. + * Initialize using PDMDRVHLP::pfnCritSectRwInit(). + */ +typedef union PDMCRITSECTRW +{ + /** Padding. */ + uint8_t padding[HC_ARCH_BITS == 32 ? 0xc0 : 0x100]; +#ifdef PDMCRITSECTRWINT_DECLARED + /** The internal structure (not normally visible). */ + struct PDMCRITSECTRWINT s; +#endif +} PDMCRITSECTRW; + +VMMR3DECL(int) PDMR3CritSectRwInit(PVM pVM, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, ...); +VMMR3DECL(int) PDMR3CritSectRwDelete(PPDMCRITSECTRW pCritSect); +VMMR3DECL(const char *) PDMR3CritSectRwName(PCPDMCRITSECTRW pCritSect); +VMMR3DECL(int) PDMR3CritSectRwEnterSharedEx(PPDMCRITSECTRW pThis, bool fCallRing3); +VMMR3DECL(int) PDMR3CritSectRwEnterExclEx(PPDMCRITSECTRW pThis, bool fCallRing3); + +VMMDECL(int) PDMCritSectRwEnterShared(PPDMCRITSECTRW pCritSect, int rcBusy); +VMMDECL(int) PDMCritSectRwEnterSharedDebug(PPDMCRITSECTRW pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL); +VMMDECL(int) PDMCritSectRwTryEnterShared(PPDMCRITSECTRW pCritSect); +VMMDECL(int) PDMCritSectRwTryEnterSharedDebug(PPDMCRITSECTRW pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL); +VMMDECL(int) PDMCritSectRwLeaveShared(PPDMCRITSECTRW pCritSect); +VMMDECL(int) PDMCritSectRwEnterExcl(PPDMCRITSECTRW pCritSect, int rcBusy); +VMMDECL(int) PDMCritSectRwEnterExclDebug(PPDMCRITSECTRW pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL); +VMMDECL(int) PDMCritSectRwTryEnterExcl(PPDMCRITSECTRW pCritSect); +VMMDECL(int) PDMCritSectRwTryEnterExclDebug(PPDMCRITSECTRW pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL); +VMMDECL(int) PDMCritSectRwLeaveExcl(PPDMCRITSECTRW pCritSect); + +VMMDECL(bool) PDMCritSectRwIsWriteOwner(PPDMCRITSECTRW pCritSect); +VMMDECL(bool) PDMCritSectRwIsReadOwner(PPDMCRITSECTRW pCritSect, bool fWannaHear); +VMMDECL(uint32_t) PDMCritSectRwGetWriteRecursion(PPDMCRITSECTRW pCritSect); +VMMDECL(uint32_t) PDMCritSectRwGetWriterReadRecursion(PPDMCRITSECTRW pCritSect); +VMMDECL(uint32_t) PDMCritSectRwGetReadCount(PPDMCRITSECTRW pCritSect); +VMMDECL(bool) PDMCritSectRwIsInitialized(PCPDMCRITSECTRW pCritSect); + +/* Lock strict build: Remap the three enter calls to the debug versions. */ +#ifdef VBOX_STRICT +# ifdef ___iprt_asm_h +# define PDMCritSectRwEnterExcl(pCritSect, rcBusy) PDMCritSectRwEnterExclDebug(pCritSect, rcBusy, (uintptr_t)ASMReturnAddress(), RT_SRC_POS) +# define PDMCritSectRwTryEnterExcl(pCritSect) PDMCritSectRwTryEnterExclDebug(pCritSect, (uintptr_t)ASMReturnAddress(), RT_SRC_POS) +# define PDMCritSectRwEnterShared(pCritSect, rcBusy) PDMCritSectRwEnterSharedDebug(pCritSect, rcBusy, (uintptr_t)ASMReturnAddress(), RT_SRC_POS) +# define PDMCritSectRwTryEnterShared(pCritSect) PDMCritSectRwTryEnterSharedDebug(pCritSect, (uintptr_t)ASMReturnAddress(), RT_SRC_POS) +# else +# define PDMCritSectRwEnterExcl(pCritSect, rcBusy) PDMCritSectRwEnterExclDebug(pCritSect, rcBusy, 0, RT_SRC_POS) +# define PDMCritSectRwTryEnterExcl(pCritSect) PDMCritSectRwTryEnterExclDebug(pCritSect, 0, RT_SRC_POS) +# define PDMCritSectRwEnterShared(pCritSect, rcBusy) PDMCritSectRwEnterSharedDebug(pCritSect, rcBusy, 0, RT_SRC_POS) +# define PDMCritSectRwTryEnterShared(pCritSect) PDMCritSectRwTryEnterSharedDebug(pCritSect, 0, RT_SRC_POS) +# endif +#endif + +/** @} */ + +RT_C_DECLS_END + +#endif + diff --git a/include/VBox/vmm/pdmdev.h b/include/VBox/vmm/pdmdev.h index 892ed590..7a964b74 100644 --- a/include/VBox/vmm/pdmdev.h +++ b/include/VBox/vmm/pdmdev.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2011 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -39,6 +39,7 @@ #include <VBox/vmm/dbgf.h> #include <VBox/err.h> #include <VBox/pci.h> +#include <VBox/sup.h> #include <iprt/stdarg.h> @@ -108,30 +109,6 @@ typedef DECLCALLBACK(void) FNPDMDEVRELOCATE(PPDMDEVINS pDevIns, RTGCINTPTR offDe typedef FNPDMDEVRELOCATE *PFNPDMDEVRELOCATE; /** - * Device I/O Control interface. - * - * This is used by external components, such as the COM interface, to - * communicate with devices using a class wide interface or a device - * specific interface. - * - * @returns VBox status code. - * @param pDevIns Pointer to the device instance. - * @param uFunction Function to perform. - * @param pvIn Pointer to input data. - * @param cbIn Size of input data. - * @param pvOut Pointer to output data. - * @param cbOut Size of output data. - * @param pcbOut Where to store the actual size of the output data. - * - * @remarks Not used. - */ -typedef DECLCALLBACK(int) FNPDMDEVIOCTL(PPDMDEVINS pDevIns, uint32_t uFunction, - void *pvIn, uint32_t cbIn, - void *pvOut, uint32_t cbOut, PRTUINT pcbOut); -/** Pointer to a FNPDMDEVIOCTL() function. */ -typedef FNPDMDEVIOCTL *PFNPDMDEVIOCTL; - -/** * Power On notification. * * @returns VBox status. @@ -185,7 +162,7 @@ typedef FNPDMDEVRESUME *PFNPDMDEVRESUME; * * This is only called when the VMR3PowerOff call is made on a running VM. This * means that there is no notification if the VM was suspended before being - * powered of. There will also be no callback when hot plugging devices. + * powered off. There will also be no callback when hot plugging devices. * * @param pDevIns The device instance data. * @thread EMT(0) @@ -264,6 +241,21 @@ typedef DECLCALLBACK(int) FNPDMDEVINITCOMPLETE(PPDMDEVINS pDevIns); typedef FNPDMDEVINITCOMPLETE *PFNPDMDEVINITCOMPLETE; +/** + * The context of a pfnMemSetup call. + */ +typedef enum PDMDEVMEMSETUPCTX +{ + /** Invalid zero value. */ + PDMDEVMEMSETUPCTX_INVALID = 0, + /** After construction. */ + PDMDEVMEMSETUPCTX_AFTER_CONSTRUCTION, + /** After reset. */ + PDMDEVMEMSETUPCTX_AFTER_RESET, + /** Type size hack. */ + PDMDEVMEMSETUPCTX_32BIT_HACK = 0x7fffffff +} PDMDEVMEMSETUPCTX; + /** * PDM Device Registration Structure. @@ -304,9 +296,16 @@ typedef struct PDMDEVREG /** Relocation command - optional. * Critical section NOT entered. */ PFNPDMDEVRELOCATE pfnRelocate; - /** I/O Control interface - optional. - * Not used. */ - PFNPDMDEVIOCTL pfnIOCtl; + + /** + * Memory setup callback. + * + * @param pDevIns The device instance data. + * @param enmCtx Indicates the context of the call. + * @remarks The critical section is entered prior to calling this method. + */ + DECLR3CALLBACKMEMBER(void, pfnMemSetup, (PPDMDEVINS pDevIns, PDMDEVMEMSETUPCTX enmCtx)); + /** Power on notification - optional. * Critical section is entered. */ PFNPDMDEVPOWERON pfnPowerOn; @@ -345,7 +344,7 @@ typedef PDMDEVREG *PPDMDEVREG; typedef PDMDEVREG const *PCPDMDEVREG; /** Current DEVREG version number. */ -#define PDM_DEVREG_VERSION PDM_VERSION_MAKE(0xffff, 1, 0) +#define PDM_DEVREG_VERSION PDM_VERSION_MAKE(0xffff, 2, 0) /** PDM Device Flags. * @{ */ @@ -503,6 +502,7 @@ typedef struct PDMPCIBUSREG * @param pszName Pointer to device name (permanent, readonly). For debugging, not unique. * @param iDev The device number ((dev << 3) | function) the device should have on the bus. * If negative, the pci bus device will assign one. + * @remarks Caller enters the PDM critical section. */ DECLR3CALLBACKMEMBER(int, pfnRegisterR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, const char *pszName, int iDev)); @@ -513,6 +513,7 @@ typedef struct PDMPCIBUSREG * @param pDevIns Device instance of the PCI Bus. * @param pPciDev The PCI device structure. * @param pMsiReg MSI registration structure + * @remarks Caller enters the PDM critical section. */ DECLR3CALLBACKMEMBER(int, pfnRegisterMsiR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PPDMMSIREG pMsiReg)); @@ -526,6 +527,7 @@ typedef struct PDMPCIBUSREG * @param cbRegion Size of the region. * @param iType PCI_ADDRESS_SPACE_MEM, PCI_ADDRESS_SPACE_IO or PCI_ADDRESS_SPACE_MEM_PREFETCH. * @param pfnCallback Callback for doing the mapping. + * @remarks Caller enters the PDM critical section. */ DECLR3CALLBACKMEMBER(int, pfnIORegionRegisterR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback)); @@ -542,6 +544,7 @@ typedef struct PDMPCIBUSREG * @param pfnWriteOld Pointer to function pointer which will receive the old (default) * PCI config write function. This way, user can decide when (and if) * to call default PCI config write function. Can be NULL. + * @remarks Caller enters the PDM critical section. * @thread EMT */ DECLR3CALLBACKMEMBER(void, pfnSetConfigCallbacksR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld, @@ -555,36 +558,18 @@ typedef struct PDMPCIBUSREG * @param iIrq IRQ number to set. * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines. * @param uTagSrc The IRQ tag and source (for tracing). + * @remarks Caller enters the PDM critical section. */ DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel, uint32_t uTagSrc)); /** - * Saves a state of the PCI device. - * - * @returns VBox status code. - * @param pDevIns Device instance of the PCI Bus. - * @param pPciDev Pointer to PCI device. - * @param pSSMHandle The handle to save the state to. - */ - DECLR3CALLBACKMEMBER(int, pfnSaveExecR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSMHandle)); - - /** - * Loads a saved PCI device state. - * - * @returns VBox status code. - * @param pDevIns Device instance of the PCI Bus. - * @param pPciDev Pointer to PCI device. - * @param pSSMHandle The handle to the saved state. - */ - DECLR3CALLBACKMEMBER(int, pfnLoadExecR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSMHandle)); - - /** * Called to perform the job of the bios. * This is only called for the first PCI Bus - it is expected to * service all the PCI buses. * * @returns VBox status. * @param pDevIns Device instance of the first bus. + * @remarks Caller enters the PDM critical section. */ DECLR3CALLBACKMEMBER(int, pfnFakePCIBIOSR3,(PPDMDEVINS pDevIns)); @@ -599,7 +584,7 @@ typedef struct PDMPCIBUSREG typedef PDMPCIBUSREG *PPDMPCIBUSREG; /** Current PDMPCIBUSREG version number. */ -#define PDM_PCIBUSREG_VERSION PDM_VERSION_MAKE(0xfffe, 3, 0) +#define PDM_PCIBUSREG_VERSION PDM_VERSION_MAKE(0xfffe, 4, 0) /** * PCI Bus RC helpers. @@ -858,6 +843,7 @@ typedef struct PDMPICREG * @param iIrq IRQ number to set. * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines. * @param uTagSrc The IRQ tag and source (for tracing). + * @remarks Caller enters the PDM critical section. */ DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)); @@ -867,6 +853,7 @@ typedef struct PDMPICREG * @returns Pending interrupt number. * @param pDevIns Device instance of the PIC. * @param puTagSrc Where to return the IRQ tag and source. + * @remarks Caller enters the PDM critical section. */ DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, uint32_t *puTagSrc)); @@ -1077,40 +1064,52 @@ typedef struct PDMAPICREG * * @returns Pending interrupt number. * @param pDevIns Device instance of the APIC. + * @param idCpu The VCPU Id. * @param puTagSrc Where to return the tag source. + * @remarks Caller enters the PDM critical section */ - DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, uint32_t *puTagSrc)); + DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t *puTagSrc)); /** * Check if the APIC has a pending interrupt/if a TPR change would active one * * @returns Pending interrupt yes/no * @param pDevIns Device instance of the APIC. + * @param idCpu The VCPU Id. + * @param pu8PendingIrq Where to store the highest priority pending IRQ + * (optional, can be NULL). + * @remarks Unlike the other callbacks, the PDM lock may not always be entered + * prior to calling this method. */ - DECLR3CALLBACKMEMBER(bool, pfnHasPendingIrqR3,(PPDMDEVINS pDevIns)); + DECLR3CALLBACKMEMBER(bool, pfnHasPendingIrqR3,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint8_t *pu8PendingIrq)); /** * Set the APIC base. * * @param pDevIns Device instance of the APIC. + * @param idCpu The VCPU Id. * @param u64Base The new base. + * @remarks Caller enters the PDM critical section. */ - DECLR3CALLBACKMEMBER(void, pfnSetBaseR3,(PPDMDEVINS pDevIns, uint64_t u64Base)); + DECLR3CALLBACKMEMBER(void, pfnSetBaseR3,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint64_t u64Base)); /** * Get the APIC base. * * @returns Current base. * @param pDevIns Device instance of the APIC. + * @param idCpu The VCPU Id. + * @remarks Caller enters the PDM critical section. */ - DECLR3CALLBACKMEMBER(uint64_t, pfnGetBaseR3,(PPDMDEVINS pDevIns)); + DECLR3CALLBACKMEMBER(uint64_t, pfnGetBaseR3,(PPDMDEVINS pDevIns, VMCPUID idCpu)); /** * Set the TPR (task priority register). * * @param pDevIns Device instance of the APIC. - * @param idCpu VCPU id + * @param idCpu The VCPU id. * @param u8TPR The new TPR. + * @remarks Caller enters the PDM critical section. */ DECLR3CALLBACKMEMBER(void, pfnSetTPRR3,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint8_t u8TPR)); @@ -1120,6 +1119,7 @@ typedef struct PDMAPICREG * @returns The current TPR. * @param pDevIns Device instance of the APIC. * @param idCpu VCPU id + * @remarks Caller enters the PDM critical section. */ DECLR3CALLBACKMEMBER(uint8_t, pfnGetTPRR3,(PPDMDEVINS pDevIns, VMCPUID idCpu)); @@ -1169,6 +1169,7 @@ typedef struct PDMAPICREG * @param u8Polarity See APIC implementation. * @param u8TriggerMode See APIC implementation. * @param uTagSrc The IRQ tag and source (for tracing). + * @remarks Caller enters the PDM critical section */ DECLR3CALLBACKMEMBER(int, pfnBusDeliverR3,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode, uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc)); @@ -1184,6 +1185,7 @@ typedef struct PDMAPICREG * @param u8Pin Local pin number (0 or 1 for current CPUs). * @param u8Level The level. * @param uTagSrc The IRQ tag and source (for tracing). + * @remarks Caller enters the PDM critical section */ DECLR3CALLBACKMEMBER(int, pfnLocalInterruptR3,(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level)); @@ -1572,6 +1574,7 @@ typedef struct PDMIOAPICREG * @param iIrq IRQ number to set. * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines. * @param uTagSrc The IRQ tag and source (for tracing). + * @remarks Caller enters the PDM critical section */ DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)); @@ -1588,6 +1591,7 @@ typedef struct PDMIOAPICREG * @param GCPhys Request address. * @param uValue Request value. * @param uTagSrc The IRQ tag and source (for tracing). + * @remarks Caller enters the PDM critical section */ DECLR3CALLBACKMEMBER(void, pfnSendMsiR3,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc)); @@ -2017,11 +2021,12 @@ typedef R3PTRTYPE(const PDMPCIRAWHLPR3 *) PCPDMPCIRAWHLPR3; * DMA Transfer Handler. * * @returns Number of bytes transferred. - * @param pDevIns Device instance of the DMA. - * @param pvUser User pointer. - * @param uChannel Channel number. - * @param off DMA position. - * @param cb Block size. + * @param pDevIns Device instance of the DMA. + * @param pvUser User pointer. + * @param uChannel Channel number. + * @param off DMA position. + * @param cb Block size. + * @remarks The device lock is not taken, however, the DMA device lock is held. */ typedef DECLCALLBACK(uint32_t) FNDMATRANSFERHANDLER(PPDMDEVINS pDevIns, void *pvUser, unsigned uChannel, uint32_t off, uint32_t cb); /** Pointer to a FNDMATRANSFERHANDLER(). */ @@ -2040,6 +2045,7 @@ typedef struct PDMDMAREG * * @returns A more work indiciator. I.e. 'true' if there is more to be done, and 'false' if all is done. * @param pDevIns Device instance of the DMAC. + * @remarks No locks held, called on EMT(0) as a form of serialization. */ DECLR3CALLBACKMEMBER(bool, pfnRun,(PPDMDEVINS pDevIns)); @@ -2050,6 +2056,7 @@ typedef struct PDMDMAREG * @param uChannel Channel number. * @param pfnTransferHandler Device specific transfer function. * @param pvUSer User pointer to be passed to the callback. + * @remarks No locks held, called on an EMT. */ DECLR3CALLBACKMEMBER(void, pfnRegister,(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser)); @@ -2061,6 +2068,7 @@ typedef struct PDMDMAREG * @param pvBuffer Pointer to target buffer. * @param off DMA position. * @param cbBlock Block size. + * @remarks No locks held, called on an EMT. */ DECLR3CALLBACKMEMBER(uint32_t, pfnReadMemory,(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock)); @@ -2072,6 +2080,7 @@ typedef struct PDMDMAREG * @param pvBuffer Memory to write. * @param off DMA position. * @param cbBlock Block size. + * @remarks No locks held, called on an EMT. */ DECLR3CALLBACKMEMBER(uint32_t, pfnWriteMemory,(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock)); @@ -2081,6 +2090,7 @@ typedef struct PDMDMAREG * @param pDevIns Device instance of the DMAC. * @param uChannel Channel number. * @param uLevel Level of the line. + * @remarks No locks held, called on an EMT. */ DECLR3CALLBACKMEMBER(void, pfnSetDREQ,(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel)); @@ -2090,6 +2100,7 @@ typedef struct PDMDMAREG * @returns Channel mode. * @param pDevIns Device instance of the DMAC. * @param uChannel Channel number. + * @remarks No locks held, called on an EMT. */ DECLR3CALLBACKMEMBER(uint8_t, pfnGetChannelMode,(PPDMDEVINS pDevIns, unsigned uChannel)); @@ -2140,6 +2151,7 @@ typedef struct PDMRTCREG * @param pDevIns Device instance of the RTC. * @param iReg The CMOS register index. * @param u8Value The CMOS register value. + * @remarks Caller enters the device critical section. */ DECLR3CALLBACKMEMBER(int, pfnWrite,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value)); @@ -2150,6 +2162,7 @@ typedef struct PDMRTCREG * @param pDevIns Device instance of the RTC. * @param iReg The CMOS register index. * @param pu8Value Where to store the CMOS register value. + * @remarks Caller enters the device critical section. */ DECLR3CALLBACKMEMBER(int, pfnRead,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value)); @@ -2160,7 +2173,7 @@ typedef PDMRTCREG *PPDMRTCREG; typedef const PDMRTCREG *PCPDMRTCREG; /** Current PDMRTCREG version number. */ -#define PDM_RTCREG_VERSION PDM_VERSION_MAKE(0xffe9, 1, 0) +#define PDM_RTCREG_VERSION PDM_VERSION_MAKE(0xffe9, 2, 0) /** @@ -2211,6 +2224,8 @@ typedef struct PDMDEVHLPR3 * @param pfnOutStr Pointer to function which is gonna handle string OUT operations. * @param pfnInStr Pointer to function which is gonna handle string IN operations. * @param pszDesc Pointer to description string. This must not be freed. + * @remarks Caller enters the device critical section prior to invoking the + * registered callback methods. */ DECLR3CALLBACKMEMBER(int, pfnIOPortRegister,(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTHCPTR pvUser, PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn, @@ -2235,6 +2250,8 @@ typedef struct PDMDEVHLPR3 * @param pszOutStr Name of the RC function which is gonna handle string OUT operations. * @param pszInStr Name of the RC function which is gonna handle string IN operations. * @param pszDesc Pointer to description string. This must not be freed. + * @remarks Caller enters the device critical section prior to invoking the + * registered callback methods. */ DECLR3CALLBACKMEMBER(int, pfnIOPortRegisterRC,(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTRCPTR pvUser, const char *pszOut, const char *pszIn, @@ -2256,6 +2273,8 @@ typedef struct PDMDEVHLPR3 * @param pszOutStr Name of the R0 function which is gonna handle string OUT operations. * @param pszInStr Name of the R0 function which is gonna handle string IN operations. * @param pszDesc Pointer to description string. This must not be freed. + * @remarks Caller enters the device critical section prior to invoking the + * registered callback methods. */ DECLR3CALLBACKMEMBER(int, pfnIOPortRegisterR0,(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTR0PTR pvUser, const char *pszOut, const char *pszIn, @@ -2290,6 +2309,8 @@ typedef struct PDMDEVHLPR3 * @param pfnFill Pointer to function which is gonna handle Fill/memset operations. (optional) * @param fFlags Flags, IOMMMIO_FLAGS_XXX. * @param pszDesc Pointer to description string. This must not be freed. + * @remarks Caller enters the device critical section prior to invoking the + * registered callback methods. */ DECLR3CALLBACKMEMBER(int, pfnMMIORegister,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTHCPTR pvUser, PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill, @@ -2310,6 +2331,8 @@ typedef struct PDMDEVHLPR3 * @param pszWrite Name of the RC function which is gonna handle Write operations. * @param pszRead Name of the RC function which is gonna handle Read operations. * @param pszFill Name of the RC function which is gonna handle Fill/memset operations. (optional) + * @remarks Caller enters the device critical section prior to invoking the + * registered callback methods. */ DECLR3CALLBACKMEMBER(int, pfnMMIORegisterRC,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTRCPTR pvUser, const char *pszWrite, const char *pszRead, const char *pszFill)); @@ -2330,6 +2353,8 @@ typedef struct PDMDEVHLPR3 * @param pszRead Name of the RC function which is gonna handle Read operations. * @param pszFill Name of the RC function which is gonna handle Fill/memset operations. (optional) * @param pszDesc Obsolete. NULL is fine. + * @remarks Caller enters the device critical section prior to invoking the + * registered callback methods. */ DECLR3CALLBACKMEMBER(int, pfnMMIORegisterR0,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTR0PTR pvUser, const char *pszWrite, const char *pszRead, const char *pszFill)); @@ -2512,6 +2537,8 @@ typedef struct PDMDEVHLPR3 * @param pfnLoadPrep Prepare load callback, optional. * @param pfnLoadExec Execute load callback, optional. * @param pfnLoadDone Done load callback, optional. + * @remarks Caller enters the device critical section prior to invoking the + * registered callback methods. */ DECLR3CALLBACKMEMBER(int, pfnSSMRegister,(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess, const char *pszBefore, PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote, @@ -2530,6 +2557,8 @@ typedef struct PDMDEVHLPR3 * @param pszDesc Pointer to description string which must stay around * until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()). * @param ppTimer Where to store the timer on success. + * @remarks Caller enters the device critical section prior to invoking the + * callback. */ DECLR3CALLBACKMEMBER(int, pfnTMTimerCreate,(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer)); @@ -2797,6 +2826,22 @@ typedef struct PDMDEVHLPR3 DECLR3CALLBACKMEMBER(int, pfnDBGFInfoRegister,(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler)); /** + * Registers a set of registers for a device. + * + * The @a pvUser argument of the getter and setter callbacks will be + * @a pDevIns. The register names will be prefixed by the device name followed + * immediately by the instance number. + * + * @returns VBox status code. + * @param pDevIns The device instance. + * @param paRegisters The register descriptors. + * + * @remarks The device critical section is NOT entered prior to working the + * callbacks registered via this helper! + */ + DECLR3CALLBACKMEMBER(int, pfnDBGFRegRegister,(PPDMDEVINS pDevIns, PCDBGFREGDESC paRegisters)); + + /** * Gets the trace buffer handle. * * This is used by the macros found in VBox/vmm/dbgftrace.h and is not @@ -2861,22 +2906,6 @@ typedef struct PDMDEVHLPR3 STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list args)); /** - * Reads data via bus mastering, if enabled. If no bus mastering is available, - * this function does nothing and returns VINF_PGM_PCI_PHYS_READ_BM_DISABLED. - * - * @return IPRT status code. - */ - DECLR3CALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)); - - /** - * Writes data via bus mastering, if enabled. If no bus mastering is available, - * this function does nothing and returns VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED. - * - * @return IPRT status code. - */ - DECLR3CALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)); - - /** * Registers the device with the default PCI bus. * * @returns VBox status code. @@ -2907,8 +2936,11 @@ typedef struct PDMDEVHLPR3 * @param cbRegion Size of the region. * @param enmType PCI_ADDRESS_SPACE_MEM, PCI_ADDRESS_SPACE_IO or PCI_ADDRESS_SPACE_MEM_PREFETCH. * @param pfnCallback Callback for doing the mapping. + * @remarks The callback will be invoked holding the PDM lock. The device lock + * is NOT take because that is very likely be a lock order violation. */ - DECLR3CALLBACKMEMBER(int, pfnPCIIORegionRegister,(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback)); + DECLR3CALLBACKMEMBER(int, pfnPCIIORegionRegister,(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, + PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback)); /** * Register PCI configuration space read/write callbacks. @@ -2924,12 +2956,40 @@ typedef struct PDMDEVHLPR3 * @param pfnWriteOld Pointer to function pointer which will receive the old (default) * PCI config write function. This way, user can decide when (and if) * to call default PCI config write function. Can be NULL. + * @remarks The callbacks will be invoked holding the PDM lock. The device lock + * is NOT take because that is very likely be a lock order violation. * @thread EMT */ DECLR3CALLBACKMEMBER(void, pfnPCISetConfigCallbacks,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld, PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld)); /** + * Bus master physical memory read. + * + * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_READ_BM_DISABLED, later maybe + * VERR_EM_MEMORY. The informational status shall NOT be propagated! + * @param pDevIns The device instance. + * @param GCPhys Physical address start reading from. + * @param pvBuf Where to put the read bits. + * @param cbRead How many bytes to read. + * @thread Any thread, but the call may involve the emulation thread. + */ + DECLR3CALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)); + + /** + * Bus master physical memory write. + * + * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_WRITE_BM_DISABLED, later maybe + * VERR_EM_MEMORY. The informational status shall NOT be propagated! + * @param pDevIns The device instance. + * @param GCPhys Physical address to write to. + * @param pvBuf What to write. + * @param cbWrite How many bytes to write. + * @thread Any thread, but the call may involve the emulation thread. + */ + DECLR3CALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)); + + /** * Set the IRQ for a PCI device. * * @param pDevIns The device instance. @@ -2985,7 +3045,8 @@ typedef struct PDMDEVHLPR3 * @param pszDesc Pointer to a string describing the LUN. This string must remain valid * for the live of the device instance. */ - DECLR3CALLBACKMEMBER(int, pfnDriverAttach,(PPDMDEVINS pDevIns, uint32_t iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc)); + DECLR3CALLBACKMEMBER(int, pfnDriverAttach,(PPDMDEVINS pDevIns, uint32_t iLun, PPDMIBASE pBaseInterface, + PPDMIBASE *ppBaseInterface, const char *pszDesc)); /** * Create a queue. @@ -3002,6 +3063,9 @@ typedef struct PDMDEVHLPR3 * appended automatically. * @param ppQueue Where to store the queue handle on success. * @thread The emulation thread. + * @remarks The device critical section will NOT be entered before calling the + * callback. No locks will be held, but for now it's safe to assume + * that only one EMT will do queue callbacks at any one time. */ DECLR3CALLBACKMEMBER(int, pfnQueueCreate,(PPDMDEVINS pDevIns, size_t cbItem, uint32_t cItems, uint32_t cMilliesInterval, PFNPDMQUEUEDEV pfnCallback, bool fRZEnabled, const char *pszName, PPDMQUEUE *ppQueue)); @@ -3075,6 +3139,8 @@ typedef struct PDMDEVHLPR3 * @param cbStack See RTThreadCreate. * @param enmType See RTThreadCreate. * @param pszName See RTThreadCreate. + * @remarks The device critical section will NOT be entered prior to invoking + * the function pointers. */ DECLR3CALLBACKMEMBER(int, pfnThreadCreate,(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread, PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)); @@ -3089,6 +3155,8 @@ typedef struct PDMDEVHLPR3 * @param pDevIns The device instance. * @param pfnAsyncNotify The callback. * @thread EMT(0) + * @remarks The caller will enter the device critical section prior to invoking + * the callback. */ DECLR3CALLBACKMEMBER(int, pfnSetAsyncNotification, (PPDMDEVINS pDevIns, PFNPDMDEVASYNCNOTIFY pfnAsyncNotify)); @@ -3372,6 +3440,25 @@ typedef struct PDMDEVHLPR3 */ DECLR3CALLBACKMEMBER(int, pfnCallR0,(PPDMDEVINS pDevIns, uint32_t uOperation, uint64_t u64Arg)); + /** + * Gets the reason for the most recent VM suspend. + * + * @returns The suspend reason. VMSUSPENDREASON_INVALID is returned if no + * suspend has been made or if the pDevIns is invalid. + * @param pDevIns The device instance. + */ + DECLR3CALLBACKMEMBER(VMSUSPENDREASON, pfnVMGetSuspendReason,(PPDMDEVINS pDevIns)); + + /** + * Gets the reason for the most recent VM resume. + * + * @returns The resume reason. VMRESUMEREASON_INVALID is returned if no + * resume has been made or if the pDevIns is invalid. + * @param pDevIns The device instance. + */ + DECLR3CALLBACKMEMBER(VMRESUMEREASON, pfnVMGetResumeReason,(PPDMDEVINS pDevIns)); + + /** Space reserved for future members. * @{ */ DECLR3CALLBACKMEMBER(void, pfnReserved1,(void)); @@ -3381,9 +3468,9 @@ typedef struct PDMDEVHLPR3 DECLR3CALLBACKMEMBER(void, pfnReserved5,(void)); DECLR3CALLBACKMEMBER(void, pfnReserved6,(void)); DECLR3CALLBACKMEMBER(void, pfnReserved7,(void)); - DECLR3CALLBACKMEMBER(void, pfnReserved8,(void)); - DECLR3CALLBACKMEMBER(void, pfnReserved9,(void)); - DECLR3CALLBACKMEMBER(void, pfnReserved10,(void)); + /*DECLR3CALLBACKMEMBER(void, pfnReserved8,(void)); + DECLR3CALLBACKMEMBER(void, pfnReserved9,(void));*/ + /*DECLR3CALLBACKMEMBER(void, pfnReserved10,(void));*/ /** @} */ @@ -3394,8 +3481,17 @@ typedef struct PDMDEVHLPR3 * * @{ */ + /** - * Gets the VM handle. Restricted API. + * Gets the user mode VM handle. Restricted API. + * + * @returns User mode VM Handle. + * @param pDevIns The device instance. + */ + DECLR3CALLBACKMEMBER(PUVM, pfnGetUVM,(PPDMDEVINS pDevIns)); + + /** + * Gets the global VM handle. Restricted API. * * @returns VM Handle. * @param pDevIns The device instance. @@ -3527,6 +3623,16 @@ typedef struct PDMDEVHLPR3 */ DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetNano,(PPDMDEVINS pDevIns)); + /** + * Gets the support driver session. + * + * This is intended for working with the semaphore API. + * + * @returns Support driver session handle. + * @param pDrvIns The driver instance. + */ + DECLR3CALLBACKMEMBER(PSUPDRVSESSION, pfnGetSupDrvSession,(PPDMDEVINS pDevIns)); + /** @} */ /** Just a safety precaution. (PDM_DEVHLPR3_VERSION) */ @@ -3539,7 +3645,7 @@ typedef R3PTRTYPE(struct PDMDEVHLPR3 *) PPDMDEVHLPR3; typedef R3PTRTYPE(const struct PDMDEVHLPR3 *) PCPDMDEVHLPR3; /** Current PDMDEVHLPR3 version number. */ -#define PDM_DEVHLPR3_VERSION PDM_VERSION_MAKE(0xffe7, 9, 0) +#define PDM_DEVHLPR3_VERSION PDM_VERSION_MAKE(0xffe7, 12, 1) /** @@ -3551,20 +3657,30 @@ typedef struct PDMDEVHLPRC uint32_t u32Version; /** - * Reads data via bus mastering, if enabled. If no bus mastering is available, - * this function does nothing and returns VINF_PGM_PCI_PHYS_READ_BM_DISABLED. + * Bus master physical memory read. * - * @return IPRT status code. + * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_READ_BM_DISABLED, later maybe + * VERR_EM_MEMORY. The informational status shall NOT be propagated! + * @param pDevIns The device instance. + * @param GCPhys Physical address start reading from. + * @param pvBuf Where to put the read bits. + * @param cbRead How many bytes to read. + * @thread Any thread, but the call may involve the emulation thread. */ - DECLRCCALLBACKMEMBER(int, pfnPCIDevPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)); + DECLRCCALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)); /** - * Writes data via bus mastering, if enabled. If no bus mastering is available, - * this function does nothing and returns VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED. + * Bus master physical memory write. * - * @return IPRT status code. + * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_WRITE_BM_DISABLED, later maybe + * VERR_EM_MEMORY. The informational status shall NOT be propagated! + * @param pDevIns The device instance. + * @param GCPhys Physical address to write to. + * @param pvBuf What to write. + * @param cbWrite How many bytes to write. + * @thread Any thread, but the call may involve the emulation thread. */ - DECLRCCALLBACKMEMBER(int, pfnPCIDevPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)); + DECLRCCALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)); /** * Set the IRQ for a PCI device. @@ -3746,7 +3862,7 @@ typedef RCPTRTYPE(struct PDMDEVHLPRC *) PPDMDEVHLPRC; typedef RCPTRTYPE(const struct PDMDEVHLPRC *) PCPDMDEVHLPRC; /** Current PDMDEVHLP version number. */ -#define PDM_DEVHLPRC_VERSION PDM_VERSION_MAKE(0xffe6, 3, 0) +#define PDM_DEVHLPRC_VERSION PDM_VERSION_MAKE(0xffe6, 3, 1) /** @@ -3758,18 +3874,28 @@ typedef struct PDMDEVHLPR0 uint32_t u32Version; /** - * Reads data via bus mastering, if enabled. If no bus mastering is available, - * this function does nothing and returns VINF_PGM_PCI_PHYS_READ_BM_DISABLED. + * Bus master physical memory read. * - * @return IPRT status code. + * @returns VINF_SUCCESS or VERR_PDM_NOT_PCI_BUS_MASTER, later maybe + * VERR_EM_MEMORY. + * @param pDevIns The device instance. + * @param GCPhys Physical address start reading from. + * @param pvBuf Where to put the read bits. + * @param cbRead How many bytes to read. + * @thread Any thread, but the call may involve the emulation thread. */ DECLR0CALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)); /** - * Writes data via bus mastering, if enabled. If no bus mastering is available, - * this function does nothing and returns VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED. + * Bus master physical memory write. * - * @return IPRT status code. + * @returns VINF_SUCCESS or VERR_PDM_NOT_PCI_BUS_MASTER, later maybe + * VERR_EM_MEMORY. + * @param pDevIns The device instance. + * @param GCPhys Physical address to write to. + * @param pvBuf What to write. + * @param cbWrite How many bytes to write. + * @thread Any thread, but the call may involve the emulation thread. */ DECLR0CALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)); @@ -3961,7 +4087,7 @@ typedef R0PTRTYPE(struct PDMDEVHLPR0 *) PPDMDEVHLPR0; typedef R0PTRTYPE(const struct PDMDEVHLPR0 *) PCPDMDEVHLPR0; /** Current PDMDEVHLP version number. */ -#define PDM_DEVHLPR0_VERSION PDM_VERSION_MAKE(0xffe5, 3, 0) +#define PDM_DEVHLPR0_VERSION PDM_VERSION_MAKE(0xffe5, 3, 1) @@ -4621,6 +4747,14 @@ DECLINLINE(int) PDMDevHlpDBGFInfoRegister(PPDMDEVINS pDevIns, const char *pszNam } /** + * @copydoc PDMDEVHLPR3::pfnDBGFRegRegister + */ +DECLINLINE(int) PDMDevHlpDBGFRegRegister(PPDMDEVINS pDevIns, PCDBGFREGDESC paRegisters) +{ + return pDevIns->pHlpR3->pfnDBGFRegRegister(pDevIns, paRegisters); +} + +/** * @copydoc PDMDEVHLPR3::pfnSTAMRegister */ DECLINLINE(void) PDMDevHlpSTAMRegister(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc) @@ -4673,56 +4807,24 @@ DECLINLINE(void) PDMDevHlpPCISetConfigCallbacks(PPDMDEVINS pDevIns, PPCIDEVICE p pDevIns->pHlpR3->pfnPCISetConfigCallbacks(pDevIns, pPciDev, pfnRead, ppfnReadOld, pfnWrite, ppfnWriteOld); } +#endif /* IN_RING3 */ + /** - * Reads data via bus mastering, if enabled. If no bus mastering is available, - * this function does nothing and returns VINF_PGM_PCI_PHYS_READ_BM_DISABLED. - * - * @return IPRT status code. + * @copydoc PDMDEVHLPR3::pfnPCIPhysRead */ -DECLINLINE(int) PDMDevHlpPCIDevPhysRead(PPCIDEVICE pPciDev, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead) +DECLINLINE(int) PDMDevHlpPCIPhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead) { - AssertPtrReturn(pPciDev, VERR_INVALID_POINTER); - AssertPtrReturn(pvBuf, VERR_INVALID_POINTER); - AssertReturn(cbRead, VERR_INVALID_PARAMETER); - - if (!PCIDevIsBusmaster(pPciDev)) - { -#ifdef DEBUG - Log2(("%s: %RU16:%RU16: No bus master (anymore), skipping read %p (%z)\n", __FUNCTION__, - PCIDevGetVendorId(pPciDev), PCIDevGetDeviceId(pPciDev), pvBuf, cbRead)); -#endif - return VINF_PDM_PCI_PHYS_READ_BM_DISABLED; - } - - return PDMDevHlpPhysRead(pPciDev->pDevIns, GCPhys, pvBuf, cbRead); + return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysRead(pDevIns, GCPhys, pvBuf, cbRead); } /** - * Writes data via bus mastering, if enabled. If no bus mastering is available, - * this function does nothing and returns VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED. - * - * @return IPRT status code. + * @copydoc PDMDEVHLPR3::pfnPCIPhysWrite */ -DECLINLINE(int) PDMDevHlpPCIDevPhysWrite(PPCIDEVICE pPciDev, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite) +DECLINLINE(int) PDMDevHlpPCIPhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite) { - AssertPtrReturn(pPciDev, VERR_INVALID_POINTER); - AssertPtrReturn(pvBuf, VERR_INVALID_POINTER); - AssertReturn(cbWrite, VERR_INVALID_PARAMETER); - - if (!PCIDevIsBusmaster(pPciDev)) - { -#ifdef DEBUG - Log2(("%s: %RU16:%RU16: No bus master (anymore), skipping write %p (%z)\n", __FUNCTION__, - PCIDevGetVendorId(pPciDev), PCIDevGetDeviceId(pPciDev), pvBuf, cbWrite)); -#endif - return VINF_PDM_PCI_PHYS_WRITE_BM_DISABLED; - } - - return PDMDevHlpPhysWrite(pPciDev->pDevIns, GCPhys, pvBuf, cbWrite); + return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysWrite(pDevIns, GCPhys, pvBuf, cbWrite); } -#endif /* IN_RING3 */ - /** * @copydoc PDMDEVHLPR3::pfnPCISetIrq */ @@ -4999,6 +5101,30 @@ DECLINLINE(int) PDMDevHlpCallR0(PPDMDEVINS pDevIns, uint32_t uOperation, uint64_ return pDevIns->pHlpR3->pfnCallR0(pDevIns, uOperation, u64Arg); } +/** + * @copydoc PDMDEVHLP::pfnVMGetSuspendReason + */ +DECLINLINE(VMSUSPENDREASON) PDMDevHlpVMGetSuspendReason(PPDMDEVINS pDevIns) +{ + return pDevIns->pHlpR3->pfnVMGetSuspendReason(pDevIns); +} + +/** + * @copydoc PDMDEVHLP::pfnVMGetResumeReason + */ +DECLINLINE(VMRESUMEREASON) PDMDevHlpVMGetResumeReason(PPDMDEVINS pDevIns) +{ + return pDevIns->pHlpR3->pfnVMGetResumeReason(pDevIns); +} + +/** + * @copydoc PDMDEVHLPR3::pfnGetUVM + */ +DECLINLINE(PUVM) PDMDevHlpGetUVM(PPDMDEVINS pDevIns) +{ + return pDevIns->CTX_SUFF(pHlp)->pfnGetUVM(pDevIns); +} + #endif /* IN_RING3 */ /** @@ -5111,6 +5237,14 @@ DECLINLINE(void) PDMDevHlpGetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf, uint32_t pDevIns->pHlpR3->pfnGetCpuId(pDevIns, iLeaf, pEax, pEbx, pEcx, pEdx); } +/** + * @copydoc PDMDEVHLPR3::pfnGetSupDrvSession + */ +DECLINLINE(PSUPDRVSESSION) PDMDevHlpGetSupDrvSession(PPDMDEVINS pDevIns) +{ + return pDevIns->pHlpR3->pfnGetSupDrvSession(pDevIns); +} + #endif /* IN_RING3 */ #ifdef IN_RING0 diff --git a/include/VBox/vmm/pdmdrv.h b/include/VBox/vmm/pdmdrv.h index d830ea69..57dbe960 100644 --- a/include/VBox/vmm/pdmdrv.h +++ b/include/VBox/vmm/pdmdrv.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -1297,12 +1297,43 @@ typedef struct PDMDRVHLPR3 PFNPDMBLKCACHEXFERENQUEUEDRV pfnXferEnqueue, PFNPDMBLKCACHEXFERENQUEUEDISCARDDRV pfnXferEnqueueDiscard, const char *pcszId)); + /** + * Gets the reason for the most recent VM suspend. + * + * @returns The suspend reason. VMSUSPENDREASON_INVALID is returned if no + * suspend has been made or if the pDrvIns is invalid. + * @param pDrvIns The driver instance. + */ + DECLR3CALLBACKMEMBER(VMSUSPENDREASON, pfnVMGetSuspendReason,(PPDMDRVINS pDrvIns)); + + /** + * Gets the reason for the most recent VM resume. + * + * @returns The resume reason. VMRESUMEREASON_INVALID is returned if no + * resume has been made or if the pDrvIns is invalid. + * @param pDrvIns The driver instance. + */ + DECLR3CALLBACKMEMBER(VMRESUMEREASON, pfnVMGetResumeReason,(PPDMDRVINS pDrvIns)); + + /** @name Space reserved for minor interface changes. + * @{ */ + DECLR3CALLBACKMEMBER(void, pfnReserved0,(PPDMDRVINS pDrvIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved1,(PPDMDRVINS pDrvIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved2,(PPDMDRVINS pDrvIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved3,(PPDMDRVINS pDrvIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved4,(PPDMDRVINS pDrvIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved5,(PPDMDRVINS pDrvIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved6,(PPDMDRVINS pDrvIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved7,(PPDMDRVINS pDrvIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved8,(PPDMDRVINS pDrvIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved9,(PPDMDRVINS pDrvIns)); + /** @} */ /** Just a safety precaution. */ uint32_t u32TheEnd; } PDMDRVHLPR3; /** Current DRVHLP version number. */ -#define PDM_DRVHLPR3_VERSION PDM_VERSION_MAKE(0xf0fb, 2, 0) +#define PDM_DRVHLPR3_VERSION PDM_VERSION_MAKE(0xf0fb, 3, 0) #endif /* IN_RING3 */ @@ -1777,6 +1808,23 @@ DECLINLINE(int) PDMDrvHlpBlkCacheRetain(PPDMDRVINS pDrvIns, PPPDMBLKCACHE ppBlkC return pDrvIns->pHlpR3->pfnBlkCacheRetain(pDrvIns, ppBlkCache, pfnXferComplete, pfnXferEnqueue, pfnXferEnqueueDiscard, pcszId); } +/** + * @copydoc PDMDRVHLP::pfnVMGetSuspendReason + */ +DECLINLINE(VMSUSPENDREASON) PDMDrvHlpVMGetSuspendReason(PPDMDRVINS pDrvIns) +{ + return pDrvIns->pHlpR3->pfnVMGetSuspendReason(pDrvIns); +} + +/** + * @copydoc PDMDRVHLP::pfnVMGetResumeReason + */ +DECLINLINE(VMRESUMEREASON) PDMDrvHlpVMGetResumeReason(PPDMDRVINS pDrvIns) +{ + return pDrvIns->pHlpR3->pfnVMGetResumeReason(pDrvIns); +} + + /** Pointer to callbacks provided to the VBoxDriverRegister() call. */ typedef struct PDMDRVREGCB *PPDMDRVREGCB; /** Pointer to const callbacks provided to the VBoxDriverRegister() call. */ diff --git a/include/VBox/vmm/pdmifs.h b/include/VBox/vmm/pdmifs.h index 17dba105..913c0dc2 100644 --- a/include/VBox/vmm/pdmifs.h +++ b/include/VBox/vmm/pdmifs.h @@ -296,14 +296,16 @@ typedef struct PDMIMOUSEPORT * @returns VBox status code. Return VERR_TRY_AGAIN if you cannot process the * event now and want it to be repeated at a later point. * - * @param pInterface Pointer to this interface structure. - * @param iDeltaX The X delta. - * @param iDeltaY The Y delta. - * @param iDeltaZ The Z delta. - * @param iDeltaW The W (horizontal scroll button) delta. - * @param fButtonStates The button states, see the PDMIMOUSEPORT_BUTTON_* \#defines. + * @param pInterface Pointer to this interface structure. + * @param dx The X delta. + * @param dy The Y delta. + * @param dz The Z delta. + * @param dw The W (horizontal scroll button) delta. + * @param fButtons The button states, see the PDMIMOUSEPORT_BUTTON_* \#defines. */ - DECLR3CALLBACKMEMBER(int, pfnPutEvent,(PPDMIMOUSEPORT pInterface, int32_t iDeltaX, int32_t iDeltaY, int32_t iDeltaZ, int32_t iDeltaW, uint32_t fButtonStates)); + DECLR3CALLBACKMEMBER(int, pfnPutEvent,(PPDMIMOUSEPORT pInterface, + int32_t dx, int32_t dy, int32_t dz, + int32_t dw, uint32_t fButtons)); /** * Puts an absolute mouse event. * @@ -313,17 +315,45 @@ typedef struct PDMIMOUSEPORT * @returns VBox status code. Return VERR_TRY_AGAIN if you cannot process the * event now and want it to be repeated at a later point. * - * @param pInterface Pointer to this interface structure. - * @param uX The X value, in the range 0 to 0xffff. - * @param uY The Y value, in the range 0 to 0xffff. - * @param iDeltaZ The Z delta. - * @param iDeltaW The W (horizontal scroll button) delta. - * @param fButtonStates The button states, see the PDMIMOUSEPORT_BUTTON_* \#defines. + * @param pInterface Pointer to this interface structure. + * @param x The X value, in the range 0 to 0xffff. + * @param z The Y value, in the range 0 to 0xffff. + * @param dz The Z delta. + * @param dw The W (horizontal scroll button) delta. + * @param fButtons The button states, see the PDMIMOUSEPORT_BUTTON_* \#defines. */ - DECLR3CALLBACKMEMBER(int, pfnPutEventAbs,(PPDMIMOUSEPORT pInterface, uint32_t uX, uint32_t uY, int32_t iDeltaZ, int32_t iDeltaW, uint32_t fButtonStates)); + DECLR3CALLBACKMEMBER(int, pfnPutEventAbs,(PPDMIMOUSEPORT pInterface, + uint32_t x, uint32_t z, + int32_t dz, int32_t dw, + uint32_t fButtons)); + /** + * Puts a multi-touch event. + * + * @returns VBox status code. Return VERR_TRY_AGAIN if you cannot process the + * event now and want it to be repeated at a later point. + * + * @param pInterface Pointer to this interface structure. + * @param cContacts How many touch contacts in this event. + * @param pau64Contacts Pointer to array of packed contact information. + * Each 64bit element contains: + * Bits 0..15: X coordinate in pixels (signed). + * Bits 16..31: Y coordinate in pixels (signed). + * Bits 32..39: contact identifier. + * Bit 40: "in contact" flag, which indicates that + * there is a contact with the touch surface. + * Bit 41: "in range" flag, the contact is close enough + * to the touch surface. + * All other bits are reserved for future use and must be set to 0. + * @param u32ScanTime Timestamp of this event in milliseconds. Only relative + * time between event is important. + */ + DECLR3CALLBACKMEMBER(int, pfnPutEventMultiTouch,(PPDMIMOUSEPORT pInterface, + uint8_t cContacts, + const uint64_t *pau64Contacts, + uint32_t u32ScanTime)); } PDMIMOUSEPORT; /** PDMIMOUSEPORT interface ID. */ -#define PDMIMOUSEPORT_IID "442136fe-6f3c-49ec-9964-259b378ffa64" +#define PDMIMOUSEPORT_IID "359364f0-9fa3-4490-a6b4-7ed771901c93" /** Mouse button defines for PDMIMOUSEPORT::pfnPutEvent. * @{ */ @@ -350,8 +380,9 @@ typedef struct PDMIMOUSECONNECTOR * @param pInterface Pointer to the this interface. * @param fRelative Whether relative mode is currently supported. * @param fAbsolute Whether absolute mode is currently supported. + * @param fAbsolute Whether multi-touch mode is currently supported. */ - DECLR3CALLBACKMEMBER(void, pfnReportModes,(PPDMIMOUSECONNECTOR pInterface, bool fRelative, bool fAbsolute)); + DECLR3CALLBACKMEMBER(void, pfnReportModes,(PPDMIMOUSECONNECTOR pInterface, bool fRelative, bool fAbsolute, bool fMultiTouch)); } PDMIMOUSECONNECTOR; /** PDMIMOUSECONNECTOR interface ID. */ @@ -598,8 +629,11 @@ typedef struct VBVAHOSTFLAGS *PVBVAHOSTFLAGS; typedef struct VBOXVDMACMD_CHROMIUM_CMD *PVBOXVDMACMD_CHROMIUM_CMD; /* <- chromium [hgsmi] command */ typedef struct VBOXVDMACMD_CHROMIUM_CTL *PVBOXVDMACMD_CHROMIUM_CTL; /* <- chromium [hgsmi] command */ + /** Pointer to a display connector interface. */ typedef struct PDMIDISPLAYCONNECTOR *PPDMIDISPLAYCONNECTOR; +struct VBOXCRCMDCTL; +typedef DECLCALLBACKPTR(void, PFNCRCTLCOMPLETION)(struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd, int rc, void *pvCompletion); /** * Display connector interface (up). * Pair with PDMIDISPLAYPORT. @@ -703,9 +737,12 @@ typedef struct PDMIDISPLAYCONNECTOR * * @param pInterface Pointer to this interface. * @param pCmd Video HW Acceleration Command to be processed. + * @returns VINF_SUCCESS - command is completed, + * VINF_CALLBACK_RETURN - command will by asynchronously completed via complete callback + * VERR_INVALID_STATE - the command could not be processed (most likely because the framebuffer was disconnected) - the post should be retried later * @thread The emulation thread. */ - DECLR3CALLBACKMEMBER(void, pfnVHWACommandProcess, (PPDMIDISPLAYCONNECTOR pInterface, PVBOXVHWACMD pCmd)); + DECLR3CALLBACKMEMBER(int, pfnVHWACommandProcess, (PPDMIDISPLAYCONNECTOR pInterface, PVBOXVHWACMD pCmd)); /** * Process the guest chromium command. @@ -725,6 +762,17 @@ typedef struct PDMIDISPLAYCONNECTOR */ DECLR3CALLBACKMEMBER(void, pfnCrHgsmiControlProcess, (PPDMIDISPLAYCONNECTOR pInterface, PVBOXVDMACMD_CHROMIUM_CTL pCtl, uint32_t cbCtl)); + /** + * Process the guest chromium control command. + * + * @param pInterface Pointer to this interface. + * @param pCmd Video HW Acceleration Command to be processed. + * @thread The emulation thread. + */ + DECLR3CALLBACKMEMBER(int, pfnCrHgcmCtlSubmit, (PPDMIDISPLAYCONNECTOR pInterface, + struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd, + PFNCRCTLCOMPLETION pfnCompletion, + void *pvCompletion)); /** * The specified screen enters VBVA mode. @@ -835,7 +883,7 @@ typedef struct PDMIDISPLAYCONNECTOR /** @} */ } PDMIDISPLAYCONNECTOR; /** PDMIDISPLAYCONNECTOR interface ID. */ -#define PDMIDISPLAYCONNECTOR_IID "c7a1b36d-8dfc-421d-b71f-3a0eeaf733e6" +#define PDMIDISPLAYCONNECTOR_IID "05ba9649-302e-43dd-b9ff-60b6fb311d97" /** Pointer to a block port interface. */ @@ -892,6 +940,12 @@ typedef enum PDMBLOCKTYPE PDMBLOCKTYPE_FLOPPY_1_44, /** 2.88MB 3 1/2" floppy drive. */ PDMBLOCKTYPE_FLOPPY_2_88, + /** Fake drive that can take up to 15.6 MB images. + * C=255, H=2, S=63. */ + PDMBLOCKTYPE_FLOPPY_FAKE_15_6, + /** Fake drive that can take up to 63.5 MB images. + * C=255, H=2, S=255. */ + PDMBLOCKTYPE_FLOPPY_FAKE_63_5, /** CDROM drive. */ PDMBLOCKTYPE_CDROM, /** DVD drive. */ @@ -900,6 +954,8 @@ typedef enum PDMBLOCKTYPE PDMBLOCKTYPE_HARD_DISK } PDMBLOCKTYPE; +/** Check if the given block type is a floppy. */ +#define PDMBLOCKTYPE_IS_FLOPPY(a_enmType) ( (a_enmType) >= PDMBLOCKTYPE_FLOPPY_360 && (a_enmType) <= PDMBLOCKTYPE_FLOPPY_2_88 ) /** * Block raw command data transfer direction. @@ -1000,6 +1056,15 @@ typedef struct PDMIBLOCK DECLR3CALLBACKMEMBER(uint64_t, pfnGetSize,(PPDMIBLOCK pInterface)); /** + * Gets the media sector size in bytes. + * + * @returns Media sector size in bytes. + * @param pInterface Pointer to the interface structure containing the called function pointer. + * @thread Any thread. + */ + DECLR3CALLBACKMEMBER(uint32_t, pfnGetSectorSize,(PPDMIBLOCK pInterface)); + + /** * Gets the block drive type. * * @returns block drive type. @@ -1245,6 +1310,15 @@ typedef struct PDMIMEDIA DECLR3CALLBACKMEMBER(uint64_t, pfnGetSize,(PPDMIMEDIA pInterface)); /** + * Gets the media sector size in bytes. + * + * @returns Media sector size in bytes. + * @param pInterface Pointer to the interface structure containing the called function pointer. + * @thread Any thread. + */ + DECLR3CALLBACKMEMBER(uint32_t, pfnGetSectorSize,(PPDMIMEDIA pInterface)); + + /** * Check if the media is readonly or not. * * @returns true if readonly. @@ -2065,8 +2139,19 @@ typedef struct PDMIVMMDEVPORT * @param cy Vertical pixel resolution (0 = do not change). * @param cBits Bits per pixel (0 = do not change). * @param idxDisplay The display index. + * @param xOrigin The X coordinate of the lower left + * corner of the secondary display with + * ID = idxDisplay + * @param yOrigin The Y coordinate of the lower left + * corner of the secondary display with + * ID = idxDisplay + * @param fEnabled Whether the display is enabled or not. (Guessing + * again.) + * @param fChangeOrigin Whether the display origin point changed. (Guess) */ - DECLR3CALLBACKMEMBER(int, pfnRequestDisplayChange,(PPDMIVMMDEVPORT pInterface, uint32_t cx, uint32_t cy, uint32_t cBits, uint32_t idxDisplay)); + DECLR3CALLBACKMEMBER(int, pfnRequestDisplayChange,(PPDMIVMMDEVPORT pInterface, uint32_t cx, + uint32_t cy, uint32_t cBits, uint32_t idxDisplay, + int32_t xOrigin, int32_t yOrigin, bool fEnabled, bool fChangeOrigin)); /** * Pass credentials to guest. @@ -2237,6 +2322,23 @@ typedef struct PDMIVMMDEVCONNECTOR uint32_t fFlags, PCRTTIMESPEC pTimeSpecTS)); /** + * Updates a guest user state. + * + * Called in response to VMMDevReq_ReportGuestUserState. + * + * @param pInterface Pointer to this interface. + * @param pszUser Guest user name to update status for. + * @param pszDomain Domain the guest user is bound to. Optional. + * @param uState New guest user state to notify host about. + * @param puDetails Pointer to optional state data. + * @param cbDetails Size (in bytes) of optional state data. + * @thread The emulation thread. + */ + DECLR3CALLBACKMEMBER(void, pfnUpdateGuestUserState,(PPDMIVMMDEVCONNECTOR pInterface, const char *pszUser, const char *pszDomain, + uint32_t uState, + const uint8_t *puDetails, uint32_t cbDetails)); + + /** * Reports the guest API and OS version. * Called whenever the Additions issue a guest info report request. * @@ -2966,6 +3068,11 @@ typedef struct PDMIDISPLAYVBVACALLBACKS DECLR3CALLBACKMEMBER(int, pfnCrHgsmiControlCompleteAsync, (PPDMIDISPLAYVBVACALLBACKS pInterface, PVBOXVDMACMD_CHROMIUM_CTL pCmd, int rc)); + + DECLR3CALLBACKMEMBER(int, pfnCrCtlSubmit, (PPDMIDISPLAYVBVACALLBACKS pInterface, + struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd, + PFNCRCTLCOMPLETION pfnCompletion, + void *pvCompletion)); } PDMIDISPLAYVBVACALLBACKS; /** PDMIDISPLAYVBVACALLBACKS */ #define PDMIDISPLAYVBVACALLBACKS_IID "b78b81d2-c821-4e66-96ff-dbafa76343a5" diff --git a/include/VBox/vmm/pdmnetinline.h b/include/VBox/vmm/pdmnetinline.h index 66c3078f..ac2bb6f7 100644 --- a/include/VBox/vmm/pdmnetinline.h +++ b/include/VBox/vmm/pdmnetinline.h @@ -6,7 +6,7 @@ */ /* - * Copyright (C) 2010 Oracle Corporation + * Copyright (C) 2010-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/vmm/pdmnetshaper.h b/include/VBox/vmm/pdmnetshaper.h index b2aa5bab..d3610564 100644 --- a/include/VBox/vmm/pdmnetshaper.h +++ b/include/VBox/vmm/pdmnetshaper.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2011-2012 Oracle Corporation + * Copyright (C) 2011-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -33,84 +33,43 @@ #include <iprt/sg.h> -#define PDM_NETSHAPER_MIN_BUCKET_SIZE 65536 /* bytes */ -#define PDM_NETSHAPER_MAX_LATENCY 100 /* milliseconds */ +/** @defgroup grp_pdm_net_shaper The PDM Network Shaper API + * @ingroup grp_pdm + * @{ + */ + + +#define PDM_NETSHAPER_MIN_BUCKET_SIZE UINT32_C(65536) /**< bytes */ +#define PDM_NETSHAPER_MAX_LATENCY UINT32_C(100) /**< milliseconds */ RT_C_DECLS_BEGIN typedef struct PDMNSFILTER { - /** [R3] Pointer to the next group in the list. */ - struct PDMNSFILTER *pNext; - /** [R3] Pointer to the bandwidth group. */ - struct PDMNSBWGROUP *pBwGroupR3; - /** [R0] Pointer to the bandwidth group. */ - R0PTRTYPE(struct PDMNSBWGROUP *) pBwGroupR0; - /** Becomes true when filter fails to obtain bandwidth. */ - bool fChoked; - /** [R3] The driver this filter is aggregated into. */ - PPDMINETWORKDOWN pIDrvNet; + /** Pointer to the next group in the list (ring-3). */ + R3PTRTYPE(struct PDMNSFILTER *) pNextR3; + /** Pointer to the bandwidth group (ring-3). */ + R3PTRTYPE(struct PDMNSBWGROUP *) pBwGroupR3; + /** Pointer to the bandwidth group (ring-0). */ + R0PTRTYPE(struct PDMNSBWGROUP *) pBwGroupR0; + /** Set when the filter fails to obtain bandwidth. */ + bool fChoked; + /** Aligment padding. */ + bool afPadding[HC_ARCH_BITS == 32 ? 3 : 7]; + /** The driver this filter is aggregated into (ring-3). */ + R3PTRTYPE(PPDMINETWORKDOWN) pIDrvNetR3; } PDMNSFILTER; -/** @defgroup grp_pdm_net_shaper The PDM Network Shaper API - * @ingroup grp_pdm - * @{ - */ - /** Pointer to a PDM filter handle. */ typedef struct PDMNSFILTER *PPDMNSFILTER; /** Pointer to a network shaper. */ typedef struct PDMNETSHAPER *PPDMNETSHAPER; -/** - * Obtain bandwidth in a bandwidth group (R0 version). - * - * @returns VBox status code. - * @param pFilter Pointer to the filter that allocates bandwidth. - * @param cbTransfer Number of bytes to allocate. - */ -VMMR0DECL(bool) PDMR0NsAllocateBandwidth(PPDMNSFILTER pFilter, size_t cbTransfer); - -/** - * Obtain bandwidth in a bandwidth group. - * - * @returns VBox status code. - * @param pFilter Pointer to the filter that allocates bandwidth. - * @param cbTransfer Number of bytes to allocate. - */ -VMMR3DECL(bool) PDMR3NsAllocateBandwidth(PPDMNSFILTER pFilter, size_t cbTransfer); - -/** - * Attach network filter driver from bandwidth group. - * - * @returns VBox status code. - * @param pVM Handle of VM. - * @param pDrvIns The driver instance. - * @param pcszBwGroup Name of the bandwidth group to attach to. - * @param pFilter Pointer to the filter we attach. - */ -VMMR3DECL(int) PDMR3NsAttach(PVM pVM, PPDMDRVINS pDrvIns, const char *pcszBwGroup, PPDMNSFILTER pFilter); - -/** - * Detach network filter driver from bandwidth group. - * - * @returns VBox status code. - * @param pVM Handle of VM. - * @param pDrvIns The driver instance. - * @param pFilter Pointer to the filter we detach. - */ -VMMR3DECL(int) PDMR3NsDetach(PVM pVM, PPDMDRVINS pDrvIns, PPDMNSFILTER pFilter); - -/** - * Adjusts the maximum rate for the bandwidth group. - * - * @returns VBox status code. - * @param pVM Handle of VM. - * @param pcszBwGroup Name of the bandwidth group to attach to. - * @param cbTransferPerSecMax Maximum number of bytes per second to be transmitted. - */ -VMMR3DECL(int) PDMR3NsBwGroupSetLimit(PVM pVM, const char *pcszBwGroup, uint64_t cbTransferPerSecMax); +VMMDECL(bool) PDMNsAllocateBandwidth(PPDMNSFILTER pFilter, size_t cbTransfer); +VMMR3_INT_DECL(int) PDMR3NsAttach(PUVM pUVM, PPDMDRVINS pDrvIns, const char *pcszBwGroup, PPDMNSFILTER pFilter); +VMMR3_INT_DECL(int) PDMR3NsDetach(PUVM pUVM, PPDMDRVINS pDrvIns, PPDMNSFILTER pFilter); +VMMR3DECL(int) PDMR3NsBwGroupSetLimit(PUVM pUVM, const char *pszBwGroup, uint64_t cbPerSecMax); /** @} */ diff --git a/include/VBox/vmm/pdmnetshaperint.h b/include/VBox/vmm/pdmnetshaperint.h deleted file mode 100644 index 3bbfcda7..00000000 --- a/include/VBox/vmm/pdmnetshaperint.h +++ /dev/null @@ -1,94 +0,0 @@ -/* $Id: pdmnetshaperint.h $ */ -/** @file - * PDM Network Shaper - Internal data structures and functions common for both - * R0 and R3 parts. - */ - -/* - * Copyright (C) 2011-2012 Oracle Corporation - * - * This file is part of VirtualBox Open Source Edition (OSE), as - * available from http://www.virtualbox.org. This file is free software; - * you can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) as published by the Free Software - * Foundation, in version 2 as it comes in the "COPYING" file of the - * VirtualBox OSE distribution. VirtualBox OSE is distributed in the - * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. - * - * The contents of this file may alternatively be used under the terms - * of the Common Development and Distribution License Version 1.0 - * (CDDL) only, as it comes in the "COPYING.CDDL" file of the - * VirtualBox OSE distribution, in which case the provisions of the - * CDDL are applicable instead of those of the GPL. - * - * You may elect to license modified versions of this file under the - * terms and conditions of either the GPL or the CDDL or both. - */ - -/** - * Bandwidth group instance data - */ -typedef struct PDMNSBWGROUP -{ - /** Pointer to the next group in the list. */ - struct PDMNSBWGROUP *pNext; - /** Pointer to the shared UVM structure. */ - struct PDMNETSHAPER *pShaper; - /** Critical section protecting all members below. */ - PDMCRITSECT cs; - /** Pointer to the first filter attached to this group. */ - struct PDMNSFILTER *pFiltersHead; - /** Bandwidth group name. */ - char *pszName; - /** Maximum number of bytes filters are allowed to transfer. */ - volatile uint64_t cbTransferPerSecMax; - /** Number of bytes we are allowed to transfer in one burst. */ - volatile uint32_t cbBucketSize; - /** Number of bytes we were allowed to transfer at the last update. */ - volatile uint32_t cbTokensLast; - /** Timestamp of the last update */ - volatile uint64_t tsUpdatedLast; - /** Reference counter - How many filters are associated with this group. */ - volatile uint32_t cRefs; -} PDMNSBWGROUP; -/** Pointer to a bandwidth group. */ -typedef PDMNSBWGROUP *PPDMNSBWGROUP; - -DECLINLINE(bool) pdmNsAllocateBandwidth(PPDMNSFILTER pFilter, size_t cbTransfer) -{ - AssertPtrReturn(pFilter, true); - if (!VALID_PTR(pFilter->CTX_SUFF(pBwGroup))) - return true; - - PPDMNSBWGROUP pBwGroup = ASMAtomicReadPtrT(&pFilter->CTX_SUFF(pBwGroup), PPDMNSBWGROUP); - int rc = PDMCritSectEnter(&pBwGroup->cs, VERR_SEM_BUSY); AssertRC(rc); - if (RT_UNLIKELY(rc == VERR_SEM_BUSY)) - return true; - bool fAllowed = true; - if (pBwGroup->cbTransferPerSecMax) - { - /* Re-fill the bucket first */ - uint64_t tsNow = RTTimeSystemNanoTS(); - uint32_t uTokensAdded = (tsNow - pBwGroup->tsUpdatedLast)*pBwGroup->cbTransferPerSecMax/(1000*1000*1000); - uint32_t uTokens = RT_MIN(pBwGroup->cbBucketSize, uTokensAdded + pBwGroup->cbTokensLast); - - if (cbTransfer > uTokens) - { - fAllowed = false; - ASMAtomicWriteBool(&pFilter->fChoked, true); - } - else - { - pBwGroup->tsUpdatedLast = tsNow; - pBwGroup->cbTokensLast = uTokens - (uint32_t)cbTransfer; - } - Log2((LOG_FN_FMT "BwGroup=%#p{%s} cbTransfer=%u uTokens=%u uTokensAdded=%u fAllowed=%RTbool\n", - __PRETTY_FUNCTION__, pBwGroup, pBwGroup->pszName, cbTransfer, uTokens, uTokensAdded, fAllowed)); - } - else - Log2((LOG_FN_FMT "BwGroup=%#p{%s} disabled fAllowed=%RTbool\n", - __PRETTY_FUNCTION__, pBwGroup, pBwGroup->pszName, fAllowed)); - - rc = PDMCritSectLeave(&pBwGroup->cs); AssertRC(rc); - return fAllowed; -} diff --git a/include/VBox/vmm/pdmnvram.h b/include/VBox/vmm/pdmnvram.h index 10c1abc4..03967dff 100644 --- a/include/VBox/vmm/pdmnvram.h +++ b/include/VBox/vmm/pdmnvram.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2012 Oracle Corporation + * Copyright (C) 2012-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -36,35 +36,85 @@ RT_C_DECLS_BEGIN * @{ */ -typedef struct PDMINVRAM *PPDMINVRAM; +/** Pointer to NVRAM interface provided by the driver. */ +typedef struct PDMINVRAMCONNECTOR *PPDMINVRAMCONNECTOR; -typedef struct PDMINVRAM +/** + * Non-volatile RAM storage interface provided by the driver (up). + * + * @note The variable indexes used here 0-based, sequential and without gaps. + */ +typedef struct PDMINVRAMCONNECTOR { /** - * This method flushes all values in the storage. + * Query a variable by variable index. + * + * @returns VBox status code. + * @retval VERR_NOT_FOUND if the variable was not found. This indicates that + * there are not variables with a higher index. + * + * @param idxVariable The variable index. By starting @a idxVariable at 0 + * and increasing it with each call, this can be used + * to enumerate all available variables. + * @param pVendorUuid The vendor UUID of the variable. + * @param pszName The variable name buffer. + * @param pcchName On input this hold the name buffer size (including + * the space for the terminator char). On successful + * return it holds the strlen() value for @a pszName. + * @param pfAttributes Where to return the value attributes. + * @param pbValue The value buffer. + * @param pcbValue On input the size of the value buffer, on output the + * actual number of bytes returned. */ - DECLR3CALLBACKMEMBER(int, pfnFlushNvramStorage, (PPDMINVRAM pInterface)); + DECLR3CALLBACKMEMBER(int, pfnVarQueryByIndex,(PPDMINVRAMCONNECTOR pInterface, uint32_t idxVariable, + PRTUUID pVendorUuid, char *pszName, uint32_t *pcchName, + uint32_t *pfAttributes, uint8_t *pbValue, uint32_t *pcbValue)); /** - * This method store NVRAM variable to storage + * Begins variable store sequence. + * + * @returns VBox status code. + * @param pInterance Pointer to this interface structure. + * @param cVariables The number of variables. */ - DECLR3CALLBACKMEMBER(int, pfnStoreNvramValue, (PPDMINVRAM pInterface, int idxVariable, RTUUID *pVendorUuid, const char *pcszVariableName, size_t cbVariableName, uint8_t *pu8Value, size_t cbValue)); + DECLR3CALLBACKMEMBER(int, pfnVarStoreSeqBegin,(PPDMINVRAMCONNECTOR pInterface, uint32_t cVariables)); /** - * This method load NVRAM variable to storage + * Puts the next variable in the store sequence. + * + * @returns VBox status code. + * @param idxVariable The variable index. This will start at 0 and advance + * up to @a cVariables - 1. + * @param pVendorUuid The vendor UUID of the variable. + * @param pszName The variable name buffer. + * @param pcchName On input this hold the name buffer size (including + * the space for the terminator char). On successful + * return it holds the strlen() value for @a pszName. + * @param fAttributes The value attributes. + * @param pbValue The value buffer. + * @param pcbValue On input the size of the value buffer, on output the + * actual number of bytes returned. */ - DECLR3CALLBACKMEMBER(int, pfnLoadNvramValue, (PPDMINVRAM pInterface, int idxVariable, RTUUID *pVendorUuid, char *pcszVariableName, size_t *pcbVariableName, uint8_t *pu8Value, size_t *pcbValue)); - -} PDMINVRAM; + DECLR3CALLBACKMEMBER(int, pfnVarStoreSeqPut,(PPDMINVRAMCONNECTOR pInterface, int idxVariable, + PCRTUUID pVendorUuid, const char *pszName, size_t cchName, + uint32_t fAttributes, uint8_t const *pbValue, size_t cbValue)); + /** + * Ends a variable store sequence. + * + * @returns VBox status code, @a rc on success. + * @param pInterance Pointer to this interface structure. + * @param rc The VBox status code for the whole store operation. + */ + DECLR3CALLBACKMEMBER(int, pfnVarStoreSeqEnd,(PPDMINVRAMCONNECTOR pInterface, int rc)); -#define PDMINVRAM_IID "11226408-CB4C-4369-9218-1EE0092FB9F8" +} PDMINVRAMCONNECTOR; +/** PDMINVRAMCONNECTOR interface ID. */ +#define PDMINVRAMCONNECTOR_IID "057bc5c9-8022-43a8-9a41-0b106f97a89f" /** @} */ RT_C_DECLS_END - #endif - diff --git a/include/VBox/vmm/pdmqueue.h b/include/VBox/vmm/pdmqueue.h index 3445c85a..4edf16c3 100644 --- a/include/VBox/vmm/pdmqueue.h +++ b/include/VBox/vmm/pdmqueue.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2011 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -65,6 +65,9 @@ typedef struct PDMQUEUEITEMCORE * If false the item will not be removed and the flushing will stop. * @param pDevIns The device instance. * @param pItem The item to consume. Upon return this item will be freed. + * @remarks The device critical section will NOT be entered before calling the + * callback. No locks will be held, but for now it's safe to assume + * that only one EMT will do queue callbacks at any one time. */ typedef DECLCALLBACK(bool) FNPDMQUEUEDEV(PPDMDEVINS pDevIns, PPDMQUEUEITEMCORE pItem); /** Pointer to a FNPDMQUEUEDEV(). */ @@ -77,6 +80,8 @@ typedef FNPDMQUEUEDEV *PFNPDMQUEUEDEV; * If false the item will not be removed and the flushing will stop. * @param pDevIns The USB device instance. * @param pItem The item to consume. Upon return this item will be freed. + * @remarks No locks will be held, but for now it's safe to assume that only one + * EMT will do queue callbacks at any one time. */ typedef DECLCALLBACK(bool) FNPDMQUEUEUSB(PPDMUSBINS pUsbIns, PPDMQUEUEITEMCORE pItem); /** Pointer to a FNPDMQUEUEUSB(). */ @@ -89,6 +94,8 @@ typedef FNPDMQUEUEUSB *PFNPDMQUEUEUSB; * If false the item will not be removed and the flushing will stop. * @param pDrvIns The driver instance. * @param pItem The item to consume. Upon return this item will be freed. + * @remarks No locks will be held, but for now it's safe to assume that only one + * EMT will do queue callbacks at any one time. */ typedef DECLCALLBACK(bool) FNPDMQUEUEDRV(PPDMDRVINS pDrvIns, PPDMQUEUEITEMCORE pItem); /** Pointer to a FNPDMQUEUEDRV(). */ @@ -101,6 +108,8 @@ typedef FNPDMQUEUEDRV *PFNPDMQUEUEDRV; * If false the item will not be removed and the flushing will stop. * @param pVM The VM handle. * @param pItem The item to consume. Upon return this item will be freed. + * @remarks No locks will be held, but for now it's safe to assume that only one + * EMT will do queue callbacks at any one time. */ typedef DECLCALLBACK(bool) FNPDMQUEUEINT(PVM pVM, PPDMQUEUEITEMCORE pItem); /** Pointer to a FNPDMQUEUEINT(). */ @@ -113,6 +122,8 @@ typedef FNPDMQUEUEINT *PFNPDMQUEUEINT; * If false the item will not be removed and the flushing will stop. * @param pvUser User argument. * @param pItem The item to consume. Upon return this item will be freed. + * @remarks No locks will be held, but for now it's safe to assume that only one + * EMT will do queue callbacks at any one time. */ typedef DECLCALLBACK(bool) FNPDMQUEUEEXT(void *pvUser, PPDMQUEUEITEMCORE pItem); /** Pointer to a FNPDMQUEUEEXT(). */ diff --git a/include/VBox/vmm/pdmusb.h b/include/VBox/vmm/pdmusb.h index ae3f5cfb..6abe2a14 100644 --- a/include/VBox/vmm/pdmusb.h +++ b/include/VBox/vmm/pdmusb.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -113,6 +113,11 @@ typedef PDMUSBDESCCACHE *PPDMUSBDESCCACHE; typedef const PDMUSBDESCCACHE *PCPDMUSBDESCCACHE; +/** PDM Device Flags. + * @{ */ +/** A high-speed capable USB 2.0 device (also required to support full-speed). */ +#define PDM_USBREG_HIGHSPEED_CAPABLE RT_BIT(0) +/** @} */ /** PDM USB Device Registration Structure, * @@ -164,7 +169,7 @@ typedef struct PDMUSBREG * Most VM resources are freed by the VM. This callback is provided so that any non-VM * resources can be freed correctly. * - * This method will be called regardless of the pfnConstruc result to avoid + * This method will be called regardless of the pfnConstruct result to avoid * complicated failure paths. * * @param pUsbIns The USB device instance data. @@ -672,6 +677,38 @@ typedef struct PDMUSBHLP */ DECLR3CALLBACKMEMBER(void, pfnAsyncNotificationCompleted, (PPDMUSBINS pUsbIns)); + /** + * Gets the reason for the most recent VM suspend. + * + * @returns The suspend reason. VMSUSPENDREASON_INVALID is returned if no + * suspend has been made or if the pUsbIns is invalid. + * @param pUsbIns The driver instance. + */ + DECLR3CALLBACKMEMBER(VMSUSPENDREASON, pfnVMGetSuspendReason,(PPDMUSBINS pUsbIns)); + + /** + * Gets the reason for the most recent VM resume. + * + * @returns The resume reason. VMRESUMEREASON_INVALID is returned if no + * resume has been made or if the pUsbIns is invalid. + * @param pUsbIns The driver instance. + */ + DECLR3CALLBACKMEMBER(VMRESUMEREASON, pfnVMGetResumeReason,(PPDMUSBINS pUsbIns)); + + /** @name Space reserved for minor interface changes. + * @{ */ + DECLR3CALLBACKMEMBER(void, pfnReserved0,(PPDMUSBINS pUsbIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved1,(PPDMUSBINS pUsbIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved2,(PPDMUSBINS pUsbIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved3,(PPDMUSBINS pUsbIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved4,(PPDMUSBINS pUsbIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved5,(PPDMUSBINS pUsbIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved6,(PPDMUSBINS pUsbIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved7,(PPDMUSBINS pUsbIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved8,(PPDMUSBINS pUsbIns)); + DECLR3CALLBACKMEMBER(void, pfnReserved9,(PPDMUSBINS pUsbIns)); + /** @} */ + /** Just a safety precaution. */ uint32_t u32TheEnd; } PDMUSBHLP; @@ -681,7 +718,7 @@ typedef PDMUSBHLP *PPDMUSBHLP; typedef const PDMUSBHLP *PCPDMUSBHLP; /** Current USBHLP version number. */ -#define PDM_USBHLP_VERSION PDM_VERSION_MAKE(0xeefe, 2, 0) +#define PDM_USBHLP_VERSION PDM_VERSION_MAKE(0xeefe, 3, 0) #endif /* IN_RING3 */ @@ -732,9 +769,12 @@ typedef struct PDMUSBINS uint32_t fTracing; /** The tracing ID of this device. */ uint32_t idTracing; + /** The USB version of the hub this device is attached to. Used to + * determine whether the device communicates at high-speed or full-/low-speed. */ + uint32_t iUsbHubVersion; /** Padding to make achInstanceData aligned at 32 byte boundary. */ - uint32_t au32Padding[HC_ARCH_BITS == 32 ? 3 : 4]; + uint32_t au32Padding[HC_ARCH_BITS == 32 ? 2 : 3]; /** Device instance data. The size of this area is defined * in the PDMUSBREG::cbInstanceData field. */ @@ -991,10 +1031,11 @@ typedef struct PDMUSBREGCB */ typedef DECLCALLBACK(int) FNPDMVBOXUSBREGISTER(PCPDMUSBREGCB pCallbacks, uint32_t u32Version); -VMMR3DECL(int) PDMR3USBCreateProxyDevice(PVM pVM, PCRTUUID pUuid, bool fRemote, const char *pszAddress, void *pvBackend, +VMMR3DECL(int) PDMR3UsbCreateEmulatedDevice(PUVM pUVM, const char *pszDeviceName, PCFGMNODE pDeviceNode, PCRTUUID pUuid); +VMMR3DECL(int) PDMR3UsbCreateProxyDevice(PUVM pUVM, PCRTUUID pUuid, bool fRemote, const char *pszAddress, void *pvBackend, uint32_t iUsbVersion, uint32_t fMaskedIfs); -VMMR3DECL(int) PDMR3USBDetachDevice(PVM pVM, PCRTUUID pUuid); -VMMR3DECL(bool) PDMR3USBHasHub(PVM pVM); +VMMR3DECL(int) PDMR3UsbDetachDevice(PUVM pUVM, PCRTUUID pUuid); +VMMR3DECL(bool) PDMR3UsbHasHub(PUVM pUVM); /** @} */ diff --git a/include/VBox/vmm/pdmwebcaminfs.h b/include/VBox/vmm/pdmwebcaminfs.h new file mode 100644 index 00000000..40b01614 --- /dev/null +++ b/include/VBox/vmm/pdmwebcaminfs.h @@ -0,0 +1,133 @@ +/* $Id: pdmwebcaminfs.h $ */ + +/** @file + * webcaminfs - interfaces between dev and driver. + */ + +/* + * Copyright (C) 2011-2013 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL) only, as it comes in the "COPYING.CDDL" file of the + * VirtualBox OSE distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + */ + +#ifndef ___VBox_vmm_pdmwebcaminfs_h +#define ___VBox_vmm_pdmwebcaminfs_h + + +typedef struct PDMIWEBCAM_DEVICEDESC PDMIWEBCAM_DEVICEDESC; +typedef struct PDMIWEBCAM_CTRLHDR PDMIWEBCAM_CTRLHDR; +typedef struct PDMIWEBCAM_FRAMEHDR PDMIWEBCAM_FRAMEHDR; + + +#define PDMIWEBCAMDOWN_IID "0d29b9a1-f4cd-4719-a564-38d5634ba9f8" +typedef struct PDMIWEBCAMDOWN *PPDMIWEBCAMDOWN; +typedef struct PDMIWEBCAMDOWN +{ + /* + * The PDM device is ready to get webcam notifications. + * + * @param pInterface Pointer to the interface. + * @param fReady Whether the device is ready. + */ + DECLR3CALLBACKMEMBER(void, pfnWebcamDownReady, (PPDMIWEBCAMDOWN pInterface, + bool fReady)); + + /* + * Send a control request to the webcam. + * Async response will be returned by pfnWebcamUpControl callback. + * + * @param pInterface Pointer to the interface. + * @param pvUser The callers context. + * @param u64DeviceId Unique id for the reported webcam assigned by the driver. + * @param pCtrl The control data. + * @param cbCtrl The size of the control data. + */ + DECLR3CALLBACKMEMBER(int, pfnWebcamDownControl, (PPDMIWEBCAMDOWN pInterface, + void *pvUser, + uint64_t u64DeviceId, + const PDMIWEBCAM_CTRLHDR *pCtrl, + uint32_t cbCtrl)); +} PDMIWEBCAMDOWN; + + +#define PDMIWEBCAMUP_IID "6ac03e3c-f56c-4a35-80af-c13ce47a9dd7" +typedef struct PDMIWEBCAMUP *PPDMIWEBCAMUP; +typedef struct PDMIWEBCAMUP +{ + /* + * A webcam is available. + * + * @param pInterface Pointer to the interface. + * @param u64DeviceId Unique id for the reported webcam assigned by the driver. + * @param pDeviceDesc The device description. + * @param cbDeviceDesc The size of the device description. + * @param u32Version The remote video input protocol version. + * @param fu32Capabilities The remote video input protocol capabilities. + */ + DECLR3CALLBACKMEMBER(int, pfnWebcamUpAttached,(PPDMIWEBCAMUP pInterface, + uint64_t u64DeviceId, + const PDMIWEBCAM_DEVICEDESC *pDeviceDesc, + uint32_t cbDeviceDesc, + uint32_t u32Version, + uint32_t fu32Capabilities)); + + /* + * The webcam is not available anymore. + * + * @param pInterface Pointer to the interface. + * @param u64DeviceId Unique id for the reported webcam assigned by the driver. + */ + DECLR3CALLBACKMEMBER(void, pfnWebcamUpDetached,(PPDMIWEBCAMUP pInterface, + uint64_t u64DeviceId)); + + /* + * There is a control response or a control change for the webcam. + * + * @param pInterface Pointer to the interface. + * @param fResponse True if this is a response for a previous pfnWebcamDownControl call. + * @param pvUser The pvUser parameter of the pfnWebcamDownControl call. Undefined if fResponse == false. + * @param u64DeviceId Unique id for the reported webcam assigned by the driver. + * @param pCtrl The control data. + * @param cbCtrl The size of the control data. + */ + DECLR3CALLBACKMEMBER(void, pfnWebcamUpControl,(PPDMIWEBCAMUP pInterface, + bool fResponse, + void *pvUser, + uint64_t u64DeviceId, + const PDMIWEBCAM_CTRLHDR *pCtrl, + uint32_t cbCtrl)); + + /* + * A new frame. + * + * @param pInterface Pointer to the interface. + * @param u64DeviceId Unique id for the reported webcam assigned by the driver. + * @param pHeader Payload header. + * @param cbHeader Size of the payload header. + * @param pvFrame Frame (image) data. + * @param cbFrame Size of the image data. + */ + DECLR3CALLBACKMEMBER(void, pfnWebcamUpFrame,(PPDMIWEBCAMUP pInterface, + uint64_t u64DeviceId, + PDMIWEBCAM_FRAMEHDR *pHeader, + uint32_t cbHeader, + const void *pvFrame, + uint32_t cbFrame)); +} PDMIWEBCAMUP; + +#endif diff --git a/include/VBox/vmm/pgm.h b/include/VBox/vmm/pgm.h index 5d8b5f0d..7e397b2a 100644 --- a/include/VBox/vmm/pgm.h +++ b/include/VBox/vmm/pgm.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -333,13 +333,14 @@ VMMDECL(bool) PGMGstIsPagePresent(PVMCPU pVCpu, RTGCPTR GCPtr); VMMDECL(int) PGMGstSetPage(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cb, uint64_t fFlags); VMMDECL(int) PGMGstModifyPage(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cb, uint64_t fFlags, uint64_t fMask); VMM_INT_DECL(int) PGMGstGetPaePdpes(PVMCPU pVCpu, PX86PDPE paPdpes); -VMM_INT_DECL(int) PGMGstUpdatePaePdpes(PVMCPU pVCpu, PCX86PDPE paPdpes); +VMM_INT_DECL(void) PGMGstUpdatePaePdpes(PVMCPU pVCpu, PCX86PDPE paPdpes); VMMDECL(int) PGMInvalidatePage(PVMCPU pVCpu, RTGCPTR GCPtrPage); VMMDECL(int) PGMFlushTLB(PVMCPU pVCpu, uint64_t cr3, bool fGlobal); VMMDECL(int) PGMSyncCR3(PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal); VMMDECL(int) PGMUpdateCR3(PVMCPU pVCpu, uint64_t cr3); VMMDECL(int) PGMChangeMode(PVMCPU pVCpu, uint64_t cr0, uint64_t cr4, uint64_t efer); +VMMDECL(void) PGMCr0WpEnabled(PVMCPU pVCpu); VMMDECL(PGMMODE) PGMGetGuestMode(PVMCPU pVCpu); VMMDECL(PGMMODE) PGMGetShadowMode(PVMCPU pVCpu); VMMDECL(PGMMODE) PGMGetHostMode(PVM pVM); @@ -383,7 +384,9 @@ VMMDECL(int) PGMPhysSimpleDirtyWriteGCPtr(PVMCPU pVCpu, RTGCPTR GCPtrDst, VMMDECL(int) PGMPhysInterpretedRead(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, void *pvDst, RTGCPTR GCPtrSrc, size_t cb); VMMDECL(int) PGMPhysInterpretedReadNoHandlers(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, void *pvDst, RTGCUINTPTR GCPtrSrc, size_t cb, bool fRaiseTrap); VMMDECL(int) PGMPhysInterpretedWriteNoHandlers(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, RTGCPTR GCPtrDst, void const *pvSrc, size_t cb, bool fRaiseTrap); -VMM_INT_DECL(int) PGMPhysIemGCPhys2Ptr(PVM pVM, RTGCPHYS GCPhys, bool fWritable, bool fByPassHandlers, void **ppv, PPGMPAGEMAPLOCK pLock); +VMM_INT_DECL(int) PGMPhysIemGCPhys2Ptr(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, bool fWritable, bool fByPassHandlers, void **ppv, PPGMPAGEMAPLOCK pLock); +VMM_INT_DECL(int) PGMPhysIemQueryAccess(PVM pVM, RTGCPHYS GCPhys, bool fWritable, bool fByPassHandlers); + #ifdef VBOX_STRICT VMMDECL(unsigned) PGMAssertHandlerAndFlagsInSync(PVM pVM); VMMDECL(unsigned) PGMAssertNoMappingConflicts(PVM pVM); @@ -455,8 +458,9 @@ VMMR3DECL(int) PGMR3InitDynMap(PVM pVM); VMMR3DECL(int) PGMR3InitFinalize(PVM pVM); VMMR3_INT_DECL(int) PGMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat); VMMR3DECL(void) PGMR3Relocate(PVM pVM, RTGCINTPTR offDelta); -VMMR3DECL(void) PGMR3ResetUnpluggedCpu(PVM pVM, PVMCPU pVCpu); -VMMR3DECL(void) PGMR3Reset(PVM pVM); +VMMR3DECL(void) PGMR3ResetCpu(PVM pVM, PVMCPU pVCpu); +VMMR3_INT_DECL(void) PGMR3Reset(PVM pVM); +VMMR3_INT_DECL(void) PGMR3MemSetup(PVM pVM, bool fReset); VMMR3DECL(int) PGMR3Term(PVM pVM); VMMR3DECL(int) PGMR3LockCall(PVM pVM); VMMR3DECL(int) PGMR3ChangeMode(PVM pVM, PVMCPU pVCpu, PGMMODE enmGuestMode); @@ -468,8 +472,8 @@ VMMR3DECL(int) PGMR3PhysEnumDirtyFTPages(PVM pVM, PFNPGMENUMDIRTYFTPAGES pf VMMR3DECL(uint32_t) PGMR3PhysGetRamRangeCount(PVM pVM); VMMR3DECL(int) PGMR3PhysGetRange(PVM pVM, uint32_t iRange, PRTGCPHYS pGCPhysStart, PRTGCPHYS pGCPhysLast, const char **ppszDesc, bool *pfIsMmio); -VMMR3DECL(int) PGMR3QueryMemoryStats(PVM pVM, uint64_t *pcbTotalMem, uint64_t *pcbPrivateMem, uint64_t *pcbSharedMem, uint64_t *pcbZeroMem); -VMMR3DECL(int) PGMR3QueryGlobalMemoryStats(PVM pVM, uint64_t *pcbAllocMem, uint64_t *pcbFreeMem, uint64_t *pcbBallonedMem, uint64_t *pcbSharedMem); +VMMR3DECL(int) PGMR3QueryMemoryStats(PUVM pUVM, uint64_t *pcbTotalMem, uint64_t *pcbPrivateMem, uint64_t *pcbSharedMem, uint64_t *pcbZeroMem); +VMMR3DECL(int) PGMR3QueryGlobalMemoryStats(PUVM pUVM, uint64_t *pcbAllocMem, uint64_t *pcbFreeMem, uint64_t *pcbBallonedMem, uint64_t *pcbSharedMem); VMMR3DECL(int) PGMR3PhysMMIORegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, R3PTRTYPE(PFNPGMR3PHYSHANDLER) pfnHandlerR3, RTR3PTR pvUserR3, @@ -507,12 +511,13 @@ VMMDECL(void) PGMR3PhysSetA20(PVMCPU pVCpu, bool fEnable); VMMR3DECL(int) PGMR3MapPT(PVM pVM, RTGCPTR GCPtr, uint32_t cb, uint32_t fFlags, PFNPGMRELOCATE pfnRelocate, void *pvUser, const char *pszDesc); VMMR3DECL(int) PGMR3UnmapPT(PVM pVM, RTGCPTR GCPtr); VMMR3DECL(int) PGMR3FinalizeMappings(PVM pVM); -VMMR3DECL(int) PGMR3MappingsDisable(PVM pVM); VMMR3DECL(int) PGMR3MappingsSize(PVM pVM, uint32_t *pcb); VMMR3DECL(int) PGMR3MappingsFix(PVM pVM, RTGCPTR GCPtrBase, uint32_t cb); VMMR3DECL(int) PGMR3MappingsUnfix(PVM pVM); VMMR3DECL(bool) PGMR3MappingsNeedReFixing(PVM pVM); +#if defined(VBOX_WITH_RAW_MODE) || (HC_ARCH_BITS != 64 && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)) VMMR3DECL(int) PGMR3MapIntermediate(PVM pVM, RTUINTPTR Addr, RTHCPHYS HCPhys, unsigned cbPages); +#endif VMMR3DECL(int) PGMR3MapRead(PVM pVM, void *pvDst, RTGCPTR GCPtrSrc, size_t cb); VMMR3DECL(int) PGMR3HandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast, @@ -552,15 +557,15 @@ VMMR3DECL(int) PGMR3PhysAllocateLargeHandyPage(PVM pVM, RTGCPHYS GCPhys); VMMR3DECL(int) PGMR3CheckIntegrity(PVM pVM); -VMMR3DECL(int) PGMR3DbgR3Ptr2GCPhys(PVM pVM, RTR3PTR R3Ptr, PRTGCPHYS pGCPhys); -VMMR3DECL(int) PGMR3DbgR3Ptr2HCPhys(PVM pVM, RTR3PTR R3Ptr, PRTHCPHYS pHCPhys); -VMMR3DECL(int) PGMR3DbgHCPhys2GCPhys(PVM pVM, RTHCPHYS HCPhys, PRTGCPHYS pGCPhys); -VMMR3DECL(int) PGMR3DbgReadGCPhys(PVM pVM, void *pvDst, RTGCPHYS GCPhysSrc, size_t cb, uint32_t fFlags, size_t *pcbRead); -VMMR3DECL(int) PGMR3DbgWriteGCPhys(PVM pVM, RTGCPHYS GCPhysDst, const void *pvSrc, size_t cb, uint32_t fFlags, size_t *pcbWritten); -VMMR3DECL(int) PGMR3DbgReadGCPtr(PVM pVM, void *pvDst, RTGCPTR GCPtrSrc, size_t cb, uint32_t fFlags, size_t *pcbRead); -VMMR3DECL(int) PGMR3DbgWriteGCPtr(PVM pVM, RTGCPTR GCPtrDst, void const *pvSrc, size_t cb, uint32_t fFlags, size_t *pcbWritten); -VMMR3DECL(int) PGMR3DbgScanPhysical(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cbRange, RTGCPHYS GCPhysAlign, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCPHYS pGCPhysHit); -VMMR3DECL(int) PGMR3DbgScanVirtual(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, RTGCPTR cbRange, RTGCPTR GCPtrAlign, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCUINTPTR pGCPhysHit); +VMMR3DECL(int) PGMR3DbgR3Ptr2GCPhys(PUVM pUVM, RTR3PTR R3Ptr, PRTGCPHYS pGCPhys); +VMMR3DECL(int) PGMR3DbgR3Ptr2HCPhys(PUVM pUVM, RTR3PTR R3Ptr, PRTHCPHYS pHCPhys); +VMMR3DECL(int) PGMR3DbgHCPhys2GCPhys(PUVM pUVM, RTHCPHYS HCPhys, PRTGCPHYS pGCPhys); +VMMR3_INT_DECL(int) PGMR3DbgReadGCPhys(PVM pVM, void *pvDst, RTGCPHYS GCPhysSrc, size_t cb, uint32_t fFlags, size_t *pcbRead); +VMMR3_INT_DECL(int) PGMR3DbgWriteGCPhys(PVM pVM, RTGCPHYS GCPhysDst, const void *pvSrc, size_t cb, uint32_t fFlags, size_t *pcbWritten); +VMMR3_INT_DECL(int) PGMR3DbgReadGCPtr(PVM pVM, void *pvDst, RTGCPTR GCPtrSrc, size_t cb, uint32_t fFlags, size_t *pcbRead); +VMMR3_INT_DECL(int) PGMR3DbgWriteGCPtr(PVM pVM, RTGCPTR GCPtrDst, void const *pvSrc, size_t cb, uint32_t fFlags, size_t *pcbWritten); +VMMR3_INT_DECL(int) PGMR3DbgScanPhysical(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cbRange, RTGCPHYS GCPhysAlign, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCPHYS pGCPhysHit); +VMMR3_INT_DECL(int) PGMR3DbgScanVirtual(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, RTGCPTR cbRange, RTGCPTR GCPtrAlign, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCUINTPTR pGCPhysHit); VMMR3_INT_DECL(int) PGMR3DumpHierarchyShw(PVM pVM, uint64_t cr3, uint32_t fFlags, uint64_t u64FirstAddr, uint64_t u64LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp); VMMR3_INT_DECL(int) PGMR3DumpHierarchyGst(PVM pVM, uint64_t cr3, uint32_t fFlags, RTGCPTR FirstAddr, RTGCPTR LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp); diff --git a/include/VBox/vmm/rem.h b/include/VBox/vmm/rem.h index 79a18810..bda6e29a 100644 --- a/include/VBox/vmm/rem.h +++ b/include/VBox/vmm/rem.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/vmm/selm.h b/include/VBox/vmm/selm.h index 763d0acf..7503e734 100644 --- a/include/VBox/vmm/selm.h +++ b/include/VBox/vmm/selm.h @@ -41,7 +41,6 @@ RT_C_DECLS_BEGIN VMMDECL(RTSEL) SELMGetTrap8Selector(PVM pVM); VMMDECL(void) SELMSetTrap8EIP(PVM pVM, uint32_t u32EIP); VMMDECL(int) SELMGetRing1Stack(PVM pVM, uint32_t *pSS, PRTGCPTR32 pEsp); -VMMDECL(RTGCPTR) SELMGetGuestTSS(PVM pVM); VMMDECL(RTSEL) SELMGetHyperCS(PVM pVM); VMMDECL(RTSEL) SELMGetHyperCS64(PVM pVM); VMMDECL(RTSEL) SELMGetHyperDS(PVM pVM); @@ -94,11 +93,12 @@ VMMR3DECL(int) SELMR3InitFinalize(PVM pVM); VMMR3DECL(void) SELMR3Relocate(PVM pVM); VMMR3DECL(int) SELMR3Term(PVM pVM); VMMR3DECL(void) SELMR3Reset(PVM pVM); +# ifdef VBOX_WITH_RAW_MODE VMMR3DECL(VBOXSTRICTRC) SELMR3UpdateFromCPUM(PVM pVM, PVMCPU pVCpu); VMMR3DECL(int) SELMR3SyncTSS(PVM pVM, PVMCPU pVCpu); +# endif VMMR3DECL(int) SELMR3GetSelectorInfo(PVM pVM, PVMCPU pVCpu, RTSEL Sel, PDBGFSELINFO pSelInfo); VMMR3DECL(int) SELMR3GetShadowSelectorInfo(PVM pVM, RTSEL Sel, PDBGFSELINFO pSelInfo); -VMMR3DECL(void) SELMR3DisableMonitoring(PVM pVM); VMMR3DECL(void) SELMR3DumpDescriptor(X86DESC Desc, RTSEL Sel, const char *pszMsg); VMMR3DECL(void) SELMR3DumpHyperGDT(PVM pVM); VMMR3DECL(void) SELMR3DumpHyperLDT(PVM pVM); @@ -106,6 +106,10 @@ VMMR3DECL(void) SELMR3DumpGuestGDT(PVM pVM); VMMR3DECL(void) SELMR3DumpGuestLDT(PVM pVM); VMMR3DECL(bool) SELMR3CheckTSS(PVM pVM); VMMR3DECL(int) SELMR3DebugCheck(PVM pVM); +# ifdef VBOX_WITH_SAFE_STR +VMMR3DECL(bool) SELMR3CheckShadowTR(PVM pVM); +# endif + /** @def SELMR3_DEBUG_CHECK * Invokes SELMR3DebugCheck in stricts builds. */ # ifdef VBOX_STRICT diff --git a/include/VBox/vmm/ssm.h b/include/VBox/vmm/ssm.h index 427e0796..8218930f 100644 --- a/include/VBox/vmm/ssm.h +++ b/include/VBox/vmm/ssm.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -377,7 +377,11 @@ typedef struct SSMFIELD #define SSMSTRUCT_FLAGS_DONT_IGNORE RT_BIT_32(2) /** Saved using SSMR3PutMem, don't be too strict. */ #define SSMSTRUCT_FLAGS_SAVED_AS_MEM RT_BIT_32(3) -/** Band-aid for old SSMR3PutMem/SSMR3GetMem of structurs with host pointers. */ +/** Band-aid for old SSMR3PutMem/SSMR3GetMem of structurs with host pointers. + * @remarks This type is normally only used up to the first changes to the + * structures take place in order to make sure the conversion from + * SSMR3PutMem to field descriptors went smoothly. Replace with + * SSMSTRUCT_FLAGS_MEM_BAND_AID_RELAXED when changing the structure. */ #define SSMSTRUCT_FLAGS_MEM_BAND_AID ( SSMSTRUCT_FLAGS_DONT_IGNORE | SSMSTRUCT_FLAGS_FULL_STRUCT \ | SSMSTRUCT_FLAGS_NO_MARKERS | SSMSTRUCT_FLAGS_SAVED_AS_MEM) /** Band-aid for old SSMR3PutMem/SSMR3GetMem of structurs with host @@ -399,6 +403,7 @@ typedef struct SSMFIELD * @returns VBox status code. * @param pDevIns Device instance of the device which registered the data unit. * @param pSSM SSM operation handle. + * @remarks The caller enters the device critical section prior to the call. * @thread Any. */ typedef DECLCALLBACK(int) FNSSMDEVLIVEPREP(PPDMDEVINS pDevIns, PSSMHANDLE pSSM); @@ -415,6 +420,7 @@ typedef FNSSMDEVLIVEPREP *PFNSSMDEVLIVEPREP; * @param pDevIns Device instance of the device which registered the data unit. * @param pSSM SSM operation handle. * @param uPass The pass. + * @remarks The caller enters the device critical section prior to the call. * @thread Any. */ typedef DECLCALLBACK(int) FNSSMDEVLIVEEXEC(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass); @@ -437,6 +443,7 @@ typedef FNSSMDEVLIVEEXEC *PFNSSMDEVLIVEEXEC; * @param pDevIns Device instance of the device which registered the data unit. * @param pSSM SSM operation handle. * @param uPass The data pass. + * @remarks The caller enters the device critical section prior to the call. * @thread Any. */ typedef DECLCALLBACK(int) FNSSMDEVLIVEVOTE(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass); @@ -449,6 +456,7 @@ typedef FNSSMDEVLIVEVOTE *PFNSSMDEVLIVEVOTE; * @returns VBox status code. * @param pDevIns Device instance of the device which registered the data unit. * @param pSSM SSM operation handle. + * @remarks The caller enters the device critical section prior to the call. */ typedef DECLCALLBACK(int) FNSSMDEVSAVEPREP(PPDMDEVINS pDevIns, PSSMHANDLE pSSM); /** Pointer to a FNSSMDEVSAVEPREP() function. */ @@ -460,6 +468,7 @@ typedef FNSSMDEVSAVEPREP *PFNSSMDEVSAVEPREP; * @returns VBox status code. * @param pDevIns Device instance of the device which registered the data unit. * @param pSSM SSM operation handle. + * @remarks The caller enters the device critical section prior to the call. */ typedef DECLCALLBACK(int) FNSSMDEVSAVEEXEC(PPDMDEVINS pDevIns, PSSMHANDLE pSSM); /** Pointer to a FNSSMDEVSAVEEXEC() function. */ @@ -471,6 +480,7 @@ typedef FNSSMDEVSAVEEXEC *PFNSSMDEVSAVEEXEC; * @returns VBox status code. * @param pDevIns Device instance of the device which registered the data unit. * @param pSSM SSM operation handle. + * @remarks The caller enters the device critical section prior to the call. */ typedef DECLCALLBACK(int) FNSSMDEVSAVEDONE(PPDMDEVINS pDevIns, PSSMHANDLE pSSM); /** Pointer to a FNSSMDEVSAVEDONE() function. */ @@ -482,6 +492,7 @@ typedef FNSSMDEVSAVEDONE *PFNSSMDEVSAVEDONE; * @returns VBox status code. * @param pDevIns Device instance of the device which registered the data unit. * @param pSSM SSM operation handle. + * @remarks The caller enters the device critical section prior to the call. */ typedef DECLCALLBACK(int) FNSSMDEVLOADPREP(PPDMDEVINS pDevIns, PSSMHANDLE pSSM); /** Pointer to a FNSSMDEVLOADPREP() function. */ @@ -496,6 +507,7 @@ typedef FNSSMDEVLOADPREP *PFNSSMDEVLOADPREP; * @param uVersion Data layout version. * @param uPass The pass. This is always SSM_PASS_FINAL for units * that doesn't specify a pfnSaveLive callback. + * @remarks The caller enters the device critical section prior to the call. */ typedef DECLCALLBACK(int) FNSSMDEVLOADEXEC(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass); /** Pointer to a FNSSMDEVLOADEXEC() function. */ @@ -507,6 +519,7 @@ typedef FNSSMDEVLOADEXEC *PFNSSMDEVLOADEXEC; * @returns VBox load code. * @param pDevIns Device instance of the device which registered the data unit. * @param pSSM SSM operation handle. + * @remarks The caller enters the device critical section prior to the call. */ typedef DECLCALLBACK(int) FNSSMDEVLOADDONE(PPDMDEVINS pDevIns, PSSMHANDLE pSSM); /** Pointer to a FNSSMDEVLOADDONE() function. */ @@ -1131,22 +1144,28 @@ typedef struct SSMSTRMOPS VMMR3_INT_DECL(void) SSMR3Term(PVM pVM); -VMMR3DECL(int) SSMR3RegisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess, const char *pszBefore, - PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote, - PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone, - PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone); -VMMR3DECL(int) SSMR3RegisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess, - PFNSSMDRVLIVEPREP pfnLivePrep, PFNSSMDRVLIVEEXEC pfnLiveExec, PFNSSMDRVLIVEVOTE pfnLiveVote, - PFNSSMDRVSAVEPREP pfnSavePrep, PFNSSMDRVSAVEEXEC pfnSaveExec, PFNSSMDRVSAVEDONE pfnSaveDone, - PFNSSMDRVLOADPREP pfnLoadPrep, PFNSSMDRVLOADEXEC pfnLoadExec, PFNSSMDRVLOADDONE pfnLoadDone); -VMMR3DECL(int) SSMR3RegisterInternal(PVM pVM, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess, - PFNSSMINTLIVEPREP pfnLivePrep, PFNSSMINTLIVEEXEC pfnLiveExec, PFNSSMINTLIVEVOTE pfnLiveVote, - PFNSSMINTSAVEPREP pfnSavePrep, PFNSSMINTSAVEEXEC pfnSaveExec, PFNSSMINTSAVEDONE pfnSaveDone, - PFNSSMINTLOADPREP pfnLoadPrep, PFNSSMINTLOADEXEC pfnLoadExec, PFNSSMINTLOADDONE pfnLoadDone); -VMMR3DECL(int) SSMR3RegisterExternal(PVM pVM, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess, - PFNSSMEXTLIVEPREP pfnLivePrep, PFNSSMEXTLIVEEXEC pfnLiveExec, PFNSSMEXTLIVEVOTE pfnLiveVote, - PFNSSMEXTSAVEPREP pfnSavePrep, PFNSSMEXTSAVEEXEC pfnSaveExec, PFNSSMEXTSAVEDONE pfnSaveDone, - PFNSSMEXTLOADPREP pfnLoadPrep, PFNSSMEXTLOADEXEC pfnLoadExec, PFNSSMEXTLOADDONE pfnLoadDone, void *pvUser); +VMMR3_INT_DECL(int) +SSMR3RegisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName, uint32_t uInstance, uint32_t uVersion, + size_t cbGuess, const char *pszBefore, + PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote, + PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone, + PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone); +VMMR3_INT_DECL(int) +SSMR3RegisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess, + PFNSSMDRVLIVEPREP pfnLivePrep, PFNSSMDRVLIVEEXEC pfnLiveExec, PFNSSMDRVLIVEVOTE pfnLiveVote, + PFNSSMDRVSAVEPREP pfnSavePrep, PFNSSMDRVSAVEEXEC pfnSaveExec, PFNSSMDRVSAVEDONE pfnSaveDone, + PFNSSMDRVLOADPREP pfnLoadPrep, PFNSSMDRVLOADEXEC pfnLoadExec, PFNSSMDRVLOADDONE pfnLoadDone); +VMMR3DECL(int) +SSMR3RegisterInternal(PVM pVM, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess, + PFNSSMINTLIVEPREP pfnLivePrep, PFNSSMINTLIVEEXEC pfnLiveExec, PFNSSMINTLIVEVOTE pfnLiveVote, + PFNSSMINTSAVEPREP pfnSavePrep, PFNSSMINTSAVEEXEC pfnSaveExec, PFNSSMINTSAVEDONE pfnSaveDone, + PFNSSMINTLOADPREP pfnLoadPrep, PFNSSMINTLOADEXEC pfnLoadExec, PFNSSMINTLOADDONE pfnLoadDone); +VMMR3DECL(int) +SSMR3RegisterExternal(PUVM pUVM, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess, + PFNSSMEXTLIVEPREP pfnLivePrep, PFNSSMEXTLIVEEXEC pfnLiveExec, PFNSSMEXTLIVEVOTE pfnLiveVote, + PFNSSMEXTSAVEPREP pfnSavePrep, PFNSSMEXTSAVEEXEC pfnSaveExec, PFNSSMEXTSAVEDONE pfnSaveDone, + PFNSSMEXTLOADPREP pfnLoadPrep, PFNSSMEXTLOADEXEC pfnLoadExec, PFNSSMEXTLOADDONE pfnLoadDone, void *pvUser); +VMMR3DECL(int) SSMR3RegisterStub(PVM pVM, const char *pszName, uint32_t uInstance); VMMR3_INT_DECL(int) SSMR3DeregisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName, uint32_t uInstance); VMMR3_INT_DECL(int) SSMR3DeregisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName, uint32_t uInstance); VMMR3DECL(int) SSMR3DeregisterInternal(PVM pVM, const char *pszName); @@ -1176,7 +1195,7 @@ VMMR3DECL(uint32_t) SSMR3HandleVersion(PSSMHANDLE pSSM); VMMR3DECL(const char *) SSMR3HandleHostOSAndArch(PSSMHANDLE pSSM); VMMR3_INT_DECL(int) SSMR3HandleSetGCPtrSize(PSSMHANDLE pSSM, unsigned cbGCPtr); VMMR3DECL(void) SSMR3HandleReportLivePercent(PSSMHANDLE pSSM, unsigned uPercent); -VMMR3DECL(int) SSMR3Cancel(PVM pVM); +VMMR3DECL(int) SSMR3Cancel(PUVM pUVM); /** Save operations. diff --git a/include/VBox/vmm/stam.h b/include/VBox/vmm/stam.h index c25c606f..e7f2c556 100644 --- a/include/VBox/vmm/stam.h +++ b/include/VBox/vmm/stam.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -1200,38 +1200,17 @@ VMMR3DECL(int) STAMR3RegisterCallback(PVM pVM, void *pvSample, STAMVISIBILITY e VMMR3DECL(int) STAMR3RegisterCallbackV(PVM pVM, void *pvSample, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, PFNSTAMR3CALLBACKRESET pfnReset, PFNSTAMR3CALLBACKPRINT pfnPrint, const char *pszDesc, const char *pszName, va_list args); -VMMR3DECL(int) STAMR3DeregisterU(PUVM pUVM, void *pvSample); -VMMR3DECL(int) STAMR3Deregister(PVM pVM, void *pvSample); - -/** @def STAM_REL_DEREG - * Deregisters a statistics sample if statistics are enabled. - * - * @param pVM VM Handle. - * @param pvSample Pointer to the sample. - */ -#define STAM_REL_DEREG(pVM, pvSample) \ - STAM_REL_STATS({ int rcStam = STAMR3Deregister(pVM, pvSample); AssertRC(rcStam); }) -/** @def STAM_DEREG - * Deregisters a statistics sample if statistics are enabled. - * - * @param pVM VM Handle. - * @param pvSample Pointer to the sample. - */ -#define STAM_DEREG(pVM, pvSample) \ - STAM_STATS({ STAM_REL_DEREG(pVM, pvSample); }) - -VMMR3DECL(int) STAMR3ResetU(PUVM pUVM, const char *pszPat); -VMMR3DECL(int) STAMR3Reset(PVM pVM, const char *pszPat); -VMMR3DECL(int) STAMR3SnapshotU(PUVM pUVM, const char *pszPat, char **ppszSnapshot, size_t *pcchSnapshot, bool fWithDesc); -VMMR3DECL(int) STAMR3Snapshot(PVM pVM, const char *pszPat, char **ppszSnapshot, size_t *pcchSnapshot, bool fWithDesc); -VMMR3DECL(int) STAMR3SnapshotFreeU(PUVM pUVM, char *pszSnapshot); -VMMR3DECL(int) STAMR3SnapshotFree(PVM pVM, char *pszSnapshot); -VMMR3DECL(int) STAMR3DumpU(PUVM pUVM, const char *pszPat); -VMMR3DECL(int) STAMR3Dump(PVM pVM, const char *pszPat); -VMMR3DECL(int) STAMR3DumpToReleaseLogU(PUVM pUVM, const char *pszPat); -VMMR3DECL(int) STAMR3DumpToReleaseLog(PVM pVM, const char *pszPat); -VMMR3DECL(int) STAMR3PrintU(PUVM pUVM, const char *pszPat); -VMMR3DECL(int) STAMR3Print(PVM pVM, const char *pszPat); +VMMR3DECL(int) STAMR3Deregister(PUVM pUVM, const char *pszPat); +VMMR3DECL(int) STAMR3DeregisterF(PUVM pUVM, const char *pszPatFmt, ...); +VMMR3DECL(int) STAMR3DeregisterV(PUVM pUVM, const char *pszPatFmt, va_list va); +VMMR3DECL(int) STAMR3DeregisterByAddr(PUVM pUVM, void *pvSample); + +VMMR3DECL(int) STAMR3Reset(PUVM pUVM, const char *pszPat); +VMMR3DECL(int) STAMR3Snapshot(PUVM pUVM, const char *pszPat, char **ppszSnapshot, size_t *pcchSnapshot, bool fWithDesc); +VMMR3DECL(int) STAMR3SnapshotFree(PUVM pUVM, char *pszSnapshot); +VMMR3DECL(int) STAMR3Dump(PUVM pUVM, const char *pszPat); +VMMR3DECL(int) STAMR3DumpToReleaseLog(PUVM pUVM, const char *pszPat); +VMMR3DECL(int) STAMR3Print(PUVM pUVM, const char *pszPat); /** * Callback function for STAMR3Enum(). @@ -1251,8 +1230,7 @@ typedef DECLCALLBACK(int) FNSTAMR3ENUM(const char *pszName, STAMTYPE enmType, vo /** Pointer to a FNSTAMR3ENUM(). */ typedef FNSTAMR3ENUM *PFNSTAMR3ENUM; -VMMR3DECL(int) STAMR3EnumU(PUVM pUVM, const char *pszPat, PFNSTAMR3ENUM pfnEnum, void *pvUser); -VMMR3DECL(int) STAMR3Enum(PVM pVM, const char *pszPat, PFNSTAMR3ENUM pfnEnum, void *pvUser); +VMMR3DECL(int) STAMR3Enum(PUVM pUVM, const char *pszPat, PFNSTAMR3ENUM pfnEnum, void *pvUser); VMMR3DECL(const char *) STAMR3GetUnit(STAMUNIT enmUnit); /** @} */ diff --git a/include/VBox/vmm/tm.h b/include/VBox/vmm/tm.h index be328b1c..8f857a4c 100644 --- a/include/VBox/vmm/tm.h +++ b/include/VBox/vmm/tm.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -87,9 +87,9 @@ VMM_INT_DECL(void) TMNotifyEndOfHalt(PVMCPU pVCpu); #ifdef IN_RING3 VMMR3DECL(int) TMR3NotifySuspend(PVM pVM, PVMCPU pVCpu); VMMR3DECL(int) TMR3NotifyResume(PVM pVM, PVMCPU pVCpu); -VMMR3DECL(int) TMR3SetWarpDrive(PVM pVM, uint32_t u32Percent); +VMMR3DECL(int) TMR3SetWarpDrive(PUVM pUVM, uint32_t u32Percent); +VMMR3DECL(uint32_t) TMR3GetWarpDrive(PUVM pUVM); #endif -VMMDECL(uint32_t) TMGetWarpDrive(PVM pVM); VMM_INT_DECL(uint32_t) TMCalcHostTimerFrequency(PVM pVM, PVMCPU pVCpu); #ifdef IN_RING3 VMMR3DECL(int) TMR3GetCpuLoadTimes(PVM pVM, VMCPUID idCpu, uint64_t *pcNsTotal, uint64_t *pcNsExecuting, diff --git a/include/VBox/vmm/trpm.h b/include/VBox/vmm/trpm.h index 0cdfc153..7dc436c6 100644 --- a/include/VBox/vmm/trpm.h +++ b/include/VBox/vmm/trpm.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -68,17 +68,20 @@ typedef TRPMEVENT const *PCTRPMEVENT; */ #define TRPM_INVALID_HANDLER 0 -VMMDECL(int) TRPMQueryTrap(PVMCPU pVCpu, uint8_t *pu8TrapNo, PTRPMEVENT pEnmType); +VMMDECL(int) TRPMQueryTrap(PVMCPU pVCpu, uint8_t *pu8TrapNo, PTRPMEVENT penmType); VMMDECL(uint8_t) TRPMGetTrapNo(PVMCPU pVCpu); VMMDECL(RTGCUINT) TRPMGetErrorCode(PVMCPU pVCpu); VMMDECL(RTGCUINTPTR) TRPMGetFaultAddress(PVMCPU pVCpu); +VMMDECL(uint8_t) TRPMGetInstrLength(PVMCPU pVCpu); VMMDECL(int) TRPMResetTrap(PVMCPU pVCpu); VMMDECL(int) TRPMAssertTrap(PVMCPU pVCpu, uint8_t u8TrapNo, TRPMEVENT enmType); +VMMDECL(int) TRPMAssertXcptPF(PVMCPU pVCpu, RTGCUINTPTR uCR2, RTGCUINT uErrorCode); VMMDECL(void) TRPMSetErrorCode(PVMCPU pVCpu, RTGCUINT uErrorCode); VMMDECL(void) TRPMSetFaultAddress(PVMCPU pVCpu, RTGCUINTPTR uCR2); +VMMDECL(void) TRPMSetInstrLength(PVMCPU pVCpu, uint8_t cbInstr); VMMDECL(bool) TRPMIsSoftwareInterrupt(PVMCPU pVCpu); VMMDECL(bool) TRPMHasTrap(PVMCPU pVCpu); -VMMDECL(int) TRPMQueryTrapAll(PVMCPU pVCpu, uint8_t *pu8TrapNo, PTRPMEVENT pEnmType, PRTGCUINT puErrorCode, PRTGCUINTPTR puCR2); +VMMDECL(int) TRPMQueryTrapAll(PVMCPU pVCpu, uint8_t *pu8TrapNo, PTRPMEVENT pEnmType, PRTGCUINT puErrorCode, PRTGCUINTPTR puCR2, uint8_t *pcbInstr); VMMDECL(void) TRPMSaveTrap(PVMCPU pVCpu); VMMDECL(void) TRPMRestoreTrap(PVMCPU pVCpu); VMMDECL(int) TRPMForwardTrap(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t iGate, uint32_t cbInstr, TRPMERRORCODE enmError, TRPMEVENT enmType, int32_t iOrgTrap); @@ -96,16 +99,17 @@ VMMR3DECL(int) TRPMR3Init(PVM pVM); VMMR3DECL(void) TRPMR3Relocate(PVM pVM, RTGCINTPTR offDelta); VMMR3DECL(void) TRPMR3ResetCpu(PVMCPU pVCpu); VMMR3DECL(void) TRPMR3Reset(PVM pVM); -VMMR3_INT_DECL(int) TRPMR3GetImportRC(PVM pVM, const char *pszSymbol, PRTRCPTR pRCPtrValue); VMMR3DECL(int) TRPMR3Term(PVM pVM); -VMMR3DECL(int) TRPMR3EnableGuestTrapHandler(PVM pVM, unsigned iTrap); -VMMR3DECL(int) TRPMR3SetGuestTrapHandler(PVM pVM, unsigned iTrap, RTRCPTR pHandler); -VMMR3DECL(RTRCPTR) TRPMR3GetGuestTrapHandler(PVM pVM, unsigned iTrap); -VMMR3DECL(void) TRPMR3DisableMonitoring(PVM pVM); +VMMR3DECL(int) TRPMR3InjectEvent(PVM pVM, PVMCPU pVCpu, TRPMEVENT enmEvent); +# ifdef VBOX_WITH_RAW_MODE +VMMR3_INT_DECL(int) TRPMR3GetImportRC(PVM pVM, const char *pszSymbol, PRTRCPTR pRCPtrValue); VMMR3DECL(int) TRPMR3SyncIDT(PVM pVM, PVMCPU pVCpu); VMMR3DECL(bool) TRPMR3IsGateHandler(PVM pVM, RTRCPTR GCPtr); VMMR3DECL(uint32_t) TRPMR3QueryGateByHandler(PVM pVM, RTRCPTR GCPtr); -VMMR3DECL(int) TRPMR3InjectEvent(PVM pVM, PVMCPU pVCpu, TRPMEVENT enmEvent); +VMMR3DECL(int) TRPMR3EnableGuestTrapHandler(PVM pVM, unsigned iTrap); +VMMR3DECL(int) TRPMR3SetGuestTrapHandler(PVM pVM, unsigned iTrap, RTRCPTR pHandler); +VMMR3DECL(RTRCPTR) TRPMR3GetGuestTrapHandler(PVM pVM, unsigned iTrap); +# endif /** @} */ #endif diff --git a/include/VBox/vmm/uvm.h b/include/VBox/vmm/uvm.h index 10b8e49b..37087752 100644 --- a/include/VBox/vmm/uvm.h +++ b/include/VBox/vmm/uvm.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2007-2010 Oracle Corporation + * Copyright (C) 2007-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -55,6 +55,16 @@ typedef struct UVMCPU #endif uint8_t padding[512]; } vm; + + /** The DBGF data. */ + union + { +#ifdef ___DBGFInternal_h + struct DBGFUSERPERVMCPU s; +#endif + uint8_t padding[64]; + } dbgf; + } UVMCPU; AssertCompileMemberAlignment(UVMCPU, vm, 32); @@ -114,7 +124,7 @@ typedef struct UVM #ifdef ___PDMInternal_h struct PDMUSERPERVM s; #endif - uint8_t padding[128]; + uint8_t padding[256]; } pdm; /** The STAM data. */ @@ -123,9 +133,18 @@ typedef struct UVM #ifdef ___STAMInternal_h struct STAMUSERPERVM s; #endif - uint8_t padding[6624]; + uint8_t padding[6880]; } stam; + /** The DBGF data. */ + union + { +#ifdef ___DBGFInternal_h + struct DBGFUSERPERVM s; +#endif + uint8_t padding[256]; + } dbgf; + /** Per virtual CPU data. */ UVMCPU aCpus[1]; } UVM; diff --git a/include/VBox/vmm/vm.h b/include/VBox/vmm/vm.h index ef713127..bebb9836 100644 --- a/include/VBox/vmm/vm.h +++ b/include/VBox/vmm/vm.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2012 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -68,7 +68,9 @@ typedef enum VMCPUSTATE /** CPU started. */ VMCPUSTATE_STARTED, - /** Executing guest code and can be poked. */ + /** CPU started in HM context. */ + VMCPUSTATE_STARTED_HM, + /** Executing guest code and can be poked (RC or STI bits of HM). */ VMCPUSTATE_STARTED_EXEC, /** Executing guest code in the recompiler. */ VMCPUSTATE_STARTED_EXEC_REM, @@ -84,7 +86,9 @@ typedef enum VMCPUSTATE /** - * Per virtual CPU data. + * The cross context virtual CPU structure. + * + * Run 'kmk run-struct-tests' (from src/VBox/VMM if you like) after updating! */ typedef struct VMCPU { @@ -110,7 +114,7 @@ typedef struct VMCPU /** The native R0 thread handle. (different from the R3 handle!) */ RTNATIVETHREAD hNativeThreadR0; /* 48 / 32 */ /** Which host CPU ID is this EMT running on. - * Only valid when in RC or HWACCMR0 with scheduling disabled. */ + * Only valid when in RC or HMR0 with scheduling disabled. */ RTCPUID volatile idHostCpu; /* 56 / 36 */ /** Trace groups enable flags. */ @@ -138,14 +142,14 @@ typedef struct VMCPU uint8_t padding[3584]; /* multiple of 64 */ } cpum; - /** HWACCM part. */ + /** HM part. */ union { -#ifdef ___HWACCMInternal_h - struct HWACCMCPU s; +#ifdef ___HMInternal_h + struct HMCPU s; #endif - uint8_t padding[5376]; /* multiple of 64 */ - } hwaccm; + uint8_t padding[5568]; /* multiple of 64 */ + } hm; /** EM part. */ union @@ -189,7 +193,7 @@ typedef struct VMCPU #ifdef ___VMMInternal_h struct VMMCPU s; #endif - uint8_t padding[640]; /* multiple of 64 */ + uint8_t padding[704]; /* multiple of 64 */ } vmm; /** PDM part. */ @@ -198,7 +202,7 @@ typedef struct VMCPU #ifdef ___PDMInternal_h struct PDMCPU s; #endif - uint8_t padding[128]; /* multiple of 64 */ + uint8_t padding[256]; /* multiple of 64 */ } pdm; /** IOM part. */ @@ -221,7 +225,7 @@ typedef struct VMCPU } dbgf; /** Align the following members on page boundary. */ - uint8_t abAlignment2[1024 - 320 - 128]; + uint8_t abAlignment2[192]; /** PGM part. */ union @@ -271,6 +275,16 @@ typedef struct VMCPU /** The name of the Ring 0 Context VMM Core module. */ #define VMMR0_MAIN_MODULE_NAME "VMMR0.r0" +/** + * Wrapper macro for avoiding too much \#ifdef VBOX_WITH_RAW_MODE. + */ +#ifdef VBOX_WITH_RAW_MODE +# define VM_WHEN_RAW_MODE(a_WithExpr, a_WithoutExpr) a_WithExpr +#else +# define VM_WHEN_RAW_MODE(a_WithExpr, a_WithoutExpr) a_WithoutExpr +#endif + + /** VM Forced Action Flags. * * Use the VM_FF_SET() and VM_FF_CLEAR() macros to change the force @@ -347,6 +361,12 @@ typedef struct VMCPU /** This action forces the VM to service pending requests from other * thread or requests which must be executed in another context. */ #define VMCPU_FF_REQUEST RT_BIT_32(9) +/** This action forces the VM to service any pending updates to CR3 (used only + * by HM). */ +#define VMCPU_FF_HM_UPDATE_CR3 RT_BIT_32(12) +/** This action forces the VM to service any pending updates to PAE PDPEs (used + * only by HM). */ +#define VMCPU_FF_HM_UPDATE_PAE_PDPES RT_BIT_32(13) /** This action forces the VM to resync the page tables before going * back to execute guest code. (GLOBAL FLUSH) */ #define VMCPU_FF_PGM_SYNC_CR3 RT_BIT_32(16) @@ -354,29 +374,33 @@ typedef struct VMCPU * (NON-GLOBAL FLUSH) */ #define VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL RT_BIT_32(17) /** Check for pending TLB shootdown actions. - * Consumer: HWACCM - * @todo rename to VMCPU_FF_HWACCM_TLB_SHOOTDOWN */ + * Consumer: HM + * @todo rename to VMCPU_FF_HM_TLB_SHOOTDOWN */ #define VMCPU_FF_TLB_SHOOTDOWN RT_BIT_32(18) /** Check for pending TLB flush action. - * Consumer: HWACCM - * @todo rename to VMCPU_FF_HWACCM_TLB_FLUSH */ + * Consumer: HM + * @todo rename to VMCPU_FF_HM_TLB_FLUSH */ #define VMCPU_FF_TLB_FLUSH RT_BIT_32(VMCPU_FF_TLB_FLUSH_BIT) /** The bit number for VMCPU_FF_TLB_FLUSH. */ #define VMCPU_FF_TLB_FLUSH_BIT 19 +#ifdef VBOX_WITH_RAW_MODE /** Check the interrupt and trap gates */ -#define VMCPU_FF_TRPM_SYNC_IDT RT_BIT_32(20) +# define VMCPU_FF_TRPM_SYNC_IDT RT_BIT_32(20) /** Check Guest's TSS ring 0 stack */ -#define VMCPU_FF_SELM_SYNC_TSS RT_BIT_32(21) +# define VMCPU_FF_SELM_SYNC_TSS RT_BIT_32(21) /** Check Guest's GDT table */ -#define VMCPU_FF_SELM_SYNC_GDT RT_BIT_32(22) +# define VMCPU_FF_SELM_SYNC_GDT RT_BIT_32(22) /** Check Guest's LDT table */ -#define VMCPU_FF_SELM_SYNC_LDT RT_BIT_32(23) +# define VMCPU_FF_SELM_SYNC_LDT RT_BIT_32(23) +#endif /* VBOX_WITH_RAW_MODE */ /** Inhibit interrupts pending. See EMGetInhibitInterruptsPC(). */ #define VMCPU_FF_INHIBIT_INTERRUPTS RT_BIT_32(24) +#ifdef VBOX_WITH_RAW_MODE /** CSAM needs to scan the page that's being executed */ -#define VMCPU_FF_CSAM_SCAN_PAGE RT_BIT_32(26) +# define VMCPU_FF_CSAM_SCAN_PAGE RT_BIT_32(26) /** CSAM needs to do some homework. */ -#define VMCPU_FF_CSAM_PENDING_ACTION RT_BIT_32(27) +# define VMCPU_FF_CSAM_PENDING_ACTION RT_BIT_32(27) +#endif /* VBOX_WITH_RAW_MODE */ /** Force return to Ring-3. */ #define VMCPU_FF_TO_R3 RT_BIT_32(28) @@ -389,45 +413,67 @@ typedef struct VMCPU #define VM_FF_EXTERNAL_HALTED_MASK ( VM_FF_CHECK_VM_STATE | VM_FF_DBGF | VM_FF_REQUEST \ | VM_FF_PDM_QUEUES | VM_FF_PDM_DMA | VM_FF_EMT_RENDEZVOUS) /** Externally forced VMCPU actions. Used to quit the idle/wait loop. */ -#define VMCPU_FF_EXTERNAL_HALTED_MASK (VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_REQUEST | VMCPU_FF_TIMER) +#define VMCPU_FF_EXTERNAL_HALTED_MASK ( VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_REQUEST \ + | VMCPU_FF_TIMER) /** High priority VM pre-execution actions. */ #define VM_FF_HIGH_PRIORITY_PRE_MASK ( VM_FF_CHECK_VM_STATE | VM_FF_DBGF | VM_FF_TM_VIRTUAL_SYNC \ - | VM_FF_DEBUG_SUSPEND | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY | VM_FF_EMT_RENDEZVOUS) + | VM_FF_DEBUG_SUSPEND | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY \ + | VM_FF_EMT_RENDEZVOUS) /** High priority VMCPU pre-execution actions. */ -#define VMCPU_FF_HIGH_PRIORITY_PRE_MASK ( VMCPU_FF_TIMER | VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_PGM_SYNC_CR3 \ - | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL | VMCPU_FF_SELM_SYNC_TSS | VMCPU_FF_TRPM_SYNC_IDT \ - | VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT | VMCPU_FF_INHIBIT_INTERRUPTS) +#define VMCPU_FF_HIGH_PRIORITY_PRE_MASK ( VMCPU_FF_TIMER | VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC \ + | VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL \ + | VMCPU_FF_INHIBIT_INTERRUPTS \ + | VM_WHEN_RAW_MODE( VMCPU_FF_SELM_SYNC_TSS | VMCPU_FF_TRPM_SYNC_IDT \ + | VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT, 0 ) ) /** High priority VM pre raw-mode execution mask. */ #define VM_FF_HIGH_PRIORITY_PRE_RAW_MASK (VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY) /** High priority VMCPU pre raw-mode execution mask. */ -#define VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK ( VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL | VMCPU_FF_SELM_SYNC_TSS | VMCPU_FF_TRPM_SYNC_IDT \ - | VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT | VMCPU_FF_INHIBIT_INTERRUPTS) +#define VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK ( VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL \ + | VMCPU_FF_INHIBIT_INTERRUPTS \ + | VM_WHEN_RAW_MODE( VMCPU_FF_SELM_SYNC_TSS | VMCPU_FF_TRPM_SYNC_IDT \ + | VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT, 0) ) /** High priority post-execution actions. */ #define VM_FF_HIGH_PRIORITY_POST_MASK (VM_FF_PGM_NO_MEMORY) /** High priority post-execution actions. */ -#define VMCPU_FF_HIGH_PRIORITY_POST_MASK (VMCPU_FF_PDM_CRITSECT|VMCPU_FF_CSAM_PENDING_ACTION) +#define VMCPU_FF_HIGH_PRIORITY_POST_MASK ( VMCPU_FF_PDM_CRITSECT | VM_WHEN_RAW_MODE(VMCPU_FF_CSAM_PENDING_ACTION, 0) \ + | VMCPU_FF_HM_UPDATE_CR3 | VMCPU_FF_HM_UPDATE_PAE_PDPES) /** Normal priority VM post-execution actions. */ #define VM_FF_NORMAL_PRIORITY_POST_MASK ( VM_FF_CHECK_VM_STATE | VM_FF_DBGF | VM_FF_RESET \ | VM_FF_PGM_NO_MEMORY | VM_FF_EMT_RENDEZVOUS) /** Normal priority VMCPU post-execution actions. */ -#define VMCPU_FF_NORMAL_PRIORITY_POST_MASK (VMCPU_FF_CSAM_SCAN_PAGE) +#define VMCPU_FF_NORMAL_PRIORITY_POST_MASK VM_WHEN_RAW_MODE(VMCPU_FF_CSAM_SCAN_PAGE, 0) /** Normal priority VM actions. */ -#define VM_FF_NORMAL_PRIORITY_MASK (VM_FF_REQUEST | VM_FF_PDM_QUEUES | VM_FF_PDM_DMA | VM_FF_REM_HANDLER_NOTIFY | VM_FF_EMT_RENDEZVOUS) +#define VM_FF_NORMAL_PRIORITY_MASK ( VM_FF_REQUEST | VM_FF_PDM_QUEUES | VM_FF_PDM_DMA | VM_FF_REM_HANDLER_NOTIFY \ + | VM_FF_EMT_RENDEZVOUS) /** Normal priority VMCPU actions. */ #define VMCPU_FF_NORMAL_PRIORITY_MASK (VMCPU_FF_REQUEST) /** Flags to clear before resuming guest execution. */ #define VMCPU_FF_RESUME_GUEST_MASK (VMCPU_FF_TO_R3) -/** VM Flags that cause the HWACCM loops to go back to ring-3. */ -#define VM_FF_HWACCM_TO_R3_MASK (VM_FF_TM_VIRTUAL_SYNC | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY | VM_FF_PDM_QUEUES | VM_FF_EMT_RENDEZVOUS) -/** VMCPU Flags that cause the HWACCM loops to go back to ring-3. */ -#define VMCPU_FF_HWACCM_TO_R3_MASK (VMCPU_FF_TO_R3 | VMCPU_FF_TIMER | VMCPU_FF_PDM_CRITSECT) +/** VM Flags that cause the HM loops to go back to ring-3. */ +#define VM_FF_HM_TO_R3_MASK ( VM_FF_TM_VIRTUAL_SYNC | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY \ + | VM_FF_PDM_QUEUES | VM_FF_EMT_RENDEZVOUS) +/** VMCPU Flags that cause the HM loops to go back to ring-3. */ +#define VMCPU_FF_HM_TO_R3_MASK (VMCPU_FF_TO_R3 | VMCPU_FF_TIMER | VMCPU_FF_PDM_CRITSECT) + +/** High priority ring-0 VM pre HM-mode execution mask. */ +#define VM_FF_HP_R0_PRE_HM_MASK (VM_FF_HM_TO_R3_MASK | VM_FF_REQUEST | VM_FF_PGM_POOL_FLUSH_PENDING | VM_FF_PDM_DMA) +/** High priority ring-0 VMCPU pre HM-mode execution mask. */ +#define VMCPU_FF_HP_R0_PRE_HM_MASK ( VMCPU_FF_HM_TO_R3_MASK | VMCPU_FF_PGM_SYNC_CR3 \ + | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL | VMCPU_FF_REQUEST) +/** High priority ring-0 VM pre HM-mode execution mask, single stepping. */ +#define VM_FF_HP_R0_PRE_HM_STEP_MASK (VM_FF_HP_R0_PRE_HM_MASK & ~( VM_FF_TM_VIRTUAL_SYNC | VM_FF_PDM_QUEUES \ + | VM_FF_EMT_RENDEZVOUS | VM_FF_REQUEST \ + | VM_FF_PDM_DMA) ) +/** High priority ring-0 VMCPU pre HM-mode execution mask, single stepping. */ +#define VMCPU_FF_HP_R0_PRE_HM_STEP_MASK (VMCPU_FF_HP_R0_PRE_HM_MASK & ~( VMCPU_FF_TO_R3 | VMCPU_FF_TIMER \ + | VMCPU_FF_PDM_CRITSECT | VMCPU_FF_REQUEST) ) /** All the forced VM flags. */ #define VM_FF_ALL_MASK (~0U) @@ -439,14 +485,15 @@ typedef struct VMCPU #define VM_FF_ALL_REM_MASK (~(VM_FF_HIGH_PRIORITY_PRE_RAW_MASK) | VM_FF_PGM_NO_MEMORY) /** All the forced VMCPU flags except those related to raw-mode and hardware * assisted execution. */ -#define VMCPU_FF_ALL_REM_MASK (~(VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK | VMCPU_FF_CSAM_PENDING_ACTION | VMCPU_FF_PDM_CRITSECT | VMCPU_FF_TLB_FLUSH | VMCPU_FF_TLB_SHOOTDOWN)) - +#define VMCPU_FF_ALL_REM_MASK (~( VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK | VMCPU_FF_PDM_CRITSECT \ + | VMCPU_FF_TLB_FLUSH | VMCPU_FF_TLB_SHOOTDOWN \ + | VM_WHEN_RAW_MODE(VMCPU_FF_CSAM_PENDING_ACTION, 0) )) /** @} */ /** @def VM_FF_SET * Sets a force action flag. * - * @param pVM VM Handle. + * @param pVM Pointer to the VM. * @param fFlag The flag to set. */ #if 1 @@ -461,15 +508,15 @@ typedef struct VMCPU /** @def VMCPU_FF_SET * Sets a force action flag for the given VCPU. * - * @param pVCpu VMCPU Handle. + * @param pVCpu Pointer to the VMCPU. * @param fFlag The flag to set. */ -#define VMCPU_FF_SET(pVCpu, fFlag) ASMAtomicOrU32(&(pVCpu)->fLocalForcedActions, (fFlag)) +#define VMCPU_FF_SET(pVCpu, fFlag) ASMAtomicOrU32(&(pVCpu)->fLocalForcedActions, (fFlag)) /** @def VM_FF_CLEAR * Clears a force action flag. * - * @param pVM VM Handle. + * @param pVM Pointer to the VM. * @param fFlag The flag to clear. */ #if 1 @@ -484,80 +531,68 @@ typedef struct VMCPU /** @def VMCPU_FF_CLEAR * Clears a force action flag for the given VCPU. * - * @param pVCpu VMCPU Handle. + * @param pVCpu Pointer to the VMCPU. * @param fFlag The flag to clear. */ -#define VMCPU_FF_CLEAR(pVCpu, fFlag) ASMAtomicAndU32(&(pVCpu)->fLocalForcedActions, ~(fFlag)) +#define VMCPU_FF_CLEAR(pVCpu, fFlag) ASMAtomicAndU32(&(pVCpu)->fLocalForcedActions, ~(fFlag)) -/** @def VM_FF_ISSET +/** @def VM_FF_IS_SET * Checks if a force action flag is set. * - * @param pVM VM Handle. + * @param pVM Pointer to the VM. * @param fFlag The flag to check. */ #define VM_FF_IS_SET(pVM, fFlag) (((pVM)->fGlobalForcedActions & (fFlag)) == (fFlag)) -/** @deprecated */ -#define VM_FF_ISSET(pVM, fFlag) VM_FF_IS_SET(pVM, fFlag) -/** @def VMCPU_FF_ISSET +/** @def VMCPU_FF_IS_SET * Checks if a force action flag is set for the given VCPU. * - * @param pVCpu VMCPU Handle. + * @param pVCpu Pointer to the VMCPU. * @param fFlag The flag to check. */ #define VMCPU_FF_IS_SET(pVCpu, fFlag) (((pVCpu)->fLocalForcedActions & (fFlag)) == (fFlag)) -/** @deprecated */ -#define VMCPU_FF_ISSET(pVCpu, fFlag) VMCPU_FF_IS_SET(pVCpu, fFlag) -/** @def VM_FF_ISPENDING +/** @def VM_FF_IS_PENDING * Checks if one or more force action in the specified set is pending. * - * @param pVM VM Handle. + * @param pVM Pointer to the VM. * @param fFlags The flags to check for. */ -#define VM_FF_IS_PENDING(pVM, fFlags) ((pVM)->fGlobalForcedActions & (fFlags)) -/** @deprecated */ -#define VM_FF_ISPENDING(pVM, fFlags) VM_FF_IS_PENDING(pVM, fFlags) +#define VM_FF_IS_PENDING(pVM, fFlags) RT_BOOL((pVM)->fGlobalForcedActions & (fFlags)) /** @def VM_FF_TESTANDCLEAR * Checks if one (!) force action in the specified set is pending and clears it atomically * * @returns true if the bit was set. * @returns false if the bit was clear. - * @param pVM VM Handle. + * @param pVM Pointer to the VM. * @param iBit Bit position to check and clear */ #define VM_FF_TEST_AND_CLEAR(pVM, iBit) (ASMAtomicBitTestAndClear(&(pVM)->fGlobalForcedActions, iBit##_BIT)) -/** @deprecated */ -#define VM_FF_TESTANDCLEAR(pVM, iBit) (ASMAtomicBitTestAndClear(&(pVM)->fGlobalForcedActions, iBit##_BIT)) /** @def VMCPU_FF_TESTANDCLEAR * Checks if one (!) force action in the specified set is pending and clears it atomically * * @returns true if the bit was set. * @returns false if the bit was clear. - * @param pVCpu VMCPU Handle. + * @param pVCpu Pointer to the VMCPU. * @param iBit Bit position to check and clear */ #define VMCPU_FF_TEST_AND_CLEAR(pVCpu, iBit) (ASMAtomicBitTestAndClear(&(pVCpu)->fLocalForcedActions, iBit##_BIT)) -/** @deprecated */ -#define VMCPU_FF_TESTANDCLEAR(pVCpu, iBit) (ASMAtomicBitTestAndClear(&(pVCpu)->fLocalForcedActions, iBit##_BIT)) -/** @def VMCPU_FF_ISPENDING +/** @def VMCPU_FF_IS_PENDING * Checks if one or more force action in the specified set is pending for the given VCPU. * - * @param pVCpu VMCPU Handle. + * @param pVCpu Pointer to the VMCPU. * @param fFlags The flags to check for. */ -#define VMCPU_FF_IS_PENDING(pVCpu, fFlags) ((pVCpu)->fLocalForcedActions & (fFlags)) -/** @deprecated */ -#define VMCPU_FF_ISPENDING(pVCpu, fFlags) VMCPU_FF_IS_PENDING(pVCpu, fFlags) +#define VMCPU_FF_IS_PENDING(pVCpu, fFlags) RT_BOOL((pVCpu)->fLocalForcedActions & (fFlags)) -/** @def VM_FF_ISPENDING +/** @def VM_FF_IS_PENDING_EXCEPT * Checks if one or more force action in the specified set is pending while one * or more other ones are not. * - * @param pVM VM Handle. + * @param pVM Pointer to the VM. * @param fFlags The flags to check for. * @param fExcpt The flags that should not be set. */ @@ -567,7 +602,7 @@ typedef struct VMCPU * Checks if one or more force action in the specified set is pending for the given * VCPU while one or more other ones are not. * - * @param pVCpu VMCPU Handle. + * @param pVCpu Pointer to the VMCPU. * @param fFlags The flags to check for. * @param fExcpt The flags that should not be set. */ @@ -615,7 +650,10 @@ typedef struct VMCPU #ifdef IN_RC # define VMCPU_ASSERT_EMT(pVCpu) Assert(VMCPU_IS_EMT(pVCpu)) #elif defined(IN_RING0) -# define VMCPU_ASSERT_EMT(pVCpu) Assert(VMCPU_IS_EMT(pVCpu)) +# define VMCPU_ASSERT_EMT(pVCpu) AssertMsg(VMCPU_IS_EMT(pVCpu), \ + ("Not emulation thread! Thread=%RTnthrd ThreadEMT=%RTnthrd idCpu=%u\n", \ + RTThreadNativeSelf(), (pVCpu) ? (pVCpu)->hNativeThreadR0 : 0, \ + (pVCpu) ? (pVCpu)->idCpu : 0)) #else # define VMCPU_ASSERT_EMT(pVCpu) \ AssertMsg(VMCPU_IS_EMT(pVCpu), \ @@ -723,15 +761,21 @@ typedef struct VMCPU ("state %s, expected %s\n", VMGetStateName((pVM)->enmVMState), VMGetStateName(_enmState)), \ (rc)) +/** @def VM_IS_VALID_EXT + * Asserts a the VM handle is valid for external access, i.e. not being destroy + * or terminated. */ +#define VM_IS_VALID_EXT(pVM) \ + ( RT_VALID_ALIGNED_PTR(pVM, PAGE_SIZE) \ + && ( (unsigned)(pVM)->enmVMState < (unsigned)VMSTATE_DESTROYING \ + || ( (unsigned)(pVM)->enmVMState == (unsigned)VMSTATE_DESTROYING \ + && VM_IS_EMT(pVM))) ) + /** @def VM_ASSERT_VALID_EXT_RETURN * Asserts a the VM handle is valid for external access, i.e. not being * destroy or terminated. */ #define VM_ASSERT_VALID_EXT_RETURN(pVM, rc) \ - AssertMsgReturn( RT_VALID_ALIGNED_PTR(pVM, PAGE_SIZE) \ - && ( (unsigned)(pVM)->enmVMState < (unsigned)VMSTATE_DESTROYING \ - || ( (unsigned)(pVM)->enmVMState == (unsigned)VMSTATE_DESTROYING \ - && VM_IS_EMT(pVM))), \ + AssertMsgReturn(VM_IS_VALID_EXT(pVM), \ ("pVM=%p state %s\n", (pVM), RT_VALID_ALIGNED_PTR(pVM, PAGE_SIZE) \ ? VMGetStateName(pVM->enmVMState) : ""), \ (rc)) @@ -753,17 +797,17 @@ typedef struct VMCPU -/** This is the VM structure. +/** + * The cross context VM structure. * - * It contains (nearly?) all the VM data which have to be available in all - * contexts. Even if it contains all the data the idea is to use APIs not - * to modify all the members all around the place. Therefore we make use of - * unions to hide everything which isn't local to the current source module. - * This means we'll have to pay a little bit of attention when adding new - * members to structures in the unions and make sure to keep the padding sizes - * up to date. + * It contains all the VM data which have to be available in all contexts. + * Even if it contains all the data the idea is to use APIs not to modify all + * the members all around the place. Therefore we make use of unions to hide + * everything which isn't local to the current source module. This means we'll + * have to pay a little bit of attention when adding new members to structures + * in the unions and make sure to keep the padding sizes up to date. * - * Run tstVMStructSize after update! + * Run 'kmk run-struct-tests' (from src/VBox/VMM if you like) after updating! */ typedef struct VM { @@ -835,6 +879,8 @@ typedef struct VM bool fRecompileUser; /** Whether to recompile supervisor mode code or run it raw/hm. */ bool fRecompileSupervisor; + /** Whether raw mode supports ring-1 code or not. */ + bool fRawRing1Enabled; /** PATM enabled flag. * This is placed here for performance reasons. */ bool fPATMEnabled; @@ -842,19 +888,26 @@ typedef struct VM * This is placed here for performance reasons. */ bool fCSAMEnabled; /** Hardware VM support is available and enabled. + * Determined very early during init. * This is placed here for performance reasons. */ - bool fHWACCMEnabled; - /** Hardware VM support is required and non-optional. - * This is initialized together with the rest of the VM structure. */ - bool fHwVirtExtForced; - /** Set when this VM is the master FT node. */ + bool fHMEnabled; + /** For asserting on fHMEnable usage. */ + bool fHMEnabledFixed; + /** Hardware VM support requires a minimal raw-mode context. + * This is never set on 64-bit hosts, only 32-bit hosts requires it. */ + bool fHMNeedRawModeCtx; + /** Set when this VM is the master FT node. + * @todo This doesn't need to be here, FTM should store it in it's own + * structures instead. */ bool fFaultTolerantMaster; - /** Large page enabled flag. */ + /** Large page enabled flag. + * @todo This doesn't need to be here, PGM should store it in it's own + * structures instead. */ bool fUseLargePages; /** @} */ /** Alignment padding.. */ - uint32_t uPadding1; + uint8_t uPadding1[2]; /** @name Debugging * @{ */ @@ -929,14 +982,14 @@ typedef struct VM uint8_t padding[4096*2+6080]; /* multiple of 64 */ } pgm; - /** HWACCM part. */ + /** HM part. */ union { -#ifdef ___HWACCMInternal_h - struct HWACCM s; +#ifdef ___HMInternal_h + struct HM s; #endif - uint8_t padding[5376]; /* multiple of 64 */ - } hwaccm; + uint8_t padding[5440]; /* multiple of 64 */ + } hm; /** TRPM part. */ union @@ -980,7 +1033,7 @@ typedef struct VM #ifdef ___IOMInternal_h struct IOM s; #endif - uint8_t padding[832]; /* multiple of 64 */ + uint8_t padding[896]; /* multiple of 64 */ } iom; /** PATM part. */ @@ -1077,7 +1130,7 @@ typedef struct VM /** Padding for aligning the cpu array on a page boundary. */ - uint8_t abAlignment2[542]; + uint8_t abAlignment2[414]; /* ---- end small stuff ---- */ diff --git a/include/VBox/vmm/vm.mac b/include/VBox/vmm/vm.mac index 6d65b0c9..2a1be76b 100644 --- a/include/VBox/vmm/vm.mac +++ b/include/VBox/vmm/vm.mac @@ -3,7 +3,7 @@ ; ; -; Copyright (C) 2006-2012 Oracle Corporation +; Copyright (C) 2006-2013 Oracle Corporation ; ; This file is part of VirtualBox Open Source Edition (OSE), as ; available from http://www.virtualbox.org. This file is free software; @@ -58,14 +58,16 @@ struc VM .pfnVMMRCToHostAsmNoReturn resd 1 .fRecompileUser resb 1 .fRecompileSupervisor resb 1 + .fRawRing1Enabled resb 1 .fPATMEnabled resb 1 .fCSAMEnabled resb 1 - .fHWACCMEnabled resb 1 - .fHwVirtExtForced resb 1 + .fHMEnabled resb 1 + .fHMEnabledFixed resb 1 + .fHMNeedRawModeCtx resb 1 .fFaultTolerantMaster resb 1 .fUseLargePages resb 1 - .uPadding1 resd 1 + .uPadding1 resb 2 .hTraceBufRC RTRCPTR_RES 1 .hTraceBufR3 RTR3PTR_RES 1 @@ -132,13 +134,13 @@ struc VMCPU alignb 64 .cpum resb 3584 - .hwaccm resb 5376 + .hm resb 5568 .em resb 1472 .iem resb 3072 .trpm resb 128 .tm resb 384 - .vmm resb 640 - .pdm resb 128 + .vmm resb 704 + .pdm resb 256 .iom resb 512 .dbgf resb 64 alignb 4096 diff --git a/include/VBox/vmm/vmapi.h b/include/VBox/vmm/vmapi.h index b15fc7f6..d19ac645 100644 --- a/include/VBox/vmm/vmapi.h +++ b/include/VBox/vmm/vmapi.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -92,20 +92,20 @@ RT_C_DECLS_BEGIN /** * VM error callback function. * - * @param pVM The VM handle. Can be NULL if an error occurred before - * successfully creating a VM. + * @param pUVM The user mode VM handle. Can be NULL if an error + * occurred before successfully creating a VM. * @param pvUser The user argument. * @param rc VBox status code. * @param RT_SRC_POS_DECL The source position arguments. See RT_SRC_POS and RT_SRC_POS_ARGS. * @param pszFormat Error message format string. * @param args Error message arguments. */ -typedef DECLCALLBACK(void) FNVMATERROR(PVM pVM, void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszError, va_list args); +typedef DECLCALLBACK(void) FNVMATERROR(PUVM pUVM, void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszError, va_list args); /** Pointer to a VM error callback. */ typedef FNVMATERROR *PFNVMATERROR; -VMMDECL(int) VMSetError(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...); -VMMDECL(int) VMSetErrorV(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list args); +VMMDECL(int) VMSetError(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...); +VMMDECL(int) VMSetErrorV(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list args); /** @def VM_SET_ERROR * Macro for setting a simple VM error message. @@ -122,20 +122,35 @@ VMMDECL(int) VMSetErrorV(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat */ #define VM_SET_ERROR(pVM, rc, pszMessage) (VMSetError(pVM, rc, RT_SRC_POS, pszMessage)) +/** @def VM_SET_ERROR + * Macro for setting a simple VM error message. + * Don't use '%' in the message! + * + * @returns rc. Meaning you can do: + * @code + * return VM_SET_ERROR(pVM, VERR_OF_YOUR_CHOICE, "descriptive message"); + * @endcode + * @param pVM VM handle. + * @param rc VBox status code. + * @param pszMessage Error message string. + * @thread Any + */ +#define VM_SET_ERROR_U(a_pUVM, a_rc, a_pszMessage) (VMR3SetError(a_pUVM, a_rc, RT_SRC_POS, a_pszMessage)) + /** * VM runtime error callback function. * * See VMSetRuntimeError for the detailed description of parameters. * - * @param pVM The VM handle. + * @param pUVM The user mode VM handle. * @param pvUser The user argument. * @param fFlags The error flags. * @param pszErrorId Error ID string. * @param pszFormat Error message format string. * @param va Error message arguments. */ -typedef DECLCALLBACK(void) FNVMATRUNTIMEERROR(PVM pVM, void *pvUser, uint32_t fFlags, const char *pszErrorId, +typedef DECLCALLBACK(void) FNVMATRUNTIMEERROR(PUVM pUVM, void *pvUser, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va); /** Pointer to a VM runtime error callback. */ typedef FNVMATRUNTIMEERROR *PFNVMATRUNTIMEERROR; @@ -163,17 +178,17 @@ VMMDECL(int) VMSetRuntimeErrorV(PVM pVM, uint32_t fFlags, const char *pszErrorId /** @} */ /** - * VM state callback function. + * VM state change callback function. * * You are not allowed to call any function which changes the VM state from a * state callback, except VMR3Destroy(). * - * @param pVM The VM handle. + * @param pUVM The user mode VM handle. * @param enmState The new state. * @param enmOldState The old state. * @param pvUser The user argument. */ -typedef DECLCALLBACK(void) FNVMATSTATE(PVM pVM, VMSTATE enmState, VMSTATE enmOldState, void *pvUser); +typedef DECLCALLBACK(void) FNVMATSTATE(PUVM pUVM, VMSTATE enmState, VMSTATE enmOldState, void *pvUser); /** Pointer to a VM state callback. */ typedef FNVMATSTATE *PFNVMATSTATE; @@ -309,45 +324,102 @@ typedef enum VMINITCOMPLETED /** The ring-0 init is completed. */ VMINITCOMPLETED_RING0, /** The hardware accelerated virtualization init is completed. - * Used to make decisision depending on whether HWACCMIsEnabled(). */ - VMINITCOMPLETED_HWACCM, - /** The GC init is completed. */ - VMINITCOMPLETED_GC + * Used to make decisision depending on HM* bits being completely + * initialized. */ + VMINITCOMPLETED_HM, + /** The RC init is completed. */ + VMINITCOMPLETED_RC } VMINITCOMPLETED; -VMMR3DECL(int) VMR3Create(uint32_t cCpus, PCVMM2USERMETHODS pVm2UserCbs, - PFNVMATERROR pfnVMAtError, void *pvUserVM, - PFNCFGMCONSTRUCTOR pfnCFGMConstructor, void *pvUserCFGM, - PVM *ppVM); -VMMR3DECL(int) VMR3PowerOn(PVM pVM); -VMMR3DECL(int) VMR3Suspend(PVM pVM); -VMMR3DECL(int) VMR3Resume(PVM pVM); -VMMR3DECL(int) VMR3Reset(PVM pVM); +/** Reason for VM resume. */ +typedef enum VMRESUMEREASON +{ + VMRESUMEREASON_INVALID = 0, + /** User decided to do so. */ + VMRESUMEREASON_USER, + /** VM reconfiguration (like changing DVD). */ + VMRESUMEREASON_RECONFIG, + /** The host resumed. */ + VMRESUMEREASON_HOST_RESUME, + /** Restored state. */ + VMRESUMEREASON_STATE_RESTORED, + /** Snapshot / saved state. */ + VMRESUMEREASON_STATE_SAVED, + /** Teleported to a new box / instance. */ + VMRESUMEREASON_TELEPORTED, + /** Teleportation failed. */ + VMRESUMEREASON_TELEPORT_FAILED, + /** FTM temporarily suspended the VM. */ + VMRESUMEREASON_FTM_SYNC, + /** End of valid reasons. */ + VMRESUMEREASON_END, + /** Blow the type up to 32-bits. */ + VMRESUMEREASON_32BIT_HACK = 0x7fffffff +} VMRESUMEREASON; + +/** Reason for VM suspend. */ +typedef enum VMSUSPENDREASON +{ + VMSUSPENDREASON_INVALID = 0, + /** User decided to do so. */ + VMSUSPENDREASON_USER, + /** VM reconfiguration (like changing DVD). */ + VMSUSPENDREASON_RECONFIG, + /** The VM is suspending itself. */ + VMSUSPENDREASON_VM, + /** The Vm is suspending because of a runtime error. */ + VMSUSPENDREASON_RUNTIME_ERROR, + /** The host was suspended. */ + VMSUSPENDREASON_HOST_SUSPEND, + /** The host is running low on battery power. */ + VMSUSPENDREASON_HOST_BATTERY_LOW, + /** FTM is temporarily suspending the VM. */ + VMSUSPENDREASON_FTM_SYNC, + /** End of valid reasons. */ + VMSUSPENDREASON_END, + /** Blow the type up to 32-bits. */ + VMSUSPENDREASON_32BIT_HACK = 0x7fffffff +} VMSUSPENDREASON; + /** * Progress callback. + * * This will report the completion percentage of an operation. * * @returns VINF_SUCCESS. * @returns Error code to cancel the operation with. - * @param pVM The VM handle. + * @param pUVM The user mode VM handle. * @param uPercent Completion percentage (0-100). * @param pvUser User specified argument. */ -typedef DECLCALLBACK(int) FNVMPROGRESS(PVM pVM, unsigned uPercent, void *pvUser); +typedef DECLCALLBACK(int) FNVMPROGRESS(PUVM pUVM, unsigned uPercent, void *pvUser); /** Pointer to a FNVMPROGRESS function. */ typedef FNVMPROGRESS *PFNVMPROGRESS; -VMMR3DECL(int) VMR3Save(PVM pVM, const char *pszFilename, bool fContinueAfterwards, PFNVMPROGRESS pfnProgress, void *pvUser, bool *pfSuspended); -VMMR3DECL(int) VMR3Teleport(PVM pVM, uint32_t cMsDowntime, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, PFNVMPROGRESS pfnProgress, void *pvProgressUser, bool *pfSuspended); -VMMR3DECL(int) VMR3LoadFromFile(PVM pVM, const char *pszFilename, PFNVMPROGRESS pfnProgress, void *pvUser); -VMMR3DECL(int) VMR3LoadFromStream(PVM pVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, - PFNVMPROGRESS pfnProgress, void *pvProgressUser); -VMMR3DECL(int) VMR3PowerOff(PVM pVM); -VMMR3DECL(int) VMR3Destroy(PVM pVM); -VMMR3DECL(void) VMR3Relocate(PVM pVM, RTGCINTPTR offDelta); -VMMR3DECL(PVM) VMR3EnumVMs(PVM pVMPrev); + +VMMR3DECL(int) VMR3Create(uint32_t cCpus, PCVMM2USERMETHODS pVm2UserCbs, + PFNVMATERROR pfnVMAtError, void *pvUserVM, + PFNCFGMCONSTRUCTOR pfnCFGMConstructor, void *pvUserCFGM, + PVM *ppVM, PUVM *ppUVM); +VMMR3DECL(int) VMR3PowerOn(PUVM pUVM); +VMMR3DECL(int) VMR3Suspend(PUVM pUVM, VMSUSPENDREASON enmReason); +VMMR3DECL(VMSUSPENDREASON) VMR3GetSuspendReason(PUVM); +VMMR3DECL(int) VMR3Resume(PUVM pUVM, VMRESUMEREASON enmReason); +VMMR3DECL(VMRESUMEREASON) VMR3GetResumeReason(PUVM); +VMMR3DECL(int) VMR3Reset(PUVM pUVM); +VMMR3DECL(int) VMR3Save(PUVM pUVM, const char *pszFilename, bool fContinueAfterwards, PFNVMPROGRESS pfnProgress, void *pvUser, bool *pfSuspended); +VMMR3_INT_DECL(int) VMR3SaveFT(PUVM pUVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, bool *pfSuspended, bool fSkipStateChanges); +VMMR3DECL(int) VMR3Teleport(PUVM pUVM, uint32_t cMsDowntime, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, PFNVMPROGRESS pfnProgress, void *pvProgressUser, bool *pfSuspended); +VMMR3DECL(int) VMR3LoadFromFile(PUVM pUVM, const char *pszFilename, PFNVMPROGRESS pfnProgress, void *pvUser); +VMMR3DECL(int) VMR3LoadFromStream(PUVM pUVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, + PFNVMPROGRESS pfnProgress, void *pvProgressUser); +VMMR3_INT_DECL(int) VMR3LoadFromStreamFT(PUVM pUVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser); + +VMMR3DECL(int) VMR3PowerOff(PUVM pUVM); +VMMR3DECL(int) VMR3Destroy(PUVM pUVM); +VMMR3_INT_DECL(void) VMR3Relocate(PVM pVM, RTGCINTPTR offDelta); VMMR3DECL(PVM) VMR3GetVM(PUVM pUVM); VMMR3DECL(PUVM) VMR3GetUVM(PVM pVM); @@ -358,48 +430,38 @@ VMMR3DECL(PRTUUID) VMR3GetUuid(PUVM pUVM, PRTUUID pUuid); VMMR3DECL(VMSTATE) VMR3GetState(PVM pVM); VMMR3DECL(VMSTATE) VMR3GetStateU(PUVM pUVM); VMMR3DECL(const char *) VMR3GetStateName(VMSTATE enmState); +VMMR3DECL(int) VMR3AtStateRegister(PUVM pUVM, PFNVMATSTATE pfnAtState, void *pvUser); +VMMR3DECL(int) VMR3AtStateDeregister(PUVM pUVM, PFNVMATSTATE pfnAtState, void *pvUser); +VMMR3_INT_DECL(bool) VMR3TeleportedAndNotFullyResumedYet(PVM pVM); +VMMR3DECL(int) VMR3AtErrorRegister(PUVM pUVM, PFNVMATERROR pfnAtError, void *pvUser); +VMMR3DECL(int) VMR3AtErrorDeregister(PUVM pUVM, PFNVMATERROR pfnAtError, void *pvUser); +VMMR3DECL(int) VMR3SetError(PUVM pUVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...); +VMMR3DECL(int) VMR3SetErrorV(PUVM pUVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va); +VMMR3_INT_DECL(void) VMR3SetErrorWorker(PVM pVM); +VMMR3_INT_DECL(uint32_t) VMR3GetErrorCount(PUVM pUVM); +VMMR3DECL(int) VMR3AtRuntimeErrorRegister(PUVM pUVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser); +VMMR3DECL(int) VMR3AtRuntimeErrorDeregister(PUVM pUVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser); +VMMR3_INT_DECL(int) VMR3SetRuntimeErrorWorker(PVM pVM); +VMMR3_INT_DECL(uint32_t) VMR3GetRuntimeErrorCount(PUVM pUVM); + +VMMR3DECL(int) VMR3ReqCallU(PUVM pUVM, VMCPUID idDstCpu, PVMREQ *ppReq, RTMSINTERVAL cMillies, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, ...); +VMMR3DECL(int) VMR3ReqCallVU(PUVM pUVM, VMCPUID idDstCpu, PVMREQ *ppReq, RTMSINTERVAL cMillies, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, va_list Args); +VMMR3_INT_DECL(int) VMR3ReqCallWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); +VMMR3DECL(int) VMR3ReqCallWaitU(PUVM pUVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); +VMMR3DECL(int) VMR3ReqCallNoWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); +VMMR3DECL(int) VMR3ReqCallNoWaitU(PUVM pUVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); +VMMR3_INT_DECL(int) VMR3ReqCallVoidWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); +VMMR3DECL(int) VMR3ReqCallVoidWaitU(PUVM pUVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); +VMMR3DECL(int) VMR3ReqCallVoidNoWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); +VMMR3DECL(int) VMR3ReqPriorityCallWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); +VMMR3DECL(int) VMR3ReqPriorityCallWaitU(PUVM pUVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); +VMMR3DECL(int) VMR3ReqPriorityCallVoidWaitU(PUVM pUVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); +VMMR3DECL(int) VMR3ReqAlloc(PUVM pUVM, PVMREQ *ppReq, VMREQTYPE enmType, VMCPUID idDstCpu); +VMMR3DECL(int) VMR3ReqFree(PVMREQ pReq); +VMMR3DECL(int) VMR3ReqQueue(PVMREQ pReq, RTMSINTERVAL cMillies); +VMMR3DECL(int) VMR3ReqWait(PVMREQ pReq, RTMSINTERVAL cMillies); +VMMR3_INT_DECL(int) VMR3ReqProcessU(PUVM pUVM, VMCPUID idDstCpu, bool fPriorityOnly); -/** - * VM destruction callback. - * @param pVM The VM which is about to be destroyed. - * @param pvUser The user parameter specified at registration. - */ -typedef DECLCALLBACK(void) FNVMATDTOR(PVM pVM, void *pvUser); -/** Pointer to a VM destruction callback. */ -typedef FNVMATDTOR *PFNVMATDTOR; - -VMMR3DECL(int) VMR3AtDtorRegister(PFNVMATDTOR pfnAtDtor, void *pvUser); -VMMR3DECL(int) VMR3AtDtorDeregister(PFNVMATDTOR pfnAtDtor); -VMMR3DECL(int) VMR3AtStateRegister(PVM pVM, PFNVMATSTATE pfnAtState, void *pvUser); -VMMR3DECL(int) VMR3AtStateDeregister(PVM pVM, PFNVMATSTATE pfnAtState, void *pvUser); -VMMR3DECL(bool) VMR3TeleportedAndNotFullyResumedYet(PVM pVM); -VMMR3DECL(int) VMR3AtErrorRegister(PVM pVM, PFNVMATERROR pfnAtError, void *pvUser); -VMMR3DECL(int) VMR3AtErrorRegisterU(PUVM pVM, PFNVMATERROR pfnAtError, void *pvUser); -VMMR3DECL(int) VMR3AtErrorDeregister(PVM pVM, PFNVMATERROR pfnAtError, void *pvUser); -VMMR3DECL(void) VMR3SetErrorWorker(PVM pVM); -VMMR3DECL(uint32_t) VMR3GetErrorCount(PVM pVM); -VMMR3DECL(uint32_t) VMR3GetErrorCountU(PUVM pUVM); -VMMR3DECL(int) VMR3AtRuntimeErrorRegister(PVM pVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser); -VMMR3DECL(int) VMR3AtRuntimeErrorDeregister(PVM pVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser); -VMMR3DECL(int) VMR3SetRuntimeErrorWorker(PVM pVM); -VMMR3DECL(uint32_t) VMR3GetRuntimeErrorCount(PVM pVM); -VMMR3DECL(int) VMR3ReqCall(PVM pVM, VMCPUID idDstCpu, PVMREQ *ppReq, RTMSINTERVAL cMillies, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, ...); -VMMR3DECL(int) VMR3ReqCallU(PUVM pUVM, VMCPUID idDstCpu, PVMREQ *ppReq, RTMSINTERVAL cMillies, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, ...); -VMMR3DECL(int) VMR3ReqCallVU(PUVM pUVM, VMCPUID idDstCpu, PVMREQ *ppReq, RTMSINTERVAL cMillies, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, va_list Args); -VMMR3DECL(int) VMR3ReqCallWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); -VMMR3DECL(int) VMR3ReqCallNoWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); -VMMR3DECL(int) VMR3ReqCallVoidWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); -VMMR3DECL(int) VMR3ReqCallVoidNoWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); -VMMR3DECL(int) VMR3ReqPriorityCallWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); -VMMR3DECL(int) VMR3ReqPriorityCallVoidWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...); -VMMR3DECL(int) VMR3ReqAlloc(PVM pVM, PVMREQ *ppReq, VMREQTYPE enmType, VMCPUID idDstCpu); -VMMR3DECL(int) VMR3ReqAllocU(PUVM pUVM, PVMREQ *ppReq, VMREQTYPE enmType, VMCPUID idDstCpu); -VMMR3DECL(int) VMR3ReqFree(PVMREQ pReq); -VMMR3DECL(int) VMR3ReqQueue(PVMREQ pReq, RTMSINTERVAL cMillies); -VMMR3DECL(int) VMR3ReqWait(PVMREQ pReq, RTMSINTERVAL cMillies); -VMMR3DECL(int) VMR3ReqProcessU(PUVM pUVM, VMCPUID idDstCpu, bool fPriorityOnly); -VMMR3DECL(void) VMR3NotifyGlobalFFU(PUVM pUVM, uint32_t fFlags); -VMMR3DECL(void) VMR3NotifyCpuFFU(PUVMCPU pUVMCpu, uint32_t fFlags); /** @name Flags for VMR3NotifyCpuFFU and VMR3NotifyGlobalFFU. * @{ */ /** Whether we've done REM or not. */ @@ -407,20 +469,21 @@ VMMR3DECL(void) VMR3NotifyCpuFFU(PUVMCPU pUVMCpu, uint32_t fFlags); /** Whether we should poke the CPU if it's executing guest code. */ #define VMNOTIFYFF_FLAGS_POKE RT_BIT_32(1) /** @} */ - -VMMR3DECL(int) VMR3WaitHalted(PVM pVM, PVMCPU pVCpu, bool fIgnoreInterrupts); -VMMR3DECL(int) VMR3WaitU(PUVMCPU pUVMCpu); +VMMR3_INT_DECL(void) VMR3NotifyGlobalFFU(PUVM pUVM, uint32_t fFlags); +VMMR3_INT_DECL(void) VMR3NotifyCpuFFU(PUVMCPU pUVMCpu, uint32_t fFlags); +VMMR3_INT_DECL(int) VMR3WaitHalted(PVM pVM, PVMCPU pVCpu, bool fIgnoreInterrupts); +VMMR3_INT_DECL(int) VMR3WaitU(PUVMCPU pUVMCpu); VMMR3_INT_DECL(int) VMR3AsyncPdmNotificationWaitU(PUVMCPU pUVCpu); VMMR3_INT_DECL(void) VMR3AsyncPdmNotificationWakeupU(PUVM pUVM); -VMMR3DECL(RTCPUID) VMR3GetVMCPUId(PVM pVM); -VMMR3DECL(RTTHREAD) VMR3GetVMCPUThread(PVM pVM); -VMMR3DECL(RTTHREAD) VMR3GetVMCPUThreadU(PUVM pUVM); +VMMR3_INT_DECL(RTCPUID) VMR3GetVMCPUId(PVM pVM); +VMMR3DECL(RTTHREAD) VMR3GetVMCPUThread(PUVM pUVM); VMMR3DECL(RTNATIVETHREAD) VMR3GetVMCPUNativeThread(PVM pVM); VMMR3DECL(RTNATIVETHREAD) VMR3GetVMCPUNativeThreadU(PUVM pUVM); -VMMR3DECL(int) VMR3GetCpuCoreAndPackageIdFromCpuId(PVM pVM, VMCPUID idCpu, uint32_t *pidCpuCore, uint32_t *pidCpuPackage); -VMMR3DECL(int) VMR3HotUnplugCpu(PVM pVM, VMCPUID idCpu); -VMMR3DECL(int) VMR3HotPlugCpu(PVM pVM, VMCPUID idCpu); -VMMR3DECL(int) VMR3SetCpuExecutionCap(PVM pVM, uint32_t uCpuExecutionCap); +VMMR3DECL(int) VMR3GetCpuCoreAndPackageIdFromCpuId(PUVM pUVM, VMCPUID idCpu, uint32_t *pidCpuCore, uint32_t *pidCpuPackage); +VMMR3DECL(int) VMR3HotUnplugCpu(PUVM pUVM, VMCPUID idCpu); +VMMR3DECL(int) VMR3HotPlugCpu(PUVM pUVM, VMCPUID idCpu); +VMMR3DECL(int) VMR3SetCpuExecutionCap(PUVM pUVM, uint32_t uCpuExecutionCap); +VMMR3DECL(int) VMR3SetPowerOffInsteadOfReset(PUVM pUVM, bool fPowerOffInsteadOfReset); /** @} */ #endif /* IN_RING3 */ diff --git a/include/VBox/vmm/vmm.h b/include/VBox/vmm/vmm.h index e3af0c29..bd3cee05 100644 --- a/include/VBox/vmm/vmm.h +++ b/include/VBox/vmm/vmm.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2010 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -31,6 +31,7 @@ #include <VBox/sup.h> #include <VBox/log.h> #include <iprt/stdarg.h> +#include <iprt/thread.h> RT_C_DECLS_BEGIN @@ -63,6 +64,10 @@ typedef enum VMMSWITCHER VMMSWITCHER_AMD64_TO_PAE, /** Switcher for AMD64 host paging to AMD64 shadow paging. */ VMMSWITCHER_AMD64_TO_AMD64, + /** Stub switcher for 32-bit and PAE. */ + VMMSWITCHER_X86_STUB, + /** Stub switcher for AMD64. */ + VMMSWITCHER_AMD64_STUB, /** Used to make a count for array declarations and suchlike. */ VMMSWITCHER_MAX, /** The usual 32-bit paranoia. */ @@ -81,6 +86,10 @@ typedef enum VMMCALLRING3 VMMCALLRING3_PDM_LOCK, /** Acquire the critical section specified as argument. */ VMMCALLRING3_PDM_CRIT_SECT_ENTER, + /** Enter the R/W critical section (in argument) exclusively. */ + VMMCALLRING3_PDM_CRIT_SECT_RW_ENTER_EXCL, + /** Enter the R/W critical section (in argument) shared. */ + VMMCALLRING3_PDM_CRIT_SECT_RW_ENTER_SHARED, /** Acquire the PGM lock. */ VMMCALLRING3_PGM_LOCK, /** Grow the PGM shadow page pool. */ @@ -103,7 +112,8 @@ typedef enum VMMCALLRING3 VMMCALLRING3_VM_SET_RUNTIME_ERROR, /** Signal a ring 0 assertion. */ VMMCALLRING3_VM_R0_ASSERTION, - /** Ring switch to force preemption. */ + /** Ring switch to force preemption. This is also used by PDMCritSect to + * handle VERR_INTERRUPTED in kernel context. */ VMMCALLRING3_VM_R0_PREEMPT, /** Sync the FTM state with the standby node. */ VMMCALLRING3_FTM_SET_CHECKPOINT, @@ -112,17 +122,16 @@ typedef enum VMMCALLRING3 } VMMCALLRING3; /** - * VMMR3AtomicExecuteHandler callback function. + * VMMRZCallRing3 notification callback. * * @returns VBox status code. - * @param pVM Pointer to the shared VM structure. - * @param pvUser User specified argument - * - * @todo missing prefix. + * @param pVCpu Pointer to the VMCPU. + * @param enmOperation The operation causing the ring-3 jump. + * @param pvUser The user argument. */ -typedef DECLCALLBACK(int) FNATOMICHANDLER(PVM pVM, void *pvUser); -/** Pointer to a FNMMATOMICHANDLER(). */ -typedef FNATOMICHANDLER *PFNATOMICHANDLER; +typedef DECLCALLBACK(int) FNVMMR0CALLRING3NOTIFICATION(PVMCPU pVCpu, VMMCALLRING3 enmOperation, void *pvUser); +/** Pointer to a FNRTMPNOTIFICATION(). */ +typedef FNVMMR0CALLRING3NOTIFICATION *PFNVMMR0CALLRING3NOTIFICATION; /** * Rendezvous callback. @@ -213,6 +222,16 @@ typedef struct VMM2USERMETHODS */ DECLR3CALLBACKMEMBER(void, pfnNotifyPdmtTerm,(PCVMM2USERMETHODS pThis, PUVM pUVM)); + /** + * Notification callback that that a VM reset will be turned into a power off. + * + * @param pThis Pointer to the callback method table. + * @param pUVM The user mode VM handle. + * + * @remarks This is optional and shall be set to NULL if not wanted. + */ + DECLR3CALLBACKMEMBER(void, pfnNotifyResetTurnedIntoPowerOff,(PCVMM2USERMETHODS pThis, PUVM pUVM)); + /** Magic value (VMM2USERMETHODS_MAGIC) marking the end of the structure. */ uint32_t u32EndMagic; } VMM2USERMETHODS; @@ -220,28 +239,34 @@ typedef struct VMM2USERMETHODS /** Magic value of the VMM2USERMETHODS (Franz Kafka). */ #define VMM2USERMETHODS_MAGIC UINT32_C(0x18830703) /** The VMM2USERMETHODS structure version. */ -#define VMM2USERMETHODS_VERSION UINT32_C(0x00020000) +#define VMM2USERMETHODS_VERSION UINT32_C(0x00020001) -VMMDECL(RTRCPTR) VMMGetStackRC(PVMCPU pVCpu); -VMMDECL(VMCPUID) VMMGetCpuId(PVM pVM); -VMMDECL(PVMCPU) VMMGetCpu(PVM pVM); -VMMDECL(PVMCPU) VMMGetCpu0(PVM pVM); -VMMDECL(PVMCPU) VMMGetCpuById(PVM pVM, VMCPUID idCpu); -VMMDECL(uint32_t) VMMGetSvnRev(void); -VMMDECL(VMMSWITCHER) VMMGetSwitcher(PVM pVM); -VMMDECL(void) VMMTrashVolatileXMMRegs(void); - -/** @def VMMIsHwVirtExtForced - * Checks if forced to use the hardware assisted virtualization extensions. - * - * This is intended for making setup decisions where we can save resources when - * using hardware assisted virtualization. +/** + * Checks whether we've armed the ring-0 long jump machinery. * - * @returns true / false. - * @param pVM Pointer to the shared VM structure. + * @returns @c true / @c false + * @param pVCpu The caller's cross context virtual CPU structure. + * @thread EMT + * @sa VMMR0IsLongJumpArmed */ -#define VMMIsHwVirtExtForced(pVM) ((pVM)->fHwVirtExtForced) +#ifdef IN_RING0 +# define VMMIsLongJumpArmed(a_pVCpu) VMMR0IsLongJumpArmed(a_pVCpu) +#else +# define VMMIsLongJumpArmed(a_pVCpu) (false) +#endif + + +VMM_INT_DECL(RTRCPTR) VMMGetStackRC(PVMCPU pVCpu); +VMMDECL(VMCPUID) VMMGetCpuId(PVM pVM); +VMMDECL(PVMCPU) VMMGetCpu(PVM pVM); +VMMDECL(PVMCPU) VMMGetCpu0(PVM pVM); +VMMDECL(PVMCPU) VMMGetCpuById(PVM pVM, VMCPUID idCpu); +VMMR3DECL(PVMCPU) VMMR3GetCpuByIdU(PUVM pVM, VMCPUID idCpu); +VMM_INT_DECL(uint32_t) VMMGetSvnRev(void); +VMM_INT_DECL(VMMSWITCHER) VMMGetSwitcher(PVM pVM); +VMM_INT_DECL(bool) VMMIsInRing3Call(PVMCPU pVCpu); +VMM_INT_DECL(void) VMMTrashVolatileXMMRegs(void); #ifdef IN_RING3 @@ -251,23 +276,26 @@ VMMDECL(void) VMMTrashVolatileXMMRegs(void); */ VMMR3_INT_DECL(int) VMMR3Init(PVM pVM); VMMR3_INT_DECL(int) VMMR3InitR0(PVM pVM); +# ifdef VBOX_WITH_RAW_MODE VMMR3_INT_DECL(int) VMMR3InitRC(PVM pVM); +# endif VMMR3_INT_DECL(int) VMMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat); VMMR3_INT_DECL(int) VMMR3Term(PVM pVM); VMMR3_INT_DECL(void) VMMR3Relocate(PVM pVM, RTGCINTPTR offDelta); VMMR3_INT_DECL(int) VMMR3UpdateLoggers(PVM pVM); VMMR3DECL(const char *) VMMR3GetRZAssertMsg1(PVM pVM); VMMR3DECL(const char *) VMMR3GetRZAssertMsg2(PVM pVM); -VMMR3_INT_DECL(int) VMMR3GetImportRC(PVM pVM, const char *pszSymbol, PRTRCPTR pRCPtrValue); VMMR3_INT_DECL(int) VMMR3SelectSwitcher(PVM pVM, VMMSWITCHER enmSwitcher); -VMMR3_INT_DECL(int) VMMR3DisableSwitcher(PVM pVM); VMMR3_INT_DECL(RTR0PTR) VMMR3GetHostToGuestSwitcher(PVM pVM, VMMSWITCHER enmSwitcher); +VMMR3_INT_DECL(int) VMMR3HmRunGC(PVM pVM, PVMCPU pVCpu); +# ifdef VBOX_WITH_RAW_MODE VMMR3_INT_DECL(int) VMMR3RawRunGC(PVM pVM, PVMCPU pVCpu); -VMMR3_INT_DECL(int) VMMR3HwAccRunGC(PVM pVM, PVMCPU pVCpu); +VMMR3DECL(int) VMMR3ResumeHyper(PVM pVM, PVMCPU pVCpu); +VMMR3_INT_DECL(int) VMMR3GetImportRC(PVM pVM, const char *pszSymbol, PRTRCPTR pRCPtrValue); VMMR3DECL(int) VMMR3CallRC(PVM pVM, RTRCPTR RCPtrEntry, unsigned cArgs, ...); VMMR3DECL(int) VMMR3CallRCV(PVM pVM, RTRCPTR RCPtrEntry, unsigned cArgs, va_list args); +# endif VMMR3DECL(int) VMMR3CallR0(PVM pVM, uint32_t uOperation, uint64_t u64Arg, PSUPVMMR0REQHDR pReqHdr); -VMMR3DECL(int) VMMR3ResumeHyper(PVM pVM, PVMCPU pVCpu); VMMR3DECL(void) VMMR3FatalDump(PVM pVM, PVMCPU pVCpu, int rcErr); VMMR3_INT_DECL(void) VMMR3YieldSuspend(PVM pVM); VMMR3_INT_DECL(void) VMMR3YieldStop(PVM pVM); @@ -320,7 +348,7 @@ typedef enum VMMR0OPERATION /** Run guest context. */ VMMR0_DO_RAW_RUN = SUP_VMMR0_DO_RAW_RUN, /** Run guest code using the available hardware acceleration technology. */ - VMMR0_DO_HWACC_RUN = SUP_VMMR0_DO_HWACC_RUN, + VMMR0_DO_HM_RUN = SUP_VMMR0_DO_HM_RUN, /** Official NOP that we use for profiling. */ VMMR0_DO_NOP = SUP_VMMR0_DO_NOP, /** Official slow iocl NOP that we use for profiling. */ @@ -352,9 +380,9 @@ typedef enum VMMR0OPERATION /** Call VMMR0 Per VM Termination. */ VMMR0_DO_VMMR0_TERM, /** Setup the hardware accelerated raw-mode session. */ - VMMR0_DO_HWACC_SETUP_VM, + VMMR0_DO_HM_SETUP_VM, /** Attempt to enable or disable hardware accelerated raw-mode. */ - VMMR0_DO_HWACC_ENABLE, + VMMR0_DO_HM_ENABLE, /** Calls function in the hypervisor. * The caller must setup the hypervisor context so the call will be performed. * The difference between VMMR0_DO_RUN_GC and this one is the handling of @@ -475,18 +503,30 @@ typedef struct GCFGMVALUEREQ */ typedef GCFGMVALUEREQ *PGCFGMVALUEREQ; -VMMR0DECL(int) VMMR0EntryInt(PVM pVM, VMMR0OPERATION enmOperation, void *pvArg); -VMMR0DECL(void) VMMR0EntryFast(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation); -VMMR0DECL(int) VMMR0EntryEx(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION); -VMMR0DECL(int) VMMR0TermVM(PVM pVM, PGVM pGVM); - -#ifdef LOG_ENABLED -VMMR0DECL(void) VMMR0LogFlushDisable(PVMCPU pVCpu); -VMMR0DECL(void) VMMR0LogFlushEnable(PVMCPU pVCpu); -#else -#define VMMR0LogFlushDisable(pVCpu) do { } while(0) -#define VMMR0LogFlushEnable(pVCpu) do { } while(0) -#endif +#ifdef IN_RING0 +VMMR0DECL(int) VMMR0EntryInt(PVM pVM, VMMR0OPERATION enmOperation, void *pvArg); +VMMR0DECL(void) VMMR0EntryFast(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation); +VMMR0DECL(int) VMMR0EntryEx(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION); +VMMR0DECL(int) VMMR0TermVM(PVM pVM, PGVM pGVM); +VMMR0_INT_DECL(bool) VMMR0IsLongJumpArmed(PVMCPU pVCpu); +VMMR0_INT_DECL(bool) VMMR0IsInRing3LongJump(PVMCPU pVCpu); +VMMR0DECL(int) VMMR0ThreadCtxHooksCreate(PVMCPU pVCpu); +VMMR0DECL(void) VMMR0ThreadCtxHooksRelease(PVMCPU pVCpu); +VMMR0DECL(bool) VMMR0ThreadCtxHooksAreCreated(PVMCPU pVCpu); +VMMR0DECL(int) VMMR0ThreadCtxHooksRegister(PVMCPU pVCpu, PFNRTTHREADCTXHOOK pfnHook); +VMMR0DECL(int) VMMR0ThreadCtxHooksDeregister(PVMCPU pVCpu); +VMMR0DECL(bool) VMMR0ThreadCtxHooksAreRegistered(PVMCPU pVCpu); + +# ifdef LOG_ENABLED +VMMR0DECL(void) VMMR0LogFlushDisable(PVMCPU pVCpu); +VMMR0DECL(void) VMMR0LogFlushEnable(PVMCPU pVCpu); +VMMR0DECL(bool) VMMR0IsLogFlushDisabled(PVMCPU pVCpu); +# else +# define VMMR0LogFlushDisable(pVCpu) do { } while(0) +# define VMMR0LogFlushEnable(pVCpu) do { } while(0) +# define VMMR0IsLogFlushDisabled(pVCpu) (true) +# endif /* LOG_ENABLED */ +#endif /* IN_RING0 */ /** @} */ @@ -512,6 +552,9 @@ VMMRZDECL(int) VMMRZCallRing3NoCpu(PVM pVM, VMMCALLRING3 enmOperation, uint VMMRZDECL(void) VMMRZCallRing3Disable(PVMCPU pVCpu); VMMRZDECL(void) VMMRZCallRing3Enable(PVMCPU pVCpu); VMMRZDECL(bool) VMMRZCallRing3IsEnabled(PVMCPU pVCpu); +VMMRZDECL(int) VMMRZCallRing3SetNotification(PVMCPU pVCpu, R0PTRTYPE(PFNVMMR0CALLRING3NOTIFICATION) pfnCallback, RTR0PTR pvUser); +VMMRZDECL(void) VMMRZCallRing3RemoveNotification(PVMCPU pVCpu); +VMMRZDECL(bool) VMMRZCallRing3IsNotificationSet(PVMCPU pVCpu); /** @} */ #endif diff --git a/include/VBox/vrdpusb.h b/include/VBox/vrdpusb.h index 92491500..69bdeb6b 100644 --- a/include/VBox/vrdpusb.h +++ b/include/VBox/vrdpusb.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/include/VBox/vscsi.h b/include/VBox/vscsi.h index 217ce885..f3544cb2 100644 --- a/include/VBox/vscsi.h +++ b/include/VBox/vscsi.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2011 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -121,6 +121,32 @@ typedef struct VSCSILUNIOCALLBACKS uint64_t *pcbSize)); /** + * Retrieve the sector size of the underlying medium. + * + * @returns VBox status status code. + * @param hVScsiLun Virtual SCSI LUN handle. + * @param pvScsiLunUser Opaque user data which may + * be used to identify the medium. + * @param pcbSectorSize Where to store the sector size of the + * medium. + */ + DECLR3CALLBACKMEMBER(int, pfnVScsiLunMediumGetSectorSize, (VSCSILUN hVScsiLun, + void *pvScsiLunUser, + uint32_t *pcbSectorSize)); + + /** + * Set the lock state of the underlying medium. + * + * @returns VBox status status code. + * @param hVScsiLun Virtual SCSI LUN handle. + * @param pvScsiLunUser Opaque user data which may + * be used to identify the medium. + * @param fLocked New lock state (locked/unlocked). + */ + DECLR3CALLBACKMEMBER(int, pfnVScsiLunMediumSetLock, (VSCSILUN hVScsiLun, + void *pvScsiLunUser, + bool fLocked)); + /** * Enqueue a read or write request from the medium. * * @returns VBox status status code. @@ -270,6 +296,22 @@ VBOXDDU_DECL(int) VSCSILunCreate(PVSCSILUN phVScsiLun, VSCSILUNTYPE enmLunType, VBOXDDU_DECL(int) VSCSILunDestroy(VSCSILUN hVScsiLun); /** + * Notify virtual SCSI LUN of medium being mounted. + * + * @returns VBox status code. + * @param hVScsiLun The virtual SCSI LUN handle to destroy. + */ +VBOXDDU_DECL(int) VSCSILunMountNotify(VSCSILUN hVScsiLun); + +/** + * Notify virtual SCSI LUN of medium being unmounted. + * + * @returns VBox status code. + * @param hVScsiLun The virtual SCSI LUN handle to destroy. + */ +VBOXDDU_DECL(int) VSCSILunUnmountNotify(VSCSILUN hVScsiLun); + +/** * Notify a that a I/O request completed. * * @returns VBox status code. diff --git a/include/VBox/vusb.h b/include/VBox/vusb.h index 3a2d9b8f..c1aba4f0 100644 --- a/include/VBox/vusb.h +++ b/include/VBox/vusb.h @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -54,6 +54,7 @@ RT_C_DECLS_BEGIN #define VUSB_DT_DEVICE_QUALIFIER 0x06 #define VUSB_DT_OTHER_SPEED_CFG 0x07 #define VUSB_DT_INTERFACE_POWER 0x08 +#define VUSB_DT_INTERFACE_ASSOCIATION 0x0B /** @} */ /** @name USB Descriptor minimum sizes (from spec) @@ -162,6 +163,26 @@ typedef const VUSBDESCCONFIG *PCVUSBDESCCONFIG; /** + * USB interface association descriptor (from USB ECN Interface Association Descriptors) + */ +typedef struct VUSBDESCIAD +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bFirstInterface; + uint8_t bInterfaceCount; + uint8_t bFunctionClass; + uint8_t bFunctionSubClass; + uint8_t bFunctionProtocol; + uint8_t iFunction; +} VUSBDESCIAD; +/** Pointer to a USB interface association descriptor. */ +typedef VUSBDESCIAD *PVUSBDESCIAD; +/** Pointer to a readonly USB interface association descriptor. */ +typedef const VUSBDESCIAD *PCVUSBDESCIAD; + + +/** * USB interface descriptor (from spec) */ typedef struct VUSBDESCINTERFACE @@ -256,6 +277,11 @@ typedef struct VUSBDESCINTERFACEEX /** Pointer to an array of the endpoints referenced by the interface. * Core.bNumEndpoints in size. */ const struct VUSBDESCENDPOINTEX *paEndpoints; + /** Interface association descriptor, which prepends a group of interfaces, + * starting with this interface. */ + PCVUSBDESCIAD pIAD; + /** Size of interface association descriptor. */ + uint16_t cbIAD; } VUSBDESCINTERFACEEX; /** Pointer to an prased USB interface descriptor. */ typedef VUSBDESCINTERFACEEX *PVUSBDESCINTERFACEEX; |