Merge pull request #2839 from Subv/global_kernel_lock
Kernel/HLE: Use a mutex to synchronize access to the HLE kernel state between the cpu thread and any other possible threads that might touch the kernel (network thread, etc).master
commit
61442d6afb
|
|
@ -59,6 +59,7 @@ set(SRCS
|
||||||
hle/kernel/timer.cpp
|
hle/kernel/timer.cpp
|
||||||
hle/kernel/vm_manager.cpp
|
hle/kernel/vm_manager.cpp
|
||||||
hle/kernel/wait_object.cpp
|
hle/kernel/wait_object.cpp
|
||||||
|
hle/lock.cpp
|
||||||
hle/romfs.cpp
|
hle/romfs.cpp
|
||||||
hle/service/ac/ac.cpp
|
hle/service/ac/ac.cpp
|
||||||
hle/service/ac/ac_i.cpp
|
hle/service/ac/ac_i.cpp
|
||||||
|
|
@ -256,6 +257,7 @@ set(HEADERS
|
||||||
hle/kernel/timer.h
|
hle/kernel/timer.h
|
||||||
hle/kernel/vm_manager.h
|
hle/kernel/vm_manager.h
|
||||||
hle/kernel/wait_object.h
|
hle/kernel/wait_object.h
|
||||||
|
hle/lock.h
|
||||||
hle/result.h
|
hle/result.h
|
||||||
hle/romfs.h
|
hle/romfs.h
|
||||||
hle/service/ac/ac.h
|
hle/service/ac/ac.h
|
||||||
|
|
|
||||||
|
|
@ -132,4 +132,4 @@ void Init(u32 system_mode);
|
||||||
/// Shutdown the kernel
|
/// Shutdown the kernel
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
} // namespace
|
} // namespace Kernel
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
@ -31,6 +31,7 @@
|
||||||
#include "core/hle/kernel/timer.h"
|
#include "core/hle/kernel/timer.h"
|
||||||
#include "core/hle/kernel/vm_manager.h"
|
#include "core/hle/kernel/vm_manager.h"
|
||||||
#include "core/hle/kernel/wait_object.h"
|
#include "core/hle/kernel/wait_object.h"
|
||||||
|
#include "core/hle/lock.h"
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
|
||||||
|
|
@ -1188,7 +1189,7 @@ struct FunctionDef {
|
||||||
Func* func;
|
Func* func;
|
||||||
const char* name;
|
const char* name;
|
||||||
};
|
};
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
static const FunctionDef SVC_Table[] = {
|
static const FunctionDef SVC_Table[] = {
|
||||||
{0x00, nullptr, "Unknown"},
|
{0x00, nullptr, "Unknown"},
|
||||||
|
|
@ -1332,6 +1333,9 @@ MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70));
|
||||||
void CallSVC(u32 immediate) {
|
void CallSVC(u32 immediate) {
|
||||||
MICROPROFILE_SCOPE(Kernel_SVC);
|
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);
|
const FunctionDef* info = GetSVCInfo(immediate);
|
||||||
if (info) {
|
if (info) {
|
||||||
if (info->func) {
|
if (info->func) {
|
||||||
|
|
@ -1342,4 +1346,4 @@ void CallSVC(u32 immediate) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace SVC
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
|
#include "core/hle/lock.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
#include "core/memory_setup.h"
|
#include "core/memory_setup.h"
|
||||||
#include "core/mmio.h"
|
#include "core/mmio.h"
|
||||||
|
|
@ -181,6 +182,9 @@ T Read(const VAddr vaddr) {
|
||||||
return value;
|
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];
|
PageType type = current_page_table->attributes[vaddr >> PAGE_BITS];
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PageType::Unmapped:
|
case PageType::Unmapped:
|
||||||
|
|
@ -219,6 +223,9 @@ void Write(const VAddr vaddr, const T data) {
|
||||||
return;
|
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];
|
PageType type = current_page_table->attributes[vaddr >> PAGE_BITS];
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PageType::Unmapped:
|
case PageType::Unmapped:
|
||||||
|
|
@ -746,4 +753,4 @@ boost::optional<VAddr> PhysicalToVirtualAddress(const PAddr addr) {
|
||||||
return boost::none;
|
return boost::none;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace Memory
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue