]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
selftests/powerpc: Fix prefixes in alignment_handler signal handler
authorJordan Niethe <jniethe5@gmail.com>
Mon, 24 Aug 2020 13:12:31 +0000 (23:12 +1000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 Oct 2020 09:11:39 +0000 (10:11 +0100)
[ Upstream commit db96221a683342fd4775fd820a4d5376cd2f2ed0 ]

The signal handler in the alignment handler self test has the ability
to jump over the instruction that triggered the signal. It does this
by incrementing the PT_NIP in the user context by 4. If it were a
prefixed instruction this will mean that the suffix is then executed
which is incorrect. Instead check if the major opcode indicates a
prefixed instruction (e.g. it is 1) and if so increment PT_NIP by 8.

If ISA v3.1 is not available treat it as a word instruction even if
the major opcode is 1.

Fixes: 620a6473df36 ("selftests/powerpc: Add prefixed loads/stores to alignment_handler test")
Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
[mpe: Fix 32-bit build, rename haveprefixes to prefixes_enabled]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200824131231.14008-1-jniethe5@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
tools/testing/selftests/powerpc/alignment/alignment_handler.c

index 55ef15184057d337ad589bf11477fa364fcaef0e..386bca731e58108dd44c9715a88afc0053dc3f19 100644 (file)
@@ -64,6 +64,7 @@ int bufsize;
 int debug;
 int testing;
 volatile int gotsig;
+bool prefixes_enabled;
 char *cipath = "/dev/fb0";
 long cioffset;
 
@@ -77,7 +78,12 @@ void sighandler(int sig, siginfo_t *info, void *ctx)
        }
        gotsig = sig;
 #ifdef __powerpc64__
-       ucp->uc_mcontext.gp_regs[PT_NIP] += 4;
+       if (prefixes_enabled) {
+               u32 inst = *(u32 *)ucp->uc_mcontext.gp_regs[PT_NIP];
+               ucp->uc_mcontext.gp_regs[PT_NIP] += ((inst >> 26 == 1) ? 8 : 4);
+       } else {
+               ucp->uc_mcontext.gp_regs[PT_NIP] += 4;
+       }
 #else
        ucp->uc_mcontext.uc_regs->gregs[PT_NIP] += 4;
 #endif
@@ -648,6 +654,8 @@ int main(int argc, char *argv[])
                exit(1);
        }
 
+       prefixes_enabled = have_hwcap2(PPC_FEATURE2_ARCH_3_1);
+
        rc |= test_harness(test_alignment_handler_vsx_206,
                           "test_alignment_handler_vsx_206");
        rc |= test_harness(test_alignment_handler_vsx_207,