parisc unaligned handler fixes

Two patches which fix a few bugs in the unalignment handlers.  The fldd
 and fstd instructions weren't handled at all on 32-bit kernels, the stw
 instruction didn't checked for fault errors and the fldw_l and ldw_m
 were handled wrongly as integer vs. floating point instructions.
 Both patches are tagged for stable series.
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYIAB0WIQS86RI+GtKfB8BJu973ErUQojoPXwUCYhZtYAAKCRD3ErUQojoP
 X95qAP4umgbso0RkZrxClYVCON6J/Ndo3PHEe3B992/Jv+R7ZAEA2O5ZOs7nUjdv
 rN27wpJU/BBhbKBqs3rYCw4UgQ2zTQI=
 =H3yW
 -----END PGP SIGNATURE-----

Merge tag 'for-5.17/parisc-4' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux

Pull parisc unaligned handler fixes from Helge Deller:
 "Two patches which fix a few bugs in the unalignment handlers.

  The fldd and fstd instructions weren't handled at all on 32-bit
  kernels, the stw instruction didn't check for fault errors and the
  fldw_l and ldw_m were handled wrongly as integer vs floating point
  instructions.

  Both patches are tagged for stable series"

* tag 'for-5.17/parisc-4' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
  parisc/unaligned: Fix ldw() and stw() unalignment handlers
  parisc/unaligned: Fix fldd and fstd unaligned handlers on 32-bit kernel
This commit is contained in:
Linus Torvalds 2022-02-23 12:06:23 -08:00
commit 23d0432844
1 changed files with 7 additions and 7 deletions

View File

@ -340,7 +340,7 @@ static int emulate_stw(struct pt_regs *regs, int frreg, int flop)
: "r" (val), "r" (regs->ior), "r" (regs->isr) : "r" (val), "r" (regs->ior), "r" (regs->isr)
: "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER ); : "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER );
return 0; return ret;
} }
static int emulate_std(struct pt_regs *regs, int frreg, int flop) static int emulate_std(struct pt_regs *regs, int frreg, int flop)
{ {
@ -397,7 +397,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop)
__asm__ __volatile__ ( __asm__ __volatile__ (
" mtsp %4, %%sr1\n" " mtsp %4, %%sr1\n"
" zdep %2, 29, 2, %%r19\n" " zdep %2, 29, 2, %%r19\n"
" dep %%r0, 31, 2, %2\n" " dep %%r0, 31, 2, %3\n"
" mtsar %%r19\n" " mtsar %%r19\n"
" zvdepi -2, 32, %%r19\n" " zvdepi -2, 32, %%r19\n"
"1: ldw 0(%%sr1,%3),%%r20\n" "1: ldw 0(%%sr1,%3),%%r20\n"
@ -409,7 +409,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop)
" andcm %%r21, %%r19, %%r21\n" " andcm %%r21, %%r19, %%r21\n"
" or %1, %%r20, %1\n" " or %1, %%r20, %1\n"
" or %2, %%r21, %2\n" " or %2, %%r21, %2\n"
"3: stw %1,0(%%sr1,%1)\n" "3: stw %1,0(%%sr1,%3)\n"
"4: stw %%r1,4(%%sr1,%3)\n" "4: stw %%r1,4(%%sr1,%3)\n"
"5: stw %2,8(%%sr1,%3)\n" "5: stw %2,8(%%sr1,%3)\n"
" copy %%r0, %0\n" " copy %%r0, %0\n"
@ -596,7 +596,6 @@ void handle_unaligned(struct pt_regs *regs)
ret = ERR_NOTHANDLED; /* "undefined", but lets kill them. */ ret = ERR_NOTHANDLED; /* "undefined", but lets kill them. */
break; break;
} }
#ifdef CONFIG_PA20
switch (regs->iir & OPCODE2_MASK) switch (regs->iir & OPCODE2_MASK)
{ {
case OPCODE_FLDD_L: case OPCODE_FLDD_L:
@ -607,22 +606,23 @@ void handle_unaligned(struct pt_regs *regs)
flop=1; flop=1;
ret = emulate_std(regs, R2(regs->iir),1); ret = emulate_std(regs, R2(regs->iir),1);
break; break;
#ifdef CONFIG_PA20
case OPCODE_LDD_L: case OPCODE_LDD_L:
ret = emulate_ldd(regs, R2(regs->iir),0); ret = emulate_ldd(regs, R2(regs->iir),0);
break; break;
case OPCODE_STD_L: case OPCODE_STD_L:
ret = emulate_std(regs, R2(regs->iir),0); ret = emulate_std(regs, R2(regs->iir),0);
break; break;
}
#endif #endif
}
switch (regs->iir & OPCODE3_MASK) switch (regs->iir & OPCODE3_MASK)
{ {
case OPCODE_FLDW_L: case OPCODE_FLDW_L:
flop=1; flop=1;
ret = emulate_ldw(regs, R2(regs->iir),0); ret = emulate_ldw(regs, R2(regs->iir), 1);
break; break;
case OPCODE_LDW_M: case OPCODE_LDW_M:
ret = emulate_ldw(regs, R2(regs->iir),1); ret = emulate_ldw(regs, R2(regs->iir), 0);
break; break;
case OPCODE_FSTW_L: case OPCODE_FSTW_L: