- Timestamp:
- Oct 17, 2022 10:27:05 PM (2 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
-
include/VBox/vmm/cpum.h (modified) (5 diffs)
-
src/VBox/VMM/VMMAll/IEMAllCImpl.cpp (modified) (3 diffs)
-
src/VBox/VMM/VMMAll/VMXAllTemplate.cpp.h (modified) (4 diffs)
-
src/VBox/VMM/VMMR3/CPUM.cpp (modified) (3 diffs)
-
src/VBox/VMM/VMMR3/NEMR3Native-linux.cpp (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/cpum.h
r97182 r97183 1939 1939 1940 1940 /** 1941 * Checks if we're in an "interrupt shadow", i.e. after a STI, POP For MOV SS,1941 * Checks if we're in an "interrupt shadow", i.e. after a STI, POP SS or MOV SS, 1942 1942 * updating the state if stale. 1943 1943 * 1944 1944 * This also inhibit NMIs, except perhaps for nested guests. 1945 1945 * 1946 * @returns true if interrupts are inhibited by interrupt shadow, false if not. 1946 * @retval true if interrupts are inhibited by interrupt shadow. 1947 * @retval false if not. 1947 1948 * @param pCtx Current guest CPU context. 1948 1949 * @note Requires pCtx->rip to be up to date. … … 1962 1963 1963 1964 /** 1964 * Sets the "interrupt shadow" flag, after a STI, POPF or MOV SS instruction. 1965 * Checks if we're in an "interrupt shadow" due to a POP SS or MOV SS 1966 * instruction. 1967 * 1968 * This also inhibit NMIs, except perhaps for nested guests. 1969 * 1970 * @retval true if interrupts are inhibited due to POP/MOV SS. 1971 * @retval false if not. 1972 * @param pCtx Current guest CPU context. 1973 * @note Requires pCtx->rip to be up to date. 1974 * @note Does not clear fInhibit when CPUMCTX::uRipInhibitInt differs 1975 * from CPUMCTX::rip. 1976 * @note Both CPUMIsInInterruptShadowAfterSti() and this function may return 1977 * true depending on the execution engine being used. 1978 */ 1979 DECLINLINE(bool) CPUMIsInInterruptShadowAfterSs(PCCPUMCTX pCtx) 1980 { 1981 if (!(pCtx->fInhibit & CPUMCTX_INHIBIT_SHADOW_SS)) 1982 return false; 1983 1984 CPUMCTX_ASSERT_NOT_EXTRN(pCtx, CPUMCTX_EXTRN_RIP); 1985 return pCtx->uRipInhibitInt == pCtx->rip; 1986 } 1987 1988 /** 1989 * Checks if we're in an "interrupt shadow" due to an STI instruction. 1990 * 1991 * This also inhibit NMIs, except perhaps for nested guests. 1992 * 1993 * @retval true if interrupts are inhibited due to STI. 1994 * @retval false if not. 1995 * @param pCtx Current guest CPU context. 1996 * @note Requires pCtx->rip to be up to date. 1997 * @note Does not clear fInhibit when CPUMCTX::uRipInhibitInt differs 1998 * from CPUMCTX::rip. 1999 * @note Both CPUMIsInInterruptShadowAfterSs() and this function may return 2000 * true depending on the execution engine being used. 2001 */ 2002 DECLINLINE(bool) CPUMIsInInterruptShadowAfterSti(PCCPUMCTX pCtx) 2003 { 2004 if (!(pCtx->fInhibit & CPUMCTX_INHIBIT_SHADOW_STI)) 2005 return false; 2006 2007 CPUMCTX_ASSERT_NOT_EXTRN(pCtx, CPUMCTX_EXTRN_RIP); 2008 return pCtx->uRipInhibitInt == pCtx->rip; 2009 } 2010 2011 /** 2012 * Sets the "interrupt shadow" flag, after a STI, POP SS or MOV SS instruction. 1965 2013 * 1966 2014 * @param pCtx Current guest CPU context. … … 1975 2023 1976 2024 /** 1977 * Sets the "interrupt shadow" flag, after a STI, POP For MOV SS instruction,2025 * Sets the "interrupt shadow" flag, after a STI, POP SS or MOV SS instruction, 1978 2026 * extended version. 1979 2027 * … … 1985 2033 pCtx->fInhibit |= CPUMCTX_INHIBIT_SHADOW; 1986 2034 pCtx->uRipInhibitInt = rip; 2035 } 2036 2037 /** 2038 * Sets the "interrupt shadow" flag after a POP SS or MOV SS instruction. 2039 * 2040 * @param pCtx Current guest CPU context. 2041 * @note Requires pCtx->rip to be up to date. 2042 */ 2043 DECLINLINE(void) CPUMSetInInterruptShadowSs(PCPUMCTX pCtx) 2044 { 2045 CPUMCTX_ASSERT_NOT_EXTRN(pCtx, CPUMCTX_EXTRN_RIP); 2046 pCtx->fInhibit |= CPUMCTX_INHIBIT_SHADOW_SS; 2047 pCtx->uRipInhibitInt = pCtx->rip; 2048 } 2049 2050 /** 2051 * Sets the "interrupt shadow" flag after an STI instruction. 2052 * 2053 * @param pCtx Current guest CPU context. 2054 * @note Requires pCtx->rip to be up to date. 2055 */ 2056 DECLINLINE(void) CPUMSetInInterruptShadowSti(PCPUMCTX pCtx) 2057 { 2058 CPUMCTX_ASSERT_NOT_EXTRN(pCtx, CPUMCTX_EXTRN_RIP); 2059 pCtx->fInhibit |= CPUMCTX_INHIBIT_SHADOW_STI; 2060 pCtx->uRipInhibitInt = pCtx->rip; 1987 2061 } 1988 2062 … … 2034 2108 } 2035 2109 return fInhibited; 2110 } 2111 2112 /** 2113 * Update the two "interrupt shadow" flags separately, extended version. 2114 * 2115 * @param pCtx Current guest CPU context. 2116 * @param fInhibitedBySs The new state for the MOV SS & POP SS aspect. 2117 * @param fInhibitedBySti The new state for the STI aspect. 2118 * @param rip The RIP for which it is inhibited. 2119 */ 2120 DECLINLINE(void) CPUMUpdateInterruptShadowSsStiEx(PCPUMCTX pCtx, bool fInhibitedBySs, bool fInhibitedBySti, uint64_t rip) 2121 { 2122 if (!(fInhibitedBySs | fInhibitedBySti)) 2123 pCtx->fInhibit &= (uint8_t)~CPUMCTX_INHIBIT_SHADOW; 2124 else 2125 { 2126 pCtx->fInhibit |= (fInhibitedBySs ? CPUMCTX_INHIBIT_SHADOW_SS : 0) 2127 | (fInhibitedBySti ? CPUMCTX_INHIBIT_SHADOW_STI : 0); 2128 pCtx->uRipInhibitInt = rip; 2129 } 2036 2130 } 2037 2131 -
trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp
r97178 r97183 4704 4704 VBOXSTRICTRC rcStrict = IEM_CIMPL_CALL_2(iemCImpl_LoadSReg, iSegReg, uSel); 4705 4705 if (iSegReg == X86_SREG_SS && rcStrict == VINF_SUCCESS) 4706 CPUMSetInInterruptShadow (&pVCpu->cpum.GstCtx);4706 CPUMSetInInterruptShadowSs(&pVCpu->cpum.GstCtx); 4707 4707 return rcStrict; 4708 4708 } … … 4762 4762 pVCpu->cpum.GstCtx.rsp = TmpRsp.u; 4763 4763 if (iSegReg == X86_SREG_SS) 4764 CPUMSetInInterruptShadow (&pVCpu->cpum.GstCtx);4764 CPUMSetInInterruptShadowSs(&pVCpu->cpum.GstCtx); 4765 4765 } 4766 4766 return rcStrict; … … 7512 7512 iemRegAddToRipAndClearRF(pVCpu, cbInstr); 7513 7513 if (!(fEflOld & X86_EFL_IF) && (fEfl & X86_EFL_IF)) 7514 CPUMSetInInterruptShadow (&pVCpu->cpum.GstCtx);7514 CPUMSetInInterruptShadowSti(&pVCpu->cpum.GstCtx); 7515 7515 Log2(("STI: %#x -> %#x\n", fEflOld, fEfl)); 7516 7516 return VINF_SUCCESS; -
trunk/src/VBox/VMM/VMMAll/VMXAllTemplate.cpp.h
r97178 r97183 1698 1698 static uint32_t vmxHCGetGuestIntrStateAndUpdateFFs(PVMCPUCC pVCpu) 1699 1699 { 1700 uint32_t fIntrState = 0;1700 uint32_t fIntrState; 1701 1701 1702 1702 /* 1703 1703 * Check if we should inhibit interrupt delivery due to instructions like STI and MOV SS. 1704 1704 */ 1705 if (CPUMIsInInterruptShadowWithUpdate(&pVCpu->cpum.GstCtx)) 1706 { 1707 /* If inhibition is active, RIP and RFLAGS should've been imported from the VMCS already. */ 1708 HMVMX_CPUMCTX_ASSERT(pVCpu, CPUMCTX_EXTRN_RIP | CPUMCTX_EXTRN_RFLAGS); 1709 1710 /** @todo r=bird: This heuristic isn't all that correct, it would be safer 1711 * to always use MOVSS here. Best deal would be to track both bits in CPUM. */ 1712 if (pVCpu->cpum.GstCtx.eflags.Bits.u1IF) 1705 if (!CPUMIsInInterruptShadowWithUpdate(&pVCpu->cpum.GstCtx)) 1706 fIntrState = 0; 1707 else 1708 { 1709 /* If inhibition is active, RIP should've been imported from the VMCS already. */ 1710 HMVMX_CPUMCTX_ASSERT(pVCpu, CPUMCTX_EXTRN_RIP); 1711 1712 if (CPUMIsInInterruptShadowAfterSs(&pVCpu->cpum.GstCtx)) 1713 fIntrState = VMX_VMCS_GUEST_INT_STATE_BLOCK_MOVSS; 1714 else 1715 { 1713 1716 fIntrState = VMX_VMCS_GUEST_INT_STATE_BLOCK_STI; 1714 else 1715 fIntrState = VMX_VMCS_GUEST_INT_STATE_BLOCK_MOVSS; 1717 1718 /* Block-by-STI must not be set when interrupts are disabled. */ 1719 AssertStmt(pVCpu->cpum.GstCtx.eflags.Bits.u1IF, fIntrState = VMX_VMCS_GUEST_INT_STATE_BLOCK_MOVSS); 1720 } 1716 1721 } 1717 1722 … … 1719 1724 * Check if we should inhibit NMI delivery. 1720 1725 */ 1721 if (CPUMAreInterruptsInhibitedByNmiEx(&pVCpu->cpum.GstCtx)) 1726 if (!CPUMAreInterruptsInhibitedByNmiEx(&pVCpu->cpum.GstCtx)) 1727 { /* likely */ } 1728 else 1722 1729 fIntrState |= VMX_VMCS_GUEST_INT_STATE_BLOCK_NMI; 1723 1730 … … 1725 1732 * Validate. 1726 1733 */ 1727 #ifdef VBOX_STRICT1728 1734 /* We don't support block-by-SMI yet.*/ 1729 1735 Assert(!(fIntrState & VMX_VMCS_GUEST_INT_STATE_BLOCK_SMI)); 1730 1731 /* Block-by-STI must not be set when interrupts are disabled. */1732 if (fIntrState & VMX_VMCS_GUEST_INT_STATE_BLOCK_STI)1733 {1734 HMVMX_CPUMCTX_ASSERT(pVCpu, CPUMCTX_EXTRN_RFLAGS);1735 Assert(pVCpu->cpum.GstCtx.eflags.u & X86_EFL_IF);1736 }1737 #endif1738 1736 1739 1737 return fIntrState; … … 3383 3381 vmxHCImportGuestRFlags(pVCpu, pVmcsInfo); 3384 3382 3385 CPUMUpdateInterruptShadowEx(&pVCpu->cpum.GstCtx, 3386 RT_BOOL(fGstIntState & (VMX_VMCS_GUEST_INT_STATE_BLOCK_MOVSS | VMX_VMCS_GUEST_INT_STATE_BLOCK_STI)), 3387 pVCpu->cpum.GstCtx.rip); 3383 CPUMUpdateInterruptShadowSsStiEx(&pVCpu->cpum.GstCtx, 3384 RT_BOOL(fGstIntState & VMX_VMCS_GUEST_INT_STATE_BLOCK_MOVSS), 3385 RT_BOOL(fGstIntState & VMX_VMCS_GUEST_INT_STATE_BLOCK_STI), 3386 pVCpu->cpum.GstCtx.rip); 3388 3387 CPUMUpdateInterruptInhibitingByNmiEx(&pVCpu->cpum.GstCtx, RT_BOOL(fGstIntState & VMX_VMCS_GUEST_INT_STATE_BLOCK_NMI)); 3389 3388 } -
trunk/src/VBox/VMM/VMMR3/CPUM.cpp
r97178 r97183 3089 3089 * 3090 3090 * @param pszEFlags Where to write the mnemonics. (Assumes sufficient buffer space.) 3091 * @param efl The EFLAGS value .3091 * @param efl The EFLAGS value with fInhibit in bits 31:24. 3092 3092 */ 3093 3093 static void cpumR3InfoFormatFlags(char *pszEFlags, uint32_t efl) … … 3116 3116 { "po", "pe", X86_EFL_PF }, 3117 3117 { "cy", "nc", X86_EFL_CF }, 3118 { "inh-ss", NULL, (uint32_t)CPUMCTX_INHIBIT_SHADOW_SS << 24 }, 3119 { "inh-sti", NULL, (uint32_t)CPUMCTX_INHIBIT_SHADOW_STI << 24 }, 3120 { "inh-nmi", NULL, (uint32_t)CPUMCTX_INHIBIT_NMI << 24 }, 3118 3121 }; 3119 3122 char *psz = pszEFlags; … … 3152 3155 uint32_t efl = pCtxCore->eflags.u32; 3153 3156 char szEFlags[80]; 3154 cpumR3InfoFormatFlags(&szEFlags[0], efl );3157 cpumR3InfoFormatFlags(&szEFlags[0], efl | ((uint32_t)pCtx->fInhibit << 24)); 3155 3158 3156 3159 /* -
trunk/src/VBox/VMM/VMMR3/NEMR3Native-linux.cpp
r97178 r97183 1476 1476 pVCpu->cpum.GstCtx.rip = pRun->s.regs.regs.rip; 1477 1477 1478 CPUMUpdateInterruptShadowEx(&pVCpu->cpum.GstCtx, KvmEvents.interrupt.shadow != 0, pVCpu->cpum.GstCtx.rip); 1478 CPUMUpdateInterruptShadowSsStiEx(&pVCpu->cpum.GstCtx, 1479 RT_BOOL(KvmEvents.interrupt.shadow & KVM_X86_SHADOW_INT_MOV_SS), 1480 RT_BOOL(KvmEvents.interrupt.shadow & KVM_X86_SHADOW_INT_STI), 1481 pVCpu->cpum.GstCtx.rip); 1479 1482 CPUMUpdateInterruptInhibitingByNmi(&pVCpu->cpum.GstCtx, KvmEvents.nmi.masked != 0); 1480 1483 … … 1865 1868 { /* probably likely */ } 1866 1869 else 1867 KvmEvents.interrupt.shadow = KVM_X86_SHADOW_INT_MOV_SS | KVM_X86_SHADOW_INT_STI; 1870 KvmEvents.interrupt.shadow = (CPUMIsInInterruptShadowAfterSs() ? KVM_X86_SHADOW_INT_MOV_SS : 0) 1871 | (CPUMIsInInterruptShadowAfterSti() ? KVM_X86_SHADOW_INT_STI : 0); 1868 1872 1869 1873 /* No flag - this is updated unconditionally. */ … … 2049 2053 if (!(pVCpu->cpum.GstCtx.fExtrn & CPUMCTX_EXTRN_INHIBIT_INT)) 2050 2054 KvmEvents.interrupt.shadow = !CPUMIsInInterruptShadowWithUpdate(&pVCpu->cpum.GstCtx) ? 0 2051 : KVM_X86_SHADOW_INT_MOV_SS | KVM_X86_SHADOW_INT_STI; 2055 : (CPUMIsInInterruptShadowAfterSs() ? KVM_X86_SHADOW_INT_MOV_SS : 0) 2056 | (CPUMIsInInterruptShadowAfterSti() ? KVM_X86_SHADOW_INT_STI : 0); 2052 2057 else 2053 CPUMUpdateInterruptShadowEx(&pVCpu->cpum.GstCtx, KvmEvents.interrupt.shadow != 0, pRun->s.regs.regs.rip); 2058 CPUMUpdateInterruptShadowSsStiEx(&pVCpu->cpum.GstCtx, 2059 RT_BOOL(KvmEvents.interrupt.shadow & KVM_X86_SHADOW_INT_MOV_SS), 2060 RT_BOOL(KvmEvents.interrupt.shadow & KVM_X86_SHADOW_INT_MOV_STI), 2061 pRun->s.regs.regs.rip); 2054 2062 2055 2063 if (!(pVCpu->cpum.GstCtx.fExtrn & CPUMCTX_EXTRN_INHIBIT_NMI))
Note:
See TracChangeset
for help on using the changeset viewer.

