diff options
author | Shuai Xue <xueshuai@linux.alibaba.com> | 2023-04-04 16:23:53 +0800 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2023-04-24 11:32:13 -0700 |
commit | 95b089cf33ae2fac5cd34236cdc4e8fdd69c6dbb (patch) | |
tree | 3da30748c24c7ac5a9a912ddeead7bdffed2cf11 | |
parent | 56c34a74bb5946e153fd8529dba87e2adca57f5d (diff) | |
download | ras-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-- | Makefile | 20 | ||||
-rw-r--r-- | cmcistorm.c | 40 | ||||
-rw-r--r-- | einj.c | 100 | ||||
-rw-r--r-- | einj.h | 52 | ||||
-rw-r--r-- | einj_mem_uc.c | 159 | ||||
-rw-r--r-- | hornet.c | 33 | ||||
-rw-r--r-- | memattr.c | 61 | ||||
-rw-r--r-- | rep_ce_page.c | 32 |
8 files changed, 212 insertions, 285 deletions
@@ -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); @@ -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); +} @@ -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", @@ -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; @@ -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]); |