VirtualBox

Changeset 72190 in vbox for trunk/src/VBox


Ignore:
Timestamp:
May 10, 2018 3:19:33 PM (7 years ago)
Author:
vboxsync
Message:

VMM/GIM/HyperV: Implement extended hypercalls HvExtCallQueryCapabilities and HvExtCallGetBootZeroedMemory.

Location:
trunk/src/VBox/VMM
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp

    r70952 r72190  
    176176    /*
    177177     * Get the hypercall operation code and modes.
     178     * Fast hypercalls have only two or fewer inputs but no output parameters.
    178179     */
    179180    const bool       fIs64BitMode     = CPUMIsGuestIn64BitCodeEx(pCtx);
     
    181182    const uint16_t   uHyperOp         = GIM_HV_HYPERCALL_IN_CALL_CODE(uHyperIn);
    182183    const bool       fHyperFast       = GIM_HV_HYPERCALL_IN_IS_FAST(uHyperIn);
    183     /*const uint16_t   cHyperReps       = GIM_HV_HYPERCALL_IN_REP_COUNT(uHyperIn); - unused */
    184     /*const uint16_t   idxHyperRepStart = GIM_HV_HYPERCALL_IN_REP_START_IDX(uHyperIn); - unused */
     184    const uint16_t   cHyperReps       = GIM_HV_HYPERCALL_IN_REP_COUNT(uHyperIn);
     185    const uint16_t   idxHyperRepStart = GIM_HV_HYPERCALL_IN_REP_START_IDX(uHyperIn);
    185186    uint64_t         cHyperRepsDone   = 0;
     187
     188    /* Currently no repeating hypercalls are supported. */
     189    RT_NOREF2(cHyperReps, idxHyperRepStart);
    186190
    187191    int rc     = VINF_SUCCESS;
     
    332336            }
    333337
     338            case GIM_HV_EXT_HYPERCALL_OP_QUERY_CAP:              /* Non-rep, extended hypercall. */
     339            {
     340                if (pHv->uPartFlags & GIM_HV_PART_FLAGS_EXTENDED_HYPERCALLS)
     341                {
     342                    rc = gimHvReadSlowHypercallParam(pVM, pCtx, fIs64BitMode, GIMHVHYPERCALLPARAM_OUT, &rcHv);
     343                    if (   RT_SUCCESS(rc)
     344                        && rcHv == GIM_HV_STATUS_SUCCESS)
     345                    {
     346                        rc = gimR3HvHypercallExtQueryCap(pVM, &rcHv);
     347                    }
     348                }
     349                else
     350                {
     351                    LogRel(("GIM: HyperV: Denied HvExtCallQueryCapabilities when the feature is not exposed\n"));
     352                    rcHv = GIM_HV_STATUS_ACCESS_DENIED;
     353                }
     354                break;
     355            }
     356
     357            case GIM_HV_EXT_HYPERCALL_OP_GET_BOOT_ZEROED_MEM:    /* Non-rep, extended hypercall. */
     358            {
     359                if (pHv->uPartFlags & GIM_HV_PART_FLAGS_EXTENDED_HYPERCALLS)
     360                {
     361                    rc = gimHvReadSlowHypercallParam(pVM, pCtx, fIs64BitMode, GIMHVHYPERCALLPARAM_OUT, &rcHv);
     362                    if (   RT_SUCCESS(rc)
     363                        && rcHv == GIM_HV_STATUS_SUCCESS)
     364                    {
     365                        rc = gimR3HvHypercallExtGetBootZeroedMem(pVM, &rcHv);
     366                    }
     367                }
     368                else
     369                {
     370                    LogRel(("GIM: HyperV: Denied HvExtCallGetBootZeroedMemory when the feature is not exposed\n"));
     371                    rcHv = GIM_HV_STATUS_ACCESS_DENIED;
     372                }
     373                break;
     374            }
     375
    334376            default:
    335377            {
  • trunk/src/VBox/VMM/VMMR3/GIMHv.cpp

    r69111 r72190  
    283283                         ;
    284284
     285        /* Partition features. */
     286        pHv->uPartFlags |= GIM_HV_PART_FLAGS_EXTENDED_HYPERCALLS;
     287
    285288        /* Expose more if we're posing as Microsoft. We can, if needed, force MSR-based Hv
    286289           debugging by not exposing these bits while exposing the VS interface. The better
     
    289292        {
    290293            pHv->uMiscFeat  |= GIM_HV_MISC_FEAT_GUEST_DEBUGGING
    291                              | GIM_HV_MISC_FEAT_DEBUG_MSRS;
     294                            | GIM_HV_MISC_FEAT_DEBUG_MSRS;
    292295
    293296            pHv->uPartFlags |= GIM_HV_PART_FLAGS_DEBUGGING;
     
    21632166}
    21642167
     2168
     2169/**
     2170 * Performs the HvExtCallQueryCapabilities extended hypercall.
     2171 *
     2172 * @returns VBox status code.
     2173 * @param   pVM         The cross context VM structure.
     2174 * @param   prcHv       Where to store the result of the hypercall operation.
     2175 *
     2176 * @thread  EMT.
     2177 */
     2178VMMR3_INT_DECL(int) gimR3HvHypercallExtQueryCap(PVM pVM, int *prcHv)
     2179{
     2180    AssertPtr(pVM);
     2181    AssertPtr(prcHv);
     2182    PGIMHV pHv  = &pVM->gim.s.u.Hv;
     2183
     2184    /*
     2185     * Grab the parameters.
     2186     */
     2187   PGIMHVEXTQUERYCAP pOut = (PGIMHVEXTQUERYCAP)pHv->pbHypercallOut;
     2188
     2189    /*
     2190     * Perform the hypercall.
     2191     */
     2192    pOut->fCapabilities = GIM_HV_EXT_HYPERCALL_CAP_ZERO_MEM;
     2193
     2194    /*
     2195     * Update the guest memory with result.
     2196     */
     2197    int rcHv;
     2198    int rc = PGMPhysSimpleWriteGCPhys(pVM, pHv->GCPhysHypercallOut, pHv->pbHypercallOut, sizeof(GIMHVEXTQUERYCAP));
     2199    if (RT_SUCCESS(rc))
     2200    {
     2201        rcHv = GIM_HV_STATUS_SUCCESS;
     2202        LogRel(("GIM: HyperV: Queried extended hypercall capabilities %#RX64 at %#RGp\n", pOut->fCapabilities,
     2203                pHv->GCPhysHypercallOut));
     2204    }
     2205    else
     2206    {
     2207        rcHv = GIM_HV_STATUS_OPERATION_DENIED;
     2208        LogRelMax(10, ("GIM: HyperV: HvHypercallExtQueryCap failed to update guest memory. rc=%Rrc\n", rc));
     2209        rc = VERR_GIM_HYPERCALL_MEMORY_WRITE_FAILED;
     2210    }
     2211
     2212    *prcHv = rcHv;
     2213    return rc;
     2214}
     2215
     2216
     2217/**
     2218 * Performs the HvExtCallGetBootZeroedMemory extended hypercall.
     2219 *
     2220 * @returns VBox status code.
     2221 * @param   pVM         The cross context VM structure.
     2222 * @param   prcHv       Where to store the result of the hypercall operation.
     2223 *
     2224 * @thread  EMT.
     2225 */
     2226VMMR3_INT_DECL(int) gimR3HvHypercallExtGetBootZeroedMem(PVM pVM, int *prcHv)
     2227{
     2228    AssertPtr(pVM);
     2229    AssertPtr(prcHv);
     2230    PGIMHV pHv  = &pVM->gim.s.u.Hv;
     2231
     2232    /*
     2233     * Grab the parameters.
     2234     */
     2235    PGIMHVEXTGETBOOTZEROMEM pOut = (PGIMHVEXTGETBOOTZEROMEM)pHv->pbHypercallOut;
     2236
     2237    /*
     2238     * Perform the hypercall.
     2239     */
     2240    uint32_t const cRanges = PGMR3PhysGetRamRangeCount(pVM);
     2241    pOut->cPages = 0;
     2242    for (uint32_t iRange = 0; iRange < cRanges; iRange++)
     2243    {
     2244        RTGCPHYS GCPhysStart;
     2245        RTGCPHYS GCPhysEnd;
     2246        int rc = PGMR3PhysGetRange(pVM, iRange, &GCPhysStart, &GCPhysEnd, NULL /* pszDesc */, NULL /* fIsMmio */);
     2247        if (RT_FAILURE(rc))
     2248        {
     2249            LogRelMax(10, ("GIM: HyperV: HvHypercallExtGetBootZeroedMem: PGMR3PhysGetRange failed for iRange(%u) rc=%Rrc\n",
     2250                           iRange, rc));
     2251            *prcHv = GIM_HV_STATUS_OPERATION_DENIED;
     2252            return rc;
     2253        }
     2254
     2255        RTGCPHYS const cbRange = RT_ALIGN(GCPhysEnd - GCPhysStart + 1, PAGE_SIZE);
     2256        pOut->cPages += cbRange >> GIM_HV_PAGE_SHIFT;
     2257        if (iRange == 0)
     2258            pOut->GCPhysStart = GCPhysStart;
     2259    }
     2260
     2261    /*
     2262     * Update the guest memory with result.
     2263     */
     2264    int rcHv;
     2265    int rc = PGMPhysSimpleWriteGCPhys(pVM, pHv->GCPhysHypercallOut, pHv->pbHypercallOut, sizeof(GIMHVEXTGETBOOTZEROMEM));
     2266    if (RT_SUCCESS(rc))
     2267    {
     2268        LogRel(("GIM: HyperV: Queried boot zeroed guest memory range (starting at %#RGp spanning %u pages) at %#RGp\n",
     2269                pOut->GCPhysStart, pOut->cPages, pHv->GCPhysHypercallOut));
     2270        rcHv = GIM_HV_STATUS_SUCCESS;
     2271    }
     2272    else
     2273    {
     2274        rcHv = GIM_HV_STATUS_OPERATION_DENIED;
     2275        LogRelMax(10, ("GIM: HyperV: HvHypercallExtGetBootZeroedMem failed to update guest memory. rc=%Rrc\n", rc));
     2276        rc = VERR_GIM_HYPERCALL_MEMORY_WRITE_FAILED;
     2277    }
     2278
     2279    *prcHv = rcHv;
     2280    return rc;
     2281}
     2282
  • trunk/src/VBox/VMM/include/GIMHvInternal.h

    r71265 r72190  
    586586/** Reset debug session. */
    587587#define GIM_HV_HYPERCALL_OP_RESET_DEBUG_SESSION   0x6B
     588/** @} */
     589
     590/** @name Hyper-V extended hypercall op codes.
     591 * @{
     592 */
     593/** Query extended hypercall capabilities. */
     594#define GIM_HV_EXT_HYPERCALL_OP_QUERY_CAP                0x8001
     595/** Query guest physical address range that has zero'd filled memory. */
     596#define GIM_HV_EXT_HYPERCALL_OP_GET_BOOT_ZEROED_MEM      0x8002
     597/** @} */
     598
     599
     600/** @name Hyper-V Extended hypercall - HvExtCallQueryCapabilities.
     601 * @{
     602 */
     603/** Boot time zeroed pages. */
     604#define GIM_HV_EXT_HYPERCALL_CAP_ZERO_MEM                       RT_BIT_64(0)
     605/** Whether boot time zeroed pages capability is enabled. */
     606#define GIM_HV_EXT_HYPERCALL_CAP_IS_ZERO_MEM_ENABLED(a)         RT_BOOL((a) & GIM_HV_EXT_HYPERCALL_CAP_ZERO_MEM)
    588607/** @} */
    589608
     
    10361055typedef GIMHVDEBUGRETRIEVEOUT *PGIMHVDEBUGRETRIEVEOUT;
    10371056AssertCompileSize(GIMHVDEBUGRETRIEVEOUT, 8);
     1057
     1058/**
     1059 * HvExtCallQueryCapabilities hypercall output.
     1060 */
     1061typedef struct GIMHVEXTQUERYCAP
     1062{
     1063    uint64_t fCapabilities;
     1064} GIMHVEXTQUERYCAP;
     1065/** Pointer to a HvExtCallQueryCapabilities output struct. */
     1066typedef GIMHVEXTQUERYCAP *PGIMHVEXTQUERYCAP;
     1067AssertCompileSize(GIMHVEXTQUERYCAP, 8);
     1068
     1069/**
     1070 * HvExtCallGetBootZeroedMemory hypercall output.
     1071 */
     1072typedef struct GIMHVEXTGETBOOTZEROMEM
     1073{
     1074    RTGCPHYS GCPhysStart;
     1075    uint64_t cPages;
     1076} GIMHVEXTGETBOOTZEROMEM;
     1077/** Pointer to a HvExtCallGetBootZeroedMemory output struct. */
     1078typedef GIMHVEXTGETBOOTZEROMEM *PGIMHVEXTGETBOOTZEROMEM;
     1079AssertCompileSize(GIMHVEXTGETBOOTZEROMEM, 16);
    10381080/** @} */
    10391081
     
    10411083/** Hyper-V page size.  */
    10421084#define GIM_HV_PAGE_SIZE                          4096
     1085/** Hyper-V page shift. */
     1086#define GIM_HV_PAGE_SHIFT                         12
    10431087
    10441088/** Microsoft Hyper-V vendor signature. */
     
    13131357VMMR3_INT_DECL(int)             gimR3HvDebugRead(PVM pVM, void *pvBuf, uint32_t cbBuf, uint32_t cbRead, uint32_t *pcbRead,
    13141358                                                 uint32_t cMsTimeout, bool fUdpPkt);
     1359VMMR3_INT_DECL(int)             gimR3HvHypercallExtQueryCap(PVM pVM, int *prcHv);
     1360VMMR3_INT_DECL(int)             gimR3HvHypercallExtGetBootZeroedMem(PVM pVM, int *prcHv);
     1361
    13151362#endif /* IN_RING3 */
    13161363
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