ppc: Fix the bad exception NIP value and the range check in LSWX
The range checks in the LSWX instruction are completely insufficient: They do not take the wrap-around case into account, and the check "reg < rx" should be "reg <= rx" instead. Fix it by using the new lsw_reg_in_range() helper function that is already used for LSWI, too. Then there is a second problem: In case the INVAL exception is generated, the NIP value is wrong, it currently points to the instruction before the LSWX instruction. This is because gen_lswx() already decreases the NIP value by 4 (to be prepared for page fault exceptions), and powerpc_excp() later decreases it again by 4 while handling the program exception. So to get this right, we've got to undo the "- 4" from gen_lswx() here before calling helper_raise_exception_err(). Signed-off-by: Thomas Huth <thuth@redhat.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
afbee7128c
commit
537d3e8e6b
@ -102,8 +102,9 @@ void helper_lswx(CPUPPCState *env, target_ulong addr, uint32_t reg,
|
||||
{
|
||||
if (likely(xer_bc != 0)) {
|
||||
int num_used_regs = (xer_bc + 3) / 4;
|
||||
if (unlikely((ra != 0 && reg < ra && (reg + num_used_regs) > ra) ||
|
||||
(reg < rb && (reg + num_used_regs) > rb))) {
|
||||
if (unlikely((ra != 0 && lsw_reg_in_range(reg, num_used_regs, ra)) ||
|
||||
lsw_reg_in_range(reg, num_used_regs, rb))) {
|
||||
env->nip += 4; /* Compensate the "nip - 4" from gen_lswx() */
|
||||
helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
|
||||
POWERPC_EXCP_INVAL |
|
||||
POWERPC_EXCP_INVAL_LSWX);
|
||||
|
Loading…
Reference in New Issue
Block a user