aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShuai Xue <xueshuai@linux.alibaba.com>2023-04-04 16:23:53 +0800
committerTony Luck <tony.luck@intel.com>2023-04-24 11:32:13 -0700
commit95b089cf33ae2fac5cd34236cdc4e8fdd69c6dbb (patch)
tree3da30748c24c7ac5a9a912ddeead7bdffed2cf11
parent56c34a74bb5946e153fd8529dba87e2adca57f5d (diff)
downloadras-tools-95b089cf33ae2fac5cd34236cdc4e8fdd69c6dbb.tar.gz
einj.h: add a header file to declare common EINJ related operations
Lots of files declare the same EINJ related macros like EINJ_ETYPE and functions like wfile(), include the same header files. To simplify the code and make it easier to maintain, move all common EINJ related operations to a header file. [Tony: Move the code out of einj.h and into new file einj.c] Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
-rw-r--r--Makefile20
-rw-r--r--cmcistorm.c40
-rw-r--r--einj.c100
-rw-r--r--einj.h52
-rw-r--r--einj_mem_uc.c159
-rw-r--r--hornet.c33
-rw-r--r--memattr.c61
-rw-r--r--rep_ce_page.c32
8 files changed, 212 insertions, 285 deletions
diff --git a/Makefile b/Makefile
index 3d5ec43..0d18223 100644
--- a/Makefile
+++ b/Makefile
@@ -13,23 +13,23 @@ mca-recover: mca-recover.o proc_pagemap.o
vtop: vtop.c
cc -o vtop $(CFLAGS) vtop.c
-cmcistorm: cmcistorm.o proc_pagemap.o
- cc -o cmcistorm $(CFLAGS) cmcistorm.o proc_pagemap.o
+cmcistorm: cmcistorm.o proc_pagemap.o einj.o
+ cc -o cmcistorm $(CFLAGS) cmcistorm.o proc_pagemap.o einj.o
-rep_ce_page: rep_ce_page.o proc_pagemap.o
- cc -o rep_ce_page $(CFLAGS) rep_ce_page.o proc_pagemap.o
+rep_ce_page: rep_ce_page.o proc_pagemap.o einj.o
+ cc -o rep_ce_page $(CFLAGS) rep_ce_page.o proc_pagemap.o einj.o
-hornet: hornet.c
- cc -o hornet $(CFLAGS) hornet.c
+hornet: hornet.o einj.o
+ cc -o hornet $(CFLAGS) hornet.o einj.o
-einj_mem_uc: einj_mem_uc.o proc_cpuinfo.o proc_interrupt.o proc_pagemap.o do_memcpy.o
- cc -o einj_mem_uc einj_mem_uc.o proc_cpuinfo.o proc_interrupt.o proc_pagemap.o do_memcpy.o -pthread
+einj_mem_uc: einj_mem_uc.o proc_cpuinfo.o proc_interrupt.o proc_pagemap.o do_memcpy.o einj.o
+ cc -o einj_mem_uc einj_mem_uc.o proc_cpuinfo.o proc_interrupt.o proc_pagemap.o do_memcpy.o einj.o -pthread
lmce: proc_pagemap.o lmce.o
cc -o lmce proc_pagemap.o lmce.o -pthread
-memattr: memattr.c
- cc -o memattr $(CFLAGS) memattr.c
+memattr: memattr.o einj.o
+ cc -o memattr $(CFLAGS) memattr.o einj.o
victim: victim.c
cc -o victim $(CFLAGS) victim.c
diff --git a/cmcistorm.c b/cmcistorm.c
index ab97162..6a1d2e3 100644
--- a/cmcistorm.c
+++ b/cmcistorm.c
@@ -13,45 +13,17 @@
* Allocate memory - use EINJ to inject a bunch of soft errors,
* then consume them all as fast a possible.
*/
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <ctype.h>
-
-#define EINJ_ETYPE "/sys/kernel/debug/apei/einj/error_type"
-#define EINJ_ADDR "/sys/kernel/debug/apei/einj/param1"
-#define EINJ_MASK "/sys/kernel/debug/apei/einj/param2"
-#define EINJ_NOTRIGGER "/sys/kernel/debug/apei/einj/notrigger"
-#define EINJ_DOIT "/sys/kernel/debug/apei/einj/error_inject"
+
+#include "einj.h"
extern unsigned long long vtop(unsigned long long addr, pid_t pid);
volatile int trigger;
+char *progname;
+long pagesize;
+int Sflag;
#define BUFSZ (64 * 1024)
-static void wfile(char *file, unsigned long val)
-{
- FILE *fp;
- static int total_errors;
-
-tryagain:
- fp = fopen(file, "w");
- if (fp == NULL) {
- perror(file);
- exit(1);
- }
- fprintf(fp, "0x%lx\n", val);
- if (fclose(fp) == EOF) {
- perror(file);
- if (++total_errors == 10)
- exit(1);
- sleep(3);
- goto tryagain;
- }
-}
-
static void inject(int nerrors, double interval)
{
char *b, *buf;
@@ -95,6 +67,8 @@ int main(int argc, char **argv)
int nerrors = (argc > 1) ? atoi(argv[1]) : 20;
double interval = (argc > 2) ? atof(argv[2]) : 1.0;
+ progname = argv[0];
+
wfile(EINJ_ETYPE, 0x8);
wfile(EINJ_MASK, ~0x0ul);
wfile(EINJ_NOTRIGGER, 1);
diff --git a/einj.c b/einj.c
new file mode 100644
index 0000000..d411570
--- /dev/null
+++ b/einj.c
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Copyright (C) 2015 Intel Corporation
+ * Author: Tony Luck
+ */
+
+#include "einj.h"
+
+int check_errortype_available(char *file, unsigned long long val)
+{
+ FILE *fp;
+ int ret = -1;
+ unsigned long long available_error_type;
+
+ if (strcmp(file, EINJ_ETYPE) != 0)
+ return 0;
+
+ fp = fopen(EINJ_ETYPE_AVAILABLE, "r");
+ if (!fp) {
+ fprintf(stderr, "%s: cannot open '%s'\n", progname, file);
+ exit(1);
+ }
+
+ while (fscanf(fp, "%llx%*[^\n]", &available_error_type) == 1) {
+ if (val == available_error_type) {
+ ret = 0;
+ break;
+ }
+ }
+
+ fclose(fp);
+ return ret;
+}
+
+void wfile(char *file, unsigned long long val)
+{
+ FILE *fp;
+
+ if (check_errortype_available(file, val) != 0) {
+ fprintf(stderr, "%s: no support for error type: 0x%llx\n", progname, val);
+ exit(1);
+ }
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)
+ if (!strcmp(file, EINJ_FLAGS))
+ return;
+#endif
+
+ fp = fopen(file, "w");
+ if (fp == NULL) {
+ fprintf(stderr, "%s: cannot open '%s'\n", progname, file);
+ exit(1);
+ }
+ fprintf(fp, "0x%llx\n", val);
+ if (fclose(fp) == EOF) {
+ fprintf(stderr, "%s: write error on '%s'\n", progname, file);
+ exit(1);
+ }
+}
+
+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;
+}
+
+int is_privileged(void)
+{
+ if (getuid() != 0) {
+ fprintf(stderr, "%s: must be root to run error injection tests\n", progname);
+ return 0;
+ }
+ return 1;
+}
+
+void inject_mem_uc(unsigned long long addr, void *vaddr, int notrigger)
+{
+ PRINT_INJECTING;
+
+ if (Sflag) {
+ vaddr = (void *)((long)vaddr & ~(pagesize - 1));
+ madvise(vaddr, pagesize, MADV_HWPOISON);
+ return;
+ }
+
+ wfile(EINJ_ETYPE, 0x10);
+ wfile(EINJ_ADDR, addr);
+ wfile(EINJ_MASK, ~0x0ul);
+ wfile(EINJ_FLAGS, 2);
+ wfile(EINJ_NOTRIGGER, notrigger);
+ wfile(EINJ_DOIT, 1);
+}
diff --git a/einj.h b/einj.h
new file mode 100644
index 0000000..a5c8e9a
--- /dev/null
+++ b/einj.h
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Copyright (C) 2023 Alibaba Corporation
+ * Authors: Shuai Xue
+ *
+ * This software may be redistributed and/or modified under the terms of
+ * the GNU General Public License ("GPL") version 2 only as published by the
+ * Free Software Foundation.
+ */
+
+#ifndef EINJ_H
+#define EINJ_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <linux/version.h>
+#include <sys/mman.h>
+#include <string.h>
+#include <stdint.h>
+#include <errno.h>
+
+#define EINJ_ETYPE "/sys/kernel/debug/apei/einj/error_type"
+#define EINJ_ETYPE_AVAILABLE "/sys/kernel/debug/apei/einj/available_error_type"
+#define EINJ_ADDR "/sys/kernel/debug/apei/einj/param1"
+#define EINJ_MASK "/sys/kernel/debug/apei/einj/param2"
+#define EINJ_APIC "/sys/kernel/debug/apei/einj/param3"
+#define EINJ_SBDF "/sys/kernel/debug/apei/einj/param4"
+#define EINJ_FLAGS "/sys/kernel/debug/apei/einj/flags"
+#define EINJ_NOTRIGGER "/sys/kernel/debug/apei/einj/notrigger"
+#define EINJ_DOIT "/sys/kernel/debug/apei/einj/error_inject"
+#define EINJ_VENDOR "/sys/kernel/debug/apei/einj/vendor"
+
+#define PRINT_INJECTING printf("injecting ...\n")
+#define PRINT_TRIGGERING printf("triggering ...\n")
+
+extern char *progname;
+extern int Sflag;
+extern long pagesize;
+
+int check_errortype_available(char *file, unsigned long long val);
+
+void wfile(char *file, unsigned long long val);
+
+int is_einj_support(void);
+
+int is_privileged(void);
+
+void inject_mem_uc(unsigned long long addr, void *vaddr, int notrigger);
+
+#endif /* EINJ_H */
diff --git a/einj_mem_uc.c b/einj_mem_uc.c
index 88764d0..16df329 100644
--- a/einj_mem_uc.c
+++ b/einj_mem_uc.c
@@ -9,59 +9,44 @@
* Free Software Foundation.
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
#include <fcntl.h>
-#include <string.h>
#include <time.h>
-#include <sys/mman.h>
#include <sys/time.h>
#include <setjmp.h>
#include <signal.h>
#define _GNU_SOURCE 1
#define __USE_GNU 1
#include <sched.h>
-#include <errno.h>
#include <sys/syscall.h>
#include <linux/futex.h>
#include <pthread.h>
#include <sys/wait.h>
-#include <linux/version.h>
+#include "einj.h"
#ifndef MAP_HUGETLB
#define MAP_HUGETLB 0x40000
#endif
+char *progname;
+long pagesize;
+int Sflag;
+
unsigned long long vtop(unsigned long long addr, pid_t pid);
extern void proc_cpuinfo(int *nsockets, int *ncpus, char *model, int *modelnum, int **apicmap);
extern void proc_interrupts(long *nmce, long *ncmci);
extern void do_memcpy(void *dst, void *src, int cnt);
static void show_help(void);
-static char *progname;
static int nsockets, ncpus, lcpus_persocket;
static int force_flag;
static int cmci_skip_flag;
static int all_flag;
-static int Sflag;
-static long pagesize;
static int *apicmap;
static int child_process;
#define CACHE_LINE_SIZE 64
#define DOUBLE_INJECT_OFFSET (pagesize / 4)
-#define EINJ_ETYPE "/sys/kernel/debug/apei/einj/error_type"
-#define EINJ_ETYPE_AVAILABLE "/sys/kernel/debug/apei/einj/available_error_type"
-#define EINJ_ADDR "/sys/kernel/debug/apei/einj/param1"
-#define EINJ_MASK "/sys/kernel/debug/apei/einj/param2"
-#define EINJ_APIC "/sys/kernel/debug/apei/einj/param3"
-#define EINJ_FLAGS "/sys/kernel/debug/apei/einj/flags"
-#define EINJ_NOTRIGGER "/sys/kernel/debug/apei/einj/notrigger"
-#define EINJ_DOIT "/sys/kernel/debug/apei/einj/error_inject"
-#define EINJ_VENDOR "/sys/kernel/debug/apei/einj/vendor"
-
/*
* Vendor extensions for platform specific operations
*/
@@ -74,78 +59,6 @@ struct vendor_error_type_extension {
int8_t reserved[3];
};
-#define PRINT_INJECTING printf("injecting ...\n")
-#define PRINT_TRIGGERING printf("triggering ...\n")
-
-static int check_errortype_available(char *file, unsigned long long val)
-{
- FILE *fp;
- int ret = -1;
- unsigned long long available_error_type;
-
- if (strcmp(file, EINJ_ETYPE) != 0) return 0;
-
- fp = fopen(EINJ_ETYPE_AVAILABLE, "r");
- if (!fp) {
- fprintf(stderr, "%s: cannot open '%s'\n", progname, file);
- exit(1);
- }
-
- while (fscanf(fp, "%llx%*[^\n]", &available_error_type) == 1) {
- if (val == available_error_type) {
- ret = 0;
- break;
- }
- }
-
- fclose(fp);
- return ret;
-}
-
-static void wfile(char *file, unsigned long long val)
-{
- FILE *fp;
-
- if (check_errortype_available(file, val) != 0) {
- fprintf(stderr, "%s: no support for error type: 0x%llx\n", progname, val);
- exit(1);
- }
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)
- if (!strcmp(file, EINJ_FLAGS))
- return;
-#endif
-
- fp = fopen(file, "w");
- if (fp == NULL) {
- fprintf(stderr, "%s: cannot open '%s'\n", progname, file);
- exit(1);
- }
- fprintf(fp, "0x%llx\n", val);
- if (fclose(fp) == EOF) {
- fprintf(stderr, "%s: write error on '%s'\n", progname, file);
- exit(1);
- }
-}
-
-static void inject_uc(unsigned long long addr, void *vaddr, int notrigger)
-{
- PRINT_INJECTING;
-
- if (Sflag) {
- vaddr = (void *)((long)vaddr & ~(pagesize - 1));
- madvise(vaddr, pagesize, MADV_HWPOISON);
- return;
- }
-
- wfile(EINJ_ETYPE, 0x10);
- wfile(EINJ_ADDR, addr);
- wfile(EINJ_MASK, ~0x0ul);
- wfile(EINJ_FLAGS, 2);
- wfile(EINJ_NOTRIGGER, notrigger);
- wfile(EINJ_DOIT, 1);
-}
-
static void inject_double_uc(unsigned long long addr, void *vaddr, int notrigger)
{
PRINT_INJECTING;
@@ -315,27 +228,7 @@ static void inject_smmu_tbu_fatal(unsigned long long addr, void *vaddr, int notr
}
#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)
@@ -906,27 +799,27 @@ struct test {
} tests[] = {
{
"single", "Single read in pipeline to target address, generates SRAR machine check",
- data_alloc, inject_uc, 1, trigger_single, F_MCE|F_CMCI|F_SIGBUS,
+ data_alloc, inject_mem_uc, 1, trigger_single, F_MCE|F_CMCI|F_SIGBUS,
},
{
"double", "Double read in pipeline to target address, generates SRAR machine check",
- data_alloc, inject_uc, 1, trigger_double, F_MCE|F_CMCI|F_SIGBUS,
+ data_alloc, inject_mem_uc, 1, trigger_double, F_MCE|F_CMCI|F_SIGBUS,
},
{
"split", "Unaligned read crosses cacheline from good to bad. Probably fatal",
- data_alloc, inject_uc, 1, trigger_split, F_MCE|F_CMCI|F_SIGBUS|F_FATAL,
+ data_alloc, inject_mem_uc, 1, trigger_split, F_MCE|F_CMCI|F_SIGBUS|F_FATAL,
},
{
"THP", "Try to inject in transparent huge page, generates SRAR machine check",
- thp_data_alloc, inject_uc, 1, trigger_single, F_MCE|F_CMCI|F_SIGBUS,
+ thp_data_alloc, inject_mem_uc, 1, trigger_single, F_MCE|F_CMCI|F_SIGBUS,
},
{
"hugetlb", "Try to inject in hugetlb page, generates SRAR machine check",
- hugetlb_alloc, inject_uc, 1, trigger_single, F_MCE|F_CMCI|F_SIGBUS,
+ hugetlb_alloc, inject_mem_uc, 1, trigger_single, F_MCE|F_CMCI|F_SIGBUS,
},
{
"store", "Write to target address. Should generate a UCNA/CMCI",
- data_alloc, inject_uc, 1, trigger_write, F_CMCI,
+ data_alloc, inject_mem_uc, 1, trigger_write, F_CMCI,
},
#ifdef __aarch64__
{
@@ -971,44 +864,44 @@ struct test {
},
{
"strbyte", "Write to target address. Should generate a UCNA/CMCI",
- data_alloc, inject_uc, 1, trigger_write_byte, F_CMCI,
+ data_alloc, inject_mem_uc, 1, trigger_write_byte, F_CMCI,
},
{
"strword", "Write to target address. Should generate a UCNA/CMCI",
- data_alloc, inject_uc, 1, trigger_write_word, F_CMCI,
+ data_alloc, inject_mem_uc, 1, trigger_write_word, F_CMCI,
},
{
"strdword", "Write to target address. Should generate a UCNA/CMCI",
- data_alloc, inject_uc, 1, trigger_write_dword, F_CMCI,
+ data_alloc, inject_mem_uc, 1, trigger_write_dword, F_CMCI,
},
{
"strqword", "Write to target address. Should generate a UCNA/CMCI",
- data_alloc, inject_uc, 1, trigger_write_qword, F_CMCI,
+ data_alloc, inject_mem_uc, 1, trigger_write_qword, F_CMCI,
},
#endif
{
"prefetch", "Prefetch data into L1 cache. Should generate CMCI",
- data_alloc, inject_uc, 1, trigger_prefetch, F_CMCI,
+ data_alloc, inject_mem_uc, 1, trigger_prefetch, F_CMCI,
},
{
"memcpy", "Streaming read from target address. Probably fatal",
- data_alloc, inject_uc, 1, trigger_memcpy, F_MCE|F_CMCI|F_SIGBUS|F_FATAL,
+ data_alloc, inject_mem_uc, 1, trigger_memcpy, F_MCE|F_CMCI|F_SIGBUS|F_FATAL,
},
{
"instr", "Instruction fetch. Generates SRAR that OS should transparently fix",
- instr_alloc, inject_uc, 1, trigger_instr, F_MCE|F_CMCI,
+ instr_alloc, inject_mem_uc, 1, trigger_instr, F_MCE|F_CMCI,
},
{
"patrol", "Patrol scrubber, generates SRAO machine check",
- data_alloc, inject_uc, 0, trigger_patrol, F_EITHER|F_LONGWAIT,
+ data_alloc, inject_mem_uc, 0, trigger_patrol, F_EITHER|F_LONGWAIT,
},
{
"thread", "Single read by two threads to target address at the same time, generates SRAR machine check",
- data_alloc, inject_uc, 1, trigger_thread, F_MCE|F_CMCI|F_SIGBUS,
+ data_alloc, inject_mem_uc, 1, trigger_thread, F_MCE|F_CMCI|F_SIGBUS,
},
{
"share", "Share memory is read by two tasks to target address, generates SRAR machine check",
- map_file_alloc, inject_uc, 1, trigger_share, F_MCE|F_CMCI|F_SIGBUS,
+ map_file_alloc, inject_mem_uc, 1, trigger_share, F_MCE|F_CMCI|F_SIGBUS,
},
{
"overflow", "Read to two target addresses at the same time, Probably fatal",
@@ -1020,23 +913,23 @@ struct test {
},
{
"copyin", "Kernel copies data from user. Probably fatal",
- data_alloc, inject_uc, 1, trigger_copyin, F_MCE|F_CMCI|F_FATAL,
+ data_alloc, inject_mem_uc, 1, trigger_copyin, F_MCE|F_CMCI|F_FATAL,
},
{
"copyout", "Kernel copies data to user. Probably fatal",
- map_file_alloc, inject_uc, 1, trigger_copyout, F_MCE|F_CMCI|F_SIGBUS|F_FATAL,
+ map_file_alloc, inject_mem_uc, 1, trigger_copyout, F_MCE|F_CMCI|F_SIGBUS|F_FATAL,
},
{
"copy-on-write", "Kernel copies user page. Probably fatal",
- data_alloc_private, inject_uc, 1, trigger_copy_on_write, F_MCE|F_CMCI|F_SIGBUS|F_FATAL,
+ data_alloc_private, inject_mem_uc, 1, trigger_copy_on_write, F_MCE|F_CMCI|F_SIGBUS|F_FATAL,
},
{
"futex", "Kernel access to futex(2). Probably fatal",
- data_alloc, inject_uc, 1, trigger_futex, F_MCE|F_CMCI|F_FATAL,
+ data_alloc, inject_mem_uc, 1, trigger_futex, F_MCE|F_CMCI|F_FATAL,
},
{
"mlock", "mlock target page then inject/read to generates SRAR machine check",
- mlock_data_alloc, inject_uc, 1, trigger_single, F_MCE|F_CMCI|F_SIGBUS,
+ mlock_data_alloc, inject_mem_uc, 1, trigger_single, F_MCE|F_CMCI|F_SIGBUS,
},
{
"core_ce", "Core corrected error",
diff --git a/hornet.c b/hornet.c
index 9763e5e..6a27697 100644
--- a/hornet.c
+++ b/hornet.c
@@ -15,12 +15,7 @@
* memory address
*/
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include <fcntl.h>
-#include <errno.h>
#include <time.h>
#include <sys/types.h>
#include <sys/signal.h>
@@ -30,14 +25,16 @@
#include <linux/ptrace.h>
#include <sys/uio.h>
#include <elf.h>
-
-static char *progname;
+#include "einj.h"
long addr;
double delay;
int pid;
int tflag, dflag, bflag, sflag, mflag, pflag, vflag;
int trace;
+char *progname;
+long pagesize;
+int Sflag;
static void usage(void)
{
@@ -48,12 +45,6 @@ static void usage(void)
exit(1);
}
-#define EINJ_ETYPE "/sys/kernel/debug/apei/einj/error_type"
-#define EINJ_ADDR "/sys/kernel/debug/apei/einj/param1"
-#define EINJ_MASK "/sys/kernel/debug/apei/einj/param2"
-#define EINJ_NOTRIGGER "/sys/kernel/debug/apei/einj/notrigger"
-#define EINJ_DOIT "/sys/kernel/debug/apei/einj/error_inject"
-
#define check_ptrace(req, pid, addr, data) \
do { \
if (ptrace(req, pid, addr, data) == -1) { \
@@ -96,22 +87,6 @@ static void usage(void)
})
#endif
-static void wfile(char *file, unsigned long val)
-{
- FILE *fp;
-
- fp = fopen(file, "w");
- if (fp == NULL) {
- perror(file);
- exit(1);
- }
- fprintf(fp, "0x%lx\n", val);
- if (fclose(fp) == EOF) {
- perror(file);
- exit(1);
- }
-}
-
static int startproc(char **args)
{
int pid;
diff --git a/memattr.c b/memattr.c
index 3e2dc45..7464a69 100644
--- a/memattr.c
+++ b/memattr.c
@@ -7,11 +7,8 @@
* Free Software Foundation.
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
+
#include <fcntl.h>
-#include <string.h>
#include <time.h>
#include <sys/mman.h>
#include <sys/time.h>
@@ -20,9 +17,13 @@
#define _GNU_SOURCE 1
#define __USE_GNU 1
#include <sched.h>
-#include <errno.h>
#include <sys/syscall.h>
#include <linux/futex.h>
+#include "einj.h"
+
+char *progname;
+long pagesize;
+int Sflag;
typedef struct
{
@@ -39,54 +40,6 @@ extern unsigned long long vtop(unsigned long long addr, pid_t pid);
#define DEV_NAME "/dev/pgprot_drv"
#define PAGE_SHIFT 12
static mpgprot_drv_ctx *ctx = NULL;
-static char *progname;
-
-#define EINJ_ETYPE "/sys/kernel/debug/apei/einj/error_type"
-#define EINJ_ETYPE_AVAILABLE "/sys/kernel/debug/apei/einj/available_error_type"
-#define EINJ_ADDR "/sys/kernel/debug/apei/einj/param1"
-#define EINJ_MASK "/sys/kernel/debug/apei/einj/param2"
-#define EINJ_APIC "/sys/kernel/debug/apei/einj/param3"
-#define EINJ_FLAGS "/sys/kernel/debug/apei/einj/flags"
-#define EINJ_NOTRIGGER "/sys/kernel/debug/apei/einj/notrigger"
-#define EINJ_DOIT "/sys/kernel/debug/apei/einj/error_inject"
-#define EINJ_VENDOR "/sys/kernel/debug/apei/einj/vendor"
-
-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 void wfile(char *file, unsigned long long val)
-{
- FILE *fp;
-
- fp = fopen(file, "w");
- if (fp == NULL)
- {
- fprintf(stderr, "%s: cannot open '%s'\n", progname, file);
- exit(1);
- }
- fprintf(fp, "0x%llx\n", val);
- if (fclose(fp) == EOF)
- {
- fprintf(stderr, "%s: write error on '%s'\n", progname, file);
- exit(1);
- }
-}
-
-static void inject_uc(unsigned long long addr, void *vaddr, int notrigger)
-{
- wfile(EINJ_ETYPE, 0x20);
- wfile(EINJ_ADDR, addr);
- wfile(EINJ_MASK, ~0x0ul);
- wfile(EINJ_FLAGS, 2);
- wfile(EINJ_NOTRIGGER, notrigger);
- wfile(EINJ_DOIT, 1);
-}
int trigger_write(char *addr)
{
@@ -191,7 +144,7 @@ int main(int argc, char *argv[])
/* pick from kernel */
long long int paddr = ctx->paddr;
printf("vaddr = %p paddr = %llx\n", vaddr, paddr);
- inject_uc(paddr, vaddr, 1);
+ inject_mem_uc(paddr, vaddr, 1);
sleep(3);
trigger_write(vaddr);
}
diff --git a/rep_ce_page.c b/rep_ce_page.c
index 479ec6f..985ca4a 100644
--- a/rep_ce_page.c
+++ b/rep_ce_page.c
@@ -13,39 +13,17 @@
* Allocate memory - loop using EINJ to inject a soft error,
* consuming after each until the page is taken offline.
*/
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <unistd.h>
-
#include <sys/mman.h>
+#include "einj.h"
-#define EINJ_ETYPE "/sys/kernel/debug/apei/einj/error_type"
-#define EINJ_ADDR "/sys/kernel/debug/apei/einj/param1"
-#define EINJ_MASK "/sys/kernel/debug/apei/einj/param2"
-#define EINJ_NOTRIGGER "/sys/kernel/debug/apei/einj/notrigger"
-#define EINJ_DOIT "/sys/kernel/debug/apei/einj/error_inject"
+char *progname;
+long pagesize;
+int Sflag;
volatile int trigger;
extern unsigned long long vtop(unsigned long long addr, pid_t pid);
-static void wfile(char *file, unsigned long val)
-{
- FILE *fp;
-
- fp = fopen(file, "w");
- if (fp == NULL) {
- perror(file);
- exit(1);
- }
- fprintf(fp, "0x%lx\n", val);
- if (fclose(fp) == EOF) {
- perror(file);
- exit(1);
- }
-}
-
#define MAX_TRIES 30
int main(int argc, char **argv)
@@ -56,6 +34,8 @@ int main(int argc, char **argv)
int i;
pid_t pid;
+ progname = argv[0];
+
if (argc == 2)
tries = atoi(argv[1]);