diff options
| author | 2023-12-11 20:21:23 -0500 | |
|---|---|---|
| committer | 2023-12-22 21:52:49 -0500 | |
| commit | 419055e484f0f0073d5832f7ded5fd3a3e5ad7de (patch) | |
| tree | 81ff70e80fff780d6fb92f78a2df18cfc323df78 /src/core/hle/kernel | |
| parent | Merge pull request #12412 from ameerj/gl-query-prims (diff) | |
| download | yuzu-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.cpp | 19 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_condition_variable.cpp | 8 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_process.cpp | 18 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_process.h | 15 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_thread.h | 6 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 13 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 4 |
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 | ||
| 29 | bool DecrementIfLessThan(Core::System& system, s32* out, KProcessAddress address, s32 value) { | 30 | bool 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 | ||
| 69 | bool UpdateIfEqual(Core::System& system, s32* out, KProcessAddress address, s32 value, | 70 | bool 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 | ||
| 31 | bool UpdateLockAtomic(Core::System& system, u32* out, KProcessAddress address, u32 if_zero, | 31 | bool 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) {} | |||
| 1128 | KProcess::KProcess(KernelCore& kernel) | 1128 | KProcess::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()} {} | ||
| 1132 | KProcess::~KProcess() = default; | 1133 | KProcess::~KProcess() = default; |
| 1133 | 1134 | ||
| 1134 | Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size, | 1135 | Result 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 | ||
| 1237 | void KProcess::InitializeInterfaces() { | 1238 | void 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 | ||
| 1308 | Core::Memory::Memory& KProcess::GetMemory() const { | 1313 | void 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 | ||
| 21 | namespace Kernel { | 23 | namespace 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 | ||
| 130 | private: | 135 | private: |
| 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 | ||
| 507 | public: | 520 | public: |
| 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 | ||
| 962 | Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() { | ||
| 963 | return *impl->exclusive_monitor; | ||
| 964 | } | ||
| 965 | |||
| 966 | const Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() const { | ||
| 967 | return *impl->exclusive_monitor; | ||
| 968 | } | ||
| 969 | |||
| 970 | KAutoObjectWithListContainer& KernelCore::ObjectListContainer() { | 957 | KAutoObjectWithListContainer& 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; |