summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
authorGravatar Liam2023-12-11 20:21:23 -0500
committerGravatar Liam2023-12-22 21:52:49 -0500
commit419055e484f0f0073d5832f7ded5fd3a3e5ad7de (patch)
tree81ff70e80fff780d6fb92f78a2df18cfc323df78 /src/core/hle/kernel
parentMerge pull request #12412 from ameerj/gl-query-prims (diff)
downloadyuzu-419055e484f0f0073d5832f7ded5fd3a3e5ad7de.tar.gz
yuzu-419055e484f0f0073d5832f7ded5fd3a3e5ad7de.tar.xz
yuzu-419055e484f0f0073d5832f7ded5fd3a3e5ad7de.zip
kernel: instantiate memory separately for each guest process
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/k_address_arbiter.cpp19
-rw-r--r--src/core/hle/kernel/k_condition_variable.cpp8
-rw-r--r--src/core/hle/kernel/k_process.cpp18
-rw-r--r--src/core/hle/kernel/k_process.h15
-rw-r--r--src/core/hle/kernel/k_thread.h6
-rw-r--r--src/core/hle/kernel/kernel.cpp13
-rw-r--r--src/core/hle/kernel/kernel.h4
7 files changed, 41 insertions, 42 deletions
diff --git a/src/core/hle/kernel/k_address_arbiter.cpp b/src/core/hle/kernel/k_address_arbiter.cpp
index 78d43d729..48889253d 100644
--- a/src/core/hle/kernel/k_address_arbiter.cpp
+++ b/src/core/hle/kernel/k_address_arbiter.cpp
@@ -4,6 +4,7 @@
4#include "core/arm/exclusive_monitor.h" 4#include "core/arm/exclusive_monitor.h"
5#include "core/core.h" 5#include "core/core.h"
6#include "core/hle/kernel/k_address_arbiter.h" 6#include "core/hle/kernel/k_address_arbiter.h"
7#include "core/hle/kernel/k_process.h"
7#include "core/hle/kernel/k_scheduler.h" 8#include "core/hle/kernel/k_scheduler.h"
8#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" 9#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
9#include "core/hle/kernel/k_thread.h" 10#include "core/hle/kernel/k_thread.h"
@@ -26,9 +27,9 @@ bool ReadFromUser(KernelCore& kernel, s32* out, KProcessAddress address) {
26 return true; 27 return true;
27} 28}
28 29
29bool DecrementIfLessThan(Core::System& system, s32* out, KProcessAddress address, s32 value) { 30bool DecrementIfLessThan(KernelCore& kernel, s32* out, KProcessAddress address, s32 value) {
30 auto& monitor = system.Monitor(); 31 auto& monitor = GetCurrentProcess(kernel).GetExclusiveMonitor();
31 const auto current_core = system.Kernel().CurrentPhysicalCoreIndex(); 32 const auto current_core = kernel.CurrentPhysicalCoreIndex();
32 33
33 // NOTE: If scheduler lock is not held here, interrupt disable is required. 34 // NOTE: If scheduler lock is not held here, interrupt disable is required.
34 // KScopedInterruptDisable di; 35 // KScopedInterruptDisable di;
@@ -66,10 +67,10 @@ bool DecrementIfLessThan(Core::System& system, s32* out, KProcessAddress address
66 return true; 67 return true;
67} 68}
68 69
69bool UpdateIfEqual(Core::System& system, s32* out, KProcessAddress address, s32 value, 70bool UpdateIfEqual(KernelCore& kernel, s32* out, KProcessAddress address, s32 value,
70 s32 new_value) { 71 s32 new_value) {
71 auto& monitor = system.Monitor(); 72 auto& monitor = GetCurrentProcess(kernel).GetExclusiveMonitor();
72 const auto current_core = system.Kernel().CurrentPhysicalCoreIndex(); 73 const auto current_core = kernel.CurrentPhysicalCoreIndex();
73 74
74 // NOTE: If scheduler lock is not held here, interrupt disable is required. 75 // NOTE: If scheduler lock is not held here, interrupt disable is required.
75 // KScopedInterruptDisable di; 76 // KScopedInterruptDisable di;
@@ -159,7 +160,7 @@ Result KAddressArbiter::SignalAndIncrementIfEqual(uint64_t addr, s32 value, s32
159 160
160 // Check the userspace value. 161 // Check the userspace value.
161 s32 user_value{}; 162 s32 user_value{};
162 R_UNLESS(UpdateIfEqual(m_system, std::addressof(user_value), addr, value, value + 1), 163 R_UNLESS(UpdateIfEqual(m_kernel, std::addressof(user_value), addr, value, value + 1),
163 ResultInvalidCurrentMemory); 164 ResultInvalidCurrentMemory);
164 R_UNLESS(user_value == value, ResultInvalidState); 165 R_UNLESS(user_value == value, ResultInvalidState);
165 166
@@ -219,7 +220,7 @@ Result KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(uint64_t addr, s32
219 s32 user_value{}; 220 s32 user_value{};
220 bool succeeded{}; 221 bool succeeded{};
221 if (value != new_value) { 222 if (value != new_value) {
222 succeeded = UpdateIfEqual(m_system, std::addressof(user_value), addr, value, new_value); 223 succeeded = UpdateIfEqual(m_kernel, std::addressof(user_value), addr, value, new_value);
223 } else { 224 } else {
224 succeeded = ReadFromUser(m_kernel, std::addressof(user_value), addr); 225 succeeded = ReadFromUser(m_kernel, std::addressof(user_value), addr);
225 } 226 }
@@ -262,7 +263,7 @@ Result KAddressArbiter::WaitIfLessThan(uint64_t addr, s32 value, bool decrement,
262 s32 user_value{}; 263 s32 user_value{};
263 bool succeeded{}; 264 bool succeeded{};
264 if (decrement) { 265 if (decrement) {
265 succeeded = DecrementIfLessThan(m_system, std::addressof(user_value), addr, value); 266 succeeded = DecrementIfLessThan(m_kernel, std::addressof(user_value), addr, value);
266 } else { 267 } else {
267 succeeded = ReadFromUser(m_kernel, std::addressof(user_value), addr); 268 succeeded = ReadFromUser(m_kernel, std::addressof(user_value), addr);
268 } 269 }
diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp
index 7633a51fb..94ea3527a 100644
--- a/src/core/hle/kernel/k_condition_variable.cpp
+++ b/src/core/hle/kernel/k_condition_variable.cpp
@@ -28,10 +28,10 @@ bool WriteToUser(KernelCore& kernel, KProcessAddress address, const u32* p) {
28 return true; 28 return true;
29} 29}
30 30
31bool UpdateLockAtomic(Core::System& system, u32* out, KProcessAddress address, u32 if_zero, 31bool UpdateLockAtomic(KernelCore& kernel, u32* out, KProcessAddress address, u32 if_zero,
32 u32 new_orr_mask) { 32 u32 new_orr_mask) {
33 auto& monitor = system.Monitor(); 33 auto& monitor = GetCurrentProcess(kernel).GetExclusiveMonitor();
34 const auto current_core = system.Kernel().CurrentPhysicalCoreIndex(); 34 const auto current_core = kernel.CurrentPhysicalCoreIndex();
35 35
36 u32 expected{}; 36 u32 expected{};
37 37
@@ -208,7 +208,7 @@ void KConditionVariable::SignalImpl(KThread* thread) {
208 // TODO(bunnei): We should call CanAccessAtomic(..) here. 208 // TODO(bunnei): We should call CanAccessAtomic(..) here.
209 can_access = true; 209 can_access = true;
210 if (can_access) [[likely]] { 210 if (can_access) [[likely]] {
211 UpdateLockAtomic(m_system, std::addressof(prev_tag), address, own_tag, 211 UpdateLockAtomic(m_kernel, std::addressof(prev_tag), address, own_tag,
212 Svc::HandleWaitMask); 212 Svc::HandleWaitMask);
213 } 213 }
214 } 214 }
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index 3a2635e1f..905d141ea 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -1128,7 +1128,8 @@ void KProcess::Switch(KProcess* cur_process, KProcess* next_process) {}
1128KProcess::KProcess(KernelCore& kernel) 1128KProcess::KProcess(KernelCore& kernel)
1129 : KAutoObjectWithSlabHeapAndContainer(kernel), m_page_table{kernel}, m_state_lock{kernel}, 1129 : KAutoObjectWithSlabHeapAndContainer(kernel), m_page_table{kernel}, m_state_lock{kernel},
1130 m_list_lock{kernel}, m_cond_var{kernel.System()}, m_address_arbiter{kernel.System()}, 1130 m_list_lock{kernel}, m_cond_var{kernel.System()}, m_address_arbiter{kernel.System()},
1131 m_handle_table{kernel} {} 1131 m_handle_table{kernel}, m_dirty_memory_managers{}, m_exclusive_monitor{},
1132 m_memory{kernel.System()} {}
1132KProcess::~KProcess() = default; 1133KProcess::~KProcess() = default;
1133 1134
1134Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size, 1135Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size,
@@ -1235,7 +1236,11 @@ void KProcess::LoadModule(CodeSet code_set, KProcessAddress base_addr) {
1235} 1236}
1236 1237
1237void KProcess::InitializeInterfaces() { 1238void KProcess::InitializeInterfaces() {
1239 m_exclusive_monitor =
1240 Core::MakeExclusiveMonitor(this->GetMemory(), Core::Hardware::NUM_CPU_CORES);
1241
1238 this->GetMemory().SetCurrentPageTable(*this); 1242 this->GetMemory().SetCurrentPageTable(*this);
1243 this->GetMemory().SetGPUDirtyManagers(m_dirty_memory_managers);
1239 1244
1240#ifdef HAS_NCE 1245#ifdef HAS_NCE
1241 if (this->Is64Bit() && Settings::IsNceEnabled()) { 1246 if (this->Is64Bit() && Settings::IsNceEnabled()) {
@@ -1248,13 +1253,13 @@ void KProcess::InitializeInterfaces() {
1248 for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { 1253 for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
1249 m_arm_interfaces[i] = std::make_unique<Core::ArmDynarmic64>( 1254 m_arm_interfaces[i] = std::make_unique<Core::ArmDynarmic64>(
1250 m_kernel.System(), m_kernel.IsMulticore(), this, 1255 m_kernel.System(), m_kernel.IsMulticore(), this,
1251 static_cast<Core::DynarmicExclusiveMonitor&>(m_kernel.GetExclusiveMonitor()), i); 1256 static_cast<Core::DynarmicExclusiveMonitor&>(*m_exclusive_monitor), i);
1252 } 1257 }
1253 } else { 1258 } else {
1254 for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { 1259 for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
1255 m_arm_interfaces[i] = std::make_unique<Core::ArmDynarmic32>( 1260 m_arm_interfaces[i] = std::make_unique<Core::ArmDynarmic32>(
1256 m_kernel.System(), m_kernel.IsMulticore(), this, 1261 m_kernel.System(), m_kernel.IsMulticore(), this,
1257 static_cast<Core::DynarmicExclusiveMonitor&>(m_kernel.GetExclusiveMonitor()), i); 1262 static_cast<Core::DynarmicExclusiveMonitor&>(*m_exclusive_monitor), i);
1258 } 1263 }
1259 } 1264 }
1260} 1265}
@@ -1305,9 +1310,10 @@ bool KProcess::RemoveWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointT
1305 return true; 1310 return true;
1306} 1311}
1307 1312
1308Core::Memory::Memory& KProcess::GetMemory() const { 1313void KProcess::GatherGPUDirtyMemory(std::function<void(VAddr, size_t)>& callback) {
1309 // TODO: per-process memory 1314 for (auto& manager : m_dirty_memory_managers) {
1310 return m_kernel.System().ApplicationMemory(); 1315 manager.Gather(callback);
1316 }
1311} 1317}
1312 1318
1313} // namespace Kernel 1319} // namespace Kernel
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h
index 4b114e39b..53c0e3316 100644
--- a/src/core/hle/kernel/k_process.h
+++ b/src/core/hle/kernel/k_process.h
@@ -7,6 +7,7 @@
7 7
8#include "core/arm/arm_interface.h" 8#include "core/arm/arm_interface.h"
9#include "core/file_sys/program_metadata.h" 9#include "core/file_sys/program_metadata.h"
10#include "core/gpu_dirty_memory_manager.h"
10#include "core/hle/kernel/code_set.h" 11#include "core/hle/kernel/code_set.h"
11#include "core/hle/kernel/k_address_arbiter.h" 12#include "core/hle/kernel/k_address_arbiter.h"
12#include "core/hle/kernel/k_capabilities.h" 13#include "core/hle/kernel/k_capabilities.h"
@@ -17,6 +18,7 @@
17#include "core/hle/kernel/k_system_resource.h" 18#include "core/hle/kernel/k_system_resource.h"
18#include "core/hle/kernel/k_thread.h" 19#include "core/hle/kernel/k_thread.h"
19#include "core/hle/kernel/k_thread_local_page.h" 20#include "core/hle/kernel/k_thread_local_page.h"
21#include "core/memory.h"
20 22
21namespace Kernel { 23namespace Kernel {
22 24
@@ -126,6 +128,9 @@ private:
126#ifdef HAS_NCE 128#ifdef HAS_NCE
127 std::unordered_map<u64, u64> m_post_handlers{}; 129 std::unordered_map<u64, u64> m_post_handlers{};
128#endif 130#endif
131 std::array<Core::GPUDirtyMemoryManager, Core::Hardware::NUM_CPU_CORES> m_dirty_memory_managers;
132 std::unique_ptr<Core::ExclusiveMonitor> m_exclusive_monitor;
133 Core::Memory::Memory m_memory;
129 134
130private: 135private:
131 Result StartTermination(); 136 Result StartTermination();
@@ -502,7 +507,15 @@ public:
502 507
503 void InitializeInterfaces(); 508 void InitializeInterfaces();
504 509
505 Core::Memory::Memory& GetMemory() const; 510 Core::Memory::Memory& GetMemory() {
511 return m_memory;
512 }
513
514 void GatherGPUDirtyMemory(std::function<void(VAddr, size_t)>& callback);
515
516 Core::ExclusiveMonitor& GetExclusiveMonitor() const {
517 return *m_exclusive_monitor;
518 }
506 519
507public: 520public:
508 // Overridden parent functions. 521 // Overridden parent functions.
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index e9925d231..f13e232b2 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -314,11 +314,7 @@ public:
314 m_current_core_id = core; 314 m_current_core_id = core;
315 } 315 }
316 316
317 KProcess* GetOwnerProcess() { 317 KProcess* GetOwnerProcess() const {
318 return m_parent;
319 }
320
321 const KProcess* GetOwnerProcess() const {
322 return m_parent; 318 return m_parent;
323 } 319 }
324 320
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index e479dacde..2efca27c2 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -126,8 +126,6 @@ struct KernelCore::Impl {
126 126
127 preemption_event = nullptr; 127 preemption_event = nullptr;
128 128
129 exclusive_monitor.reset();
130
131 // Cleanup persistent kernel objects 129 // Cleanup persistent kernel objects
132 auto CleanupObject = [](KAutoObject* obj) { 130 auto CleanupObject = [](KAutoObject* obj) {
133 if (obj) { 131 if (obj) {
@@ -191,8 +189,6 @@ struct KernelCore::Impl {
191 } 189 }
192 190
193 void InitializePhysicalCores() { 191 void InitializePhysicalCores() {
194 exclusive_monitor =
195 Core::MakeExclusiveMonitor(system.ApplicationMemory(), Core::Hardware::NUM_CPU_CORES);
196 for (u32 i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { 192 for (u32 i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
197 const s32 core{static_cast<s32>(i)}; 193 const s32 core{static_cast<s32>(i)};
198 194
@@ -805,7 +801,6 @@ struct KernelCore::Impl {
805 std::mutex server_lock; 801 std::mutex server_lock;
806 std::vector<std::unique_ptr<Service::ServerManager>> server_managers; 802 std::vector<std::unique_ptr<Service::ServerManager>> server_managers;
807 803
808 std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor;
809 std::array<std::unique_ptr<Kernel::PhysicalCore>, Core::Hardware::NUM_CPU_CORES> cores; 804 std::array<std::unique_ptr<Kernel::PhysicalCore>, Core::Hardware::NUM_CPU_CORES> cores;
810 805
811 // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others 806 // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others
@@ -959,14 +954,6 @@ Kernel::KHardwareTimer& KernelCore::HardwareTimer() {
959 return *impl->hardware_timer; 954 return *impl->hardware_timer;
960} 955}
961 956
962Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() {
963 return *impl->exclusive_monitor;
964}
965
966const Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() const {
967 return *impl->exclusive_monitor;
968}
969
970KAutoObjectWithListContainer& KernelCore::ObjectListContainer() { 957KAutoObjectWithListContainer& KernelCore::ObjectListContainer() {
971 return *impl->global_object_list_container; 958 return *impl->global_object_list_container;
972} 959}
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 78c88902c..fefd7aaba 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -170,10 +170,6 @@ public:
170 /// Stops execution of 'id' core, in order to reschedule a new thread. 170 /// Stops execution of 'id' core, in order to reschedule a new thread.
171 void PrepareReschedule(std::size_t id); 171 void PrepareReschedule(std::size_t id);
172 172
173 Core::ExclusiveMonitor& GetExclusiveMonitor();
174
175 const Core::ExclusiveMonitor& GetExclusiveMonitor() const;
176
177 KAutoObjectWithListContainer& ObjectListContainer(); 173 KAutoObjectWithListContainer& ObjectListContainer();
178 174
179 const KAutoObjectWithListContainer& ObjectListContainer() const; 175 const KAutoObjectWithListContainer& ObjectListContainer() const;