diff options
author | Nick Sanders <nsanders@chromium.org> | 2018-06-11 18:43:27 -0700 |
---|---|---|
committer | Nick Sanders <nsanders@chromium.org> | 2018-06-11 18:49:38 -0700 |
commit | c8ce5af2c2ac12377d1c229f8be73410acdd00ff (patch) | |
tree | 136164f9ad1a7941d23eacacc4d442a632206a15 | |
parent | dd550fcf808a97a822a7d32ae18b1ee9a5213001 (diff) | |
download | stressapptest-c8ce5af2c2ac12377d1c229f8be73410acdd00ff.tar.gz |
Fix VirtualToPhysical reporting
The kernel interface for discovering the physical address
https://www.kernel.org/doc/Documentation/vm/pagemap.txt
has changed. We'll update the call to use the new API.
BUG=https://github.com/stressapptest/stressapptest/issues/64
TEST=stressapptest --force_errors looks legit
Signed-off-by: Nick Sanders <nsanders@chromium.org>
-rw-r--r-- | src/os.cc | 28 |
1 files changed, 21 insertions, 7 deletions
@@ -141,10 +141,17 @@ int OsLayer::AddressMode() { // Translates user virtual to physical address. uint64 OsLayer::VirtualToPhysical(void *vaddr) { - uint64 frame, shift; - off64_t off = ((uintptr_t)vaddr) / sysconf(_SC_PAGESIZE) * 8; + uint64 frame, paddr, pfnmask, pagemask; + int pagesize = sysconf(_SC_PAGESIZE); + off64_t off = ((uintptr_t)vaddr) / pagesize * 8; int fd = open(kPagemapPath, O_RDONLY); - // /proc/self/pagemap is available in kernel >= 2.6.25 + + /* + * https://www.kernel.org/doc/Documentation/vm/pagemap.txt + * API change (July 2015) + * https://patchwork.kernel.org/patch/6787991/ + */ + if (fd < 0) return 0; @@ -158,11 +165,18 @@ uint64 OsLayer::VirtualToPhysical(void *vaddr) { return 0; } close(fd); - if (!(frame & (1LL << 63)) || (frame & (1LL << 62))) + + /* Check if page is present and not swapped. */ + if (!(frame & (1ULL << 63)) || (frame & (1ULL << 62))) return 0; - shift = (frame >> 55) & 0x3f; - frame = (frame & 0x007fffffffffffffLL) << shift; - return frame | ((uintptr_t)vaddr & ((1LL << shift) - 1)); + + /* pfn is bits 0-54. */ + pfnmask = ((1ULL << 55) - 1); + /* Pagesize had better be a power of 2. */ + pagemask = pagesize - 1; + + paddr = ((frame & pfnmask) * pagesize) | ((uintptr_t)vaddr & pagemask); + return paddr; } // Returns the HD device that contains this file. |