#define fail(fmt, ...) \
({ \
nr_failures++; \
- printf(fmt, ##__VA_ARGS__); \
+ (void)printf(fmt, ##__VA_ARGS__); \
})
#define memdup(ptr) \
}
}
+static bool leaves_are_sorted(const xen_cpuid_leaf_t *leaves, unsigned int nr)
+{
+ for ( unsigned int i = 1; i < nr; ++i )
+ {
+ /* leaf index went backwards => not sorted. */
+ if ( leaves[i - 1].leaf > leaves[i].leaf )
+ return false;
+
+ /* leaf index went forwards => ok */
+ if ( leaves[i - 1].leaf < leaves[i].leaf )
+ continue;
+
+ /* leave index the same, subleaf didn't increase => not sorted. */
+ if ( leaves[i - 1].subleaf >= leaves[i].subleaf )
+ return false;
+ }
+
+ return true;
+}
+
+static void test_cpuid_current(void)
+{
+ struct cpuid_policy p;
+ xen_cpuid_leaf_t leaves[CPUID_MAX_SERIALISED_LEAVES];
+ unsigned int nr = ARRAY_SIZE(leaves);
+ int rc;
+
+ printf("Testing CPUID on current CPU\n");
+
+ x86_cpuid_policy_fill_native(&p);
+
+ rc = x86_cpuid_copy_to_buffer(&p, leaves, &nr);
+ if ( rc != 0 )
+ return fail(" Serialise, expected rc 0, got %d\n", rc);
+
+ if ( !leaves_are_sorted(leaves, nr) )
+ return fail(" Leaves not sorted\n");
+}
+
static void test_cpuid_serialise_success(void)
{
static const struct test {
goto test_done;
}
+ if ( !leaves_are_sorted(leaves, nr) )
+ {
+ fail(" Test %s, leaves not sorted\n",
+ t->name);
+ goto test_done;
+ }
+
test_done:
free(leaves);
}
test_vendor_identification();
+ test_cpuid_current();
test_cpuid_serialise_success();
test_cpuid_deserialise_failure();
test_cpuid_out_of_range_clearing();