uint64_t valid_xstate_leaves = 0;
uint32_t max_leaf = 0, max_l7_subleaf = 0,
max_hv_leaf = 0, max_hv2_leaf = 0, max_extd_leaf = 0;
+ uint32_t xen_first_leaf = ~0, xen_last_leaf = 0;
for ( ;; )
{
case 0x40000000U:
max_hv_leaf = eax;
+
+ if ( ebx == XEN_CPUID_SIGNATURE_EBX &&
+ ecx == XEN_CPUID_SIGNATURE_ECX &&
+ edx == XEN_CPUID_SIGNATURE_EDX )
+ {
+ xen_first_leaf = leaf;
+ xen_last_leaf = eax;
+ }
+
break;
case 0x40000100U:
max_hv2_leaf = eax;
+
+ if ( ebx == XEN_CPUID_SIGNATURE_EBX &&
+ ecx == XEN_CPUID_SIGNATURE_ECX &&
+ edx == XEN_CPUID_SIGNATURE_EDX )
+ {
+ xen_first_leaf = leaf;
+ xen_last_leaf = eax;
+ }
+
break;
case 0x80000000U:
break;
}
+ if ( leaf >= xen_first_leaf && leaf <= xen_last_leaf )
+ {
+ /* The Xen leaves have no documented identification of max leaf. */
+
+ switch ( leaf - xen_first_leaf )
+ {
+ case 3:
+ if ( subleaf < 2 ) /* Max leaf hardcoded. */
+ {
+ subleaf++;
+ continue;
+ }
+ break;
+
+ case 4: /* Leaf semantics, but ??? */
+ break;
+ }
+ }
+
leaf++;
if ( (leaf > 0) && (leaf < 0x40000000U) && (leaf > max_leaf) )
leaf = 0x40000000U;
break;
subleaf = ~0;
- if ( leaf == 4 || leaf == 7 || leaf == 0xd )
+ if ( leaf == 4 || leaf == 7 || leaf == 0xd ||
+ ((leaf >= xen_first_leaf && leaf <= xen_last_leaf) &&
+ ((leaf - xen_first_leaf) == 3 || (leaf - xen_first_leaf) == 4)) )
subleaf = 0;
}
}