Expand the feature-fixups self-tests to includes tests for prefixed
instructions.

Signed-off-by: Jordan Niethe <jniet...@gmail.com>
---
v6: New to series
v8: Use OP_PREFIX
---
 arch/powerpc/lib/feature-fixups-test.S | 69 ++++++++++++++++++++++++
 arch/powerpc/lib/feature-fixups.c      | 73 ++++++++++++++++++++++++++
 2 files changed, 142 insertions(+)

diff --git a/arch/powerpc/lib/feature-fixups-test.S 
b/arch/powerpc/lib/feature-fixups-test.S
index b12168c2447a..480172fbd024 100644
--- a/arch/powerpc/lib/feature-fixups-test.S
+++ b/arch/powerpc/lib/feature-fixups-test.S
@@ -7,6 +7,7 @@
 #include <asm/ppc_asm.h>
 #include <asm/synch.h>
 #include <asm/asm-compat.h>
+#include <asm/ppc-opcode.h>
 
        .text
 
@@ -791,3 +792,71 @@ globl(lwsync_fixup_test_expected_SYNC)
 1:     or      1,1,1
        sync
 
+globl(ftr_fixup_prefix1)
+       or      1,1,1
+       .long OP_PREFIX << 26
+       .long 0x0000000
+       or      2,2,2
+globl(end_ftr_fixup_prefix1)
+
+globl(ftr_fixup_prefix1_orig)
+       or      1,1,1
+       .long OP_PREFIX << 26
+       .long 0x0000000
+       or      2,2,2
+
+globl(ftr_fixup_prefix1_expected)
+       or      1,1,1
+       nop
+       nop
+       or      2,2,2
+
+globl(ftr_fixup_prefix2)
+       or      1,1,1
+       .long OP_PREFIX << 26
+       .long 0x0000000
+       or      2,2,2
+globl(end_ftr_fixup_prefix2)
+
+globl(ftr_fixup_prefix2_orig)
+       or      1,1,1
+       .long OP_PREFIX << 26
+       .long 0x0000000
+       or      2,2,2
+
+globl(ftr_fixup_prefix2_alt)
+       .long OP_PREFIX << 26
+       .long 0x0000001
+
+globl(ftr_fixup_prefix2_expected)
+       or      1,1,1
+       .long OP_PREFIX << 26
+       .long 0x0000001
+       or      2,2,2
+
+globl(ftr_fixup_prefix3)
+       or      1,1,1
+       .long OP_PREFIX << 26
+       .long 0x0000000
+       or      2,2,2
+       or      3,3,3
+globl(end_ftr_fixup_prefix3)
+
+globl(ftr_fixup_prefix3_orig)
+       or      1,1,1
+       .long OP_PREFIX << 26
+       .long 0x0000000
+       or      2,2,2
+       or      3,3,3
+
+globl(ftr_fixup_prefix3_alt)
+       .long OP_PREFIX << 26
+       .long 0x0000001
+       nop
+
+globl(ftr_fixup_prefix3_expected)
+       or      1,1,1
+       .long OP_PREFIX << 26
+       .long 0x0000001
+       nop
+       or      3,3,3
diff --git a/arch/powerpc/lib/feature-fixups.c 
b/arch/powerpc/lib/feature-fixups.c
index a8238eff3a31..5144854713e6 100644
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -689,6 +689,74 @@ static void test_lwsync_macros(void)
        }
 }
 
+#ifdef __powerpc64__
+static void __init test_prefix_patching(void)
+{
+       extern unsigned int ftr_fixup_prefix1[];
+       extern unsigned int end_ftr_fixup_prefix1[];
+       extern unsigned int ftr_fixup_prefix1_orig[];
+       extern unsigned int ftr_fixup_prefix1_expected[];
+       int size = sizeof(unsigned int) * (end_ftr_fixup_prefix1 - 
ftr_fixup_prefix1);
+
+       fixup.value = fixup.mask = 8;
+       fixup.start_off = calc_offset(&fixup, ftr_fixup_prefix1 + 1);
+       fixup.end_off = calc_offset(&fixup, ftr_fixup_prefix1 + 3);
+       fixup.alt_start_off = fixup.alt_end_off = 0;
+
+       /* Sanity check */
+       check(memcmp(ftr_fixup_prefix1, ftr_fixup_prefix1_orig, size) == 0);
+
+       patch_feature_section(0, &fixup);
+       check(memcmp(ftr_fixup_prefix1, ftr_fixup_prefix1_expected, size) == 0);
+       check(memcmp(ftr_fixup_prefix1, ftr_fixup_prefix1_orig, size) != 0);
+}
+
+static void __init test_prefix_alt_patching(void)
+{
+       extern unsigned int ftr_fixup_prefix2[];
+       extern unsigned int end_ftr_fixup_prefix2[];
+       extern unsigned int ftr_fixup_prefix2_orig[];
+       extern unsigned int ftr_fixup_prefix2_expected[];
+       extern unsigned int ftr_fixup_prefix2_alt[];
+       int size = sizeof(unsigned int) * (end_ftr_fixup_prefix2 - 
ftr_fixup_prefix2);
+
+       fixup.value = fixup.mask = 8;
+       fixup.start_off = calc_offset(&fixup, ftr_fixup_prefix2 + 1);
+       fixup.end_off = calc_offset(&fixup, ftr_fixup_prefix2 + 3);
+       fixup.alt_start_off = calc_offset(&fixup, ftr_fixup_prefix2_alt);
+       fixup.alt_end_off = calc_offset(&fixup, ftr_fixup_prefix2_alt + 2);
+       /* Sanity check */
+       check(memcmp(ftr_fixup_prefix2, ftr_fixup_prefix2_orig, size) == 0);
+
+       patch_feature_section(0, &fixup);
+       check(memcmp(ftr_fixup_prefix2, ftr_fixup_prefix2_expected, size) == 0);
+       check(memcmp(ftr_fixup_prefix2, ftr_fixup_prefix2_orig, size) != 0);
+}
+
+static void __init test_prefix_word_alt_patching(void)
+{
+       extern unsigned int ftr_fixup_prefix3[];
+       extern unsigned int end_ftr_fixup_prefix3[];
+       extern unsigned int ftr_fixup_prefix3_orig[];
+       extern unsigned int ftr_fixup_prefix3_expected[];
+       extern unsigned int ftr_fixup_prefix3_alt[];
+       int size = sizeof(unsigned int) * (end_ftr_fixup_prefix3 - 
ftr_fixup_prefix3);
+
+       fixup.value = fixup.mask = 8;
+       fixup.start_off = calc_offset(&fixup, ftr_fixup_prefix3 + 1);
+       fixup.end_off = calc_offset(&fixup, ftr_fixup_prefix3 + 4);
+       fixup.alt_start_off = calc_offset(&fixup, ftr_fixup_prefix3_alt);
+       fixup.alt_end_off = calc_offset(&fixup, ftr_fixup_prefix3_alt + 3);
+       /* Sanity check */
+       check(memcmp(ftr_fixup_prefix3, ftr_fixup_prefix3_orig, size) == 0);
+
+       patch_feature_section(0, &fixup);
+       check(memcmp(ftr_fixup_prefix3, ftr_fixup_prefix3_expected, size) == 0);
+       patch_feature_section(0, &fixup);
+       check(memcmp(ftr_fixup_prefix3, ftr_fixup_prefix3_orig, size) != 0);
+}
+#endif /* __powerpc64__ */
+
 static int __init test_feature_fixups(void)
 {
        printk(KERN_DEBUG "Running feature fixup self-tests ...\n");
@@ -703,6 +771,11 @@ static int __init test_feature_fixups(void)
        test_cpu_macros();
        test_fw_macros();
        test_lwsync_macros();
+#ifdef __powerpc64__
+       test_prefix_patching();
+       test_prefix_alt_patching();
+       test_prefix_word_alt_patching();
+#endif
 
        return 0;
 }
-- 
2.17.1

Reply via email to