Changeset 57989 in vbox
- Timestamp:
- Oct 1, 2015 4:44:12 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 21 edited
-
include/VBox/err.h (modified) (1 diff)
-
include/VBox/log.h (modified) (2 diffs)
-
include/VBox/vmm/gim.h (modified) (2 diffs)
-
include/VBox/vmm/vm.h (modified) (5 diffs)
-
src/VBox/Devices/GIMDev/DrvUDP.cpp (added)
-
src/VBox/Devices/GIMDev/GIMDev.cpp (modified) (5 diffs)
-
src/VBox/Devices/Makefile.kmk (modified) (1 diff)
-
src/VBox/Devices/build/VBoxDD.cpp (modified) (1 diff)
-
src/VBox/Devices/build/VBoxDD.h (modified) (1 diff)
-
src/VBox/Main/src-client/ConsoleImpl2.cpp (modified) (1 diff)
-
src/VBox/VMM/VMMAll/GIMAll.cpp (modified) (3 diffs)
-
src/VBox/VMM/VMMAll/GIMAllHv.cpp (modified) (12 diffs)
-
src/VBox/VMM/VMMAll/GIMAllKvm.cpp (modified) (4 diffs)
-
src/VBox/VMM/VMMR0/HMSVMR0.cpp (modified) (1 diff)
-
src/VBox/VMM/VMMR0/HMVMXR0.cpp (modified) (1 diff)
-
src/VBox/VMM/VMMR3/EMHM.cpp (modified) (1 diff)
-
src/VBox/VMM/VMMR3/EMRaw.cpp (modified) (1 diff)
-
src/VBox/VMM/VMMR3/GIM.cpp (modified) (2 diffs)
-
src/VBox/VMM/VMMR3/GIMHv.cpp (modified) (14 diffs)
-
src/VBox/VMM/include/EMHandleRCTmpl.h (modified) (1 diff)
-
src/VBox/VMM/include/GIMHvInternal.h (modified) (13 diffs)
-
src/VBox/VMM/include/GIMInternal.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/err.h
r57213 r57989 2671 2671 /** Hypercall cannot be enabled/performed due to access/permissions/CPL. */ 2672 2672 #define VERR_GIM_HYPERCALL_ACCESS_DENIED (-6311) 2673 /** Failed to read to a memory region while performing a hypercall. */ 2674 #define VERR_GIM_HYPERCALL_MEMORY_READ_FAILED (-6312) 2675 /** Failed to write to a memory region while performing a hypercall. */ 2676 #define VERR_GIM_HYPERCALL_MEMORY_WRITE_FAILED (-6313) 2677 /** Generic hypercall operation failure. */ 2678 #define VERR_GIM_HYPERCALL_FAILED (-6314) 2679 /** No debug connection configured. */ 2680 #define VERR_GIM_NO_DEBUG_CONNECTION (-6315) 2681 /** Return to ring-3 to perform the hypercall there. */ 2682 #define VINF_GIM_R3_HYPERCALL 6316 2673 2683 /** @} */ 2674 2684 -
trunk/include/VBox/log.h
r57809 r57989 228 228 /** TUN network transport driver group */ 229 229 LOG_GROUP_DRV_TUN, 230 /** UDP socket stream driver group. */ 231 LOG_GROUP_DRV_UDP, 230 232 /** UDP tunnet network transport driver group. */ 231 233 LOG_GROUP_DRV_UDPTUNNEL, … … 885 887 "DRV_TRANSPORT_ASYNC", \ 886 888 "DRV_TUN", \ 889 "DRV_UDP", \ 887 890 "DRV_UDPTUNNEL", \ 888 891 "DRV_USBPROXY", \ -
trunk/include/VBox/vmm/gim.h
r55129 r57989 32 32 33 33 #include <VBox/vmm/cpum.h> 34 #include <VBox/vmm/pdmifs.h> 34 35 35 36 /** The value used to specify that VirtualBox must use the newest … … 164 165 VMMR3_INT_DECL(int) GIMR3Term(PVM pVM); 165 166 VMMR3_INT_DECL(void) GIMR3Reset(PVM pVM); 166 VMMR3DECL(void) GIMR3GimDeviceRegister(PVM pVM, PPDMDEVINS pDevIns );167 VMMR3DECL(void) GIMR3GimDeviceRegister(PVM pVM, PPDMDEVINS pDevInsR3, PPDMISTREAM pDebugStreamR3); 167 168 VMMR3DECL(PGIMMMIO2REGION) GIMR3GetMmio2Regions(PVM pVM, uint32_t *pcRegions); 168 169 /** @} */ -
trunk/include/VBox/vmm/vm.h
r57492 r57989 225 225 struct GIMCPU s; 226 226 #endif 227 uint8_t padding[64]; /* multiple of 64 */227 uint8_t padding[64]; /* multiple of 64 */ 228 228 } gim; 229 229 … … 1119 1119 struct SSM s; 1120 1120 #endif 1121 uint8_t padding[128]; /* multiple of 64 */1121 uint8_t padding[128]; /* multiple of 64 */ 1122 1122 } ssm; 1123 1123 … … 1128 1128 struct FTM s; 1129 1129 #endif 1130 uint8_t padding[512]; /* multiple of 64 */1130 uint8_t padding[512]; /* multiple of 64 */ 1131 1131 } ftm; 1132 1132 … … 1145 1145 struct GIM s; 1146 1146 #endif 1147 uint8_t padding[320 ];/* multiple of 64 */1147 uint8_t padding[320+64]; /* multiple of 64 */ 1148 1148 } gim; 1149 1149 … … 1170 1170 1171 1171 /** Padding for aligning the cpu array on a page boundary. */ 1172 uint8_t abAlignment2[ 30];1172 uint8_t abAlignment2[4062]; 1173 1173 1174 1174 /* ---- end small stuff ---- */ -
trunk/src/VBox/Devices/GIMDev/GIMDev.cpp
r57358 r57989 26 26 27 27 #include "VBoxDD.h" 28 #include <iprt/uuid.h> 29 30 #define GIMDEV_DEBUG_LUN 998 28 31 29 32 /** … … 40 43 /** Alignment. */ 41 44 RTRCPTR Alignment0; 45 46 /** LUN\#998: The debug interface. */ 47 PDMIBASE IDbgBase; 48 /** LUN\#998: The stream port interface. */ 49 PDMISTREAM IDbgStreamPort; 50 /** Pointer to the attached base debug driver. */ 51 R3PTRTYPE(PPDMIBASE) pDbgDrvBase; 52 /** Pointer to the attached debug stream driver. */ 53 R3PTRTYPE(PPDMISTREAM) pDbgDrvStream; 42 54 } GIMDEV; 43 55 /** Pointer to the GIM device state. */ 44 56 typedef GIMDEV *PGIMDEV; 45 57 AssertCompileMemberAlignment(GIMDEV, IDbgBase, 8); 46 58 47 59 #ifndef VBOX_DEVICE_STRUCT_TESTCASE 48 60 49 61 #ifdef IN_RING3 62 63 64 /* -=-=-=-=-=-=-=-=- PDMIBASE on LUN#GIMDEV_DEBUG_LUN -=-=-=-=-=-=-=-=- */ 65 66 /** 67 * @interface_method_impl{PDMIBASE, pfnQueryInterface} 68 */ 69 static DECLCALLBACK(void *) gimdevR3QueryInterface(PPDMIBASE pInterface, const char *pszIID) 70 { 71 PGIMDEV pThis = RT_FROM_MEMBER(pInterface, GIMDEV, IDbgBase); 72 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThis->IDbgBase); 73 PDMIBASE_RETURN_INTERFACE(pszIID, PDMISTREAM, &pThis->IDbgStreamPort); 74 return NULL; 75 } 76 77 50 78 /** 51 79 * @interface_method_impl{PDMDEVREG,pfnConstruct} … … 65 93 66 94 /* 95 * Attach the stream driver for the debug connection. 96 */ 97 pThis->IDbgBase.pfnQueryInterface = gimdevR3QueryInterface; 98 int rc = PDMDevHlpDriverAttach(pDevIns, GIMDEV_DEBUG_LUN, &pThis->IDbgBase, &pThis->pDbgDrvBase, "GIM Debug Port"); 99 if (RT_SUCCESS(rc)) 100 { 101 pThis->pDbgDrvStream = PDMIBASE_QUERY_INTERFACE(pThis->pDbgDrvBase, PDMISTREAM); 102 if (pThis->pDbgDrvStream) 103 LogRel(("GIMDev: LUN#%u: Debug port configured\n", GIMDEV_DEBUG_LUN)); 104 else 105 LogRel(("GIMDev: LUN#%u: No unit\n", GIMDEV_DEBUG_LUN)); 106 } 107 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 108 { 109 pThis->pDbgDrvBase = NULL; 110 pThis->pDbgDrvStream = NULL; 111 LogRel(("GIMDev: LUN#%u: No debug port configured\n", GIMDEV_DEBUG_LUN)); 112 } 113 else 114 { 115 AssertLogRelMsgFailed(("GIMDev: LUN#%u: Failed to attach to driver on debug port. rc=%Rrc\n", GIMDEV_DEBUG_LUN, rc)); 116 /* Don't call VMSetError here as we assume that the driver already set an appropriate error */ 117 return rc; 118 } 119 120 /* 67 121 * Register ourselves with the GIM VMM component. 68 122 */ 69 123 PVM pVM = PDMDevHlpGetVM(pDevIns); 70 GIMR3GimDeviceRegister(pVM, pDevIns );124 GIMR3GimDeviceRegister(pVM, pDevIns, pThis->pDbgDrvStream); 71 125 72 126 /* … … 85 139 { 86 140 Assert(!pCur->fRegistered); 87 intrc = PDMDevHlpMMIO2Register(pDevIns, pCur->iRegion, pCur->cbRegion, 0 /* fFlags */, &pCur->pvPageR3,141 rc = PDMDevHlpMMIO2Register(pDevIns, pCur->iRegion, pCur->cbRegion, 0 /* fFlags */, &pCur->pvPageR3, 88 142 pCur->szDescription); 89 143 if (RT_FAILURE(rc)) … … 126 180 return VINF_SUCCESS; 127 181 } 182 128 183 129 184 /** -
trunk/src/VBox/Devices/Makefile.kmk
r57809 r57989 153 153 PC/DevPcArch.cpp \ 154 154 GIMDev/GIMDev.cpp \ 155 GIMDev/DrvUDP.cpp \ 155 156 VMMDev/VMMDev.cpp \ 156 157 $(if $(VBOX_WITH_HGCM),VMMDev/VMMDevHGCM.cpp,) \ -
trunk/src/VBox/Devices/build/VBoxDD.cpp
r57809 r57989 339 339 if (RT_FAILURE(rc)) 340 340 return rc; 341 rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvUDP); 342 if (RT_FAILURE(rc)) 343 return rc; 341 344 rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvRawFile); 342 345 if (RT_FAILURE(rc)) -
trunk/src/VBox/Devices/build/VBoxDD.h
r57809 r57989 146 146 extern const PDMDRVREG g_DrvNamedPipe; 147 147 extern const PDMDRVREG g_DrvTCP; 148 extern const PDMDRVREG g_DrvUDP; 148 149 extern const PDMDRVREG g_DrvRawFile; 149 150 extern const PDMDRVREG g_DrvHostParallel; -
trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
r57979 r57989 1410 1410 InsertConfigInteger(pInst, "Trusted", 1); /* boolean */ 1411 1411 //InsertConfigNode(pInst, "Config", &pCfg); 1412 1413 InsertConfigNode(pInst, "LUN#998", &pLunL0); 1414 InsertConfigString(pLunL0, "Driver", "UDP"); 1415 InsertConfigNode(pLunL0, "Config", &pLunL1); 1416 InsertConfigString(pLunL1, "ServerAddress", "127.0.0.1"); 1417 InsertConfigInteger(pLunL1, "ServerPort", 51000); 1412 1418 } 1413 1419 -
trunk/src/VBox/VMM/VMMAll/GIMAll.cpp
r57358 r57989 88 88 * @param pVCpu Pointer to the VMCPU. 89 89 * @param pCtx Pointer to the guest-CPU context. 90 * 91 * @remarks Guest RIP may or may not have been incremented at this point. 90 92 */ 91 93 VMM_INT_DECL(int) GIMHypercall(PVMCPU pVCpu, PCPUMCTX pCtx) … … 162 164 return gimKvmShouldTrapXcptUD(pVCpu); 163 165 166 case GIMPROVIDERID_HYPERV: 167 return gimHvShouldTrapXcptUD(pVCpu); 168 164 169 default: 165 170 return false; … … 185 190 case GIMPROVIDERID_KVM: 186 191 return gimKvmXcptUD(pVCpu, pCtx, pDis); 192 193 case GIMPROVIDERID_HYPERV: 194 return gimHvXcptUD(pVCpu, pCtx, pDis); 187 195 188 196 default: -
trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp
r57851 r57989 24 24 #include "GIMInternal.h" 25 25 26 #include <iprt/asm-amd64-x86.h> 27 #ifdef IN_RING3 28 # include <iprt/mem.h> 29 #endif 30 26 31 #include <VBox/err.h> 32 #include <VBox/vmm/em.h> 27 33 #include <VBox/vmm/hm.h> 28 34 #include <VBox/vmm/tm.h> … … 32 38 #include <VBox/vmm/pdmapi.h> 33 39 34 #include <iprt/asm-amd64-x86.h> 35 36 37 /** 38 * Handles the Hyper-V hypercall. 40 41 #ifdef IN_RING3 42 /** 43 * Helper for reading and validating slow hypercall input/output parameters. 44 * 45 * A 'slow' hypercall is one that passes parameters pointers through guest 46 * memory as opposed to a 'fast' hypercall which passes parameters through guest 47 * general-purpose registers. 48 * 49 * @returns VBox status code. 50 * @param pVM Pointer to the VM. 51 * @param pCtx Pointer to the guest-CPU context. 52 * @param fIs64BitMode Whether the guest is currently in 64-bit mode or not. 53 * @param pGCPhysIn Where to store the guest-physical address of the 54 * hypercall input page. Optional, can be NULL. 55 * @param pGCPhysOut Where to store the guest-physical address of the 56 * hypercall output page. Optional, can be NULL. 57 * @param prcHv Where to store the Hyper-V status code. Only valid 58 * to the caller when this function returns 59 * VINF_SUCCESS. 60 */ 61 static int gimHvReadSlowHypercallParams(PVM pVM, PCPUMCTX pCtx, bool fIs64BitMode, PRTGCPHYS pGCPhysIn, PRTGCPHYS pGCPhysOut, 62 int *prcHv) 63 { 64 int rc = VINF_SUCCESS; 65 RTGCPHYS GCPhysIn = fIs64BitMode ? pCtx->rdx : (pCtx->rbx << 32) | pCtx->ecx; 66 RTGCPHYS GCPhysOut = fIs64BitMode ? pCtx->r8 : (pCtx->rdi << 32) | pCtx->esi; 67 if (pGCPhysIn) 68 *pGCPhysIn = GCPhysIn; 69 if (pGCPhysOut) 70 *pGCPhysOut = GCPhysOut; 71 if ( RT_ALIGN_64(GCPhysIn, 8) == GCPhysIn 72 && RT_ALIGN_64(GCPhysOut, 8) == GCPhysOut) 73 { 74 if ( PGMPhysIsGCPhysNormal(pVM, GCPhysIn) 75 && PGMPhysIsGCPhysNormal(pVM, GCPhysOut)) 76 { 77 PGIMHV pHv = &pVM->gim.s.u.Hv; 78 rc = PGMPhysSimpleReadGCPhys(pVM, pHv->pbHypercallIn, GCPhysIn, GIM_HV_PAGE_SIZE); 79 if (RT_SUCCESS(rc)) 80 { 81 rc = PGMPhysSimpleReadGCPhys(pVM, pHv->pbHypercallOut, GCPhysOut, GIM_HV_PAGE_SIZE); 82 if (RT_SUCCESS(rc)) 83 { 84 *prcHv = GIM_HV_STATUS_SUCCESS; 85 return VINF_SUCCESS; 86 } 87 Log(("GIM: HyperV: gimHvReadSlowHypercallParams reading GCPhysOut=%#RGp failed. rc=%Rrc\n", GCPhysOut, rc)); 88 rc = VERR_GIM_HYPERCALL_MEMORY_READ_FAILED; 89 } 90 else 91 { 92 Log(("GIM: HyperV: gimHvReadSlowHypercallParams reading GCPhysIn=%#RGp failed. rc=%Rrc\n", GCPhysIn,rc)); 93 rc = VERR_GIM_HYPERCALL_MEMORY_READ_FAILED; 94 } 95 } 96 else 97 *prcHv = GIM_HV_STATUS_INVALID_PARAMETER; 98 } 99 else 100 *prcHv = GIM_HV_STATUS_INVALID_ALIGNMENT; 101 return rc; 102 } 103 #endif 104 105 106 /** 107 * Handles all Hyper-V hypercalls. 39 108 * 40 109 * @returns VBox status code. 41 110 * @param pVCpu Pointer to the VMCPU. 42 111 * @param pCtx Pointer to the guest-CPU context. 112 * 113 * @thread EMT. 114 * @remarks Guest RIP may or may not have been incremented at this point. 43 115 */ 44 116 VMM_INT_DECL(int) gimHvHypercall(PVMCPU pVCpu, PCPUMCTX pCtx) 45 117 { 46 NOREF(pCtx); 118 #ifndef IN_RING3 119 return VINF_GIM_R3_HYPERCALL; 120 #else 47 121 PVM pVM = pVCpu->CTX_SUFF(pVM); 122 123 /* 124 * Verify that hypercalls are enabled. 125 */ 48 126 if (!MSR_GIM_HV_HYPERCALL_IS_ENABLED(pVM->gim.s.u.Hv.u64HypercallMsr)) 49 127 return VERR_GIM_HYPERCALLS_NOT_ENABLED; 50 128 51 /** @todo Handle hypercalls. Fail for now */ 52 return VERR_GIM_IPE_3; 129 /* 130 * Verify guest is in ring-0 protected mode. 131 */ 132 uint32_t uCpl = CPUMGetGuestCPL(pVCpu); 133 if ( uCpl 134 || CPUMIsGuestInRealModeEx(pCtx)) 135 { 136 return VERR_GIM_HYPERCALL_ACCESS_DENIED; 137 } 138 139 /* 140 * Get the hypercall operation code and modes. 141 */ 142 const bool fIs64BitMode = CPUMIsGuestIn64BitCodeEx(pCtx); 143 const uint64_t uHyperIn = fIs64BitMode ? pCtx->rcx : (pCtx->rdx << 32) | pCtx->eax; 144 const uint16_t uHyperOp = GIM_HV_HYPERCALL_IN_CALL_CODE(uHyperIn); 145 const bool fHyperFast = GIM_HV_HYPERCALL_IN_IS_FAST(uHyperIn); 146 const uint16_t cHyperReps = GIM_HV_HYPERCALL_IN_REP_COUNT(uHyperIn); 147 const uint16_t idxHyperRepStart = GIM_HV_HYPERCALL_IN_REP_START_IDX(uHyperIn); 148 uint64_t cHyperRepsDone = 0; 149 150 int rc = VINF_SUCCESS; 151 int rcHv = GIM_HV_STATUS_OPERATION_DENIED; 152 PGIMHV pHv = &pVM->gim.s.u.Hv; 153 154 /* 155 * Validate common hypercall input parameters. 156 */ 157 if ( !GIM_HV_HYPERCALL_IN_RSVD_1(uHyperIn) 158 && !GIM_HV_HYPERCALL_IN_RSVD_2(uHyperIn) 159 && !GIM_HV_HYPERCALL_IN_RSVD_3(uHyperIn)) 160 { 161 /* 162 * Perform the hypercall. 163 */ 164 switch (uHyperOp) 165 { 166 case GIM_HV_HYPERCALL_OP_RETREIVE_DEBUG_DATA: /* Non-rep, memory IO. */ 167 { 168 if (pHv->uPartFlags & GIM_HV_PART_FLAGS_DEBUGGING) 169 { 170 RTGCPHYS GCPhysOut; 171 rc = gimHvReadSlowHypercallParams(pVM, pCtx, fIs64BitMode, NULL /*pGCPhysIn*/, &GCPhysOut, &rcHv); 172 if ( RT_SUCCESS(rc) 173 && rcHv == GIM_HV_STATUS_SUCCESS) 174 { 175 rc = gimR3HvHypercallRetrieveDebugData(pVM, GCPhysOut, &rcHv); 176 if (RT_FAILURE(rc)) 177 LogRelMax(10, ("GIM: HyperV: gimR3HvHypercallRetrieveDebugData failed. rc=%Rrc\n", rc)); 178 } 179 } 180 else 181 rcHv = GIM_HV_STATUS_ACCESS_DENIED; 182 break; 183 } 184 185 case GIM_HV_HYPERCALL_OP_POST_DEBUG_DATA: /* Non-rep, memory IO. */ 186 { 187 if (pHv->uPartFlags & GIM_HV_PART_FLAGS_DEBUGGING) 188 { 189 RTGCPHYS GCPhysOut; 190 rc = gimHvReadSlowHypercallParams(pVM, pCtx, fIs64BitMode, NULL /*pGCPhysIn*/, &GCPhysOut, &rcHv); 191 if ( RT_SUCCESS(rc) 192 && rcHv == GIM_HV_STATUS_SUCCESS) 193 { 194 rc = gimR3HvHypercallPostDebugData(pVM, GCPhysOut, &rcHv); 195 if (RT_FAILURE(rc)) 196 LogRelMax(10, ("GIM: HyperV: gimR3HvHypercallPostDebugData failed. rc=%Rrc\n", rc)); 197 } 198 } 199 else 200 rcHv = GIM_HV_STATUS_ACCESS_DENIED; 201 break; 202 } 203 204 case GIM_HV_HYPERCALL_OP_RESET_DEBUG_SESSION: /* Non-rep, fast (register IO). */ 205 { 206 if (pHv->uPartFlags & GIM_HV_PART_FLAGS_DEBUGGING) 207 { 208 uint32_t fFlags = 0; 209 if (!fHyperFast) 210 { 211 rc = gimHvReadSlowHypercallParams(pVM, pCtx, fIs64BitMode, NULL /*pGCPhysIn*/, NULL /*pGCPhysOut*/, 212 &rcHv); 213 if ( RT_SUCCESS(rc) 214 && rcHv == GIM_HV_STATUS_SUCCESS) 215 { 216 PGIMHVDEBUGRESETIN pIn = (PGIMHVDEBUGRESETIN)pHv->pbHypercallIn; 217 fFlags = pIn->fFlags; 218 } 219 } 220 else 221 { 222 rcHv = GIM_HV_STATUS_SUCCESS; 223 fFlags = fIs64BitMode ? pCtx->rdx : pCtx->ebx; 224 } 225 226 /* 227 * Since we don't really maintain our own buffers for the debug 228 * communication channel, we don't have anything to flush. 229 */ 230 if (rcHv == GIM_HV_STATUS_SUCCESS) 231 { 232 if (!fFlags) 233 rcHv = GIM_HV_STATUS_INVALID_PARAMETER; 234 } 235 } 236 else 237 rcHv = GIM_HV_STATUS_ACCESS_DENIED; 238 break; 239 } 240 241 default: 242 rcHv = GIM_HV_STATUS_INVALID_HYPERCALL_CODE; 243 break; 244 } 245 } 246 else 247 rcHv = GIM_HV_STATUS_INVALID_HYPERCALL_INPUT; 248 249 /* 250 * Update the guest with results of the hypercall. 251 */ 252 if (RT_SUCCESS(rc)) 253 { 254 if (fIs64BitMode) 255 pCtx->rax = (cHyperRepsDone << 32) | rcHv; 256 else 257 { 258 pCtx->edx = cHyperRepsDone; 259 pCtx->eax = rcHv; 260 } 261 } 262 263 return rc; 264 #endif 53 265 } 54 266 … … 122 334 * @param pRange The range this MSR belongs to. 123 335 * @param puValue Where to store the MSR value read. 336 * 337 * @thread EMT. 124 338 */ 125 339 VMM_INT_DECL(VBOXSTRICTRC) gimHvReadMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue) … … 195 409 case MSR_GIM_HV_CRASH_P4: *puValue = pHv->uCrashP4; return VINF_SUCCESS; 196 410 411 case MSR_GIM_HV_DEBUG_OPTIONS_MSR: 412 { 413 if (pHv->fIsVendorMsHv) 414 { 415 *puValue = GIM_HV_DEBUG_OPTIONS_MSR_ENABLE; 416 return VINF_SUCCESS; 417 } 418 return VERR_CPUM_RAISE_GP_0; 419 } 420 197 421 default: 198 422 { … … 201 425 if (s_cTimes++ < 20) 202 426 LogRel(("GIM: HyperV: Unknown/invalid RdMsr (%#x) -> #GP(0)\n", idMsr)); 427 #else 428 return VINF_CPUM_R3_MSR_READ; 203 429 #endif 204 430 LogFunc(("Unknown/invalid RdMsr (%#RX32) -> #GP(0)\n", idMsr)); … … 222 448 * @param pRange The range this MSR belongs to. 223 449 * @param uRawValue The raw value with the ignored bits not masked. 450 * 451 * @thread EMT. 224 452 */ 225 453 VMM_INT_DECL(VBOXSTRICTRC) gimHvWriteMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t uRawValue) … … 253 481 gimR3HvDisableHypercallPage(pVM); 254 482 pHv->u64HypercallMsr &= ~MSR_GIM_HV_HYPERCALL_ENABLE_BIT; 483 LogRel(("GIM: HyperV: Hypercalls disabled via Guest OS ID Msr\n")); 255 484 } 256 485 else … … 286 515 return VINF_CPUM_R3_MSR_WRITE; 287 516 #else /* IN_RING3 */ 517 # if 0 288 518 /* 289 519 * For now ignore writes to the hypercall MSR (i.e. keeps it disabled). … … 292 522 */ 293 523 return VINF_SUCCESS; 294 # if 0524 # else 295 525 /* First, update all but the hypercall enable bit. */ 296 526 pHv->u64HypercallMsr = (uRawValue & ~MSR_GIM_HV_HYPERCALL_ENABLE_BIT); … … 399 629 return VERR_CPUM_RAISE_GP_0; 400 630 631 case MSR_GIM_HV_DEBUG_OPTIONS_MSR: 632 { 633 if (pHv->fIsVendorMsHv) 634 return VINF_SUCCESS; 635 return VERR_CPUM_RAISE_GP_0; 636 } 637 401 638 default: 402 639 { … … 406 643 LogRel(("GIM: HyperV: Unknown/invalid WrMsr (%#x,%#x`%08x) -> #GP(0)\n", idMsr, 407 644 uRawValue & UINT64_C(0xffffffff00000000), uRawValue & UINT64_C(0xffffffff))); 645 #else 646 return VINF_CPUM_R3_MSR_WRITE; 408 647 #endif 409 648 LogFunc(("Unknown/invalid WrMsr (%#RX32,%#RX64) -> #GP(0)\n", idMsr, uRawValue)); … … 415 654 } 416 655 656 657 /** 658 * Whether we need to trap #UD exceptions in the guest. 659 * 660 * We only need to trap #UD exceptions for raw-mode guests when hypercalls are 661 * enabled. For HM VMs, the hypercall would be handled via the 662 * VMCALL/VMMCALL VM-exit. 663 * 664 * @param pVCpu Pointer to the VMCPU. 665 */ 666 VMM_INT_DECL(bool) gimHvShouldTrapXcptUD(PVMCPU pVCpu) 667 { 668 PVM pVM = pVCpu->CTX_SUFF(pVM); 669 if ( !HMIsEnabled(pVM) 670 && gimHvAreHypercallsEnabled(pVCpu)) 671 return true; 672 return false; 673 } 674 675 676 /** 677 * Exception handler for #UD. 678 * 679 * @param pVCpu Pointer to the VMCPU. 680 * @param pCtx Pointer to the guest-CPU context. 681 * @param pDis Pointer to the disassembled instruction state at RIP. 682 * Optional, can be NULL. 683 * 684 * @thread EMT. 685 */ 686 VMM_INT_DECL(int) gimHvXcptUD(PVMCPU pVCpu, PCPUMCTX pCtx, PDISCPUSTATE pDis) 687 { 688 /* 689 * If we didn't ask for #UD to be trapped, bail. 690 */ 691 PVM pVM = pVCpu->CTX_SUFF(pVM); 692 if (!gimHvShouldTrapXcptUD(pVCpu)) 693 return VERR_GIM_OPERATION_FAILED; 694 695 int rc = VINF_SUCCESS; 696 if (!pDis) 697 { 698 /* 699 * Disassemble the instruction at RIP to figure out if it's the Intel VMCALL instruction 700 * or the AMD VMMCALL instruction and if so, handle it as a hypercall. 701 */ 702 DISCPUSTATE Dis; 703 rc = EMInterpretDisasCurrent(pVM, pVCpu, &Dis, NULL /* pcbInstr */); 704 pDis = &Dis; 705 } 706 707 if (RT_SUCCESS(rc)) 708 { 709 CPUMCPUVENDOR enmGuestCpuVendor = CPUMGetGuestCpuVendor(pVM); 710 if ( ( pDis->pCurInstr->uOpcode == OP_VMCALL 711 && ( enmGuestCpuVendor == CPUMCPUVENDOR_INTEL 712 || enmGuestCpuVendor == CPUMCPUVENDOR_VIA)) 713 || ( pDis->pCurInstr->uOpcode == OP_VMMCALL 714 && enmGuestCpuVendor == CPUMCPUVENDOR_AMD)) 715 { 716 /* 717 * Make sure guest ring-0 is the one making the hypercall. 718 */ 719 if (CPUMGetGuestCPL(pVCpu)) 720 return VERR_GIM_HYPERCALL_ACCESS_DENIED; 721 722 /* 723 * Perform the hypercall and update RIP. 724 */ 725 rc = gimHvHypercall(pVCpu, pCtx); 726 pCtx->rip += pDis->cbInstr; 727 return rc; 728 } 729 return VERR_GIM_OPERATION_FAILED; 730 } 731 return VERR_GIM_OPERATION_FAILED; 732 } 733 -
trunk/src/VBox/VMM/VMMAll/GIMAllKvm.cpp
r57851 r57989 45 45 * @param pVCpu Pointer to the VMCPU. 46 46 * @param pCtx Pointer to the guest-CPU context. 47 * 48 * @remarks Guest RIP may or may not have been incremented at this point. 47 49 */ 48 50 VMM_INT_DECL(int) gimKvmHypercall(PVMCPU pVCpu, PCPUMCTX pCtx) … … 353 355 * @param pDis Pointer to the disassembled instruction state at RIP. 354 356 * Optional, can be NULL. 357 * 358 * @thread EMT. 355 359 */ 356 360 VMM_INT_DECL(int) gimKvmXcptUD(PVMCPU pVCpu, PCPUMCTX pCtx, PDISCPUSTATE pDis) … … 364 368 return VERR_GIM_OPERATION_FAILED; 365 369 366 /*367 * Make sure guest ring-0 is the one making the hypercall.368 */369 if (CPUMGetGuestCPL(pVCpu))370 return VERR_GIM_HYPERCALL_ACCESS_DENIED;371 372 370 int rc = VINF_SUCCESS; 373 371 if (!pDis) … … 391 389 || pDis->pCurInstr->uOpcode == OP_VMMCALL) 392 390 { 391 /* 392 * Make sure guest ring-0 is the one making the hypercall. 393 */ 394 if (CPUMGetGuestCPL(pVCpu)) 395 return VERR_GIM_HYPERCALL_ACCESS_DENIED; 396 393 397 if ( pDis->pCurInstr->uOpcode != pKvm->uOpCodeNative 394 398 && HMIsEnabled(pVM)) -
trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
r57857 r57989 5156 5156 { 5157 5157 rc = GIMHypercall(pVCpu, pCtx); 5158 if (RT_SUCCESS(rc)) 5158 if ( rc == VINF_SUCCESS 5159 || rc == VINF_GIM_R3_HYPERCALL) 5159 5160 { 5160 5161 /* If the hypercall changes anything other than guest general-purpose registers, 5161 5162 we would need to reload the guest changed bits here before VM-reentry. */ 5162 5163 hmR0SvmUpdateRip(pVCpu, pCtx, 3); 5163 return VINF_SUCCESS;5164 return rc; 5164 5165 } 5165 5166 } -
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r57886 r57989 10153 10153 10154 10154 rc = GIMHypercall(pVCpu, pMixedCtx); 10155 if (RT_SUCCESS(rc)) 10155 if ( rc == VINF_SUCCESS 10156 || rc == VINF_GIM_R3_HYPERCALL) 10156 10157 { 10157 10158 /* If the hypercall changes anything other than guest general-purpose registers, 10158 10159 we would need to reload the guest changed bits here before VM-reentry. */ 10159 10160 hmR0VmxAdvanceGuestRip(pVCpu, pMixedCtx, pVmxTransient); 10160 return VINF_SUCCESS;10161 return rc; 10161 10162 } 10162 10163 } -
trunk/src/VBox/VMM/VMMR3/EMHM.cpp
r57358 r57989 42 42 #include "EMInternal.h" 43 43 #include <VBox/vmm/vm.h> 44 #include <VBox/vmm/gim.h> 44 45 #include <VBox/vmm/cpumdis.h> 45 46 #include <VBox/dis.h> -
trunk/src/VBox/VMM/VMMR3/EMRaw.cpp
r57358 r57989 43 43 #include "EMInternal.h" 44 44 #include <VBox/vmm/vm.h> 45 #include <VBox/vmm/gim.h> 45 46 #include <VBox/vmm/cpumdis.h> 46 47 #include <VBox/dis.h> -
trunk/src/VBox/VMM/VMMR3/GIM.cpp
r57358 r57989 72 72 static DECLCALLBACK(int) gimR3Save(PVM pVM, PSSMHANDLE pSSM); 73 73 static DECLCALLBACK(int) gimR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uSSMVersion, uint32_t uPass); 74 static FNPGMPHYSHANDLER gimR3Mmio2WriteHandler;74 static FNPGMPHYSHANDLER gimR3Mmio2WriteHandler; 75 75 76 76 … … 410 410 * Registers the GIM device with VMM. 411 411 * 412 * @param pVM Pointer to the VM. 413 * @param pDevIns Pointer to the GIM device instance. 414 */ 415 VMMR3DECL(void) GIMR3GimDeviceRegister(PVM pVM, PPDMDEVINS pDevIns) 416 { 417 pVM->gim.s.pDevInsR3 = pDevIns; 412 * @param pVM Pointer to the VM. 413 * @param pDevInsR3 Pointer to the GIM device instance. 414 * @param pDebugStream Pointer to the GIM device debug connection, can be 415 * NULL. 416 */ 417 VMMR3DECL(void) GIMR3GimDeviceRegister(PVM pVM, PPDMDEVINS pDevInsR3, PPDMISTREAM pDebugStreamR3) 418 { 419 pVM->gim.s.pDevInsR3 = pDevInsR3; 420 pVM->gim.s.pDebugStreamR3 = pDebugStreamR3; 421 } 422 423 424 /** 425 * Read data from a host debug session. 426 * 427 * @returns VBox status code. 428 * 429 * @param pVM Pointer to the VM. 430 * @param pvRead The read buffer. 431 * @param pcbRead The size of the read buffer as well as where to store 432 * the number of bytes read. 433 * @thread EMT. 434 */ 435 VMMR3_INT_DECL(int) GIMR3DebugRead(PVM pVM, void *pvRead, size_t *pcbRead) 436 { 437 PPDMISTREAM pDebugStream = pVM->gim.s.pDebugStreamR3; 438 if (pDebugStream) 439 return pDebugStream->pfnRead(pDebugStream, pvRead, pcbRead); 440 return VERR_GIM_NO_DEBUG_CONNECTION; 441 } 442 443 444 /** 445 * Write data to a host debug session. 446 * 447 * @returns VBox status code. 448 * 449 * @param pVM Pointer to the VM. 450 * @param pvWrite The write buffer. 451 * @param pcbWrite The size of the write buffer as well as where to store 452 * the number of bytes written. 453 * @thread EMT. 454 */ 455 VMMR3_INT_DECL(int) GIMR3DebugWrite(PVM pVM, void *pvWrite, size_t *pcbWrite) 456 { 457 PPDMISTREAM pDebugStream = pVM->gim.s.pDebugStreamR3; 458 if (pDebugStream) 459 return pDebugStream->pfnWrite(pDebugStream, pvWrite, pcbWrite); 460 return VERR_GIM_NO_DEBUG_CONNECTION; 418 461 } 419 462 -
trunk/src/VBox/VMM/VMMR3/GIMHv.cpp
r57506 r57989 27 27 #include <iprt/string.h> 28 28 #include <iprt/mem.h> 29 #include <iprt/semaphore.h> 29 30 #include <iprt/spinlock.h> 30 31 31 32 #include <VBox/vmm/cpum.h> 33 #include <VBox/vmm/mm.h> 32 34 #include <VBox/vmm/ssm.h> 33 35 #include <VBox/vmm/vm.h> … … 40 42 * Defined Constants And Macros * 41 43 *********************************************************************************************************************************/ 42 //#define GIMHV_HYPERCALL "GIMHvHypercall"43 44 44 /** 45 45 * GIM Hyper-V saved-state version. … … 47 47 #define GIM_HV_SAVED_STATE_VERSION UINT32_C(1) 48 48 49 50 /*********************************************************************************************************************************51 * Global Variables *52 *********************************************************************************************************************************/53 49 #ifdef VBOX_WITH_STATISTICS 54 50 # define GIMHV_MSRRANGE(a_uFirst, a_uLast, a_szName) \ … … 59 55 #endif 60 56 57 58 /********************************************************************************************************************************* 59 * Global Variables * 60 *********************************************************************************************************************************/ 61 61 /** 62 62 * Array of MSR ranges supported by Hyper-V. … … 75 75 GIMHV_MSRRANGE(MSR_GIM_HV_RANGE9_START, MSR_GIM_HV_RANGE9_END, "Hyper-V range 9"), 76 76 GIMHV_MSRRANGE(MSR_GIM_HV_RANGE10_START, MSR_GIM_HV_RANGE10_END, "Hyper-V range 10"), 77 GIMHV_MSRRANGE(MSR_GIM_HV_RANGE11_START, MSR_GIM_HV_RANGE11_END, "Hyper-V range 11") 77 GIMHV_MSRRANGE(MSR_GIM_HV_RANGE11_START, MSR_GIM_HV_RANGE11_END, "Hyper-V range 11"), 78 GIMHV_MSRRANGE(MSR_GIM_HV_RANGE12_START, MSR_GIM_HV_RANGE12_END, "Hyper-V range 12") 78 79 }; 79 80 #undef GIMHV_MSRRANGE 81 82 83 /********************************************************************************************************************************* 84 * Internal Functions * 85 *********************************************************************************************************************************/ 86 static int gimR3HvInitDebugSupport(PVM pVM); 87 static void gimR3HvTermDebugSupport(PVM pVM); 80 88 81 89 … … 105 113 rc = CFGMR3QueryStringDef(pCfgNode, "VendorID", szVendor, sizeof(szVendor), "VBoxVBoxVBox"); 106 114 AssertLogRelRCReturn(rc, rc); 115 116 if (!RTStrNCmp(szVendor, GIM_HV_VENDOR_MICROSOFT, sizeof(GIM_HV_VENDOR_MICROSOFT) - 1)) 117 pHv->fIsVendorMsHv = true; 107 118 108 119 /* … … 129 140 130 141 /* Miscellaneous features. */ 131 pHv->uMiscFeat = GIM_HV_MISC_FEAT_TIMER_FREQ 132 | GIM_HV_MISC_FEAT_GUEST_CRASH_MSRS; 142 pHv->uMiscFeat = 0 143 //| GIM_HV_MISC_FEAT_GUEST_DEBUGGING 144 //| GIM_HV_MISC_FEAT_XMM_HYPERCALL_INPUT 145 | GIM_HV_MISC_FEAT_TIMER_FREQ 146 | GIM_HV_MISC_FEAT_GUEST_CRASH_MSRS 147 //| GIM_HV_MISC_FEAT_DEBUG_MSRS 148 ; 133 149 134 150 /* Hypervisor recommendations to the guest. */ 135 151 pHv->uHyperHints = GIM_HV_HINT_MSR_FOR_SYS_RESET 136 152 | GIM_HV_HINT_RELAX_TIME_CHECKS; 153 154 /* Expose more if we're posing as Microsoft. */ 155 if (pHv->fIsVendorMsHv) 156 { 157 pHv->uMiscFeat |= GIM_HV_MISC_FEAT_GUEST_DEBUGGING 158 | GIM_HV_MISC_FEAT_DEBUG_MSRS; 159 160 pHv->uPartFlags |= GIM_HV_PART_FLAGS_DEBUGGING; 161 } 137 162 } 138 163 … … 190 215 HyperLeaf.uLeaf = UINT32_C(0x40000000); 191 216 HyperLeaf.uEax = UINT32_C(0x40000006); /* Minimum value for Hyper-V is 0x40000005. */ 192 /* Don't report vendor as 'Microsoft Hv' by default, see @bugref{7270#c152}. */ 217 /* 218 * Don't report vendor as 'Microsoft Hv'[1] by default, see @bugref{7270#c152}. 219 * [1]: ebx=0x7263694d ('rciM') ecx=0x666f736f ('foso') edx=0x76482074 ('vH t') 220 */ 193 221 { 194 222 uint32_t uVendorEbx; … … 258 286 pHv->uCrashCtl = MSR_GIM_HV_CRASH_CTL_NOTIFY_BIT; 259 287 288 /* 289 * Setup guest-host debugging connection. 290 */ 291 if (pHv->uMiscFeat & GIM_HV_MISC_FEAT_GUEST_DEBUGGING) 292 { 293 rc = gimR3HvInitDebugSupport(pVM); 294 AssertLogRelRCReturn(rc, rc); 295 296 /* 297 * Pretend that hypercalls are enabled unconditionally when posing as Microsoft, 298 * as Windows guests invoke debug hypercalls before enabling them via the hypercall MSR. 299 */ 300 if (pHv->fIsVendorMsHv) 301 { 302 pHv->u64HypercallMsr |= MSR_GIM_HV_HYPERCALL_ENABLE_BIT; 303 for (VMCPUID i = 0; i < pVM->cCpus; i++) 304 VMMHypercallsEnable(&pVM->aCpus[i]); 305 } 306 } 307 260 308 return VINF_SUCCESS; 261 309 } … … 323 371 { 324 372 gimR3HvReset(pVM); 373 374 PGIMHV pHv = &pVM->gim.s.u.Hv; 375 if (pHv->uMiscFeat & GIM_HV_MISC_FEAT_GUEST_DEBUGGING) 376 gimR3HvTermDebugSupport(pVM); 325 377 return VINF_SUCCESS; 326 378 } … … 352 404 * 353 405 * @param pVM Pointer to the VM. 354 * @thread EMT(0). 406 * 407 * @thread EMT(0). 355 408 */ 356 409 VMMR3_INT_DECL(void) gimR3HvReset(PVM pVM) … … 375 428 376 429 /* 377 * Reset MSRs .430 * Reset MSRs (Careful! Don't reset non-zero MSRs). 378 431 */ 379 432 pHv->u64GuestOsIdMsr = 0; … … 385 438 pHv->uCrashP3 = 0; 386 439 pHv->uCrashP4 = 0; 440 441 /* Extra faking required while posing as Microsoft, see gimR3HvInit(). */ 442 if ( (pHv->uMiscFeat & GIM_HV_MISC_FEAT_GUEST_DEBUGGING) 443 && pHv->fIsVendorMsHv) 444 { 445 pHv->u64HypercallMsr |= MSR_GIM_HV_HYPERCALL_ENABLE_BIT; 446 for (VMCPUID i = 0; i < pVM->cCpus; i++) 447 VMMHypercallsEnable(&pVM->aCpus[i]); 448 } 387 449 } 388 450 … … 870 932 } 871 933 934 935 /** 936 * Initializes Hyper-V guest debugging support. 937 * 938 * @returns VBox status code. 939 * @param pVM Pointer to the VM. 940 */ 941 static int gimR3HvInitDebugSupport(PVM pVM) 942 { 943 int rc = VINF_SUCCESS; 944 PGIMHV pHv = &pVM->gim.s.u.Hv; 945 pHv->pbHypercallIn = (uint8_t *)RTMemAllocZ(GIM_HV_PAGE_SIZE); 946 if (RT_LIKELY(pHv->pbHypercallIn)) 947 { 948 pHv->pbHypercallOut = (uint8_t *)RTMemAllocZ(GIM_HV_PAGE_SIZE); 949 if (RT_LIKELY(pHv->pbHypercallOut)) 950 return VINF_SUCCESS; 951 RTMemFree(pHv->pbHypercallIn); 952 } 953 return VERR_NO_MEMORY; 954 } 955 956 957 /** 958 * Terminates Hyper-V guest debugging support. 959 * 960 * @param pVM Pointer to the VM. 961 */ 962 static void gimR3HvTermDebugSupport(PVM pVM) 963 { 964 PGIMHV pHv = &pVM->gim.s.u.Hv; 965 RTMemFree(pHv->pbHypercallIn); 966 pHv->pbHypercallIn = NULL; 967 968 RTMemFree(pHv->pbHypercallOut); 969 pHv->pbHypercallOut = NULL; 970 } 971 972 973 /** 974 * Reads data from a debugger connection, asynchronous. 975 * 976 * @returns VBox status code. 977 * @param pVM Pointer to the VM. 978 * @param pvBuf Where to read the data. 979 * @param cbBuf Size of the read buffer @a pvBuf. 980 * @param pcbRead Where to store how many bytes were really read. 981 * @param cMsTimeout Timeout of the read operation in milliseconds. 982 * 983 * @thread EMT. 984 */ 985 static int gimR3HvDebugRead(PVM pVM, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead, uint32_t cMsTimeout) 986 { 987 NOREF(cMsTimeout); /** @todo implement */ 988 PGIMHV pHv = &pVM->gim.s.u.Hv; 989 AssertCompile(sizeof(size_t) >= sizeof(uint32_t)); 990 size_t cbRead = cbBuf; 991 int rc = GIMR3DebugRead(pVM, pvBuf, &cbRead); 992 *pcbRead = (uint32_t)cbRead; 993 return rc; 994 } 995 996 997 /** 998 * Writes data to the debugger connection, asynchronous. 999 * 1000 * @returns VBox status code. 1001 * @param pVM Pointer to the VM. 1002 * @param pvBuf Pointer to the data to be written. 1003 * @param cbBuf Size of the write buffer @a pvBuf. 1004 * @param pcbWritten Where to store how many bytes were really written. 1005 * 1006 * @thread EMT. 1007 */ 1008 static int gimR3HvDebugWrite(PVM pVM, void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten) 1009 { 1010 PGIMHV pHv = &pVM->gim.s.u.Hv; 1011 AssertCompile(sizeof(size_t) >= sizeof(uint32_t)); 1012 size_t cbWrite = cbBuf; 1013 int rc = GIMR3DebugWrite(pVM, pvBuf, &cbWrite); 1014 *pcbWritten = (uint32_t)cbWrite; 1015 return rc; 1016 } 1017 1018 1019 /** 1020 * Performs the HvPostDebugData hypercall. 1021 * 1022 * @returns VBox status code. 1023 * @param pVM Pointer to the VM. 1024 * @param GCPhysOut Where to write the hypercall output parameters after 1025 * performing the hypercall. 1026 * @param prcHv Where to store the result of the hypercall operation. 1027 * 1028 * @thread EMT. 1029 */ 1030 VMMR3_INT_DECL(int) gimR3HvHypercallPostDebugData(PVM pVM, RTGCPHYS GCPhysOut, int *prcHv) 1031 { 1032 AssertPtr(pVM); 1033 AssertPtr(prcHv); 1034 PGIMHV pHv = &pVM->gim.s.u.Hv; 1035 int rcHv = GIM_HV_STATUS_OPERATION_DENIED; 1036 1037 /* 1038 * Grab the parameters. 1039 */ 1040 PGIMHVDEBUGPOSTIN pIn = (PGIMHVDEBUGPOSTIN)pHv->pbHypercallIn; 1041 AssertPtrReturn(pIn, VERR_GIM_IPE_1); 1042 uint32_t cbWrite = pIn->cbWrite; 1043 uint32_t fFlags = pIn->fFlags; 1044 uint8_t *pbData = ((uint8_t *)pIn) + sizeof(PGIMHVDEBUGPOSTIN); 1045 1046 PGIMHVDEBUGPOSTOUT pOut = (PGIMHVDEBUGPOSTOUT)pHv->pbHypercallOut; 1047 AssertPtrReturn(pOut, VERR_GIM_IPE_2); 1048 uint32_t *pcbPendingWrite = &pOut->cbPending; 1049 1050 /* 1051 * Perform the hypercall. 1052 */ 1053 #if 0 1054 /* Currently disabled as Windows 10 guest passes us undocumented flags. */ 1055 if (fFlags & ~GIM_HV_DEBUG_POST_OPTIONS_MASK)) 1056 rcHv = GIM_HV_STATUS_INVALID_PARAMETER; 1057 #endif 1058 if (cbWrite > GIM_HV_DEBUG_MAX_DATA_SIZE) 1059 rcHv = GIM_HV_STATUS_INVALID_PARAMETER; 1060 else if (!cbWrite) 1061 rcHv = GIM_HV_STATUS_SUCCESS; 1062 else if (cbWrite > 0) 1063 { 1064 bool fIgnorePacket = false; 1065 if (pHv->fIsVendorMsHv) 1066 { 1067 /* 1068 * Windows guests sends us ethernet frames over the Hyper-V debug connection. 1069 * It sends DHCP/ARP queries with zero'd out MAC addresses and requires fudging up the 1070 * packets somewhere. 1071 * 1072 * The Microsoft WinDbg debugger talks UDP and thus only expects the actual debug 1073 * protocol payload. 1074 * 1075 * At present, we only handle guests configured with the "nodhcp" option. This makes 1076 * the guest send ARP queries with a self-chosen IP and after a couple of attempts of 1077 * receiving no replies, the guest picks its own IP address. After this, the guest 1078 * starts sending the UDP packets we require. We thus ignore the initial ARP packets 1079 * (and to be safe all non-UDP packets) until the guest eventually starts talking 1080 * UDP. Then we can finally feed the UDP payload over the debug connection. 1081 */ 1082 if (cbWrite > sizeof(RTNETETHERHDR)) 1083 { 1084 PRTNETETHERHDR pEtherHdr = (PRTNETETHERHDR)pbData; 1085 if (pEtherHdr->EtherType != RT_H2N_U16_C(RTNET_ETHERTYPE_IPV4)) 1086 fIgnorePacket = true; /* Supress passing ARP and other non IPv4 frames to debugger. */ 1087 else if (cbWrite > sizeof(RTNETETHERHDR) + RTNETIPV4_MIN_LEN + RTNETUDP_MIN_LEN) 1088 { 1089 /* Extract UDP payload, recording the guest IP address to pass to the debugger. */ 1090 PRTNETIPV4 pIp4Hdr = (PRTNETIPV4)(pbData + sizeof(RTNETETHERHDR)); 1091 if ( pIp4Hdr->ip_v == 4 1092 && pIp4Hdr->ip_p == RTNETIPV4_PROT_UDP) 1093 { 1094 pHv->DbgGuestAddr = pIp4Hdr->ip_src; 1095 pbData += sizeof(RTNETETHERHDR) + RTNETIPV4_MIN_LEN + RTNETUDP_MIN_LEN; 1096 cbWrite -= sizeof(RTNETETHERHDR) + RTNETIPV4_MIN_LEN + RTNETUDP_MIN_LEN; 1097 } 1098 else 1099 fIgnorePacket = true; /* Supress passing non-UDP packets to the debugger. */ 1100 } 1101 } 1102 } 1103 1104 if (!fIgnorePacket) 1105 { 1106 uint32_t cbReallyWritten = 0; 1107 int rc2 = gimR3HvDebugWrite(pVM, pbData, cbWrite, &cbReallyWritten); 1108 if ( RT_SUCCESS(rc2) 1109 && cbReallyWritten == cbWrite) 1110 { 1111 *pcbPendingWrite = 0; 1112 rcHv = GIM_HV_STATUS_SUCCESS; 1113 } 1114 else 1115 { 1116 /* 1117 * No need to update "*pcbPendingWrite" here as the guest isn't supposed to/doesn't 1118 * look at any of the output parameters when we fail the hypercall operation. 1119 */ 1120 rcHv = GIM_HV_STATUS_INSUFFICIENT_BUFFERS; 1121 } 1122 } 1123 else 1124 { 1125 /* Pretend success. */ 1126 *pcbPendingWrite = 0; 1127 rcHv = GIM_HV_STATUS_SUCCESS; 1128 } 1129 } 1130 1131 /* 1132 * Update the guest memory with result. 1133 */ 1134 int rc = PGMPhysSimpleWriteGCPhys(pVM, GCPhysOut, pHv->pbHypercallOut, sizeof(GIMHVDEBUGPOSTOUT)); 1135 if (RT_FAILURE(rc)) 1136 { 1137 LogRelMax(10, ("GIM: HyperV: HvPostDebugData failed to update guest memory. rc=%Rrc\n", rc)); 1138 rc = VERR_GIM_HYPERCALL_MEMORY_WRITE_FAILED; 1139 } 1140 1141 *prcHv = rcHv; 1142 return rc; 1143 } 1144 1145 1146 /** 1147 * Performs the HvRetrieveDebugData hypercall. 1148 * 1149 * @returns VBox status code. 1150 * @param pVM Pointer to the VM. 1151 * @param GCPhysOut Where to write the hypercall output parameters after 1152 * performing the hypercall. 1153 * @param prcHv Where to store the result of the hypercall operation. 1154 * 1155 * @thread EMT. 1156 */ 1157 VMMR3_INT_DECL(int) gimR3HvHypercallRetrieveDebugData(PVM pVM, RTGCPHYS GCPhysOut, int *prcHv) 1158 { 1159 AssertPtr(pVM); 1160 AssertPtr(prcHv); 1161 PGIMHV pHv = &pVM->gim.s.u.Hv; 1162 int rcHv = GIM_HV_STATUS_OPERATION_DENIED; 1163 1164 /* 1165 * Grab the parameters. 1166 */ 1167 PGIMHVDEBUGRETRIEVEIN pIn = (PGIMHVDEBUGRETRIEVEIN)pHv->pbHypercallIn; 1168 AssertPtrReturn(pIn, VERR_GIM_IPE_1); 1169 uint32_t cbRead = pIn->cbRead; 1170 uint32_t fFlags = pIn->fFlags; 1171 uint64_t uTimeout = pIn->u64Timeout; 1172 uint32_t cMsTimeout = (fFlags & GIM_HV_DEBUG_RETREIVE_LOOP) ? (uTimeout * 100) / RT_NS_1MS_64 : 0; 1173 1174 PGIMHVDEBUGRETRIEVEOUT pOut = (PGIMHVDEBUGRETRIEVEOUT)pHv->pbHypercallOut; 1175 AssertPtrReturn(pOut, VERR_GIM_IPE_2); 1176 uint32_t *pcbReallyRead = &pOut->cbRead; 1177 uint32_t *pcbRemainingRead = &pOut->cbRemaining; 1178 void *pvData = ((uint8_t *)pOut) + sizeof(GIMHVDEBUGRETRIEVEOUT); 1179 1180 /* 1181 * Perform the hypercall. 1182 */ 1183 *pcbReallyRead = 0; 1184 *pcbRemainingRead = cbRead; 1185 #if 0 1186 /* Currently disabled as Windows 10 guest passes us undocumented flags. */ 1187 if (fFlags & ~GIM_HV_DEBUG_RETREIVE_OPTIONS_MASK) 1188 rcHv = GIM_HV_STATUS_INVALID_PARAMETER; 1189 #endif 1190 if (cbRead > GIM_HV_DEBUG_MAX_DATA_SIZE) 1191 rcHv = GIM_HV_STATUS_INVALID_PARAMETER; 1192 else if (fFlags & GIM_HV_DEBUG_RETREIVE_TEST_ACTIVITY) 1193 rcHv = GIM_HV_STATUS_SUCCESS; /** @todo implement this. */ 1194 else if (!cbRead) 1195 rcHv = GIM_HV_STATUS_SUCCESS; 1196 else if (cbRead > 0) 1197 { 1198 int rc2 = gimR3HvDebugRead(pVM, pvData, cbRead, pcbReallyRead, cMsTimeout); 1199 Assert(*pcbReallyRead <= cbRead); 1200 if ( RT_SUCCESS(rc2) 1201 && *pcbReallyRead > 0) 1202 { 1203 uint8_t abFrame[sizeof(RTNETETHERHDR) + RTNETIPV4_MIN_LEN + sizeof(RTNETUDP)]; 1204 if ( pHv->fIsVendorMsHv 1205 && *pcbReallyRead + sizeof(abFrame) <= GIM_HV_PAGE_SIZE) 1206 { 1207 /* 1208 * Windows guests pumps ethernet frames over the Hyper-V debug connection as 1209 * explained in gimR3HvHypercallPostDebugData(). Here, we reconstruct the packet 1210 * with the guest's self-chosen IP ARP address we saved in pHv->DbgGuestAddr. 1211 * 1212 * Note! We really need to pass the minimum IPv4 header length. The Windows 10 guest 1213 * is -not- happy if we include the IPv4 options field, i.e. using sizeof(RTNETIPV4) 1214 * instead of RTNETIPV4_MIN_LEN. 1215 */ 1216 RT_ZERO(abFrame); 1217 PRTNETETHERHDR pEthHdr = (PRTNETETHERHDR)&abFrame[0]; 1218 PRTNETIPV4 pIpHdr = (PRTNETIPV4) (pEthHdr + 1); 1219 PRTNETUDP pUdpHdr = (PRTNETUDP) ((uint8_t *)pIpHdr + RTNETIPV4_MIN_LEN); 1220 1221 /* Ethernet */ 1222 pEthHdr->EtherType = RT_H2N_U16_C(RTNET_ETHERTYPE_IPV4); 1223 /* IPv4 */ 1224 pIpHdr->ip_v = 4; 1225 pIpHdr->ip_hl = RTNETIPV4_MIN_LEN / sizeof(uint32_t); 1226 pIpHdr->ip_tos = 0; 1227 pIpHdr->ip_len = RT_H2N_U16((uint16_t)*pcbReallyRead + sizeof(RTNETUDP) + RTNETIPV4_MIN_LEN); 1228 pIpHdr->ip_id = 0; 1229 pIpHdr->ip_off = 0; 1230 pIpHdr->ip_ttl = 255; 1231 pIpHdr->ip_p = RTNETIPV4_PROT_UDP; 1232 pIpHdr->ip_sum = 0; 1233 pIpHdr->ip_src.u = 0; 1234 pIpHdr->ip_dst.u = pHv->DbgGuestAddr.u; 1235 pIpHdr->ip_sum = RTNetIPv4HdrChecksum(pIpHdr); 1236 /* UDP */ 1237 pUdpHdr->uh_ulen = RT_H2N_U16_C((uint16_t)*pcbReallyRead + sizeof(*pUdpHdr)); 1238 1239 /* Make room by moving the payload and prepending the headers. */ 1240 uint8_t *pbData = (uint8_t *)pvData; 1241 memmove(pbData + sizeof(abFrame), pbData, *pcbReallyRead); 1242 memcpy(pbData, &abFrame[0], sizeof(abFrame)); 1243 1244 /* Update the adjusted sizes. */ 1245 *pcbReallyRead += sizeof(abFrame); 1246 *pcbRemainingRead = cbRead - *pcbReallyRead; 1247 } 1248 rcHv = GIM_HV_STATUS_SUCCESS; 1249 } 1250 else 1251 rcHv = GIM_HV_STATUS_NO_DATA; 1252 } 1253 1254 /* 1255 * Update the guest memory with result. 1256 */ 1257 int rc = PGMPhysSimpleWriteGCPhys(pVM, GCPhysOut, pHv->pbHypercallOut, sizeof(GIMHVDEBUGRETRIEVEOUT) + *pcbReallyRead); 1258 if (RT_FAILURE(rc)) 1259 { 1260 LogRelMax(10, ("GIM: HyperV: HvRetrieveDebugData failed to update guest memory. rc=%Rrc\n", rc)); 1261 rc = VERR_GIM_HYPERCALL_MEMORY_WRITE_FAILED; 1262 } 1263 1264 *prcHv = rcHv; 1265 return rc; 1266 } 1267 -
trunk/src/VBox/VMM/include/EMHandleRCTmpl.h
r56287 r57989 232 232 break; 233 233 234 /* 235 * GIM hypercall. 236 */ 237 case VINF_GIM_R3_HYPERCALL: 238 rc = GIMHypercall(pVCpu, pCtx); 239 break; 240 234 241 #ifdef EMHANDLERC_WITH_HM 235 242 /* -
trunk/src/VBox/VMM/include/GIMHvInternal.h
r57158 r57989 22 22 #include <VBox/vmm/cpum.h> 23 23 24 #include <iprt/net.h> 24 25 25 26 /** @name Hyper-V base feature identification. … … 32 33 #define GIM_HV_BASE_FEAT_PART_TIME_REF_COUNT_MSR RT_BIT(1) 33 34 /** Basic Synthetic Interrupt Controller MSRs available. */ 34 #define GIM_HV_BASE_FEAT_BASIC_SYN TH_ICRT_BIT(2)35 #define GIM_HV_BASE_FEAT_BASIC_SYNIC_MSRS RT_BIT(2) 35 36 /** Synthetic Timer MSRs available. */ 36 #define GIM_HV_BASE_FEAT_S YNTH_TIMER_MSRSRT_BIT(3)37 #define GIM_HV_BASE_FEAT_STIMER_MSRS RT_BIT(3) 37 38 /** APIC access MSRs (EOI, ICR, TPR) available. */ 38 39 #define GIM_HV_BASE_FEAT_APIC_ACCESS_MSRS RT_BIT(4) … … 125 126 #define GIM_HV_MISC_FEAT_TIMER_FREQ RT_BIT(8) 126 127 /** Support for injecting synthetic machine checks. */ 127 #define GIM_HV_MISC_FEAT_INJECT_SYN TH_MC_XCPTRT_BIT(9)128 #define GIM_HV_MISC_FEAT_INJECT_SYNMC_XCPT RT_BIT(9) 128 129 /** Support for guest crash MSRs. */ 129 130 #define GIM_HV_MISC_FEAT_GUEST_CRASH_MSRS RT_BIT(10) … … 360 361 361 362 /** Start of range 11. */ 362 #define MSR_GIM_HV_RANGE11_START UINT32_C(0x40000100) 363 #define MSR_GIM_HV_RANGE11_START UINT32_C(0x400000FF) 364 /** Undocumented debug options MSR. */ 365 #define MSR_GIM_HV_DEBUG_OPTIONS_MSR UINT32_C(0x400000FF) 366 /** End of range 11. */ 367 #define MSR_GIM_HV_RANGE11_END MSR_GIM_HV_DEBUG_OPTIONS_MSR 368 369 /** Start of range 12. */ 370 #define MSR_GIM_HV_RANGE12_START UINT32_C(0x40000100) 363 371 /** Guest crash MSR 0. */ 364 372 #define MSR_GIM_HV_CRASH_P0 UINT32_C(0x40000100) … … 373 381 /** Guest crash control. */ 374 382 #define MSR_GIM_HV_CRASH_CTL UINT32_C(0x40000105) 375 /** End of range 1 1. */376 #define MSR_GIM_HV_RANGE1 1_END MSR_GIM_HV_CRASH_CTL383 /** End of range 12. */ 384 #define MSR_GIM_HV_RANGE12_END MSR_GIM_HV_CRASH_CTL 377 385 /** @} */ 378 386 … … 447 455 /** @} */ 448 456 457 /** @name Hyper-V hypercall op codes. 458 * @{ 459 */ 460 /** Post debug data to hypervisor. */ 461 #define GIM_HV_HYPERCALL_OP_POST_DEBUG_DATA 0x69 462 /** Retreive debug data from hypervisor. */ 463 #define GIM_HV_HYPERCALL_OP_RETREIVE_DEBUG_DATA 0x6A 464 /** Reset debug session. */ 465 #define GIM_HV_HYPERCALL_OP_RESET_DEBUG_SESSION 0x6B 466 /** @} */ 467 468 /** @name Hyper-V hypercall inputs. 469 * @{ 470 */ 471 /** The hypercall call operation code. */ 472 #define GIM_HV_HYPERCALL_IN_CALL_CODE(a) ((a) & UINT64_C(0xffff)) 473 /** Whether it's a fast (register based) hypercall or not (memory-based). */ 474 #define GIM_HV_HYPERCALL_IN_IS_FAST(a) RT_BOOL((a) & RT_BIT_64(16)) 475 /** Total number of reps for a rep hypercall. */ 476 #define GIM_HV_HYPERCALL_IN_REP_COUNT(a) (((a) << 32) & UINT64_C(0xfff)) 477 /** Rep start index for a rep hypercall. */ 478 #define GIM_HV_HYPERCALL_IN_REP_START_IDX(a) (((a) << 48) & UINT64_C(0xfff)) 479 /** Reserved bits range 1. */ 480 #define GIM_HV_HYPERCALL_IN_RSVD_1(a) (((a) << 17) & UINT64_C(0x7fff)) 481 /** Reserved bits range 2. */ 482 #define GIM_HV_HYPERCALL_IN_RSVD_2(a) (((a) << 44) & UINT64_C(0xf)) 483 /** Reserved bits range 3. */ 484 #define GIM_HV_HYPERCALL_IN_RSVD_3(a) (((a) << 60) & UINT64_C(0x7)) 485 /** @} */ 486 487 488 /** @name Hyper-V hypercall status codes. 489 * @{ 490 */ 491 /** Success. */ 492 #define GIM_HV_STATUS_SUCCESS 0x00 493 /** Unrecognized hypercall. */ 494 #define GIM_HV_STATUS_INVALID_HYPERCALL_CODE 0x02 495 /** Invalid hypercall input (rep count, rsvd bits). */ 496 #define GIM_HV_STATUS_INVALID_HYPERCALL_INPUT 0x03 497 /** Hypercall guest-physical address not 8-byte aligned or crosses page boundary. */ 498 #define GIM_HV_STATUS_INVALID_ALIGNMENT 0x04 499 /** Invalid hypercall parameters. */ 500 #define GIM_HV_STATUS_INVALID_PARAMETER 0x05 501 /** Access denied. */ 502 #define GIM_HV_STATUS_ACCESS_DENIED 0x06 503 /** The partition state not valid for specified op. */ 504 #define GIM_HV_STATUS_INVALID_PARTITION_STATE 0x07 505 /** The hypercall operation could not be performed. */ 506 #define GIM_HV_STATUS_OPERATION_DENIED 0x08 507 /** Specified partition property ID not recognized. */ 508 #define GIM_HV_STATUS_UNKNOWN_PROPERTY 0x09 509 /** Specified partition property value not within range. */ 510 #define GIM_HV_STATUS_PROPERTY_VALUE_OUT_OF_RANGE 0x0a 511 /** Insufficient memory for performing the hypercall. */ 512 #define GIM_HV_STATUS_INSUFFICIENT_MEMORY 0x0b 513 /** Maximum partition depth has been exceeded for the partition hierarchy. */ 514 #define GIM_HV_STATUS_PARTITION_TOO_DEEP 0x0c 515 /** The specified partition ID is not valid. */ 516 #define GIM_HV_STATUS_INVALID_PARTITION_ID 0x0d 517 /** The specified virtual processor index in invalid. */ 518 #define GIM_HV_STATUS_INVALID_VP_INDEX 0x0e 519 /** The specified port ID is not unique or doesn't exist. */ 520 #define GIM_HV_STATUS_INVALID_PORT_ID 0x11 521 /** The specified connection ID is not unique or doesn't exist. */ 522 #define GIM_HV_STATUS_INVALID_CONNECTION_ID 0x12 523 /** The target port doesn't have sufficient buffers for the caller to post a message. */ 524 #define GIM_HV_STATUS_INSUFFICIENT_BUFFERS 0x13 525 /** External interrupt not acknowledged.*/ 526 #define GIM_HV_STATUS_NOT_ACKNOWLEDGED 0x14 527 /** External interrupt acknowledged. */ 528 #define GIM_HV_STATUS_ACKNOWLEDGED 0x16 529 /** Invalid state due to misordering Hv[Save|Restore]PartitionState. */ 530 #define GIM_HV_STATUS_INVALID_SAVE_RESTORE_STATE 0x17 531 /** Operation not perform due to a required feature of SynIc was disabled. */ 532 #define GIM_HV_STATUS_INVALID_SYNIC_STATE 0x18 533 /** Object or value already in use. */ 534 #define GIM_HV_STATUS_OBJECT_IN_USE 0x19 535 /** Invalid proximity domain information. */ 536 #define GIM_HV_STATUS_INVALID_PROXIMITY_DOMAIN_INFO 0x1A 537 /** Attempt to retrieve data failed. */ 538 #define GIM_HV_STATUS_NO_DATA 0x1B 539 /** Debug connection has not recieved any new data since the last time. */ 540 #define GIM_HV_STATUS_INACTIVE 0x1C 541 /** A resource is unavailable for allocation. */ 542 #define GIM_HV_STATUS_NO_RESOURCES 0x1D 543 /** A hypervisor feature is not available to the caller. */ 544 #define GIM_HV_STATUS_FEATURE_UNAVAILABLE 0x1E 545 /** The debug packet returned is partial due to an I/O error. */ 546 #define GIM_HV_STATUS_PARTIAL_PACKET 0x1F 547 /** Processor feature SSE3 unsupported. */ 548 #define GIM_HV_STATUS_PROC_FEAT_SSE3_NOT_SUPPORTED 0x20 549 /** Processor feature LAHSAHF unsupported. */ 550 #define GIM_HV_STATUS_PROC_FEAT_LAHSAHF_NOT_SUPPORTED 0x21 551 /** Processor feature SSSE3 unsupported. */ 552 #define GIM_HV_STATUS_PROC_FEAT_SSSE3_NOT_SUPPORTED 0x22 553 /** Processor feature SSE4.1 unsupported. */ 554 #define GIM_HV_STATUS_PROC_FEAT_SSE4_1_NOT_SUPPORTED 0x23 555 /** Processor feature SSE4.2 unsupported. */ 556 #define GIM_HV_STATUS_PROC_FEAT_SSE4_2_NOT_SUPPORTED 0x24 557 /** Processor feature SSE4A unsupported. */ 558 #define GIM_HV_STATUS_PROC_FEAT_SSE4A_NOT_SUPPORTED 0x25 559 /** Processor feature XOP unsupported. */ 560 #define GIM_HV_STATUS_PROC_FEAT_XOP_NOT_SUPPORTED 0x26 561 /** Processor feature POPCNT unsupported. */ 562 #define GIM_HV_STATUS_PROC_FEAT_POPCNT_NOT_SUPPORTED 0x27 563 /** Processor feature CMPXCHG16B unsupported. */ 564 #define GIM_HV_STATUS_PROC_FEAT_CMPXCHG16B_NOT_SUPPORTED 0x28 565 /** Processor feature ALTMOVCR8 unsupported. */ 566 #define GIM_HV_STATUS_PROC_FEAT_ALTMOVCR8_NOT_SUPPORTED 0x29 567 /** Processor feature LZCNT unsupported. */ 568 #define GIM_HV_STATUS_PROC_FEAT_LZCNT_NOT_SUPPORTED 0x2A 569 /** Processor feature misaligned SSE unsupported. */ 570 #define GIM_HV_STATUS_PROC_FEAT_MISALIGNED_SSE_NOT_SUPPORTED 0x2B 571 /** Processor feature MMX extensions unsupported. */ 572 #define GIM_HV_STATUS_PROC_FEAT_MMX_EXT_NOT_SUPPORTED 0x2C 573 /** Processor feature 3DNow! unsupported. */ 574 #define GIM_HV_STATUS_PROC_FEAT_3DNOW_NOT_SUPPORTED 0x2D 575 /** Processor feature Extended 3DNow! unsupported. */ 576 #define GIM_HV_STATUS_PROC_FEAT_EXTENDED_3DNOW_NOT_SUPPORTED 0x2E 577 /** Processor feature 1GB large page unsupported. */ 578 #define GIM_HV_STATUS_PROC_FEAT_PAGE_1GB_NOT_SUPPORTED 0x2F 579 /** Processor cache line flush size incompatible. */ 580 #define GIM_HV_STATUS_PROC_CACHE_LINE_FLUSH_SIZE_INCOMPATIBLE 0x30 581 /** Processor feature XSAVE unsupported. */ 582 #define GIM_HV_STATUS_PROC_FEAT_XSAVE_NOT_SUPPORTED 0x31 583 /** Processor feature XSAVEOPT unsupported. */ 584 #define GIM_HV_STATUS_PROC_FEAT_XSAVEOPT_NOT_SUPPORTED 0x32 585 /** The specified buffer was too small for all requested data. */ 586 #define GIM_HV_STATUS_INSUFFICIENT_BUFFER 0x33 587 /** Processor feature XSAVEOPT unsupported. */ 588 #define GIM_HV_STATUS_PROC_FEAT_XSAVE_AVX_NOT_SUPPORTED 0x34 589 /** Processor feature XSAVEOPT unsupported. */ 590 #define GIM_HV_STATUS_PROC_FEAT_XSAVE_FEAT_NOT_SUPPORTED 0x35 /** Huh, isn't this same as 0x31? */ 591 /** Processor feature XSAVEOPT unsupported. */ 592 #define GIM_HV_STATUS_PROC_FEAT_PAGE_XSAVE_SAVE_AREA_INCOMPATIBLE 0x36 593 /** Processor architecture unsupoorted. */ 594 #define GIM_HV_STATUS_INCOMPATIBLE_PROCESSOR 0x37 595 /** Max. domains for platform I/O remapping reached. */ 596 #define GIM_HV_STATUS_INSUFFICIENT_DEVICE_DOMAINS 0x38 597 /** Processor feature AES unsupported. */ 598 #define GIM_HV_STATUS_PROC_FEAT_AES_NOT_SUPPORTED 0x39 599 /** Processor feature PCMULQDQ unsupported. */ 600 #define GIM_HV_STATUS_PROC_FEAT_PCMULQDQ_NOT_SUPPORTED 0x3A 601 /** Processor feature XSAVE features unsupported. */ 602 #define GIM_HV_STATUS_PROC_FEAT_XSAVE_FEATURES_INCOMPATIBLE 0x3B 603 /** Generic CPUID validation error. */ 604 #define GIM_HV_STATUS_CPUID_FEAT_VALIDATION_ERROR 0x3C 605 /** XSAVE CPUID validation error. */ 606 #define GIM_HV_STATUS_CPUID_XSAVE_FEAT_VALIDATION_ERROR 0x3D 607 /** Processor startup timed out. */ 608 #define GIM_HV_STATUS_PROCESSOR_STARTUP_TIMEOUT 0x3E 609 /** SMX enabled by the BIOS. */ 610 #define GIM_HV_STATUS_SMX_ENABLED 0x3F 611 /** Processor feature PCID unsupported. */ 612 #define GIM_HV_STATUS_PROC_FEAT_PCID_NOT_SUPPORTED 0x40 613 /** Invalid LP index. */ 614 #define GIM_HV_STATUS_INVALID_LP_INDEX 0x41 615 /** Processor feature PCID unsupported. */ 616 #define GIM_HV_STATUS_FEAT_FMA4_NOT_SUPPORTED 0x42 617 /** Processor feature PCID unsupported. */ 618 #define GIM_HV_STATUS_FEAT_F16C_NOT_SUPPORTED 0x43 619 /** Processor feature PCID unsupported. */ 620 #define GIM_HV_STATUS_PROC_FEAT_RDRAND_NOT_SUPPORTED 0x44 621 /** Processor feature RDWRFSGS unsupported. */ 622 #define GIM_HV_STATUS_PROC_FEAT_RDWRFSGS_NOT_SUPPORTED 0x45 623 /** Processor feature SMEP unsupported. */ 624 #define GIM_HV_STATUS_PROC_FEAT_SMEP_NOT_SUPPORTED 0x46 625 /** Processor feature enhanced fast string unsupported. */ 626 #define GIM_HV_STATUS_PROC_FEAT_ENHANCED_FAST_STRING_NOT_SUPPORTED 0x47 627 /** Processor feature MOVBE unsupported. */ 628 #define GIM_HV_STATUS_PROC_FEAT_MOVBE_NOT_SUPPORTED 0x48 629 /** Processor feature BMI1 unsupported. */ 630 #define GIM_HV_STATUS_PROC_FEAT_BMI1_NOT_SUPPORTED 0x49 631 /** Processor feature BMI2 unsupported. */ 632 #define GIM_HV_STATUS_PROC_FEAT_BMI2_NOT_SUPPORTED 0x4A 633 /** Processor feature HLE unsupported. */ 634 #define GIM_HV_STATUS_PROC_FEAT_HLE_NOT_SUPPORTED 0x4B 635 /** Processor feature RTM unsupported. */ 636 #define GIM_HV_STATUS_PROC_FEAT_RTM_NOT_SUPPORTED 0x4C 637 /** Processor feature XSAVE FMA unsupported. */ 638 #define GIM_HV_STATUS_PROC_FEAT_XSAVE_FMA_NOT_SUPPORTED 0x4D 639 /** Processor feature XSAVE AVX2 unsupported. */ 640 #define GIM_HV_STATUS_PROC_FEAT_XSAVE_AVX2_NOT_SUPPORTED 0x4E 641 /** Processor feature NPIEP1 unsupported. */ 642 #define GIM_HV_STATUS_PROC_FEAT_NPIEP1_NOT_SUPPORTED 0x4F 643 /** @} */ 644 645 646 /** @name Hyper-V debug support. 647 * Options and constants for Hyper-V debug hypercalls. 648 * @{ 649 */ 650 /** Maximum debug data payload size in bytes. */ 651 #define GIM_HV_DEBUG_MAX_DATA_SIZE 4088 652 653 /** The undocumented bit for MSR_GIM_HV_DEBUG_OPTIONS_MSR that makes it all 654 * work. */ 655 #define GIM_HV_DEBUG_OPTIONS_MSR_ENABLE RT_BIT(2) 656 657 /** Guest will perform the HvPostDebugData hypercall until completion. */ 658 #define GIM_HV_DEBUG_POST_LOOP RT_BIT_32(0) 659 /** Mask of valid HvPostDebugData options. */ 660 #define GIM_HV_DEBUG_POST_OPTIONS_MASK RT_BIT_32(0) 661 662 /** Guest will perform the HvRetrieveDebugData hypercall until completion. */ 663 #define GIM_HV_DEBUG_RETREIVE_LOOP RT_BIT_32(0) 664 /** Guest checks if any global debug session is active. */ 665 #define GIM_HV_DEBUG_RETREIVE_TEST_ACTIVITY RT_BIT_32(1) 666 /** Mask of valid HvRetrieveDebugData options. */ 667 #define GIM_HV_DEBUG_RETREIVE_OPTIONS_MASK RT_BIT_32(0) | RT_BIT_32(1) 668 669 /** Guest requests purging of incoming debug data. */ 670 #define GIM_HV_DEBUG_PURGE_INCOMING_DATA RT_BIT_32(0) 671 /** Guest requests purging of outgoing debug data. */ 672 #define GIM_HV_DEBUG_PURGE_OUTGOING_DATA RT_BIT_32(1) 673 674 /** 675 * HvResetDebugData hypercall input. 676 */ 677 typedef struct GIMHVDEBUGRESETIN 678 { 679 uint32_t fFlags; 680 uint32_t uPadding; 681 } GIMHVDEBUGRESETIN; 682 /** Pointer to a HvResetDebugData input struct. */ 683 typedef GIMHVDEBUGRESETIN *PGIMHVDEBUGRESETIN; 684 AssertCompileSize(GIMHVDEBUGRESETIN, 8); 685 686 /** 687 * HvPostDebugData hypercall input. 688 */ 689 typedef struct GIMHVDEBUGPOSTIN 690 { 691 uint32_t cbWrite; 692 uint32_t fFlags; 693 } GIMHVDEBUGPOSTIN; 694 /** Pointer to a HvPostDebugData input struct. */ 695 typedef GIMHVDEBUGPOSTIN *PGIMHVDEBUGPOSTIN; 696 AssertCompileSize(GIMHVDEBUGPOSTIN, 8); 697 698 /** 699 * HvPostDebugData hypercall output. 700 */ 701 typedef struct GIMHVDEBUGPOSTOUT 702 { 703 uint32_t cbPending; 704 uint32_t uPadding; 705 } GIMHVDEBUGPOSTOUT; 706 /** Pointer to a HvPostDebugData output struct. */ 707 typedef GIMHVDEBUGPOSTOUT *PGIMHVDEBUGPOSTOUT; 708 AssertCompileSize(GIMHVDEBUGPOSTOUT, 8); 709 710 /** 711 * HvRetrieveDebugData hypercall input. 712 */ 713 typedef struct GIMHVDEBUGRETRIEVEIN 714 { 715 uint32_t cbRead; 716 uint32_t fFlags; 717 uint64_t u64Timeout; 718 } GIMHVDEBUGRETRIEVEIN; 719 /** Pointer to a HvRetrieveDebugData input struct. */ 720 typedef GIMHVDEBUGRETRIEVEIN *PGIMHVDEBUGRETRIEVEIN; 721 AssertCompileSize(GIMHVDEBUGRETRIEVEIN, 16); 722 723 /** 724 * HvRetriveDebugData hypercall output. 725 */ 726 typedef struct GIMHVDEBUGRETRIEVEOUT 727 { 728 uint32_t cbRead; 729 uint32_t cbRemaining; 730 } GIMHVDEBUGRETRIEVEOUT; 731 /** Pointer to a HvRetrieveDebugData output struct. */ 732 typedef GIMHVDEBUGRETRIEVEOUT *PGIMHVDEBUGRETRIEVEOUT; 733 AssertCompileSize(GIMHVDEBUGRETRIEVEOUT, 8); 734 /** @} */ 735 736 449 737 /** Hyper-V page size. */ 450 #define GIM_HV_PAGE_SIZE 0x1000 738 #define GIM_HV_PAGE_SIZE 4096 739 740 /** Microsoft Hyper-V vendor signature. */ 741 #define GIM_HV_VENDOR_MICROSOFT "Microsoft Hv" 451 742 452 743 /** … … 476 767 typedef GIMHVREFTSC const *PCGIMHVREFTSC; 477 768 478 479 769 /** 480 770 * GIM Hyper-V VM instance data. … … 483 773 typedef struct GIMHV 484 774 { 485 /** @name MSRs.486 * { */775 /** @name Primary MSRs. 776 * @{ */ 487 777 /** Guest OS identity MSR. */ 488 778 uint64_t u64GuestOsIdMsr; … … 494 784 495 785 /** @name CPUID features. 496 * { */786 * @{ */ 497 787 /** Basic features. */ 498 788 uint32_t uBaseFeat; … … 510 800 511 801 /** @name Guest Crash MSRs. 512 * @{802 * @{ 513 803 */ 514 804 /** Guest crash control MSR. */ … … 526 816 /** @} */ 527 817 818 /** @name Time management. 819 * @{ */ 528 820 /** Per-VM R0 Spinlock for protecting EMT writes to the TSC page. */ 529 821 RTSPINLOCK hSpinlockR0; … … 533 825 /** The TSC frequency (in HZ) reported to the guest. */ 534 826 uint64_t cTscTicksPerSecond; 827 /** @} */ 828 829 /** @name Hypercalls. */ 830 /* @{ */ 831 /** Pointer to the hypercall input parameter page - R3. */ 832 R3PTRTYPE(uint8_t *) pbHypercallIn; 833 /** Pointer to the hypercall output parameter page - R3. */ 834 R3PTRTYPE(uint8_t *) pbHypercallOut; 835 /** @} */ 836 837 /** @name Guest debugging. 838 * @{ */ 839 /** Whether we're posing as the official Microsoft vendor. */ 840 bool fIsVendorMsHv; 841 bool afAlignment0[7]; 842 /** The auto IP address last chosen by the guest after failed ARP queries. */ 843 RTNETADDRIPV4 DbgGuestAddr; 844 uint32_t uAlignment1; 845 /** @} */ 535 846 536 847 /** Array of MMIO2 regions. */ … … 566 877 VMMR3_INT_DECL(int) gimR3HvDisableHypercallPage(PVM pVM); 567 878 VMMR3_INT_DECL(int) gimR3HvEnableHypercallPage(PVM pVM, RTGCPHYS GCPhysHypercallPage); 879 880 VMMR3_INT_DECL(int) gimR3HvHypercallPostDebugData(PVM pVM, RTGCPHYS GCPhysOut, int *prcHv); 881 VMMR3_INT_DECL(int) gimR3HvHypercallRetrieveDebugData(PVM pVM, RTGCPHYS GCPhysOut, int *prcHv); 568 882 #endif /* IN_RING3 */ 569 883 570 884 VMM_INT_DECL(bool) gimHvIsParavirtTscEnabled(PVM pVM); 571 885 VMM_INT_DECL(bool) gimHvAreHypercallsEnabled(PVMCPU pVCpu); 886 VMM_INT_DECL(bool) gimHvShouldTrapXcptUD(PVMCPU pVCpu); 887 VMM_INT_DECL(int) gimHvXcptUD(PVMCPU pVCpu, PCPUMCTX pCtx, PDISCPUSTATE pDis); 572 888 VMM_INT_DECL(int) gimHvHypercall(PVMCPU pVCpu, PCPUMCTX pCtx); 573 889 VMM_INT_DECL(VBOXSTRICTRC) gimHvReadMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue); -
trunk/src/VBox/VMM/include/GIMInternal.h
r55493 r57989 52 52 uint32_t u32Padding; 53 53 54 /** Pointer to the GIM device - ring-3 context. */54 /** Pointer to the GIM device - R3 ptr. */ 55 55 R3PTRTYPE(PPDMDEVINS) pDevInsR3; 56 /** Pointer to the GIM device debug stream - R3 ptr. */ 57 R3PTRTYPE(PPDMISTREAM) pDebugStreamR3; 56 58 #if 0 57 59 /** Pointer to the provider's ring-3 hypercall handler. */ … … 105 107 VMMR3_INT_DECL(int) GIMR3Mmio2HandlerPhysicalRegister(PVM pVM, PGIMMMIO2REGION pRegion); 106 108 VMMR3_INT_DECL(int) GIMR3Mmio2HandlerPhysicalDeregister(PVM pVM, PGIMMMIO2REGION pRegion); 109 110 VMMR3_INT_DECL(int) GIMR3DebugRead(PVM pVM, void *pvRead, size_t *pcbRead); 111 VMMR3_INT_DECL(int) GIMR3DebugWrite(PVM pVM, void *pvWrite, size_t *pcbWrite); 107 112 #endif /* IN_RING3 */ 108 113
Note:
See TracChangeset
for help on using the changeset viewer.

