@@ -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+
97123GfxPartition::GfxPartition (OSMemory::ReservedCpuAddressRange &reservedCpuAddressRangeForHeapSvm) : reservedCpuAddressRangeForHeapSvm(reservedCpuAddressRangeForHeapSvm), osMemory(OSMemory::create()) {}
98124
99125GfxPartition::~GfxPartition () {
100126 osMemory->releaseCpuAddressRange (reservedCpuAddressRangeForHeapSvm);
101127 reservedCpuAddressRangeForHeapSvm = {};
102128 osMemory->releaseCpuAddressRange (reservedCpuAddressRangeForHeapExtended);
129+ for (auto &reservedCpuAddressRange : reservedCpuAddressRangesBlocked) {
130+ osMemory->releaseCpuAddressRange (reservedCpuAddressRange);
131+ }
103132}
104133
105134void 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 ;
0 commit comments