Changeset 12625 in vbox
- Timestamp:
- Sep 22, 2008 7:15:38 AM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 36901
- Location:
- trunk/src/VBox/VMM/VMMR0
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
r12610 r12625 1775 1775 IoExitInfo.au32[0] = pVMCB->ctrl.u64ExitInfo1; 1776 1776 1777 /* If any IO breakpoints are armed, then we should check if a debug trap needs to be generated. */1778 if (pCtx->dr[7] & X86_DR7_ENABLED_MASK)1779 {1780 STAM_COUNTER_INC(&pVM->hwaccm.s.StatDRxIOCheck);1781 for (unsigned i=0;i<4;i++)1782 {1783 if ( pCtx->dr[i] == IoExitInfo.n.u16Port1784 && (pCtx->dr[7] & (X86_DR7_L(i) | X86_DR7_G(i)))1785 && (pCtx->dr[7] & X86_DR7_RW(i, X86_DR7_RW_IO)) == X86_DR7_RW(i, X86_DR7_RW_IO))1786 {1787 SVM_EVENT Event;1788 1789 Assert(CPUMIsGuestDebugStateActive(pVM));1790 1791 /* Clear all breakpoint status flags and set the one we just hit. */1792 pCtx->dr[6] &= ~(X86_DR6_B0|X86_DR6_B1|X86_DR6_B2|X86_DR6_B3);1793 pCtx->dr[6] |= RT_BIT(i);1794 1795 /* Note: AMD64 Architecture Programmer's Manual 13.1:1796 * Bits 15:13 of the DR6 register is never cleared by the processor and must be cleared by software after1797 * the contents have been read.1798 */1799 pVMCB->guest.u64DR6 = pCtx->dr[6];1800 1801 /* X86_DR7_GD will be cleared if drx accesses should be trapped inside the guest. */1802 pCtx->dr[7] &= ~X86_DR7_GD;1803 1804 /* Paranoia. */1805 pCtx->dr[7] &= 0xffffffff; /* upper 32 bits reserved */1806 pCtx->dr[7] &= ~(RT_BIT(11) | RT_BIT(12) | RT_BIT(14) | RT_BIT(15)); /* must be zero */1807 pCtx->dr[7] |= 0x400; /* must be one */1808 1809 pVMCB->guest.u64DR7 = pCtx->dr[7];1810 1811 /* Inject the exception. */1812 Log(("Inject IO debug trap at %VGv\n", pCtx->rip));1813 1814 Event.au64[0] = 0;1815 Event.n.u3Type = SVM_EVENT_EXCEPTION; /* trap or fault */1816 Event.n.u1Valid = 1;1817 Event.n.u8Vector = X86_XCPT_DB;1818 1819 SVMR0InjectEvent(pVM, pVMCB, pCtx, &Event);1820 1821 STAM_PROFILE_ADV_STOP(&pVM->hwaccm.s.StatExit, x);1822 goto ResumeExecution;1823 }1824 }1825 }1826 1827 1777 /** @todo could use a lookup table here */ 1828 1778 if (IoExitInfo.n.u1OP8) … … 1905 1855 if (RT_LIKELY(rc == VINF_SUCCESS)) 1906 1856 { 1857 /* If any IO breakpoints are armed, then we should check if a debug trap needs to be generated. */ 1858 if (pCtx->dr[7] & X86_DR7_ENABLED_MASK) 1859 { 1860 STAM_COUNTER_INC(&pVM->hwaccm.s.StatDRxIOCheck); 1861 for (unsigned i=0;i<4;i++) 1862 { 1863 if ( pCtx->dr[i] == IoExitInfo.n.u16Port 1864 && (pCtx->dr[7] & (X86_DR7_L(i) | X86_DR7_G(i))) 1865 && (pCtx->dr[7] & X86_DR7_RW(i, X86_DR7_RW_IO)) == X86_DR7_RW(i, X86_DR7_RW_IO)) 1866 { 1867 SVM_EVENT Event; 1868 1869 Assert(CPUMIsGuestDebugStateActive(pVM)); 1870 1871 /* Clear all breakpoint status flags and set the one we just hit. */ 1872 pCtx->dr[6] &= ~(X86_DR6_B0|X86_DR6_B1|X86_DR6_B2|X86_DR6_B3); 1873 pCtx->dr[6] |= RT_BIT(i); 1874 1875 /* Note: AMD64 Architecture Programmer's Manual 13.1: 1876 * Bits 15:13 of the DR6 register is never cleared by the processor and must be cleared by software after 1877 * the contents have been read. 1878 */ 1879 pVMCB->guest.u64DR6 = pCtx->dr[6]; 1880 1881 /* X86_DR7_GD will be cleared if drx accesses should be trapped inside the guest. */ 1882 pCtx->dr[7] &= ~X86_DR7_GD; 1883 1884 /* Paranoia. */ 1885 pCtx->dr[7] &= 0xffffffff; /* upper 32 bits reserved */ 1886 pCtx->dr[7] &= ~(RT_BIT(11) | RT_BIT(12) | RT_BIT(14) | RT_BIT(15)); /* must be zero */ 1887 pCtx->dr[7] |= 0x400; /* must be one */ 1888 1889 pVMCB->guest.u64DR7 = pCtx->dr[7]; 1890 1891 /* Inject the exception. */ 1892 Log(("Inject IO debug trap at %VGv\n", pCtx->rip)); 1893 1894 Event.au64[0] = 0; 1895 Event.n.u3Type = SVM_EVENT_EXCEPTION; /* trap or fault */ 1896 Event.n.u1Valid = 1; 1897 Event.n.u8Vector = X86_XCPT_DB; 1898 1899 SVMR0InjectEvent(pVM, pVMCB, pCtx, &Event); 1900 1901 STAM_PROFILE_ADV_STOP(&pVM->hwaccm.s.StatExit, x); 1902 goto ResumeExecution; 1903 } 1904 } 1905 } 1906 1907 1907 STAM_PROFILE_ADV_STOP(&pVM->hwaccm.s.StatExit, x); 1908 1908 goto ResumeExecution; -
trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
r12610 r12625 2111 2111 } 2112 2112 2113 /* If any IO breakpoints are armed, then we should check if a debug trap needs to be generated. */2114 if (pCtx->dr[7] & X86_DR7_ENABLED_MASK)2115 {2116 STAM_COUNTER_INC(&pVM->hwaccm.s.StatDRxIOCheck);2117 for (unsigned i=0;i<4;i++)2118 {2119 if ( pCtx->dr[i] == uPort2120 && (pCtx->dr[7] & (X86_DR7_L(i) | X86_DR7_G(i)))2121 && (pCtx->dr[7] & X86_DR7_RW(i, X86_DR7_RW_IO)) == X86_DR7_RW(i, X86_DR7_RW_IO))2122 {2123 uint64_t uDR6;2124 2125 Assert(CPUMIsGuestDebugStateActive(pVM));2126 2127 uDR6 = ASMGetDR6();2128 2129 /* Clear all breakpoint status flags and set the one we just hit. */2130 uDR6 &= ~(X86_DR6_B0|X86_DR6_B1|X86_DR6_B2|X86_DR6_B3);2131 uDR6 |= RT_BIT(i);2132 2133 /* Note: AMD64 Architecture Programmer's Manual 13.1:2134 * Bits 15:13 of the DR6 register is never cleared by the processor and must be cleared by software after2135 * the contents have been read.2136 */2137 ASMSetDR6(uDR6);2138 2139 /* X86_DR7_GD will be cleared if drx accesses should be trapped inside the guest. */2140 pCtx->dr[7] &= ~X86_DR7_GD;2141 2142 /* Paranoia. */2143 pCtx->dr[7] &= 0xffffffff; /* upper 32 bits reserved */2144 pCtx->dr[7] &= ~(RT_BIT(11) | RT_BIT(12) | RT_BIT(14) | RT_BIT(15)); /* must be zero */2145 pCtx->dr[7] |= 0x400; /* must be one */2146 2147 /* Resync DR7 */2148 rc = VMXWriteVMCS(VMX_VMCS_GUEST_DR7, pCtx->dr[7]);2149 AssertRC(rc);2150 2151 /* Construct inject info. */2152 intInfo = X86_XCPT_DB;2153 intInfo |= (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT);2154 intInfo |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_HWEXCPT << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT);2155 2156 Log(("Inject IO debug trap at %VGv\n", pCtx->rip));2157 rc = VMXR0InjectEvent(pVM, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo), 0, 0);2158 AssertRC(rc);2159 2160 STAM_PROFILE_ADV_STOP(&pVM->hwaccm.s.StatExit, x);2161 goto ResumeExecution;2162 }2163 }2164 }2165 2166 2113 uint32_t cbSize = aIOSize[uIOWidth]; 2167 2114 … … 2221 2168 if (RT_LIKELY(rc == VINF_SUCCESS)) 2222 2169 { 2170 /* If any IO breakpoints are armed, then we should check if a debug trap needs to be generated. */ 2171 if (pCtx->dr[7] & X86_DR7_ENABLED_MASK) 2172 { 2173 STAM_COUNTER_INC(&pVM->hwaccm.s.StatDRxIOCheck); 2174 for (unsigned i=0;i<4;i++) 2175 { 2176 if ( pCtx->dr[i] == uPort 2177 && (pCtx->dr[7] & (X86_DR7_L(i) | X86_DR7_G(i))) 2178 && (pCtx->dr[7] & X86_DR7_RW(i, X86_DR7_RW_IO)) == X86_DR7_RW(i, X86_DR7_RW_IO)) 2179 { 2180 uint64_t uDR6; 2181 2182 Assert(CPUMIsGuestDebugStateActive(pVM)); 2183 2184 uDR6 = ASMGetDR6(); 2185 2186 /* Clear all breakpoint status flags and set the one we just hit. */ 2187 uDR6 &= ~(X86_DR6_B0|X86_DR6_B1|X86_DR6_B2|X86_DR6_B3); 2188 uDR6 |= RT_BIT(i); 2189 2190 /* Note: AMD64 Architecture Programmer's Manual 13.1: 2191 * Bits 15:13 of the DR6 register is never cleared by the processor and must be cleared by software after 2192 * the contents have been read. 2193 */ 2194 ASMSetDR6(uDR6); 2195 2196 /* X86_DR7_GD will be cleared if drx accesses should be trapped inside the guest. */ 2197 pCtx->dr[7] &= ~X86_DR7_GD; 2198 2199 /* Paranoia. */ 2200 pCtx->dr[7] &= 0xffffffff; /* upper 32 bits reserved */ 2201 pCtx->dr[7] &= ~(RT_BIT(11) | RT_BIT(12) | RT_BIT(14) | RT_BIT(15)); /* must be zero */ 2202 pCtx->dr[7] |= 0x400; /* must be one */ 2203 2204 /* Resync DR7 */ 2205 rc = VMXWriteVMCS(VMX_VMCS_GUEST_DR7, pCtx->dr[7]); 2206 AssertRC(rc); 2207 2208 /* Construct inject info. */ 2209 intInfo = X86_XCPT_DB; 2210 intInfo |= (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT); 2211 intInfo |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_HWEXCPT << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT); 2212 2213 Log(("Inject IO debug trap at %VGv\n", pCtx->rip)); 2214 rc = VMXR0InjectEvent(pVM, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo), 0, 0); 2215 AssertRC(rc); 2216 2217 STAM_PROFILE_ADV_STOP(&pVM->hwaccm.s.StatExit, x); 2218 goto ResumeExecution; 2219 } 2220 } 2221 } 2222 2223 2223 STAM_PROFILE_ADV_STOP(&pVM->hwaccm.s.StatExit, x); 2224 2224 goto ResumeExecution;
Note:
See TracChangeset
for help on using the changeset viewer.