aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Sanders <nsanders@chromium.org>2018-06-11 18:43:27 -0700
committerNick Sanders <nsanders@chromium.org>2018-06-11 18:49:38 -0700
commitc8ce5af2c2ac12377d1c229f8be73410acdd00ff (patch)
tree136164f9ad1a7941d23eacacc4d442a632206a15
parentdd550fcf808a97a822a7d32ae18b1ee9a5213001 (diff)
downloadstressapptest-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.cc28
1 files changed, 21 insertions, 7 deletions
diff --git a/src/os.cc b/src/os.cc
index a792c14..089b92d 100644
--- a/src/os.cc
+++ b/src/os.cc
@@ -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.