summaryrefslogtreecommitdiff
path: root/src/core/memory.cpp
diff options
context:
space:
mode:
authorGravatar liamwhite2023-07-24 13:47:11 -0400
committerGravatar GitHub2023-07-24 13:47:11 -0400
commit18000df5e968af0aa9784f398a97da2733262126 (patch)
tree731480485f1d42ebc9945ce42351dd5340a4f889 /src/core/memory.cpp
parentMerge pull request #11135 from liamwhite/getaddrinfo (diff)
parentcore: reduce TOCTTOU memory access (diff)
downloadyuzu-18000df5e968af0aa9784f398a97da2733262126.tar.gz
yuzu-18000df5e968af0aa9784f398a97da2733262126.tar.xz
yuzu-18000df5e968af0aa9784f398a97da2733262126.zip
Merge pull request #11095 from liamwhite/memory2
memory: cleanup
Diffstat (limited to 'src/core/memory.cpp')
-rw-r--r--src/core/memory.cpp115
1 files changed, 57 insertions, 58 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index e1fbe8e00..179685b72 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -183,13 +183,13 @@ struct Memory::Impl {
183 return string; 183 return string;
184 } 184 }
185 185
186 void WalkBlock(const Kernel::KProcess& process, const Common::ProcessAddress addr, 186 bool WalkBlock(const Common::ProcessAddress addr, const std::size_t size, auto on_unmapped,
187 const std::size_t size, auto on_unmapped, auto on_memory, auto on_rasterizer, 187 auto on_memory, auto on_rasterizer, auto increment) {
188 auto increment) { 188 const auto& page_table = system.ApplicationProcess()->GetPageTable().PageTableImpl();
189 const auto& page_table = process.GetPageTable().PageTableImpl();
190 std::size_t remaining_size = size; 189 std::size_t remaining_size = size;
191 std::size_t page_index = addr >> YUZU_PAGEBITS; 190 std::size_t page_index = addr >> YUZU_PAGEBITS;
192 std::size_t page_offset = addr & YUZU_PAGEMASK; 191 std::size_t page_offset = addr & YUZU_PAGEMASK;
192 bool user_accessible = true;
193 193
194 while (remaining_size) { 194 while (remaining_size) {
195 const std::size_t copy_amount = 195 const std::size_t copy_amount =
@@ -200,6 +200,7 @@ struct Memory::Impl {
200 const auto [pointer, type] = page_table.pointers[page_index].PointerType(); 200 const auto [pointer, type] = page_table.pointers[page_index].PointerType();
201 switch (type) { 201 switch (type) {
202 case Common::PageType::Unmapped: { 202 case Common::PageType::Unmapped: {
203 user_accessible = false;
203 on_unmapped(copy_amount, current_vaddr); 204 on_unmapped(copy_amount, current_vaddr);
204 break; 205 break;
205 } 206 }
@@ -227,13 +228,15 @@ struct Memory::Impl {
227 increment(copy_amount); 228 increment(copy_amount);
228 remaining_size -= copy_amount; 229 remaining_size -= copy_amount;
229 } 230 }
231
232 return user_accessible;
230 } 233 }
231 234
232 template <bool UNSAFE> 235 template <bool UNSAFE>
233 void ReadBlockImpl(const Kernel::KProcess& process, const Common::ProcessAddress src_addr, 236 bool ReadBlockImpl(const Common::ProcessAddress src_addr, void* dest_buffer,
234 void* dest_buffer, const std::size_t size) { 237 const std::size_t size) {
235 WalkBlock( 238 return WalkBlock(
236 process, src_addr, size, 239 src_addr, size,
237 [src_addr, size, &dest_buffer](const std::size_t copy_amount, 240 [src_addr, size, &dest_buffer](const std::size_t copy_amount,
238 const Common::ProcessAddress current_vaddr) { 241 const Common::ProcessAddress current_vaddr) {
239 LOG_ERROR(HW_Memory, 242 LOG_ERROR(HW_Memory,
@@ -256,14 +259,14 @@ struct Memory::Impl {
256 }); 259 });
257 } 260 }
258 261
259 void ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer, 262 bool ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
260 const std::size_t size) { 263 const std::size_t size) {
261 ReadBlockImpl<false>(*system.ApplicationProcess(), src_addr, dest_buffer, size); 264 return ReadBlockImpl<false>(src_addr, dest_buffer, size);
262 } 265 }
263 266
264 void ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer, 267 bool ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer,
265 const std::size_t size) { 268 const std::size_t size) {
266 ReadBlockImpl<true>(*system.ApplicationProcess(), src_addr, dest_buffer, size); 269 return ReadBlockImpl<true>(src_addr, dest_buffer, size);
267 } 270 }
268 271
269 const u8* GetSpan(const VAddr src_addr, const std::size_t size) const { 272 const u8* GetSpan(const VAddr src_addr, const std::size_t size) const {
@@ -283,10 +286,10 @@ struct Memory::Impl {
283 } 286 }
284 287
285 template <bool UNSAFE> 288 template <bool UNSAFE>
286 void WriteBlockImpl(const Kernel::KProcess& process, const Common::ProcessAddress dest_addr, 289 bool WriteBlockImpl(const Common::ProcessAddress dest_addr, const void* src_buffer,
287 const void* src_buffer, const std::size_t size) { 290 const std::size_t size) {
288 WalkBlock( 291 return WalkBlock(
289 process, dest_addr, size, 292 dest_addr, size,
290 [dest_addr, size](const std::size_t copy_amount, 293 [dest_addr, size](const std::size_t copy_amount,
291 const Common::ProcessAddress current_vaddr) { 294 const Common::ProcessAddress current_vaddr) {
292 LOG_ERROR(HW_Memory, 295 LOG_ERROR(HW_Memory,
@@ -308,20 +311,19 @@ struct Memory::Impl {
308 }); 311 });
309 } 312 }
310 313
311 void WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer, 314 bool WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer,
312 const std::size_t size) { 315 const std::size_t size) {
313 WriteBlockImpl<false>(*system.ApplicationProcess(), dest_addr, src_buffer, size); 316 return WriteBlockImpl<false>(dest_addr, src_buffer, size);
314 } 317 }
315 318
316 void WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer, 319 bool WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer,
317 const std::size_t size) { 320 const std::size_t size) {
318 WriteBlockImpl<true>(*system.ApplicationProcess(), dest_addr, src_buffer, size); 321 return WriteBlockImpl<true>(dest_addr, src_buffer, size);
319 } 322 }
320 323
321 void ZeroBlock(const Kernel::KProcess& process, const Common::ProcessAddress dest_addr, 324 bool ZeroBlock(const Common::ProcessAddress dest_addr, const std::size_t size) {
322 const std::size_t size) { 325 return WalkBlock(
323 WalkBlock( 326 dest_addr, size,
324 process, dest_addr, size,
325 [dest_addr, size](const std::size_t copy_amount, 327 [dest_addr, size](const std::size_t copy_amount,
326 const Common::ProcessAddress current_vaddr) { 328 const Common::ProcessAddress current_vaddr) {
327 LOG_ERROR(HW_Memory, 329 LOG_ERROR(HW_Memory,
@@ -339,23 +341,23 @@ struct Memory::Impl {
339 [](const std::size_t copy_amount) {}); 341 [](const std::size_t copy_amount) {});
340 } 342 }
341 343
342 void CopyBlock(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, 344 bool CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
343 Common::ProcessAddress src_addr, const std::size_t size) { 345 const std::size_t size) {
344 WalkBlock( 346 return WalkBlock(
345 process, dest_addr, size, 347 dest_addr, size,
346 [&](const std::size_t copy_amount, const Common::ProcessAddress current_vaddr) { 348 [&](const std::size_t copy_amount, const Common::ProcessAddress current_vaddr) {
347 LOG_ERROR(HW_Memory, 349 LOG_ERROR(HW_Memory,
348 "Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})", 350 "Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
349 GetInteger(current_vaddr), GetInteger(src_addr), size); 351 GetInteger(current_vaddr), GetInteger(src_addr), size);
350 ZeroBlock(process, dest_addr, copy_amount); 352 ZeroBlock(dest_addr, copy_amount);
351 }, 353 },
352 [&](const std::size_t copy_amount, const u8* const src_ptr) { 354 [&](const std::size_t copy_amount, const u8* const src_ptr) {
353 WriteBlockImpl<false>(process, dest_addr, src_ptr, copy_amount); 355 WriteBlockImpl<false>(dest_addr, src_ptr, copy_amount);
354 }, 356 },
355 [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount, 357 [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
356 u8* const host_ptr) { 358 u8* const host_ptr) {
357 HandleRasterizerDownload(GetInteger(current_vaddr), copy_amount); 359 HandleRasterizerDownload(GetInteger(current_vaddr), copy_amount);
358 WriteBlockImpl<false>(process, dest_addr, host_ptr, copy_amount); 360 WriteBlockImpl<false>(dest_addr, host_ptr, copy_amount);
359 }, 361 },
360 [&](const std::size_t copy_amount) { 362 [&](const std::size_t copy_amount) {
361 dest_addr += copy_amount; 363 dest_addr += copy_amount;
@@ -364,13 +366,13 @@ struct Memory::Impl {
364 } 366 }
365 367
366 template <typename Callback> 368 template <typename Callback>
367 Result PerformCacheOperation(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, 369 Result PerformCacheOperation(Common::ProcessAddress dest_addr, std::size_t size,
368 std::size_t size, Callback&& cb) { 370 Callback&& cb) {
369 class InvalidMemoryException : public std::exception {}; 371 class InvalidMemoryException : public std::exception {};
370 372
371 try { 373 try {
372 WalkBlock( 374 WalkBlock(
373 process, dest_addr, size, 375 dest_addr, size,
374 [&](const std::size_t block_size, const Common::ProcessAddress current_vaddr) { 376 [&](const std::size_t block_size, const Common::ProcessAddress current_vaddr) {
375 LOG_ERROR(HW_Memory, "Unmapped cache maintenance @ {:#018X}", 377 LOG_ERROR(HW_Memory, "Unmapped cache maintenance @ {:#018X}",
376 GetInteger(current_vaddr)); 378 GetInteger(current_vaddr));
@@ -387,37 +389,34 @@ struct Memory::Impl {
387 return ResultSuccess; 389 return ResultSuccess;
388 } 390 }
389 391
390 Result InvalidateDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, 392 Result InvalidateDataCache(Common::ProcessAddress dest_addr, std::size_t size) {
391 std::size_t size) {
392 auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr, 393 auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
393 const std::size_t block_size) { 394 const std::size_t block_size) {
394 // dc ivac: Invalidate to point of coherency 395 // dc ivac: Invalidate to point of coherency
395 // GPU flush -> CPU invalidate 396 // GPU flush -> CPU invalidate
396 HandleRasterizerDownload(GetInteger(current_vaddr), block_size); 397 HandleRasterizerDownload(GetInteger(current_vaddr), block_size);
397 }; 398 };
398 return PerformCacheOperation(process, dest_addr, size, on_rasterizer); 399 return PerformCacheOperation(dest_addr, size, on_rasterizer);
399 } 400 }
400 401
401 Result StoreDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, 402 Result StoreDataCache(Common::ProcessAddress dest_addr, std::size_t size) {
402 std::size_t size) {
403 auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr, 403 auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
404 const std::size_t block_size) { 404 const std::size_t block_size) {
405 // dc cvac: Store to point of coherency 405 // dc cvac: Store to point of coherency
406 // CPU flush -> GPU invalidate 406 // CPU flush -> GPU invalidate
407 system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size); 407 system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size);
408 }; 408 };
409 return PerformCacheOperation(process, dest_addr, size, on_rasterizer); 409 return PerformCacheOperation(dest_addr, size, on_rasterizer);
410 } 410 }
411 411
412 Result FlushDataCache(const Kernel::KProcess& process, Common::ProcessAddress dest_addr, 412 Result FlushDataCache(Common::ProcessAddress dest_addr, std::size_t size) {
413 std::size_t size) {
414 auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr, 413 auto on_rasterizer = [&](const Common::ProcessAddress current_vaddr,
415 const std::size_t block_size) { 414 const std::size_t block_size) {
416 // dc civac: Store to point of coherency, and invalidate from cache 415 // dc civac: Store to point of coherency, and invalidate from cache
417 // CPU flush -> GPU invalidate 416 // CPU flush -> GPU invalidate
418 system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size); 417 system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size);
419 }; 418 };
420 return PerformCacheOperation(process, dest_addr, size, on_rasterizer); 419 return PerformCacheOperation(dest_addr, size, on_rasterizer);
421 } 420 }
422 421
423 void MarkRegionDebug(u64 vaddr, u64 size, bool debug) { 422 void MarkRegionDebug(u64 vaddr, u64 size, bool debug) {
@@ -899,14 +898,14 @@ std::string Memory::ReadCString(Common::ProcessAddress vaddr, std::size_t max_le
899 return impl->ReadCString(vaddr, max_length); 898 return impl->ReadCString(vaddr, max_length);
900} 899}
901 900
902void Memory::ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer, 901bool Memory::ReadBlock(const Common::ProcessAddress src_addr, void* dest_buffer,
903 const std::size_t size) { 902 const std::size_t size) {
904 impl->ReadBlock(src_addr, dest_buffer, size); 903 return impl->ReadBlock(src_addr, dest_buffer, size);
905} 904}
906 905
907void Memory::ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer, 906bool Memory::ReadBlockUnsafe(const Common::ProcessAddress src_addr, void* dest_buffer,
908 const std::size_t size) { 907 const std::size_t size) {
909 impl->ReadBlockUnsafe(src_addr, dest_buffer, size); 908 return impl->ReadBlockUnsafe(src_addr, dest_buffer, size);
910} 909}
911 910
912const u8* Memory::GetSpan(const VAddr src_addr, const std::size_t size) const { 911const u8* Memory::GetSpan(const VAddr src_addr, const std::size_t size) const {
@@ -917,23 +916,23 @@ u8* Memory::GetSpan(const VAddr src_addr, const std::size_t size) {
917 return impl->GetSpan(src_addr, size); 916 return impl->GetSpan(src_addr, size);
918} 917}
919 918
920void Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer, 919bool Memory::WriteBlock(const Common::ProcessAddress dest_addr, const void* src_buffer,
921 const std::size_t size) { 920 const std::size_t size) {
922 impl->WriteBlock(dest_addr, src_buffer, size); 921 return impl->WriteBlock(dest_addr, src_buffer, size);
923} 922}
924 923
925void Memory::WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer, 924bool Memory::WriteBlockUnsafe(const Common::ProcessAddress dest_addr, const void* src_buffer,
926 const std::size_t size) { 925 const std::size_t size) {
927 impl->WriteBlockUnsafe(dest_addr, src_buffer, size); 926 return impl->WriteBlockUnsafe(dest_addr, src_buffer, size);
928} 927}
929 928
930void Memory::CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr, 929bool Memory::CopyBlock(Common::ProcessAddress dest_addr, Common::ProcessAddress src_addr,
931 const std::size_t size) { 930 const std::size_t size) {
932 impl->CopyBlock(*system.ApplicationProcess(), dest_addr, src_addr, size); 931 return impl->CopyBlock(dest_addr, src_addr, size);
933} 932}
934 933
935void Memory::ZeroBlock(Common::ProcessAddress dest_addr, const std::size_t size) { 934bool Memory::ZeroBlock(Common::ProcessAddress dest_addr, const std::size_t size) {
936 impl->ZeroBlock(*system.ApplicationProcess(), dest_addr, size); 935 return impl->ZeroBlock(dest_addr, size);
937} 936}
938 937
939void Memory::SetGPUDirtyManagers(std::span<Core::GPUDirtyMemoryManager> managers) { 938void Memory::SetGPUDirtyManagers(std::span<Core::GPUDirtyMemoryManager> managers) {
@@ -941,15 +940,15 @@ void Memory::SetGPUDirtyManagers(std::span<Core::GPUDirtyMemoryManager> managers
941} 940}
942 941
943Result Memory::InvalidateDataCache(Common::ProcessAddress dest_addr, const std::size_t size) { 942Result Memory::InvalidateDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
944 return impl->InvalidateDataCache(*system.ApplicationProcess(), dest_addr, size); 943 return impl->InvalidateDataCache(dest_addr, size);
945} 944}
946 945
947Result Memory::StoreDataCache(Common::ProcessAddress dest_addr, const std::size_t size) { 946Result Memory::StoreDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
948 return impl->StoreDataCache(*system.ApplicationProcess(), dest_addr, size); 947 return impl->StoreDataCache(dest_addr, size);
949} 948}
950 949
951Result Memory::FlushDataCache(Common::ProcessAddress dest_addr, const std::size_t size) { 950Result Memory::FlushDataCache(Common::ProcessAddress dest_addr, const std::size_t size) {
952 return impl->FlushDataCache(*system.ApplicationProcess(), dest_addr, size); 951 return impl->FlushDataCache(dest_addr, size);
953} 952}
954 953
955void Memory::RasterizerMarkRegionCached(Common::ProcessAddress vaddr, u64 size, bool cached) { 954void Memory::RasterizerMarkRegionCached(Common::ProcessAddress vaddr, u64 size, bool cached) {