aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShuai Xue <xueshuai@linux.alibaba.com>2022-08-12 19:39:02 +0800
committerShuai Xue <xueshuai@linux.alibaba.com>2022-08-25 08:49:58 +0800
commit5813875f6df15d5f5bc6ab534196e8511c1f6c1b (patch)
tree84a2ca9b1866ecbfb0e094c41fc1ef56b2b41ea5
parent0ba123cafe1a1d96f99268ada302c14367244f87 (diff)
downloadras-tools-5813875f6df15d5f5bc6ab534196e8511c1f6c1b.tar.gz
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 <xueshuai@linux.alibaba.com>
-rw-r--r--do_memcpy.S8
-rw-r--r--einj_mem_uc.c73
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");