Merge pull request #6938 from lioncash/priv

Interpreter: Check processor privilege level when executing supervisor instructions
This commit is contained in:
Tilka 2018-05-22 10:04:53 +01:00 committed by GitHub
commit 5ac05725c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 2 deletions

View File

@ -7,6 +7,7 @@
#include "Core/ConfigManager.h" #include "Core/ConfigManager.h"
#include "Core/CoreTiming.h" #include "Core/CoreTiming.h"
#include "Core/HLE/HLE.h" #include "Core/HLE/HLE.h"
#include "Core/PowerPC/Interpreter/ExceptionUtils.h"
#include "Core/PowerPC/Interpreter/Interpreter.h" #include "Core/PowerPC/Interpreter/Interpreter.h"
#include "Core/PowerPC/MMU.h" #include "Core/PowerPC/MMU.h"
#include "Core/PowerPC/PowerPC.h" #include "Core/PowerPC/PowerPC.h"
@ -119,6 +120,12 @@ void Interpreter::HLEFunction(UGeckoInstruction inst)
void Interpreter::rfi(UGeckoInstruction inst) void Interpreter::rfi(UGeckoInstruction inst)
{ {
if (MSR.PR)
{
GenerateProgramException();
return;
}
// Restore saved bits from SRR1 to MSR. // Restore saved bits from SRR1 to MSR.
// Gecko/Broadway can save more bits than explicitly defined in ppc spec // Gecko/Broadway can save more bits than explicitly defined in ppc spec
const u32 mask = 0x87C0FFFF; const u32 mask = 0x87C0FFFF;

View File

@ -456,6 +456,12 @@ void Interpreter::dcbf(UGeckoInstruction inst)
void Interpreter::dcbi(UGeckoInstruction inst) void Interpreter::dcbi(UGeckoInstruction inst)
{ {
if (MSR.PR)
{
GenerateProgramException();
return;
}
// TODO: Implement some sort of L2 emulation. // TODO: Implement some sort of L2 emulation.
// TODO: Raise DSI if translation fails (except for direct-store segments). // TODO: Raise DSI if translation fails (except for direct-store segments).
@ -1054,6 +1060,12 @@ void Interpreter::sync(UGeckoInstruction inst)
void Interpreter::tlbie(UGeckoInstruction inst) void Interpreter::tlbie(UGeckoInstruction inst)
{ {
if (MSR.PR)
{
GenerateProgramException();
return;
}
// Invalidate TLB entry // Invalidate TLB entry
const u32 address = rGPR[inst.RB]; const u32 address = rGPR[inst.RB];
@ -1062,5 +1074,10 @@ void Interpreter::tlbie(UGeckoInstruction inst)
void Interpreter::tlbsync(UGeckoInstruction inst) void Interpreter::tlbsync(UGeckoInstruction inst)
{ {
if (MSR.PR)
{
GenerateProgramException();
}
// Ignored // Ignored
} }

View File

@ -137,24 +137,46 @@ void Interpreter::mtcrf(UGeckoInstruction inst)
void Interpreter::mfmsr(UGeckoInstruction inst) void Interpreter::mfmsr(UGeckoInstruction inst)
{ {
// Privileged? if (MSR.PR)
{
GenerateProgramException();
return;
}
rGPR[inst.RD] = MSR.Hex; rGPR[inst.RD] = MSR.Hex;
} }
void Interpreter::mfsr(UGeckoInstruction inst) void Interpreter::mfsr(UGeckoInstruction inst)
{ {
if (MSR.PR)
{
GenerateProgramException();
return;
}
rGPR[inst.RD] = PowerPC::ppcState.sr[inst.SR]; rGPR[inst.RD] = PowerPC::ppcState.sr[inst.SR];
} }
void Interpreter::mfsrin(UGeckoInstruction inst) void Interpreter::mfsrin(UGeckoInstruction inst)
{ {
if (MSR.PR)
{
GenerateProgramException();
return;
}
const u32 index = (rGPR[inst.RB] >> 28) & 0xF; const u32 index = (rGPR[inst.RB] >> 28) & 0xF;
rGPR[inst.RD] = PowerPC::ppcState.sr[index]; rGPR[inst.RD] = PowerPC::ppcState.sr[index];
} }
void Interpreter::mtmsr(UGeckoInstruction inst) void Interpreter::mtmsr(UGeckoInstruction inst)
{ {
// Privileged? if (MSR.PR)
{
GenerateProgramException();
return;
}
MSR.Hex = rGPR[inst.RS]; MSR.Hex = rGPR[inst.RS];
PowerPC::CheckExceptions(); PowerPC::CheckExceptions();
m_end_block = true; m_end_block = true;
@ -171,6 +193,12 @@ static void SetSR(u32 index, u32 value)
void Interpreter::mtsr(UGeckoInstruction inst) void Interpreter::mtsr(UGeckoInstruction inst)
{ {
if (MSR.PR)
{
GenerateProgramException();
return;
}
const u32 index = inst.SR; const u32 index = inst.SR;
const u32 value = rGPR[inst.RS]; const u32 value = rGPR[inst.RS];
SetSR(index, value); SetSR(index, value);
@ -178,6 +206,12 @@ void Interpreter::mtsr(UGeckoInstruction inst)
void Interpreter::mtsrin(UGeckoInstruction inst) void Interpreter::mtsrin(UGeckoInstruction inst)
{ {
if (MSR.PR)
{
GenerateProgramException();
return;
}
const u32 index = (rGPR[inst.RB] >> 28) & 0xF; const u32 index = (rGPR[inst.RB] >> 28) & 0xF;
const u32 value = rGPR[inst.RS]; const u32 value = rGPR[inst.RS];
SetSR(index, value); SetSR(index, value);