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>
diff --git a/Makefile b/Makefile
index 4c902ee..3d5ec43 100644
--- a/Makefile
+++ b/Makefile
@@ -7,8 +7,8 @@
 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 @@
 {
 	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 @@
 
 	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 @@
 	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 @@
 
 	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 @@
 
 	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 @@
 		}
 
 		/* 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);
 		}
diff --git a/lmce.c b/lmce.c
index b9e8427..797d53a 100644
--- a/lmce.c
+++ b/lmce.c
@@ -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 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 @@
 	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 @@
                         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 @@
 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 @@
 	}
 	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 @@
 		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");
diff --git a/memattr.c b/memattr.c
index 1465c73..3e2dc45 100644
--- a/memattr.c
+++ b/memattr.c
@@ -35,7 +35,7 @@
 	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 @@
 	unsigned long long paddr;
 	int tries = MAX_TRIES;
 	int i;
+	pid_t pid;
 
 	if (argc == 2)
 		tries = atoi(argv[1]);
@@ -62,13 +63,14 @@
 		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 @@
 		usleep(250);
 		trigger += *addr;
 		sleep(2);
-		if (paddr != vtop((unsigned long long)addr))
+		if (paddr != vtop((unsigned long long)addr, pid))
 			break;
 	}
 
diff --git a/vtop.c b/vtop.c
index 4009dc1..a20f2fc 100644
--- a/vtop.c
+++ b/vtop.c
@@ -30,7 +30,7 @@
  * 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 @@
 	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 @@
 
 int main(int argc, char **argv)
 {
-	int process_id;
+	pid_t process_id;
 	unsigned long long buf, phys;
 
 	if (argc != 3) {