VirtualBox

Changeset 49635 in vbox for trunk/src


Ignore:
Timestamp:
Nov 23, 2013 2:17:32 AM (11 years ago)
Author:
vboxsync
Message:

SUPDrv-win.cpp: Half tested windows MSR workers.

Location:
trunk/src/VBox/HostDrivers/Support
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c

    r49634 r49635  
    972972# ifdef SUPDRV_LINUX_HAS_SAFE_MSR_API
    973973    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);
    978979# else
    979980    return VERR_NOT_SUPPORTED;
  • trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp

    r49634 r49635  
    4040#include <iprt/string.h>
    4141#include <VBox/log.h>
     42
     43#include <iprt/asm-amd64-x86.h>
    4244
    4345
     
    10371039#ifdef SUPDRV_WITH_MSR_PROBER
    10381040
     1041/**
     1042 * Argument package used by supdrvOSMsrProberRead and supdrvOSMsrProberWrite.
     1043 */
     1044typedef 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.} */
     1052static 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
    10391074int VBOXCALL    supdrvOSMsrProberRead(uint32_t uMsr, RTCPUID idCpu, uint64_t *puValue)
    10401075{
    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.} */
     1098static 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}
    10451117
    10461118int VBOXCALL    supdrvOSMsrProberWrite(uint32_t uMsr, RTCPUID idCpu, uint64_t uValue)
    10471119{
    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.} */
     1140static 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);
    10501234}
    10511235
     
    10531237int VBOXCALL    supdrvOSMsrProberModify(RTCPUID idCpu, PSUPMSRPROBER pReq)
    10541238{
    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);
    10571245}
    10581246
Note: See TracChangeset for help on using the changeset viewer.

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