Skip to content

Commit ceb196d

Browse files
[llvm-exegesis] Validate that address annotations are aligned (#75554)
This patch adds in validation at two different levels that address annotations are page aligned. This is necessary as otherwise the mmap calls will fail as MAP_FIXED/MAP_FIXED_NOREPLACE require page aligned addresses. This happens silently in the subprocess. This patch adds validation at snippet parsing time to give feedback to the user and also adds asserts at code generation/address usage time to ensure that other users of the Exegesis APIs conform to the same requirements.
1 parent 9277ef1 commit ceb196d

File tree

5 files changed

+75
-0
lines changed

5 files changed

+75
-0
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# REQUIRES: exegesis-can-measure-latency, x86_64-linux
2+
3+
# Test that we error out if the requested address is not aligned to a page
4+
# boundary. Here we test out mapping at 2^12+4, which is off from a page
5+
# boundary by four bytes.
6+
7+
# RUN: not llvm-exegesis -mtriple=x86_64-unknown-unknown -mode=latency -snippets-file=%s -execution-mode=subprocess 2>&1 | FileCheck %s
8+
9+
# LLVM-EXEGESIS-MEM-DEF test1 4096 414D47
10+
# LLVM-EXEGESIS-MEM-MAP test1 65540
11+
12+
nop
13+
14+
# CHECK: invalid comment 'LLVM-EXEGESIS-MEM-MAP test1 65540', expected <ADDRESS> to be a multiple of the platform page size.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# REQUIRES: exegesis-can-measure-latency, x86_64-linux
2+
3+
# Test that we error out if the requested snippet address is not aligned to
4+
# a page boundary. Here we test out mapping at 2^12+4 which is off from a page
5+
# boundary by four bytes.
6+
7+
# RUN: not llvm-exegesis -mtriple=x86_64-unknown-unknown -mode=latency -snippets-file=%s -execution-mode=subprocess 2>&1 | FileCheck %s
8+
9+
# LLVM-EXEGESIS-SNIPPET-ADDRESS 65540
10+
11+
nop
12+
13+
# CHECK: invalid comment 'LLVM-EXEGESIS-SNIPPET-ADDRESS 65540, expected <ADDRESS> to be a multiple of the platform page size.

llvm/tools/llvm-exegesis/lib/Assembler.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636
#include "perfmon/perf_event.h"
3737
#endif // HAVE_LIBPFM
3838

39+
#ifdef __linux__
40+
#include <unistd.h>
41+
#endif
42+
3943
namespace llvm {
4044
namespace exegesis {
4145

@@ -53,6 +57,13 @@ static bool generateSnippetSetupCode(
5357
if (GenerateMemoryInstructions) {
5458
BBF.addInstructions(ET.generateMemoryInitialSetup());
5559
for (const MemoryMapping &MM : Key.MemoryMappings) {
60+
#ifdef __linux__
61+
// The frontend that generates that parses the memory mapping information
62+
// from the user should validate that the requested address is a multiple
63+
// of the page size. Assert that this is true here.
64+
assert(MM.Address % getpagesize() == 0 &&
65+
"Memory mappings need to be aligned to page boundaries.");
66+
#endif
5667
BBF.addInstructions(ET.generateMmap(
5768
MM.Address, Key.MemoryValues.at(MM.MemoryValueName).SizeBytes,
5869
ET.getAuxiliaryMemoryStartAddress() +

llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,12 @@ class SubProcessFunctionExecutorImpl
418418
exit(ChildProcessExitCodeE::RSeqDisableFailed);
419419
#endif // GLIBC_INITS_RSEQ
420420

421+
// The frontend that generates the memory annotation structures should
422+
// validate that the address to map the snippet in at is a multiple of
423+
// the page size. Assert that this is true here.
424+
assert(Key.SnippetAddress % getpagesize() == 0 &&
425+
"The snippet address needs to be aligned to a page boundary.");
426+
421427
size_t FunctionDataCopySize = this->Function.FunctionBytes.size();
422428
void *MapAddress = NULL;
423429
int MapFlags = MAP_PRIVATE | MAP_ANONYMOUS;

llvm/tools/llvm-exegesis/lib/SnippetFile.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
#include "llvm/Support/SourceMgr.h"
2424
#include <string>
2525

26+
#ifdef __linux__
27+
#include <unistd.h>
28+
#endif // __linux__
29+
2630
namespace llvm {
2731
namespace exegesis {
2832
namespace {
@@ -118,6 +122,19 @@ class BenchmarkCodeStreamer : public MCStreamer, public AsmCommentConsumer {
118122
MemoryMapping MemMap;
119123
MemMap.MemoryValueName = Parts[0].trim().str();
120124
MemMap.Address = std::stol(Parts[1].trim().str());
125+
126+
#ifdef __linux__
127+
// Validate that the annotation is a multiple of the platform's page
128+
// size.
129+
if (MemMap.Address % getpagesize() != 0) {
130+
errs() << "invalid comment 'LLVM-EXEGESIS-MEM-MAP " << CommentText
131+
<< "', expected <ADDRESS> to be a multiple of the platform page "
132+
"size.";
133+
++InvalidComments;
134+
return;
135+
}
136+
#endif // __linux__
137+
121138
// validate that the annotation refers to an already existing memory
122139
// definition
123140
auto MemValIT = Result->Key.MemoryValues.find(Parts[0].trim().str());
@@ -142,6 +159,20 @@ class BenchmarkCodeStreamer : public MCStreamer, public AsmCommentConsumer {
142159
++InvalidComments;
143160
return;
144161
}
162+
163+
#ifdef __linux__
164+
// Validate that the address in the annotation is a multiple of the
165+
// platform's page size.
166+
if (Result->Key.SnippetAddress % getpagesize() != 0) {
167+
errs() << "invalid comment 'LLVM-EXEGESIS-SNIPPET-ADDRESS "
168+
<< CommentText
169+
<< ", expected <ADDRESS> to be a multiple of the platform page "
170+
"size.";
171+
++InvalidComments;
172+
return;
173+
}
174+
#endif // __linux__
175+
145176
return;
146177
}
147178
}

0 commit comments

Comments
 (0)