summaryrefslogtreecommitdiff
path: root/src/VBox/VMM/VMMRC/VMMRC.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2014-03-26 19:21:20 +0000
committer <>2014-05-08 15:03:54 +0000
commitfb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch)
treec2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/VMM/VMMRC/VMMRC.cpp
parent58ed4748338f9466599adfc8a9171280ed99e23f (diff)
downloadVirtualBox-master.tar.gz
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2.HEADVirtualBox-4.3.10master
Diffstat (limited to 'src/VBox/VMM/VMMRC/VMMRC.cpp')
-rw-r--r--src/VBox/VMM/VMMRC/VMMRC.cpp95
1 files changed, 89 insertions, 6 deletions
diff --git a/src/VBox/VMM/VMMRC/VMMRC.cpp b/src/VBox/VMM/VMMRC/VMMRC.cpp
index fb2a2c62..06e20031 100644
--- a/src/VBox/VMM/VMMRC/VMMRC.cpp
+++ b/src/VBox/VMM/VMMRC/VMMRC.cpp
@@ -4,7 +4,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;
@@ -47,6 +47,8 @@ extern "C" DECLIMPORT(RTLOGGERRC) g_RelLogger;
static int vmmGCTest(PVM pVM, unsigned uOperation, unsigned uArg);
static DECLCALLBACK(int) vmmGCTestTmpPFHandler(PVM pVM, PCPUMCTXCORE pRegFrame);
static DECLCALLBACK(int) vmmGCTestTmpPFHandlerCorruptFS(PVM pVM, PCPUMCTXCORE pRegFrame);
+DECLASM(bool) vmmRCSafeMsrRead(uint32_t uMsr, uint64_t *pu64Value);
+DECLASM(bool) vmmRCSafeMsrWrite(uint32_t uMsr, uint64_t u64Value);
@@ -69,18 +71,23 @@ VMMRCDECL(int) VMMGCEntry(PVM pVM, unsigned uOperation, unsigned uArg, ...)
case VMMGC_DO_VMMGC_INIT:
{
/*
- * Validate the svn revision (uArg).
+ * Validate the svn revision (uArg) and build type (ellipsis).
*/
if (uArg != VMMGetSvnRev())
return VERR_VMM_RC_VERSION_MISMATCH;
+ va_list va;
+ va_start(va, uArg);
+
+ uint32_t uBuildType = va_arg(va, uint32_t);
+ if (uBuildType != vmmGetBuildType())
+ return VERR_VMM_RC_VERSION_MISMATCH;
+
/*
* Initialize the runtime.
- * (The program timestamp is found in the elipsis.)
*/
- va_list va;
- va_start(va, uArg);
uint64_t u64TS = va_arg(va, uint64_t);
+
va_end(va);
int rc = RTRCInit(u64TS);
@@ -119,7 +126,7 @@ VMMRCDECL(int) VMMGCEntry(PVM pVM, unsigned uOperation, unsigned uArg, ...)
/*
* Testcase executes a privileged instruction to force a world switch. (in both SVM & VMX)
*/
- case VMMGC_DO_TESTCASE_HWACCM_NOP:
+ case VMMGC_DO_TESTCASE_HM_NOP:
ASMRdMsr_Low(MSR_IA32_SYSENTER_CS);
return 0;
@@ -338,6 +345,82 @@ static int vmmGCTest(PVM pVM, unsigned uOperation, unsigned uArg)
}
+
+/**
+ * Reads a range of MSRs.
+ *
+ * This is called directly via VMMR3CallRC.
+ *
+ * @returns VBox status code.
+ * @param pVM The VM handle.
+ * @param uMsr The MSR to start at.
+ * @param cMsrs The number of MSRs to read.
+ * @param paResults Where to store the results. This must be large
+ * enough to hold at least @a cMsrs result values.
+ */
+extern "C" VMMRCDECL(int)
+VMMRCTestReadMsrs(PVM pVM, uint32_t uMsr, uint32_t cMsrs, PVMMTESTMSRENTRY paResults)
+{
+ AssertReturn(cMsrs <= 16384, VERR_INVALID_PARAMETER);
+ AssertPtrReturn(paResults, VERR_INVALID_POINTER);
+ ASMIntEnable(); /* Run with interrupts enabled, so we can query more MSRs in one block. */
+
+ for (uint32_t i = 0; i < cMsrs; i++, uMsr++)
+ {
+ if (vmmRCSafeMsrRead(uMsr, &paResults[i].uValue))
+ paResults[i].uMsr = uMsr;
+ else
+ paResults[i].uMsr = UINT64_MAX;
+ }
+
+ ASMIntDisable();
+ return VINF_SUCCESS;
+}
+
+
+/**
+ * Tries to write the given value to an MSR, returns the effect and restors the
+ * original value.
+ *
+ * This is called directly via VMMR3CallRC.
+ *
+ * @returns VBox status code.
+ * @param pVM The VM handle.
+ * @param uMsr The MSR to start at.
+ * @param u32ValueLow The low part of the value to write.
+ * @param u32ValueHi The high part of the value to write.
+ * @param puValueBefore The value before writing.
+ * @param puValueAfter The value read back after writing.
+ */
+extern "C" VMMRCDECL(int)
+VMMRCTestTestWriteMsr(PVM pVM, uint32_t uMsr, uint32_t u32ValueLow, uint32_t u32ValueHi,
+ uint64_t *puValueBefore, uint64_t *puValueAfter)
+{
+ AssertPtrReturn(puValueBefore, VERR_INVALID_POINTER);
+ AssertPtrReturn(puValueAfter, VERR_INVALID_POINTER);
+ ASMIntDisable();
+
+ int rc = VINF_SUCCESS;
+ uint64_t uValueBefore = UINT64_MAX;
+ uint64_t uValueAfter = UINT64_MAX;
+ if (vmmRCSafeMsrRead(uMsr, &uValueBefore))
+ {
+ if (!vmmRCSafeMsrWrite(uMsr, RT_MAKE_U64(u32ValueLow, u32ValueHi)))
+ rc = VERR_WRITE_PROTECT;
+ if (!vmmRCSafeMsrRead(uMsr, &uValueAfter) && RT_SUCCESS(rc))
+ rc = VERR_READ_ERROR;
+ vmmRCSafeMsrWrite(uMsr, uValueBefore);
+ }
+ else
+ rc = VERR_ACCESS_DENIED;
+
+ *puValueBefore = uValueBefore;
+ *puValueAfter = uValueAfter;
+ return rc;
+}
+
+
+
/**
* Temporary \#PF trap handler for the \#PF test case.
*