diff options
Diffstat (limited to 'drivers/s390/crypto/ap_queue.c')
-rw-r--r-- | drivers/s390/crypto/ap_queue.c | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c index 1f647ffd6f4d..9a0e6e4d8a5e 100644 --- a/drivers/s390/crypto/ap_queue.c +++ b/drivers/s390/crypto/ap_queue.c @@ -22,6 +22,11 @@ static void __ap_flush_queue(struct ap_queue *aq); * some AP queue helper functions */ +static inline bool ap_q_supported_in_se(struct ap_queue *aq) +{ + return aq->card->hwinfo.ep11 || aq->card->hwinfo.accel; +} + static inline bool ap_q_supports_bind(struct ap_queue *aq) { return aq->card->hwinfo.ep11 || aq->card->hwinfo.accel; @@ -171,8 +176,8 @@ static struct ap_queue_status ap_sm_recv(struct ap_queue *aq) aq->queue_count = 0; list_splice_init(&aq->pendingq, &aq->requestq); aq->requestq_count += aq->pendingq_count; - pr_debug("%s queue 0x%02x.%04x rescheduled %d reqs (new req %d)\n", - __func__, AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid), + pr_debug("queue 0x%02x.%04x rescheduled %d reqs (new req %d)\n", + AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid), aq->pendingq_count, aq->requestq_count); aq->pendingq_count = 0; break; @@ -453,8 +458,8 @@ static enum ap_sm_wait ap_sm_assoc_wait(struct ap_queue *aq) case AP_BS_Q_USABLE: /* association is through */ aq->sm_state = AP_SM_STATE_IDLE; - pr_debug("%s queue 0x%02x.%04x associated with %u\n", - __func__, AP_QID_CARD(aq->qid), + pr_debug("queue 0x%02x.%04x associated with %u\n", + AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid), aq->assoc_idx); return AP_SM_WAIT_NONE; case AP_BS_Q_USABLE_NO_SECURE_KEY: @@ -697,8 +702,8 @@ static ssize_t ap_functions_show(struct device *dev, status = ap_test_queue(aq->qid, 1, &hwinfo); if (status.response_code > AP_RESPONSE_BUSY) { - pr_debug("%s RC 0x%02x on tapq(0x%02x.%04x)\n", - __func__, status.response_code, + pr_debug("RC 0x%02x on tapq(0x%02x.%04x)\n", + status.response_code, AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); return -EIO; } @@ -853,8 +858,8 @@ static ssize_t se_bind_show(struct device *dev, status = ap_test_queue(aq->qid, 1, &hwinfo); if (status.response_code > AP_RESPONSE_BUSY) { - pr_debug("%s RC 0x%02x on tapq(0x%02x.%04x)\n", - __func__, status.response_code, + pr_debug("RC 0x%02x on tapq(0x%02x.%04x)\n", + status.response_code, AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); return -EIO; } @@ -981,8 +986,8 @@ static ssize_t se_associate_show(struct device *dev, status = ap_test_queue(aq->qid, 1, &hwinfo); if (status.response_code > AP_RESPONSE_BUSY) { - pr_debug("%s RC 0x%02x on tapq(0x%02x.%04x)\n", - __func__, status.response_code, + pr_debug("RC 0x%02x on tapq(0x%02x.%04x)\n", + status.response_code, AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); return -EIO; } @@ -1104,18 +1109,19 @@ static void ap_queue_device_release(struct device *dev) kfree(aq); } -struct ap_queue *ap_queue_create(ap_qid_t qid, int device_type) +struct ap_queue *ap_queue_create(ap_qid_t qid, struct ap_card *ac) { struct ap_queue *aq; aq = kzalloc(sizeof(*aq), GFP_KERNEL); if (!aq) return NULL; + aq->card = ac; aq->ap_dev.device.release = ap_queue_device_release; aq->ap_dev.device.type = &ap_queue_type; - aq->ap_dev.device_type = device_type; - // add optional SE secure binding attributes group - if (ap_sb_available() && is_prot_virt_guest()) + aq->ap_dev.device_type = ac->ap_dev.device_type; + /* in SE environment add bind/associate attributes group */ + if (ap_is_se_guest() && ap_q_supported_in_se(aq)) aq->ap_dev.device.groups = ap_queue_dev_sb_attr_groups; aq->qid = qid; spin_lock_init(&aq->lock); @@ -1196,10 +1202,16 @@ bool ap_queue_usable(struct ap_queue *aq) } /* SE guest's queues additionally need to be bound */ - if (ap_q_needs_bind(aq) && - !(aq->se_bstate == AP_BS_Q_USABLE || - aq->se_bstate == AP_BS_Q_USABLE_NO_SECURE_KEY)) - rc = false; + if (ap_is_se_guest()) { + if (!ap_q_supported_in_se(aq)) { + rc = false; + goto unlock_and_out; + } + if (ap_q_needs_bind(aq) && + !(aq->se_bstate == AP_BS_Q_USABLE || + aq->se_bstate == AP_BS_Q_USABLE_NO_SECURE_KEY)) + rc = false; + } unlock_and_out: spin_unlock_bh(&aq->lock); |