diff options
author | Aurelien Jarno <aurelien@aurel32.net> | 2015-07-14 17:45:16 +0200 |
---|---|---|
committer | Leon Alrae <leon.alrae@imgtec.com> | 2015-07-15 14:07:25 +0100 |
commit | 908680c6441ac468f4871d513f42be396ea0d264 (patch) | |
tree | 859583452660338766188f7f8dd438fabcc8774e /target-mips | |
parent | f01a361bfcce4bd0c439b0e051ef2a1e56727a44 (diff) |
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.
Cc: Leon Alrae <leon.alrae@imgtec.com>
Reported-by: Hervé Poussineau <hpoussin@reactos.org>
Tested-by: Hervé Poussineau <hpoussin@reactos.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
Diffstat (limited to 'target-mips')
-rw-r--r-- | target-mips/translate.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/target-mips/translate.c b/target-mips/translate.c index 4a1ffdbd94..d1de35ad30 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -2142,6 +2142,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, break; case OPC_LDL: t1 = tcg_temp_new(); + /* Do a byte access to possibly trigger a page + fault with the unaligned address. */ + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); tcg_gen_andi_tl(t1, t0, 7); #ifndef TARGET_WORDS_BIGENDIAN tcg_gen_xori_tl(t1, t1, 7); @@ -2163,6 +2166,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, break; case OPC_LDR: t1 = tcg_temp_new(); + /* Do a byte access to possibly trigger a page + fault with the unaligned address. */ + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); tcg_gen_andi_tl(t1, t0, 7); #ifdef TARGET_WORDS_BIGENDIAN tcg_gen_xori_tl(t1, t1, 7); @@ -2229,6 +2235,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, break; case OPC_LWL: t1 = tcg_temp_new(); + /* Do a byte access to possibly trigger a page + fault with the unaligned address. */ + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); tcg_gen_andi_tl(t1, t0, 3); #ifndef TARGET_WORDS_BIGENDIAN tcg_gen_xori_tl(t1, t1, 3); @@ -2251,6 +2260,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, break; case OPC_LWR: t1 = tcg_temp_new(); + /* Do a byte access to possibly trigger a page + fault with the unaligned address. */ + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); tcg_gen_andi_tl(t1, t0, 3); #ifdef TARGET_WORDS_BIGENDIAN tcg_gen_xori_tl(t1, t1, 3); |