From 0337ca116abe9b9b9877e6071ad0697188198885 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sun, 20 May 2018 15:16:16 -0400 Subject: [PATCH] Interpreter_SystemRegisters: Check processor privilege level in mfspr and mtspr If a program executing in user mode tries to write to any SPRs other than XER, LR, or CTR registers, then a program exception occurs. Similarly this also applies for reading SPRs as well, however the upper and lower timebase halves can also be read (but not written to). --- .../Interpreter_SystemRegisters.cpp | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp index 2c060f42bb..1bdee2fbf7 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp @@ -194,9 +194,13 @@ void Interpreter::mfspr(UGeckoInstruction inst) { const u32 index = ((inst.SPR & 0x1F) << 5) + ((inst.SPR >> 5) & 0x1F); - // TODO - check processor privilege level - many of these require privilege - // XER LR CTR are the only ones available in user mode, time base can be read too. - // GameCube games always run in superuser mode, but hey.... + // XER, LR, CTR, and timebase halves are the only ones available in user mode. + if (MSR.PR && index != SPR_XER && index != SPR_LR && index != SPR_CTR && index != SPR_TL && + index != SPR_TU) + { + PowerPC::ppcState.Exceptions |= EXCEPTION_PROGRAM; + return; + } switch (index) { @@ -237,13 +241,17 @@ void Interpreter::mfspr(UGeckoInstruction inst) void Interpreter::mtspr(UGeckoInstruction inst) { const u32 index = (inst.SPRU << 5) | (inst.SPRL & 0x1F); + + // XER, LR, and CTR are the only ones available to be written to in user mode + if (MSR.PR && index != SPR_XER && index != SPR_LR && index != SPR_CTR) + { + PowerPC::ppcState.Exceptions |= EXCEPTION_PROGRAM; + return; + } + const u32 old_value = rSPR(index); rSPR(index) = rGPR[inst.RD]; - // TODO - check processor privilege level - many of these require privilege - // XER LR CTR are the only ones available in user mode, time base can be read too. - // GameCube games always run in superuser mode, but hey.... - // Our DMA emulation is highly inaccurate - instead of properly emulating the queue // and so on, we simply make all DMA:s complete instantaneously.