[CRIU] [PATCH] pagemap: Factor out pfn retrieving for vdso and zero page
Pavel Emelyanov
xemul at parallels.com
Thu Jan 30 02:44:14 PST 2014
Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
diff --git a/arch/x86/vdso.c b/arch/x86/vdso.c
index 1beac24..f24de54 100644
--- a/arch/x86/vdso.c
+++ b/arch/x86/vdso.c
@@ -70,33 +70,10 @@ static int vdso_fill_self_symtable(struct vdso_symtable *s)
int vdso_init(void)
{
- int ret = -1, fd;
- off_t off;
-
if (vdso_fill_self_symtable(&vdso_sym_rt))
return -1;
- fd = open_proc(getpid(), "pagemap");
- if (fd < 0)
- return -1;
-
- off = (vdso_sym_rt.vma_start / PAGE_SIZE) * sizeof(u64);
- if (lseek(fd, off, SEEK_SET) != off) {
- pr_perror("Failed to seek address %lx\n", vdso_sym_rt.vma_start);
- goto out;
- }
-
- ret = read(fd, &vdso_pfn, sizeof(vdso_pfn));
- if (ret < 0 || ret != sizeof(vdso_pfn)) {
- pr_perror("Can't read pme for pid %d", getpid());
- ret = -1;
- } else {
- vdso_pfn = PME_PFRAME(vdso_pfn);
- ret = 0;
- }
-out:
- close(fd);
- return ret;
+ return vaddr_to_pfn(vdso_sym_rt.vma_start, &vdso_pfn);
}
/*
diff --git a/include/util.h b/include/util.h
index 6d7f5ed..890265a 100644
--- a/include/util.h
+++ b/include/util.h
@@ -289,4 +289,6 @@ extern int read_fd_link(int lfd, char *buf, size_t size);
#define USEC_PER_SEC 1000000L
#define NSEC_PER_SEC 1000000000L
+int vaddr_to_pfn(unsigned long vaddr, u64 *pfn);
+
#endif /* __CR_UTIL_H__ */
diff --git a/kerndat.c b/kerndat.c
index 27acf0c..204f6fa 100644
--- a/kerndat.c
+++ b/kerndat.c
@@ -159,9 +159,7 @@ unsigned long zero_page_pfn;
static int init_zero_page_pfn()
{
void *addr;
- loff_t off;
- u64 pfn;
- int fd = -1;
+ int ret;
addr = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (addr == MAP_FAILED) {
@@ -171,37 +169,16 @@ static int init_zero_page_pfn()
if (*((int *) addr) != 0) {
BUG();
- goto err;
- }
-
- fd = open("/proc/self/pagemap", O_RDONLY);
- if (fd < 0) {
- pr_perror("Unable to open /proc/self/pagemap");
- goto err;
- }
-
- off = (unsigned long) addr / PAGE_SIZE * 8;
- if (lseek(fd, off, SEEK_SET) != off) {
- pr_perror("Can't open pagemap file");
- goto err;
- }
- if (read(fd, &pfn, sizeof(pfn)) != sizeof(pfn)) {
- pr_perror("Can't read pagemap file");
- goto err;
+ return -1;
}
- if (!(pfn & PME_PRESENT)) {
- pr_err("The zero page isn't present");
- goto err;
- }
+ ret = vaddr_to_pfn((unsigned long)addr, &zero_page_pfn);
+ munmap(addr, PAGE_SIZE);
- pfn &= PME_PFRAME_MASK;
+ if (zero_page_pfn == 0)
+ ret = -1;
- zero_page_pfn = pfn;
-err:
- munmap(addr, PAGE_SIZE);
- close_safe(&fd);
- return zero_page_pfn ? 0 : -1;
+ return ret;
}
int kerndat_init(void)
diff --git a/util.c b/util.c
index 7057c73..6d1e71d 100644
--- a/util.c
+++ b/util.c
@@ -581,3 +581,29 @@ int is_root_user()
return 1;
}
+
+int vaddr_to_pfn(unsigned long vaddr, u64 *pfn)
+{
+ int fd, ret = -1;
+ off_t off;
+
+ fd = open_proc(getpid(), "pagemap");
+ if (fd < 0)
+ return -1;
+
+ off = (vaddr / PAGE_SIZE) * sizeof(u64);
+ if (lseek(fd, off, SEEK_SET) != off) {
+ pr_perror("Failed to seek address %lx\n", vaddr);
+ goto out;
+ }
+
+ ret = read(fd, pfn, sizeof(*pfn));
+ if (ret != sizeof(*pfn)) {
+ pr_perror("Can't read pme for pid %d", getpid());
+ ret = -1;
+ } else
+ ret = 0;
+out:
+ close(fd);
+ return ret;
+}
More information about the CRIU
mailing list