Skip to content

Commit fbda790

Browse files
committed
Merge tag 'powerpc-5.12-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc fixes from Michael Ellerman: "One non-fix, the conversion of vio_driver->remove() to return void, which touches various powerpc specific drivers. Fix the privilege checks we do in our perf handling, which could cause soft/hard lockups in some configurations. Fix a bug with IRQ affinity seen on kdump kernels when CPU 0 is offline in the second kernel. Fix missed page faults after mprotect(..., PROT_NONE) on 603 (32-bit). Fix a bug in our VSX (vector) instruction emulation, which should only be seen when doing VSX ops to cache inhibited mappings. Three commits fixing various build issues with obscure configurations. Thanks to Athira Rajeev, Cédric Le Goater, Christophe Leroy, Christoph Plattner, Greg Kurz, Jordan Niethe, Laurent Vivier, Ravi Bangoria, Tyrel Datwyler, and Uwe Kleine-König" * tag 'powerpc-5.12-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: powerpc/sstep: Fix VSX instruction emulation powerpc/perf: Fix handling of privilege level checks in perf interrupt context powerpc: Force inlining of mmu_has_feature to fix build failure vio: make remove callback return void powerpc/syscall: Force inlining of __prep_irq_for_enabled_exit() powerpc/603: Fix protection of user pages mapped with PROT_NONE powerpc/pseries: Don't enforce MSI affinity with kdump powerpc/4xx: Fix build errors from mfdcr()
2 parents dac5187 + 5c88a17 commit fbda790

20 files changed

Lines changed: 55 additions & 53 deletions

File tree

arch/powerpc/include/asm/dcr-native.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ static inline void mtdcrx(unsigned int reg, unsigned int val)
5353
#define mfdcr(rn) \
5454
({unsigned int rval; \
5555
if (__builtin_constant_p(rn) && rn < 1024) \
56-
asm volatile("mfdcr %0," __stringify(rn) \
57-
: "=r" (rval)); \
56+
asm volatile("mfdcr %0, %1" : "=r" (rval) \
57+
: "n" (rn)); \
5858
else if (likely(cpu_has_feature(CPU_FTR_INDEXED_DCR))) \
5959
rval = mfdcrx(rn); \
6060
else \
@@ -64,8 +64,8 @@ static inline void mtdcrx(unsigned int reg, unsigned int val)
6464
#define mtdcr(rn, v) \
6565
do { \
6666
if (__builtin_constant_p(rn) && rn < 1024) \
67-
asm volatile("mtdcr " __stringify(rn) ",%0" \
68-
: : "r" (v)); \
67+
asm volatile("mtdcr %0, %1" \
68+
: : "n" (rn), "r" (v)); \
6969
else if (likely(cpu_has_feature(CPU_FTR_INDEXED_DCR))) \
7070
mtdcrx(rn, v); \
7171
else \

arch/powerpc/include/asm/mmu.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ enum {
228228
#define MMU_FTRS_ALWAYS 0
229229
#endif
230230

231-
static inline bool early_mmu_has_feature(unsigned long feature)
231+
static __always_inline bool early_mmu_has_feature(unsigned long feature)
232232
{
233233
if (MMU_FTRS_ALWAYS & feature)
234234
return true;
@@ -286,7 +286,7 @@ static inline void mmu_feature_keys_init(void)
286286

287287
}
288288

289-
static inline bool mmu_has_feature(unsigned long feature)
289+
static __always_inline bool mmu_has_feature(unsigned long feature)
290290
{
291291
return early_mmu_has_feature(feature);
292292
}

arch/powerpc/include/asm/vio.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ struct vio_driver {
113113
const char *name;
114114
const struct vio_device_id *id_table;
115115
int (*probe)(struct vio_dev *dev, const struct vio_device_id *id);
116-
int (*remove)(struct vio_dev *dev);
116+
void (*remove)(struct vio_dev *dev);
117117
/* A driver must have a get_desired_dma() function to
118118
* be loaded in a CMO environment if it uses DMA.
119119
*/

arch/powerpc/kernel/head_book3s_32.S

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -457,11 +457,12 @@ InstructionTLBMiss:
457457
cmplw 0,r1,r3
458458
#endif
459459
mfspr r2, SPRN_SDR1
460-
li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
460+
li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC | _PAGE_USER
461461
rlwinm r2, r2, 28, 0xfffff000
462462
#ifdef CONFIG_MODULES
463463
bgt- 112f
464464
lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
465+
li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
465466
addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
466467
#endif
467468
112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
@@ -520,10 +521,11 @@ DataLoadTLBMiss:
520521
lis r1, TASK_SIZE@h /* check if kernel address */
521522
cmplw 0,r1,r3
522523
mfspr r2, SPRN_SDR1
523-
li r1, _PAGE_PRESENT | _PAGE_ACCESSED
524+
li r1, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_USER
524525
rlwinm r2, r2, 28, 0xfffff000
525526
bgt- 112f
526527
lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
528+
li r1, _PAGE_PRESENT | _PAGE_ACCESSED
527529
addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
528530
112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
529531
lwz r2,0(r2) /* get pmd entry */
@@ -597,10 +599,11 @@ DataStoreTLBMiss:
597599
lis r1, TASK_SIZE@h /* check if kernel address */
598600
cmplw 0,r1,r3
599601
mfspr r2, SPRN_SDR1
600-
li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED
602+
li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_USER
601603
rlwinm r2, r2, 28, 0xfffff000
602604
bgt- 112f
603605
lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
606+
li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED
604607
addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
605608
112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
606609
lwz r2,0(r2) /* get pmd entry */

arch/powerpc/kernel/interrupt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ notrace long system_call_exception(long r3, long r4, long r5,
149149
* enabled when the interrupt handler returns (indicating a process-context /
150150
* synchronous interrupt) then irqs_enabled should be true.
151151
*/
152-
static notrace inline bool __prep_irq_for_enabled_exit(bool clear_ri)
152+
static notrace __always_inline bool __prep_irq_for_enabled_exit(bool clear_ri)
153153
{
154154
/* This must be done with RI=1 because tracing may touch vmaps */
155155
trace_hardirqs_on();

arch/powerpc/lib/sstep.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,7 @@ static nokprobe_inline int do_vsx_load(struct instruction_op *op,
904904
if (!address_ok(regs, ea, size) || copy_mem_in(mem, ea, size, regs))
905905
return -EFAULT;
906906

907-
nr_vsx_regs = size / sizeof(__vector128);
907+
nr_vsx_regs = max(1ul, size / sizeof(__vector128));
908908
emulate_vsx_load(op, buf, mem, cross_endian);
909909
preempt_disable();
910910
if (reg < 32) {
@@ -951,7 +951,7 @@ static nokprobe_inline int do_vsx_store(struct instruction_op *op,
951951
if (!address_ok(regs, ea, size))
952952
return -EFAULT;
953953

954-
nr_vsx_regs = size / sizeof(__vector128);
954+
nr_vsx_regs = max(1ul, size / sizeof(__vector128));
955955
preempt_disable();
956956
if (reg < 32) {
957957
/* FP regs + extensions */

arch/powerpc/perf/core-book3s.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ static inline void perf_get_data_addr(struct perf_event *event, struct pt_regs *
222222
if (!(mmcra & MMCRA_SAMPLE_ENABLE) || sdar_valid)
223223
*addrp = mfspr(SPRN_SDAR);
224224

225-
if (is_kernel_addr(mfspr(SPRN_SDAR)) && perf_allow_kernel(&event->attr) != 0)
225+
if (is_kernel_addr(mfspr(SPRN_SDAR)) && event->attr.exclude_kernel)
226226
*addrp = 0;
227227
}
228228

@@ -507,7 +507,7 @@ static void power_pmu_bhrb_read(struct perf_event *event, struct cpu_hw_events *
507507
* addresses, hence include a check before filtering code
508508
*/
509509
if (!(ppmu->flags & PPMU_ARCH_31) &&
510-
is_kernel_addr(addr) && perf_allow_kernel(&event->attr) != 0)
510+
is_kernel_addr(addr) && event->attr.exclude_kernel)
511511
continue;
512512

513513
/* Branches are read most recent first (ie. mfbhrb 0 is

arch/powerpc/platforms/pseries/msi.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Copyright 2006-2007 Michael Ellerman, IBM Corp.
55
*/
66

7+
#include <linux/crash_dump.h>
78
#include <linux/device.h>
89
#include <linux/irq.h>
910
#include <linux/msi.h>
@@ -458,8 +459,28 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type)
458459
return hwirq;
459460
}
460461

461-
virq = irq_create_mapping_affinity(NULL, hwirq,
462-
entry->affinity);
462+
/*
463+
* Depending on the number of online CPUs in the original
464+
* kernel, it is likely for CPU #0 to be offline in a kdump
465+
* kernel. The associated IRQs in the affinity mappings
466+
* provided by irq_create_affinity_masks() are thus not
467+
* started by irq_startup(), as per-design for managed IRQs.
468+
* This can be a problem with multi-queue block devices driven
469+
* by blk-mq : such a non-started IRQ is very likely paired
470+
* with the single queue enforced by blk-mq during kdump (see
471+
* blk_mq_alloc_tag_set()). This causes the device to remain
472+
* silent and likely hangs the guest at some point.
473+
*
474+
* We don't really care for fine-grained affinity when doing
475+
* kdump actually : simply ignore the pre-computed affinity
476+
* masks in this case and let the default mask with all CPUs
477+
* be used when creating the IRQ mappings.
478+
*/
479+
if (is_kdump_kernel())
480+
virq = irq_create_mapping(NULL, hwirq);
481+
else
482+
virq = irq_create_mapping_affinity(NULL, hwirq,
483+
entry->affinity);
463484

464485
if (!virq) {
465486
pr_debug("rtas_msi: Failed mapping hwirq %d\n", hwirq);

arch/powerpc/platforms/pseries/vio.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,7 +1261,6 @@ static int vio_bus_remove(struct device *dev)
12611261
struct vio_dev *viodev = to_vio_dev(dev);
12621262
struct vio_driver *viodrv = to_vio_driver(dev->driver);
12631263
struct device *devptr;
1264-
int ret = 1;
12651264

12661265
/*
12671266
* Hold a reference to the device after the remove function is called
@@ -1270,13 +1269,13 @@ static int vio_bus_remove(struct device *dev)
12701269
devptr = get_device(dev);
12711270

12721271
if (viodrv->remove)
1273-
ret = viodrv->remove(viodev);
1272+
viodrv->remove(viodev);
12741273

1275-
if (!ret && firmware_has_feature(FW_FEATURE_CMO))
1274+
if (firmware_has_feature(FW_FEATURE_CMO))
12761275
vio_cmo_bus_remove(viodev);
12771276

12781277
put_device(devptr);
1279-
return ret;
1278+
return 0;
12801279
}
12811280

12821281
/**

drivers/char/hw_random/pseries-rng.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,9 @@ static int pseries_rng_probe(struct vio_dev *dev,
5454
return hwrng_register(&pseries_rng);
5555
}
5656

57-
static int pseries_rng_remove(struct vio_dev *dev)
57+
static void pseries_rng_remove(struct vio_dev *dev)
5858
{
5959
hwrng_unregister(&pseries_rng);
60-
return 0;
6160
}
6261

6362
static const struct vio_device_id pseries_rng_driver_ids[] = {

0 commit comments

Comments
 (0)