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

sparc64: Fix sun4u execute bit check in TSB I-TLB load.

Thanks to testcase and report from Brad Spengler:

--------------------
#include <stdio.h>

typedef int (* _wee)(void);

int main(void)
{
char buf[8] = { '\x81', '\xc7', '\xe0', '\x08', '\x81', '\xe8',
'\x00', '\x00' };
_wee wee;
printf("%p\n", &buf);
wee = (_wee)&buf;
wee();

return 0;
}
--------------------

TSB I-tlb load code tries to use andcc to check the _PAGE_EXEC_4U bit,
but that's bit 12 so it gets sign extended all the way up to bit 63
and the test nearly always passes as a result.

Use sethi to fix the bug.

Signed-off-by: David S. Miller <davem@davemloft.net>

+4 -2
+4 -2
arch/sparc/kernel/tsb.S
··· 191 191 192 192 tsb_itlb_load: 193 193 /* Executable bit must be set. */ 194 - 661: andcc %g5, _PAGE_EXEC_4U, %g0 195 - .section .sun4v_1insn_patch, "ax" 194 + 661: sethi %hi(_PAGE_EXEC_4U), %g4 195 + andcc %g5, %g4, %g0 196 + .section .sun4v_2insn_patch, "ax" 196 197 .word 661b 197 198 andcc %g5, _PAGE_EXEC_4V, %g0 199 + nop 198 200 .previous 199 201 200 202 be,pn %xcc, tsb_do_fault