target/ppc: Assert if MSR bits differ from msr_mask during exceptions

We currently abort QEMU during the dispatch of an interrupt if we try
to set MSR_HV without having MSR_HVB in the msr_mask. I think we
should verify this for all MSR bits. There is no reason to ever have a
MSR bit set if the corresponding bit is not set in that CPU's
msr_mask.

Note that this is not about the emulated code setting reserved
bits. We clear the new_msr when starting to dispatch an exception, so
if we end up with bits not present in the msr_mask that is a QEMU
programming error.

I kept the HSRR verification for BookS because it is the only CPU
family that has HSRRs.

Signed-off-by: Fabiano Rosas <farosas@linux.ibm.com>
Message-Id: <20220207183036.1507882-4-farosas@linux.ibm.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
This commit is contained in:
Fabiano Rosas 2022-02-09 09:08:56 +01:00 committed by Cédric Le Goater
parent c6eaac893a
commit fce9fbafe9

View File

@ -364,6 +364,8 @@ static void powerpc_set_excp_state(PowerPCCPU *cpu,
CPUState *cs = CPU(cpu);
CPUPPCState *env = &cpu->env;
assert((msr & env->msr_mask) == msr);
/*
* We don't use hreg_store_msr here as already have treated any
* special case that could occur. Just store MSR and update hflags
@ -372,7 +374,7 @@ static void powerpc_set_excp_state(PowerPCCPU *cpu,
* will prevent setting of the HV bit which some exceptions might need
* to do.
*/
env->msr = msr & env->msr_mask;
env->msr = msr;
hreg_compute_hflags(env);
env->nip = vector;
/* Reset exception state */
@ -519,18 +521,6 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp)
break;
}
/* Sanity check */
if (!(env->msr_mask & MSR_HVB)) {
if (new_msr & MSR_HVB) {
cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with "
"no HV support\n", excp);
}
if (srr0 == SPR_HSRR0) {
cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with "
"no HV support\n", excp);
}
}
/* Save PC */
env->spr[srr0] = env->nip;
@ -699,14 +689,6 @@ static void powerpc_excp_6xx(PowerPCCPU *cpu, int excp)
break;
}
/* Sanity check */
if (!(env->msr_mask & MSR_HVB)) {
if (new_msr & MSR_HVB) {
cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with "
"no HV support\n", excp);
}
}
/*
* Sort out endianness of interrupt, this differs depending on the
* CPU, the HV mode, etc...
@ -893,14 +875,6 @@ static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp)
break;
}
/* Sanity check */
if (!(env->msr_mask & MSR_HVB)) {
if (new_msr & MSR_HVB) {
cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with "
"no HV support\n", excp);
}
}
/*
* Sort out endianness of interrupt, this differs depending on the
* CPU, the HV mode, etc...
@ -1079,14 +1053,6 @@ static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp)
break;
}
/* Sanity check */
if (!(env->msr_mask & MSR_HVB)) {
if (new_msr & MSR_HVB) {
cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with "
"no HV support\n", excp);
}
}
/*
* Sort out endianness of interrupt, this differs depending on the
* CPU, the HV mode, etc...
@ -1291,18 +1257,6 @@ static void powerpc_excp_booke(PowerPCCPU *cpu, int excp)
break;
}
/* Sanity check */
if (!(env->msr_mask & MSR_HVB)) {
if (new_msr & MSR_HVB) {
cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with "
"no HV support\n", excp);
}
if (srr0 == SPR_HSRR0) {
cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with "
"no HV support\n", excp);
}
}
#if defined(TARGET_PPC64)
if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) {
/* Cat.64-bit: EPCR.ICM is copied to MSR.CM */
@ -1573,15 +1527,9 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int excp)
}
/* Sanity check */
if (!(env->msr_mask & MSR_HVB)) {
if (new_msr & MSR_HVB) {
cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with "
"no HV support\n", excp);
}
if (srr0 == SPR_HSRR0) {
cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with "
"no HV support\n", excp);
}
if (!(env->msr_mask & MSR_HVB) && srr0 == SPR_HSRR0) {
cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with "
"no HV support\n", excp);
}
/*