summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Rowe <jroweboy@gmail.com>2017-08-24 02:17:44 +0200
committerGitHub <noreply@github.com>2017-08-24 02:17:44 +0200
commit61442d6afba2f7528ddf3bbee64e8c2d86a4f4a8 (patch)
treeb4b16a86d9959e14c01e43f68400342d7224c5a8
parentMerge pull request #2893 from Subv/not_schedule_main_thread (diff)
parentKernel/Memory: Acquire the global HLE lock when a memory read/write operation falls outside of the fast path, for it might perform an MMIO operation. (diff)
downloadyuzu-61442d6afba2f7528ddf3bbee64e8c2d86a4f4a8.tar
yuzu-61442d6afba2f7528ddf3bbee64e8c2d86a4f4a8.tar.gz
yuzu-61442d6afba2f7528ddf3bbee64e8c2d86a4f4a8.tar.bz2
yuzu-61442d6afba2f7528ddf3bbee64e8c2d86a4f4a8.tar.lz
yuzu-61442d6afba2f7528ddf3bbee64e8c2d86a4f4a8.tar.xz
yuzu-61442d6afba2f7528ddf3bbee64e8c2d86a4f4a8.tar.zst
yuzu-61442d6afba2f7528ddf3bbee64e8c2d86a4f4a8.zip
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/hle/kernel/kernel.h2
-rw-r--r--src/core/hle/lock.cpp11
-rw-r--r--src/core/hle/lock.h18
-rw-r--r--src/core/hle/svc.cpp8
-rw-r--r--src/core/memory.cpp9
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
hle/kernel/timer.cpp
hle/kernel/vm_manager.cpp
hle/kernel/wait_object.cpp
+ hle/lock.cpp
hle/romfs.cpp
hle/service/ac/ac.cpp
hle/service/ac/ac_i.cpp
@@ -256,6 +257,7 @@ set(HEADERS
hle/kernel/timer.h
hle/kernel/vm_manager.h
hle/kernel/wait_object.h
+ hle/lock.h
hle/result.h
hle/romfs.h
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);
/// Shutdown the kernel
void Shutdown();
-} // namespace
+} // 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 @@
+// Copyright 2017 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <core/hle/lock.h>
+
+namespace HLE {
+std::mutex g_hle_lock;
+}
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 @@
+// Copyright 2017 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <mutex>
+
+namespace HLE {
+/*
+ * Synchronizes access to the internal HLE kernel structures, it is acquired when a guest
+ * application thread performs a syscall. It should be acquired by any host threads that read or
+ * modify the HLE kernel state. Note: Any operation that directly or indirectly reads from or writes
+ * to the emulated memory is not protected by this mutex, and should be avoided in any threads other
+ * than the CPU thread.
+ */
+extern std::mutex g_hle_lock;
+} // 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 @@
#include "core/hle/kernel/timer.h"
#include "core/hle/kernel/vm_manager.h"
#include "core/hle/kernel/wait_object.h"
+#include "core/hle/lock.h"
#include "core/hle/result.h"
#include "core/hle/service/service.h"
@@ -1188,7 +1189,7 @@ struct FunctionDef {
Func* func;
const char* name;
};
-}
+} // namespace
static const FunctionDef SVC_Table[] = {
{0x00, nullptr, "Unknown"},
@@ -1332,6 +1333,9 @@ MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70));
void CallSVC(u32 immediate) {
MICROPROFILE_SCOPE(Kernel_SVC);
+ // Lock the global kernel mutex when we enter the kernel HLE.
+ std::lock_guard<std::mutex> lock(HLE::g_hle_lock);
+
const FunctionDef* info = GetSVCInfo(immediate);
if (info) {
if (info->func) {
@@ -1342,4 +1346,4 @@ void CallSVC(u32 immediate) {
}
}
-} // namespace
+} // 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 @@
#include "common/logging/log.h"
#include "common/swap.h"
#include "core/hle/kernel/process.h"
+#include "core/hle/lock.h"
#include "core/memory.h"
#include "core/memory_setup.h"
#include "core/mmio.h"
@@ -181,6 +182,9 @@ T Read(const VAddr vaddr) {
return value;
}
+ // The memory access might do an MMIO or cached access, so we have to lock the HLE kernel state
+ std::lock_guard<std::mutex> lock(HLE::g_hle_lock);
+
PageType type = current_page_table->attributes[vaddr >> PAGE_BITS];
switch (type) {
case PageType::Unmapped:
@@ -219,6 +223,9 @@ void Write(const VAddr vaddr, const T data) {
return;
}
+ // The memory access might do an MMIO or cached access, so we have to lock the HLE kernel state
+ std::lock_guard<std::mutex> lock(HLE::g_hle_lock);
+
PageType type = current_page_table->attributes[vaddr >> PAGE_BITS];
switch (type) {
case PageType::Unmapped:
@@ -746,4 +753,4 @@ boost::optional<VAddr> PhysicalToVirtualAddress(const PAddr addr) {
return boost::none;
}
-} // namespace
+} // namespace Memory