linux/arch/mips/lib
Matt Redfearn e4c63743a8 MIPS: memset.S: Fix clobber of v1 in last_fixup
commit c96eebf076 upstream.

The label .Llast_fixup\@ is jumped to on page fault within the final
byte set loop of memset (on < MIPSR6 architectures). For some reason, in
this fault handler, the v1 register is randomly set to a2 & STORMASK.
This clobbers v1 for the calling function. This can be observed with the
following test code:

static int __init __attribute__((optimize("O0"))) test_clear_user(void)
{
  register int t asm("v1");
  char *test;
  int j, k;

  pr_info("\n\n\nTesting clear_user\n");
  test = vmalloc(PAGE_SIZE);

  for (j = 256; j < 512; j++) {
    t = 0xa5a5a5a5;
    if ((k = clear_user(test + PAGE_SIZE - 256, j)) != j - 256) {
        pr_err("clear_user (%px %d) returned %d\n", test + PAGE_SIZE - 256, j, k);
    }
    if (t != 0xa5a5a5a5) {
       pr_err("v1 was clobbered to 0x%x!\n", t);
    }
  }

  return 0;
}
late_initcall(test_clear_user);

Which demonstrates that v1 is indeed clobbered (MIPS64):

Testing clear_user
v1 was clobbered to 0x1!
v1 was clobbered to 0x2!
v1 was clobbered to 0x3!
v1 was clobbered to 0x4!
v1 was clobbered to 0x5!
v1 was clobbered to 0x6!
v1 was clobbered to 0x7!

Since the number of bytes that could not be set is already contained in
a2, the andi placing a value in v1 is not necessary and actively
harmful in clobbering v1.

Reported-by: James Hogan <jhogan@kernel.org>
Signed-off-by: Matt Redfearn <matt.redfearn@mips.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/19109/
Signed-off-by: James Hogan <jhogan@kernel.org>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
History 2018-10-21 08:45:31 +01:00
..
ashldi3.c [MIPS] Fix optimization for size build. 2006-06-19 17:39:16 +01:00
ashrdi3.c [MIPS] Fix optimization for size build. 2006-06-19 17:39:16 +01:00
bitops.c MIPS: Remove unneeded volatile from arch/mips/lib/bitops.c 2013-05-08 01:19:06 +02:00
cmpdi2.c [MIPS] Add __cmpdi2 2007-08-27 02:17:00 +01:00
csum_partial.S MIPS: csum_partial.S CPU_DADDI_WORKAROUNDS bug fix 2014-05-13 00:29:39 +02:00
delay.c MIPS: __delay ABI-dependent subtraction simplification 2014-05-30 21:01:08 +02:00
dump_tlb.c Revert "MIPS: Allow ASID size to be determined at boot time." 2013-05-16 20:35:42 +02:00
iomap-pci.c mips: use the the PCI controller's io_map_base 2012-01-31 23:20:30 +02:00
iomap.c PCI: Cleanup the includes of <linux/pci.h> 2007-05-02 19:02:35 -07:00
libgcc.h MIPS: libgcc.h: Checkpatch cleanup 2010-04-12 17:26:15 +01:00
lshrdi3.c [MIPS] Fix optimization for size build. 2006-06-19 17:39:16 +01:00
Makefile MIPS: Make irqflags.h functions preempt-safe for non-mipsr2 cpus 2012-11-09 10:59:21 +01:00
memcpy.S MIPS: lib: memcpy: Restore NOP on delay slot before returning to caller 2014-12-01 10:26:05 +00:00
memset.S MIPS: memset.S: Fix clobber of v1 in last_fixup 2018-10-21 08:45:31 +01:00
mips-atomic.c MIPS: MT: Remove SMTC support 2014-05-24 00:07:01 +02:00
r3k_dump_tlb.c Revert "MIPS: Allow ASID size to be determined at boot time." 2013-05-16 20:35:42 +02:00
strlen_user.S MIPS: lib: strlen_user: Add EVA support 2014-03-26 23:09:13 +01:00
strncpy_user.S MIPS: __strncpy_from_user_asm CPU_DADDI_WORKAROUNDS bug fix 2014-05-13 00:29:38 +02:00
strnlen_user.S MIPS: lib: strnlen_user: Add EVA support 2014-03-26 23:09:13 +01:00
ucmpdi2.c [MIPS] Export __ucmpdi2 to modules. 2008-03-12 14:14:41 +00:00
uncached.c mips: delete non-required instances of include <linux/init.h> 2014-01-24 22:39:56 +01:00