From 1dbb40a37bee31db4125b2f6ae0a5be1a87f063d Mon Sep 17 00:00:00 2001 From: "nick.j.sanders" Date: Mon, 7 Jan 2013 22:02:45 +0000 Subject: [PATCH] This patch replaces the existing OsLayer::VirtualToPhysical stub with an actual implementation that translates addresses via the Linux /proc/self/pagemap interface. This causes failing memory locations to be reported with both virtual and physical address, and facilitates isolating a defective memory module. Like many other functions currently implemented in the generic OsLayer class, this functionality is specific to Linux and would need to be moved to a respective subclass if proper multi-OS support ever gets implemented. Signed-off-by: Julius Werner --- src/os.cc | 20 ++++++++++++++++++-- src/os.h | 1 + 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/os.cc b/src/os.cc index 8032cfc..944ff88 100644 --- a/src/os.cc +++ b/src/os.cc @@ -129,8 +129,24 @@ int OsLayer::AddressMode() { // Translates user virtual to physical address. uint64 OsLayer::VirtualToPhysical(void *vaddr) { - // Needs platform specific implementation. - return 0; + uint64 frame, shift; + off64_t off = ((uintptr_t)vaddr) / getpagesize() * 8; + int fd = open(kPagemapPath, O_RDONLY); + if (fd < 0 || lseek64(fd, off, SEEK_SET) != off || read(fd, &frame, 8) != 8) { + int err = errno; + string errtxt = ErrorString(err); + logprintf(0, "Error: failed to access %s with errno %d (%s)\n", + kPagemapPath, err, errtxt.c_str()); + if (fd >= 0) + close(fd); + return 0; + } + close(fd); + if (!(frame & (1LL << 63)) || (frame & (1LL << 62))) + return 0; + shift = (frame >> 55) & 0x3f; + frame = (frame & 0x007fffffffffffffLL) << shift; + return frame | ((uintptr_t)vaddr & ((1LL << shift) - 1)); } // Returns the HD device that contains this file. diff --git a/src/os.h b/src/os.h index b043b61..3f3d3e9 100644 --- a/src/os.h +++ b/src/os.h @@ -27,6 +27,7 @@ #include "adler32memcpy.h" // NOLINT #include "sattypes.h" // NOLINT +const char kPagemapPath[] = "/proc/self/pagemap"; const char kSysfsPath[] = "/sys/bus/pci/devices"; struct PCIDevice { -- 2.30.2