| From: Michael Ellerman <mpe@ellerman.id.au> |
| Date: Tue, 17 Apr 2018 00:39:03 +1000 |
| Subject: powerpc/lib: Fix the feature fixup tests to actually work |
| |
| commit cad0e39023b43d94d5e38dfd55c103e15bdd093d upstream. |
| |
| The code patching code has always been a bit confused about whether |
| it's best to use void *, unsigned int *, char *, etc. to point to |
| instructions. In fact in the feature fixups tests we use both unsigned |
| int[] and u8[] in different places. |
| |
| Unfortunately the tests that use unsigned int[] calculate the size of |
| the code blocks using subtraction of those unsigned int pointers, and |
| then pass the result to memcmp(). This means we're only comparing 1/4 |
| of the bytes we need to, because we need to multiply by |
| sizeof(unsigned int) to get the number of *bytes*. |
| |
| The result is that the tests do all the patching and then only compare |
| some of the resulting code, so patching bugs that only effect that |
| last 3/4 of the code could slip through undetected. It turns out that |
| hasn't been happening, although one test had a bad expected case (see |
| previous commit). |
| |
| Fix it for now by multiplying the size by 4 in the affected functions. |
| |
| Fixes: 362e7701fd18 ("powerpc: Add self-tests of the feature fixup code") |
| Epic-brown-paper-bag-by: Michael Ellerman <mpe@ellerman.id.au> |
| Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| arch/powerpc/lib/feature-fixups.c | 12 ++++++------ |
| 1 file changed, 6 insertions(+), 6 deletions(-) |
| |
| --- a/arch/powerpc/lib/feature-fixups.c |
| +++ b/arch/powerpc/lib/feature-fixups.c |
| @@ -170,7 +170,7 @@ void test_basic_patching(void) |
| extern unsigned int end_ftr_fixup_test1[]; |
| extern unsigned int ftr_fixup_test1_orig[]; |
| extern unsigned int ftr_fixup_test1_expected[]; |
| - int size = end_ftr_fixup_test1 - ftr_fixup_test1; |
| + int size = 4 * (end_ftr_fixup_test1 - ftr_fixup_test1); |
| |
| fixup.value = fixup.mask = 8; |
| fixup.start_off = calc_offset(&fixup, ftr_fixup_test1 + 1); |
| @@ -202,7 +202,7 @@ static void test_alternative_patching(vo |
| extern unsigned int ftr_fixup_test2_orig[]; |
| extern unsigned int ftr_fixup_test2_alt[]; |
| extern unsigned int ftr_fixup_test2_expected[]; |
| - int size = end_ftr_fixup_test2 - ftr_fixup_test2; |
| + int size = 4 * (end_ftr_fixup_test2 - ftr_fixup_test2); |
| |
| fixup.value = fixup.mask = 0xF; |
| fixup.start_off = calc_offset(&fixup, ftr_fixup_test2 + 1); |
| @@ -234,7 +234,7 @@ static void test_alternative_case_too_bi |
| extern unsigned int end_ftr_fixup_test3[]; |
| extern unsigned int ftr_fixup_test3_orig[]; |
| extern unsigned int ftr_fixup_test3_alt[]; |
| - int size = end_ftr_fixup_test3 - ftr_fixup_test3; |
| + int size = 4 * (end_ftr_fixup_test3 - ftr_fixup_test3); |
| |
| fixup.value = fixup.mask = 0xC; |
| fixup.start_off = calc_offset(&fixup, ftr_fixup_test3 + 1); |
| @@ -261,7 +261,7 @@ static void test_alternative_case_too_sm |
| extern unsigned int ftr_fixup_test4_orig[]; |
| extern unsigned int ftr_fixup_test4_alt[]; |
| extern unsigned int ftr_fixup_test4_expected[]; |
| - int size = end_ftr_fixup_test4 - ftr_fixup_test4; |
| + int size = 4 * (end_ftr_fixup_test4 - ftr_fixup_test4); |
| unsigned long flag; |
| |
| /* Check a high-bit flag */ |
| @@ -295,7 +295,7 @@ static void test_alternative_case_with_b |
| extern unsigned int ftr_fixup_test5[]; |
| extern unsigned int end_ftr_fixup_test5[]; |
| extern unsigned int ftr_fixup_test5_expected[]; |
| - int size = end_ftr_fixup_test5 - ftr_fixup_test5; |
| + int size = 4 * (end_ftr_fixup_test5 - ftr_fixup_test5); |
| |
| check(memcmp(ftr_fixup_test5, ftr_fixup_test5_expected, size) == 0); |
| } |
| @@ -305,7 +305,7 @@ static void test_alternative_case_with_e |
| extern unsigned int ftr_fixup_test6[]; |
| extern unsigned int end_ftr_fixup_test6[]; |
| extern unsigned int ftr_fixup_test6_expected[]; |
| - int size = end_ftr_fixup_test6 - ftr_fixup_test6; |
| + int size = 4 * (end_ftr_fixup_test6 - ftr_fixup_test6); |
| |
| check(memcmp(ftr_fixup_test6, ftr_fixup_test6_expected, size) == 0); |
| } |