From: Michael Neuling <mikey@neuling.org>
To: Neil Campbell <neilc@linux.vnet.ibm.com>
Cc: linuxppc-dev@ozlabs.org
Subject: Re: [PATCH] powerpc: handle VSX alignment faults correctly in little-endian mode
Date: Tue, 15 Dec 2009 08:05:08 +1100 [thread overview]
Message-ID: <14867.1260824708@neuling.org> (raw)
In-Reply-To: <4B2646F9.4000203@linux.vnet.ibm.com>
> This patch fixes the handling of VSX alignment faults in little-endian
> mode (the current code assumes the processor is in big-endian mode).
>
> The patch also makes the handlers clear the top 8 bytes of the register
> when handling an 8 byte VSX load.
>
> This is based on 2.6.32.
>
> Signed-off-by: Neil Campbell <neilc@linux.vnet.ibm.com>
Thanks for this Neil!
Acked-by: Michael Neuling <mikey@neuling.org>
> Cc: <stable@kernel.org>
> ---
> diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
> index a5b632e..f0c624f 100644
> --- a/arch/powerpc/kernel/align.c
> +++ b/arch/powerpc/kernel/align.c
> @@ -642,10 +642,14 @@ static int emulate_spe(struct pt_regs *regs, unsigned i
nt reg,
> */
> static int emulate_vsx(unsigned char __user *addr, unsigned int reg,
> unsigned int areg, struct pt_regs *regs,
> - unsigned int flags, unsigned int length)
> + unsigned int flags, unsigned int length,
> + unsigned int elsize)
> {
> char *ptr;
> + unsigned long *lptr;
> int ret = 0;
> + int sw = 0;
> + int i, j;
>
> flush_vsx_to_thread(current);
>
> @@ -654,19 +658,35 @@ static int emulate_vsx(unsigned char __user *addr, unsi
gned int reg,
> else
> ptr = (char *) ¤t->thread.vr[reg - 32];
>
> - if (flags & ST)
> - ret = __copy_to_user(addr, ptr, length);
> - else {
> - if (flags & SPLT){
> - ret = __copy_from_user(ptr, addr, length);
> - ptr += length;
> + lptr = (unsigned long *) ptr;
> +
> + if (flags & SW)
> + sw = elsize-1;
> +
> + for (j = 0; j < length; j += elsize) {
> + for (i = 0; i < elsize; ++i) {
> + if (flags & ST)
> + ret |= __put_user(ptr[i^sw], addr + i);
> + else
> + ret |= __get_user(ptr[i^sw], addr + i);
> }
> - ret |= __copy_from_user(ptr, addr, length);
> + ptr += elsize;
> + addr += elsize;
> }
> - if (flags & U)
> - regs->gpr[areg] = regs->dar;
> - if (ret)
> +
> + if (!ret) {
> + if (flags & U)
> + regs->gpr[areg] = regs->dar;
> +
> + /* Splat load copies the same data to top and bottom 8 bytes */
> + if (flags & SPLT)
> + lptr[1] = lptr[0];
> + /* For 8 byte loads, zero the top 8 bytes */
> + else if (!(flags & ST) && (8 == length))
> + lptr[1] = 0;
> + } else
> return -EFAULT;
> +
> return 1;
> }
> #endif
> @@ -767,16 +787,25 @@ int fix_alignment(struct pt_regs *regs)
>
> #ifdef CONFIG_VSX
> if ((instruction & 0xfc00003e) == 0x7c000018) {
> - /* Additional register addressing bit (64 VSX vs 32 FPR/GPR */
> + unsigned int elsize;
> +
> + /* Additional register addressing bit (64 VSX vs 32 FPR/GPR) */
> reg |= (instruction & 0x1) << 5;
> /* Simple inline decoder instead of a table */
> + /* VSX has only 8 and 16 byte memory accesses */
> + nb = 8;
> if (instruction & 0x200)
> nb = 16;
> - else if (instruction & 0x080)
> - nb = 8;
> - else
> - nb = 4;
> +
> + /* Vector stores in little-endian mode swap individual
> + elements, so process them separately */
> + elsize = 4;
> + if (instruction & 0x80)
> + elsize = 8;
> +
> flags = 0;
> + if (regs->msr & MSR_LE)
> + flags |= SW;
> if (instruction & 0x100)
> flags |= ST;
> if (instruction & 0x040)
> @@ -787,7 +816,7 @@ int fix_alignment(struct pt_regs *regs)
> nb = 8;
> }
> PPC_WARN_EMULATED(vsx);
> - return emulate_vsx(addr, reg, areg, regs, flags, nb);
> + return emulate_vsx(addr, reg, areg, regs, flags, nb, elsize);
> }
> #endif
> /* A size of 0 indicates an instruction we don't support, with
>
prev parent reply other threads:[~2009-12-14 21:05 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-12-14 14:08 [PATCH] powerpc: handle VSX alignment faults correctly in little-endian mode Neil Campbell
2009-12-14 14:21 ` Neil Campbell
2009-12-14 21:05 ` Michael Neuling [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=14867.1260824708@neuling.org \
--to=mikey@neuling.org \
--cc=linuxppc-dev@ozlabs.org \
--cc=neilc@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.