- Timestamp:
- Nov 23, 2013 2:17:32 AM (11 years ago)
- Location:
- trunk/src/VBox/HostDrivers/Support
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
r49634 r49635 972 972 # ifdef SUPDRV_LINUX_HAS_SAFE_MSR_API 973 973 if (idCpu == NIL_RTCPUID) 974 idCpu = RTMpCpuId(); 975 else if (!RTMpIsCpuOnline(idCpu)) 976 return VERR_CPU_OFFLINE; 977 return RTMpOnSpecific(idCpu, supdrvOsMsrProberModifyOnCpu, pReq, NULL); 974 { 975 supdrvLnxMsrProberModifyOnCpu(idCpu, pReq); 976 return VINF_SUCCESS; 977 } 978 return RTMpOnSpecific(idCpu, supdrvLnxMsrProberModifyOnCpu, pReq, NULL); 978 979 # else 979 980 return VERR_NOT_SUPPORTED; -
trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
r49634 r49635 40 40 #include <iprt/string.h> 41 41 #include <VBox/log.h> 42 43 #include <iprt/asm-amd64-x86.h> 42 44 43 45 … … 1037 1039 #ifdef SUPDRV_WITH_MSR_PROBER 1038 1040 1041 /** 1042 * Argument package used by supdrvOSMsrProberRead and supdrvOSMsrProberWrite. 1043 */ 1044 typedef struct SUPDRVNTMSPROBERARGS 1045 { 1046 uint32_t uMsr; 1047 uint64_t uValue; 1048 bool fGp; 1049 } SUPDRVNTMSPROBERARGS; 1050 1051 /** @callback_method_impl{FNRTMPWORKER, Worker for supdrvOSMsrProberRead.} */ 1052 static DECLCALLBACK(void) supdrvNtMsProberReadOnCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2) 1053 { 1054 /* 1055 * rdmsr and wrmsr faults can be caught even with interrupts disabled. 1056 * (At least on 32-bit XP.) 1057 */ 1058 SUPDRVNTMSPROBERARGS *pArgs = (SUPDRVNTMSPROBERARGS *)pvUser1; NOREF(idCpu); NOREF(pvUser2); 1059 RTCCUINTREG fOldFlags = ASMIntDisableFlags(); 1060 __try 1061 { 1062 pArgs->uValue = ASMRdMsr(pArgs->uMsr); 1063 pArgs->fGp = false; 1064 } 1065 __except(EXCEPTION_EXECUTE_HANDLER) 1066 { 1067 pArgs->fGp = true; 1068 pArgs->uValue = 0; 1069 } 1070 ASMSetFlags(fOldFlags); 1071 } 1072 1073 1039 1074 int VBOXCALL supdrvOSMsrProberRead(uint32_t uMsr, RTCPUID idCpu, uint64_t *puValue) 1040 1075 { 1041 NOREF(uMsr); NOREF(idCpu); NOREF(puValue); 1042 return VERR_NOT_SUPPORTED; 1043 } 1044 1076 SUPDRVNTMSPROBERARGS Args; 1077 Args.uMsr = uMsr; 1078 Args.uValue = 0; 1079 Args.fGp = true; 1080 1081 if (idCpu == NIL_RTCPUID) 1082 supdrvNtMsProberReadOnCpu(idCpu, &Args, NULL); 1083 else 1084 { 1085 int rc = RTMpOnSpecific(idCpu, supdrvNtMsProberReadOnCpu, &Args, NULL); 1086 if (RT_FAILURE(rc)) 1087 return rc; 1088 } 1089 1090 if (Args.fGp) 1091 return VERR_ACCESS_DENIED; 1092 *puValue = Args.uValue; 1093 return VINF_SUCCESS; 1094 } 1095 1096 1097 /** @callback_method_impl{FNRTMPWORKER, Worker for supdrvOSMsrProberWrite.} */ 1098 static DECLCALLBACK(void) supdrvNtMsProberWriteOnCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2) 1099 { 1100 /* 1101 * rdmsr and wrmsr faults can be caught even with interrupts disabled. 1102 * (At least on 32-bit XP.) 1103 */ 1104 SUPDRVNTMSPROBERARGS *pArgs = (SUPDRVNTMSPROBERARGS *)pvUser1; NOREF(idCpu); NOREF(pvUser2); 1105 RTCCUINTREG fOldFlags = ASMIntDisableFlags(); 1106 __try 1107 { 1108 ASMWrMsr(pArgs->uMsr, pArgs->uValue); 1109 pArgs->fGp = false; 1110 } 1111 __except(EXCEPTION_EXECUTE_HANDLER) 1112 { 1113 pArgs->fGp = true; 1114 } 1115 ASMSetFlags(fOldFlags); 1116 } 1045 1117 1046 1118 int VBOXCALL supdrvOSMsrProberWrite(uint32_t uMsr, RTCPUID idCpu, uint64_t uValue) 1047 1119 { 1048 NOREF(uMsr); NOREF(idCpu); NOREF(uValue); 1049 return VERR_NOT_SUPPORTED; 1120 SUPDRVNTMSPROBERARGS Args; 1121 Args.uMsr = uMsr; 1122 Args.uValue = uValue; 1123 Args.fGp = true; 1124 1125 if (idCpu == NIL_RTCPUID) 1126 supdrvNtMsProberReadOnCpu(idCpu, &Args, NULL); 1127 else 1128 { 1129 int rc = RTMpOnSpecific(idCpu, supdrvNtMsProberReadOnCpu, &Args, NULL); 1130 if (RT_FAILURE(rc)) 1131 return rc; 1132 } 1133 1134 if (Args.fGp) 1135 return VERR_ACCESS_DENIED; 1136 return VINF_SUCCESS; 1137 } 1138 1139 /** @callback_method_impl{FNRTMPWORKER, Worker for supdrvOSMsrProberModify.} */ 1140 static DECLCALLBACK(void) supdrvNtMsProberModifyOnCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2) 1141 { 1142 PSUPMSRPROBER pReq = (PSUPMSRPROBER)pvUser1; 1143 register uint32_t uMsr = pReq->u.In.uMsr; 1144 bool const fFaster = pReq->u.In.enmOp == SUPMSRPROBEROP_MODIFY_FASTER; 1145 uint64_t uBefore = 0; 1146 uint64_t uWritten = 0; 1147 uint64_t uAfter = 0; 1148 bool fBeforeGp = true; 1149 bool fModifyGp = true; 1150 bool fAfterGp = true; 1151 bool fRestoreGp = true; 1152 RTCCUINTREG fOldFlags; 1153 1154 /* 1155 * Do the job. 1156 */ 1157 fOldFlags = ASMIntDisableFlags(); 1158 ASMCompilerBarrier(); /* paranoia */ 1159 if (!fFaster) 1160 ASMWriteBackAndInvalidateCaches(); 1161 1162 __try 1163 { 1164 uBefore = ASMRdMsr(uMsr); 1165 fBeforeGp = false; 1166 } 1167 __except(EXCEPTION_EXECUTE_HANDLER) 1168 { 1169 fBeforeGp = true; 1170 } 1171 if (!fBeforeGp) 1172 { 1173 register uint64_t uRestore = uBefore; 1174 1175 /* Modify. */ 1176 uWritten = uRestore; 1177 uWritten &= pReq->u.In.uArgs.Modify.fAndMask; 1178 uWritten |= pReq->u.In.uArgs.Modify.fOrMask; 1179 __try 1180 { 1181 ASMWrMsr(uMsr, uWritten); 1182 fModifyGp = false; 1183 } 1184 __except(EXCEPTION_EXECUTE_HANDLER) 1185 { 1186 fModifyGp = true; 1187 } 1188 1189 /* Read modified value. */ 1190 __try 1191 { 1192 uAfter = ASMRdMsr(uMsr); 1193 fAfterGp = false; 1194 } 1195 __except(EXCEPTION_EXECUTE_HANDLER) 1196 { 1197 fAfterGp = true; 1198 } 1199 1200 /* Restore original value. */ 1201 __try 1202 { 1203 ASMWrMsr(uMsr, uRestore); 1204 fRestoreGp = false; 1205 } 1206 __except(EXCEPTION_EXECUTE_HANDLER) 1207 { 1208 fRestoreGp = true; 1209 } 1210 1211 /* Invalid everything we can. */ 1212 if (!fFaster) 1213 { 1214 ASMWriteBackAndInvalidateCaches(); 1215 ASMReloadCR3(); 1216 ASMNopPause(); 1217 } 1218 } 1219 1220 ASMCompilerBarrier(); /* paranoia */ 1221 ASMSetFlags(fOldFlags); 1222 1223 /* 1224 * Write out the results. 1225 */ 1226 pReq->u.Out.uResults.Modify.uBefore = uBefore; 1227 pReq->u.Out.uResults.Modify.uWritten = uWritten; 1228 pReq->u.Out.uResults.Modify.uAfter = uAfter; 1229 pReq->u.Out.uResults.Modify.fBeforeGp = fBeforeGp; 1230 pReq->u.Out.uResults.Modify.fModifyGp = fModifyGp; 1231 pReq->u.Out.uResults.Modify.fAfterGp = fAfterGp; 1232 pReq->u.Out.uResults.Modify.fRestoreGp = fRestoreGp; 1233 RT_ZERO(pReq->u.Out.uResults.Modify.afReserved); 1050 1234 } 1051 1235 … … 1053 1237 int VBOXCALL supdrvOSMsrProberModify(RTCPUID idCpu, PSUPMSRPROBER pReq) 1054 1238 { 1055 NOREF(idCpu); NOREF(pReq); 1056 return VERR_NOT_SUPPORTED; 1239 if (idCpu == NIL_RTCPUID) 1240 { 1241 supdrvNtMsProberModifyOnCpu(idCpu, pReq, NULL); 1242 return VINF_SUCCESS; 1243 } 1244 return RTMpOnSpecific(idCpu, supdrvNtMsProberModifyOnCpu, pReq, NULL); 1057 1245 } 1058 1246
Note:
See TracChangeset
for help on using the changeset viewer.