The xuseg and xsseg checks only tested UX and SX respectively; kernel and supervisor accesses must instead use the mode bit that applies to the current execution mode.
Allow supervisor and kernel mode to use xuseg when SX or KX is set, and allow kernel mode to use xsseg when KX is set. Signed-off-by: Kirill A. Korinsky <[email protected]> --- target/mips/system/physaddr.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/target/mips/system/physaddr.c b/target/mips/system/physaddr.c index 746dbf8aa4..626d7ccc4c 100644 --- a/target/mips/system/physaddr.c +++ b/target/mips/system/physaddr.c @@ -143,7 +143,9 @@ int get_physical_address(CPUMIPSState *env, hwaddr *physical, #if defined(TARGET_MIPS64) } else if (address < 0x4000000000000000ULL) { /* xuseg */ - if (UX && address <= (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) { + if (((user_mode && UX) || (supervisor_mode && SX) || + (kernel_mode && KX)) && + address <= (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) { ret = env->tlb->map_address(env, physical, prot, real_address, access_type); } else { @@ -151,8 +153,8 @@ int get_physical_address(CPUMIPSState *env, hwaddr *physical, } } else if (address < 0x8000000000000000ULL) { /* xsseg */ - if ((supervisor_mode || kernel_mode) && - SX && address <= (0x7FFFFFFFFFFFFFFFULL & env->SEGMask)) { + if (((supervisor_mode && SX) || (kernel_mode && KX)) && + address <= (0x7FFFFFFFFFFFFFFFULL & env->SEGMask)) { ret = env->tlb->map_address(env, physical, prot, real_address, access_type); } else { -- 2.54.0
