Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

[IA64] Fix unaligned handler for floating point instructions with base update

The compiler team did the hard work for this distilling a problem in
large fortran application which showed up when applied to a 290MB input
data set down to this instruction:

ldfd f34=[r17],-8

Which they noticed incremented r17 by 0x10 rather than decrementing it
by 8 when the value in r17 caused an unaligned data fault. I tracked
it down to some bad instruction decoding in unaligned.c. The code
assumes that the 'x' bit can determine whether the instruction is
an "ldf" or "ldfp" ... which it is for opcode=6 (see table 4-29 on
page 3:302 of the SDM). But for opcode=7 the 'x' bit is irrelevent,
all variants are "ldf" instructions (see table 4-36 on page 3:306).

Note also that interpreting the instruction as "ldfp" means that the
"paired" floating point register (f35 in the example here) will also
be corrupted.

Signed-off-by: Tony Luck <tony.luck@intel.com>

+7 -4
+7 -4
arch/ia64/kernel/unaligned.c
··· 1488 1488 case LDFA_OP: 1489 1489 case LDFCCLR_OP: 1490 1490 case LDFCNC_OP: 1491 - case LDF_IMM_OP: 1492 - case LDFA_IMM_OP: 1493 - case LDFCCLR_IMM_OP: 1494 - case LDFCNC_IMM_OP: 1495 1491 if (u.insn.x) 1496 1492 ret = emulate_load_floatpair(ifa, u.insn, regs); 1497 1493 else 1498 1494 ret = emulate_load_float(ifa, u.insn, regs); 1495 + break; 1496 + 1497 + case LDF_IMM_OP: 1498 + case LDFA_IMM_OP: 1499 + case LDFCCLR_IMM_OP: 1500 + case LDFCNC_IMM_OP: 1501 + ret = emulate_load_float(ifa, u.insn, regs); 1499 1502 break; 1500 1503 1501 1504 case STF_OP: