Skip to content

Commit f005de0

Browse files
committed
Michael writes: "powerpc fixes for 4.19 fail0verflow#3 A reasonably big batch of fixes due to me being away for a few weeks. A fix for the TM emulation support on Power9, which could result in corrupting the guest r11 when running under KVM. Two fixes to the TM code which could lead to userspace GPR corruption if we take an SLB miss at exactly the wrong time. Our dynamic patching code had a bug that meant we could patch freed __init text, which could lead to corrupting userspace memory. csum_ipv6_magic() didn't work on little endian platforms since we optimised it recently. A fix for an endian bug when reading a device tree property telling us how many storage keys the machine has available. Fix a crash seen on some configurations of PowerVM when migrating the partition from one machine to another. A fix for a regression in the setup of our CPU to NUMA node mapping in KVM guests. A fix to our selftest Makefiles to make them work since a recent change to the shared Makefile logic." * tag 'powerpc-4.19-3' of https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: selftests/powerpc: Fix Makefiles for headers_install change powerpc/numa: Use associativity if VPHN hcall is successful powerpc/tm: Avoid possible userspace r1 corruption on reclaim powerpc/tm: Fix userspace r13 corruption powerpc/pseries: Fix unitialized timer reset on migration powerpc/pkeys: Fix reading of ibm, processor-storage-keys property powerpc: fix csum_ipv6_magic() on little endian platforms powerpc/powernv/ioda2: Reduce upper limit for DMA window size (again) powerpc: Avoid code patching freed init sections KVM: PPC: Book3S HV: Fix guest r11 corruption with POWER9 TM workarounds
2 parents 900915f + 7e0cf1c commit f005de0

File tree

26 files changed

+55
-9
lines changed

26 files changed

+55
-9
lines changed

arch/powerpc/include/asm/setup.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ extern void ppc_printk_progress(char *s, unsigned short hex);
99

1010
extern unsigned int rtas_data;
1111
extern unsigned long long memory_limit;
12+
extern bool init_mem_is_free;
1213
extern unsigned long klimit;
1314
extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask);
1415

arch/powerpc/kernel/exceptions-64s.S

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,9 +1314,7 @@ EXC_REAL_BEGIN(denorm_exception_hv, 0x1500, 0x100)
13141314

13151315
#ifdef CONFIG_PPC_DENORMALISATION
13161316
mfspr r10,SPRN_HSRR1
1317-
mfspr r11,SPRN_HSRR0 /* save HSRR0 */
13181317
andis. r10,r10,(HSRR1_DENORM)@h /* denorm? */
1319-
addi r11,r11,-4 /* HSRR0 is next instruction */
13201318
bne+ denorm_assist
13211319
#endif
13221320

@@ -1382,6 +1380,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
13821380
*/
13831381
XVCPSGNDP32(32)
13841382
denorm_done:
1383+
mfspr r11,SPRN_HSRR0
1384+
subi r11,r11,4
13851385
mtspr SPRN_HSRR0,r11
13861386
mtcrf 0x80,r9
13871387
ld r9,PACA_EXGEN+EX_R9(r13)

arch/powerpc/kernel/tm.S

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,13 +176,27 @@ _GLOBAL(tm_reclaim)
176176
std r1, PACATMSCRATCH(r13)
177177
ld r1, PACAR1(r13)
178178

179-
/* Store the PPR in r11 and reset to decent value */
180179
std r11, GPR11(r1) /* Temporary stash */
181180

181+
/*
182+
* Move the saved user r1 to the kernel stack in case PACATMSCRATCH is
183+
* clobbered by an exception once we turn on MSR_RI below.
184+
*/
185+
ld r11, PACATMSCRATCH(r13)
186+
std r11, GPR1(r1)
187+
188+
/*
189+
* Store r13 away so we can free up the scratch SPR for the SLB fault
190+
* handler (needed once we start accessing the thread_struct).
191+
*/
192+
GET_SCRATCH0(r11)
193+
std r11, GPR13(r1)
194+
182195
/* Reset MSR RI so we can take SLB faults again */
183196
li r11, MSR_RI
184197
mtmsrd r11, 1
185198

199+
/* Store the PPR in r11 and reset to decent value */
186200
mfspr r11, SPRN_PPR
187201
HMT_MEDIUM
188202

@@ -207,11 +221,11 @@ _GLOBAL(tm_reclaim)
207221
SAVE_GPR(8, r7) /* user r8 */
208222
SAVE_GPR(9, r7) /* user r9 */
209223
SAVE_GPR(10, r7) /* user r10 */
210-
ld r3, PACATMSCRATCH(r13) /* user r1 */
224+
ld r3, GPR1(r1) /* user r1 */
211225
ld r4, GPR7(r1) /* user r7 */
212226
ld r5, GPR11(r1) /* user r11 */
213227
ld r6, GPR12(r1) /* user r12 */
214-
GET_SCRATCH0(8) /* user r13 */
228+
ld r8, GPR13(r1) /* user r13 */
215229
std r3, GPR1(r7)
216230
std r4, GPR7(r7)
217231
std r5, GPR11(r7)

arch/powerpc/lib/checksum_64.S

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,9 @@ _GLOBAL(csum_ipv6_magic)
443443
addc r0, r8, r9
444444
ld r10, 0(r4)
445445
ld r11, 8(r4)
446+
#ifdef CONFIG_CPU_LITTLE_ENDIAN
447+
rotldi r5, r5, 8
448+
#endif
446449
adde r0, r0, r10
447450
add r5, r5, r7
448451
adde r0, r0, r11

arch/powerpc/lib/code-patching.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ static int __patch_instruction(unsigned int *exec_addr, unsigned int instr,
2828
{
2929
int err;
3030

31+
/* Make sure we aren't patching a freed init section */
32+
if (init_mem_is_free && init_section_contains(exec_addr, 4)) {
33+
pr_debug("Skipping init section patching addr: 0x%px\n", exec_addr);
34+
return 0;
35+
}
36+
3137
__put_user_size(instr, patch_addr, 4, err);
3238
if (err)
3339
return err;

arch/powerpc/mm/mem.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
#endif
6464

6565
unsigned long long memory_limit;
66+
bool init_mem_is_free;
6667

6768
#ifdef CONFIG_HIGHMEM
6869
pte_t *kmap_pte;
@@ -396,6 +397,7 @@ void free_initmem(void)
396397
{
397398
ppc_md.progress = ppc_printk_progress;
398399
mark_initmem_nx();
400+
init_mem_is_free = true;
399401
free_initmem_default(POISON_FREE_INITMEM);
400402
}
401403

arch/powerpc/mm/numa.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,7 +1204,9 @@ int find_and_online_cpu_nid(int cpu)
12041204
int new_nid;
12051205

12061206
/* Use associativity from first thread for all siblings */
1207-
vphn_get_associativity(cpu, associativity);
1207+
if (vphn_get_associativity(cpu, associativity))
1208+
return cpu_to_node(cpu);
1209+
12081210
new_nid = associativity_to_nid(associativity);
12091211
if (new_nid < 0 || !node_possible(new_nid))
12101212
new_nid = first_online_node;
@@ -1452,7 +1454,8 @@ static struct timer_list topology_timer;
14521454

14531455
static void reset_topology_timer(void)
14541456
{
1455-
mod_timer(&topology_timer, jiffies + topology_timer_secs * HZ);
1457+
if (vphn_enabled)
1458+
mod_timer(&topology_timer, jiffies + topology_timer_secs * HZ);
14561459
}
14571460

14581461
#ifdef CONFIG_SMP

arch/powerpc/mm/pkeys.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ static void scan_pkey_feature(void)
4545
* Since any pkey can be used for data or execute, we will just treat
4646
* all keys as equal and track them as one entity.
4747
*/
48-
pkeys_total = be32_to_cpu(vals[0]);
48+
pkeys_total = vals[0];
4949
pkeys_devtree_defined = true;
5050
}
5151

arch/powerpc/platforms/powernv/pci-ioda-tce.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,
276276
level_shift = entries_shift + 3;
277277
level_shift = max_t(unsigned int, level_shift, PAGE_SHIFT);
278278

279-
if ((level_shift - 3) * levels + page_shift >= 60)
279+
if ((level_shift - 3) * levels + page_shift >= 55)
280280
return -EINVAL;
281281

282282
/* Allocate TCE table */
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
TEST_GEN_PROGS := copy_first_unaligned alignment_handler
22

3+
top_srcdir = ../../../../..
34
include ../../lib.mk
45

56
$(TEST_GEN_PROGS): ../harness.c ../utils.c

0 commit comments

Comments
 (0)