From: Stafford Horne <shorne@gmail.com>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: QEMU Development <qemu-devel@nongnu.org>,
Richard Henderson <richard.henderson@linaro.org>,
Stafford Horne <shorne@gmail.com>
Subject: [Qemu-devel] [PULL 16/25] target/openrisc: Fix cpu_mmu_index
Date: Mon, 2 Jul 2018 22:57:57 +0900 [thread overview]
Message-ID: <20180702135806.7087-17-shorne@gmail.com> (raw)
In-Reply-To: <20180702135806.7087-1-shorne@gmail.com>
From: Richard Henderson <richard.henderson@linaro.org>
The code in cpu_mmu_index does not properly honor SR_DME.
This bug has workarounds elsewhere in that we flush the
tlb more often than necessary, on the state changes that
should be reflected in a change of mmu_index.
Fixing this means that we can respect the mmu_index that
is given to tlb_flush.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Stafford Horne <shorne@gmail.com>
---
target/openrisc/cpu.h | 23 +++++++++++++--------
target/openrisc/interrupt.c | 4 ----
target/openrisc/interrupt_helper.c | 15 +++-----------
target/openrisc/mmu.c | 33 +++++++++++++++++++++++++++---
target/openrisc/sys_helper.c | 4 ----
target/openrisc/translate.c | 2 +-
6 files changed, 49 insertions(+), 32 deletions(-)
diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index eaf6cdd40e..c3a968ec4d 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -385,9 +385,12 @@ void cpu_openrisc_count_stop(OpenRISCCPU *cpu);
#include "exec/cpu-all.h"
-#define TB_FLAGS_DFLAG 1
-#define TB_FLAGS_R0_0 2
+#define TB_FLAGS_SM SR_SM
+#define TB_FLAGS_DME SR_DME
+#define TB_FLAGS_IME SR_IME
#define TB_FLAGS_OVE SR_OVE
+#define TB_FLAGS_DFLAG 2 /* reuse SR_TEE */
+#define TB_FLAGS_R0_0 4 /* reuse SR_IEE */
static inline uint32_t cpu_get_gpr(const CPUOpenRISCState *env, int i)
{
@@ -405,17 +408,21 @@ static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env,
{
*pc = env->pc;
*cs_base = 0;
- *flags = (env->dflag
- | (cpu_get_gpr(env, 0) == 0 ? TB_FLAGS_R0_0 : 0)
- | (env->sr & SR_OVE));
+ *flags = (env->dflag ? TB_FLAGS_DFLAG : 0)
+ | (cpu_get_gpr(env, 0) ? 0 : TB_FLAGS_R0_0)
+ | (env->sr & (SR_SM | SR_DME | SR_IME | SR_OVE));
}
static inline int cpu_mmu_index(CPUOpenRISCState *env, bool ifetch)
{
- if (!(env->sr & SR_IME)) {
- return MMU_NOMMU_IDX;
+ int ret = MMU_NOMMU_IDX; /* mmu is disabled */
+
+ if (env->sr & (ifetch ? SR_IME : SR_DME)) {
+ /* The mmu is enabled; test supervisor state. */
+ ret = env->sr & SR_SM ? MMU_SUPERVISOR_IDX : MMU_USER_IDX;
}
- return (env->sr & SR_SM) == 0 ? MMU_USER_IDX : MMU_SUPERVISOR_IDX;
+
+ return ret;
}
static inline uint32_t cpu_get_sr(const CPUOpenRISCState *env)
diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c
index 23abcf29ed..138ad17f00 100644
--- a/target/openrisc/interrupt.c
+++ b/target/openrisc/interrupt.c
@@ -51,10 +51,6 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
env->eear = env->pc;
}
- /* For machine-state changed between user-mode and supervisor mode,
- we need flush TLB when we enter&exit EXCP. */
- tlb_flush(cs);
-
env->esr = cpu_get_sr(env);
env->sr &= ~SR_DME;
env->sr &= ~SR_IME;
diff --git a/target/openrisc/interrupt_helper.c b/target/openrisc/interrupt_helper.c
index a2e9003969..9c5489f5f7 100644
--- a/target/openrisc/interrupt_helper.c
+++ b/target/openrisc/interrupt_helper.c
@@ -25,16 +25,7 @@
void HELPER(rfe)(CPUOpenRISCState *env)
{
- OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
-#ifndef CONFIG_USER_ONLY
- int need_flush_tlb = (cpu->env.sr & (SR_SM | SR_IME | SR_DME)) ^
- (cpu->env.esr & (SR_SM | SR_IME | SR_DME));
- if (need_flush_tlb) {
- CPUState *cs = CPU(cpu);
- tlb_flush(cs);
- }
-#endif
- cpu->env.pc = cpu->env.epcr;
- cpu->env.lock_addr = -1;
- cpu_set_sr(&cpu->env, cpu->env.esr);
+ env->pc = env->epcr;
+ env->lock_addr = -1;
+ cpu_set_sr(env, env->esr);
}
diff --git a/target/openrisc/mmu.c b/target/openrisc/mmu.c
index 856969a7f2..b293b64e98 100644
--- a/target/openrisc/mmu.c
+++ b/target/openrisc/mmu.c
@@ -246,9 +246,36 @@ hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
void tlb_fill(CPUState *cs, target_ulong addr, int size,
MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
{
- int ret = openrisc_cpu_handle_mmu_fault(cs, addr, size,
- access_type, mmu_idx);
- if (ret) {
+ OpenRISCCPU *cpu = OPENRISC_CPU(cs);
+ int ret, prot = 0;
+ hwaddr physical = 0;
+
+ if (mmu_idx == MMU_NOMMU_IDX) {
+ ret = get_phys_nommu(&physical, &prot, addr);
+ } else {
+ bool super = mmu_idx == MMU_SUPERVISOR_IDX;
+ if (access_type == MMU_INST_FETCH) {
+ ret = get_phys_code(cpu, &physical, &prot, addr, 2, super);
+ } else {
+ ret = get_phys_data(cpu, &physical, &prot, addr,
+ access_type == MMU_DATA_STORE, super);
+ }
+ }
+
+ if (ret == TLBRET_MATCH) {
+ tlb_set_page(cs, addr & TARGET_PAGE_MASK,
+ physical & TARGET_PAGE_MASK, prot,
+ mmu_idx, TARGET_PAGE_SIZE);
+ } else if (ret < 0) {
+ int rw;
+ if (access_type == MMU_INST_FETCH) {
+ rw = 2;
+ } else if (access_type == MMU_DATA_STORE) {
+ rw = 1;
+ } else {
+ rw = 0;
+ }
+ cpu_openrisc_raise_mmu_exception(cpu, addr, rw, ret);
/* Raise Exception. */
cpu_loop_exit_restore(cs, retaddr);
}
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index c9702cd26c..852b219f9b 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -56,10 +56,6 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
break;
case TO_SPR(0, 17): /* SR */
- if ((env->sr & (SR_IME | SR_DME | SR_SM)) ^
- (rb & (SR_IME | SR_DME | SR_SM))) {
- tlb_flush(cs);
- }
cpu_set_sr(env, rb);
break;
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 64b5e84630..a271cd3903 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -55,7 +55,7 @@ static inline bool is_user(DisasContext *dc)
#ifdef CONFIG_USER_ONLY
return true;
#else
- return dc->mem_idx == MMU_USER_IDX;
+ return !(dc->tb_flags & TB_FLAGS_SM);
#endif
}
--
2.17.0
next prev parent reply other threads:[~2018-07-02 13:58 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-07-02 13:57 [Qemu-devel] [PULL 00/25] OpenRISC updates for 3.0 Stafford Horne
2018-07-02 13:57 ` [Qemu-devel] [PULL 01/25] target/openrisc: Fix mtspr shadow gprs Stafford Horne
2018-07-02 13:57 ` [Qemu-devel] [PULL 02/25] target/openrisc: Add print_insn_or1k Stafford Horne
2018-07-02 13:57 ` [Qemu-devel] [PULL 03/25] target/openrisc: Log interrupts Stafford Horne
2018-07-02 13:57 ` [Qemu-devel] [PULL 04/25] target/openrisc: Remove DISAS_JUMP & DISAS_TB_JUMP Stafford Horne
2018-07-02 13:57 ` [Qemu-devel] [PULL 05/25] target/openrisc: Use exit_tb instead of CPU_INTERRUPT_EXITTB Stafford Horne
2018-07-02 13:57 ` [Qemu-devel] [PULL 06/25] target/openrisc: Fix singlestep_enabled Stafford Horne
2018-07-02 13:57 ` [Qemu-devel] [PULL 07/25] target/openrisc: Link more translation blocks Stafford Horne
2018-07-02 13:57 ` [Qemu-devel] [PULL 09/25] target/openrisc: Exit the TB after l.mtspr Stafford Horne
2018-07-02 13:57 ` [Qemu-devel] [PULL 10/25] target/openrisc: Form the spr index from tcg Stafford Horne
2018-07-02 13:57 ` [Qemu-devel] [PULL 11/25] target/openrisc: Merge tlb allocation into CPUOpenRISCState Stafford Horne
2018-07-02 13:57 ` [Qemu-devel] [PULL 12/25] target/openrisc: Remove indirect function calls for mmu Stafford Horne
2018-07-02 13:57 ` [Qemu-devel] [PULL 13/25] target/openrisc: Merge mmu_helper.c into mmu.c Stafford Horne
2018-07-02 13:57 ` [Qemu-devel] [PULL 14/25] target/openrisc: Reduce tlb to a single dimension Stafford Horne
2018-07-02 13:57 ` [Qemu-devel] [PULL 15/25] target/openrisc: Fix tlb flushing in mtspr Stafford Horne
2018-07-02 13:57 ` Stafford Horne [this message]
2018-07-02 13:57 ` [Qemu-devel] [PULL 17/25] target/openrisc: Use identical sizes for ITLB and DTLB Stafford Horne
2018-07-02 13:57 ` [Qemu-devel] [PULL 18/25] target/openrisc: Stub out handle_mmu_fault for softmmu Stafford Horne
2018-07-02 13:58 ` [Qemu-devel] [PULL 19/25] target/openrisc: Increase the TLB size Stafford Horne
2018-07-02 13:58 ` [Qemu-devel] [PULL 20/25] target/openrisc: Reorg tlb lookup Stafford Horne
2018-07-02 13:58 ` [Qemu-devel] [PULL 21/25] target/openrisc: Add support in scripts/qemu-binfmt-conf.sh Stafford Horne
2018-07-02 13:58 ` [Qemu-devel] [PULL 22/25] linux-user: Implement signals for openrisc Stafford Horne
2018-07-02 13:58 ` [Qemu-devel] [PULL 23/25] linux-user: Fix struct sigaltstack " Stafford Horne
2018-07-02 13:58 ` [Qemu-devel] [PULL 24/25] target/openrisc: Fix delay slot exception flag to match spec Stafford Horne
2018-07-02 13:58 ` [Qemu-devel] [PULL 25/25] target/openrisc: Fix writes to interrupt mask register Stafford Horne
2018-07-02 14:47 ` [Qemu-devel] [PULL 00/25] OpenRISC updates for 3.0 Stafford Horne
2018-07-02 15:34 ` Alex Bennée
2018-07-02 23:55 ` Stafford Horne
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180702135806.7087-17-shorne@gmail.com \
--to=shorne@gmail.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).