Skip to content

Commit

Permalink
Merge tag 'powerpc-5.12-2' of git://git.kernel.org/pub/scm/linux/kern…
Browse files Browse the repository at this point in the history
…el/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()
  • Loading branch information
Linus Torvalds committed Mar 7, 2021
2 parents dac5187 + 5c88a17 commit fbda790
Show file tree
Hide file tree
Showing 20 changed files with 55 additions and 53 deletions.
8 changes: 4 additions & 4 deletions arch/powerpc/include/asm/dcr-native.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ static inline void mtdcrx(unsigned int reg, unsigned int val)
#define mfdcr(rn) \
({unsigned int rval; \
if (__builtin_constant_p(rn) && rn < 1024) \
asm volatile("mfdcr %0," __stringify(rn) \
: "=r" (rval)); \
asm volatile("mfdcr %0, %1" : "=r" (rval) \
: "n" (rn)); \
else if (likely(cpu_has_feature(CPU_FTR_INDEXED_DCR))) \
rval = mfdcrx(rn); \
else \
Expand All @@ -64,8 +64,8 @@ static inline void mtdcrx(unsigned int reg, unsigned int val)
#define mtdcr(rn, v) \
do { \
if (__builtin_constant_p(rn) && rn < 1024) \
asm volatile("mtdcr " __stringify(rn) ",%0" \
: : "r" (v)); \
asm volatile("mtdcr %0, %1" \
: : "n" (rn), "r" (v)); \
else if (likely(cpu_has_feature(CPU_FTR_INDEXED_DCR))) \
mtdcrx(rn, v); \
else \
Expand Down
4 changes: 2 additions & 2 deletions arch/powerpc/include/asm/mmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ enum {
#define MMU_FTRS_ALWAYS 0
#endif

static inline bool early_mmu_has_feature(unsigned long feature)
static __always_inline bool early_mmu_has_feature(unsigned long feature)
{
if (MMU_FTRS_ALWAYS & feature)
return true;
Expand Down Expand Up @@ -286,7 +286,7 @@ static inline void mmu_feature_keys_init(void)

}

static inline bool mmu_has_feature(unsigned long feature)
static __always_inline bool mmu_has_feature(unsigned long feature)
{
return early_mmu_has_feature(feature);
}
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/include/asm/vio.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ struct vio_driver {
const char *name;
const struct vio_device_id *id_table;
int (*probe)(struct vio_dev *dev, const struct vio_device_id *id);
int (*remove)(struct vio_dev *dev);
void (*remove)(struct vio_dev *dev);
/* A driver must have a get_desired_dma() function to
* be loaded in a CMO environment if it uses DMA.
*/
Expand Down
9 changes: 6 additions & 3 deletions arch/powerpc/kernel/head_book3s_32.S
Original file line number Diff line number Diff line change
Expand Up @@ -457,11 +457,12 @@ InstructionTLBMiss:
cmplw 0,r1,r3
#endif
mfspr r2, SPRN_SDR1
li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC | _PAGE_USER
rlwinm r2, r2, 28, 0xfffff000
#ifdef CONFIG_MODULES
bgt- 112f
lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
#endif
112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
Expand Down Expand Up @@ -520,10 +521,11 @@ DataLoadTLBMiss:
lis r1, TASK_SIZE@h /* check if kernel address */
cmplw 0,r1,r3
mfspr r2, SPRN_SDR1
li r1, _PAGE_PRESENT | _PAGE_ACCESSED
li r1, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_USER
rlwinm r2, r2, 28, 0xfffff000
bgt- 112f
lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
li r1, _PAGE_PRESENT | _PAGE_ACCESSED
addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
lwz r2,0(r2) /* get pmd entry */
Expand Down Expand Up @@ -597,10 +599,11 @@ DataStoreTLBMiss:
lis r1, TASK_SIZE@h /* check if kernel address */
cmplw 0,r1,r3
mfspr r2, SPRN_SDR1
li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED
li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_USER
rlwinm r2, r2, 28, 0xfffff000
bgt- 112f
lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED
addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
lwz r2,0(r2) /* get pmd entry */
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/kernel/interrupt.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ notrace long system_call_exception(long r3, long r4, long r5,
* enabled when the interrupt handler returns (indicating a process-context /
* synchronous interrupt) then irqs_enabled should be true.
*/
static notrace inline bool __prep_irq_for_enabled_exit(bool clear_ri)
static notrace __always_inline bool __prep_irq_for_enabled_exit(bool clear_ri)
{
/* This must be done with RI=1 because tracing may touch vmaps */
trace_hardirqs_on();
Expand Down
4 changes: 2 additions & 2 deletions arch/powerpc/lib/sstep.c
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,7 @@ static nokprobe_inline int do_vsx_load(struct instruction_op *op,
if (!address_ok(regs, ea, size) || copy_mem_in(mem, ea, size, regs))
return -EFAULT;

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

nr_vsx_regs = size / sizeof(__vector128);
nr_vsx_regs = max(1ul, size / sizeof(__vector128));
preempt_disable();
if (reg < 32) {
/* FP regs + extensions */
Expand Down
4 changes: 2 additions & 2 deletions arch/powerpc/perf/core-book3s.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ static inline void perf_get_data_addr(struct perf_event *event, struct pt_regs *
if (!(mmcra & MMCRA_SAMPLE_ENABLE) || sdar_valid)
*addrp = mfspr(SPRN_SDAR);

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

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

/* Branches are read most recent first (ie. mfbhrb 0 is
Expand Down
25 changes: 23 additions & 2 deletions arch/powerpc/platforms/pseries/msi.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Copyright 2006-2007 Michael Ellerman, IBM Corp.
*/

#include <linux/crash_dump.h>
#include <linux/device.h>
#include <linux/irq.h>
#include <linux/msi.h>
Expand Down Expand Up @@ -458,8 +459,28 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type)
return hwirq;
}

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

if (!virq) {
pr_debug("rtas_msi: Failed mapping hwirq %d\n", hwirq);
Expand Down
7 changes: 3 additions & 4 deletions arch/powerpc/platforms/pseries/vio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1261,7 +1261,6 @@ static int vio_bus_remove(struct device *dev)
struct vio_dev *viodev = to_vio_dev(dev);
struct vio_driver *viodrv = to_vio_driver(dev->driver);
struct device *devptr;
int ret = 1;

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

if (viodrv->remove)
ret = viodrv->remove(viodev);
viodrv->remove(viodev);

if (!ret && firmware_has_feature(FW_FEATURE_CMO))
if (firmware_has_feature(FW_FEATURE_CMO))
vio_cmo_bus_remove(viodev);

put_device(devptr);
return ret;
return 0;
}

/**
Expand Down
3 changes: 1 addition & 2 deletions drivers/char/hw_random/pseries-rng.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,9 @@ static int pseries_rng_probe(struct vio_dev *dev,
return hwrng_register(&pseries_rng);
}

static int pseries_rng_remove(struct vio_dev *dev)
static void pseries_rng_remove(struct vio_dev *dev)
{
hwrng_unregister(&pseries_rng);
return 0;
}

static const struct vio_device_id pseries_rng_driver_ids[] = {
Expand Down
4 changes: 1 addition & 3 deletions drivers/char/tpm/tpm_ibmvtpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ static int ibmvtpm_crq_send_init_complete(struct ibmvtpm_dev *ibmvtpm)
*
* Return: Always 0.
*/
static int tpm_ibmvtpm_remove(struct vio_dev *vdev)
static void tpm_ibmvtpm_remove(struct vio_dev *vdev)
{
struct tpm_chip *chip = dev_get_drvdata(&vdev->dev);
struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev);
Expand Down Expand Up @@ -372,8 +372,6 @@ static int tpm_ibmvtpm_remove(struct vio_dev *vdev)
kfree(ibmvtpm);
/* For tpm_ibmvtpm_get_desired_dma */
dev_set_drvdata(&vdev->dev, NULL);

return 0;
}

/**
Expand Down
4 changes: 1 addition & 3 deletions drivers/crypto/nx/nx-842-pseries.c
Original file line number Diff line number Diff line change
Expand Up @@ -1042,7 +1042,7 @@ static int nx842_probe(struct vio_dev *viodev,
return ret;
}

static int nx842_remove(struct vio_dev *viodev)
static void nx842_remove(struct vio_dev *viodev)
{
struct nx842_devdata *old_devdata;
unsigned long flags;
Expand All @@ -1063,8 +1063,6 @@ static int nx842_remove(struct vio_dev *viodev)
if (old_devdata)
kfree(old_devdata->counters);
kfree(old_devdata);

return 0;
}

static const struct vio_device_id nx842_vio_driver_ids[] = {
Expand Down
4 changes: 1 addition & 3 deletions drivers/crypto/nx/nx.c
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,7 @@ static int nx_probe(struct vio_dev *viodev, const struct vio_device_id *id)
return nx_register_algs();
}

static int nx_remove(struct vio_dev *viodev)
static void nx_remove(struct vio_dev *viodev)
{
dev_dbg(&viodev->dev, "entering nx_remove for UA 0x%x\n",
viodev->unit_address);
Expand Down Expand Up @@ -811,8 +811,6 @@ static int nx_remove(struct vio_dev *viodev)
nx_unregister_skcipher(&nx_ecb_aes_alg, NX_FC_AES,
NX_MODE_AES_ECB);
}

return 0;
}


Expand Down
4 changes: 1 addition & 3 deletions drivers/misc/ibmvmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2288,15 +2288,13 @@ static int ibmvmc_probe(struct vio_dev *vdev, const struct vio_device_id *id)
return -EPERM;
}

static int ibmvmc_remove(struct vio_dev *vdev)
static void ibmvmc_remove(struct vio_dev *vdev)
{
struct crq_server_adapter *adapter = dev_get_drvdata(&vdev->dev);

dev_info(adapter->dev, "Entering remove for UA 0x%x\n",
vdev->unit_address);
ibmvmc_release_crq_queue(adapter);

return 0;
}

static struct vio_device_id ibmvmc_device_table[] = {
Expand Down
4 changes: 1 addition & 3 deletions drivers/net/ethernet/ibm/ibmveth.c
Original file line number Diff line number Diff line change
Expand Up @@ -1758,7 +1758,7 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
return 0;
}

static int ibmveth_remove(struct vio_dev *dev)
static void ibmveth_remove(struct vio_dev *dev)
{
struct net_device *netdev = dev_get_drvdata(&dev->dev);
struct ibmveth_adapter *adapter = netdev_priv(netdev);
Expand All @@ -1771,8 +1771,6 @@ static int ibmveth_remove(struct vio_dev *dev)

free_netdev(netdev);
dev_set_drvdata(&dev->dev, NULL);

return 0;
}

static struct attribute veth_active_attr;
Expand Down
5 changes: 1 addition & 4 deletions drivers/net/ethernet/ibm/ibmvnic.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ MODULE_LICENSE("GPL");
MODULE_VERSION(IBMVNIC_DRIVER_VERSION);

static int ibmvnic_version = IBMVNIC_INITIAL_VERSION;
static int ibmvnic_remove(struct vio_dev *);
static void release_sub_crqs(struct ibmvnic_adapter *, bool);
static int ibmvnic_reset_crq(struct ibmvnic_adapter *);
static int ibmvnic_send_crq_init(struct ibmvnic_adapter *);
Expand Down Expand Up @@ -5396,7 +5395,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
return rc;
}

static int ibmvnic_remove(struct vio_dev *dev)
static void ibmvnic_remove(struct vio_dev *dev)
{
struct net_device *netdev = dev_get_drvdata(&dev->dev);
struct ibmvnic_adapter *adapter = netdev_priv(netdev);
Expand Down Expand Up @@ -5437,8 +5436,6 @@ static int ibmvnic_remove(struct vio_dev *dev)
device_remove_file(&dev->dev, &dev_attr_failover);
free_netdev(netdev);
dev_set_drvdata(&dev->dev, NULL);

return 0;
}

static ssize_t failover_store(struct device *dev, struct device_attribute *attr,
Expand Down
3 changes: 1 addition & 2 deletions drivers/scsi/ibmvscsi/ibmvfc.c
Original file line number Diff line number Diff line change
Expand Up @@ -6038,7 +6038,7 @@ static int ibmvfc_probe(struct vio_dev *vdev, const struct vio_device_id *id)
* Return value:
* 0
**/
static int ibmvfc_remove(struct vio_dev *vdev)
static void ibmvfc_remove(struct vio_dev *vdev)
{
struct ibmvfc_host *vhost = dev_get_drvdata(&vdev->dev);
LIST_HEAD(purge);
Expand Down Expand Up @@ -6070,7 +6070,6 @@ static int ibmvfc_remove(struct vio_dev *vdev)
spin_unlock(&ibmvfc_driver_lock);
scsi_host_put(vhost->host);
LEAVE;
return 0;
}

/**
Expand Down
4 changes: 1 addition & 3 deletions drivers/scsi/ibmvscsi/ibmvscsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -2335,7 +2335,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
return -1;
}

static int ibmvscsi_remove(struct vio_dev *vdev)
static void ibmvscsi_remove(struct vio_dev *vdev)
{
struct ibmvscsi_host_data *hostdata = dev_get_drvdata(&vdev->dev);

Expand All @@ -2356,8 +2356,6 @@ static int ibmvscsi_remove(struct vio_dev *vdev)
spin_unlock(&ibmvscsi_driver_lock);

scsi_host_put(hostdata->host);

return 0;
}

/**
Expand Down
4 changes: 1 addition & 3 deletions drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
Original file line number Diff line number Diff line change
Expand Up @@ -3595,7 +3595,7 @@ static int ibmvscsis_probe(struct vio_dev *vdev,
return rc;
}

static int ibmvscsis_remove(struct vio_dev *vdev)
static void ibmvscsis_remove(struct vio_dev *vdev)
{
struct scsi_info *vscsi = dev_get_drvdata(&vdev->dev);

Expand All @@ -3622,8 +3622,6 @@ static int ibmvscsis_remove(struct vio_dev *vdev)
list_del(&vscsi->list);
spin_unlock_bh(&ibmvscsis_dev_lock);
kfree(vscsi);

return 0;
}

static ssize_t system_id_show(struct device *dev,
Expand Down
Loading

0 comments on commit fbda790

Please sign in to comment.