diff options
Diffstat (limited to '')
| -rw-r--r-- | src/core/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 2 | ||||
| -rw-r--r-- | src/core/hle/lock.cpp | 11 | ||||
| -rw-r--r-- | src/core/hle/lock.h | 18 | ||||
| -rw-r--r-- | src/core/hle/svc.cpp | 8 | ||||
| -rw-r--r-- | src/core/memory.cpp | 9 |
6 files changed, 46 insertions, 4 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 53bd50eb2..662030782 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -59,6 +59,7 @@ set(SRCS | |||
| 59 | hle/kernel/timer.cpp | 59 | hle/kernel/timer.cpp |
| 60 | hle/kernel/vm_manager.cpp | 60 | hle/kernel/vm_manager.cpp |
| 61 | hle/kernel/wait_object.cpp | 61 | hle/kernel/wait_object.cpp |
| 62 | hle/lock.cpp | ||
| 62 | hle/romfs.cpp | 63 | hle/romfs.cpp |
| 63 | hle/service/ac/ac.cpp | 64 | hle/service/ac/ac.cpp |
| 64 | hle/service/ac/ac_i.cpp | 65 | hle/service/ac/ac_i.cpp |
| @@ -256,6 +257,7 @@ set(HEADERS | |||
| 256 | hle/kernel/timer.h | 257 | hle/kernel/timer.h |
| 257 | hle/kernel/vm_manager.h | 258 | hle/kernel/vm_manager.h |
| 258 | hle/kernel/wait_object.h | 259 | hle/kernel/wait_object.h |
| 260 | hle/lock.h | ||
| 259 | hle/result.h | 261 | hle/result.h |
| 260 | hle/romfs.h | 262 | hle/romfs.h |
| 261 | hle/service/ac/ac.h | 263 | hle/service/ac/ac.h |
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 142bb84b2..73fab3981 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -132,4 +132,4 @@ void Init(u32 system_mode); | |||
| 132 | /// Shutdown the kernel | 132 | /// Shutdown the kernel |
| 133 | void Shutdown(); | 133 | void Shutdown(); |
| 134 | 134 | ||
| 135 | } // namespace | 135 | } // namespace Kernel |
diff --git a/src/core/hle/lock.cpp b/src/core/hle/lock.cpp new file mode 100644 index 000000000..082f689c8 --- /dev/null +++ b/src/core/hle/lock.cpp | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | // Copyright 2017 Citra 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 <core/hle/lock.h> | ||
| 8 | |||
| 9 | namespace HLE { | ||
| 10 | std::mutex g_hle_lock; | ||
| 11 | } | ||
diff --git a/src/core/hle/lock.h b/src/core/hle/lock.h new file mode 100644 index 000000000..8265621e1 --- /dev/null +++ b/src/core/hle/lock.h | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | // Copyright 2017 Citra 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 <mutex> | ||
| 8 | |||
| 9 | namespace HLE { | ||
| 10 | /* | ||
| 11 | * Synchronizes access to the internal HLE kernel structures, it is acquired when a guest | ||
| 12 | * application thread performs a syscall. It should be acquired by any host threads that read or | ||
| 13 | * modify the HLE kernel state. Note: Any operation that directly or indirectly reads from or writes | ||
| 14 | * to the emulated memory is not protected by this mutex, and should be avoided in any threads other | ||
| 15 | * than the CPU thread. | ||
| 16 | */ | ||
| 17 | extern std::mutex g_hle_lock; | ||
| 18 | } // namespace HLE | ||
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index e4b803046..b98938cb4 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include "core/hle/kernel/timer.h" | 31 | #include "core/hle/kernel/timer.h" |
| 32 | #include "core/hle/kernel/vm_manager.h" | 32 | #include "core/hle/kernel/vm_manager.h" |
| 33 | #include "core/hle/kernel/wait_object.h" | 33 | #include "core/hle/kernel/wait_object.h" |
| 34 | #include "core/hle/lock.h" | ||
| 34 | #include "core/hle/result.h" | 35 | #include "core/hle/result.h" |
| 35 | #include "core/hle/service/service.h" | 36 | #include "core/hle/service/service.h" |
| 36 | 37 | ||
| @@ -1188,7 +1189,7 @@ struct FunctionDef { | |||
| 1188 | Func* func; | 1189 | Func* func; |
| 1189 | const char* name; | 1190 | const char* name; |
| 1190 | }; | 1191 | }; |
| 1191 | } | 1192 | } // namespace |
| 1192 | 1193 | ||
| 1193 | static const FunctionDef SVC_Table[] = { | 1194 | static const FunctionDef SVC_Table[] = { |
| 1194 | {0x00, nullptr, "Unknown"}, | 1195 | {0x00, nullptr, "Unknown"}, |
| @@ -1332,6 +1333,9 @@ MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70)); | |||
| 1332 | void CallSVC(u32 immediate) { | 1333 | void CallSVC(u32 immediate) { |
| 1333 | MICROPROFILE_SCOPE(Kernel_SVC); | 1334 | MICROPROFILE_SCOPE(Kernel_SVC); |
| 1334 | 1335 | ||
| 1336 | // Lock the global kernel mutex when we enter the kernel HLE. | ||
| 1337 | std::lock_guard<std::mutex> lock(HLE::g_hle_lock); | ||
| 1338 | |||
| 1335 | const FunctionDef* info = GetSVCInfo(immediate); | 1339 | const FunctionDef* info = GetSVCInfo(immediate); |
| 1336 | if (info) { | 1340 | if (info) { |
| 1337 | if (info->func) { | 1341 | if (info->func) { |
| @@ -1342,4 +1346,4 @@ void CallSVC(u32 immediate) { | |||
| 1342 | } | 1346 | } |
| 1343 | } | 1347 | } |
| 1344 | 1348 | ||
| 1345 | } // namespace | 1349 | } // namespace SVC |
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 65649d9d7..a3c5f4a9d 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include "common/logging/log.h" | 9 | #include "common/logging/log.h" |
| 10 | #include "common/swap.h" | 10 | #include "common/swap.h" |
| 11 | #include "core/hle/kernel/process.h" | 11 | #include "core/hle/kernel/process.h" |
| 12 | #include "core/hle/lock.h" | ||
| 12 | #include "core/memory.h" | 13 | #include "core/memory.h" |
| 13 | #include "core/memory_setup.h" | 14 | #include "core/memory_setup.h" |
| 14 | #include "core/mmio.h" | 15 | #include "core/mmio.h" |
| @@ -181,6 +182,9 @@ T Read(const VAddr vaddr) { | |||
| 181 | return value; | 182 | return value; |
| 182 | } | 183 | } |
| 183 | 184 | ||
| 185 | // The memory access might do an MMIO or cached access, so we have to lock the HLE kernel state | ||
| 186 | std::lock_guard<std::mutex> lock(HLE::g_hle_lock); | ||
| 187 | |||
| 184 | PageType type = current_page_table->attributes[vaddr >> PAGE_BITS]; | 188 | PageType type = current_page_table->attributes[vaddr >> PAGE_BITS]; |
| 185 | switch (type) { | 189 | switch (type) { |
| 186 | case PageType::Unmapped: | 190 | case PageType::Unmapped: |
| @@ -219,6 +223,9 @@ void Write(const VAddr vaddr, const T data) { | |||
| 219 | return; | 223 | return; |
| 220 | } | 224 | } |
| 221 | 225 | ||
| 226 | // The memory access might do an MMIO or cached access, so we have to lock the HLE kernel state | ||
| 227 | std::lock_guard<std::mutex> lock(HLE::g_hle_lock); | ||
| 228 | |||
| 222 | PageType type = current_page_table->attributes[vaddr >> PAGE_BITS]; | 229 | PageType type = current_page_table->attributes[vaddr >> PAGE_BITS]; |
| 223 | switch (type) { | 230 | switch (type) { |
| 224 | case PageType::Unmapped: | 231 | case PageType::Unmapped: |
| @@ -746,4 +753,4 @@ boost::optional<VAddr> PhysicalToVirtualAddress(const PAddr addr) { | |||
| 746 | return boost::none; | 753 | return boost::none; |
| 747 | } | 754 | } |
| 748 | 755 | ||
| 749 | } // namespace | 756 | } // namespace Memory |