Most of the p8 exception handling accesses env->pending_interrupts and
env->spr[SPR_LPCR] at multiple places. Passing it directly as local
variables simplifies the code and avoids multiple indirect accesses.
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
---
target/ppc/excp_helper.c | 60 +++++++++++++++++++++-------------------
1 file changed, 32 insertions(+), 28 deletions(-)
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index c7641898ca..c0828aac88 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -1765,39 +1765,42 @@ static int p7_next_unmasked_interrupt(CPUPPCState *env)
PPC_INTERRUPT_CEXT | PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL | \
PPC_INTERRUPT_FIT | PPC_INTERRUPT_PIT | PPC_INTERRUPT_THERM)
-static int p8_interrupt_powersave(CPUPPCState *env)
+static int p8_interrupt_powersave(uint32_t pending_interrupts,
+ target_ulong lpcr)
{
- if ((env->pending_interrupts & PPC_INTERRUPT_EXT) &&
- (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) {
+ if ((pending_interrupts & PPC_INTERRUPT_EXT) &&
+ (lpcr & LPCR_P8_PECE2)) {
return PPC_INTERRUPT_EXT;
}
- if ((env->pending_interrupts & PPC_INTERRUPT_DECR) &&
- (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) {
+ if ((pending_interrupts & PPC_INTERRUPT_DECR) &&
+ (lpcr & LPCR_P8_PECE3)) {
return PPC_INTERRUPT_DECR;
}
- if ((env->pending_interrupts & PPC_INTERRUPT_MCK) &&
- (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
+ if ((pending_interrupts & PPC_INTERRUPT_MCK) &&
+ (lpcr & LPCR_P8_PECE4)) {
return PPC_INTERRUPT_MCK;
}
- if ((env->pending_interrupts & PPC_INTERRUPT_HMI) &&
- (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
+ if ((pending_interrupts & PPC_INTERRUPT_HMI) &&
+ (lpcr & LPCR_P8_PECE4)) {
return PPC_INTERRUPT_HMI;
}
- if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) &&
- (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) {
+ if ((pending_interrupts & PPC_INTERRUPT_DOORBELL) &&
+ (lpcr & LPCR_P8_PECE0)) {
return PPC_INTERRUPT_DOORBELL;
}
- if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) &&
- (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) {
+ if ((pending_interrupts & PPC_INTERRUPT_HDOORBELL) &&
+ (lpcr & LPCR_P8_PECE1)) {
return PPC_INTERRUPT_HDOORBELL;
}
- if (env->pending_interrupts & PPC_INTERRUPT_RESET) {
+ if (pending_interrupts & PPC_INTERRUPT_RESET) {
return PPC_INTERRUPT_RESET;
}
return 0;
}
-static int p8_next_unmasked_interrupt(CPUPPCState *env)
+static int p8_next_unmasked_interrupt(CPUPPCState *env,
+ uint32_t pending_interrupts,
+ target_ulong lpcr)
{
CPUState *cs = env_cpu(env);
@@ -1808,18 +1811,18 @@ static int p8_next_unmasked_interrupt(CPUPPCState *env)
if (cs->halted) {
/* LPCR[PECE] controls which interrupts can exit power-saving mode */
- return p8_interrupt_powersave(env);
+ return p8_interrupt_powersave(pending_interrupts, lpcr);
}
/* Machine check exception */
- if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
+ if (pending_interrupts & PPC_INTERRUPT_MCK) {
return PPC_INTERRUPT_MCK;
}
/* Hypervisor decrementer exception */
- if (env->pending_interrupts & PPC_INTERRUPT_HDECR) {
+ if (pending_interrupts & PPC_INTERRUPT_HDECR) {
/* LPCR will be clear when not supported so this will work */
- bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
+ bool hdice = !!(lpcr & LPCR_HDICE);
if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) {
/* HDEC clears on delivery */
return PPC_INTERRUPT_HDECR;
@@ -1827,9 +1830,9 @@ static int p8_next_unmasked_interrupt(CPUPPCState *env)
}
/* External interrupt can ignore MSR:EE under some circumstances */
- if (env->pending_interrupts & PPC_INTERRUPT_EXT) {
- bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
- bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
+ if (pending_interrupts & PPC_INTERRUPT_EXT) {
+ bool lpes0 = !!(lpcr & LPCR_LPES0);
+ bool heic = !!(lpcr & LPCR_HEIC);
/* HEIC blocks delivery to the hypervisor */
if ((msr_ee && !(heic && FIELD_EX64_HV(env->msr) &&
!FIELD_EX64(env->msr, MSR, PR))) ||
@@ -1839,20 +1842,20 @@ static int p8_next_unmasked_interrupt(CPUPPCState *env)
}
if (msr_ee != 0) {
/* Decrementer exception */
- if (env->pending_interrupts & PPC_INTERRUPT_DECR) {
+ if (pending_interrupts & PPC_INTERRUPT_DECR) {
return PPC_INTERRUPT_DECR;
}
- if (env->pending_interrupts & PPC_INTERRUPT_DOORBELL) {
+ if (pending_interrupts & PPC_INTERRUPT_DOORBELL) {
return PPC_INTERRUPT_DOORBELL;
}
- if (env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) {
+ if (pending_interrupts & PPC_INTERRUPT_HDOORBELL) {
return PPC_INTERRUPT_HDOORBELL;
}
- if (env->pending_interrupts & PPC_INTERRUPT_PERFM) {
+ if (pending_interrupts & PPC_INTERRUPT_PERFM) {
return PPC_INTERRUPT_PERFM;
}
/* EBB exception */
- if (env->pending_interrupts & PPC_INTERRUPT_EBB) {
+ if (pending_interrupts & PPC_INTERRUPT_EBB) {
/*
* EBB exception must be taken in problem state and
* with BESCR_GE set.
@@ -2021,7 +2024,8 @@ static int ppc_next_unmasked_interrupt(CPUPPCState *env)
case POWERPC_EXCP_POWER7:
return p7_next_unmasked_interrupt(env);
case POWERPC_EXCP_POWER8:
- return p8_next_unmasked_interrupt(env);
+ return p8_next_unmasked_interrupt(env, env->pending_interrupts,
+ env->spr[SPR_LPCR]);
case POWERPC_EXCP_POWER9:
case POWERPC_EXCP_POWER10:
case POWERPC_EXCP_POWER11:
--
2.45.2
On Fri Sep 13, 2024 at 2:13 PM AEST, Harsh Prateek Bora wrote:
> Most of the p8 exception handling accesses env->pending_interrupts and
> env->spr[SPR_LPCR] at multiple places. Passing it directly as local
> variables simplifies the code and avoids multiple indirect accesses.
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
>
> Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
> ---
> target/ppc/excp_helper.c | 60 +++++++++++++++++++++-------------------
> 1 file changed, 32 insertions(+), 28 deletions(-)
>
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index c7641898ca..c0828aac88 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -1765,39 +1765,42 @@ static int p7_next_unmasked_interrupt(CPUPPCState *env)
> PPC_INTERRUPT_CEXT | PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL | \
> PPC_INTERRUPT_FIT | PPC_INTERRUPT_PIT | PPC_INTERRUPT_THERM)
>
> -static int p8_interrupt_powersave(CPUPPCState *env)
> +static int p8_interrupt_powersave(uint32_t pending_interrupts,
> + target_ulong lpcr)
> {
> - if ((env->pending_interrupts & PPC_INTERRUPT_EXT) &&
> - (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) {
> + if ((pending_interrupts & PPC_INTERRUPT_EXT) &&
> + (lpcr & LPCR_P8_PECE2)) {
> return PPC_INTERRUPT_EXT;
> }
> - if ((env->pending_interrupts & PPC_INTERRUPT_DECR) &&
> - (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) {
> + if ((pending_interrupts & PPC_INTERRUPT_DECR) &&
> + (lpcr & LPCR_P8_PECE3)) {
> return PPC_INTERRUPT_DECR;
> }
> - if ((env->pending_interrupts & PPC_INTERRUPT_MCK) &&
> - (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
> + if ((pending_interrupts & PPC_INTERRUPT_MCK) &&
> + (lpcr & LPCR_P8_PECE4)) {
> return PPC_INTERRUPT_MCK;
> }
> - if ((env->pending_interrupts & PPC_INTERRUPT_HMI) &&
> - (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
> + if ((pending_interrupts & PPC_INTERRUPT_HMI) &&
> + (lpcr & LPCR_P8_PECE4)) {
> return PPC_INTERRUPT_HMI;
> }
> - if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) &&
> - (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) {
> + if ((pending_interrupts & PPC_INTERRUPT_DOORBELL) &&
> + (lpcr & LPCR_P8_PECE0)) {
> return PPC_INTERRUPT_DOORBELL;
> }
> - if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) &&
> - (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) {
> + if ((pending_interrupts & PPC_INTERRUPT_HDOORBELL) &&
> + (lpcr & LPCR_P8_PECE1)) {
> return PPC_INTERRUPT_HDOORBELL;
> }
> - if (env->pending_interrupts & PPC_INTERRUPT_RESET) {
> + if (pending_interrupts & PPC_INTERRUPT_RESET) {
> return PPC_INTERRUPT_RESET;
> }
> return 0;
> }
>
> -static int p8_next_unmasked_interrupt(CPUPPCState *env)
> +static int p8_next_unmasked_interrupt(CPUPPCState *env,
> + uint32_t pending_interrupts,
> + target_ulong lpcr)
> {
> CPUState *cs = env_cpu(env);
>
> @@ -1808,18 +1811,18 @@ static int p8_next_unmasked_interrupt(CPUPPCState *env)
>
> if (cs->halted) {
> /* LPCR[PECE] controls which interrupts can exit power-saving mode */
> - return p8_interrupt_powersave(env);
> + return p8_interrupt_powersave(pending_interrupts, lpcr);
> }
>
> /* Machine check exception */
> - if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
> + if (pending_interrupts & PPC_INTERRUPT_MCK) {
> return PPC_INTERRUPT_MCK;
> }
>
> /* Hypervisor decrementer exception */
> - if (env->pending_interrupts & PPC_INTERRUPT_HDECR) {
> + if (pending_interrupts & PPC_INTERRUPT_HDECR) {
> /* LPCR will be clear when not supported so this will work */
> - bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
> + bool hdice = !!(lpcr & LPCR_HDICE);
> if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) {
> /* HDEC clears on delivery */
> return PPC_INTERRUPT_HDECR;
> @@ -1827,9 +1830,9 @@ static int p8_next_unmasked_interrupt(CPUPPCState *env)
> }
>
> /* External interrupt can ignore MSR:EE under some circumstances */
> - if (env->pending_interrupts & PPC_INTERRUPT_EXT) {
> - bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
> - bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
> + if (pending_interrupts & PPC_INTERRUPT_EXT) {
> + bool lpes0 = !!(lpcr & LPCR_LPES0);
> + bool heic = !!(lpcr & LPCR_HEIC);
> /* HEIC blocks delivery to the hypervisor */
> if ((msr_ee && !(heic && FIELD_EX64_HV(env->msr) &&
> !FIELD_EX64(env->msr, MSR, PR))) ||
> @@ -1839,20 +1842,20 @@ static int p8_next_unmasked_interrupt(CPUPPCState *env)
> }
> if (msr_ee != 0) {
> /* Decrementer exception */
> - if (env->pending_interrupts & PPC_INTERRUPT_DECR) {
> + if (pending_interrupts & PPC_INTERRUPT_DECR) {
> return PPC_INTERRUPT_DECR;
> }
> - if (env->pending_interrupts & PPC_INTERRUPT_DOORBELL) {
> + if (pending_interrupts & PPC_INTERRUPT_DOORBELL) {
> return PPC_INTERRUPT_DOORBELL;
> }
> - if (env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) {
> + if (pending_interrupts & PPC_INTERRUPT_HDOORBELL) {
> return PPC_INTERRUPT_HDOORBELL;
> }
> - if (env->pending_interrupts & PPC_INTERRUPT_PERFM) {
> + if (pending_interrupts & PPC_INTERRUPT_PERFM) {
> return PPC_INTERRUPT_PERFM;
> }
> /* EBB exception */
> - if (env->pending_interrupts & PPC_INTERRUPT_EBB) {
> + if (pending_interrupts & PPC_INTERRUPT_EBB) {
> /*
> * EBB exception must be taken in problem state and
> * with BESCR_GE set.
> @@ -2021,7 +2024,8 @@ static int ppc_next_unmasked_interrupt(CPUPPCState *env)
> case POWERPC_EXCP_POWER7:
> return p7_next_unmasked_interrupt(env);
> case POWERPC_EXCP_POWER8:
> - return p8_next_unmasked_interrupt(env);
> + return p8_next_unmasked_interrupt(env, env->pending_interrupts,
> + env->spr[SPR_LPCR]);
> case POWERPC_EXCP_POWER9:
> case POWERPC_EXCP_POWER10:
> case POWERPC_EXCP_POWER11:
© 2016 - 2026 Red Hat, Inc.