Skip to content

Commit a482003

Browse files
committed
Block CPU VA with 48th bit set on aarch64
Signed-off-by: Vihang Mehta <[email protected]>
1 parent dbc85c4 commit a482003

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

shared/source/helpers/aligned_memory.h

+3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222

2323
template <typename T, typename TNoRef = typename std::remove_reference<T>::type>
2424
constexpr inline TNoRef alignUp(T before, size_t alignment) {
25+
if (alignment == 0) {
26+
return before;
27+
}
2528
OPTIONAL_UNRECOVERABLE_IF(!Math::isPow2(alignment));
2629
TNoRef mask = static_cast<TNoRef>(alignment - 1);
2730
return (before + mask) & ~mask;

shared/source/memory_manager/gfx_partition.cpp

+35
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,41 @@ static void reserve57BitRangeWithMemoryMapsParse(OSMemory *osMemory, OSMemory::R
9494
reserveRangeWithMemoryMapsParse(osMemory, reservedCpuAddressRange, areaBase, areaTop, reservationSize);
9595
}
9696

97+
[[maybe_unused]] static void reserveAllHigh48BitRangeGapsWithMemoryMapsParse(OSMemory *osMemory, std::vector<OSMemory::ReservedCpuAddressRange> &reservedCpuAddressRanges) {
98+
constexpr uint64_t high48BitAreaBase = maxNBitValue(47) + 1;
99+
constexpr uint64_t high48BitAreaTop = maxNBitValue(48);
100+
101+
OSMemory::MemoryMaps memoryMaps;
102+
osMemory->getMemoryMaps(memoryMaps);
103+
std::sort(memoryMaps.begin(), memoryMaps.end(), [](const OSMemory::MappedRegion &a, const OSMemory::MappedRegion &b) { return a.start < b.start; });
104+
105+
uint64_t current = high48BitAreaBase;
106+
for (size_t i = 0; i < memoryMaps.size(); i++) {
107+
if (memoryMaps[i].end <= high48BitAreaBase) {
108+
continue;
109+
}
110+
111+
if (memoryMaps[i].start > current) {
112+
reservedCpuAddressRanges.push_back(osMemory->reserveCpuAddressRange(reinterpret_cast<void *>(current), static_cast<size_t>(memoryMaps[i].start - current), 0));
113+
}
114+
115+
current = memoryMaps[i].end;
116+
}
117+
118+
if (current < high48BitAreaTop) {
119+
reservedCpuAddressRanges.push_back(osMemory->reserveCpuAddressRange(reinterpret_cast<void *>(current), static_cast<size_t>(high48BitAreaTop - current), 0));
120+
}
121+
}
122+
97123
GfxPartition::GfxPartition(OSMemory::ReservedCpuAddressRange &reservedCpuAddressRangeForHeapSvm) : reservedCpuAddressRangeForHeapSvm(reservedCpuAddressRangeForHeapSvm), osMemory(OSMemory::create()) {}
98124

99125
GfxPartition::~GfxPartition() {
100126
osMemory->releaseCpuAddressRange(reservedCpuAddressRangeForHeapSvm);
101127
reservedCpuAddressRangeForHeapSvm = {};
102128
osMemory->releaseCpuAddressRange(reservedCpuAddressRangeForHeapExtended);
129+
for (auto &reservedCpuAddressRange : reservedCpuAddressRangesBlocked) {
130+
osMemory->releaseCpuAddressRange(reservedCpuAddressRange);
131+
}
103132
}
104133

105134
void GfxPartition::Heap::init(uint64_t base, uint64_t size, size_t allocationAlignment) {
@@ -245,6 +274,12 @@ bool GfxPartition::init(uint64_t gpuAddressSpace, size_t cpuAddressRangeSizeToRe
245274
gfxBase = maxNBitValue(32) + 1;
246275
heapInit(HeapIndex::heapSvm, 0ull, gfxBase);
247276
} else {
277+
#if defined(__aarch64__)
278+
// Remove the 0x800000000000-0xFFFFFFFFFFFF set of addresses from the SVM range.
279+
// These are addressed differently on the CPU vs GPU (uncanonized vs not) and setting
280+
// up SVM for them and translating these addresses is a bit involved.
281+
reserveAllHigh48BitRangeGapsWithMemoryMapsParse(osMemory.get(), reservedCpuAddressRangesBlocked);
282+
#endif
248283
auto cpuVirtualAddressSize = CpuInfo::getInstance().getVirtualAddressSize();
249284
if (cpuVirtualAddressSize == 48 && gpuAddressSpace == maxNBitValue(48)) {
250285
gfxBase = maxNBitValue(48 - 1) + 1;

shared/source/memory_manager/gfx_partition.h

+1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ class GfxPartition {
133133

134134
OSMemory::ReservedCpuAddressRange &reservedCpuAddressRangeForHeapSvm;
135135
OSMemory::ReservedCpuAddressRange reservedCpuAddressRangeForHeapExtended{};
136+
std::vector<OSMemory::ReservedCpuAddressRange> reservedCpuAddressRangesBlocked;
136137
std::unique_ptr<OSMemory> osMemory;
137138
};
138139
} // namespace NEO

0 commit comments

Comments
 (0)