1212#include "kvm_util.h"
1313#include "processor.h"
1414
15- /* CPUIDs known to differ */
16- struct {
17- u32 function ;
18- u32 index ;
19- } mangled_cpuids [] = {
20- /*
21- * These entries depend on the vCPU's XCR0 register and IA32_XSS MSR,
22- * which are not controlled for by this test.
23- */
24- {.function = 0xd , .index = 0 },
25- {.function = 0xd , .index = 1 },
15+ struct cpuid_mask {
16+ union {
17+ struct {
18+ u32 eax ;
19+ u32 ebx ;
20+ u32 ecx ;
21+ u32 edx ;
22+ };
23+ u32 regs [4 ];
24+ };
2625};
2726
2827static void test_guest_cpuids (struct kvm_cpuid2 * guest_cpuid )
@@ -56,17 +55,29 @@ static void guest_main(struct kvm_cpuid2 *guest_cpuid)
5655 GUEST_DONE ();
5756}
5857
59- static bool is_cpuid_mangled (const struct kvm_cpuid_entry2 * entrie )
58+ static struct cpuid_mask get_const_cpuid_mask (const struct kvm_cpuid_entry2 * entry )
6059{
61- int i ;
62-
63- for (i = 0 ; i < ARRAY_SIZE (mangled_cpuids ); i ++ ) {
64- if (mangled_cpuids [i ].function == entrie -> function &&
65- mangled_cpuids [i ].index == entrie -> index )
66- return true;
60+ struct cpuid_mask mask ;
61+
62+ memset (& mask , 0xff , sizeof (mask ));
63+
64+ switch (entry -> function ) {
65+ case 0x1 :
66+ mask .regs [X86_FEATURE_OSXSAVE .reg ] &= ~BIT (X86_FEATURE_OSXSAVE .bit );
67+ break ;
68+ case 0x7 :
69+ mask .regs [X86_FEATURE_OSPKE .reg ] &= ~BIT (X86_FEATURE_OSPKE .bit );
70+ break ;
71+ case 0xd :
72+ /*
73+ * CPUID.0xD.{0,1}.EBX enumerate XSAVE size based on the current
74+ * XCR0 and IA32_XSS MSR values.
75+ */
76+ if (entry -> index < 2 )
77+ mask .ebx = 0 ;
78+ break ;
6779 }
68-
69- return false;
80+ return mask ;
7081}
7182
7283static void compare_cpuids (const struct kvm_cpuid2 * cpuid1 ,
@@ -79,6 +90,8 @@ static void compare_cpuids(const struct kvm_cpuid2 *cpuid1,
7990 "CPUID nent mismatch: %d vs. %d" , cpuid1 -> nent , cpuid2 -> nent );
8091
8192 for (i = 0 ; i < cpuid1 -> nent ; i ++ ) {
93+ struct cpuid_mask mask ;
94+
8295 e1 = & cpuid1 -> entries [i ];
8396 e2 = & cpuid2 -> entries [i ];
8497
@@ -88,15 +101,19 @@ static void compare_cpuids(const struct kvm_cpuid2 *cpuid1,
88101 i , e1 -> function , e1 -> index , e1 -> flags ,
89102 e2 -> function , e2 -> index , e2 -> flags );
90103
91- if ( is_cpuid_mangled ( e1 ))
92- continue ;
104+ /* Mask off dynamic bits, e.g. OSXSAVE, when comparing entries. */
105+ mask = get_const_cpuid_mask ( e1 ) ;
93106
94- TEST_ASSERT (e1 -> eax == e2 -> eax && e1 -> ebx == e2 -> ebx &&
95- e1 -> ecx == e2 -> ecx && e1 -> edx == e2 -> edx ,
107+ TEST_ASSERT ((e1 -> eax & mask .eax ) == (e2 -> eax & mask .eax ) &&
108+ (e1 -> ebx & mask .ebx ) == (e2 -> ebx & mask .ebx ) &&
109+ (e1 -> ecx & mask .ecx ) == (e2 -> ecx & mask .ecx ) &&
110+ (e1 -> edx & mask .edx ) == (e2 -> edx & mask .edx ),
96111 "CPUID 0x%x.%x differ: 0x%x:0x%x:0x%x:0x%x vs 0x%x:0x%x:0x%x:0x%x" ,
97112 e1 -> function , e1 -> index ,
98- e1 -> eax , e1 -> ebx , e1 -> ecx , e1 -> edx ,
99- e2 -> eax , e2 -> ebx , e2 -> ecx , e2 -> edx );
113+ e1 -> eax & mask .eax , e1 -> ebx & mask .ebx ,
114+ e1 -> ecx & mask .ecx , e1 -> edx & mask .edx ,
115+ e2 -> eax & mask .eax , e2 -> ebx & mask .ebx ,
116+ e2 -> ecx & mask .ecx , e2 -> edx & mask .edx );
100117 }
101118}
102119
0 commit comments