bool chkstop; /* checkstop state */
ap_qid_t qid; /* AP queue id. */
bool interrupt; /* indicate if interrupts are enabled */
+ bool se_bound; /* SE bound state */
unsigned int assoc_idx; /* SE association index */
int queue_count; /* # messages currently on AP queue. */
int pendingq_count; /* # requests on pendingq list. */
int ap_queue_message(struct ap_queue *aq, struct ap_message *ap_msg);
void ap_cancel_message(struct ap_queue *aq, struct ap_message *ap_msg);
void ap_flush_queue(struct ap_queue *aq);
+bool ap_queue_usable(struct ap_queue *aq);
void *ap_airq_ptr(void);
int ap_sb_available(void);
return ap_test_bit(&aq->card->functions, AP_FUNC_EP11);
}
+static inline bool ap_q_needs_bind(struct ap_queue *aq)
+{
+ return ap_q_supports_bind(aq) && ap_sb_available();
+}
+
/**
* ap_queue_enable_irq(): Enable interrupt support on this AP queue.
* @aq: The AP queue
aq->sm_state = AP_SM_STATE_RESET_WAIT;
aq->interrupt = false;
aq->rapq_fbit = 0;
+ aq->se_bound = false;
return AP_SM_WAIT_LOW_TIMEOUT;
default:
aq->dev_state = AP_DEV_STATE_ERROR;
}
status = ap_bapq(aq->qid);
spin_unlock_bh(&aq->lock);
- if (status.response_code) {
+ if (!status.response_code) {
+ aq->se_bound = true;
+ AP_DBF_INFO("%s bapq(0x%02x.%04x) success\n", __func__,
+ AP_QID_CARD(aq->qid),
+ AP_QID_QUEUE(aq->qid));
+ } else {
AP_DBF_WARN("%s RC 0x%02x on bapq(0x%02x.%04x)\n",
__func__, status.response_code,
AP_QID_CARD(aq->qid),
}
EXPORT_SYMBOL(ap_queue_message);
+/**
+ * ap_queue_usable(): Check if queue is usable just now.
+ * @aq: The AP queue device to test for usability.
+ * This function is intended for the scheduler to query if it makes
+ * sense to enqueue a message into this AP queue device by calling
+ * ap_queue_message(). The perspective is very short-term as the
+ * state machine and device state(s) may change at any time.
+ */
+bool ap_queue_usable(struct ap_queue *aq)
+{
+ bool rc = true;
+
+ spin_lock_bh(&aq->lock);
+
+ /* check for not configured or checkstopped */
+ if (!aq->config || aq->chkstop) {
+ rc = false;
+ goto unlock_and_out;
+ }
+
+ /* device state needs to be ok */
+ if (aq->dev_state != AP_DEV_STATE_OPERATING) {
+ rc = false;
+ goto unlock_and_out;
+ }
+
+ /* SE guest's queues additionally need to be bound */
+ if (ap_q_needs_bind(aq) && !aq->se_bound)
+ rc = false;
+
+unlock_and_out:
+ spin_unlock_bh(&aq->lock);
+ return rc;
+}
+EXPORT_SYMBOL(ap_queue_usable);
+
/**
* ap_cancel_message(): Cancel a crypto request.
* @aq: The AP device that has the message queued
for_each_zcrypt_queue(zq, zc) {
/* check if device is usable and eligible */
if (!zq->online || !zq->ops->rsa_modexpo ||
- !zq->queue->config || zq->queue->chkstop)
+ !ap_queue_usable(zq->queue))
continue;
/* check if device node has admission for this queue */
if (!zcrypt_check_queue(perms,
for_each_zcrypt_queue(zq, zc) {
/* check if device is usable and eligible */
if (!zq->online || !zq->ops->rsa_modexpo_crt ||
- !zq->queue->config || zq->queue->chkstop)
+ !ap_queue_usable(zq->queue))
continue;
/* check if device node has admission for this queue */
if (!zcrypt_check_queue(perms,
for_each_zcrypt_queue(zq, zc) {
/* check for device usable and eligible */
if (!zq->online || !zq->ops->send_cprb ||
- !zq->queue->config || zq->queue->chkstop ||
+ !ap_queue_usable(zq->queue) ||
(tdom != AUTOSEL_DOM &&
tdom != AP_QID_QUEUE(zq->queue->qid)))
continue;
for_each_zcrypt_queue(zq, zc) {
/* check if device is usable and eligible */
if (!zq->online || !zq->ops->send_ep11_cprb ||
- !zq->queue->config || zq->queue->chkstop ||
+ !ap_queue_usable(zq->queue) ||
(targets &&
!is_desired_ep11_queue(zq->queue->qid,
target_num, targets)))
for_each_zcrypt_queue(zq, zc) {
/* check if device is usable and eligible */
if (!zq->online || !zq->ops->rng ||
- !zq->queue->config || zq->queue->chkstop)
+ !ap_queue_usable(zq->queue))
continue;
if (!zcrypt_queue_compare(zq, pref_zq, wgt, pref_wgt))
continue;