VirtualBox

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

Last change on this file since 69627 was 69584, checked in by vboxsync, 8 years ago

VBoxCpuReport: Need to be extra careful if MSR modifications are not all done in the kernel.

  • 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 69584 2017-11-04 22:31:10Z 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* Structures and Typedefs *
37*********************************************************************************************************************************/
38
39/*********************************************************************************************************************************
40* Global Variables *
41*********************************************************************************************************************************/
42/** The /dev/xxx/msr file descriptor. */
43static int g_fdMsr;
44
45
46static int linuxMsrProberRead(uint32_t uMsr, RTCPUID idCpu, uint64_t *puValue, bool *pfGp)
47{
48 int rc = VINF_SUCCESS;
49
50 if (idCpu != NIL_RTCPUID)
51 return VERR_INVALID_PARAMETER;
52
53 if (g_fdMsr < 0)
54 return VERR_INVALID_STATE;
55
56 *pfGp = true;
57 if (pread(g_fdMsr, puValue, sizeof(*puValue), uMsr) != sizeof(*puValue))
58 rc = VERR_READ_ERROR;
59 else
60 *pfGp = false;
61
62 return RT_SUCCESS(rc) && !pfGp;
63}
64
65static int linuxMsrProberWrite(uint32_t uMsr, RTCPUID idCpu, uint64_t uValue, bool *pfGp)
66{
67 int rc = VINF_SUCCESS;
68
69 if (idCpu != NIL_RTCPUID)
70 return VERR_INVALID_PARAMETER;
71
72 if (g_fdMsr < 0)
73 return VERR_INVALID_STATE;
74
75 *pfGp = true;
76 if (pwrite(g_fdMsr, &uValue, sizeof(uValue), uMsr) != sizeof(uValue))
77 rc = VERR_WRITE_ERROR;
78 else
79 *pfGp = false;
80
81 return RT_SUCCESS(rc) && !pfGp;
82}
83
84static int linuxMsrProberModify(uint32_t uMsr, RTCPUID idCpu, uint64_t fAndMask, uint64_t fOrMask, PSUPMSRPROBERMODIFYRESULT pResult)
85{
86 int rc = VINF_SUCCESS;
87 uint64_t uBefore, uWrite, uAfter;
88 int rcBefore, rcWrite, rcAfter, rcRestore;
89
90 if (idCpu != NIL_RTCPUID)
91 return VERR_INVALID_PARAMETER;
92
93 if (g_fdMsr < 0)
94 return VERR_INVALID_STATE;
95
96#if 0
97 vbCpuRepDebug("MSR %#x\n", uMsr);
98 RTThreadSleep(10);
99#endif
100 rcBefore = pread(g_fdMsr, &uBefore, sizeof(uBefore), uMsr) != sizeof(uBefore);
101 uWrite = (uBefore & fAndMask) | fOrMask;
102 rcWrite = pwrite(g_fdMsr, &uWrite, sizeof(uWrite), uMsr);
103 rcAfter = pread(g_fdMsr, &uAfter, sizeof(uAfter), uMsr) != sizeof(uAfter);
104 rcRestore = pwrite(g_fdMsr, &uBefore, sizeof(uBefore), uMsr) != sizeof(uBefore);
105
106#if 0
107 vbCpuRepDebug("MSR: %#x, %#llx -> %#llx -> %#llx (%d/%d/%d/%d)\n",
108 uMsr, uBefore, uWrite, uAfter,
109 rcBefore, rcWrite != sizeof(uWrite), rcAfter, rcRestore);
110#endif
111 pResult->uBefore = uBefore;
112 pResult->uWritten = uWrite;
113 pResult->uAfter = uAfter;
114 pResult->fBeforeGp = rcBefore;
115 pResult->fModifyGp = rcWrite != sizeof(uWrite);
116 pResult->fAfterGp = rcAfter;
117 pResult->fRestoreGp = rcRestore;
118
119 return rc;
120}
121
122static int linuxMsrProberTerm(void)
123{
124 if (g_fdMsr < 0)
125 return VERR_INVALID_STATE;
126
127 close(g_fdMsr);
128 return VINF_SUCCESS;
129}
130
131int PlatformMsrProberInit(VBMSRFNS *fnsMsr, bool *pfAtomicMsrMod)
132{
133 if (access(MSR_DEV_NAME, F_OK))
134 {
135 vbCpuRepDebug("warning: The " MSR_DEV_NAME " device does not exist\n");
136 return VERR_NOT_FOUND;
137 }
138
139 g_fdMsr = open(MSR_DEV_NAME, O_RDWR);
140 if (g_fdMsr <= 0)
141 {
142 vbCpuRepDebug("warning: Failed to open " MSR_DEV_NAME "\n");
143 return VERR_ACCESS_DENIED;
144 }
145
146 fnsMsr->msrRead = linuxMsrProberRead;
147 fnsMsr->msrWrite = linuxMsrProberWrite;
148 fnsMsr->msrModify = linuxMsrProberModify;
149 fnsMsr->msrProberTerm = linuxMsrProberTerm;
150 *pfAtomicMsrMod = false; /* Can't modify/restore MSRs without trip to R3. */
151
152 return VINF_SUCCESS;
153}
Note: See TracBrowser for help on using the repository browser.

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