4609a179c9
Using the parent functions frame pointer to access our arguments is completely wrong, whether or not we're building with frame pointers or not. What we should be using is the stack pointer to get at the word above the registers we stacked ourselves. Reported-by: Bosko Radivojevic <bosko.radivojevic@gmail.com> Tested-by: Bosko Radivojevic <bosko.radivojevic@gmail.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
83 lines
1.9 KiB
ArmAsm
83 lines
1.9 KiB
ArmAsm
/*
|
|
* linux/arch/arm/lib/csumpartialcopyuser.S
|
|
*
|
|
* Copyright (C) 1995-1998 Russell King
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* 27/03/03 Ian Molton Clean up CONFIG_CPU
|
|
*
|
|
*/
|
|
#include <linux/linkage.h>
|
|
#include <asm/assembler.h>
|
|
#include <asm/errno.h>
|
|
#include <asm/asm-offsets.h>
|
|
|
|
.text
|
|
|
|
.macro save_regs
|
|
stmfd sp!, {r1, r2, r4 - r8, lr}
|
|
.endm
|
|
|
|
.macro load_regs
|
|
ldmfd sp!, {r1, r2, r4 - r8, pc}
|
|
.endm
|
|
|
|
.macro load1b, reg1
|
|
ldrusr \reg1, r0, 1
|
|
.endm
|
|
|
|
.macro load2b, reg1, reg2
|
|
ldrusr \reg1, r0, 1
|
|
ldrusr \reg2, r0, 1
|
|
.endm
|
|
|
|
.macro load1l, reg1
|
|
ldrusr \reg1, r0, 4
|
|
.endm
|
|
|
|
.macro load2l, reg1, reg2
|
|
ldrusr \reg1, r0, 4
|
|
ldrusr \reg2, r0, 4
|
|
.endm
|
|
|
|
.macro load4l, reg1, reg2, reg3, reg4
|
|
ldrusr \reg1, r0, 4
|
|
ldrusr \reg2, r0, 4
|
|
ldrusr \reg3, r0, 4
|
|
ldrusr \reg4, r0, 4
|
|
.endm
|
|
|
|
/*
|
|
* unsigned int
|
|
* csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *err_ptr)
|
|
* r0 = src, r1 = dst, r2 = len, r3 = sum, [sp] = *err_ptr
|
|
* Returns : r0 = checksum, [[sp, #0], #0] = 0 or -EFAULT
|
|
*/
|
|
|
|
#define FN_ENTRY ENTRY(csum_partial_copy_from_user)
|
|
#define FN_EXIT ENDPROC(csum_partial_copy_from_user)
|
|
|
|
#include "csumpartialcopygeneric.S"
|
|
|
|
/*
|
|
* FIXME: minor buglet here
|
|
* We don't return the checksum for the data present in the buffer. To do
|
|
* so properly, we would have to add in whatever registers were loaded before
|
|
* the fault, which, with the current asm above is not predictable.
|
|
*/
|
|
.pushsection .fixup,"ax"
|
|
.align 4
|
|
9001: mov r4, #-EFAULT
|
|
ldr r5, [sp, #8*4] @ *err_ptr
|
|
str r4, [r5]
|
|
ldmia sp, {r1, r2} @ retrieve dst, len
|
|
add r2, r2, r1
|
|
mov r0, #0 @ zero the buffer
|
|
9002: teq r2, r1
|
|
strneb r0, [r1], #1
|
|
bne 9002b
|
|
load_regs
|
|
.popsection
|