@@ -94,12 +94,41 @@ static void reserve57BitRangeWithMemoryMapsParse(OSMemory *osMemory, OSMemory::R
94
94
reserveRangeWithMemoryMapsParse (osMemory, reservedCpuAddressRange, areaBase, areaTop, reservationSize);
95
95
}
96
96
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
+
97
123
GfxPartition::GfxPartition (OSMemory::ReservedCpuAddressRange &reservedCpuAddressRangeForHeapSvm) : reservedCpuAddressRangeForHeapSvm(reservedCpuAddressRangeForHeapSvm), osMemory(OSMemory::create()) {}
98
124
99
125
GfxPartition::~GfxPartition () {
100
126
osMemory->releaseCpuAddressRange (reservedCpuAddressRangeForHeapSvm);
101
127
reservedCpuAddressRangeForHeapSvm = {};
102
128
osMemory->releaseCpuAddressRange (reservedCpuAddressRangeForHeapExtended);
129
+ for (auto &reservedCpuAddressRange : reservedCpuAddressRangesBlocked) {
130
+ osMemory->releaseCpuAddressRange (reservedCpuAddressRange);
131
+ }
103
132
}
104
133
105
134
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
245
274
gfxBase = maxNBitValue (32 ) + 1 ;
246
275
heapInit (HeapIndex::heapSvm, 0ull , gfxBase);
247
276
} 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
248
283
auto cpuVirtualAddressSize = CpuInfo::getInstance ().getVirtualAddressSize ();
249
284
if (cpuVirtualAddressSize == 48 && gpuAddressSpace == maxNBitValue (48 )) {
250
285
gfxBase = maxNBitValue (48 - 1 ) + 1 ;
0 commit comments