VirtualBox

source: vbox/trunk/src/VBox/VMM/tools/MsrLinux.cpp@ 69653

Last change on this file since 69653 was 69653, checked in by vboxsync, 7 years ago

VMM: scm cleanups

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.0 KB
Line 
1/* $Id: MsrLinux.cpp 69653 2017-11-10 18:42:55Z vboxsync $ */
2/** @file
3 * MsrLinux - Linux-specific MSR access.
4 */
5
6/*
7 * Copyright (C) 2013-2017 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#include <iprt/ctype.h>
23#include <iprt/thread.h>
24
25#include <VBox/sup.h>
26#include "VBoxCpuReport.h"
27
28#include <unistd.h>
29#include <fcntl.h>
30#include <errno.h>
31
32
33#define MSR_DEV_NAME "/dev/cpu/0/msr"
34
35
36/*********************************************************************************************************************************
37* Structures and Typedefs *
38*********************************************************************************************************************************/
39
40
41/*********************************************************************************************************************************
42* Global Variables *
43*********************************************************************************************************************************/
44/** The /dev/xxx/msr file descriptor. */
45static int g_fdMsr;
46
47
48static int linuxMsrProberRead(uint32_t uMsr, RTCPUID idCpu, uint64_t *puValue, bool *pfGp)
49{
50 int rc = VINF_SUCCESS;
51
52 if (idCpu != NIL_RTCPUID)
53 return VERR_INVALID_PARAMETER;
54
55 if (g_fdMsr < 0)
56 return VERR_INVALID_STATE;
57
58 *pfGp = true;
59 if (pread(g_fdMsr, puValue, sizeof(*puValue), uMsr) != sizeof(*puValue))
60 rc = VERR_READ_ERROR;
61 else
62 *pfGp = false;
63
64 return RT_SUCCESS(rc) && !pfGp;
65}
66
67static int linuxMsrProberWrite(uint32_t uMsr, RTCPUID idCpu, uint64_t uValue, bool *pfGp)
68{
69 int rc = VINF_SUCCESS;
70
71 if (idCpu != NIL_RTCPUID)
72 return VERR_INVALID_PARAMETER;
73
74 if (g_fdMsr < 0)
75 return VERR_INVALID_STATE;
76
77 *pfGp = true;
78 if (pwrite(g_fdMsr, &uValue, sizeof(uValue), uMsr) != sizeof(uValue))
79 rc = VERR_WRITE_ERROR;
80 else
81 *pfGp = false;
82
83 return RT_SUCCESS(rc) && !pfGp;
84}
85
86static int linuxMsrProberModify(uint32_t uMsr, RTCPUID idCpu, uint64_t fAndMask, uint64_t fOrMask, PSUPMSRPROBERMODIFYRESULT pResult)
87{
88 int rc = VINF_SUCCESS;
89 uint64_t uBefore, uWrite, uAfter;
90 int rcBefore, rcWrite, rcAfter, rcRestore;
91
92 if (idCpu != NIL_RTCPUID)
93 return VERR_INVALID_PARAMETER;
94
95 if (g_fdMsr < 0)
96 return VERR_INVALID_STATE;
97
98#if 0
99 vbCpuRepDebug("MSR %#x\n", uMsr);
100 RTThreadSleep(10);
101#endif
102 rcBefore = pread(g_fdMsr, &uBefore, sizeof(uBefore), uMsr) != sizeof(uBefore);
103 uWrite = (uBefore & fAndMask) | fOrMask;
104 rcWrite = pwrite(g_fdMsr, &uWrite, sizeof(uWrite), uMsr);
105 rcAfter = pread(g_fdMsr, &uAfter, sizeof(uAfter), uMsr) != sizeof(uAfter);
106 rcRestore = pwrite(g_fdMsr, &uBefore, sizeof(uBefore), uMsr) != sizeof(uBefore);
107
108#if 0
109 vbCpuRepDebug("MSR: %#x, %#llx -> %#llx -> %#llx (%d/%d/%d/%d)\n",
110 uMsr, uBefore, uWrite, uAfter,
111 rcBefore, rcWrite != sizeof(uWrite), rcAfter, rcRestore);
112#endif
113 pResult->uBefore = uBefore;
114 pResult->uWritten = uWrite;
115 pResult->uAfter = uAfter;
116 pResult->fBeforeGp = rcBefore;
117 pResult->fModifyGp = rcWrite != sizeof(uWrite);
118 pResult->fAfterGp = rcAfter;
119 pResult->fRestoreGp = rcRestore;
120
121 return rc;
122}
123
124static int linuxMsrProberTerm(void)
125{
126 if (g_fdMsr < 0)
127 return VERR_INVALID_STATE;
128
129 close(g_fdMsr);
130 return VINF_SUCCESS;
131}
132
133int PlatformMsrProberInit(VBMSRFNS *fnsMsr, bool *pfAtomicMsrMod)
134{
135 if (access(MSR_DEV_NAME, F_OK))
136 {
137 vbCpuRepDebug("warning: The " MSR_DEV_NAME " device does not exist\n");
138 return VERR_NOT_FOUND;
139 }
140
141 g_fdMsr = open(MSR_DEV_NAME, O_RDWR);
142 if (g_fdMsr <= 0)
143 {
144 vbCpuRepDebug("warning: Failed to open " MSR_DEV_NAME "\n");
145 return VERR_ACCESS_DENIED;
146 }
147
148 fnsMsr->msrRead = linuxMsrProberRead;
149 fnsMsr->msrWrite = linuxMsrProberWrite;
150 fnsMsr->msrModify = linuxMsrProberModify;
151 fnsMsr->msrProberTerm = linuxMsrProberTerm;
152 *pfAtomicMsrMod = false; /* Can't modify/restore MSRs without trip to R3. */
153
154 return VINF_SUCCESS;
155}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette