diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 647371198c..ba6d7b80a7 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -7732,7 +7732,7 @@ static bool x86_cpu_has_work(CPUState *cs) return x86_cpu_pending_interrupt(cs, cs->interrupt_request) != 0; } -static int x86_cpu_mmu_index(CPUState *env, bool ifetch) +static int x86_cpu_mmu_index(CPUState *cs, bool ifetch) { CPUX86State *env = cpu_env(cs); int mmu_index_32 = (env->hflags & HF_CS64_MASK) ? 1 : 0; diff --git a/target/i386/cpu.h b/target/i386/cpu.h index ee4ad37202..952174bb6f 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -2326,6 +2326,12 @@ static inline bool is_mmu_index_user(int mmu_index) return (mmu_index & ~1) == MMU_USER64_IDX; } +static inline bool is_mmu_index_32(int mmu_index) +{ + assert(mmu_index < MMU_PHYS_IDX); + return mmu_index & 1; +} + static inline int cpu_mmu_index_kernel(CPUX86State *env) { int mmu_index_32 = (env->hflags & HF_LMA_MASK) ? 1 : 0; diff --git a/target/i386/tcg/sysemu/excp_helper.c b/target/i386/tcg/sysemu/excp_helper.c index b2c525e1a9..8bcdd2906d 100644 --- a/target/i386/tcg/sysemu/excp_helper.c +++ b/target/i386/tcg/sysemu/excp_helper.c @@ -558,6 +558,10 @@ static bool get_physical_address(CPUX86State *env, vaddr addr, break; default: + if (is_mmu_index_32(mmu_idx)) { + addr = (uint32_t)addr; + } + if (likely(env->cr[0] & CR0_PG_MASK)) { in.cr3 = env->cr[3]; in.mmu_idx = mmu_idx; @@ -581,14 +585,8 @@ static bool get_physical_address(CPUX86State *env, vaddr addr, break; } - /* Translation disabled. */ + /* No translation needed. */ out->paddr = addr & x86_get_a20_mask(env); -#ifdef TARGET_X86_64 - if (!(env->hflags & HF_LMA_MASK)) { - /* Without long mode we can only address 32bits in real mode */ - out->paddr = (uint32_t)out->paddr; - } -#endif out->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; out->page_size = TARGET_PAGE_SIZE; return true;