Changeset 63632 in vbox
- Timestamp:
- Aug 25, 2016 10:58:22 AM (8 years ago)
- Location:
- trunk
- Files:
-
- 6 edited
-
include/VBox/vmm/apic.h (modified) (3 diffs)
-
src/VBox/Devices/testcase/tstDeviceStructSize.cpp (modified) (1 diff)
-
src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp (modified) (1 diff)
-
src/VBox/VMM/VMMAll/APICAll.cpp (modified) (22 diffs)
-
src/VBox/VMM/VMMR3/APIC.cpp (modified) (3 diffs)
-
src/VBox/VMM/include/APICInternal.h (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/apic.h
r61794 r63632 141 141 #define XAPIC_OFF_LVT_EXT_END XAPIC_OFF_LVT_CMCI 142 142 143 /** @name xAPIC Interrupt Command Register bits. 144 * See Intel spec. 10.6.1 "Interrupt Command Register (ICR)". 145 * See Intel spec. 10.5.1 "Local Vector Table". 146 * @{ */ 147 /** 148 * xAPIC trigger mode. 149 */ 150 typedef enum XAPICTRIGGERMODE 151 { 152 XAPICTRIGGERMODE_EDGE = 0, 153 XAPICTRIGGERMODE_LEVEL 154 } XAPICTRIGGERMODE; 155 143 156 RT_C_DECLS_BEGIN 144 157 … … 148 161 */ 149 162 VMMR3_INT_DECL(void) APICR3InitIpi(PVMCPU pVCpu); 163 VMMR3_INT_DECL(void) APICR3HvEnable(PVM pVM); 150 164 /** @} */ 151 165 #endif /* IN_RING3 */ … … 165 179 VMMDECL(bool) APICGetHighestPendingInterrupt(PVMCPU pVCpu, uint8_t *pu8PendingIntr); 166 180 181 /** @name Hyper-V interface (Ring-3 and all-context API). 182 * @{ */ 183 #ifdef IN_RING3 184 VMMR3_INT_DECL(void) APICR3HvSetCompatMode(PVM pVM, bool fHyperVCompatMode); 185 #endif 186 VMM_INT_DECL(void) APICHvSendInterrupt(PVMCPU pVCpu, uint8_t uVector, bool fAutoEoi, XAPICTRIGGERMODE enmTriggerMode); 187 VMM_INT_DECL(VBOXSTRICTRC) APICHvSetTpr(PVMCPU pVCpu, uint8_t uTpr); 188 VMM_INT_DECL(uint8_t) APICHvGetTpr(PVMCPU pVCpu); 189 VMM_INT_DECL(VBOXSTRICTRC) APICHvSetIcr(PVMCPU pVCpu, uint64_t uIcr); 190 VMM_INT_DECL(uint64_t) APICHvGetIcr(PVMCPU pVCpu); 191 VMM_INT_DECL(VBOXSTRICTRC) APICHvSetEoi(PVMCPU pVCpu, uint32_t uEoi); 192 /** @} */ 193 167 194 RT_C_DECLS_END 168 195 -
trunk/src/VBox/Devices/testcase/tstDeviceStructSize.cpp
r62576 r63632 291 291 #ifdef VBOX_WITH_NEW_APIC 292 292 CHECK_MEMBER_ALIGNMENT(APICDEV, pDevInsR0, 8); 293 CHECK_MEMBER_ALIGNMENT(APICDEV, pCritSectR0, 8); 293 294 CHECK_MEMBER_ALIGNMENT(APICDEV, pDevInsRC, 8); 295 CHECK_MEMBER_ALIGNMENT(APICDEV, pCritSectRC, 8); 294 296 #else 295 297 # ifdef VBOX_WITH_STATISTICS -
trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp
r62957 r63632 773 773 GEN_CHECK_OFF(APICCPU, StatTimerIcrWrite); 774 774 GEN_CHECK_OFF(APICCPU, StatIcrLoWrite); 775 GEN_CHECK_OFF(APICCPU, StatIcrHiWrite); 776 GEN_CHECK_OFF(APICCPU, StatIcrFullWrite); 775 777 # endif /* VBOX_WITH_STATISTICS */ 776 778 #else -
trunk/src/VBox/VMM/VMMAll/APICAll.cpp
r63525 r63632 1055 1055 PXAPICPAGE pXApicPage = VMCPU_TO_XAPICPAGE(pVCpu); 1056 1056 pXApicPage->icr_hi.all.u32IcrHi = uIcrHi & XAPIC_ICR_HI_DEST; 1057 STAM_COUNTER_INC(&pVCpu->apic.s.StatIcrHiWrite); 1057 1058 Log2(("APIC%u: apicSetIcrHi: uIcrHi=%#RX32\n", pVCpu->idCpu, pXApicPage->icr_hi.all.u32IcrHi)); 1058 1059 … … 1091 1092 * @param rcRZ The return code if the operation cannot be performed 1092 1093 * in the current context. 1094 * 1095 * @remarks This function is used by both x2APIC interface and the Hyper-V 1096 * interface, see APICHvSetIcr(). The Hyper-V spec isn't clear what 1097 * happens when invalid bits are set. For the time being, it will #GP 1098 * like a regular x2APIC access. 1093 1099 */ 1094 1100 static VBOXSTRICTRC apicSetIcr(PVMCPU pVCpu, uint64_t u64Icr, int rcRZ) 1095 1101 { 1096 1102 VMCPU_ASSERT_EMT(pVCpu); 1097 Assert(XAPIC_IN_X2APIC_MODE(pVCpu));1098 1103 1099 1104 /* Validate. */ … … 1104 1109 PX2APICPAGE pX2ApicPage = VMCPU_TO_X2APICPAGE(pVCpu); 1105 1110 pX2ApicPage->icr_hi.u32IcrHi = RT_HI_U32(u64Icr); 1106 return apicSetIcrLo(pVCpu, uLo, rcRZ); 1111 STAM_COUNTER_INC(&pVCpu->apic.s.StatIcrHiWrite); 1112 STAM_COUNTER_INC(&pVCpu->apic.s.StatIcrFullWrite); 1113 return apicSetIcrLo(pVCpu, uLo, rcRZ); 1107 1114 } 1108 1115 return apicMsrAccessError(pVCpu, MSR_IA32_X2APIC_ICR, APICMSRACCESS_WRITE_RSVD_BITS); … … 1189 1196 * 1190 1197 * @returns Strict VBox status code. 1191 * @param pVCpu The cross context virtual CPU structure. 1192 * @param uTpr The TPR value. 1193 */ 1194 static VBOXSTRICTRC apicSetTpr(PVMCPU pVCpu, uint32_t uTpr) 1198 * @param pVCpu The cross context virtual CPU structure. 1199 * @param uTpr The TPR value. 1200 * @param fForceX2ApicBehaviour Pretend the APIC is in x2APIC mode during 1201 * this write. 1202 */ 1203 static VBOXSTRICTRC apicSetTprEx(PVMCPU pVCpu, uint32_t uTpr, bool fForceX2ApicBehaviour) 1195 1204 { 1196 1205 VMCPU_ASSERT_EMT(pVCpu); 1197 1206 1198 Log2(("APIC%u: apicSetTpr : uTpr=%#RX32\n", pVCpu->idCpu, uTpr));1207 Log2(("APIC%u: apicSetTprEx: uTpr=%#RX32\n", pVCpu->idCpu, uTpr)); 1199 1208 STAM_COUNTER_INC(&pVCpu->apic.s.StatTprWrite); 1200 1209 1201 if ( XAPIC_IN_X2APIC_MODE(pVCpu) 1210 bool const fX2ApicMode = XAPIC_IN_X2APIC_MODE(pVCpu) || fForceX2ApicBehaviour; 1211 if ( fX2ApicMode 1202 1212 && (uTpr & ~XAPIC_TPR_VALID)) 1203 1213 return apicMsrAccessError(pVCpu, MSR_IA32_X2APIC_TPR, APICMSRACCESS_WRITE_RSVD_BITS); … … 1215 1225 * 1216 1226 * @returns Strict VBox status code. 1217 * @param pVCpu The cross context virtual CPU structure. 1218 * @param uEoi The EOI value. 1219 */ 1220 static VBOXSTRICTRC apicSetEoi(PVMCPU pVCpu, uint32_t uEoi) 1227 * @param pVCpu The cross context virtual CPU structure. 1228 * @param uEoi The EOI value. 1229 * @param fForceX2ApicBehaviour Pretend the APIC is in x2APIC mode during 1230 * this write. 1231 */ 1232 static VBOXSTRICTRC apicSetEoi(PVMCPU pVCpu, uint32_t uEoi, bool fForceX2ApicBehaviour) 1221 1233 { 1222 1234 VMCPU_ASSERT_EMT(pVCpu); … … 1225 1237 STAM_COUNTER_INC(&pVCpu->apic.s.StatEoiWrite); 1226 1238 1227 if ( XAPIC_IN_X2APIC_MODE(pVCpu) 1239 bool const fX2ApicMode = XAPIC_IN_X2APIC_MODE(pVCpu) || fForceX2ApicBehaviour; 1240 if ( fX2ApicMode 1228 1241 && (uEoi & ~XAPIC_EOI_WO_VALID)) 1229 1242 return apicMsrAccessError(pVCpu, MSR_IA32_X2APIC_EOI, APICMSRACCESS_WRITE_RSVD_BITS); … … 1249 1262 { /* likely */ } 1250 1263 else 1251 return XAPIC_IN_X2APIC_MODE(pVCpu)? VINF_CPUM_R3_MSR_WRITE : VINF_IOM_R3_MMIO_WRITE;1264 return fX2ApicMode ? VINF_CPUM_R3_MSR_WRITE : VINF_IOM_R3_MMIO_WRITE; 1252 1265 1253 1266 /* … … 1311 1324 { 1312 1325 VMCPU_ASSERT_EMT(pVCpu); 1313 Assert(!XAPIC_IN_X2APIC_MODE(pVCpu)); 1326 PCAPIC pApic = VM_TO_APIC(pVCpu->CTX_SUFF(pVM)); 1327 Assert(!XAPIC_IN_X2APIC_MODE(pVCpu) || pApic->fHyperVCompatMode); RT_NOREF_PV(pApic); 1314 1328 1315 1329 Log2(("APIC%u: apicSetLdr: uLdr=%#RX32\n", pVCpu->idCpu, uLdr)); … … 1601 1615 pApicCpu->uHintedTimerShift = uTimerShift; 1602 1616 } 1617 } 1618 1619 1620 /** 1621 * Gets the Interrupt Command Register (ICR), without performing any interface 1622 * checks. 1623 * 1624 * @returns The ICR value. 1625 * @param pVCpu The cross context virtual CPU structure. 1626 */ 1627 DECLINLINE(uint64_t) apicGetIcrNoCheck(PVMCPU pVCpu) 1628 { 1629 PCX2APICPAGE pX2ApicPage = VMCPU_TO_CX2APICPAGE(pVCpu); 1630 uint64_t const uHi = pX2ApicPage->icr_hi.u32IcrHi; 1631 uint64_t const uLo = pX2ApicPage->icr_lo.all.u32IcrLo; 1632 uint64_t const uIcr = RT_MAKE_U64(uLo, uHi); 1633 return uIcr; 1603 1634 } 1604 1635 … … 1719 1750 case XAPIC_OFF_TPR: 1720 1751 { 1721 rcStrict = apicSetTpr (pVCpu, uValue);1752 rcStrict = apicSetTprEx(pVCpu, uValue, false /* fForceX2ApicBehaviour */); 1722 1753 break; 1723 1754 } … … 1744 1775 case XAPIC_OFF_EOI: 1745 1776 { 1746 rcStrict = apicSetEoi(pVCpu, uValue );1777 rcStrict = apicSetEoi(pVCpu, uValue, false /* fForceX2ApicBehaviour */); 1747 1778 break; 1748 1779 } … … 1843 1874 RT_NOREF_PV(pDevIns); 1844 1875 1876 PCAPIC pApic = VM_TO_APIC(pVCpu->CTX_SUFF(pVM)); 1845 1877 #ifndef IN_RING3 1846 PCAPIC pApic = VM_TO_APIC(pVCpu->CTX_SUFF(pVM));1847 1878 if (pApic->fRZEnabled) 1848 1879 { /* likely */} … … 1854 1885 1855 1886 VBOXSTRICTRC rcStrict = VINF_SUCCESS; 1856 if (RT_LIKELY(XAPIC_IN_X2APIC_MODE(pVCpu))) 1887 if (RT_LIKELY( XAPIC_IN_X2APIC_MODE(pVCpu) 1888 || pApic->fHyperVCompatMode)) 1857 1889 { 1858 1890 switch (u32Reg) … … 1861 1893 case MSR_IA32_X2APIC_ICR: 1862 1894 { 1863 PCX2APICPAGE pX2ApicPage = VMCPU_TO_CX2APICPAGE(pVCpu); 1864 uint64_t const uHi = pX2ApicPage->icr_hi.u32IcrHi; 1865 uint64_t const uLo = pX2ApicPage->icr_lo.all.u32IcrLo; 1866 *pu64Value = RT_MAKE_U64(uLo, uHi); 1895 *pu64Value = apicGetIcrNoCheck(pVCpu); 1867 1896 break; 1868 1897 } … … 1948 1977 RT_NOREF_PV(pDevIns); 1949 1978 1979 PCAPIC pApic = VM_TO_APIC(pVCpu->CTX_SUFF(pVM)); 1950 1980 #ifndef IN_RING3 1951 PCAPIC pApic = VM_TO_APIC(pVCpu->CTX_SUFF(pVM));1952 1981 if (pApic->fRZEnabled) 1953 1982 { /* likely */ } … … 1973 2002 uint32_t u32Value = RT_LO_U32(u64Value); 1974 2003 VBOXSTRICTRC rcStrict = VINF_SUCCESS; 1975 if (RT_LIKELY(XAPIC_IN_X2APIC_MODE(pVCpu))) 2004 if (RT_LIKELY( XAPIC_IN_X2APIC_MODE(pVCpu) 2005 || pApic->fHyperVCompatMode)) 1976 2006 { 1977 2007 switch (u32Reg) … … 1979 2009 case MSR_IA32_X2APIC_TPR: 1980 2010 { 1981 rcStrict = apicSetTpr (pVCpu, u32Value);2011 rcStrict = apicSetTprEx(pVCpu, u32Value, false /* fForceX2ApicBehaviour */); 1982 2012 break; 1983 2013 } … … 2035 2065 case MSR_IA32_X2APIC_EOI: 2036 2066 { 2037 rcStrict = apicSetEoi(pVCpu, u32Value );2067 rcStrict = apicSetEoi(pVCpu, u32Value, false /* fForceX2ApicBehaviour */); 2038 2068 break; 2039 2069 } 2040 2070 2071 /* 2072 * Windows guest using Hyper-V x2APIC MSR compatibility mode tries to write the "high" 2073 * LDR bits, which is quite absurd (as it's a 32-bit register) using this invalid MSR 2074 * index (0x80E). The write value was 0xffffffff on a Windows 8.1 64-bit guest. We can 2075 * safely ignore this nonsense, See @bugref{8382#c7}. 2076 */ 2077 case MSR_IA32_X2APIC_LDR + 1: 2078 { 2079 if (pApic->fHyperVCompatMode) 2080 rcStrict = VINF_SUCCESS; 2081 else 2082 rcStrict = apicMsrAccessError(pVCpu, u32Reg, APICMSRACCESS_WRITE_RSVD_OR_UNKNOWN); 2083 break; 2084 } 2085 2086 /* Special-treament (read-only normally, but not with Hyper-V) */ 2087 case MSR_IA32_X2APIC_LDR: 2088 { 2089 if (pApic->fHyperVCompatMode) 2090 { 2091 rcStrict = apicSetLdr(pVCpu, u32Value); 2092 break; 2093 } 2094 /* fallthru */ 2095 } 2041 2096 /* Read-only MSRs: */ 2042 2097 case MSR_IA32_X2APIC_ID: 2043 2098 case MSR_IA32_X2APIC_VERSION: 2044 2099 case MSR_IA32_X2APIC_PPR: 2045 case MSR_IA32_X2APIC_LDR:2046 2100 case MSR_IA32_X2APIC_ISR0: case MSR_IA32_X2APIC_ISR1: case MSR_IA32_X2APIC_ISR2: case MSR_IA32_X2APIC_ISR3: 2047 2101 case MSR_IA32_X2APIC_ISR4: case MSR_IA32_X2APIC_ISR5: case MSR_IA32_X2APIC_ISR6: case MSR_IA32_X2APIC_ISR7: … … 2232 2286 { 2233 2287 RT_NOREF_PV(pDevIns); 2234 apicSetTpr (pVCpu, u8Tpr);2288 apicSetTprEx(pVCpu, u8Tpr, false /* fForceX2ApicBehaviour */); 2235 2289 } 2236 2290 … … 2879 2933 break; 2880 2934 2881 AssertCompile(RT_ELEMENTS(pXApicPage->irr.u) == 2 * RT_ELEMENTS(pPib->a VectorBitmap));2882 for (size_t idxPib = 0, idxReg = 0; idxPib < RT_ELEMENTS(pPib->a VectorBitmap); idxPib++, idxReg += 2)2883 { 2884 uint64_t const u64Fragment = ASMAtomicXchgU64(&pPib->a VectorBitmap[idxPib], 0);2935 AssertCompile(RT_ELEMENTS(pXApicPage->irr.u) == 2 * RT_ELEMENTS(pPib->au64VectorBitmap)); 2936 for (size_t idxPib = 0, idxReg = 0; idxPib < RT_ELEMENTS(pPib->au64VectorBitmap); idxPib++, idxReg += 2) 2937 { 2938 uint64_t const u64Fragment = ASMAtomicXchgU64(&pPib->au64VectorBitmap[idxPib], 0); 2885 2939 if (u64Fragment) 2886 2940 { … … 2906 2960 break; 2907 2961 2908 AssertCompile(RT_ELEMENTS(pXApicPage->irr.u) == 2 * RT_ELEMENTS(pPib->a VectorBitmap));2909 for (size_t idxPib = 0, idxReg = 0; idxPib < RT_ELEMENTS(pPib->a VectorBitmap); idxPib++, idxReg += 2)2910 { 2911 uint64_t const u64Fragment = ASMAtomicXchgU64(&pPib->a VectorBitmap[idxPib], 0);2962 AssertCompile(RT_ELEMENTS(pXApicPage->irr.u) == 2 * RT_ELEMENTS(pPib->au64VectorBitmap)); 2963 for (size_t idxPib = 0, idxReg = 0; idxPib < RT_ELEMENTS(pPib->au64VectorBitmap); idxPib++, idxReg += 2) 2964 { 2965 uint64_t const u64Fragment = ASMAtomicXchgU64(&pPib->au64VectorBitmap[idxPib], 0); 2912 2966 if (u64Fragment) 2913 2967 { … … 2948 3002 } 2949 3003 3004 3005 /** 3006 * Posts an interrupt to a target APIC, Hyper-V interface. 3007 * 3008 * @returns true if the interrupt was accepted, false otherwise. 3009 * @param pVCpu The cross context virtual CPU structure. 3010 * @param uVector The vector of the interrupt to be posted. 3011 * @param fAutoEoi Whether this interrupt has automatic EOI 3012 * treatment. 3013 * @param enmTriggerMode The trigger mode of the interrupt. 3014 * 3015 * @thread Any. 3016 */ 3017 VMM_INT_DECL(void) APICHvSendInterrupt(PVMCPU pVCpu, uint8_t uVector, bool fAutoEoi, XAPICTRIGGERMODE enmTriggerMode) 3018 { 3019 Assert(pVCpu); 3020 Assert(!fAutoEoi); /** @todo AutoEOI. */ 3021 apicPostInterrupt(pVCpu, uVector, enmTriggerMode); 3022 } 3023 3024 3025 /** 3026 * Sets the Task Priority Register (TPR), Hyper-V interface. 3027 * 3028 * @returns Strict VBox status code. 3029 * @param pVCpu The cross context virtual CPU structure. 3030 * @param uTpr The TPR value to set. 3031 * 3032 * @remarks Validates like in x2APIC mode. 3033 */ 3034 VMM_INT_DECL(VBOXSTRICTRC) APICHvSetTpr(PVMCPU pVCpu, uint8_t uTpr) 3035 { 3036 Assert(pVCpu); 3037 VMCPU_ASSERT_EMT(pVCpu); 3038 return apicSetTprEx(pVCpu, uTpr, true /* fForceX2ApicBehaviour */); 3039 } 3040 3041 3042 /** 3043 * Gets the Task Priority Register (TPR), Hyper-V interface. 3044 * 3045 * @returns The TPR value. 3046 * @param pVCpu The cross context virtual CPU structure. 3047 */ 3048 VMM_INT_DECL(uint8_t) APICHvGetTpr(PVMCPU pVCpu) 3049 { 3050 Assert(pVCpu); 3051 VMCPU_ASSERT_EMT(pVCpu); 3052 3053 /* 3054 * The APIC could be operating in xAPIC mode and thus we should not use the apicReadMsr() 3055 * interface which validates the APIC mode and will throw a #GP(0) if not in x2APIC mode. 3056 * We could use the apicReadRegister() MMIO interface, but why bother getting the PDMDEVINS 3057 * pointer, so just directly read the APIC page. 3058 */ 3059 PCXAPICPAGE pXApicPage = VMCPU_TO_CXAPICPAGE(pVCpu); 3060 return apicReadRaw32(pXApicPage, XAPIC_OFF_TPR); 3061 } 3062 3063 3064 /** 3065 * Sets the Interrupt Command Register (ICR), Hyper-V interface. 3066 * 3067 * @returns Strict VBox status code. 3068 * @param pVCpu The cross context virtual CPU structure. 3069 * @param uIcr The ICR value to set. 3070 */ 3071 VMM_INT_DECL(VBOXSTRICTRC) APICHvSetIcr(PVMCPU pVCpu, uint64_t uIcr) 3072 { 3073 Assert(pVCpu); 3074 VMCPU_ASSERT_EMT(pVCpu); 3075 return apicSetIcr(pVCpu, uIcr, VINF_CPUM_R3_MSR_WRITE); 3076 } 3077 3078 3079 /** 3080 * Gets the Interrupt Command Register (ICR), Hyper-V interface. 3081 * 3082 * @returns The ICR value. 3083 * @param pVCpu The cross context virtual CPU structure. 3084 */ 3085 VMM_INT_DECL(uint64_t) APICHvGetIcr(PVMCPU pVCpu) 3086 { 3087 Assert(pVCpu); 3088 VMCPU_ASSERT_EMT(pVCpu); 3089 return apicGetIcrNoCheck(pVCpu); 3090 } 3091 3092 3093 /** 3094 * Sets the End-Of-Interrupt (EOI) register, Hyper-V interface. 3095 * 3096 * @returns Strict VBox status code. 3097 * @param pVCpu The cross context virtual CPU structure. 3098 * @param uEoi The EOI value. 3099 */ 3100 VMM_INT_DECL(VBOXSTRICTRC) APICHvSetEoi(PVMCPU pVCpu, uint32_t uEoi) 3101 { 3102 Assert(pVCpu); 3103 VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu); 3104 return apicSetEoi(pVCpu, uEoi, true /* fForceX2ApicBehaviour */); 3105 } 3106 -
trunk/src/VBox/VMM/VMMR3/APIC.cpp
r62658 r63632 355 355 356 356 /** 357 * Sets whether Hyper-V compatibile x2APIC mode is enabled or not. 358 * 359 * @param pVM The cross context VM structure. 360 * @param fHyperVCompatMode Whether the compatibility mode is enabled. 361 */ 362 VMMR3_INT_DECL(void) APICR3HvSetCompatMode(PVM pVM, bool fHyperVCompatMode) 363 { 364 Assert(pVM); 365 PAPIC pApic = VM_TO_APIC(pVM); 366 pApic->fHyperVCompatMode = fHyperVCompatMode; 367 } 368 369 370 /** 357 371 * Helper for dumping an APIC 256-bit sparse register. 358 372 * … … 413 427 RT_ZERO(ApicReg); 414 428 ssize_t const cFragmentsDst = RT_ELEMENTS(ApicReg.u); 415 ssize_t const cFragmentsSrc = RT_ELEMENTS(pApicPib->a VectorBitmap);416 AssertCompile(RT_ELEMENTS(ApicReg.u) == 2 * RT_ELEMENTS(pApicPib->a VectorBitmap));429 ssize_t const cFragmentsSrc = RT_ELEMENTS(pApicPib->au64VectorBitmap); 430 AssertCompile(RT_ELEMENTS(ApicReg.u) == 2 * RT_ELEMENTS(pApicPib->au64VectorBitmap)); 417 431 for (ssize_t idxPib = cFragmentsSrc - 1, idxReg = cFragmentsDst - 1; idxPib >= 0; idxPib--, idxReg -= 2) 418 432 { 419 uint64_t const uFragment = pApicPib->a VectorBitmap[idxPib];433 uint64_t const uFragment = pApicPib->au64VectorBitmap[idxPib]; 420 434 uint32_t const uFragmentLo = RT_LO_U32(uFragment); 421 435 uint32_t const uFragmentHi = RT_HI_U32(uFragment); … … 1832 1846 APIC_REG_COUNTER(&pApicCpu->StatIcrLoWrite, "Number of times the ICR Lo (send IPI) is written.", 1833 1847 "/Devices/APIC/%u/IcrLoWrite"); 1848 APIC_REG_COUNTER(&pApicCpu->StatIcrHiWrite, "Number of times the ICR Hi is written.", 1849 "/Devices/APIC/%u/IcrHiWrite"); 1850 APIC_REG_COUNTER(&pApicCpu->StatIcrFullWrite, "Number of times the ICR full (send IPI, x2APIC) is written.", 1851 "/Devices/APIC/%u/IcrFullWrite"); 1834 1852 } 1835 1853 # undef APIC_PROF_COUNTER -
trunk/src/VBox/VMM/include/APICInternal.h
r62019 r63632 63 63 & (MSR_IA32_APICBASE_EN | MSR_IA32_APICBASE_EXTD)) \ 64 64 == (MSR_IA32_APICBASE_EN | MSR_IA32_APICBASE_EXTD) ) 65 65 66 /** Get an xAPIC page offset for an x2APIC MSR value. */ 66 67 #define X2APIC_GET_XAPIC_OFF(a_uMsr) ((((a_uMsr) - MSR_IA32_X2APIC_START) << 4) & UINT32_C(0xff0)) … … 1066 1067 /** @} */ 1067 1068 1068 /** @name xAPIC Interrupt Command Register bits.1069 * See Intel spec. 10.6.1 "Interrupt Command Register (ICR)".1070 * See Intel spec. 10.5.1 "Local Vector Table".1071 * @{ */1072 /**1073 * xAPIC trigger mode.1074 */1075 typedef enum XAPICTRIGGERMODE1076 {1077 XAPICTRIGGERMODE_EDGE = 0,1078 XAPICTRIGGERMODE_LEVEL1079 } XAPICTRIGGERMODE;1080 1081 1069 /** 1082 1070 * xAPIC destination shorthand. … … 1123 1111 /** @} */ 1124 1112 1113 /** @def APIC_CACHE_LINE_SIZE 1114 * Padding (in bytes) for aligning data in different cache lines. Present 1115 * generation x86 CPUs use 64-byte cache lines[1]. However, Intel NetBurst 1116 * architecture supposedly uses 128-byte cache lines[2]. Since 128 is a 1117 * multiple of 64, we use the larger one here. 1118 * 1119 * [1] - Intel spec "Table 11-1. Characteristics of the Caches, TLBs, Store 1120 * Buffer, and Write Combining Buffer in Intel 64 and IA-32 Processors" 1121 * [2] - Intel spec. 8.10.6.7 "Place Locks and Semaphores in Aligned, 128-Byte 1122 * Blocks of Memory". 1123 */ 1124 #define APIC_CACHE_LINE_SIZE 128 1125 1125 1126 /** 1126 1127 * APIC Pending-Interrupt Bitmap (PIB). … … 1128 1129 typedef struct APICPIB 1129 1130 { 1130 uint64_t volatile a VectorBitmap[4];1131 uint64_t volatile au64VectorBitmap[4]; 1131 1132 uint32_t volatile fOutstandingNotification; 1132 uint8_t au8Reserved[ 28];1133 uint8_t au8Reserved[APIC_CACHE_LINE_SIZE - sizeof(uint32_t) - (sizeof(uint64_t) * 4)]; 1133 1134 } APICPIB; 1134 1135 AssertCompileMemberOffset(APICPIB, fOutstandingNotification, 256 / 8); 1135 AssertCompileSize(APICPIB, 64);1136 AssertCompileSize(APICPIB, APIC_CACHE_LINE_SIZE); 1136 1137 /** Pointer to a pending-interrupt bitmap. */ 1137 1138 typedef APICPIB *PAPICPIB; … … 1167 1168 PCPDMAPICHLPRC pApicHlpRC; 1168 1169 /** The PDM critical section - RC Ptr. */ 1169 RCPTRTYPE(PPDMCRITSECT) pCritSectRC;1170 RCPTRTYPE(PPDMCRITSECT) pCritSectRC; 1170 1171 /** Alignment padding. */ 1171 1172 RCPTRTYPE(void *) pvAlignment2; … … 1227 1228 /** Whether RZ is enabled or not (applies to MSR handling as well). */ 1228 1229 bool fRZEnabled; 1230 /** Whether Hyper-V x2APIC compatibility mode is enabled. */ 1231 bool fHyperVCompatMode; 1229 1232 /** Alignment padding. */ 1230 bool afAlignment 0[7];1233 bool afAlignment[2]; 1231 1234 /** The max supported APIC mode from CFGM. */ 1232 1235 PDMAPICMODE enmMaxMode; 1236 /** Alignment padding. */ 1237 uint32_t u32Alignment1; 1233 1238 /** @} */ 1234 1239 } APIC; … … 1237 1242 /** Pointer to const APIC VM instance data. */ 1238 1243 typedef APIC const *PCAPIC; 1244 AssertCompileMemberAlignment(APIC, cbApicPib, 8); 1245 AssertCompileMemberAlignment(APIC, fVirtApicRegsEnabled, 8); 1246 AssertCompileMemberAlignment(APIC, enmMaxMode, 8); 1247 AssertCompileSizeAlignment(APIC, 8); 1239 1248 1240 1249 /** … … 1285 1294 /** The APIC PIB for level-sensitive interrupts. */ 1286 1295 APICPIB ApicPibLevel; 1296 /** @} */ 1297 1298 /** @name Other miscellaneous data. 1299 * @{ */ 1287 1300 /** Whether the LINT0 interrupt line is active. */ 1288 1301 bool volatile fActiveLint0; … … 1361 1374 /** Number of times the ICR Lo (send IPI) is written. */ 1362 1375 STAMCOUNTER StatIcrLoWrite; 1376 /** Number of times the ICR Hi is written. */ 1377 STAMCOUNTER StatIcrHiWrite; 1378 /** Number of times the full ICR (x2APIC send IPI) is written. */ 1379 STAMCOUNTER StatIcrFullWrite; 1363 1380 /** @} */ 1364 1381 #endif
Note:
See TracChangeset
for help on using the changeset viewer.

