@@ -14,7 +14,8 @@ libcflat := lib/libcflat.a
cflatobjs := \
lib/panic.o \
lib/printf.o \
- lib/string.o
+ lib/string.o \
+ lib/report.o
cflatobjs += lib/argv.o
#include architecure specific make rules
@@ -45,6 +45,7 @@ extern char *strcat(char *dest, const char *src);
extern int strcmp(const char *a, const char *b);
extern int printf(const char *fmt, ...);
+extern int snprintf(char *buf, int size, const char *fmt, ...);
extern int vsnprintf(char *buf, int size, const char *fmt, va_list va);
extern void puts(const char *s);
@@ -58,4 +59,7 @@ extern long atol(const char *ptr);
#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
#define NULL ((void *)0UL)
+
+void report(const char *msg_fmt, bool pass, ...);
+int report_summary(void);
#endif
new file mode 100644
@@ -0,0 +1,36 @@
+/*
+ * Test result reporting
+ *
+ * Copyright (c) Siemens AG, 2014
+ *
+ * Authors:
+ * Jan Kiszka <jan.kiszka@siemens.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+
+#include "libcflat.h"
+
+static unsigned int tests, failures;
+
+void report(const char *msg_fmt, bool pass, ...)
+{
+ char buf[2000];
+ va_list va;
+
+ tests++;
+ printf("%s: ", pass ? "PASS" : "FAIL");
+ va_start(va, pass);
+ vsnprintf(buf, sizeof(buf), msg_fmt, va);
+ va_end(va);
+ puts(buf);
+ puts("\n");
+ if (!pass)
+ failures++;
+}
+
+int report_summary(void)
+{
+ printf("\nSUMMARY: %d tests, %d failures\n", tests, failures);
+ return failures > 0 ? 1 : 0;
+}
@@ -6,17 +6,6 @@
#include "isr.h"
#include "msr.h"
-static int g_fail;
-static int g_tests;
-
-static void report(const char *msg, int pass)
-{
- ++g_tests;
- printf("%s: %s\n", msg, (pass ? "PASS" : "FAIL"));
- if (!pass)
- ++g_fail;
-}
-
static void test_lapic_existence(void)
{
u32 lvr;
@@ -403,7 +392,5 @@ int main()
test_tsc_deadline_timer();
- printf("\nsummary: %d tests, %d failures\n", g_tests, g_fail);
-
- return g_fail != 0;
+ return report_summary();
}
@@ -7,8 +7,6 @@
#define memset __builtin_memset
#define TESTDEV_IO_PORT 0xe0
-int fails, tests;
-
static int exceptions;
struct regs {
@@ -25,17 +23,6 @@ struct insn_desc {
size_t len;
};
-void report(const char *name, int result)
-{
- ++tests;
- if (result)
- printf("PASS: %s\n", name);
- else {
- printf("FAIL: %s\n", name);
- ++fails;
- }
-}
-
static char st1[] = "abcdefghijklmnop";
void test_stringio()
@@ -1022,6 +1009,5 @@ int main()
test_string_io_mmio(mem);
- printf("\nSUMMARY: %d tests, %d failures\n", tests, fails);
- return fails ? 1 : 0;
+ return report_summary();
}
@@ -12,9 +12,6 @@
# define R "e"
#endif
-static int g_fail;
-static int g_tests;
-
static inline void io_delay(void)
{
}
@@ -24,14 +21,6 @@ static inline void outl(int addr, int val)
asm volatile ("outl %1, %w0" : : "d" (addr), "a" (val));
}
-static void report(const char *msg, int pass)
-{
- ++g_tests;
- printf("%s: %s\n", msg, (pass ? "PASS" : "FAIL"));
- if (!pass)
- ++g_fail;
-}
-
void apic_self_ipi(u8 v)
{
apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_FIXED |
@@ -416,7 +405,5 @@ int main()
printf("After int 33 with shadowed stack\n");
report("int 33 with shadowed stack", test_count == 1);
- printf("\nsummary: %d tests, %d failures\n", g_tests, g_fail);
-
- return g_fail != 0;
+ return report_summary();
}
@@ -21,19 +21,6 @@ int test_gp(void)
return exception_vector();
}
-static int nr_fail, nr_test;
-
-static void report(int cond, const char *name)
-{
- ++nr_test;
- if (!cond) {
- ++nr_fail;
- printf("%s: FAIL\n", name);
- } else {
- printf("%s: PASS\n", name);
- }
-}
-
int main(void)
{
int r;
@@ -41,9 +28,9 @@ int main(void)
printf("Starting IDT test\n");
setup_idt();
r = test_gp();
- report(r == GP_VECTOR, "Testing #GP");
+ report("Testing #GP", r == GP_VECTOR);
r = test_ud2();
- report(r == UD_VECTOR, "Testing #UD");
- printf("%d failures of %d tests\n", nr_fail, nr_test);
- return !nr_fail ? 0 : 1;
+ report("Testing #UD", r == UD_VECTOR);
+
+ return report_summary();
}
@@ -80,17 +80,6 @@ static int find_msr_info(int msr_index)
return -1;
}
-
-int nr_passed, nr_tests;
-
-static void report(const char *name, int passed)
-{
- ++nr_tests;
- if (passed)
- ++nr_passed;
- printf("%s: %s\n", name, passed ? "PASS" : "FAIL");
-}
-
static void test_msr_rw(int msr_index, unsigned long long input, unsigned long long expected)
{
unsigned long long r = 0;
@@ -142,8 +131,6 @@ int main(int ac, char **av)
test_syscall_lazy_load();
- printf("%d tests, %d failures\n", nr_tests, nr_tests - nr_passed);
-
- return nr_passed == nr_tests ? 0 : 1;
+ return report_summary();
}
@@ -4,8 +4,6 @@
#include "processor.h"
#include "desc.h"
-int nr_passed, nr_tests;
-
#define X86_FEATURE_PCID (1 << 17)
#define X86_FEATURE_INVPCID (1 << 10)
@@ -22,14 +20,6 @@ struct invpcid_desc {
unsigned long addr : 64;
};
-static void report(const char *name, int passed)
-{
- ++nr_tests;
- if (passed)
- ++nr_passed;
- printf("%s: %s\n", name, passed ? "PASS" : "FAIL");
-}
-
int write_cr0_checking(unsigned long val)
{
asm volatile(ASM_TRY("1f")
@@ -180,7 +170,5 @@ int main(int ac, char **av)
else
test_invpcid_disabled();
- printf("%d tests, %d failures\n", nr_tests, nr_tests - nr_passed);
-
- return nr_passed == nr_tests ? 0 : 1;
+ return report_summary();
}
@@ -92,7 +92,6 @@ struct pmu_event {
};
static int num_counters;
-static int tests, failures;
char *buf;
@@ -211,13 +210,6 @@ static void measure(pmu_counter_t *evt, int count)
stop_event(&evt[i]);
}
-static void report(const char *name, int n, bool pass)
-{
- printf("%s: pmu %s-%d\n", pass ? "PASS" : "FAIL", name, n);
- tests += 1;
- failures += !pass;
-}
-
static bool verify_event(uint64_t count, struct pmu_event *e)
{
// printf("%lld >= %lld <= %lld\n", e->min, count, e->max);
@@ -236,12 +228,14 @@ static void check_gp_counter(struct pmu_event *evt)
.ctr = MSR_IA32_PERFCTR0,
.config = EVNTSEL_OS | EVNTSEL_USR | evt->unit_sel,
};
+ char fmt[100];
int i;
for (i = 0; i < num_counters; i++, cnt.ctr++) {
cnt.count = 0;
measure(&cnt, 1);
- report(evt->name, i, verify_event(cnt.count, evt));
+ snprintf(fmt, sizeof(fmt), "%s-%%d", evt->name);
+ report(fmt, verify_event(cnt.count, evt), i);
}
}
@@ -268,7 +262,7 @@ static void check_fixed_counters(void)
cnt.count = 0;
cnt.ctr = fixed_events[i].unit_sel;
measure(&cnt, 1);
- report("fixed", i, verify_event(cnt.count, &fixed_events[i]));
+ report("fixed-%d", verify_event(cnt.count, &fixed_events[i]), i);
}
}
@@ -299,7 +293,7 @@ static void check_counters_many(void)
if (!verify_counter(&cnt[i]))
break;
- report("all counters", 0, i == n);
+ report("all counters", i == n);
}
static void check_counter_overflow(void)
@@ -329,13 +323,13 @@ static void check_counter_overflow(void)
idx = event_to_global_idx(&cnt);
cnt.count = 1 - count;
measure(&cnt, 1);
- report("overflow", i, cnt.count == 1);
+ report("overflow-%d", cnt.count == 1, i);
status = rdmsr(MSR_CORE_PERF_GLOBAL_STATUS);
- report("overflow status", i, status & (1ull << idx));
+ report("overflow status-%d", status & (1ull << idx), i);
wrmsr(MSR_CORE_PERF_GLOBAL_OVF_CTRL, status);
status = rdmsr(MSR_CORE_PERF_GLOBAL_STATUS);
- report("overflow status clear", i, !(status & (1ull << idx)));
- report("overflow irq", i, check_irq() == (i % 2));
+ report("overflow status clear-%d", !(status & (1ull << idx)), i);
+ report("overflow irq-%d", check_irq() == (i % 2), i);
}
}
@@ -348,7 +342,7 @@ static void check_gp_counter_cmask(void)
};
cnt.config |= (0x2 << EVNTSEL_CMASK_SHIFT);
measure(&cnt, 1);
- report("cmask", 0, cnt.count < gp_events[1].min);
+ report("cmask", cnt.count < gp_events[1].min);
}
static void check_rdpmc(void)
@@ -360,15 +354,15 @@ static void check_rdpmc(void)
uint64_t x = (val & 0xffffffff) |
((1ull << (eax.split.bit_width - 32)) - 1) << 32;
wrmsr(MSR_IA32_PERFCTR0 + i, val);
- report("rdpmc", i, rdpmc(i) == x);
- report("rdpmc fast", i, rdpmc(i | (1<<31)) == (u32)val);
+ report("rdpmc-%d", rdpmc(i) == x, i);
+ report("rdpmc fast-%d", rdpmc(i | (1<<31)) == (u32)val, i);
}
for (i = 0; i < edx.split.num_counters_fixed; i++) {
uint64_t x = (val & 0xffffffff) |
((1ull << (edx.split.bit_width_fixed - 32)) - 1) << 32;
wrmsr(MSR_CORE_PERF_FIXED_CTR0 + i, val);
- report("rdpmc fixed", i, rdpmc(i | (1 << 30)) == x);
- report("rdpmc fixed fast", i, rdpmc(i | (3<<30)) == (u32)val);
+ report("rdpmc fixed-%d", rdpmc(i | (1 << 30)) == x, i);
+ report("rdpmc fixed fast-%d", rdpmc(i | (3<<30)) == (u32)val, i);
}
}
@@ -409,6 +403,5 @@ int main(int ac, char **av)
check_counter_overflow();
check_gp_counter_cmask();
- printf("\n%d tests, %d failures\n", tests, failures);
- return !failures ? 0 : 1;
+ return report_summary();
}
@@ -18,21 +18,10 @@ static volatile unsigned int test_divider;
static char *fault_addr;
static ulong fault_phys;
-static int g_fail;
-static int g_tests;
-
static inline void io_delay(void)
{
}
-static void report(const char *msg, int pass)
-{
- ++g_tests;
- printf("%s: %s\n", msg, (pass ? "PASS" : "FAIL"));
- if (!pass)
- ++g_fail;
-}
-
static void nmi_tss(void)
{
start:
@@ -273,7 +262,5 @@ int main()
test_kernel_mode_int();
test_vm86_switch();
- printf("\nsummary: %d tests, %d failures\n", g_tests, g_fail);
-
- return g_fail != 0;
+ return report_summary();
}
@@ -37,7 +37,6 @@
#include "smp.h"
#include "io.h"
-int fails, tests;
u32 *vmxon_region;
struct vmcs *vmcs_root;
u32 vpid_cnt;
@@ -63,17 +62,6 @@ extern void *vmx_return;
extern void *entry_sysenter;
extern void *guest_entry;
-void report(const char *name, int result)
-{
- ++tests;
- if (result)
- printf("PASS: %s\n", name);
- else {
- printf("FAIL: %s\n", name);
- ++fails;
- }
-}
-
static int make_vmcs_current(struct vmcs *vmcs)
{
bool ret;
@@ -786,7 +774,6 @@ int main(void)
setup_vm();
setup_idt();
- fails = tests = 0;
hypercall_field = 0;
if (!(cpuid(1).c & (1 << 5))) {
@@ -815,6 +802,5 @@ int main(void)
goto exit;
exit:
- printf("\nSUMMARY: %d tests, %d failures\n", tests, fails);
- return fails ? 1 : 0;
+ return report_summary();
}
@@ -550,7 +550,6 @@ static inline void invept(unsigned long type, u64 eptp)
asm volatile("invept %0, %1\n" ::"m"(operand),"r"(type));
}
-void report(const char *name, int result);
void print_vmexit_info();
void install_ept_entry(unsigned long *pml4, int pte_level,
unsigned long guest_addr, unsigned long pte,