aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
authorAlexander Shmelev <ashmelev@task.sun.mcst.ru>2007-07-24 16:41:44 -0400
committerDavid S. Miller <davem@davemloft.net>2007-07-24 16:41:44 -0400
commitf61698e6489f229f9fcfe29e68f228389a772993 (patch)
treeec294315cf4e9985ae17a322bee461282a8858bc /arch/sparc
parent1b64e7abe742c0d32cdb1545d9a67f80cc6e81f3 (diff)
[SPARC32]: Fix bug in sparc optimized memset.
Sparc optimized memset (arch/sparc/lib/memset.S) does not fill last byte of the memory area, if area size is less than 8 bytes and start address is not word (4-bytes) aligned. Here is code chunk where bug located: /* %o0 - memory address, %o1 - size, %g3 - value */ 8: add %o0, 1, %o0 subcc %o1, 1, %o1 bne,a 8b stb %g3, [%o0 - 1] This code should write byte every loop iteration, but last time delay instruction stb is not executed because branch instruction sets "annul" bit. Patch replaces bne,a by bne instruction. Error can be reproduced by simple kernel module: -------------------- #include <linux/module.h> #include <linux/config.h> #include <linux/kernel.h> #include <linux/errno.h> #include <string.h> static void do_memset(void **p, int size) { memset(p, 0x00, size); } static int __init memset_test_init(void) { char fooc[8]; int *fooi; memset(fooc, 0xba, sizeof(fooc)); do_memset((void**)(fooc + 3), 1); fooi = (int*) fooc; printk("%08X %08X\n", fooi[0], fooi[1]); return -1; } static void __exit memset_test_cleanup(void) { return; } module_init(memset_test_init); module_exit(memset_test_cleanup); MODULE_LICENSE("GPL"); EXPORT_NO_SYMBOLS; -------------------- Signed-off-by: Alexander Shmelev <ashmelev@task.sun.mcst.ru> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/lib/memset.S2
1 files changed, 1 insertions, 1 deletions
diff --git a/arch/sparc/lib/memset.S b/arch/sparc/lib/memset.S
index a65eba41097c..1c37ea892deb 100644
--- a/arch/sparc/lib/memset.S
+++ b/arch/sparc/lib/memset.S
@@ -162,7 +162,7 @@ __bzero:
1628: 1628:
163 add %o0, 1, %o0 163 add %o0, 1, %o0
164 subcc %o1, 1, %o1 164 subcc %o1, 1, %o1
165 bne,a 8b 165 bne 8b
166 EX(stb %g3, [%o0 - 1], add %o1, 1) 166 EX(stb %g3, [%o0 - 1], add %o1, 1)
1670: 1670:
168 retl 168 retl