| From c93ad467ad4c582f799ca1a14986ff527609b62f Mon Sep 17 00:00:00 2001 |
| From: Harald Freudenberger <freude@linux.ibm.com> |
| Date: Fri, 22 Nov 2019 16:30:06 +0100 |
| Subject: [PATCH] s390/zcrypt: move ap device reset from bus to driver code |
| |
| commit 0c874cd04292c7ee22d70eefc341fa2648f41f46 upstream. |
| |
| This patch moves the reset invocation of an ap device when |
| fresh detected from the ap bus to the probe() function of |
| the driver responsible for this device. |
| |
| The virtualisation of ap devices makes it necessary to |
| remove unconditioned resets on fresh appearing apqn devices. |
| It may be that such a device is already enabled for guest |
| usage. So there may be a race condition between host ap bus |
| and guest ap bus doing the reset. This patch moves the |
| reset from the ap bus to the zcrypt drivers. So if there |
| is no zcrypt driver bound to an ap device - for example |
| the ap device is bound to the vfio device driver - the |
| ap device is untouched passed to the vfio device driver. |
| |
| Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> |
| Signed-off-by: Vasily Gorbik <gor@linux.ibm.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c |
| index b9fc502c58c2..eb0f8430e11d 100644 |
| --- a/drivers/s390/crypto/ap_bus.c |
| +++ b/drivers/s390/crypto/ap_bus.c |
| @@ -794,8 +794,6 @@ static int ap_device_probe(struct device *dev) |
| drvres = ap_drv->flags & AP_DRIVER_FLAG_DEFAULT; |
| if (!!devres != !!drvres) |
| 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 */ |
| diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h |
| index 6f3cf37776ca..10f8024f03cb 100644 |
| --- a/drivers/s390/crypto/ap_bus.h |
| +++ b/drivers/s390/crypto/ap_bus.h |
| @@ -260,7 +260,7 @@ void ap_queue_prepare_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_resume(struct ap_device *ap_dev); |
| -void ap_queue_reinit_state(struct ap_queue *aq); |
| +void ap_queue_init_state(struct ap_queue *aq); |
| |
| struct ap_card *ap_card_create(int id, int queue_depth, int raw_device_type, |
| int comp_device_type, unsigned int functions); |
| diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c |
| index 5ea83dc4f1d7..a3f8d2512698 100644 |
| --- a/drivers/s390/crypto/ap_queue.c |
| +++ b/drivers/s390/crypto/ap_queue.c |
| @@ -637,7 +637,7 @@ struct ap_queue *ap_queue_create(ap_qid_t qid, int device_type) |
| aq->ap_dev.device.type = &ap_queue_type; |
| aq->ap_dev.device_type = device_type; |
| aq->qid = qid; |
| - aq->state = AP_STATE_RESET_START; |
| + aq->state = AP_STATE_UNBOUND; |
| aq->interrupt = AP_INTR_DISABLED; |
| spin_lock_init(&aq->lock); |
| INIT_LIST_HEAD(&aq->list); |
| @@ -770,10 +770,11 @@ void ap_queue_remove(struct ap_queue *aq) |
| spin_unlock_bh(&aq->lock); |
| } |
| |
| -void ap_queue_reinit_state(struct ap_queue *aq) |
| +void ap_queue_init_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_init_state); |
| diff --git a/drivers/s390/crypto/zcrypt_cex2a.c b/drivers/s390/crypto/zcrypt_cex2a.c |
| index c50f3e86cc74..7cbb384ec535 100644 |
| --- a/drivers/s390/crypto/zcrypt_cex2a.c |
| +++ b/drivers/s390/crypto/zcrypt_cex2a.c |
| @@ -175,6 +175,7 @@ static int zcrypt_cex2a_queue_probe(struct ap_device *ap_dev) |
| zq->queue = aq; |
| zq->online = 1; |
| atomic_set(&zq->load, 0); |
| + ap_queue_init_state(aq); |
| ap_queue_init_reply(aq, &zq->reply); |
| aq->request_timeout = CEX2A_CLEANUP_TIME, |
| aq->private = zq; |
| diff --git a/drivers/s390/crypto/zcrypt_cex2c.c b/drivers/s390/crypto/zcrypt_cex2c.c |
| index 35c7c6672713..c78c0d119806 100644 |
| --- a/drivers/s390/crypto/zcrypt_cex2c.c |
| +++ b/drivers/s390/crypto/zcrypt_cex2c.c |
| @@ -220,6 +220,7 @@ static int zcrypt_cex2c_queue_probe(struct ap_device *ap_dev) |
| zq->queue = aq; |
| zq->online = 1; |
| atomic_set(&zq->load, 0); |
| + ap_rapq(aq->qid); |
| rc = zcrypt_cex2c_rng_supported(aq); |
| if (rc < 0) { |
| zcrypt_queue_free(zq); |
| @@ -231,6 +232,7 @@ static int zcrypt_cex2c_queue_probe(struct ap_device *ap_dev) |
| else |
| zq->ops = zcrypt_msgtype(MSGTYPE06_NAME, |
| MSGTYPE06_VARIANT_NORNG); |
| + ap_queue_init_state(aq); |
| ap_queue_init_reply(aq, &zq->reply); |
| aq->request_timeout = CEX2C_CLEANUP_TIME; |
| aq->private = zq; |
| diff --git a/drivers/s390/crypto/zcrypt_cex4.c b/drivers/s390/crypto/zcrypt_cex4.c |
| index 582ffa7e0f18..9425026d2dfe 100644 |
| --- a/drivers/s390/crypto/zcrypt_cex4.c |
| +++ b/drivers/s390/crypto/zcrypt_cex4.c |
| @@ -254,6 +254,7 @@ static int zcrypt_cex4_queue_probe(struct ap_device *ap_dev) |
| zq->queue = aq; |
| zq->online = 1; |
| atomic_set(&zq->load, 0); |
| + ap_queue_init_state(aq); |
| ap_queue_init_reply(aq, &zq->reply); |
| aq->request_timeout = CEX4_CLEANUP_TIME, |
| aq->private = zq; |
| -- |
| 2.7.4 |
| |