Commit 3578f191 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 's390-4.20-3' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux

Pull s390 updates from Martin Schwidefsky:

 - Add two missing kfree calls on error paths in the vfio-ccw code

 - Make sure that all data structures of a mediated vfio-ccw device are
   initialized before registering it

 - Fix a sparse warning in vfio-ccw

 - A followup patch for the pgtable_bytes accounting, the page table
   downgrade for compat processes missed a mm_dec_nr_pmds()

 - Reject sampling requests in the PMU init function of the CPU
   measurement counter facility

 - With the vfio AP driver an AP queue needs to be reset on every device
   probe as the alternative driver could have modified the device state

* tag 's390-4.20-3' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
  s390/mm: correct pgtable_bytes on page table downgrade
  s390/zcrypt: reinit ap queue state machine during device probe
  s390/cpum_cf: Reject request for sampling in event initialization
  s390/cio: Fix cleanup when unsupported IDA format is used
  s390/cio: Fix cleanup of pfn_array alloc failure
  vfio: ccw: Register mediated device once all structures are initialized
  s390/cio: make vfio_ccw_io_region static
parents b905e2db 814cedbc
...@@ -346,6 +346,8 @@ static int __hw_perf_event_init(struct perf_event *event) ...@@ -346,6 +346,8 @@ static int __hw_perf_event_init(struct perf_event *event)
break; break;
case PERF_TYPE_HARDWARE: case PERF_TYPE_HARDWARE:
if (is_sampling_event(event)) /* No sampling support */
return -ENOENT;
ev = attr->config; ev = attr->config;
/* Count user space (problem-state) only */ /* Count user space (problem-state) only */
if (!attr->exclude_user && attr->exclude_kernel) { if (!attr->exclude_user && attr->exclude_kernel) {
......
...@@ -131,6 +131,7 @@ void crst_table_downgrade(struct mm_struct *mm) ...@@ -131,6 +131,7 @@ void crst_table_downgrade(struct mm_struct *mm)
} }
pgd = mm->pgd; pgd = mm->pgd;
mm_dec_nr_pmds(mm);
mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN); mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN);
mm->context.asce_limit = _REGION3_SIZE; mm->context.asce_limit = _REGION3_SIZE;
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
......
...@@ -387,8 +387,10 @@ static int ccwchain_calc_length(u64 iova, struct channel_program *cp) ...@@ -387,8 +387,10 @@ static int ccwchain_calc_length(u64 iova, struct channel_program *cp)
* orb specified one of the unsupported formats, we defer * orb specified one of the unsupported formats, we defer
* checking for IDAWs in unsupported formats to here. * checking for IDAWs in unsupported formats to here.
*/ */
if ((!cp->orb.cmd.c64 || cp->orb.cmd.i2k) && ccw_is_idal(ccw)) if ((!cp->orb.cmd.c64 || cp->orb.cmd.i2k) && ccw_is_idal(ccw)) {
kfree(p);
return -EOPNOTSUPP; return -EOPNOTSUPP;
}
if ((!ccw_is_chain(ccw)) && (!ccw_is_tic(ccw))) if ((!ccw_is_chain(ccw)) && (!ccw_is_tic(ccw)))
break; break;
...@@ -528,7 +530,7 @@ static int ccwchain_fetch_direct(struct ccwchain *chain, ...@@ -528,7 +530,7 @@ static int ccwchain_fetch_direct(struct ccwchain *chain,
ret = pfn_array_alloc_pin(pat->pat_pa, cp->mdev, ccw->cda, ccw->count); ret = pfn_array_alloc_pin(pat->pat_pa, cp->mdev, ccw->cda, ccw->count);
if (ret < 0) if (ret < 0)
goto out_init; goto out_unpin;
/* Translate this direct ccw to a idal ccw. */ /* Translate this direct ccw to a idal ccw. */
idaws = kcalloc(ret, sizeof(*idaws), GFP_DMA | GFP_KERNEL); idaws = kcalloc(ret, sizeof(*idaws), GFP_DMA | GFP_KERNEL);
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include "vfio_ccw_private.h" #include "vfio_ccw_private.h"
struct workqueue_struct *vfio_ccw_work_q; struct workqueue_struct *vfio_ccw_work_q;
struct kmem_cache *vfio_ccw_io_region; static struct kmem_cache *vfio_ccw_io_region;
/* /*
* Helpers * Helpers
...@@ -134,14 +134,14 @@ static int vfio_ccw_sch_probe(struct subchannel *sch) ...@@ -134,14 +134,14 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
if (ret) if (ret)
goto out_free; goto out_free;
ret = vfio_ccw_mdev_reg(sch);
if (ret)
goto out_disable;
INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo); INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo);
atomic_set(&private->avail, 1); atomic_set(&private->avail, 1);
private->state = VFIO_CCW_STATE_STANDBY; private->state = VFIO_CCW_STATE_STANDBY;
ret = vfio_ccw_mdev_reg(sch);
if (ret)
goto out_disable;
return 0; return 0;
out_disable: out_disable:
......
...@@ -775,6 +775,8 @@ static int ap_device_probe(struct device *dev) ...@@ -775,6 +775,8 @@ static int ap_device_probe(struct device *dev)
drvres = ap_drv->flags & AP_DRIVER_FLAG_DEFAULT; drvres = ap_drv->flags & AP_DRIVER_FLAG_DEFAULT;
if (!!devres != !!drvres) if (!!devres != !!drvres)
return -ENODEV; return -ENODEV;
/* (re-)init queue's state machine */
ap_queue_reinit_state(to_ap_queue(dev));
} }
/* Add queue/card to list of active queues/cards */ /* Add queue/card to list of active queues/cards */
...@@ -807,6 +809,8 @@ static int ap_device_remove(struct device *dev) ...@@ -807,6 +809,8 @@ static int ap_device_remove(struct device *dev)
struct ap_device *ap_dev = to_ap_dev(dev); struct ap_device *ap_dev = to_ap_dev(dev);
struct ap_driver *ap_drv = ap_dev->drv; struct ap_driver *ap_drv = ap_dev->drv;
if (is_queue_dev(dev))
ap_queue_remove(to_ap_queue(dev));
if (ap_drv->remove) if (ap_drv->remove)
ap_drv->remove(ap_dev); ap_drv->remove(ap_dev);
...@@ -1444,10 +1448,6 @@ static void ap_scan_bus(struct work_struct *unused) ...@@ -1444,10 +1448,6 @@ static void ap_scan_bus(struct work_struct *unused)
aq->ap_dev.device.parent = &ac->ap_dev.device; aq->ap_dev.device.parent = &ac->ap_dev.device;
dev_set_name(&aq->ap_dev.device, dev_set_name(&aq->ap_dev.device,
"%02x.%04x", id, dom); "%02x.%04x", id, dom);
/* Start with a device reset */
spin_lock_bh(&aq->lock);
ap_wait(ap_sm_event(aq, AP_EVENT_POLL));
spin_unlock_bh(&aq->lock);
/* Register device */ /* Register device */
rc = device_register(&aq->ap_dev.device); rc = device_register(&aq->ap_dev.device);
if (rc) { if (rc) {
......
...@@ -254,6 +254,7 @@ struct ap_queue *ap_queue_create(ap_qid_t qid, int device_type); ...@@ -254,6 +254,7 @@ struct ap_queue *ap_queue_create(ap_qid_t qid, int device_type);
void ap_queue_remove(struct ap_queue *aq); void ap_queue_remove(struct ap_queue *aq);
void ap_queue_suspend(struct ap_device *ap_dev); void ap_queue_suspend(struct ap_device *ap_dev);
void ap_queue_resume(struct ap_device *ap_dev); void ap_queue_resume(struct ap_device *ap_dev);
void ap_queue_reinit_state(struct ap_queue *aq);
struct ap_card *ap_card_create(int id, int queue_depth, int raw_device_type, struct ap_card *ap_card_create(int id, int queue_depth, int raw_device_type,
int comp_device_type, unsigned int functions); int comp_device_type, unsigned int functions);
......
...@@ -718,5 +718,20 @@ void ap_queue_remove(struct ap_queue *aq) ...@@ -718,5 +718,20 @@ void ap_queue_remove(struct ap_queue *aq)
{ {
ap_flush_queue(aq); ap_flush_queue(aq);
del_timer_sync(&aq->timeout); del_timer_sync(&aq->timeout);
/* reset with zero, also clears irq registration */
spin_lock_bh(&aq->lock);
ap_zapq(aq->qid);
aq->state = AP_STATE_BORKED;
spin_unlock_bh(&aq->lock);
} }
EXPORT_SYMBOL(ap_queue_remove); EXPORT_SYMBOL(ap_queue_remove);
void ap_queue_reinit_state(struct ap_queue *aq)
{
spin_lock_bh(&aq->lock);
aq->state = AP_STATE_RESET_START;
ap_wait(ap_sm_event(aq, AP_EVENT_POLL));
spin_unlock_bh(&aq->lock);
}
EXPORT_SYMBOL(ap_queue_reinit_state);
...@@ -196,7 +196,6 @@ static void zcrypt_cex2a_queue_remove(struct ap_device *ap_dev) ...@@ -196,7 +196,6 @@ static void zcrypt_cex2a_queue_remove(struct ap_device *ap_dev)
struct ap_queue *aq = to_ap_queue(&ap_dev->device); struct ap_queue *aq = to_ap_queue(&ap_dev->device);
struct zcrypt_queue *zq = aq->private; struct zcrypt_queue *zq = aq->private;
ap_queue_remove(aq);
if (zq) if (zq)
zcrypt_queue_unregister(zq); zcrypt_queue_unregister(zq);
} }
......
...@@ -251,7 +251,6 @@ static void zcrypt_cex2c_queue_remove(struct ap_device *ap_dev) ...@@ -251,7 +251,6 @@ static void zcrypt_cex2c_queue_remove(struct ap_device *ap_dev)
struct ap_queue *aq = to_ap_queue(&ap_dev->device); struct ap_queue *aq = to_ap_queue(&ap_dev->device);
struct zcrypt_queue *zq = aq->private; struct zcrypt_queue *zq = aq->private;
ap_queue_remove(aq);
if (zq) if (zq)
zcrypt_queue_unregister(zq); zcrypt_queue_unregister(zq);
} }
......
...@@ -275,7 +275,6 @@ static void zcrypt_cex4_queue_remove(struct ap_device *ap_dev) ...@@ -275,7 +275,6 @@ static void zcrypt_cex4_queue_remove(struct ap_device *ap_dev)
struct ap_queue *aq = to_ap_queue(&ap_dev->device); struct ap_queue *aq = to_ap_queue(&ap_dev->device);
struct zcrypt_queue *zq = aq->private; struct zcrypt_queue *zq = aq->private;
ap_queue_remove(aq);
if (zq) if (zq)
zcrypt_queue_unregister(zq); zcrypt_queue_unregister(zq);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment