target-mips: fix page fault address for LWL/LWR/LDL/LDR

When a LWL, LWR, LDL or LDR instruction triggers a page fault, QEMU
currently reports the aligned address in CP0 BadVAddr, while the Windows
NT kernel expects the unaligned address.

This patch adds a byte access with the unaligned address at the
beginning of the LWL/LWR/LDL/LDR instructions to possibly trigger a page
fault and fill the QEMU TLB.

Backports commit 908680c6441ac468f4871d513f42be396ea0d264 from qemu
This commit is contained in:
Aurelien Jarno 2018-02-14 17:04:29 -05:00 committed by Lioncash
parent b045c2c99a
commit 3cc6b5251e
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -2149,6 +2149,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
break;
case OPC_LDL:
t1 = tcg_temp_new(tcg_ctx);
/* Do a byte access to possibly trigger a page
fault with the unaligned address. */
tcg_gen_qemu_ld_tl(ctx->uc, t1, t0, ctx->mem_idx, MO_UB);
tcg_gen_andi_tl(tcg_ctx, t1, t0, 7);
#ifndef TARGET_WORDS_BIGENDIAN
tcg_gen_xori_tl(tcg_ctx, t1, t1, 7);
@ -2170,6 +2173,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
break;
case OPC_LDR:
t1 = tcg_temp_new(tcg_ctx);
/* Do a byte access to possibly trigger a page
fault with the unaligned address. */
tcg_gen_qemu_ld_tl(ctx->uc, t1, t0, ctx->mem_idx, MO_UB);
tcg_gen_andi_tl(tcg_ctx, t1, t0, 7);
#ifdef TARGET_WORDS_BIGENDIAN
tcg_gen_xori_tl(tcg_ctx, t1, t1, 7);
@ -2236,6 +2242,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
break;
case OPC_LWL:
t1 = tcg_temp_new(tcg_ctx);
/* Do a byte access to possibly trigger a page
fault with the unaligned address. */
tcg_gen_qemu_ld_tl(ctx->uc, t1, t0, ctx->mem_idx, MO_UB);
tcg_gen_andi_tl(tcg_ctx, t1, t0, 3);
#ifndef TARGET_WORDS_BIGENDIAN
tcg_gen_xori_tl(tcg_ctx, t1, t1, 3);
@ -2258,6 +2267,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
break;
case OPC_LWR:
t1 = tcg_temp_new(tcg_ctx);
/* Do a byte access to possibly trigger a page
fault with the unaligned address. */
tcg_gen_qemu_ld_tl(ctx->uc, t1, t0, ctx->mem_idx, MO_UB);
tcg_gen_andi_tl(tcg_ctx, t1, t0, 3);
#ifdef TARGET_WORDS_BIGENDIAN
tcg_gen_xori_tl(tcg_ctx, t1, t1, 3);