#include #include #include #include #include #include #include #include #include #include struct pagemaps { unsigned long long pfn:55; unsigned long long shift:6; unsigned long long rsvd:1; unsigned long long swapped:1; unsigned long long present:1; }; static int translate_va2pa(uint64_t va, uint64_t pagesize, uint64_t *pa) { int rc = 0; static const char *pagemap_file = "/proc/self/pagemap"; struct pagemaps pinfo; uint64_t pinfo_size = sizeof(pinfo); uint64_t offset = va / pagesize * pinfo_size; int fd = open(pagemap_file, O_RDONLY); if (fd == -1) { rc = errno; fprintf(stderr, "Failed to open %s: %s\n", pagemap_file, strerror(rc)); goto ret; } if (pread(fd, (void *) &pinfo, pinfo_size, offset) != pinfo_size) { rc = errno; fprintf(stderr, "Failed to read offset 0x%"PRIx64": %s\n", offset, strerror(rc)); goto ret_close; } *pa = (pinfo.pfn * pagesize) | (va & (pagesize - 1)); ret_close: close(fd); ret: return rc; } int main(int argc, char **argv) { void *buf; uint64_t buf_pa; int pagesize = getpagesize(); int rc = 0; buf = mmap(NULL, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (buf == MAP_FAILED) { rc = errno; fprintf(stderr, "Failed to mmap a page: %s\n", strerror(rc)); goto ret; } memset(buf, 0xcc, pagesize); rc = translate_va2pa((uint64_t) buf, pagesize, &buf_pa); if (rc || !buf_pa) { fprintf(stderr, "Failed to get physical address of mmaped page\n"); goto ret_unmap; } fprintf(stderr, "Physical address of mmaped page = 0x%"PRIx64"\n", buf_pa); volatile int i = 1; while (i++); ret_unmap: munmap(buf, pagesize); ret: return rc; }