diff options
Diffstat (limited to 'src/VBox/VMM/VMMRC/VMMRC.cpp')
| -rw-r--r-- | src/VBox/VMM/VMMRC/VMMRC.cpp | 95 |
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. * |
