powerpc: Merge align.c (#2)
PATCH 1/1 powerpc: Merge align.c (#2)
Need testing !!!
This patch merges align.c, the result isn't quite what was in ppc64 nor what was in ppc32 :) It should implement all the functionalities of both though. Kumar, since you played with that in the past, I suppose you have some test cases for verifying that it works properly before I dig out the 601 machine ? :)
Since it's likely that I won't be able to test all scenario, code inspection is much welcome.
Signed-off-by Benjamin Herrenschmidt <[email protected]>
---
No difference, just rebased on current -git
arch/powerpc/kernel/Makefile +1 -1
@@ -12,7 +12,7 @@ endif obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ - irq.o signal_32.o pmc.o vdso.o + irq.o align.o signal_32.o pmc.o vdso.o obj-y += vdso32/ obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ signal_64.o ptrace32.o systbl.o \
arch/powerpc/kernel/align.c new file +513 -0
513 lines not on this page · raw message
arch/ppc/kernel/Makefile +1 -1
@@ -13,7 +13,7 @@ extra-y += vmlinux.lds obj-y := entry.o traps.o idle.o time.o misc.o \ - process.o align.o \ + process.o \ setup.o \ ppc_htab.o obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o
arch/ppc64/kernel/Makefile +1 -1
@@ -2,6 +2,6 @@ # Makefile for the linux ppc64 kernel. # -obj-y += idle.o align.o +obj-y += idle.o obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o
include/asm-powerpc/cputable.h +12 -10
@@ -90,6 +90,7 @@#define CPU_FTR_NEED_COHERENT ASM_CONST(0x0000000000020000)#define CPU_FTR_NO_BTIC ASM_CONST(0x0000000000040000)#define CPU_FTR_BIG_PHYS ASM_CONST(0x0000000000080000) +#define CPU_FTR_NODSISRALIGN ASM_CONST(0x0000000000100000)#ifdef __powerpc64__/* Add the 64b processor unique features in the top half of the word */
@@ -97,7 +98,6 @@#define CPU_FTR_16M_PAGE ASM_CONST(0x0000000200000000)#define CPU_FTR_TLBIEL ASM_CONST(0x0000000400000000)#define CPU_FTR_NOEXECUTE ASM_CONST(0x0000000800000000) -#define CPU_FTR_NODSISRALIGN ASM_CONST(0x0000001000000000)#define CPU_FTR_IABR ASM_CONST(0x0000002000000000)#define CPU_FTR_MMCRA ASM_CONST(0x0000004000000000)#define CPU_FTR_CTRL ASM_CONST(0x0000008000000000)
@@ -113,7 +113,6 @@#define CPU_FTR_16M_PAGE ASM_CONST(0x0)#define CPU_FTR_TLBIEL ASM_CONST(0x0)#define CPU_FTR_NOEXECUTE ASM_CONST(0x0) -#define CPU_FTR_NODSISRALIGN ASM_CONST(0x0)#define CPU_FTR_IABR ASM_CONST(0x0)#define CPU_FTR_MMCRA ASM_CONST(0x0)#define CPU_FTR_CTRL ASM_CONST(0x0)
@@ -273,18 +272,21 @@CPU_FTRS_POWER3_32 =CPU_FTR_COMMON |CPU_FTR_SPLIT_ID_CACHE |CPU_FTR_USE_TB |CPU_FTR_HPTE_TABLE ,CPU_FTRS_POWER4_32 =CPU_FTR_COMMON |CPU_FTR_SPLIT_ID_CACHE | -CPU_FTR_USE_TB |CPU_FTR_HPTE_TABLE , +CPU_FTR_USE_TB |CPU_FTR_HPTE_TABLE |CPU_FTR_NODSISRALIGN ,CPU_FTRS_970_32 =CPU_FTR_COMMON |CPU_FTR_SPLIT_ID_CACHE |CPU_FTR_USE_TB |CPU_FTR_HPTE_TABLE |CPU_FTR_ALTIVEC_COMP | -CPU_FTR_MAYBE_CAN_NAP , +CPU_FTR_MAYBE_CAN_NAP |CPU_FTR_NODSISRALIGN ,CPU_FTRS_8XX =CPU_FTR_SPLIT_ID_CACHE |CPU_FTR_USE_TB , -CPU_FTRS_40X =CPU_FTR_SPLIT_ID_CACHE |CPU_FTR_USE_TB , -CPU_FTRS_44X =CPU_FTR_SPLIT_ID_CACHE |CPU_FTR_USE_TB , -CPU_FTRS_E200 =CPU_FTR_USE_TB , -CPU_FTRS_E500 =CPU_FTR_SPLIT_ID_CACHE |CPU_FTR_USE_TB , +CPU_FTRS_40X =CPU_FTR_SPLIT_ID_CACHE |CPU_FTR_USE_TB | +CPU_FTR_NODSISRALIGN , +CPU_FTRS_44X =CPU_FTR_SPLIT_ID_CACHE |CPU_FTR_USE_TB | +CPU_FTR_NODSISRALIGN , +CPU_FTRS_E200 =CPU_FTR_USE_TB |CPU_FTR_NODSISRALIGN , +CPU_FTRS_E500 =CPU_FTR_SPLIT_ID_CACHE |CPU_FTR_USE_TB | +CPU_FTR_NODSISRALIGN ,CPU_FTRS_E500_2 =CPU_FTR_SPLIT_ID_CACHE |CPU_FTR_USE_TB | -CPU_FTR_BIG_PHYS , -CPU_FTRS_GENERIC_32 =CPU_FTR_COMMON , +CPU_FTR_BIG_PHYS |CPU_FTR_NODSISRALIGN , +CPU_FTRS_GENERIC_32 =CPU_FTR_COMMON |CPU_FTR_NODSISRALIGN , #ifdef __powerpc64__CPU_FTRS_POWER3 =CPU_FTR_SPLIT_ID_CACHE |CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR,
arch/ppc64/kernel/align.c deleted +0 -396
396 lines not on this page · raw message
Quoted 2 lines · Benjamin Herrenschmidt
Since it's likely that I won't be able to test all scenario, code inspection is much welcome.
I think you need this patch on top...
Paul.
arch/powerpc/kernel/align.c +33 -16
@@ -198,21 +198,20 @@/* bits 6:15 --> 22:31 */ dsisr = (instr &0x03ff0000 ) >>16 ; -if (IS_XFORM (instr) ) { +if (IS_XFORM (instr)) {/* bits 29:30 --> 15:16 */ dsisr |= (instr &0x00000006 ) <<14 ;/* bit 25 --> 17 */ dsisr |= (instr &0x00000040 ) <<8 ;/* bits 21:24 --> 18:21 */ dsisr |= (instr &0x00000780 ) <<3 ; - } -else { + }else {/* bit 5 --> 17 */ dsisr |= (instr &0x04000000 ) >>12 ;/* bits 1: 4 --> 18:21 */ dsisr |= (instr &0x78000000 ) >>17 ;/* bits 30:31 --> 12:13 */ -if (IS_DSFORM (instr) ) +if (IS_DSFORM (instr)) dsisr |= (instr &0x00000003 ) <<18 ; }
@@ -247,13 +246,22 @@/* * Emulate load & store multiple instructions +* On 64-bit machines, these instructions only affect/use the +* bottom 4 bytes of each register, and the loads clear the +* top 4 bytes of the affected register. */ +#ifdef CONFIG_PPC64 +#define REG_BYTE (rp, i) *((u8 *)((rp) + ((i) >> 2)) + ((i) & 3) + 4) +#else +#define REG_BYTE (rp, i) *((u8 *)(rp) + (i)) +#endif +static int emulate_multiple (struct pt_regs *regs,unsigned char __user *addr,unsigned int reg,unsigned int nb,unsigned int flags,unsigned int instr) { -unsigned char *rptr; -int nb0, i; +unsigned long *rptr; +unsigned int nb0, i;/* * We do not try to emulate 8 bytes multiple as they aren't really
@@ -291,29 +299,38 @@if (!access_ok ((flags &ST ?VERIFY_WRITE :VERIFY_READ ), addr, nb+nb0))return -EFAULT ;/* bad address */ - rptr = (unsigned char *) ®s->gpr[reg]; + rptr = ®s->gpr[reg];if (flags &LD ) { +/* +* This zeroes the top 4 bytes of the affected registers +* in 64-bit mode, and also zeroes out any remaining +* bytes of the last register for lsw*. +*/ +memset (rptr,0 , ((nb +3 ) /4 ) *sizeof (unsigned long )); +if (nb0 >0 ) +memset (®s->gpr[0 ],0 , + ((nb0 +3 ) /4 ) *sizeof (unsigned long )); +for (i =0 ; i < nb; ++i) -if (__get_user (rptr[i], addr + i)) +if (__get_user (REG_BYTE (rptr, i), addr + i))return -EFAULT ;if (nb0 >0 ) { - rptr = (unsigned char *) ®s->gpr[0 ]; + rptr = ®s->gpr[0 ]; addr += nb;for (i =0 ; i < nb0; ++i) -if (__get_user (rptr[i], addr + i)) +if (__get_user (REG_BYTE (rptr, i), addr + i))return -EFAULT ; } -for (; (i &3 ) !=0 ; ++i) - rptr[i] =0 ; + }else {for (i =0 ; i < nb; ++i) -if (__put_user (rptr[i], addr + i)) +if (__put_user (REG_BYTE (rptr, i), addr + i))return -EFAULT ;if (nb0 >0 ) { - rptr = (unsigned char *) ®s->gpr[0 ]; + rptr = ®s->gpr[0 ]; addr += nb;for (i =0 ; i < nb0; ++i) -if (__put_user (rptr[i], addr + i)) +if (__put_user (REG_BYTE (rptr, i), addr + i))return -EFAULT ; } }
@@ -338,7 +355,7 @@unsigned char __user *p;int ret, t;union { -long ll; +u64 ll;double dd;unsigned char v[8 ];struct {