@@ -97,8 +97,14 @@ void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val)
{
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
CPUPPCState *env = &cpu->env;
+ target_ulong old, new;
- env->spr[SPR_LPCR] = val & pcc->lpcr_mask;
+ old = env->spr[SPR_LPCR];
+ new = val & pcc->lpcr_mask;
+ if (old == new) {
+ return;
+ }
+ env->spr[SPR_LPCR] = new;
/* The gtse bit affects hflags */
hreg_compute_hflags(env);
@@ -403,12 +403,24 @@ void helper_store_sprd(CPUPPCState *env, target_ulong val)
void helper_store_pidr(CPUPPCState *env, target_ulong val)
{
+ if (env->spr[SPR_BOOKS_PID] == (uint32_t)val) {
+ return;
+ }
+
env->spr[SPR_BOOKS_PID] = (uint32_t)val;
- tlb_flush(env_cpu(env));
+
+ if (env->spr[SPR_LPCR] & LPCR_HR) {
+ /* PID is only relevant to CPU translations when LPCR[HR]=1 */
+ tlb_flush(env_cpu(env));
+ }
}
void helper_store_lpidr(CPUPPCState *env, target_ulong val)
{
+ if (env->spr[SPR_LPIDR] == (uint32_t)val) {
+ return;
+ }
+
env->spr[SPR_LPIDR] = (uint32_t)val;
/*
Avoid TLB flushing and hflags recomputation if LPCR, LPIDR, or PIDR are written with the same value. This is observed to happen in some cases (e.g., in hypervisor real-mode exit fastpath handlers). Signed-off-by: Nicholas Piggin <npiggin@gmail.com> --- target/ppc/cpu.c | 8 +++++++- target/ppc/misc_helper.c | 14 +++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-)