[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH for-6.2 06/43] target/mips: Implement do_unaligned_access for use
From: |
Richard Henderson |
Subject: |
[PATCH for-6.2 06/43] target/mips: Implement do_unaligned_access for user-only |
Date: |
Wed, 28 Jul 2021 14:46:10 -1000 |
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/mips/cpu_loop.c | 20 ++++++++++++++++----
target/mips/cpu.c | 2 +-
target/mips/tcg/op_helper.c | 3 +--
target/mips/tcg/user/tlb_helper.c | 23 +++++++++++------------
4 files changed, 29 insertions(+), 19 deletions(-)
diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
index 9d813ece4e..51f4eb65a6 100644
--- a/linux-user/mips/cpu_loop.c
+++ b/linux-user/mips/cpu_loop.c
@@ -158,12 +158,24 @@ done_syscall:
break;
case EXCP_TLBL:
case EXCP_TLBS:
- case EXCP_AdEL:
- case EXCP_AdES:
info.si_signo = TARGET_SIGSEGV;
info.si_errno = 0;
- /* XXX: check env->error_code */
- info.si_code = TARGET_SEGV_MAPERR;
+ info.si_code = (env->error_code & EXCP_TLB_NOMATCH
+ ? TARGET_SEGV_MAPERR : TARGET_SEGV_ACCERR);
+ info._sifields._sigfault._addr = env->CP0_BadVAddr;
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ break;
+ case EXCP_AdEL:
+ case EXCP_AdES:
+ /*
+ * Note that on real hw AdE is also raised for access to a
+ * kernel address from user mode instead of a TLB error.
+ * For simplicity, we do not distinguish this in the user
+ * version of mips_cpu_tlb_fill so only unaligned comes here.
+ */
+ info.si_signo = TARGET_SIGBUS;
+ info.si_errno = 0;
+ info.si_code = TARGET_BUS_ADRALN;
info._sifields._sigfault._addr = env->CP0_BadVAddr;
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index d426918291..a1658af910 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -541,11 +541,11 @@ static const struct TCGCPUOps mips_tcg_ops = {
.synchronize_from_tb = mips_cpu_synchronize_from_tb,
.cpu_exec_interrupt = mips_cpu_exec_interrupt,
.tlb_fill = mips_cpu_tlb_fill,
+ .do_unaligned_access = mips_cpu_do_unaligned_access,
#if !defined(CONFIG_USER_ONLY)
.do_interrupt = mips_cpu_do_interrupt,
.do_transaction_failed = mips_cpu_do_transaction_failed,
- .do_unaligned_access = mips_cpu_do_unaligned_access,
.io_recompile_replay_branch = mips_io_recompile_replay_branch,
#endif /* !CONFIG_USER_ONLY */
};
diff --git a/target/mips/tcg/op_helper.c b/target/mips/tcg/op_helper.c
index fafbf1faca..0b874823e4 100644
--- a/target/mips/tcg/op_helper.c
+++ b/target/mips/tcg/op_helper.c
@@ -375,8 +375,6 @@ void helper_pmon(CPUMIPSState *env, int function)
}
}
-#if !defined(CONFIG_USER_ONLY)
-
void mips_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
MMUAccessType access_type,
int mmu_idx, uintptr_t retaddr)
@@ -402,6 +400,7 @@ void mips_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
do_raise_exception_err(env, excp, error_code, retaddr);
}
+#if !defined(CONFIG_USER_ONLY)
void mips_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
vaddr addr, unsigned size,
MMUAccessType access_type,
diff --git a/target/mips/tcg/user/tlb_helper.c
b/target/mips/tcg/user/tlb_helper.c
index b835144b82..61a99356e9 100644
--- a/target/mips/tcg/user/tlb_helper.c
+++ b/target/mips/tcg/user/tlb_helper.c
@@ -26,24 +26,23 @@ static void raise_mmu_exception(CPUMIPSState *env,
target_ulong address,
MMUAccessType access_type)
{
CPUState *cs = env_cpu(env);
+ int error_code = 0;
+ int flags;
- env->error_code = 0;
if (access_type == MMU_INST_FETCH) {
- env->error_code |= EXCP_INST_NOTAVAIL;
+ error_code |= EXCP_INST_NOTAVAIL;
}
- /* Reference to kernel address from user mode or supervisor mode */
- /* Reference to supervisor address from user mode */
- if (access_type == MMU_DATA_STORE) {
- cs->exception_index = EXCP_AdES;
- } else {
- cs->exception_index = EXCP_AdEL;
+ flags = page_get_flags(address);
+ if (!(flags & PAGE_VALID)) {
+ error_code |= EXCP_TLB_NOMATCH;
}
- /* Raise exception */
- if (!(env->hflags & MIPS_HFLAG_DM)) {
- env->CP0_BadVAddr = address;
- }
+ cs->exception_index = (access_type == MMU_DATA_STORE
+ ? EXCP_TLBS : EXCP_TLBL);
+
+ env->error_code = error_code;
+ env->CP0_BadVAddr = address;
}
bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
--
2.25.1
- Re: [PATCH for-6.2 05/43] target/microblaze: Implement do_unaligned_access for user-only, (continued)
[PATCH for-6.2 04/43] target/hppa: Implement do_unaligned_access for user-only, Richard Henderson, 2021/07/28
[PATCH for-6.2 07/43] target/ppc: Set fault address in ppc_cpu_do_unaligned_access, Richard Henderson, 2021/07/28
[PATCH for-6.2 06/43] target/mips: Implement do_unaligned_access for user-only,
Richard Henderson <=
[PATCH for-6.2 09/43] target/riscv: Implement do_unaligned_access for user-only, Richard Henderson, 2021/07/28
[PATCH for-6.2 08/43] target/ppc: Implement do_unaligned_access for user-only, Richard Henderson, 2021/07/28
[PATCH for-6.2 10/43] target/s390x: Implement do_unaligned_access for user-only, Richard Henderson, 2021/07/28
[PATCH for-6.2 16/43] target/xtensa: Implement do_unaligned_access for user-only, Richard Henderson, 2021/07/28
[PATCH for-6.2 12/43] target/sh4: Implement do_unaligned_access for user-only, Richard Henderson, 2021/07/28