Commit a3f99858 authored by David S. Miller's avatar David S. Miller

[SPARC64]: Move kernel unaligned trap handlers into assembler file.

GCC 4.x really dislikes the games we are playing in
unaligned.c, and the cleanest way to fix this is to
move things into assembler.

Noted by Al Viro.
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8d529014
...@@ -8,7 +8,7 @@ EXTRA_CFLAGS := -Werror ...@@ -8,7 +8,7 @@ EXTRA_CFLAGS := -Werror
extra-y := head.o init_task.o vmlinux.lds extra-y := head.o init_task.o vmlinux.lds
obj-y := process.o setup.o cpu.o idprom.o \ obj-y := process.o setup.o cpu.o idprom.o \
traps.o devices.o auxio.o \ traps.o devices.o auxio.o una_asm.o \
irq.o ptrace.o time.o sys_sparc.o signal.o \ irq.o ptrace.o time.o sys_sparc.o signal.o \
unaligned.o central.o pci.o starfire.o semaphore.o \ unaligned.o central.o pci.o starfire.o semaphore.o \
power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o
......
...@@ -2127,6 +2127,9 @@ void __init trap_init(void) ...@@ -2127,6 +2127,9 @@ void __init trap_init(void)
TI_PRE_COUNT != offsetof(struct thread_info, preempt_count) || TI_PRE_COUNT != offsetof(struct thread_info, preempt_count) ||
TI_NEW_CHILD != offsetof(struct thread_info, new_child) || TI_NEW_CHILD != offsetof(struct thread_info, new_child) ||
TI_SYS_NOERROR != offsetof(struct thread_info, syscall_noerror) || TI_SYS_NOERROR != offsetof(struct thread_info, syscall_noerror) ||
TI_RESTART_BLOCK != offsetof(struct thread_info, restart_block) ||
TI_KUNA_REGS != offsetof(struct thread_info, kern_una_regs) ||
TI_KUNA_INSN != offsetof(struct thread_info, kern_una_insn) ||
TI_FPREGS != offsetof(struct thread_info, fpregs) || TI_FPREGS != offsetof(struct thread_info, fpregs) ||
(TI_FPREGS & (64 - 1))) (TI_FPREGS & (64 - 1)))
thread_info_offsets_are_bolixed_dave(); thread_info_offsets_are_bolixed_dave();
......
/* una_asm.S: Kernel unaligned trap assembler helpers.
*
* Copyright (C) 1996,2005 David S. Miller (davem@davemloft.net)
* Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
*/
.text
kernel_unaligned_trap_fault:
call kernel_mna_trap_fault
nop
retl
nop
.size kern_unaligned_trap_fault, .-kern_unaligned_trap_fault
.globl __do_int_store
__do_int_store:
rd %asi, %o4
wr %o3, 0, %asi
ldx [%o2], %g3
cmp %o1, 2
be,pn %icc, 2f
cmp %o1, 4
be,pt %icc, 1f
srlx %g3, 24, %g2
srlx %g3, 56, %g1
srlx %g3, 48, %g7
4: stba %g1, [%o0] %asi
srlx %g3, 40, %g1
5: stba %g7, [%o0 + 1] %asi
srlx %g3, 32, %g7
6: stba %g1, [%o0 + 2] %asi
7: stba %g7, [%o0 + 3] %asi
srlx %g3, 16, %g1
8: stba %g2, [%o0 + 4] %asi
srlx %g3, 8, %g7
9: stba %g1, [%o0 + 5] %asi
10: stba %g7, [%o0 + 6] %asi
ba,pt %xcc, 0f
11: stba %g3, [%o0 + 7] %asi
1: srl %g3, 16, %g7
12: stba %g2, [%o0] %asi
srl %g3, 8, %g2
13: stba %g7, [%o0 + 1] %asi
14: stba %g2, [%o0 + 2] %asi
ba,pt %xcc, 0f
15: stba %g3, [%o0 + 3] %asi
2: srl %g3, 8, %g2
16: stba %g2, [%o0] %asi
17: stba %g3, [%o0 + 1] %asi
0:
wr %o4, 0x0, %asi
retl
nop
.size __do_int_store, .-__do_int_store
.section __ex_table
.word 4b, kernel_unaligned_trap_fault
.word 5b, kernel_unaligned_trap_fault
.word 6b, kernel_unaligned_trap_fault
.word 7b, kernel_unaligned_trap_fault
.word 8b, kernel_unaligned_trap_fault
.word 9b, kernel_unaligned_trap_fault
.word 10b, kernel_unaligned_trap_fault
.word 11b, kernel_unaligned_trap_fault
.word 12b, kernel_unaligned_trap_fault
.word 13b, kernel_unaligned_trap_fault
.word 14b, kernel_unaligned_trap_fault
.word 15b, kernel_unaligned_trap_fault
.word 16b, kernel_unaligned_trap_fault
.word 17b, kernel_unaligned_trap_fault
.previous
.globl do_int_load
do_int_load:
rd %asi, %o5
wr %o4, 0, %asi
cmp %o1, 8
bge,pn %icc, 9f
cmp %o1, 4
be,pt %icc, 6f
4: lduba [%o2] %asi, %g2
5: lduba [%o2 + 1] %asi, %g3
sll %g2, 8, %g2
brz,pt %o3, 3f
add %g2, %g3, %g2
sllx %g2, 48, %g2
srax %g2, 48, %g2
3: ba,pt %xcc, 0f
stx %g2, [%o0]
6: lduba [%o2 + 1] %asi, %g3
sll %g2, 24, %g2
7: lduba [%o2 + 2] %asi, %g7
sll %g3, 16, %g3
8: lduba [%o2 + 3] %asi, %g1
sll %g7, 8, %g7
or %g2, %g3, %g2
or %g7, %g1, %g7
or %g2, %g7, %g2
brnz,a,pt %o3, 3f
sra %g2, 0, %g2
3: ba,pt %xcc, 0f
stx %g2, [%o0]
9: lduba [%o2] %asi, %g2
10: lduba [%o2 + 1] %asi, %g3
sllx %g2, 56, %g2
11: lduba [%o2 + 2] %asi, %g7
sllx %g3, 48, %g3
12: lduba [%o2 + 3] %asi, %g1
sllx %g7, 40, %g7
sllx %g1, 32, %g1
or %g2, %g3, %g2
or %g7, %g1, %g7
13: lduba [%o2 + 4] %asi, %g3
or %g2, %g7, %g7
14: lduba [%o2 + 5] %asi, %g1
sllx %g3, 24, %g3
15: lduba [%o2 + 6] %asi, %g2
sllx %g1, 16, %g1
or %g7, %g3, %g7
16: lduba [%o2 + 7] %asi, %g3
sllx %g2, 8, %g2
or %g7, %g1, %g7
or %g2, %g3, %g2
or %g7, %g2, %g7
cmp %o1, 8
be,a,pt %icc, 0f
stx %g7, [%o0]
srlx %g7, 32, %g2
sra %g7, 0, %g7
stx %g2, [%o0]
stx %g7, [%o0 + 8]
0:
wr %o5, 0x0, %asi
retl
nop
.size __do_int_load, .-__do_int_load
.section __ex_table
.word 4b, kernel_unaligned_trap_fault
.word 5b, kernel_unaligned_trap_fault
.word 6b, kernel_unaligned_trap_fault
.word 7b, kernel_unaligned_trap_fault
.word 8b, kernel_unaligned_trap_fault
.word 9b, kernel_unaligned_trap_fault
.word 10b, kernel_unaligned_trap_fault
.word 11b, kernel_unaligned_trap_fault
.word 12b, kernel_unaligned_trap_fault
.word 13b, kernel_unaligned_trap_fault
.word 14b, kernel_unaligned_trap_fault
.word 15b, kernel_unaligned_trap_fault
.word 16b, kernel_unaligned_trap_fault
.previous
This diff is collapsed.
...@@ -68,6 +68,9 @@ struct thread_info { ...@@ -68,6 +68,9 @@ struct thread_info {
struct restart_block restart_block; struct restart_block restart_block;
struct pt_regs *kern_una_regs;
unsigned int kern_una_insn;
unsigned long fpregs[0] __attribute__ ((aligned(64))); unsigned long fpregs[0] __attribute__ ((aligned(64)));
}; };
...@@ -103,6 +106,8 @@ struct thread_info { ...@@ -103,6 +106,8 @@ struct thread_info {
#define TI_PCR 0x00000490 #define TI_PCR 0x00000490
#define TI_CEE_STUFF 0x00000498 #define TI_CEE_STUFF 0x00000498
#define TI_RESTART_BLOCK 0x000004a0 #define TI_RESTART_BLOCK 0x000004a0
#define TI_KUNA_REGS 0x000004c8
#define TI_KUNA_INSN 0x000004d0
#define TI_FPREGS 0x00000500 #define TI_FPREGS 0x00000500
/* We embed this in the uppermost byte of thread_info->flags */ /* We embed this in the uppermost byte of thread_info->flags */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment