summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorPatrick Venture <venture@google.com>2019-05-07 13:37:01 -0700
committerPatrick Venture <venture@google.com>2019-05-07 13:40:45 -0700
commit206097b720c107b40d70b801dacfd83ea0467c74 (patch)
tree7b97fad5de00639c77f5dfe41a7205f241ca79bd /tools
parentc73dce91dcfe82ef07b3833af2124be2f5303af5 (diff)
downloadphosphor-ipmi-flash-206097b720c107b40d70b801dacfd83ea0467c74.tar.gz
phosphor-ipmi-flash-206097b720c107b40d70b801dacfd83ea0467c74.zip
tools: io: do aligned read/write mapping
Align the mmap by pagesize. Tested: Verified alignment is correct and mmap succeeds where it would fail on a mis-aligned call. Signed-off-by: Patrick Venture <venture@google.com> Change-Id: I76a4f94415c9337d8ca983e24a18e3e4fc701564
Diffstat (limited to 'tools')
-rw-r--r--tools/io.cpp29
1 files changed, 23 insertions, 6 deletions
diff --git a/tools/io.cpp b/tools/io.cpp
index 75677f4..cc9e7d1 100644
--- a/tools/io.cpp
+++ b/tools/io.cpp
@@ -27,16 +27,24 @@ bool DevMemDevice::read(const std::size_t offset, const std::size_t length,
opened = true;
}
+ /* Map based on aligned addresses - behind the scenes. */
+ const std::size_t alignedDiff = offset % sys->getpagesize();
+ const std::size_t alignedOffset = offset - alignedDiff;
+ const std::size_t alignedSize = length + alignedDiff;
+
// addr, length, prot, flags, fd, offset
- devMemMapped =
- sys->mmap(0, length, PROT_WRITE, MAP_SHARED, devMemFd, offset);
+ devMemMapped = sys->mmap(0, alignedSize, PROT_READ, MAP_SHARED, devMemFd,
+ alignedOffset);
if (devMemMapped == MAP_FAILED)
{
return false; /* but leave the file open. */
}
+ void* alignedSource =
+ static_cast<std::uint8_t*>(devMemMapped) + alignedDiff;
+
/* Copy the bytes. */
- std::memcpy(destination, devMemMapped, length);
+ std::memcpy(destination, alignedSource, length);
/* Close the map between reads for now. */
sys->munmap(devMemMapped, length);
@@ -58,16 +66,25 @@ bool DevMemDevice::write(const std::size_t offset, const std::size_t length,
opened = true;
}
+ /* Map based on aligned addresses - behind the scenes. */
+ const std::size_t alignedDiff = offset % sys->getpagesize();
+ const std::size_t alignedOffset = offset - alignedDiff;
+ const std::size_t alignedSize = length + alignedDiff;
+
// addr, length, prot, flags, fd, offset
- devMemMapped =
- sys->mmap(0, length, PROT_WRITE, MAP_SHARED, devMemFd, offset);
+ devMemMapped = sys->mmap(0, alignedSize, PROT_WRITE, MAP_SHARED, devMemFd,
+ alignedOffset);
+
if (devMemMapped == MAP_FAILED)
{
return false; /* but leave the file open. */
}
+ void* alignedDestination =
+ static_cast<std::uint8_t*>(devMemMapped) + alignedDiff;
+
/* Copy the bytes. */
- std::memcpy(devMemMapped, source, length);
+ std::memcpy(alignedDestination, source, length);
/* Close the map between writes for now. */
sys->munmap(devMemMapped, length);
OpenPOWER on IntegriCloud