From 5813875f6df15d5f5bc6ab534196e8511c1f6c1b Mon Sep 17 00:00:00 2001 From: Shuai Xue Date: Fri, 12 Aug 2022 19:39:02 +0800 Subject: einj_mem_uc: surround arch dependent code with target arch macros eing_mem_uc injects Memory Uncorrectable non-fatal errors through APEI Error INJection (EINJ) interface, which is arch independent. However, einj_mem_uc fails to compile due to arch dependent configuration checks. Simply surround target arch macros to avoid compile error so we could debug and test with this tool in both X86 and arm platforms. Signed-off-by: Shuai Xue --- do_memcpy.S | 8 +++++++ einj_mem_uc.c | 73 +++++++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 62 insertions(+), 19 deletions(-) diff --git a/do_memcpy.S b/do_memcpy.S index 3aadee6..e3dcf70 100644 --- a/do_memcpy.S +++ b/do_memcpy.S @@ -1,3 +1,4 @@ +#ifdef __x86_64__ .globl do_memcpy .type do_memcpy, @function do_memcpy: @@ -8,3 +9,10 @@ do_memcpy: retq .cfi_endproc .size do_memcpy, .-do_memcpy + +#elif __aarch64__ + .globl do_memcpy +do_memcpy: + ret +#endif + diff --git a/einj_mem_uc.c b/einj_mem_uc.c index bf6bc44..a05fb11 100644 --- a/einj_mem_uc.c +++ b/einj_mem_uc.c @@ -111,6 +111,7 @@ static void inject_uc(unsigned long long addr, void *vaddr, int notrigger) wfile(EINJ_DOIT, 1); } +#ifdef __x86_64__ static void inject_llc(unsigned long long addr, void *vaddr, int notrigger) { unsigned cpu; @@ -124,7 +125,33 @@ static void inject_llc(unsigned long long addr, void *vaddr, int notrigger) wfile(EINJ_NOTRIGGER, notrigger); wfile(EINJ_DOIT, 1); } +#elif __aarch64__ +static void inject_llc(unsigned long long addr, void *vaddr, int notrigger) {} +#endif +static int is_privileged(void) +{ + if (getuid() != 0) { + fprintf(stderr, "%s: must be root to run error injection tests\n", progname); + return 0; + } + return 1; +} + +static int is_einj_support(void) +{ + if (access("/sys/firmware/acpi/tables/EINJ", R_OK) == -1) { + fprintf(stderr, "%s: Error injection not supported, check your BIOS settings\n", progname); + return 0; + } + if (access(EINJ_NOTRIGGER, R_OK|W_OK) == -1) { + fprintf(stderr, "%s: Is the einj.ko module loaded?\n", progname); + return 0; + } + return 1; +} + +#ifdef __x86_64__ static int is_advanced_ras(char *model, int modelnum) { switch (modelnum) { @@ -146,18 +173,9 @@ static void check_configuration(void) char model[512]; int modelnum; - if (getuid() != 0) { - fprintf(stderr, "%s: must be root to run error injection tests\n", progname); - exit(1); - } - if (access("/sys/firmware/acpi/tables/EINJ", R_OK) == -1) { - fprintf(stderr, "%s: Error injection not supported, check your BIOS settings\n", progname); - exit(1); - } - if (access(EINJ_NOTRIGGER, R_OK|W_OK) == -1) { - fprintf(stderr, "%s: Is the einj.ko module loaded?\n", progname); + if (!is_privileged() || !is_einj_support()) exit(1); - } + model[0] = '\0'; proc_cpuinfo(&nsockets, &ncpus, model, &modelnum, &apicmap); if (nsockets == 0 || ncpus == 0) { @@ -174,6 +192,13 @@ static void check_configuration(void) exit(1); } } +#elif __aarch64__ +static void check_configuration(void) +{ + if (!is_privileged() || !is_einj_support()) + exit(1); +} +#endif #define REP9(stmt) stmt;stmt;stmt;stmt;stmt;stmt;stmt;stmt;stmt @@ -388,10 +413,14 @@ int trigger_patrol(char *addr) sleep(1); } +#ifdef __x86_64__ int trigger_llc(char *addr) { asm volatile("clflush %0" : "+m" (*addr)); } +#elif __aarch64__ +int trigger_llc(char *addr) {} +#endif int trigger_instr(char *addr) { @@ -542,14 +571,17 @@ struct sigaction recover_act = { int main(int argc, char **argv) { int c, i; - int count = 1, cmci_wait_count = 0; + int count = 1; double delay = 1.0; struct test *t; void *vaddr; long long paddr; +#ifdef __x86_64__ + int cmci_wait_count = 0; + int either; long b_mce, b_cmci, a_mce, a_cmci; struct timeval t1, t2; - int either; +#endif progname = argv[0]; pagesize = getpagesize(); @@ -581,6 +613,7 @@ int main(int argc, char **argv) break; } + check_configuration(); if (optind < argc) @@ -596,14 +629,15 @@ int main(int argc, char **argv) sigaction(SIGBUS, &recover_act, NULL); for (i = 0; i < count; i++) { - cmci_wait_count = 0; - either = 0; vaddr = t->alloc(); paddr = vtop((long long)vaddr); printf("%d: %-8s vaddr = %p paddr = %llx\n", i, t->testname, vaddr, paddr); - +#ifdef __x86_64__ + cmci_wait_count = 0; + either = 0; proc_interrupts(&b_mce, &b_cmci); gettimeofday(&t1, NULL); +#endif if (sigsetjmp(env, 1)) { if ((t->flags & F_SIGBUS) == 0) { printf("Unexpected SIGBUS\n"); @@ -634,13 +668,13 @@ int main(int argc, char **argv) /* Give system a chance to process on possibly deep C-state idle cpus */ usleep(100); - +#ifdef __x86_64__ proc_interrupts(&a_mce, &a_cmci); - +#endif if (t->flags & F_FATAL) { printf("Big surprise ... still running. Thought that would be fatal\n"); } - +#ifdef __x86_64__ if (Sflag == 0 && (t->flags & (F_MCE | F_EITHER))) { if (a_mce == b_mce) { if (t->flags & F_EITHER) @@ -716,6 +750,7 @@ skip2: while (t->flags & F_FATAL) t = next_test(t); } +#endif } printf("Test passed\n"); -- cgit 1.2.3-korg