@@ -26,18 +26,18 @@ static void guest_code(void)
26
26
{
27
27
}
28
28
29
- static int smt_possible (void )
29
+ static bool smt_possible (void )
30
30
{
31
31
char buf [16 ];
32
32
FILE * f ;
33
- bool res = 1 ;
33
+ bool res = true ;
34
34
35
35
f = fopen ("/sys/devices/system/cpu/smt/control" , "r" );
36
36
if (f ) {
37
37
if (fread (buf , sizeof (* buf ), sizeof (buf ), f ) > 0 ) {
38
38
if (!strncmp (buf , "forceoff" , 8 ) ||
39
39
!strncmp (buf , "notsupported" , 12 ))
40
- res = 0 ;
40
+ res = false ;
41
41
}
42
42
fclose (f );
43
43
}
@@ -46,29 +46,31 @@ static int smt_possible(void)
46
46
}
47
47
48
48
static void test_hv_cpuid (struct kvm_cpuid2 * hv_cpuid_entries ,
49
- int evmcs_enabled )
49
+ bool evmcs_enabled )
50
50
{
51
51
int i ;
52
+ int nent = 9 ;
53
+ u32 test_val ;
52
54
53
- if (!evmcs_enabled )
54
- TEST_ASSERT (hv_cpuid_entries -> nent == 6 ,
55
- "KVM_GET_SUPPORTED_HV_CPUID should return 6 entries"
56
- " when Enlightened VMCS is disabled (returned %d)" ,
57
- hv_cpuid_entries -> nent );
58
- else
59
- TEST_ASSERT (hv_cpuid_entries -> nent == 7 ,
60
- "KVM_GET_SUPPORTED_HV_CPUID should return 7 entries"
61
- " when Enlightened VMCS is enabled (returned %d)" ,
62
- hv_cpuid_entries -> nent );
55
+ if (evmcs_enabled )
56
+ nent += 1 ; /* 0x4000000A */
57
+
58
+ TEST_ASSERT (hv_cpuid_entries -> nent == nent ,
59
+ "KVM_GET_SUPPORTED_HV_CPUID should return %d entries"
60
+ " with evmcs=%d (returned %d)" ,
61
+ nent , evmcs_enabled , hv_cpuid_entries -> nent );
63
62
64
63
for (i = 0 ; i < hv_cpuid_entries -> nent ; i ++ ) {
65
64
struct kvm_cpuid_entry2 * entry = & hv_cpuid_entries -> entries [i ];
66
65
67
66
TEST_ASSERT ((entry -> function >= 0x40000000 ) &&
68
- (entry -> function <= 0x4000000A ),
67
+ (entry -> function <= 0x40000082 ),
69
68
"function %x is our of supported range" ,
70
69
entry -> function );
71
70
71
+ TEST_ASSERT (evmcs_enabled || (entry -> function != 0x4000000A ),
72
+ "0x4000000A leaf should not be reported" );
73
+
72
74
TEST_ASSERT (entry -> index == 0 ,
73
75
".index field should be zero" );
74
76
@@ -78,12 +80,23 @@ static void test_hv_cpuid(struct kvm_cpuid2 *hv_cpuid_entries,
78
80
TEST_ASSERT (!entry -> padding [0 ] && !entry -> padding [1 ] &&
79
81
!entry -> padding [2 ], "padding should be zero" );
80
82
81
- if (entry -> function == 0x40000004 ) {
82
- int nononarchcs = !!(entry -> eax & (1UL << 18 ));
83
+ switch (entry -> function ) {
84
+ case 0x40000000 :
85
+ test_val = 0x40000082 ;
83
86
84
- TEST_ASSERT (nononarchcs == !smt_possible (),
87
+ TEST_ASSERT (entry -> eax == test_val ,
88
+ "Wrong max leaf report in 0x40000000.EAX: %x"
89
+ " (evmcs=%d)" ,
90
+ entry -> eax , evmcs_enabled
91
+ );
92
+ break ;
93
+ case 0x40000004 :
94
+ test_val = entry -> eax & (1UL << 18 );
95
+
96
+ TEST_ASSERT (!!test_val == !smt_possible (),
85
97
"NoNonArchitecturalCoreSharing bit"
86
98
" doesn't reflect SMT setting" );
99
+ break ;
87
100
}
88
101
89
102
/*
@@ -133,8 +146,9 @@ struct kvm_cpuid2 *kvm_get_supported_hv_cpuid(struct kvm_vm *vm)
133
146
int main (int argc , char * argv [])
134
147
{
135
148
struct kvm_vm * vm ;
136
- int rv ;
149
+ int rv , stage ;
137
150
struct kvm_cpuid2 * hv_cpuid_entries ;
151
+ bool evmcs_enabled ;
138
152
139
153
/* Tell stdout not to buffer its content */
140
154
setbuf (stdout , NULL );
@@ -145,36 +159,31 @@ int main(int argc, char *argv[])
145
159
exit (KSFT_SKIP );
146
160
}
147
161
148
- /* Create VM */
149
- vm = vm_create_default (VCPU_ID , 0 , guest_code );
150
-
151
- test_hv_cpuid_e2big (vm );
152
-
153
- hv_cpuid_entries = kvm_get_supported_hv_cpuid (vm );
154
- if (!hv_cpuid_entries )
155
- return 1 ;
156
-
157
- test_hv_cpuid (hv_cpuid_entries , 0 );
158
-
159
- free (hv_cpuid_entries );
162
+ for (stage = 0 ; stage < 3 ; stage ++ ) {
163
+ evmcs_enabled = false;
164
+
165
+ vm = vm_create_default (VCPU_ID , 0 , guest_code );
166
+ switch (stage ) {
167
+ case 0 :
168
+ test_hv_cpuid_e2big (vm );
169
+ continue ;
170
+ case 1 :
171
+ break ;
172
+ case 2 :
173
+ if (!kvm_check_cap (KVM_CAP_HYPERV_ENLIGHTENED_VMCS )) {
174
+ print_skip ("Enlightened VMCS is unsupported" );
175
+ continue ;
176
+ }
177
+ vcpu_enable_evmcs (vm , VCPU_ID );
178
+ evmcs_enabled = true;
179
+ break ;
180
+ }
160
181
161
- if (!kvm_check_cap (KVM_CAP_HYPERV_ENLIGHTENED_VMCS )) {
162
- print_skip ("Enlightened VMCS is unsupported" );
163
- goto vm_free ;
182
+ hv_cpuid_entries = kvm_get_supported_hv_cpuid (vm );
183
+ test_hv_cpuid (hv_cpuid_entries , evmcs_enabled );
184
+ free (hv_cpuid_entries );
185
+ kvm_vm_free (vm );
164
186
}
165
187
166
- vcpu_enable_evmcs (vm , VCPU_ID );
167
-
168
- hv_cpuid_entries = kvm_get_supported_hv_cpuid (vm );
169
- if (!hv_cpuid_entries )
170
- return 1 ;
171
-
172
- test_hv_cpuid (hv_cpuid_entries , 1 );
173
-
174
- free (hv_cpuid_entries );
175
-
176
- vm_free :
177
- kvm_vm_free (vm );
178
-
179
188
return 0 ;
180
189
}
0 commit comments