linux/arch/arm/lib/csumpartialcopy.S
Catalin Marinas 90303b1023 [ARM] 3256/1: Make the function-returning ldm's use sp as the base register
Patch from Catalin Marinas

If the low interrupt latency mode is enabled for the CPU (from ARMv6
onwards), the ldm/stm instructions are no longer atomic. An ldm instruction
restoring the sp and pc registers can be interrupted immediately after sp
was updated but before the pc. If this happens, the CPU restores the base
register to the value before the ldm instruction but if the base register
is not sp, the interrupt routine will corrupt the stack and the restarted
ldm instruction will load garbage.

Note that future ARM cores might always run in the low interrupt latency
mode.

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2006-01-12 16:53:51 +00:00

55 lines
1.1 KiB
ArmAsm

/*
* linux/arch/arm/lib/csumpartialcopy.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.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
.text
/* Function: __u32 csum_partial_copy_nocheck(const char *src, char *dst, int len, __u32 sum)
* Params : r0 = src, r1 = dst, r2 = len, r3 = checksum
* Returns : r0 = new checksum
*/
.macro save_regs
mov ip, sp
stmfd sp!, {r1, r4 - r8, fp, ip, lr, pc}
sub fp, ip, #4
.endm
.macro load_regs
ldmfd sp, {r1, r4 - r8, fp, sp, pc}
.endm
.macro load1b, reg1
ldrb \reg1, [r0], #1
.endm
.macro load2b, reg1, reg2
ldrb \reg1, [r0], #1
ldrb \reg2, [r0], #1
.endm
.macro load1l, reg1
ldr \reg1, [r0], #4
.endm
.macro load2l, reg1, reg2
ldr \reg1, [r0], #4
ldr \reg2, [r0], #4
.endm
.macro load4l, reg1, reg2, reg3, reg4
ldmia r0!, {\reg1, \reg2, \reg3, \reg4}
.endm
#define FN_ENTRY ENTRY(csum_partial_copy_nocheck)
#include "csumpartialcopygeneric.S"