diff options
| author | 2021-05-29 09:24:09 +0200 | |
|---|---|---|
| committer | 2021-05-29 09:28:26 +0200 | |
| commit | 42a7c5d017a3a6bb5e6ed1b51b955ea3d756eead (patch) | |
| tree | 4fefc42bc8c52930851ddb783dae2b7ddf3fbbe3 /src/core | |
| parent | core/arm_interface: Improve the performance of memory fallbacks. (diff) | |
| download | yuzu-42a7c5d017a3a6bb5e6ed1b51b955ea3d756eead.tar.gz yuzu-42a7c5d017a3a6bb5e6ed1b51b955ea3d756eead.tar.xz yuzu-42a7c5d017a3a6bb5e6ed1b51b955ea3d756eead.zip | |
core/memory: Check our memory fallbacks for out-of-bound behavior.
This makes it by far harder to crash yuzu.
Also implement the 48bit masking of AARCH64 while touching this code.
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/memory.cpp | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index bf2ef7816..9857278f6 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -591,7 +591,15 @@ struct Memory::Impl { | |||
| 591 | * @returns The instance of T read from the specified virtual address. | 591 | * @returns The instance of T read from the specified virtual address. |
| 592 | */ | 592 | */ |
| 593 | template <typename T> | 593 | template <typename T> |
| 594 | T Read(const VAddr vaddr) { | 594 | T Read(VAddr vaddr) { |
| 595 | // AARCH64 masks the upper 16 bit of all memory accesses | ||
| 596 | vaddr &= 0xffffffffffffLL; | ||
| 597 | |||
| 598 | if (vaddr >= 1uLL << current_page_table->GetAddressSpaceBits()) { | ||
| 599 | LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:08X}", sizeof(T) * 8, vaddr); | ||
| 600 | return 0; | ||
| 601 | } | ||
| 602 | |||
| 595 | // Avoid adding any extra logic to this fast-path block | 603 | // Avoid adding any extra logic to this fast-path block |
| 596 | const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw(); | 604 | const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw(); |
| 597 | if (const u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) { | 605 | if (const u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) { |
| @@ -629,7 +637,16 @@ struct Memory::Impl { | |||
| 629 | * is undefined. | 637 | * is undefined. |
| 630 | */ | 638 | */ |
| 631 | template <typename T> | 639 | template <typename T> |
| 632 | void Write(const VAddr vaddr, const T data) { | 640 | void Write(VAddr vaddr, const T data) { |
| 641 | // AARCH64 masks the upper 16 bit of all memory accesses | ||
| 642 | vaddr &= 0xffffffffffffLL; | ||
| 643 | |||
| 644 | if (vaddr >= 1uLL << current_page_table->GetAddressSpaceBits()) { | ||
| 645 | LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8, | ||
| 646 | static_cast<u32>(data), vaddr); | ||
| 647 | return; | ||
| 648 | } | ||
| 649 | |||
| 633 | // Avoid adding any extra logic to this fast-path block | 650 | // Avoid adding any extra logic to this fast-path block |
| 634 | const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw(); | 651 | const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw(); |
| 635 | if (u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) { | 652 | if (u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) { |
| @@ -656,7 +673,16 @@ struct Memory::Impl { | |||
| 656 | } | 673 | } |
| 657 | 674 | ||
| 658 | template <typename T> | 675 | template <typename T> |
| 659 | bool WriteExclusive(const VAddr vaddr, const T data, const T expected) { | 676 | bool WriteExclusive(VAddr vaddr, const T data, const T expected) { |
| 677 | // AARCH64 masks the upper 16 bit of all memory accesses | ||
| 678 | vaddr &= 0xffffffffffffLL; | ||
| 679 | |||
| 680 | if (vaddr >= 1uLL << current_page_table->GetAddressSpaceBits()) { | ||
| 681 | LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8, | ||
| 682 | static_cast<u32>(data), vaddr); | ||
| 683 | return true; | ||
| 684 | } | ||
| 685 | |||
| 660 | const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw(); | 686 | const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw(); |
| 661 | if (u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) { | 687 | if (u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) { |
| 662 | // NOTE: Avoid adding any extra logic to this fast-path block | 688 | // NOTE: Avoid adding any extra logic to this fast-path block |
| @@ -683,7 +709,16 @@ struct Memory::Impl { | |||
| 683 | return true; | 709 | return true; |
| 684 | } | 710 | } |
| 685 | 711 | ||
| 686 | bool WriteExclusive128(const VAddr vaddr, const u128 data, const u128 expected) { | 712 | bool WriteExclusive128(VAddr vaddr, const u128 data, const u128 expected) { |
| 713 | // AARCH64 masks the upper 16 bit of all memory accesses | ||
| 714 | vaddr &= 0xffffffffffffLL; | ||
| 715 | |||
| 716 | if (vaddr >= 1uLL << current_page_table->GetAddressSpaceBits()) { | ||
| 717 | LOG_ERROR(HW_Memory, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8, | ||
| 718 | static_cast<u32>(data[0]), vaddr); | ||
| 719 | return true; | ||
| 720 | } | ||
| 721 | |||
| 687 | const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw(); | 722 | const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> PAGE_BITS].Raw(); |
| 688 | if (u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) { | 723 | if (u8* const pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) { |
| 689 | // NOTE: Avoid adding any extra logic to this fast-path block | 724 | // NOTE: Avoid adding any extra logic to this fast-path block |