tests/qtest/test-x86-cpuid-compat: Switch test_feature_flag to data-driven
As with add_cpuid_test(), the add_feature_test() function also allocates memory that is leaked if the test case is not run. Fix this in the same way, by moving all the allocations into test_feature_flag() and passing it a pointer to a struct with the necessary parameters which is a compile-time constant. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Fabiano Rosas <farosas@suse.de> Signed-off-by: Fabiano Rosas <farosas@suse.de>
Peter Maydell committed
Mar 8, 2026 at 18:54 UTC
6ba08f4acec830d12f6983b0988c901258654a12
1 file changed
+73
-63
tests/qtest/test-x86-cpuid-compat.c
+73
-63
@@ -94,8 +94,12 @@ static void test_cpuid_prop(const void *data)
94
95
/* Parameters to a add_feature_test() test case */
96
typedef struct FeatureTestArgs {
97
- /* cmdline to start QEMU */
98
- const char *cmdline;
97
+ /* Test name */
98
+ const char *name;
99
+ /* CPU type */
100
+ const char *cpu;
101
+ /* CPU features, may be NULL */
102
+ const char *cpufeat;
103
/*
104
* cpuid-input-eax and cpuid-input-ecx values to look for,
105
* in "feature-words" and "filtered-features" properties.
@@ -140,10 +144,17 @@ static void test_feature_flag(const void *data)
144
{
145
const FeatureTestArgs *args = data;
146
char *path;
147
+ char *cmdline;
148
QList *present, *filtered;
149
uint32_t value;
150
146
- qtest_start(args->cmdline);
151
+ if (args->cpufeat) {
152
+ cmdline = g_strdup_printf("-cpu %s,%s", args->cpu, args->cpufeat);
153
+ } else {
154
+ cmdline = g_strdup_printf("-cpu %s", args->cpu);
155
+ }
156
+
157
+ qtest_start(cmdline);
158
path = get_cpu0_qom_path();
159
present = qobject_to(QList, qom_get(path, "feature-words"));
160
filtered = qobject_to(QList, qom_get(path, "filtered-features"));
@@ -156,40 +167,7 @@ static void test_feature_flag(const void *data)
167
qobject_unref(present);
168
qobject_unref(filtered);
169
g_free(path);
159
- g_free((void *)args->cmdline);
160
- g_free((void *)data);
161
-}
162
-
163
-/*
164
- * Add test case to ensure that a given feature flag is set in
165
- * either "feature-words" or "filtered-features", when running QEMU
166
- * using cmdline
167
- */
168
-static void add_feature_test(const char *name, const char *cpu,
169
- const char *cpufeat, uint32_t eax,
170
- uint32_t ecx, const char *reg,
171
- int bitnr, bool expected_value)
172
-{
173
- FeatureTestArgs *args = g_new0(FeatureTestArgs, 1);
174
- char *cmdline;
175
-
176
- if (!qtest_has_cpu_model(cpu)) {
177
- return;
178
- }
179
-
180
- if (cpufeat) {
181
- cmdline = g_strdup_printf("-cpu %s,%s", cpu, cpufeat);
182
- } else {
183
- cmdline = g_strdup_printf("-cpu %s", cpu);
184
- }
185
-
186
- args->cmdline = cmdline;
187
- args->in_eax = eax;
188
- args->in_ecx = ecx;
189
- args->reg = reg;
190
- args->bitnr = bitnr;
191
- args->expected_value = expected_value;
192
- qtest_add_data_func(name, args, test_feature_flag);
170
+ g_free(cmdline);
171
}
172
173
static void test_plus_minus_subprocess(void)
@@ -381,6 +359,56 @@ static const CpuidTestArgs cpuid_tests[] = {
359
},
360
};
361
362
+/*
363
+ * Test cases to ensure that a given feature flag is set in
364
+ * either "feature-words" or "filtered-features", when running QEMU
365
+ * using cmdline
366
+ */
367
+static const FeatureTestArgs feature_tests[] = {
368
+ /* Test feature parsing */
369
+ {
370
+ "x86/cpuid/features/plus",
371
+ "486", "+arat",
372
+ 6, 0, "EAX", 2, true,
373
+ },
374
+ {
375
+ "x86/cpuid/features/minus",
376
+ "pentium", "-mmx",
377
+ 1, 0, "EDX", 23, false,
378
+ },
379
+ {
380
+ "x86/cpuid/features/on",
381
+ "486", "arat=on",
382
+ 6, 0, "EAX", 2, true,
383
+ },
384
+ {
385
+ "x86/cpuid/features/off",
386
+ "pentium", "mmx=off",
387
+ 1, 0, "EDX", 23, false,
388
+ },
389
+
390
+ {
391
+ "x86/cpuid/features/max-plus-invtsc",
392
+ "max" , "+invtsc",
393
+ 0x80000007, 0, "EDX", 8, true,
394
+ },
395
+ {
396
+ "x86/cpuid/features/max-invtsc-on",
397
+ "max", "invtsc=on",
398
+ 0x80000007, 0, "EDX", 8, true,
399
+ },
400
+ {
401
+ "x86/cpuid/features/max-minus-mmx",
402
+ "max", "-mmx",
403
+ 1, 0, "EDX", 23, false,
404
+ },
405
+ {
406
+ "x86/cpuid/features/max-invtsc-on,mmx=off",
407
+ "max", "mmx=off",
408
+ 1, 0, "EDX", 23, false,
409
+ },
410
+};
411
+
412
int main(int argc, char **argv)
413
{
414
g_test_init(&argc, &argv, NULL);
@@ -397,32 +425,14 @@ int main(int argc, char **argv)
425
&cpuid_tests[i], test_cpuid_prop);
426
}
427
400
- /* Test feature parsing */
401
- add_feature_test("x86/cpuid/features/plus",
402
- "486", "+arat",
403
- 6, 0, "EAX", 2, true);
404
- add_feature_test("x86/cpuid/features/minus",
405
- "pentium", "-mmx",
406
- 1, 0, "EDX", 23, false);
407
- add_feature_test("x86/cpuid/features/on",
408
- "486", "arat=on",
409
- 6, 0, "EAX", 2, true);
410
- add_feature_test("x86/cpuid/features/off",
411
- "pentium", "mmx=off",
412
- 1, 0, "EDX", 23, false);
413
-
414
- add_feature_test("x86/cpuid/features/max-plus-invtsc",
415
- "max" , "+invtsc",
416
- 0x80000007, 0, "EDX", 8, true);
417
- add_feature_test("x86/cpuid/features/max-invtsc-on",
418
- "max", "invtsc=on",
419
- 0x80000007, 0, "EDX", 8, true);
420
- add_feature_test("x86/cpuid/features/max-minus-mmx",
421
- "max", "-mmx",
422
- 1, 0, "EDX", 23, false);
423
- add_feature_test("x86/cpuid/features/max-invtsc-on,mmx=off",
424
- "max", "mmx=off",
425
- 1, 0, "EDX", 23, false);
428
+
429
+ for (int i = 0; i < ARRAY_SIZE(feature_tests); i++) {
430
+ if (!qtest_has_cpu_model(feature_tests[i].cpu)) {
431
+ continue;
432
+ }
433
+ qtest_add_data_func(feature_tests[i].name,
434
+ &feature_tests[i], test_feature_flag);
435
+ }
436
437
return g_test_run();
438
}