Skip to content

Commit 6536c5f

Browse files
committed
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
2 parents c877b3d + 6f845eb commit 6536c5f

File tree

3 files changed

+32
-13
lines changed

3 files changed

+32
-13
lines changed

arch/powerpc/lib/memcmp_64.S

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -215,11 +215,20 @@ _GLOBAL_TOC(memcmp)
215215
beq .Lzero
216216

217217
.Lcmp_rest_lt8bytes:
218-
/* Here we have only less than 8 bytes to compare with. at least s1
219-
* Address is aligned with 8 bytes.
220-
* The next double words are load and shift right with appropriate
221-
* bits.
218+
/*
219+
* Here we have less than 8 bytes to compare. At least s1 is aligned to
220+
* 8 bytes, but s2 may not be. We must make sure s2 + 7 doesn't cross a
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.
222227
*/
228+
clrldi r6,r4,(64-12) // r6 = r4 & 0xfff
229+
cmpdi r6,0xff8
230+
bgt .Lshort
231+
223232
subfic r6,r5,8
224233
slwi r6,r6,3
225234
LD rA,0,r3

arch/powerpc/platforms/pseries/pseries_energy.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,18 +77,27 @@ static u32 cpu_to_drc_index(int cpu)
7777

7878
ret = drc.drc_index_start + (thread_index * drc.sequential_inc);
7979
} else {
80-
const __be32 *indexes;
81-
82-
indexes = of_get_property(dn, "ibm,drc-indexes", NULL);
83-
if (indexes == NULL)
84-
goto err_of_node_put;
80+
u32 nr_drc_indexes, thread_drc_index;
8581

8682
/*
87-
* The first element indexes[0] is the number of drc_indexes
88-
* returned in the list. Hence thread_index+1 will get the
89-
* drc_index corresponding to core number thread_index.
83+
* The first element of ibm,drc-indexes array is the
84+
* number of drc_indexes returned in the list. Hence
85+
* thread_index+1 will get the drc_index corresponding
86+
* to core number thread_index.
9087
*/
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;
92101
}
93102

94103
rc = 0;

arch/powerpc/platforms/pseries/ras.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,7 @@ static void pseries_print_mce_info(struct pt_regs *regs,
550550
"UE",
551551
"SLB",
552552
"ERAT",
553+
"Unknown",
553554
"TLB",
554555
"D-Cache",
555556
"Unknown",

0 commit comments

Comments
 (0)