summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-07-18 18:15:53 -0400
committerGravatar FernandoS272019-07-19 10:06:08 -0400
commit9bede4eeed523f9707a989f1297279c006086e76 (patch)
tree2acfabeff5f7f449bcdb22563f5ad66f7fa5f414 /src/core/hle/kernel
parentMerge pull request #2687 from lioncash/tls-process (diff)
downloadyuzu-9bede4eeed523f9707a989f1297279c006086e76.tar.gz
yuzu-9bede4eeed523f9707a989f1297279c006086e76.tar.xz
yuzu-9bede4eeed523f9707a989f1297279c006086e76.zip
VM_Manager: Align allocated memory to 256bytes
This commit ensures that all backing memory allocated for the Guest CPU is aligned to 256 bytes. This due to how gpu memory works and the heavy constraints it has in the alignment of physical memory.
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/code_set.h3
-rw-r--r--src/core/hle/kernel/physical_memory.h13
-rw-r--r--src/core/hle/kernel/process.cpp6
-rw-r--r--src/core/hle/kernel/shared_memory.cpp4
-rw-r--r--src/core/hle/kernel/shared_memory.h13
-rw-r--r--src/core/hle/kernel/transfer_memory.cpp2
-rw-r--r--src/core/hle/kernel/transfer_memory.h3
-rw-r--r--src/core/hle/kernel/vm_manager.cpp15
-rw-r--r--src/core/hle/kernel/vm_manager.h9
9 files changed, 42 insertions, 26 deletions
diff --git a/src/core/hle/kernel/code_set.h b/src/core/hle/kernel/code_set.h
index 879957dcb..d8ad54030 100644
--- a/src/core/hle/kernel/code_set.h
+++ b/src/core/hle/kernel/code_set.h
@@ -8,6 +8,7 @@
8#include <vector> 8#include <vector>
9 9
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "core/hle/kernel/physical_memory.h"
11 12
12namespace Kernel { 13namespace Kernel {
13 14
@@ -77,7 +78,7 @@ struct CodeSet final {
77 } 78 }
78 79
79 /// The overall data that backs this code set. 80 /// The overall data that backs this code set.
80 std::vector<u8> memory; 81 Kernel::PhysicalMemory memory;
81 82
82 /// The segments that comprise this code set. 83 /// The segments that comprise this code set.
83 std::array<Segment, 3> segments; 84 std::array<Segment, 3> segments;
diff --git a/src/core/hle/kernel/physical_memory.h b/src/core/hle/kernel/physical_memory.h
new file mode 100644
index 000000000..dd49c75a2
--- /dev/null
+++ b/src/core/hle/kernel/physical_memory.h
@@ -0,0 +1,13 @@
1// Copyright 2019 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/alignment.h"
8
9namespace Kernel {
10
11using PhysicalMemory = std::vector<u8, Common::AlignmentAllocator<u8, 256>>;
12
13}
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 92169a97b..e80a12ac3 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -247,7 +247,7 @@ VAddr Process::CreateTLSRegion() {
247 ASSERT(region_address.Succeeded()); 247 ASSERT(region_address.Succeeded());
248 248
249 const auto map_result = vm_manager.MapMemoryBlock( 249 const auto map_result = vm_manager.MapMemoryBlock(
250 *region_address, std::make_shared<std::vector<u8>>(Memory::PAGE_SIZE), 0, 250 *region_address, std::make_shared<PhysicalMemory>(Memory::PAGE_SIZE), 0,
251 Memory::PAGE_SIZE, MemoryState::ThreadLocal); 251 Memory::PAGE_SIZE, MemoryState::ThreadLocal);
252 ASSERT(map_result.Succeeded()); 252 ASSERT(map_result.Succeeded());
253 253
@@ -277,7 +277,7 @@ void Process::FreeTLSRegion(VAddr tls_address) {
277} 277}
278 278
279void Process::LoadModule(CodeSet module_, VAddr base_addr) { 279void Process::LoadModule(CodeSet module_, VAddr base_addr) {
280 const auto memory = std::make_shared<std::vector<u8>>(std::move(module_.memory)); 280 const auto memory = std::make_shared<PhysicalMemory>(std::move(module_.memory));
281 281
282 const auto MapSegment = [&](const CodeSet::Segment& segment, VMAPermission permissions, 282 const auto MapSegment = [&](const CodeSet::Segment& segment, VMAPermission permissions,
283 MemoryState memory_state) { 283 MemoryState memory_state) {
@@ -327,7 +327,7 @@ void Process::AllocateMainThreadStack(u64 stack_size) {
327 // Allocate and map the main thread stack 327 // Allocate and map the main thread stack
328 const VAddr mapping_address = vm_manager.GetTLSIORegionEndAddress() - main_thread_stack_size; 328 const VAddr mapping_address = vm_manager.GetTLSIORegionEndAddress() - main_thread_stack_size;
329 vm_manager 329 vm_manager
330 .MapMemoryBlock(mapping_address, std::make_shared<std::vector<u8>>(main_thread_stack_size), 330 .MapMemoryBlock(mapping_address, std::make_shared<PhysicalMemory>(main_thread_stack_size),
331 0, main_thread_stack_size, MemoryState::Stack) 331 0, main_thread_stack_size, MemoryState::Stack)
332 .Unwrap(); 332 .Unwrap();
333} 333}
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp
index f15c5ee36..45a9e1942 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/shared_memory.cpp
@@ -28,7 +28,7 @@ SharedPtr<SharedMemory> SharedMemory::Create(KernelCore& kernel, Process* owner_
28 shared_memory->other_permissions = other_permissions; 28 shared_memory->other_permissions = other_permissions;
29 29
30 if (address == 0) { 30 if (address == 0) {
31 shared_memory->backing_block = std::make_shared<std::vector<u8>>(size); 31 shared_memory->backing_block = std::make_shared<Kernel::PhysicalMemory>(size);
32 shared_memory->backing_block_offset = 0; 32 shared_memory->backing_block_offset = 0;
33 33
34 // Refresh the address mappings for the current process. 34 // Refresh the address mappings for the current process.
@@ -59,7 +59,7 @@ SharedPtr<SharedMemory> SharedMemory::Create(KernelCore& kernel, Process* owner_
59} 59}
60 60
61SharedPtr<SharedMemory> SharedMemory::CreateForApplet( 61SharedPtr<SharedMemory> SharedMemory::CreateForApplet(
62 KernelCore& kernel, std::shared_ptr<std::vector<u8>> heap_block, std::size_t offset, u64 size, 62 KernelCore& kernel, std::shared_ptr<Kernel::PhysicalMemory> heap_block, std::size_t offset, u64 size,
63 MemoryPermission permissions, MemoryPermission other_permissions, std::string name) { 63 MemoryPermission permissions, MemoryPermission other_permissions, std::string name) {
64 SharedPtr<SharedMemory> shared_memory(new SharedMemory(kernel)); 64 SharedPtr<SharedMemory> shared_memory(new SharedMemory(kernel));
65 65
diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h
index c2b6155e1..01ca6dcd2 100644
--- a/src/core/hle/kernel/shared_memory.h
+++ b/src/core/hle/kernel/shared_memory.h
@@ -10,6 +10,7 @@
10 10
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "core/hle/kernel/object.h" 12#include "core/hle/kernel/object.h"
13#include "core/hle/kernel/physical_memory.h"
13#include "core/hle/kernel/process.h" 14#include "core/hle/kernel/process.h"
14#include "core/hle/result.h" 15#include "core/hle/result.h"
15 16
@@ -62,12 +63,10 @@ public:
62 * block. 63 * block.
63 * @param name Optional object name, used for debugging purposes. 64 * @param name Optional object name, used for debugging purposes.
64 */ 65 */
65 static SharedPtr<SharedMemory> CreateForApplet(KernelCore& kernel, 66 static SharedPtr<SharedMemory> CreateForApplet(
66 std::shared_ptr<std::vector<u8>> heap_block, 67 KernelCore& kernel, std::shared_ptr<Kernel::PhysicalMemory> heap_block, std::size_t offset,
67 std::size_t offset, u64 size, 68 u64 size, MemoryPermission permissions, MemoryPermission other_permissions,
68 MemoryPermission permissions, 69 std::string name = "Unknown Applet");
69 MemoryPermission other_permissions,
70 std::string name = "Unknown Applet");
71 70
72 std::string GetTypeName() const override { 71 std::string GetTypeName() const override {
73 return "SharedMemory"; 72 return "SharedMemory";
@@ -135,7 +134,7 @@ private:
135 ~SharedMemory() override; 134 ~SharedMemory() override;
136 135
137 /// Backing memory for this shared memory block. 136 /// Backing memory for this shared memory block.
138 std::shared_ptr<std::vector<u8>> backing_block; 137 std::shared_ptr<PhysicalMemory> backing_block;
139 /// Offset into the backing block for this shared memory. 138 /// Offset into the backing block for this shared memory.
140 std::size_t backing_block_offset = 0; 139 std::size_t backing_block_offset = 0;
141 /// Size of the memory block. Page-aligned. 140 /// Size of the memory block. Page-aligned.
diff --git a/src/core/hle/kernel/transfer_memory.cpp b/src/core/hle/kernel/transfer_memory.cpp
index 26c4e5e67..1113c815e 100644
--- a/src/core/hle/kernel/transfer_memory.cpp
+++ b/src/core/hle/kernel/transfer_memory.cpp
@@ -47,7 +47,7 @@ ResultCode TransferMemory::MapMemory(VAddr address, u64 size, MemoryPermission p
47 return ERR_INVALID_STATE; 47 return ERR_INVALID_STATE;
48 } 48 }
49 49
50 backing_block = std::make_shared<std::vector<u8>>(size); 50 backing_block = std::make_shared<PhysicalMemory>(size);
51 51
52 const auto map_state = owner_permissions == MemoryPermission::None 52 const auto map_state = owner_permissions == MemoryPermission::None
53 ? MemoryState::TransferMemoryIsolated 53 ? MemoryState::TransferMemoryIsolated
diff --git a/src/core/hle/kernel/transfer_memory.h b/src/core/hle/kernel/transfer_memory.h
index a140b1e2b..6be9dc094 100644
--- a/src/core/hle/kernel/transfer_memory.h
+++ b/src/core/hle/kernel/transfer_memory.h
@@ -8,6 +8,7 @@
8#include <vector> 8#include <vector>
9 9
10#include "core/hle/kernel/object.h" 10#include "core/hle/kernel/object.h"
11#include "core/hle/kernel/physical_memory.h"
11 12
12union ResultCode; 13union ResultCode;
13 14
@@ -82,7 +83,7 @@ private:
82 ~TransferMemory() override; 83 ~TransferMemory() override;
83 84
84 /// Memory block backing this instance. 85 /// Memory block backing this instance.
85 std::shared_ptr<std::vector<u8>> backing_block; 86 std::shared_ptr<PhysicalMemory> backing_block;
86 87
87 /// The base address for the memory managed by this instance. 88 /// The base address for the memory managed by this instance.
88 VAddr base_address = 0; 89 VAddr base_address = 0;
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp
index 4f45fb03b..40cea1e7c 100644
--- a/src/core/hle/kernel/vm_manager.cpp
+++ b/src/core/hle/kernel/vm_manager.cpp
@@ -5,6 +5,7 @@
5#include <algorithm> 5#include <algorithm>
6#include <iterator> 6#include <iterator>
7#include <utility> 7#include <utility>
8#include "common/alignment.h"
8#include "common/assert.h" 9#include "common/assert.h"
9#include "common/logging/log.h" 10#include "common/logging/log.h"
10#include "common/memory_hook.h" 11#include "common/memory_hook.h"
@@ -103,7 +104,7 @@ bool VMManager::IsValidHandle(VMAHandle handle) const {
103} 104}
104 105
105ResultVal<VMManager::VMAHandle> VMManager::MapMemoryBlock(VAddr target, 106ResultVal<VMManager::VMAHandle> VMManager::MapMemoryBlock(VAddr target,
106 std::shared_ptr<std::vector<u8>> block, 107 std::shared_ptr<PhysicalMemory> block,
107 std::size_t offset, u64 size, 108 std::size_t offset, u64 size,
108 MemoryState state, VMAPermission perm) { 109 MemoryState state, VMAPermission perm) {
109 ASSERT(block != nullptr); 110 ASSERT(block != nullptr);
@@ -260,7 +261,7 @@ ResultVal<VAddr> VMManager::SetHeapSize(u64 size) {
260 261
261 if (heap_memory == nullptr) { 262 if (heap_memory == nullptr) {
262 // Initialize heap 263 // Initialize heap
263 heap_memory = std::make_shared<std::vector<u8>>(size); 264 heap_memory = std::make_shared<PhysicalMemory>(size);
264 heap_end = heap_region_base + size; 265 heap_end = heap_region_base + size;
265 } else { 266 } else {
266 UnmapRange(heap_region_base, GetCurrentHeapSize()); 267 UnmapRange(heap_region_base, GetCurrentHeapSize());
@@ -341,7 +342,7 @@ ResultCode VMManager::MapPhysicalMemory(VAddr target, u64 size) {
341 const auto map_size = std::min(end_addr - cur_addr, vma_end - cur_addr); 342 const auto map_size = std::min(end_addr - cur_addr, vma_end - cur_addr);
342 if (vma.state == MemoryState::Unmapped) { 343 if (vma.state == MemoryState::Unmapped) {
343 const auto map_res = 344 const auto map_res =
344 MapMemoryBlock(cur_addr, std::make_shared<std::vector<u8>>(map_size, 0), 0, 345 MapMemoryBlock(cur_addr, std::make_shared<PhysicalMemory>(map_size, 0), 0,
345 map_size, MemoryState::Heap, VMAPermission::ReadWrite); 346 map_size, MemoryState::Heap, VMAPermission::ReadWrite);
346 result = map_res.Code(); 347 result = map_res.Code();
347 if (result.IsError()) { 348 if (result.IsError()) {
@@ -442,7 +443,7 @@ ResultCode VMManager::UnmapPhysicalMemory(VAddr target, u64 size) {
442 if (result.IsError()) { 443 if (result.IsError()) {
443 for (const auto [map_address, map_size] : unmapped_regions) { 444 for (const auto [map_address, map_size] : unmapped_regions) {
444 const auto remap_res = 445 const auto remap_res =
445 MapMemoryBlock(map_address, std::make_shared<std::vector<u8>>(map_size, 0), 0, 446 MapMemoryBlock(map_address, std::make_shared<PhysicalMemory>(map_size, 0), 0,
446 map_size, MemoryState::Heap, VMAPermission::None); 447 map_size, MemoryState::Heap, VMAPermission::None);
447 ASSERT_MSG(remap_res.Succeeded(), "UnmapPhysicalMemory re-map on error"); 448 ASSERT_MSG(remap_res.Succeeded(), "UnmapPhysicalMemory re-map on error");
448 } 449 }
@@ -593,7 +594,7 @@ ResultCode VMManager::MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size, Mem
593 ASSERT_MSG(vma_offset + size <= vma->second.size, 594 ASSERT_MSG(vma_offset + size <= vma->second.size,
594 "Shared memory exceeds bounds of mapped block"); 595 "Shared memory exceeds bounds of mapped block");
595 596
596 const std::shared_ptr<std::vector<u8>>& backing_block = vma->second.backing_block; 597 const std::shared_ptr<PhysicalMemory>& backing_block = vma->second.backing_block;
597 const std::size_t backing_block_offset = vma->second.offset + vma_offset; 598 const std::size_t backing_block_offset = vma->second.offset + vma_offset;
598 599
599 CASCADE_RESULT(auto new_vma, 600 CASCADE_RESULT(auto new_vma,
@@ -606,7 +607,7 @@ ResultCode VMManager::MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size, Mem
606 return RESULT_SUCCESS; 607 return RESULT_SUCCESS;
607} 608}
608 609
609void VMManager::RefreshMemoryBlockMappings(const std::vector<u8>* block) { 610void VMManager::RefreshMemoryBlockMappings(const PhysicalMemory* block) {
610 // If this ever proves to have a noticeable performance impact, allow users of the function to 611 // If this ever proves to have a noticeable performance impact, allow users of the function to
611 // specify a specific range of addresses to limit the scan to. 612 // specify a specific range of addresses to limit the scan to.
612 for (const auto& p : vma_map) { 613 for (const auto& p : vma_map) {
@@ -764,7 +765,7 @@ void VMManager::MergeAdjacentVMA(VirtualMemoryArea& left, const VirtualMemoryAre
764 right.backing_block->begin() + right.offset + right.size); 765 right.backing_block->begin() + right.offset + right.size);
765 } else { 766 } else {
766 // Slow case: make a new memory block for left and right. 767 // Slow case: make a new memory block for left and right.
767 auto new_memory = std::make_shared<std::vector<u8>>(); 768 auto new_memory = std::make_shared<PhysicalMemory>();
768 new_memory->insert(new_memory->end(), left.backing_block->begin() + left.offset, 769 new_memory->insert(new_memory->end(), left.backing_block->begin() + left.offset,
769 left.backing_block->begin() + left.offset + left.size); 770 left.backing_block->begin() + left.offset + left.size);
770 new_memory->insert(new_memory->end(), right.backing_block->begin() + right.offset, 771 new_memory->insert(new_memory->end(), right.backing_block->begin() + right.offset,
diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h
index 0aecb7499..b18cde619 100644
--- a/src/core/hle/kernel/vm_manager.h
+++ b/src/core/hle/kernel/vm_manager.h
@@ -11,6 +11,7 @@
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "common/memory_hook.h" 12#include "common/memory_hook.h"
13#include "common/page_table.h" 13#include "common/page_table.h"
14#include "core/hle/kernel/physical_memory.h"
14#include "core/hle/result.h" 15#include "core/hle/result.h"
15#include "core/memory.h" 16#include "core/memory.h"
16 17
@@ -290,7 +291,7 @@ struct VirtualMemoryArea {
290 291
291 // Settings for type = AllocatedMemoryBlock 292 // Settings for type = AllocatedMemoryBlock
292 /// Memory block backing this VMA. 293 /// Memory block backing this VMA.
293 std::shared_ptr<std::vector<u8>> backing_block = nullptr; 294 std::shared_ptr<PhysicalMemory> backing_block = nullptr;
294 /// Offset into the backing_memory the mapping starts from. 295 /// Offset into the backing_memory the mapping starts from.
295 std::size_t offset = 0; 296 std::size_t offset = 0;
296 297
@@ -348,7 +349,7 @@ public:
348 * @param size Size of the mapping. 349 * @param size Size of the mapping.
349 * @param state MemoryState tag to attach to the VMA. 350 * @param state MemoryState tag to attach to the VMA.
350 */ 351 */
351 ResultVal<VMAHandle> MapMemoryBlock(VAddr target, std::shared_ptr<std::vector<u8>> block, 352 ResultVal<VMAHandle> MapMemoryBlock(VAddr target, std::shared_ptr<PhysicalMemory> block,
352 std::size_t offset, u64 size, MemoryState state, 353 std::size_t offset, u64 size, MemoryState state,
353 VMAPermission perm = VMAPermission::ReadWrite); 354 VMAPermission perm = VMAPermission::ReadWrite);
354 355
@@ -547,7 +548,7 @@ public:
547 * Scans all VMAs and updates the page table range of any that use the given vector as backing 548 * Scans all VMAs and updates the page table range of any that use the given vector as backing
548 * memory. This should be called after any operation that causes reallocation of the vector. 549 * memory. This should be called after any operation that causes reallocation of the vector.
549 */ 550 */
550 void RefreshMemoryBlockMappings(const std::vector<u8>* block); 551 void RefreshMemoryBlockMappings(const PhysicalMemory* block);
551 552
552 /// Dumps the address space layout to the log, for debugging 553 /// Dumps the address space layout to the log, for debugging
553 void LogLayout() const; 554 void LogLayout() const;
@@ -777,7 +778,7 @@ private:
777 // the entire virtual address space extents that bound the allocations, including any holes. 778 // the entire virtual address space extents that bound the allocations, including any holes.
778 // This makes deallocation and reallocation of holes fast and keeps process memory contiguous 779 // This makes deallocation and reallocation of holes fast and keeps process memory contiguous
779 // in the emulator address space, allowing Memory::GetPointer to be reasonably safe. 780 // in the emulator address space, allowing Memory::GetPointer to be reasonably safe.
780 std::shared_ptr<std::vector<u8>> heap_memory; 781 std::shared_ptr<PhysicalMemory> heap_memory;
781 782
782 // The end of the currently allocated heap. This is not an inclusive 783 // The end of the currently allocated heap. This is not an inclusive
783 // end of the range. This is essentially 'base_address + current_size'. 784 // end of the range. This is essentially 'base_address + current_size'.