[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC PATCH 16/17] target/ppc: Avoid flushing HV real translations
From: |
Nicholas Piggin |
Subject: |
[RFC PATCH 16/17] target/ppc: Avoid flushing HV real translations |
Date: |
Tue, 1 Apr 2025 00:46:50 +1000 |
Most TLB invalidations do not flush the HV real translation. HRMOR is
the only way to change the translation, so changing that register must
flush the full TLB, all others can get away without flushing the HV
real translation. This could help performance for real-mode firmware
and operating systems.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
target/ppc/cpu.h | 12 +++++++-----
target/ppc/cpu.c | 2 +-
target/ppc/helper_regs.c | 2 +-
target/ppc/misc_helper.c | 8 ++++----
target/ppc/mmu-hash64.c | 8 +++++++-
target/ppc/mmu_helper.c | 10 ++++++----
6 files changed, 26 insertions(+), 16 deletions(-)
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index cb0adba2ae7..ff14f5b8a7f 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -263,11 +263,13 @@ static inline bool mmu_is_64bit(powerpc_mmu_t mmu_model)
return mmu_model & POWERPC_MMU_64;
}
-#define USER_VIRT_MMUIDX_BITS 0x1
-#define PRIV_VIRT_MMUIDX_BITS 0x2
-#define VIRT_MMUIDX_BITS (USER_VIRT_MMUIDX_BITS | PRIV_VIRT_MMUIDX_BITS)
-#define SV_REAL_MMUIDX_BITS 0x4
-#define HV_REAL_MMUIDX_BITS 0x8
+#define USER_VIRT_MMUIDX_BITS 0x1
+#define PRIV_VIRT_MMUIDX_BITS 0x2
+#define VIRT_MMUIDX_BITS (USER_VIRT_MMUIDX_BITS | \
+ PRIV_VIRT_MMUIDX_BITS)
+#define SV_REAL_MMUIDX_BITS 0x4
+#define HV_REAL_MMUIDX_BITS 0x8
+#define ALLBUT_HV_REAL_MMUIDX_BITS 0x7
/*****************************************************************************/
/* Input pins model */
diff --git a/target/ppc/cpu.c b/target/ppc/cpu.c
index 55f1d1c9830..73e5537740f 100644
--- a/target/ppc/cpu.c
+++ b/target/ppc/cpu.c
@@ -109,7 +109,7 @@ void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val)
hreg_compute_hflags(env);
if ((old ^ new) & LPCR_MMU_BITS) {
- tlb_flush(env_cpu(env));
+ tlb_flush_by_mmuidx(env_cpu(env), ALLBUT_HV_REAL_MMUIDX_BITS);
}
ppc_maybe_interrupt(env);
diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
index b64eb59edf6..137620991c4 100644
--- a/target/ppc/helper_regs.c
+++ b/target/ppc/helper_regs.c
@@ -431,7 +431,7 @@ void check_tlb_flush(CPUPPCState *env, bool global)
if (env->tlb_need_flush & TLB_NEED_LOCAL_FLUSH) {
env->tlb_need_flush &= ~TLB_NEED_LOCAL_FLUSH;
slb_destroy_rmaps(env);
- tlb_flush(cs);
+ tlb_flush_by_mmuidx(cs, VIRT_MMUIDX_BITS);
}
}
#endif /* !CONFIG_USER_ONLY */
diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c
index 669bfbfda32..641f07eeb7e 100644
--- a/target/ppc/misc_helper.c
+++ b/target/ppc/misc_helper.c
@@ -220,7 +220,7 @@ void helper_store_ptcr(CPUPPCState *env, target_ulong val)
if (ppc_cpu_lpar_single_threaded(cs)) {
env->spr[SPR_PTCR] = val;
- tlb_flush(cs);
+ tlb_flush_by_mmuidx(cs, ALLBUT_HV_REAL_MMUIDX_BITS);
} else {
CPUState *ccs;
@@ -228,7 +228,7 @@ void helper_store_ptcr(CPUPPCState *env, target_ulong val)
PowerPCCPU *ccpu = POWERPC_CPU(ccs);
CPUPPCState *cenv = &ccpu->env;
cenv->spr[SPR_PTCR] = val;
- tlb_flush(ccs);
+ tlb_flush_by_mmuidx(ccs, ALLBUT_HV_REAL_MMUIDX_BITS);
}
}
}
@@ -482,7 +482,7 @@ void helper_store_pidr(CPUPPCState *env, target_ulong val)
if (env->spr[SPR_LPCR] & LPCR_HR) {
/* PID is only relevant to CPU translations when LPCR[HR]=1 */
- tlb_flush(env_cpu(env));
+ tlb_flush_by_mmuidx(env_cpu(env), ALLBUT_HV_REAL_MMUIDX_BITS);
}
}
@@ -500,7 +500,7 @@ void helper_store_lpidr(CPUPPCState *env, target_ulong val)
* potentially access and cache entries for the current LPID as
* well.
*/
- tlb_flush(env_cpu(env));
+ tlb_flush_by_mmuidx(env_cpu(env), ALLBUT_HV_REAL_MMUIDX_BITS);
}
void helper_store_40x_dbcr0(CPUPPCState *env, target_ulong val)
diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index d42d2cd4a6f..ccee4fb6036 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -208,6 +208,7 @@ static bool slb_get_clear_rmap(CPUPPCState *env, ppc_slb_t
*slb)
void helper_SLBIA(CPUPPCState *env, uint32_t ih)
{
PowerPCCPU *cpu = env_archcpu(env);
+ CPUState *cs = CPU(cpu);
int starting_entry;
int n;
@@ -232,7 +233,12 @@ void helper_SLBIA(CPUPPCState *env, uint32_t ih)
* invalidated.
*/
- env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH;
+ if (env->mmu_model == POWERPC_MMU_3_00 &&
+ env->spr[SPR_LPCR] & LPCR_HR) {
+ /* Radix mode does not flush */
+ } else {
+ tlb_flush_by_mmuidx(cs, VIRT_MMUIDX_BITS);
+ }
starting_entry = 1; /* default for IH=0,1,2,6 */
diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
index 8e95fda4d0f..e1590091102 100644
--- a/target/ppc/mmu_helper.c
+++ b/target/ppc/mmu_helper.c
@@ -432,6 +432,7 @@ typedef struct TLBIEParams {
uint32_t is;
uint32_t ric;
uint32_t prs;
+ uint16_t mmuidx;
bool local;
bool radix;
} TLBIEParams;
@@ -475,11 +476,11 @@ static void tlb_do_flush_async_free_data(CPUState *cpu,
run_on_cpu_data data)
*/
if (!tlb_skip_flush(env, p)) {
if (p->addr == 0 && p->len == (target_ulong)-1) {
- do_tlb_flush_by_mmuidx_async(cpu, ALL_MMUIDX_BITS);
+ do_tlb_flush_by_mmuidx_async(cpu, p->mmuidx);
slb_destroy_rmaps(env);
} else {
do_tlb_flush_range_by_mmuidx_async(cpu, p->addr, p->len,
- ALL_MMUIDX_BITS,
+ p->mmuidx,
TARGET_LONG_BITS);
}
}
@@ -495,11 +496,11 @@ static void tlb_do_flush(CPUPPCState *env, TLBIEParams *p)
if (p->local) {
if (!tlb_skip_flush(env, p)) {
if (p->addr == 0 && p->len == (target_ulong)-1) {
- do_tlb_flush_by_mmuidx_async(cpu, ALL_MMUIDX_BITS);
+ do_tlb_flush_by_mmuidx_async(cpu, p->mmuidx);
slb_destroy_rmaps(env);
} else {
do_tlb_flush_range_by_mmuidx_async(cpu, p->addr, p->len,
- ALL_MMUIDX_BITS,
+ p->mmuidx,
TARGET_LONG_BITS);
}
}
@@ -723,6 +724,7 @@ void helper_tlbie_isa300(CPUPPCState *env, target_ulong rb,
target_ulong rs,
.ric = (flags & TLBIE_F_RIC_MASK) >> TLBIE_F_RIC_SHIFT,
.prs = flags & TLBIE_F_PRS,
.local = flags & TLBIE_F_LOCAL,
+ .mmuidx = ALLBUT_HV_REAL_MMUIDX_BITS,
};
bool hv = FIELD_EX64(env->msr, MSR, HV);
bool ret;
--
2.47.1
- [RFC PATCH 00/17] target/ppc: MMU improvements, Nicholas Piggin, 2025/03/31
- [RFC PATCH 01/17] target/ppc: Do not set HPTE R/C bits on !guest_visible xlate, Nicholas Piggin, 2025/03/31
- [RFC PATCH 02/17] target/ppc: Machine check on invalid table walk access, Nicholas Piggin, 2025/03/31
- [RFC PATCH 05/17] target/ppc: flush TLB on HRMOR and LPCR SPR updates, Nicholas Piggin, 2025/03/31
- [RFC PATCH 14/17] target/ppc: Extend TLB flush skipping to broadcast TLB flushes, Nicholas Piggin, 2025/03/31
- [RFC PATCH 06/17] target/ppc: Avoid work if MMU SPRs are written with same value, Nicholas Piggin, 2025/03/31
- [RFC PATCH 10/17] accel/tcg: Export low level TLB range flush call, Nicholas Piggin, 2025/03/31
- [RFC PATCH 16/17] target/ppc: Avoid flushing HV real translations,
Nicholas Piggin <=
- [RFC PATCH 04/17] cputlb: add TLB access statistics, Nicholas Piggin, 2025/03/31
- [RFC PATCH 07/17] target/ppc: Avoid using mmuidx to test translation modes, Nicholas Piggin, 2025/03/31
- [RFC PATCH 08/17] target/ppc: Reduce mmu indexes used for BookS 64-bit, Nicholas Piggin, 2025/03/31
- [RFC PATCH 09/17] accel/tcg: Rename tlb flush internal functions, Nicholas Piggin, 2025/03/31
- [RFC PATCH 11/17] target/ppc: Make TLBIE with hash MMU use the isa300 helper, Nicholas Piggin, 2025/03/31
- [RFC PATCH 12/17] target/ppc: Split tlbie300 helper into radix and hash, Nicholas Piggin, 2025/03/31
- [RFC PATCH 13/17] target/ppc: Implement TLB flush skipping, Nicholas Piggin, 2025/03/31
- [RFC PATCH 15/17] target/ppc: Add precise TLB flushing for hash with ISAv3.0, Nicholas Piggin, 2025/03/31
- [RFC PATCH 03/17] target/ppc: Implement LPCR[TC] mmu mode, Nicholas Piggin, 2025/03/31
- [RFC PATCH 17/17] target/ppc: Increase page size for real mode translations, Nicholas Piggin, 2025/03/31