Changeset 72466 in vbox for trunk/src/VBox/VMM/VMMR0
- Timestamp:
- Jun 7, 2018 5:35:54 AM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 122951
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
r72462 r72466 7169 7169 } 7170 7170 7171 /**7172 * Performs the operations necessary that are part of the vmmcall instruction7173 * execution in the guest.7174 *7175 * @returns Strict VBox status code (i.e. informational status codes too).7176 * @retval VINF_SUCCESS on successful handling, no \#UD needs to be thrown,7177 * update RIP and eflags.RF depending on @a pfUpdatedRipAndRF and7178 * continue guest execution.7179 * @retval VINF_GIM_HYPERCALL_CONTINUING continue hypercall without updating7180 * RIP.7181 * @retval VINF_GIM_R3_HYPERCALL re-start the hypercall from ring-3.7182 *7183 * @param pVCpu The cross context virtual CPU structure.7184 * @param pCtx Pointer to the guest-CPU context.7185 * @param pfUpdatedRipAndRF Whether the guest RIP/EIP has been updated as7186 * part of handling the VMMCALL operation.7187 *7188 * @todo r=bird: merge this with hmR0SvmExitVmmCall and fix todos.7189 */7190 static VBOXSTRICTRC hmR0SvmVmmcall(PVMCPU pVCpu, PCPUMCTX pCtx, bool *pfUpdatedRipAndRF)7191 {7192 /*7193 * TPR patched instruction emulation for 32-bit guests.7194 */7195 PVM pVM = pVCpu->CTX_SUFF(pVM);7196 if (pVM->hm.s.fTprPatchingAllowed)7197 {7198 int rc = hmSvmEmulateMovTpr(pVCpu, pCtx);7199 if (RT_SUCCESS(rc))7200 {7201 *pfUpdatedRipAndRF = true;7202 return VINF_SUCCESS;7203 }7204 7205 if (rc != VERR_NOT_FOUND)7206 {7207 Log(("hmSvmExitVmmCall: hmSvmEmulateMovTpr returns %Rrc\n", rc));7208 *pfUpdatedRipAndRF = false;7209 return rc;7210 }7211 }7212 7213 /*7214 * Paravirtualized hypercalls.7215 */7216 *pfUpdatedRipAndRF = false; /** @todo r=bird: This is misleading/wrong, see GIMHypercall returncode docs. */7217 if (EMAreHypercallInstructionsEnabled(pVCpu))7218 return GIMHypercall(pVCpu, pCtx);7219 7220 return VERR_NOT_AVAILABLE;7221 }7222 7223 7224 7171 7225 7172 /** … … 7231 7178 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitVmcall); 7232 7179 7233 bool fRipUpdated; 7234 VBOXSTRICTRC rcStrict = hmR0SvmVmmcall(pVCpu, pCtx, &fRipUpdated); 7235 if (RT_SUCCESS(rcStrict)) 7236 { 7237 /* Only update the RIP if we're continuing guest execution and not 7238 in the case of say VINF_GIM_R3_HYPERCALL. */ 7239 if ( rcStrict == VINF_SUCCESS 7240 && !fRipUpdated) 7241 { 7242 hmR0SvmAdvanceRipHwAssist(pVCpu, pCtx, 3 /* cbInstr */); 7243 } 7244 7245 /* If the hypercall or TPR patching changes anything other than guest's general-purpose registers, 7246 we would need to reload the guest changed bits here before VM-entry. */ 7247 return VBOXSTRICTRC_VAL(rcStrict); 7180 if (pVCpu->CTX_SUFF(pVM)->hm.s.fTprPatchingAllowed) 7181 { 7182 int rc = hmSvmEmulateMovTpr(pVCpu, pCtx); 7183 if (rc != VERR_NOT_FOUND) 7184 { 7185 Log4(("hmR0SvmExitVmmCall: hmSvmEmulateMovTpr returns %Rrc\n", rc)); 7186 return rc; 7187 } 7188 } 7189 7190 if (EMAreHypercallInstructionsEnabled(pVCpu)) 7191 { 7192 VBOXSTRICTRC rcStrict = GIMHypercall(pVCpu, pCtx); 7193 if (RT_SUCCESS(rcStrict)) 7194 { 7195 /* Only update the RIP if we're continuing guest execution and not in the case 7196 of say VINF_GIM_R3_HYPERCALL. */ 7197 if (rcStrict == VINF_SUCCESS) 7198 hmR0SvmAdvanceRipHwAssist(pVCpu, pCtx, 3 /* cbInstr */); 7199 7200 return VBOXSTRICTRC_VAL(rcStrict); 7201 } 7202 else 7203 Log4(("hmR0SvmExitVmmCall: GIMHypercall returns %Rrc -> #UD\n", VBOXSTRICTRC_VAL(rcStrict))); 7248 7204 } 7249 7205
Note:
See TracChangeset
for help on using the changeset viewer.