clean pkeys when not enabled to avoid side-effects

This commit is contained in:
Stanislav Shwartsman 2016-03-19 21:15:56 +00:00
parent 5b481fe34d
commit e4832af5ab
4 changed files with 19 additions and 35 deletions

View File

@ -5026,7 +5026,6 @@ public: // for now...
#if BX_SUPPORT_PKEYS
BX_SMF void set_PKRU(Bit32u pkru);
BX_SMF void disable_PKRU();
#endif
#if BX_SUPPORT_FPU

View File

@ -1314,10 +1314,7 @@ bx_bool BX_CPU_C::SetCR4(bxInstruction_c *i, bx_address val)
// re-calculate protection keys if CR4.PKE was set
#if BX_SUPPORT_PKEYS
if (long_mode() && BX_CPU_THIS_PTR cr4.get_PKE())
set_PKRU(BX_CPU_THIS_PTR pkru);
else
disable_PKRU();
set_PKRU(BX_CPU_THIS_PTR pkru);
#endif
return 1;

View File

@ -600,10 +600,7 @@ void BX_CPU_C::after_restore_state(void)
#endif
#if BX_SUPPORT_PKEYS
if (long_mode() && BX_CPU_THIS_PTR cr4.get_PKE())
set_PKRU(BX_CPU_THIS_PTR pkru);
else
disable_PKRU();
set_PKRU(BX_CPU_THIS_PTR pkru);
#endif
assert_checks();

View File

@ -324,14 +324,6 @@ void BX_CPU_C::handleCpuModeChange(void)
// switching between compatibility and long64 mode also affect SS.BASE
// which is always zero in long64 mode
invalidate_stack_cache();
// re-initialize protection keys if entered long mode and CR4.PKE=1
#if BX_SUPPORT_PKEYS
if (BX_CPU_THIS_PTR cr4.get_PKE())
set_PKRU(BX_CPU_THIS_PTR pkru);
else
disable_PKRU();
#endif
}
else
#endif
@ -364,6 +356,11 @@ void BX_CPU_C::handleCpuModeChange(void)
#endif
#endif
// re-initialize protection keys
#if BX_SUPPORT_PKEYS
set_PKRU(BX_CPU_THIS_PTR pkru);
#endif
if (mode != BX_CPU_THIS_PTR cpu_mode) {
BX_DEBUG(("%s activated", cpu_mode_string(BX_CPU_THIS_PTR cpu_mode)));
#if BX_DEBUGGER
@ -1455,29 +1452,23 @@ void BX_CPU_C::set_PKRU(Bit32u pkru)
BX_CPU_THIS_PTR rd_pkey[i] = BX_CPU_THIS_PTR wr_pkey[i] =
TLB_SysReadOK | TLB_UserReadOK | TLB_SysWriteOK | TLB_UserWriteOK;
// accessDisable bit set
if (pkru & (1<<(i*2))) {
BX_CPU_THIS_PTR rd_pkey[i] &= ~(TLB_UserReadOK | TLB_UserWriteOK);
BX_CPU_THIS_PTR wr_pkey[i] &= ~(TLB_UserReadOK | TLB_UserWriteOK);
}
if (long_mode() && BX_CPU_THIS_PTR cr4.get_PKE()) {
// accessDisable bit set
if (pkru & (1<<(i*2))) {
BX_CPU_THIS_PTR rd_pkey[i] &= ~(TLB_UserReadOK | TLB_UserWriteOK);
BX_CPU_THIS_PTR wr_pkey[i] &= ~(TLB_UserReadOK | TLB_UserWriteOK);
}
// writeDisable bit set
if (pkru & (1<<(i*2+1))) {
BX_CPU_THIS_PTR wr_pkey[i] &= ~(TLB_UserWriteOK);
if (BX_CPU_THIS_PTR cr0.get_WP())
BX_CPU_THIS_PTR wr_pkey[i] &= ~(TLB_SysWriteOK);
// writeDisable bit set
if (pkru & (1<<(i*2+1))) {
BX_CPU_THIS_PTR wr_pkey[i] &= ~(TLB_UserWriteOK);
if (BX_CPU_THIS_PTR cr0.get_WP())
BX_CPU_THIS_PTR wr_pkey[i] &= ~(TLB_SysWriteOK);
}
}
}
}
void BX_CPU_C::disable_PKRU()
{
for (unsigned i=0; i<16; i++) {
BX_CPU_THIS_PTR rd_pkey[i] = BX_CPU_THIS_PTR wr_pkey[i] =
TLB_SysReadOK | TLB_UserReadOK | TLB_SysWriteOK | TLB_UserWriteOK;
}
}
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RDPKRU(bxInstruction_c *i)
{
if (! BX_CPU_THIS_PTR cr4.get_PKE())