diff options
Diffstat (limited to '')
| -rw-r--r-- | src/core/hle/kernel/k_page_table.cpp | 47 |
1 files changed, 25 insertions, 22 deletions
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp index d78c5e37a..2ebbc0819 100644 --- a/src/core/hle/kernel/k_page_table.cpp +++ b/src/core/hle/kernel/k_page_table.cpp | |||
| @@ -642,24 +642,26 @@ ResultCode KPageTable::MapPages(VAddr addr, const KPageLinkedList& page_linked_l | |||
| 642 | return ResultSuccess; | 642 | return ResultSuccess; |
| 643 | } | 643 | } |
| 644 | 644 | ||
| 645 | ResultCode KPageTable::MapPages(VAddr addr, KPageLinkedList& page_linked_list, KMemoryState state, | 645 | ResultCode KPageTable::MapPages(VAddr address, KPageLinkedList& page_linked_list, |
| 646 | KMemoryPermission perm) { | 646 | KMemoryState state, KMemoryPermission perm) { |
| 647 | std::lock_guard lock{page_table_lock}; | 647 | // Check that the map is in range. |
| 648 | |||
| 649 | const std::size_t num_pages{page_linked_list.GetNumPages()}; | 648 | const std::size_t num_pages{page_linked_list.GetNumPages()}; |
| 650 | const std::size_t size{num_pages * PageSize}; | 649 | const std::size_t size{num_pages * PageSize}; |
| 650 | R_UNLESS(this->CanContain(address, size, state), ResultInvalidCurrentMemory); | ||
| 651 | 651 | ||
| 652 | if (!CanContain(addr, size, state)) { | 652 | // Lock the table. |
| 653 | return ResultInvalidCurrentMemory; | 653 | std::lock_guard lock{page_table_lock}; |
| 654 | } | ||
| 655 | 654 | ||
| 656 | if (IsRegionMapped(addr, num_pages * PageSize)) { | 655 | // Check the memory state. |
| 657 | return ResultInvalidCurrentMemory; | 656 | R_TRY(this->CheckMemoryState(address, size, KMemoryState::All, KMemoryState::Free, |
| 658 | } | 657 | KMemoryPermission::None, KMemoryPermission::None, |
| 658 | KMemoryAttribute::None, KMemoryAttribute::None)); | ||
| 659 | 659 | ||
| 660 | CASCADE_CODE(MapPages(addr, page_linked_list, perm)); | 660 | // Map the pages. |
| 661 | R_TRY(MapPages(address, page_linked_list, perm)); | ||
| 661 | 662 | ||
| 662 | block_manager->Update(addr, num_pages, state, perm); | 663 | // Update the blocks. |
| 664 | block_manager->Update(address, num_pages, state, perm); | ||
| 663 | 665 | ||
| 664 | return ResultSuccess; | 666 | return ResultSuccess; |
| 665 | } | 667 | } |
| @@ -683,21 +685,23 @@ ResultCode KPageTable::UnmapPages(VAddr addr, const KPageLinkedList& page_linked | |||
| 683 | 685 | ||
| 684 | ResultCode KPageTable::UnmapPages(VAddr addr, KPageLinkedList& page_linked_list, | 686 | ResultCode KPageTable::UnmapPages(VAddr addr, KPageLinkedList& page_linked_list, |
| 685 | KMemoryState state) { | 687 | KMemoryState state) { |
| 686 | std::lock_guard lock{page_table_lock}; | 688 | // Check that the unmap is in range. |
| 687 | |||
| 688 | const std::size_t num_pages{page_linked_list.GetNumPages()}; | 689 | const std::size_t num_pages{page_linked_list.GetNumPages()}; |
| 689 | const std::size_t size{num_pages * PageSize}; | 690 | const std::size_t size{num_pages * PageSize}; |
| 691 | R_UNLESS(this->Contains(addr, size), ResultInvalidCurrentMemory); | ||
| 690 | 692 | ||
| 691 | if (!CanContain(addr, size, state)) { | 693 | // Lock the table. |
| 692 | return ResultInvalidCurrentMemory; | 694 | std::lock_guard lock{page_table_lock}; |
| 693 | } | ||
| 694 | 695 | ||
| 695 | if (IsRegionMapped(addr, num_pages * PageSize)) { | 696 | // Check the memory state. |
| 696 | return ResultInvalidCurrentMemory; | 697 | R_TRY(this->CheckMemoryState(addr, size, KMemoryState::All, state, KMemoryPermission::None, |
| 697 | } | 698 | KMemoryPermission::None, KMemoryAttribute::All, |
| 699 | KMemoryAttribute::None)); | ||
| 698 | 700 | ||
| 699 | CASCADE_CODE(UnmapPages(addr, page_linked_list)); | 701 | // Perform the unmap. |
| 702 | R_TRY(UnmapPages(addr, page_linked_list)); | ||
| 700 | 703 | ||
| 704 | // Update the blocks. | ||
| 701 | block_manager->Update(addr, num_pages, state, KMemoryPermission::None); | 705 | block_manager->Update(addr, num_pages, state, KMemoryPermission::None); |
| 702 | 706 | ||
| 703 | return ResultSuccess; | 707 | return ResultSuccess; |
| @@ -755,7 +759,6 @@ ResultCode KPageTable::SetProcessMemoryPermission(VAddr addr, std::size_t size, | |||
| 755 | 759 | ||
| 756 | // Ensure cache coherency, if we're setting pages as executable. | 760 | // Ensure cache coherency, if we're setting pages as executable. |
| 757 | if (is_x) { | 761 | if (is_x) { |
| 758 | // Memory execution state is changing, invalidate CPU cache range | ||
| 759 | system.InvalidateCpuInstructionCacheRange(addr, size); | 762 | system.InvalidateCpuInstructionCacheRange(addr, size); |
| 760 | } | 763 | } |
| 761 | 764 | ||