Changeset 104911 in vbox for trunk/src/VBox/VMM/VMMR3/GIMHv.cpp
- Timestamp:
- Jun 13, 2024 10:33:27 AM (7 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/GIMHv.cpp
r104796 r104911 2233 2233 * Perform the hypercall. 2234 2234 */ 2235 /** @todo r=bird: This is *nothing* like the microsoft description (2024-05-28). 2236 * https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/hypercalls/hvextcallgetbootzeroedmemory 2237 * 2238 * It describes this as returning pages known to be all zeros at the time this 2239 * hypercall is made. What we return instead is a is a single entry: 2240 * GIMHVEXTGETBOOTZEROMEM::GCPhysStart = 0; 2241 * GIMHVEXTGETBOOTZEROMEM::cPages = SUM(PGMRAMRANGE.cb) >> GIM_HV_PAGE_SHIFT; 2242 * 2243 * This isn't right for any VM configuration, given that VGA & MMIO & ROM memory 2244 * starts at 0xa0000 and contains pages that aren't zero. For VM configurations 2245 * with more than 3GB (or 2) of memory, it doesn't take into account the RAM hole 2246 * below 4G. 2247 * 2248 * A much better approach for VMs with large configs, but still not really correct, 2249 * would be to find the highest RAM address (non-MMIO, non-MMIO2, non-ROM) and 2250 * convert it to a page count and assign that to cPages. 2251 * 2252 * A slight improvement would be to report two or three ranges: 2253 * [0] = 0x00000-0xa0000, 2254 * [1] = 1MB - RamHole, 2255 * [2] = 4GB - EndOfRam; 2256 * 2257 * The best would be to implement this directly PGM, as the number of mapped RAM 2258 * ranges doesn't need to be constant during the call if other VCPUs are 2259 * enabling/disabling devices and such. 2260 */ 2261 uint32_t const cRanges = PGMR3PhysGetRamRangeCount(pVM); 2262 pOut->cPages = 0; 2263 for (uint32_t iRange = 0; iRange < cRanges; iRange++) 2264 { 2265 RTGCPHYS GCPhysStart; 2266 RTGCPHYS GCPhysEnd; 2267 int rc = PGMR3PhysGetRange(pVM, iRange, &GCPhysStart, &GCPhysEnd, NULL /* pszDesc */, NULL /* fIsMmio */); 2268 if (RT_FAILURE(rc)) 2235 AssertCompileMembersSameSizeAndOffset(PGMPHYSRANGES, cRanges, GIMHVEXTGETBOOTZEROMEM, cRanges); 2236 AssertCompileMembersAtSameOffset(PGMPHYSRANGES, aRanges, GIMHVEXTGETBOOTZEROMEM, aRanges); 2237 AssertCompileMembersSameSizeAndOffset(PGMPHYSRANGE, GCPhysStart, GIMHVEXTMEMRANGE, GCPhysStart); 2238 AssertCompileMembersSameSizeAndOffset(PGMPHYSRANGE, cPages, GIMHVEXTMEMRANGE, cPages); 2239 AssertCompile(RT_ELEMENTS(pOut->aRanges) == GIM_HV_MAX_BOOT_ZEROED_MEM_RANGES); 2240 2241 int rcHv; 2242 int rc = PGMR3PhysGetRamBootZeroedRanges(pVM, (PPGMPHYSRANGES)pOut, RT_ELEMENTS(pOut->aRanges)); 2243 if ( RT_SUCCESS(rc) 2244 || rc == VERR_BUFFER_OVERFLOW) 2245 { 2246 /* 2247 * Update the guest memory with result. 2248 */ 2249 rc = PGMPhysSimpleWriteGCPhys(pVM, pHv->GCPhysHypercallOut, pHv->pbHypercallOut, sizeof(GIMHVEXTGETBOOTZEROMEM)); 2250 if (RT_SUCCESS(rc)) 2269 2251 { 2270 LogRelMax(10, ("GIM: HyperV: HvHypercallExtGetBootZeroedMem: PGMR3PhysGetRange failed for iRange(%u) rc=%Rrc\n", 2271 iRange, rc)); 2272 *prcHv = GIM_HV_STATUS_OPERATION_DENIED; 2273 return rc; 2252 LogRel(("GIM: HyperV: Queried boot zeroed guest memory as %u ranges\n", pOut->cRanges)); 2253 for (uint32_t i = 0; i < pOut->cRanges; i++) 2254 LogRel(("GIM: HyperV: RAM range [%u] from %#RGp to %#RGp (%u pages, %' Rhcb)\n", i, pOut->aRanges[i].GCPhysStart, 2255 pOut->aRanges[i].GCPhysStart + pOut->aRanges[i].cPages * GUEST_PAGE_SIZE - 1, pOut->aRanges[i].cPages, 2256 pOut->aRanges[i].cPages * GUEST_PAGE_SIZE)); 2257 rcHv = GIM_HV_STATUS_SUCCESS; 2274 2258 } 2275 2276 RTGCPHYS const cbRange = RT_ALIGN(GCPhysEnd - GCPhysStart + 1, GUEST_PAGE_SIZE); 2277 pOut->cPages += cbRange >> GIM_HV_PAGE_SHIFT; 2278 if (iRange == 0) 2279 pOut->GCPhysStart = GCPhysStart; 2280 } 2281 2282 /* 2283 * Update the guest memory with result. 2284 */ 2285 int rcHv; 2286 int rc = PGMPhysSimpleWriteGCPhys(pVM, pHv->GCPhysHypercallOut, pHv->pbHypercallOut, sizeof(GIMHVEXTGETBOOTZEROMEM)); 2287 if (RT_SUCCESS(rc)) 2288 { 2289 LogRel(("GIM: HyperV: Queried boot zeroed guest memory range (starting at %#RGp spanning %u pages) at %#RGp\n", 2290 pOut->GCPhysStart, pOut->cPages, pHv->GCPhysHypercallOut)); 2291 rcHv = GIM_HV_STATUS_SUCCESS; 2259 else 2260 { 2261 LogRelMax(10, ("GIM: HyperV: HvHypercallExtGetBootZeroedMem hypercall failed to update guest memory. rc=%Rrc\n", rc)); 2262 rcHv = GIM_HV_STATUS_OPERATION_DENIED; 2263 rc = VERR_GIM_HYPERCALL_MEMORY_WRITE_FAILED; 2264 } 2292 2265 } 2293 2266 else 2294 2267 { 2268 LogRelMax(10, ("GIM: HyperV: HvHypercallExtGetBootZeroedMem failed. rc=%Rrc\n", rc)); 2295 2269 rcHv = GIM_HV_STATUS_OPERATION_DENIED; 2296 LogRelMax(10, ("GIM: HyperV: HvHypercallExtGetBootZeroedMem failed to update guest memory. rc=%Rrc\n", rc)); 2297 rc = VERR_GIM_HYPERCALL_MEMORY_WRITE_FAILED; 2270 rc = VERR_GIM_HYPERCALL_FAILED; 2298 2271 } 2299 2272
Note:
See TracChangeset
for help on using the changeset viewer.