diff options
author | Shuai Xue <xueshuai@linux.alibaba.com> | 2022-11-29 21:28:04 +0800 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2022-11-29 09:59:59 -0800 |
commit | 93f96e3f8fa2ec67e9cc19d0e728603440e535b4 (patch) | |
tree | 1fdea0147f2d683f8b75594c5461a87b13119e21 | |
parent | 132428d89a7c09744b8fd57c002ca4b13cf92107 (diff) | |
download | ras-tools-93f96e3f8fa2ec67e9cc19d0e728603440e535b4.tar.gz |
vtop: unfity all cases with the same vtop() function
There are multiple implementations of vtop() function, remove extra copies
of the vtop() function and use the one from proc_pagemap.c
Suggested-by: Luck, Tony <tony.luck@intel.com>
Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | cmcistorm.c | 6 | ||||
-rw-r--r-- | einj_mem_uc.c | 8 | ||||
-rw-r--r-- | lmce.c | 6 | ||||
-rw-r--r-- | mca-recover.c | 36 | ||||
-rw-r--r-- | memattr.c | 2 | ||||
-rw-r--r-- | proc_pagemap.c | 14 | ||||
-rw-r--r-- | rep_ce_page.c | 8 | ||||
-rw-r--r-- | vtop.c | 6 |
9 files changed, 38 insertions, 52 deletions
@@ -7,8 +7,8 @@ all: mca-recover vtop cmcistorm hornet einj_mem_uc lmce rep_ce_page memattr vict clean: rm -f *.o mca-recover vtop cmcistorm hornet einj_mem_uc lmce rep_ce_page memattr victim -mca-recover: mca-recover.c - cc -o mca-recover $(CFLAGS) mca-recover.c +mca-recover: mca-recover.o proc_pagemap.o + cc -o mca-recover $(CFLAGS) mca-recover.o proc_pagemap.o vtop: vtop.c cc -o vtop $(CFLAGS) vtop.c diff --git a/cmcistorm.c b/cmcistorm.c index e3e3a85..ab97162 100644 --- a/cmcistorm.c +++ b/cmcistorm.c @@ -26,6 +26,7 @@ #define EINJ_NOTRIGGER "/sys/kernel/debug/apei/einj/notrigger" #define EINJ_DOIT "/sys/kernel/debug/apei/einj/error_inject" +extern unsigned long long vtop(unsigned long long addr, pid_t pid); volatile int trigger; #define BUFSZ (64 * 1024) @@ -55,11 +56,12 @@ static void inject(int nerrors, double interval) { char *b, *buf; long long paddr; - extern long long vtop(char *); int i; unsigned long s, e; int bufsz = nerrors * 4096; + pid_t pid; + pid = getpid(); buf = malloc(bufsz); if (buf == NULL) { perror("malloc"); @@ -69,7 +71,7 @@ static void inject(int nerrors, double interval) for (i = 0; i < nerrors; i++) { b = buf + i * 4096; - paddr = vtop(b); + paddr = vtop((unsigned long long)b, pid); printf("%d: vaddr = %p paddr = %llx\n", i, b, paddr); wfile(EINJ_ADDR, paddr); diff --git a/einj_mem_uc.c b/einj_mem_uc.c index a98d426..bfb644b 100644 --- a/einj_mem_uc.c +++ b/einj_mem_uc.c @@ -32,7 +32,7 @@ #define MAP_HUGETLB 0x40000 #endif -extern long long vtop(long long); +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); @@ -1033,6 +1033,7 @@ int main(int argc, char **argv) struct test *t; void *vaddr; long long paddr; + pid_t pid; #ifdef __x86_64__ int cmci_wait_count = 0; int either; @@ -1042,6 +1043,7 @@ int main(int argc, char **argv) progname = argv[0]; pagesize = getpagesize(); + pid = getpid(); while ((c = getopt(argc, argv, "ac:d:fhim:z:S")) != -1) switch (c) { case 'a': @@ -1090,7 +1092,7 @@ int main(int argc, char **argv) for (i = 0; i < count; i++) { vaddr = t->alloc(); - paddr = vtop((long long)vaddr); + paddr = vtop((long long)vaddr, pid); printf("%d: %-8s vaddr = %p paddr = %llx\n", i, t->testname, vaddr, paddr); #ifdef __x86_64__ cmci_wait_count = 0; @@ -1122,7 +1124,7 @@ int main(int argc, char **argv) } /* if system didn't already take page offline, ask it to do so now */ - if (paddr == vtop((long long)vaddr)) { + if (paddr == vtop((long long)vaddr, pid)) { printf("Manually take page offline\n"); wfile("/sys/devices/system/memory/hard_offline_page", paddr); } @@ -15,7 +15,7 @@ #include <sys/mman.h> #include <setjmp.h> -extern long long vtop(long long); +extern unsigned long long vtop(unsigned long long addr, pid_t pid); #define NR_THREADS 2 #define NR_CPUS 2 @@ -354,6 +354,7 @@ int main(int argc, char *argv[]) int core_choice = 3; /*default: INSTR/DATA*/ int idx = 1; + pid_t pid; srandom(getpid() * time(0)); if (getuid() != (uid_t)0) { @@ -397,6 +398,7 @@ int main(int argc, char *argv[]) pick_cpu(testcpu, core_choice); memset(targ, 0, sizeof(targ)); sigaction(SIGBUS, &sa, NULL); + pid = getpid(); for (i = 0; i < NR_ADDRS; i++) { if ((vaddr[i] = mmap(0, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC, @@ -406,7 +408,7 @@ int main(int argc, char *argv[]) exit(1); } memcpy(vaddr[i], (void *)test_func, pagesize); - if ((paddr[i] = vtop((uint64_t)vaddr[i])) == 0) + if ((paddr[i] = vtop((uint64_t)vaddr[i], pid)) == 0) return 1; printf("Inject memory error at physical address 0x%lx(virt 0x%lx)\n", paddr[i], (uint64_t)vaddr[i]); diff --git a/mca-recover.c b/mca-recover.c index 7923804..706598c 100644 --- a/mca-recover.c +++ b/mca-recover.c @@ -24,38 +24,10 @@ #include <signal.h> #include <sys/mman.h> +extern unsigned long long vtop(unsigned long long addr, pid_t pid); static int pagesize; /* - * get information about address from /proc/{pid}/pagemap - * Assumes target address is mapped as 4K (not hugepage) - */ -unsigned long long vtop(unsigned long long addr) -{ - unsigned long long pinfo; - long offset = addr / pagesize * (sizeof pinfo); - int fd; - char pagemapname[64]; - - sprintf(pagemapname, "/proc/%d/pagemap", getpid()); - fd = open(pagemapname, O_RDONLY); - if (fd == -1) { - perror(pagemapname); - exit(1); - } - if (pread(fd, &pinfo, sizeof pinfo, offset) != sizeof pinfo) { - perror(pagemapname); - exit(1); - } - close(fd); - if ((pinfo & (1ull << 63)) == 0) { - printf("page not present\n"); - exit(1); - } - return ((pinfo & 0x007fffffffffffffull) * pagesize) + (addr & (pagesize - 1)); -} - -/* * Older glibc headers don't have the si_addr_lsb field in the siginfo_t * structure ... ugly hack to get it */ @@ -67,6 +39,7 @@ struct morebits { char *buf; unsigned long long phys; int tried_recovery; +pid_t pid; /* * "Recover" from the error by allocating a new page and mapping @@ -94,7 +67,7 @@ void recover(int sig, siginfo_t *si, void *v) } buf = newbuf; memset(buf, '*', pagesize); - phys = vtop((unsigned long long)buf); + phys = vtop((unsigned long long)buf, pid); printf("Recovery allocated new page at physical 0x%llx\n", phys); } @@ -122,8 +95,9 @@ int main(int argc, char **argv) fprintf(stderr, "Can't get a single page of memory!\n"); return 1; } + pid = getpid(); memset(buf, '*', pagesize); - phys = vtop((unsigned long long)buf); + phys = vtop((unsigned long long)buf, pid); printf("vtop(%llx) = %llx\n", (unsigned long long)buf, phys); printf("Use /sys/kernel/debug/apei/einj/... to inject\n"); @@ -35,7 +35,7 @@ typedef struct long long int paddr; } mpgprot_drv_ctx; -extern long long vtop(long long); +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; diff --git a/proc_pagemap.c b/proc_pagemap.c index 8c78ff6..8aac6de 100644 --- a/proc_pagemap.c +++ b/proc_pagemap.c @@ -21,25 +21,29 @@ #include <fcntl.h> /* - * get information about address from /proc/self/pagemap + * get information about address from /proc/{pid}/pagemap */ -unsigned long long vtop(unsigned long long addr) +unsigned long long vtop(unsigned long long addr, pid_t pid) { static int pagesize; unsigned long long pinfo; long offset; int fd; + char pagemapname[64]; if (pagesize == 0) pagesize = getpagesize(); offset = addr / pagesize * (sizeof pinfo); - fd = open("/proc/self/pagemap", O_RDONLY); + + sprintf(pagemapname, "/proc/%d/pagemap", pid); + fd = open(pagemapname, O_RDONLY); if (fd == -1) { - perror("pagemap"); + perror(pagemapname); exit(1); } if (pread(fd, &pinfo, sizeof pinfo, offset) != sizeof pinfo) { - perror("pagemap"); + perror(pagemapname); + close(fd); exit(1); } close(fd); diff --git a/rep_ce_page.c b/rep_ce_page.c index 0bd3e8d..479ec6f 100644 --- a/rep_ce_page.c +++ b/rep_ce_page.c @@ -28,7 +28,7 @@ volatile int trigger; -extern unsigned long long vtop(unsigned long long addr); +extern unsigned long long vtop(unsigned long long addr, pid_t pid); static void wfile(char *file, unsigned long val) { @@ -54,6 +54,7 @@ int main(int argc, char **argv) unsigned long long paddr; int tries = MAX_TRIES; int i; + pid_t pid; if (argc == 2) tries = atoi(argv[1]); @@ -62,13 +63,14 @@ int main(int argc, char **argv) perror("mmap"); return 1; } + pid = getpid(); wfile(EINJ_ETYPE, 0x8); wfile(EINJ_MASK, ~0x0ul); wfile(EINJ_NOTRIGGER, 1); *addr = '*'; - paddr = vtop((unsigned long long)addr); + paddr = vtop((unsigned long long)addr, pid); for (i = 0; i < tries; i++) { printf("%d: Inject to vaddr=%p paddr=0x%llx\n", i, addr, paddr); @@ -77,7 +79,7 @@ int main(int argc, char **argv) usleep(250); trigger += *addr; sleep(2); - if (paddr != vtop((unsigned long long)addr)) + if (paddr != vtop((unsigned long long)addr, pid)) break; } @@ -30,7 +30,7 @@ static int pagesize=0x1000; * get information about address from /proc/{pid}/pagemap */ -unsigned long long vtop(unsigned long long addr, int proc_id) +unsigned long long vtop(unsigned long long addr, pid_t pid) { unsigned long pinfo; @@ -41,7 +41,7 @@ unsigned long long vtop(unsigned long long addr, int proc_id) offset = addr / pagesize * (sizeof pinfo); /* sprintf(pagemapname, "/proc/%d/pagemap", getpid()); */ - sprintf(pagemapname, "/proc/%d/pagemap",proc_id); + sprintf(pagemapname, "/proc/%d/pagemap", pid); fd = open(pagemapname, O_RDONLY); if (fd == -1) { @@ -62,7 +62,7 @@ unsigned long long vtop(unsigned long long addr, int proc_id) int main(int argc, char **argv) { - int process_id; + pid_t process_id; unsigned long long buf, phys; if (argc != 3) { |