diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-31 10:44:13 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-31 10:44:13 -0400 |
| commit | 6536c5f2c8cf79db0d37e79afcdb227dc854509c (patch) | |
| tree | 8a6e11e6d7768eef8f24215598fd3aa8c1120c5e | |
| parent | c877b3df8527f010ef068704033acac1d43cbf8c (diff) | |
| parent | 6f845ebec2706841d15831fab3ffffcfd9e676fa (diff) | |
Merge tag 'powerpc-5.1-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc fixes from Michael Ellerman:
"Three non-regression fixes.
- Our optimised memcmp could read past the end of one of the buffers
and potentially trigger a page fault leading to an oops.
- Some of our code to read energy management data on PowerVM had an
endian bug leading to bogus results.
- When reporting a machine check exception we incorrectly reported
TLB multihits as D-Cache multhits due to a missing entry in the
array of causes.
Thanks to: Chandan Rajendra, Gautham R. Shenoy, Mahesh Salgaonkar,
Segher Boessenkool, Vaidyanathan Srinivasan"
* tag 'powerpc-5.1-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
powerpc/pseries/mce: Fix misleading print for TLB mutlihit
powerpc/pseries/energy: Use OF accessor functions to read ibm,drc-indexes
powerpc/64: Fix memcmp reading past the end of src/dest
| -rw-r--r-- | arch/powerpc/lib/memcmp_64.S | 17 | ||||
| -rw-r--r-- | arch/powerpc/platforms/pseries/pseries_energy.c | 27 | ||||
| -rw-r--r-- | arch/powerpc/platforms/pseries/ras.c | 1 |
3 files changed, 32 insertions, 13 deletions
diff --git a/arch/powerpc/lib/memcmp_64.S b/arch/powerpc/lib/memcmp_64.S index 844d8e774492..b7f6f6e0b6e8 100644 --- a/arch/powerpc/lib/memcmp_64.S +++ b/arch/powerpc/lib/memcmp_64.S | |||
| @@ -215,11 +215,20 @@ _GLOBAL_TOC(memcmp) | |||
| 215 | beq .Lzero | 215 | beq .Lzero |
| 216 | 216 | ||
| 217 | .Lcmp_rest_lt8bytes: | 217 | .Lcmp_rest_lt8bytes: |
| 218 | /* Here we have only less than 8 bytes to compare with. at least s1 | 218 | /* |
| 219 | * Address is aligned with 8 bytes. | 219 | * Here we have less than 8 bytes to compare. At least s1 is aligned to |
| 220 | * The next double words are load and shift right with appropriate | 220 | * 8 bytes, but s2 may not be. We must make sure s2 + 7 doesn't cross a |
| 221 | * bits. | 221 | * page boundary, otherwise we might read past the end of the buffer and |
| 222 | * trigger a page fault. We use 4K as the conservative minimum page | ||
| 223 | * size. If we detect that case we go to the byte-by-byte loop. | ||
| 224 | * | ||
| 225 | * Otherwise the next double word is loaded from s1 and s2, and shifted | ||
| 226 | * right to compare the appropriate bits. | ||
| 222 | */ | 227 | */ |
| 228 | clrldi r6,r4,(64-12) // r6 = r4 & 0xfff | ||
| 229 | cmpdi r6,0xff8 | ||
| 230 | bgt .Lshort | ||
| 231 | |||
| 223 | subfic r6,r5,8 | 232 | subfic r6,r5,8 |
| 224 | slwi r6,r6,3 | 233 | slwi r6,r6,3 |
| 225 | LD rA,0,r3 | 234 | LD rA,0,r3 |
diff --git a/arch/powerpc/platforms/pseries/pseries_energy.c b/arch/powerpc/platforms/pseries/pseries_energy.c index 6ed22127391b..921f12182f3e 100644 --- a/arch/powerpc/platforms/pseries/pseries_energy.c +++ b/arch/powerpc/platforms/pseries/pseries_energy.c | |||
| @@ -77,18 +77,27 @@ static u32 cpu_to_drc_index(int cpu) | |||
| 77 | 77 | ||
| 78 | ret = drc.drc_index_start + (thread_index * drc.sequential_inc); | 78 | ret = drc.drc_index_start + (thread_index * drc.sequential_inc); |
| 79 | } else { | 79 | } else { |
| 80 | const __be32 *indexes; | 80 | u32 nr_drc_indexes, thread_drc_index; |
| 81 | |||
| 82 | indexes = of_get_property(dn, "ibm,drc-indexes", NULL); | ||
| 83 | if (indexes == NULL) | ||
| 84 | goto err_of_node_put; | ||
| 85 | 81 | ||
| 86 | /* | 82 | /* |
| 87 | * The first element indexes[0] is the number of drc_indexes | 83 | * The first element of ibm,drc-indexes array is the |
| 88 | * returned in the list. Hence thread_index+1 will get the | 84 | * number of drc_indexes returned in the list. Hence |
| 89 | * drc_index corresponding to core number thread_index. | 85 | * thread_index+1 will get the drc_index corresponding |
| 86 | * to core number thread_index. | ||
| 90 | */ | 87 | */ |
| 91 | ret = indexes[thread_index + 1]; | 88 | rc = of_property_read_u32_index(dn, "ibm,drc-indexes", |
| 89 | 0, &nr_drc_indexes); | ||
| 90 | if (rc) | ||
| 91 | goto err_of_node_put; | ||
| 92 | |||
| 93 | WARN_ON_ONCE(thread_index > nr_drc_indexes); | ||
| 94 | rc = of_property_read_u32_index(dn, "ibm,drc-indexes", | ||
| 95 | thread_index + 1, | ||
| 96 | &thread_drc_index); | ||
| 97 | if (rc) | ||
| 98 | goto err_of_node_put; | ||
| 99 | |||
| 100 | ret = thread_drc_index; | ||
| 92 | } | 101 | } |
| 93 | 102 | ||
| 94 | rc = 0; | 103 | rc = 0; |
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c index d97d52772789..452dcfd7e5dd 100644 --- a/arch/powerpc/platforms/pseries/ras.c +++ b/arch/powerpc/platforms/pseries/ras.c | |||
| @@ -550,6 +550,7 @@ static void pseries_print_mce_info(struct pt_regs *regs, | |||
| 550 | "UE", | 550 | "UE", |
| 551 | "SLB", | 551 | "SLB", |
| 552 | "ERAT", | 552 | "ERAT", |
| 553 | "Unknown", | ||
| 553 | "TLB", | 554 | "TLB", |
| 554 | "D-Cache", | 555 | "D-Cache", |
| 555 | "Unknown", | 556 | "Unknown", |
