Skip to content

Commit dd17483

Browse files
Tony Krowiakhcahca
authored andcommitted
s390/vfio-ap: remove upper limit on wait for queue reset to complete
The architecture does not define an upper limit on how long a queue reset (RAPQ/ZAPQ) can take to complete. In order to ensure both the security requirements and prevent resource leakage and corruption in the hypervisor, it is necessary to remove the upper limit (200ms) the vfio_ap driver currently waits for a reset to complete. This, of course, may result in a hang which is a less than desirable user experience, but until a firmware solution is provided, this is a necessary evil. Signed-off-by: Tony Krowiak <[email protected]> Reviewed-by: Jason J. Herne <[email protected]> Acked-by: Halil Pasic <[email protected]> Tested-by: Viktor Mihajlovski <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Heiko Carstens <[email protected]>
1 parent c51f8c6 commit dd17483

File tree

1 file changed

+35
-29
lines changed

1 file changed

+35
-29
lines changed

drivers/s390/crypto/vfio_ap_ops.c

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#define AP_QUEUE_UNASSIGNED "unassigned"
3131
#define AP_QUEUE_IN_USE "in use"
3232

33-
#define MAX_RESET_CHECK_WAIT 200 /* Sleep max 200ms for reset check */
3433
#define AP_RESET_INTERVAL 20 /* Reset sleep interval (20ms) */
3534

3635
static int vfio_ap_mdev_reset_queues(struct ap_queue_table *qtable);
@@ -1622,58 +1621,66 @@ static int apq_status_check(int apqn, struct ap_queue_status *status)
16221621
}
16231622
}
16241623

1624+
#define WAIT_MSG "Waited %dms for reset of queue %02x.%04x (%u, %u, %u)"
1625+
16251626
static int apq_reset_check(struct vfio_ap_queue *q)
16261627
{
1627-
int ret;
1628-
int iters = MAX_RESET_CHECK_WAIT / AP_RESET_INTERVAL;
1628+
int ret = -EBUSY, elapsed = 0;
16291629
struct ap_queue_status status;
16301630

1631-
for (; iters > 0; iters--) {
1631+
while (true) {
16321632
msleep(AP_RESET_INTERVAL);
1633+
elapsed += AP_RESET_INTERVAL;
16331634
status = ap_tapq(q->apqn, NULL);
16341635
ret = apq_status_check(q->apqn, &status);
1635-
if (ret != -EBUSY)
1636+
if (ret == -EIO)
16361637
return ret;
1638+
if (ret == -EBUSY) {
1639+
pr_notice_ratelimited(WAIT_MSG, elapsed,
1640+
AP_QID_CARD(q->apqn),
1641+
AP_QID_QUEUE(q->apqn),
1642+
status.response_code,
1643+
status.queue_empty,
1644+
status.irq_enabled);
1645+
} else {
1646+
if (q->reset_rc == AP_RESPONSE_RESET_IN_PROGRESS ||
1647+
q->reset_rc == AP_RESPONSE_BUSY) {
1648+
status = ap_zapq(q->apqn, 0);
1649+
q->reset_rc = status.response_code;
1650+
continue;
1651+
}
1652+
/*
1653+
* When an AP adapter is deconfigured, the associated
1654+
* queues are reset, so let's set the status response
1655+
* code to 0 so the queue may be passed through (i.e.,
1656+
* not filtered).
1657+
*/
1658+
if (q->reset_rc == AP_RESPONSE_DECONFIGURED)
1659+
q->reset_rc = 0;
1660+
if (q->saved_isc != VFIO_AP_ISC_INVALID)
1661+
vfio_ap_free_aqic_resources(q);
1662+
break;
1663+
}
16371664
}
1638-
WARN_ONCE(iters <= 0,
1639-
"timeout verifying reset of queue %02x.%04x (%u, %u, %u)",
1640-
AP_QID_CARD(q->apqn), AP_QID_QUEUE(q->apqn),
1641-
status.queue_empty, status.irq_enabled, status.response_code);
16421665
return ret;
16431666
}
16441667

16451668
static int vfio_ap_mdev_reset_queue(struct vfio_ap_queue *q)
16461669
{
16471670
struct ap_queue_status status;
1648-
int ret;
1671+
int ret = 0;
16491672

16501673
if (!q)
16511674
return 0;
1652-
retry_zapq:
16531675
status = ap_zapq(q->apqn, 0);
16541676
q->reset_rc = status.response_code;
16551677
switch (status.response_code) {
16561678
case AP_RESPONSE_NORMAL:
1657-
ret = 0;
1658-
if (!status.irq_enabled)
1659-
vfio_ap_free_aqic_resources(q);
1660-
if (!status.queue_empty || status.irq_enabled) {
1661-
ret = apq_reset_check(q);
1662-
if (status.irq_enabled && ret == 0)
1663-
vfio_ap_free_aqic_resources(q);
1664-
}
1665-
break;
16661679
case AP_RESPONSE_RESET_IN_PROGRESS:
16671680
case AP_RESPONSE_BUSY:
1668-
/*
1669-
* There is a reset issued by another process in progress. Let's wait
1670-
* for that to complete. Since we have no idea whether it was a RAPQ or
1671-
* ZAPQ, then if it completes successfully, let's issue the ZAPQ.
1672-
*/
1681+
/* Let's verify whether the ZAPQ completed successfully */
16731682
ret = apq_reset_check(q);
1674-
if (ret)
1675-
break;
1676-
goto retry_zapq;
1683+
break;
16771684
case AP_RESPONSE_DECONFIGURED:
16781685
/*
16791686
* When an AP adapter is deconfigured, the associated
@@ -1682,7 +1689,6 @@ static int vfio_ap_mdev_reset_queue(struct vfio_ap_queue *q)
16821689
* return a value indicating the reset completed successfully.
16831690
*/
16841691
q->reset_rc = 0;
1685-
ret = 0;
16861692
vfio_ap_free_aqic_resources(q);
16871693
break;
16881694
default:

0 commit comments

Comments
 (0)