diff mbox series

powerpc/sstep: Fix VSX instruction emulation

Message ID 20210225031946.1458206-1-jniethe5@gmail.com (mailing list archive)
State Accepted
Headers show
Series powerpc/sstep: Fix VSX instruction emulation | expand

Checks

Context Check Description
snowpatch_ozlabs/apply_patch success Successfully applied on branch powerpc/merge (626a6c3d2e20da80aaa710104f34ea6037b28b33)
snowpatch_ozlabs/build-ppc64le success Build succeeded
snowpatch_ozlabs/build-ppc64be success Build succeeded
snowpatch_ozlabs/build-ppc64e success Build succeeded
snowpatch_ozlabs/build-pmac32 success Build succeeded
snowpatch_ozlabs/checkpatch success total: 0 errors, 0 warnings, 0 checks, 16 lines checked
snowpatch_ozlabs/needsstable warning Please consider tagging this patch for stable!

Commit Message

Jordan Niethe Feb. 25, 2021, 3:19 a.m. UTC
Commit af99da74333b ("powerpc/sstep: Support VSX vector paired storage
access instructions") added loading and storing 32 word long data into
adjacent VSRs. However the calculation used to determine if two VSRs
needed to be loaded/stored inadvertently prevented the load/storing
taking place for instructions with a data length less than 16 words.

This causes the emulation to not function correctly, which can be seen
by the alignment_handler selftest:

$ ./alignment_handler
[snip]
test: test_alignment_handler_vsx_207
tags: git_version:powerpc-5.12-1-0-g82d2c16b350f
VSX: 2.07B
        Doing lxsspx:   PASSED
        Doing lxsiwax:  FAILED: Wrong Data
        Doing lxsiwzx:  PASSED
        Doing stxsspx:  PASSED
        Doing stxsiwx:  PASSED
failure: test_alignment_handler_vsx_207
test: test_alignment_handler_vsx_300
tags: git_version:powerpc-5.12-1-0-g82d2c16b350f
VSX: 3.00B
        Doing lxsd:     PASSED
        Doing lxsibzx:  PASSED
        Doing lxsihzx:  PASSED
        Doing lxssp:    FAILED: Wrong Data
        Doing lxv:      PASSED
        Doing lxvb16x:  PASSED
        Doing lxvh8x:   PASSED
        Doing lxvx:     PASSED
        Doing lxvwsx:   FAILED: Wrong Data
        Doing lxvl:     PASSED
        Doing lxvll:    PASSED
        Doing stxsd:    PASSED
        Doing stxsibx:  PASSED
        Doing stxsihx:  PASSED
        Doing stxssp:   PASSED
        Doing stxv:     PASSED
        Doing stxvb16x: PASSED
        Doing stxvh8x:  PASSED
        Doing stxvx:    PASSED
        Doing stxvl:    PASSED
        Doing stxvll:   PASSED
failure: test_alignment_handler_vsx_300
[snip]

Fix this by making sure all VSX instruction emulation correctly
load/store from the VSRs.

Fixes: af99da74333b ("powerpc/sstep: Support VSX vector paired storage access instructions")
Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
 arch/powerpc/lib/sstep.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Ravi Bangoria Feb. 26, 2021, 11:09 a.m. UTC | #1
On 2/25/21 8:49 AM, Jordan Niethe wrote:
> Commit af99da74333b ("powerpc/sstep: Support VSX vector paired storage
> access instructions") added loading and storing 32 word long data into
> adjacent VSRs. However the calculation used to determine if two VSRs
> needed to be loaded/stored inadvertently prevented the load/storing
> taking place for instructions with a data length less than 16 words.
> 
> This causes the emulation to not function correctly, which can be seen
> by the alignment_handler selftest:
> 
> $ ./alignment_handler
> [snip]
> test: test_alignment_handler_vsx_207
> tags: git_version:powerpc-5.12-1-0-g82d2c16b350f
> VSX: 2.07B
>          Doing lxsspx:   PASSED
>          Doing lxsiwax:  FAILED: Wrong Data
>          Doing lxsiwzx:  PASSED
>          Doing stxsspx:  PASSED
>          Doing stxsiwx:  PASSED
> failure: test_alignment_handler_vsx_207
> test: test_alignment_handler_vsx_300
> tags: git_version:powerpc-5.12-1-0-g82d2c16b350f
> VSX: 3.00B
>          Doing lxsd:     PASSED
>          Doing lxsibzx:  PASSED
>          Doing lxsihzx:  PASSED
>          Doing lxssp:    FAILED: Wrong Data
>          Doing lxv:      PASSED
>          Doing lxvb16x:  PASSED
>          Doing lxvh8x:   PASSED
>          Doing lxvx:     PASSED
>          Doing lxvwsx:   FAILED: Wrong Data
>          Doing lxvl:     PASSED
>          Doing lxvll:    PASSED
>          Doing stxsd:    PASSED
>          Doing stxsibx:  PASSED
>          Doing stxsihx:  PASSED
>          Doing stxssp:   PASSED
>          Doing stxv:     PASSED
>          Doing stxvb16x: PASSED
>          Doing stxvh8x:  PASSED
>          Doing stxvx:    PASSED
>          Doing stxvl:    PASSED
>          Doing stxvll:   PASSED
> failure: test_alignment_handler_vsx_300
> [snip]
> 
> Fix this by making sure all VSX instruction emulation correctly
> load/store from the VSRs.
> 
> Fixes: af99da74333b ("powerpc/sstep: Support VSX vector paired storage access instructions")
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>

Yikes!

Reviewed-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
Michael Ellerman March 14, 2021, 10:01 a.m. UTC | #2
On Thu, 25 Feb 2021 14:19:46 +1100, Jordan Niethe wrote:
> Commit af99da74333b ("powerpc/sstep: Support VSX vector paired storage
> access instructions") added loading and storing 32 word long data into
> adjacent VSRs. However the calculation used to determine if two VSRs
> needed to be loaded/stored inadvertently prevented the load/storing
> taking place for instructions with a data length less than 16 words.
> 
> This causes the emulation to not function correctly, which can be seen
> by the alignment_handler selftest:
> 
> [...]

Applied to powerpc/fixes.

[1/1] powerpc/sstep: Fix VSX instruction emulation
      https://git.kernel.org/powerpc/c/5c88a17e15795226b56d83f579cbb9b7a4864f79

cheers
diff mbox series

Patch

diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 683f7c20f74b..3953e63bbba5 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -902,7 +902,7 @@  static nokprobe_inline int do_vsx_load(struct instruction_op *op,
 	if (!address_ok(regs, ea, size) || copy_mem_in(mem, ea, size, regs))
 		return -EFAULT;
 
-	nr_vsx_regs = size / sizeof(__vector128);
+	nr_vsx_regs = max(1ul, size / sizeof(__vector128));
 	emulate_vsx_load(op, buf, mem, cross_endian);
 	preempt_disable();
 	if (reg < 32) {
@@ -949,7 +949,7 @@  static nokprobe_inline int do_vsx_store(struct instruction_op *op,
 	if (!address_ok(regs, ea, size))
 		return -EFAULT;
 
-	nr_vsx_regs = size / sizeof(__vector128);
+	nr_vsx_regs = max(1ul, size / sizeof(__vector128));
 	preempt_disable();
 	if (reg < 32) {
 		/* FP regs + extensions */