Changeset 71136 in vbox for trunk/src/VBox/VMM/VMMR0
- Timestamp:
- Feb 27, 2018 1:17:36 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 121023
- Location:
- trunk/src/VBox/VMM/VMMR0
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/NEMR0Native-win.cpp
r71130 r71136 21 21 *********************************************************************************************************************************/ 22 22 #define LOG_GROUP LOG_GROUP_NEM 23 #include <iprt/nt/nt.h> 23 24 #include <iprt/nt/hyperv.h> 25 #include <iprt/nt/vid.h> 24 26 25 27 #include <VBox/vmm/nem.h> … … 50 52 * Global Variables * 51 53 *********************************************************************************************************************************/ 52 static uint64_t (* 54 static uint64_t (*g_pfnHvlInvokeHypercall)(uint64_t uCallInfo, uint64_t HCPhysInput, uint64_t HCPhysOutput); 53 55 54 56 … … 64 66 VMMR0_INT_DECL(int) NEMR0InitVM(PGVM pGVM, PVM pVM) 65 67 { 68 AssertCompile(sizeof(pGVM->nem.s) <= sizeof(pGVM->nem.padding)); 69 AssertCompile(sizeof(pGVM->aCpus[0].nem.s) <= sizeof(pGVM->aCpus[0].nem.padding)); 70 66 71 int rc = GVMMR0ValidateGVMandVMandEMT(pGVM, pVM, 0); 67 72 AssertRCReturn(rc, rc); … … 112 117 * So far, so good. 113 118 */ 114 /** @todo would be good if we could establish the partition ID ourselves. */115 /** @todo this is too EARLY! */116 pGVM->nem.s.idHvPartition = pVM->nem.s.idHvPartition;117 119 return rc; 118 120 } … … 122 124 123 125 RT_NOREF(pGVM, pVM); 126 return rc; 127 } 128 129 130 /** 131 * Perform an I/O control operation on the partition handle (VID.SYS). 132 * 133 * @returns NT status code. 134 * @param pGVM The ring-0 VM structure. 135 * @param uFunction The function to perform. 136 * @param pvInput The input buffer. This must point within the VM 137 * structure so we can easily convert to a ring-3 138 * pointer if necessary. 139 * @param cbInput The size of the input. @a pvInput must be NULL when 140 * zero. 141 * @param pvOutput The output buffer. This must also point within the 142 * VM structure for ring-3 pointer magic. 143 * @param cbOutput The size of the output. @a pvOutput must be NULL 144 * when zero. 145 */ 146 DECLINLINE(NTSTATUS) nemR0NtPerformIoControl(PGVM pGVM, uint32_t uFunction, void *pvInput, uint32_t cbInput, 147 void *pvOutput, uint32_t cbOutput) 148 { 149 #ifdef RT_STRICT 150 /* 151 * Input and output parameters are part of the VM CPU structure. 152 */ 153 PVM pVM = pGVM->pVM; 154 size_t const cbVM = RT_UOFFSETOF(VM, aCpus[pGVM->cCpus]); 155 if (pvInput) 156 AssertReturn(((uintptr_t)pvInput + cbInput) - (uintptr_t)pVM <= cbVM, VERR_INVALID_PARAMETER); 157 if (pvOutput) 158 AssertReturn(((uintptr_t)pvOutput + cbOutput) - (uintptr_t)pVM <= cbVM, VERR_INVALID_PARAMETER); 159 #endif 160 161 int32_t rcNt = STATUS_UNSUCCESSFUL; 162 int rc = SUPR0IoCtlPerform(pGVM->nem.s.pIoCtlCtx, uFunction, 163 pvInput, 164 pvInput ? (uintptr_t)pvInput + pGVM->nem.s.offRing3ConversionDelta : NIL_RTR3PTR, 165 cbInput, 166 pvOutput, 167 pvOutput ? (uintptr_t)pvOutput + pGVM->nem.s.offRing3ConversionDelta : NIL_RTR3PTR, 168 cbOutput, 169 &rcNt); 170 if (RT_SUCCESS(rc) || !NT_SUCCESS((NTSTATUS)rcNt)) 171 return (NTSTATUS)rcNt; 172 return STATUS_UNSUCCESSFUL; 173 } 174 175 176 /** 177 * 2nd part of the initialization, after we've got a partition handle. 178 * 179 * @returns VBox status code. 180 * @param pGVM The ring-0 VM handle. 181 * @param pVM The cross context VM handle. 182 * @thread EMT(0) 183 */ 184 VMMR0_INT_DECL(int) NEMR0InitVMPart2(PGVM pGVM, PVM pVM) 185 { 186 int rc = GVMMR0ValidateGVMandVMandEMT(pGVM, pVM, 0); 187 AssertRCReturn(rc, rc); 188 SUPR0Printf("NEMR0InitVMPart2\n"); LogRel(("2: NEMR0InitVMPart2\n")); 189 190 /* 191 * Copy and validate the I/O control information from ring-3. 192 */ 193 NEMWINIOCTL Copy = pVM->nem.s.IoCtlGetHvPartitionId; 194 AssertLogRelReturn(Copy.uFunction != 0, VERR_NEM_INIT_FAILED); 195 AssertLogRelReturn(Copy.cbInput == 0, VERR_NEM_INIT_FAILED); 196 AssertLogRelReturn(Copy.cbOutput == sizeof(HV_PARTITION_ID), VERR_NEM_INIT_FAILED); 197 pGVM->nem.s.IoCtlGetHvPartitionId = Copy; 198 199 Copy = pVM->nem.s.IoCtlStartVirtualProcessor; 200 AssertLogRelReturn(Copy.uFunction != 0, VERR_NEM_INIT_FAILED); 201 AssertLogRelReturn(Copy.cbInput == sizeof(HV_VP_INDEX), VERR_NEM_INIT_FAILED); 202 AssertLogRelReturn(Copy.cbOutput == 0, VERR_NEM_INIT_FAILED); 203 AssertLogRelReturn(Copy.uFunction != pGVM->nem.s.IoCtlGetHvPartitionId.uFunction, VERR_NEM_INIT_FAILED); 204 pGVM->nem.s.IoCtlStartVirtualProcessor = Copy; 205 206 Copy = pVM->nem.s.IoCtlStopVirtualProcessor; 207 AssertLogRelReturn(Copy.uFunction != 0, VERR_NEM_INIT_FAILED); 208 AssertLogRelReturn(Copy.cbInput == sizeof(HV_VP_INDEX), VERR_NEM_INIT_FAILED); 209 AssertLogRelReturn(Copy.cbOutput == 0, VERR_NEM_INIT_FAILED); 210 AssertLogRelReturn(Copy.uFunction != pGVM->nem.s.IoCtlGetHvPartitionId.uFunction, VERR_NEM_INIT_FAILED); 211 AssertLogRelReturn(Copy.uFunction != pGVM->nem.s.IoCtlStartVirtualProcessor.uFunction, VERR_NEM_INIT_FAILED); 212 pGVM->nem.s.IoCtlStopVirtualProcessor = Copy; 213 214 Copy = pVM->nem.s.IoCtlMessageSlotHandleAndGetNext; 215 AssertLogRelReturn(Copy.uFunction != 0, VERR_NEM_INIT_FAILED); 216 AssertLogRelReturn(Copy.cbInput == sizeof(VID_IOCTL_INPUT_MESSAGE_SLOT_HANDLE_AND_GET_NEXT), VERR_NEM_INIT_FAILED); 217 AssertLogRelReturn(Copy.cbOutput == 0, VERR_NEM_INIT_FAILED); 218 AssertLogRelReturn(Copy.uFunction != pGVM->nem.s.IoCtlGetHvPartitionId.uFunction, VERR_NEM_INIT_FAILED); 219 AssertLogRelReturn(Copy.uFunction != pGVM->nem.s.IoCtlStartVirtualProcessor.uFunction, VERR_NEM_INIT_FAILED); 220 AssertLogRelReturn(Copy.uFunction != pGVM->nem.s.IoCtlStopVirtualProcessor.uFunction, VERR_NEM_INIT_FAILED); 221 pGVM->nem.s.IoCtlMessageSlotHandleAndGetNext = Copy; 222 223 /* 224 * Setup of an I/O control context for the partition handle for later use. 225 */ 226 rc = SUPR0IoCtlSetupForHandle(pGVM->pSession, pVM->nem.s.hPartitionDevice, 0, &pGVM->nem.s.pIoCtlCtx); 227 AssertLogRelRCReturn(rc, rc); 228 pGVM->nem.s.offRing3ConversionDelta = (uintptr_t)pVM->pVMR3 - (uintptr_t)pGVM->pVM; 229 230 /* 231 * Get the partition ID. 232 */ 233 PVMCPU pVCpu = &pGVM->pVM->aCpus[0]; 234 NTSTATUS rcNt = nemR0NtPerformIoControl(pGVM, pGVM->nem.s.IoCtlGetHvPartitionId.uFunction, NULL, 0, 235 &pVCpu->nem.s.uIoCtlBuf.idPartition, sizeof(pVCpu->nem.s.uIoCtlBuf.idPartition)); 236 AssertLogRelMsgReturn(NT_SUCCESS(rcNt), ("IoCtlGetHvPartitionId failed: %#x\n", rcNt), VERR_NEM_INIT_FAILED); 237 pGVM->nem.s.idHvPartition = pVCpu->nem.s.uIoCtlBuf.idPartition; 238 AssertLogRelMsgReturn(pGVM->nem.s.idHvPartition == pVM->nem.s.idHvPartition, 239 ("idHvPartition mismatch: r0=%#RX64, r3=%#RX64\n", pGVM->nem.s.idHvPartition, pVM->nem.s.idHvPartition), 240 VERR_NEM_INIT_FAILED); 241 242 124 243 return rc; 125 244 } … … 137 256 { 138 257 pGVM->nem.s.idHvPartition = HV_PARTITION_ID_INVALID; 258 259 /* Clean up I/O control context. */ 260 if (pGVM->nem.s.pIoCtlCtx) 261 { 262 int rc = SUPR0IoCtlCleanup(pGVM->nem.s.pIoCtlCtx); 263 AssertRC(rc); 264 pGVM->nem.s.pIoCtlCtx = NULL; 265 } 139 266 140 267 /* Free the hypercall pages. */ … … 195 322 AssertReturn(GCPhysSrc < _1E, VERR_OUT_OF_RANGE); 196 323 } 197 198 /** @todo fix pGVM->nem.s.idHvPartition init. */199 if (pGVM->nem.s.idHvPartition == 0)200 pGVM->nem.s.idHvPartition = pVM->nem.s.idHvPartition;201 324 202 325 /* … … 291 414 AssertMsgReturn(!(GCPhys & X86_PAGE_OFFSET_MASK), ("%RGp\n", GCPhys), VERR_OUT_OF_RANGE); 292 415 AssertReturn(GCPhys < _1E, VERR_OUT_OF_RANGE); 293 294 /** @todo fix pGVM->nem.s.idHvPartition init. */295 if (pGVM->nem.s.idHvPartition == 0)296 pGVM->nem.s.idHvPartition = pVM->nem.s.idHvPartition;297 416 298 417 /* … … 732 851 AssertReturn(g_pfnHvlInvokeHypercall, VERR_NEM_MISSING_KERNEL_API); 733 852 734 /** @todo fix pGVM->nem.s.idHvPartition init. */735 if (pGVM->nem.s.idHvPartition == 0)736 pGVM->nem.s.idHvPartition = pVM->nem.s.idHvPartition;737 738 853 /* 739 854 * Call worker. … … 1146 1261 AssertReturn(g_pfnHvlInvokeHypercall, VERR_NEM_MISSING_KERNEL_API); 1147 1262 1148 /** @todo fix pGVM->nem.s.idHvPartition init. */1149 if (pGVM->nem.s.idHvPartition == 0)1150 pGVM->nem.s.idHvPartition = pVM->nem.s.idHvPartition;1151 1152 1263 /* 1153 1264 * Call worker. -
trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
r71087 r71136 1975 1975 break; 1976 1976 1977 case VMMR0_DO_NEM_INIT_VM_PART_2: 1978 if (u64Arg || pReqHdr || idCpu != 0) 1979 return VERR_INVALID_PARAMETER; 1980 rc = NEMR0InitVMPart2(pGVM, pVM); 1981 VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING); 1982 break; 1983 1977 1984 case VMMR0_DO_NEM_MAP_PAGES: 1978 1985 if (u64Arg || pReqHdr || idCpu == NIL_VMCPUID)
Note:
See TracChangeset
for help on using the changeset viewer.