Index: /trunk/include/VBox/vmm/cpum.h
===================================================================
--- /trunk/include/VBox/vmm/cpum.h	(revision 55061)
+++ /trunk/include/VBox/vmm/cpum.h	(revision 55062)
@@ -1219,5 +1219,5 @@
 VMMR3DECL(uint32_t)     CPUMR3RemEnter(PVMCPU pVCpu, uint32_t *puCpl);
 VMMR3DECL(void)         CPUMR3RemLeave(PVMCPU pVCpu, bool fNoOutOfSyncSels);
-VMMDECL(bool)           CPUMSupportsFXSR(PVM pVM);
+VMMDECL(bool)           CPUMSupportsXSave(PVM pVM);
 VMMDECL(bool)           CPUMIsHostUsingSysEnter(PVM pVM);
 VMMDECL(bool)           CPUMIsHostUsingSysCall(PVM pVM);
Index: /trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp	(revision 55061)
+++ /trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp	(revision 55062)
@@ -746,6 +746,4 @@
         pVCpu->cpum.s.fChanged |= CPUM_CHANGED_GLOBAL_TLB_FLUSH;
     pVCpu->cpum.s.fChanged |= CPUM_CHANGED_CR4;
-    if (!CPUMSupportsFXSR(pVCpu->CTX_SUFF(pVM)))
-        cr4 &= ~X86_CR4_OSFXSR;
     pVCpu->cpum.s.Guest.cr4 = cr4;
     return VINF_SUCCESS;
@@ -2480,12 +2478,13 @@
 
 /**
- * Checks if the CPU supports the FXSAVE and FXRSTOR instruction.
+ * Checks if the CPU supports the XSAVE and XRSTOR instruction.
+ *
  * @returns true if supported.
  * @returns false if not supported.
  * @param   pVM     Pointer to the VM.
  */
-VMMDECL(bool) CPUMSupportsFXSR(PVM pVM)
-{
-    return pVM->cpum.s.CPUFeatures.edx.u1FXSR != 0;
+VMMDECL(bool) CPUMSupportsXSave(PVM pVM)
+{
+    return pVM->cpum.s.HostFeatures.fXSaveRstor != 0;
 }
 
Index: /trunk/src/VBox/VMM/VMMR0/CPUMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/CPUMR0.cpp	(revision 55061)
+++ /trunk/src/VBox/VMM/VMMR0/CPUMR0.cpp	(revision 55062)
@@ -339,5 +339,5 @@
 VMMR0_INT_DECL(int) CPUMR0Trap07Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
 {
-    Assert(pVM->cpum.s.CPUFeatures.edx.u1FXSR);
+    Assert(pVM->cpum.s.HostFeatures.fFxSaveRstor);
     Assert(ASMGetCR4() & X86_CR4_OSFXSR);
 
@@ -399,5 +399,4 @@
 VMMR0_INT_DECL(int) CPUMR0LoadGuestFPU(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
 {
-
     Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
 #if HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
@@ -423,5 +422,5 @@
         uint64_t uHostEfer    = 0;
         bool     fRestoreEfer = false;
-        if (pVM->cpum.s.CPUFeaturesExt.edx & X86_CPUID_AMD_FEATURE_EDX_FFXSR)
+        if (pVM->cpum.s.HostFeatures.fLeakyFxSR)
         {
             /** @todo r=ramshankar: Can't we used a cached value here
@@ -460,5 +459,5 @@
 VMMR0_INT_DECL(int) CPUMR0SaveGuestFPU(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
 {
-    Assert(pVM->cpum.s.CPUFeatures.edx.u1FXSR);
+    Assert(pVM->cpum.s.HostFeatures.fFxSaveRstor);
     Assert(ASMGetCR4() & X86_CR4_OSFXSR);
     AssertReturn((pVCpu->cpum.s.fUseFlags & CPUM_USED_FPU), VINF_SUCCESS);
Index: /trunk/src/VBox/VMM/VMMR3/CPUM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/CPUM.cpp	(revision 55061)
+++ /trunk/src/VBox/VMM/VMMR3/CPUM.cpp	(revision 55062)
@@ -640,10 +640,6 @@
         return VMSetError(pVM, VERR_UNSUPPORTED_CPU, RT_SRC_POS, "Host CPU does not support RDTSC.");
 
-    /* Bogus on AMD? */
-    if (!pVM->cpum.s.CPUFeatures.edx.u1SEP)
-        Log(("The CPU doesn't support SYSENTER/SYSEXIT!\n"));
-
-    /*
-     * Setup the CR4 AND and OR masks used in the switcher
+    /*
+     * Setup the CR4 AND and OR masks used in the raw-mode switcher.
      */
     pVM->cpum.s.CR4.AndMask = X86_CR4_OSXMMEEXCPT | X86_CR4_PVI | X86_CR4_VME;
@@ -653,6 +649,8 @@
      * Allocate memory for the extended CPU state.
      */
-    uint32_t cbMaxXState = sizeof(X86FXSTATE);
+    uint32_t cbMaxXState = pVM->cpum.s.HostFeatures.cbMaxExtendedState;
     cbMaxXState = RT_ALIGN(cbMaxXState, 128);
+    AssertLogRelReturn(cbMaxXState >= sizeof(X86FXSTATE) && cbMaxXState <= _8K, VERR_CPUM_IPE_2);
+
     uint8_t *pbXStates;
     rc = MMR3HyperAllocOnceNoRelEx(pVM, cbMaxXState * 3 * pVM->cCpus, PAGE_SIZE, MM_TAG_CPUM_CTX,
Index: /trunk/src/VBox/VMM/VMMR3/CPUMDbg.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/CPUMDbg.cpp	(revision 55061)
+++ /trunk/src/VBox/VMM/VMMR3/CPUMDbg.cpp	(revision 55062)
@@ -239,21 +239,4 @@
 
 /**
- * Is the FPU state in FXSAVE format or not.
- *
- * @returns true if it is, false if it's in FNSAVE.
- * @param   pVCpu               Pointer to the VMCPU.
- */
-DECLINLINE(bool) cpumR3RegIsFxSaveFormat(PVMCPU pVCpu)
-{
-#ifdef RT_ARCH_AMD64
-    NOREF(pVCpu);
-    return true;
-#else
-    return pVCpu->pVMR3->cpum.s.CPUFeatures.edx.u1FXSR;
-#endif
-}
-
-
-/**
  * Determins the tag register value for a CPU register when the FPU state
  * format is FXSAVE.
@@ -300,18 +283,12 @@
     Assert(pDesc->enmType == DBGFREGVALTYPE_U16);
 
-    if (cpumR3RegIsFxSaveFormat(pVCpu))
-        pValue->u16 =  cpumR3RegCalcFpuTagFromFxSave(pFpu, 0)
-                    | (cpumR3RegCalcFpuTagFromFxSave(pFpu, 1) <<  2)
-                    | (cpumR3RegCalcFpuTagFromFxSave(pFpu, 2) <<  4)
-                    | (cpumR3RegCalcFpuTagFromFxSave(pFpu, 3) <<  6)
-                    | (cpumR3RegCalcFpuTagFromFxSave(pFpu, 4) <<  8)
-                    | (cpumR3RegCalcFpuTagFromFxSave(pFpu, 5) << 10)
-                    | (cpumR3RegCalcFpuTagFromFxSave(pFpu, 6) << 12)
-                    | (cpumR3RegCalcFpuTagFromFxSave(pFpu, 7) << 14);
-    else
-    {
-        PCX86FPUSTATE pOldFpu = (PCX86FPUSTATE)pFpu;
-        pValue->u16 = pOldFpu->FTW;
-    }
+    pValue->u16 =  cpumR3RegCalcFpuTagFromFxSave(pFpu, 0)
+                | (cpumR3RegCalcFpuTagFromFxSave(pFpu, 1) <<  2)
+                | (cpumR3RegCalcFpuTagFromFxSave(pFpu, 2) <<  4)
+                | (cpumR3RegCalcFpuTagFromFxSave(pFpu, 3) <<  6)
+                | (cpumR3RegCalcFpuTagFromFxSave(pFpu, 4) <<  8)
+                | (cpumR3RegCalcFpuTagFromFxSave(pFpu, 5) << 10)
+                | (cpumR3RegCalcFpuTagFromFxSave(pFpu, 6) << 12)
+                | (cpumR3RegCalcFpuTagFromFxSave(pFpu, 7) << 14);
     return VINF_SUCCESS;
 }
@@ -620,20 +597,8 @@
 
     PX86FXSTATE pFpuCtx = &pVCpu->cpum.s.Guest.CTX_SUFF(pXState)->x87;
-    if (cpumR3RegIsFxSaveFormat(pVCpu))
-    {
-        unsigned iReg = (pFpuCtx->FSW >> 11) & 7;
-        iReg += pDesc->offRegister;
-        iReg &= 7;
-        pValue->r80Ex = pFpuCtx->aRegs[iReg].r80Ex;
-    }
-    else
-    {
-        PCX86FPUSTATE pOldFpuCtx = (PCX86FPUSTATE)pFpuCtx;
-
-        unsigned iReg = (pOldFpuCtx->FSW >> 11) & 7;
-        iReg += pDesc->offRegister;
-        iReg &= 7;
-        pValue->r80Ex = pOldFpuCtx->regs[iReg].r80Ex;
-    }
+    unsigned iReg = (pFpuCtx->FSW >> 11) & 7;
+    iReg += pDesc->offRegister;
+    iReg &= 7;
+    pValue->r80Ex = pFpuCtx->aRegs[iReg].r80Ex;
 
     return VINF_SUCCESS;
Index: /trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp	(revision 55061)
+++ /trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp	(revision 55062)
@@ -1501,4 +1501,25 @@
 
 
+static PCCPUMCPUIDLEAF cpumR3CpuIdFindLeafEx(PCCPUMCPUIDLEAF paLeaves, uint32_t cLeaves, uint32_t uLeaf, uint32_t uSubLeaf)
+{
+    PCCPUMCPUIDLEAF pLeaf = cpumR3CpuIdFindLeaf(paLeaves, cLeaves, uLeaf);
+    if (   !pLeaf
+        || pLeaf->uSubLeaf != (uSubLeaf & pLeaf->fSubLeafMask))
+        return pLeaf;
+
+    /* Linear sub-leaf search. Lazy as usual. */
+    cLeaves = pLeaf - paLeaves;
+    while (   cLeaves-- > 0
+           && pLeaf->uLeaf == uLeaf)
+    {
+        if (pLeaf->uSubLeaf == (uSubLeaf & pLeaf->fSubLeafMask))
+            return pLeaf;
+        pLeaf++;
+    }
+
+    return NULL;
+}
+
+
 int cpumR3CpuIdExplodeFeatures(PCCPUMCPUIDLEAF paLeaves, uint32_t cLeaves, PCPUMFEATURES pFeatures)
 {
@@ -1538,9 +1559,25 @@
         pFeatures->fPat                 = RT_BOOL(paLeaves[1].uEdx & X86_CPUID_FEATURE_EDX_PAT);
         pFeatures->fFxSaveRstor         = RT_BOOL(paLeaves[1].uEdx & X86_CPUID_FEATURE_EDX_FXSR);
+        pFeatures->fXSaveRstor          = RT_BOOL(paLeaves[1].uEcx & X86_CPUID_FEATURE_ECX_XSAVE);
         pFeatures->fMmx                 = RT_BOOL(paLeaves[1].uEdx & X86_CPUID_FEATURE_EDX_MMX);
+        pFeatures->fSse                 = RT_BOOL(paLeaves[1].uEdx & X86_CPUID_FEATURE_EDX_SSE);
+        pFeatures->fSse2                = RT_BOOL(paLeaves[1].uEdx & X86_CPUID_FEATURE_EDX_SSE2);
+        pFeatures->fSse3                = RT_BOOL(paLeaves[1].uEcx & X86_CPUID_FEATURE_ECX_SSE3);
+        pFeatures->fSsse3               = RT_BOOL(paLeaves[1].uEcx & X86_CPUID_FEATURE_ECX_SSSE3);
+        pFeatures->fSse41               = RT_BOOL(paLeaves[1].uEcx & X86_CPUID_FEATURE_ECX_SSE4_1);
+        pFeatures->fSse42               = RT_BOOL(paLeaves[1].uEcx & X86_CPUID_FEATURE_ECX_SSE4_2);
+        pFeatures->fAvx                 = RT_BOOL(paLeaves[1].uEcx & X86_CPUID_FEATURE_ECX_AVX);
         pFeatures->fTsc                 = RT_BOOL(paLeaves[1].uEdx & X86_CPUID_FEATURE_EDX_TSC);
         pFeatures->fSysEnter            = RT_BOOL(paLeaves[1].uEdx & X86_CPUID_FEATURE_EDX_SEP);
         pFeatures->fHypervisorPresent   = RT_BOOL(paLeaves[1].uEcx & X86_CPUID_FEATURE_ECX_HVP);
         pFeatures->fMonitorMWait        = RT_BOOL(paLeaves[1].uEcx & X86_CPUID_FEATURE_ECX_MONITOR);
+
+        /* Structured extended features. */
+        PCCPUMCPUIDLEAF const pSxfLeaf0 = cpumR3CpuIdFindLeafEx(paLeaves, cLeaves, 7, 0);
+        if (pSxfLeaf0)
+        {
+            pFeatures->fAvx2                = RT_BOOL(pSxfLeaf0->uEcx & X86_CPUID_STEXT_FEATURE_EBX_AVX2);
+            pFeatures->fAvx512Foundation    = RT_BOOL(pSxfLeaf0->uEcx & X86_CPUID_STEXT_FEATURE_EBX_AVX512F);
+        }
 
         /* MWAIT/MONITOR leaf. */
@@ -1585,4 +1622,31 @@
                              && pFeatures->enmCpuVendor == CPUMCPUVENDOR_AMD
                              && pFeatures->uFamily >= 6 /* K7 and up */;
+
+        /*
+         * Max extended (/FPU) state.
+         */
+        pFeatures->cbMaxExtendedState = pFeatures->fFxSaveRstor ? sizeof(X86FXSTATE) : sizeof(X86FPUSTATE);
+        if (pFeatures->fXSaveRstor)
+        {
+            PCCPUMCPUIDLEAF const pXStateLeaf0 = cpumR3CpuIdFindLeafEx(paLeaves, cLeaves, 13, 0);
+            if (pXStateLeaf0)
+            {
+                if (   pXStateLeaf0->uEcx >= sizeof(X86FXSTATE)
+                    && pXStateLeaf0->uEcx <= _8K
+                    && RT_ALIGN_32(pXStateLeaf0->uEcx, 8) == pXStateLeaf0->uEcx
+                    && pXStateLeaf0->uEbx >= sizeof(X86FXSTATE)
+                    && pXStateLeaf0->uEbx <= pXStateLeaf0->uEcx
+                    && RT_ALIGN_32(pXStateLeaf0->uEbx, 8) == pXStateLeaf0->uEbx)
+                {
+                    pFeatures->cbMaxExtendedState = pXStateLeaf0->uEcx;
+                }
+                else
+                    AssertLogRelMsgFailedStmt(("Unexpected max/cur XSAVE area sizes: %#x/%#x\n", pXStateLeaf0->uEcx, pXStateLeaf0->uEbx),
+                                              pFeatures->fXSaveRstor = 0);
+            }
+            else
+                AssertLogRelMsgFailedStmt(("Expected leaf eax=0xd/ecx=0 with the XSAVE/XRSTOR feature!\n"),
+                                          pFeatures->fXSaveRstor = 0);
+        }
     }
     else
Index: /trunk/src/VBox/VMM/VMMR3/VMMSwitcher.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/VMMSwitcher.cpp	(revision 55061)
+++ /trunk/src/VBox/VMM/VMMR3/VMMSwitcher.cpp	(revision 55062)
@@ -698,5 +698,5 @@
                 uint32_t offTrg = *u.pu32++;
                 Assert(offTrg < pSwitcher->cbCode);
-                if (!CPUMSupportsFXSR(pVM))
+                if (!CPUMSupportsXSave(pVM))
                 {
                     *uSrc.pu8++ = 0xe9; /* jmp rel32 */
Index: /trunk/src/VBox/VMM/include/CPUMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/CPUMInternal.h	(revision 55061)
+++ /trunk/src/VBox/VMM/include/CPUMInternal.h	(revision 55062)
@@ -172,5 +172,7 @@
     uint8_t         cMaxPhysAddrWidth;
     /** Alignment padding. */
-    uint8_t         abPadding[3];
+    uint8_t         abPadding[1];
+    /** Max size of the extended state (or FPU state if no XSAVE). */
+    uint16_t        cbMaxExtendedState;
 
     /** Supports MSRs. */
@@ -187,6 +189,26 @@
     /** Supports the FXSAVE and FXRSTOR instructions. */
     uint32_t        fFxSaveRstor : 1;
+    /** Supports the XSAVE and XRSTOR instructions. */
+    uint32_t        fXSaveRstor : 1;
     /** Supports MMX. */
     uint32_t        fMmx : 1;
+    /** Supports SSE. */
+    uint32_t        fSse : 1;
+    /** Supports SSE2. */
+    uint32_t        fSse2 : 1;
+    /** Supports SSE3. */
+    uint32_t        fSse3 : 1;
+    /** Supports SSSE3. */
+    uint32_t        fSsse3 : 1;
+    /** Supports SSE4.1. */
+    uint32_t        fSse41 : 1;
+    /** Supports SSE4.2. */
+    uint32_t        fSse42 : 1;
+    /** Supports AVX. */
+    uint32_t        fAvx : 1;
+    /** Supports AVX2. */
+    uint32_t        fAvx2 : 1;
+    /** Supports AVX512 foundation. */
+    uint32_t        fAvx512Foundation : 1;
     /** Supports RDTSC. */
     uint32_t        fTsc : 1;
@@ -220,7 +242,6 @@
     uint32_t        fLeakyFxSR : 1;
 
-    /** Alignment padding. */
-    uint32_t        fPadding : 12;
-
+    /** Alignment padding / reserved for future use. */
+    uint32_t        fPadding : 2;
     uint64_t        auPadding[2];
 } CPUMFEATURES;
@@ -469,21 +490,4 @@
     uint32_t                fHostUseFlags;
 
-    /** Host CPU Features - ECX */
-    struct
-    {
-        /** edx part */
-        X86CPUIDFEATEDX     edx;
-        /** ecx part */
-        X86CPUIDFEATECX     ecx;
-    } CPUFeatures;
-    /** Host extended CPU features. */
-    struct
-    {
-        /** edx part */
-        uint32_t            edx;
-        /** ecx part */
-        uint32_t            ecx;
-    } CPUFeaturesExt;
-
     /** CR4 mask */
     struct
Index: /trunk/src/VBox/VMM/include/CPUMInternal.mac
===================================================================
--- /trunk/src/VBox/VMM/include/CPUMInternal.mac	(revision 55061)
+++ /trunk/src/VBox/VMM/include/CPUMInternal.mac	(revision 55062)
@@ -78,12 +78,4 @@
     .offCPUMCPU0          resd    1
     .fHostUseFlags        resd    1
-
-    ; CPUID eax=1
-    .CPUFeatures.edx      resd    1
-    .CPUFeatures.ecx      resd    1
-
-    ; CPUID eax=0x80000001
-    .CPUFeaturesExt.edx   resd    1
-    .CPUFeaturesExt.ecx   resd    1
 
     ; CR4 masks
Index: /trunk/src/VBox/VMM/testcase/tstVMStruct.h
===================================================================
--- /trunk/src/VBox/VMM/testcase/tstVMStruct.h	(revision 55061)
+++ /trunk/src/VBox/VMM/testcase/tstVMStruct.h	(revision 55062)
@@ -29,7 +29,4 @@
     GEN_CHECK_OFF(CPUM, offCPUMCPU0);
     GEN_CHECK_OFF(CPUM, fHostUseFlags);
-    GEN_CHECK_OFF(CPUM, CPUFeatures);
-    GEN_CHECK_OFF(CPUM, CPUFeaturesExt);
-    GEN_CHECK_OFF(CPUM, CPUFeaturesExt);
     GEN_CHECK_OFF(CPUM, CR4);
 #ifndef VBOX_FOR_DTRACE_LIB
