220 } 221 222 void ZPhysicalMemoryBacking::unmap_view(ZPhysicalMemory pmem, uintptr_t addr) const { 223 // Note that we must keep the address space reservation intact and just detach 224 // the backing memory. For this reason we map a new anonymous, non-accessible 225 // and non-reserved page over the mapping instead of actually unmapping. 226 const size_t size = pmem.size(); 227 const void* const res = mmap((void*)addr, size, PROT_NONE, MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0); 228 if (res == MAP_FAILED) { 229 ZErrno err; 230 map_failed(err); 231 } 232 } 233 234 uintptr_t ZPhysicalMemoryBacking::nmt_address(uintptr_t offset) const { 235 // From an NMT point of view we treat the first heap mapping (marked0) as committed 236 return ZAddress::marked0(offset); 237 } 238 239 void ZPhysicalMemoryBacking::map(ZPhysicalMemory pmem, uintptr_t offset) const { 240 if (ZUnmapBadViews) { 241 // Only map the good view, for debugging only 242 map_view(pmem, ZAddress::good(offset), AlwaysPreTouch); 243 } else { 244 // Map all views 245 map_view(pmem, ZAddress::marked0(offset), AlwaysPreTouch); 246 map_view(pmem, ZAddress::marked1(offset), AlwaysPreTouch); 247 map_view(pmem, ZAddress::remapped(offset), AlwaysPreTouch); 248 } 249 } 250 251 void ZPhysicalMemoryBacking::unmap(ZPhysicalMemory pmem, uintptr_t offset) const { 252 if (ZUnmapBadViews) { 253 // Only map the good view, for debugging only 254 unmap_view(pmem, ZAddress::good(offset)); 255 } else { 256 // Unmap all views 257 unmap_view(pmem, ZAddress::marked0(offset)); 258 unmap_view(pmem, ZAddress::marked1(offset)); 259 unmap_view(pmem, ZAddress::remapped(offset)); 260 } 261 } 262 263 void ZPhysicalMemoryBacking::flip(ZPhysicalMemory pmem, uintptr_t offset) const { 264 assert(ZUnmapBadViews, "Should be enabled"); 265 const uintptr_t addr_good = ZAddress::good(offset); 266 const uintptr_t addr_bad = ZAddress::is_marked(ZAddressGoodMask) ? ZAddress::remapped(offset) : ZAddress::marked(offset); 267 // Map/Unmap views 268 map_view(pmem, addr_good, false /* pretouch */); 269 unmap_view(pmem, addr_bad); 270 } | 220 } 221 222 void ZPhysicalMemoryBacking::unmap_view(ZPhysicalMemory pmem, uintptr_t addr) const { 223 // Note that we must keep the address space reservation intact and just detach 224 // the backing memory. For this reason we map a new anonymous, non-accessible 225 // and non-reserved page over the mapping instead of actually unmapping. 226 const size_t size = pmem.size(); 227 const void* const res = mmap((void*)addr, size, PROT_NONE, MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0); 228 if (res == MAP_FAILED) { 229 ZErrno err; 230 map_failed(err); 231 } 232 } 233 234 uintptr_t ZPhysicalMemoryBacking::nmt_address(uintptr_t offset) const { 235 // From an NMT point of view we treat the first heap mapping (marked0) as committed 236 return ZAddress::marked0(offset); 237 } 238 239 void ZPhysicalMemoryBacking::map(ZPhysicalMemory pmem, uintptr_t offset) const { 240 if (ZVerifyViews) { 241 // Map good view 242 map_view(pmem, ZAddress::good(offset), AlwaysPreTouch); 243 } else { 244 // Map all views 245 map_view(pmem, ZAddress::marked0(offset), AlwaysPreTouch); 246 map_view(pmem, ZAddress::marked1(offset), AlwaysPreTouch); 247 map_view(pmem, ZAddress::remapped(offset), AlwaysPreTouch); 248 } 249 } 250 251 void ZPhysicalMemoryBacking::unmap(ZPhysicalMemory pmem, uintptr_t offset) const { 252 if (ZVerifyViews) { 253 // Unmap good view 254 unmap_view(pmem, ZAddress::good(offset)); 255 } else { 256 // Unmap all views 257 unmap_view(pmem, ZAddress::marked0(offset)); 258 unmap_view(pmem, ZAddress::marked1(offset)); 259 unmap_view(pmem, ZAddress::remapped(offset)); 260 } 261 } 262 263 void ZPhysicalMemoryBacking::debug_map(ZPhysicalMemory pmem, uintptr_t offset) const { 264 // Map good view 265 assert(ZVerifyViews, "Should be enabled"); 266 map_view(pmem, ZAddress::good(offset), false /* pretouch */); 267 } 268 269 void ZPhysicalMemoryBacking::debug_unmap(ZPhysicalMemory pmem, uintptr_t offset) const { 270 // Unmap good view 271 assert(ZVerifyViews, "Should be enabled"); 272 unmap_view(pmem, ZAddress::good(offset)); 273 } |