@@ -634,12 +634,19 @@ static const struct cpu_feature_t features [] = {
634634/* { 0x40000003, 0, REG_EDX, 0x80000000, , ""}, */ /* Reserved */
635635
636636/* Hypervisor implementation recommendations (4000_0004h) */
637+ { 0x40000004 , 0 , REG_EAX , 0x00000001 , VENDOR_HV_XEN , "Virtualized APIC registers" },
637638 { 0x40000004 , 0 , REG_EAX , 0x00000001 , VENDOR_HV_HYPERV , "Hypercall for address space switches" },
639+ { 0x40000004 , 0 , REG_EAX , 0x00000002 , VENDOR_HV_XEN , "Virtualized x2APIC accesses" },
638640 { 0x40000004 , 0 , REG_EAX , 0x00000002 , VENDOR_HV_HYPERV , "Hypercall for local TLB flushes" },
641+ { 0x40000004 , 0 , REG_EAX , 0x00000004 , VENDOR_HV_XEN , "IOMMU mappings" },
639642 { 0x40000004 , 0 , REG_EAX , 0x00000004 , VENDOR_HV_HYPERV , "Hypercall for remote TLB flushes" },
643+ { 0x40000004 , 0 , REG_EAX , 0x00000008 , VENDOR_HV_XEN , "VCPU ID present in 40000004:EBX" },
640644 { 0x40000004 , 0 , REG_EAX , 0x00000008 , VENDOR_HV_HYPERV , "MSRs for accessing APIC registers" },
645+ { 0x40000004 , 0 , REG_EAX , 0x00000010 , VENDOR_HV_XEN , "Domain ID present in 40000004:ECX" },
641646 { 0x40000004 , 0 , REG_EAX , 0x00000010 , VENDOR_HV_HYPERV , "Hypervisor MSR for system RESET" },
647+ { 0x40000004 , 0 , REG_EAX , 0x00000020 , VENDOR_HV_XEN , "Extended APIC destination ID" },
642648 { 0x40000004 , 0 , REG_EAX , 0x00000020 , VENDOR_HV_HYPERV , "Relaxed timing" },
649+ { 0x40000004 , 0 , REG_EAX , 0x00000040 , VENDOR_HV_XEN , "Per-vCPU event channel upcalls with PIRQs" },
643650 { 0x40000004 , 0 , REG_EAX , 0x00000040 , VENDOR_HV_HYPERV , "DMA remapping" },
644651 { 0x40000004 , 0 , REG_EAX , 0x00000080 , VENDOR_HV_HYPERV , "Interrupt remapping" },
645652 { 0x40000004 , 0 , REG_EAX , 0x00000100 , VENDOR_HV_HYPERV , "x2APIC MSRs" },
@@ -1312,16 +1319,26 @@ int print_features(const struct cpu_regs_t *regs, struct cpuid_state_t *state)
13121319 reg_name (last_reg ));
13131320 break ;
13141321 case 0x40000004 :
1315- printf ("Hyper-V implementation recommendations, %s:\n" ,
1316- reg_name (last_reg ));
1322+ if (state -> vendor & VENDOR_HV_XEN ) {
1323+ printf ("Xen HVM-specific features, %s:\n" , reg_name (last_reg ));
1324+
1325+ /* We only look at EAX for this leaf. */
1326+ accounting .ebx = 0 ;
1327+ accounting .ecx = 0 ;
1328+ accounting .edx = 0 ;
1329+ } else if (state -> vendor & VENDOR_HV_HYPERV ) {
1330+ printf ("Hyper-V implementation recommendations, %s:\n" ,
1331+ reg_name (last_reg ));
13171332
1318- /* EBX doesn't contain feature bits. We should zero these
1319- * out so they don't appear to be unaccounted for.
1320- */
1321- accounting .ebx = 0 ;
1333+ /* EBX doesn't contain feature bits. We should zero these
1334+ * out so they don't appear to be unaccounted for.
1335+ */
1336+ accounting .ebx = 0 ;
1337+
1338+ /* ECX[0:6] are not feature bits. */
1339+ accounting .ecx &= ~0x3f ;
1340+ }
13221341
1323- /* ECX[0:6] are not feature bits. */
1324- accounting .ecx &= ~0x3f ;
13251342 break ;
13261343 case 0x40000006 :
13271344 printf ("Hyper-V hardware features detected and in use, %s:\n" ,
0 commit comments