Skip to content

Commit 01cd0f8

Browse files
committed
NVIDIA: VR: SAUCE: firmware: smccc: lfa: handle LFA_BUSY in PRIME and ACTIVATE
DEN0147 §2.6: LFA_ACTIVATE can return LFA_BUSY when the firmware postpones the activation. Although the rwsem in this driver prevents concurrent ACTIVATE calls from kernel space, an external agent or internal firmware state may still produce LFA_BUSY. Add an explicit retry loop (same budget and delay as CALL_AGAIN) so the code does not silently treat a retriable condition as a terminal failure. Catching LFA_BUSY explicitly also surfaces potential firmware or driver bugs. DEN0147 §2.5: LFA_PRIME returning LFA_BUSY means another CPU is running LFA_PRIME concurrently. This driver never issues parallel PRIME, so this is unexpected; log pr_warn and return so the caller can surface the anomaly rather than swallowing it in the generic error path. Signed-off-by: Vedashree Vidwans <vvidwans@nvidia.com> Signed-off-by: Nirmoy Das <nirmoyd@nvidia.com>
1 parent 1ca69bf commit 01cd0f8

1 file changed

Lines changed: 28 additions & 0 deletions

File tree

drivers/firmware/smccc/lfa_fw.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,23 @@ static int activate_fw_image(struct fw_image *image)
371371
ret = -LFA_TIMED_OUT;
372372
}
373373

374+
/*
375+
* DEN0147 §2.6: LFA_BUSY means activation was postponed by firmware
376+
* and must be retried. Although the rwsem prevents concurrent ACTIVATE
377+
* from this driver, an external agent or firmware-internal state may
378+
* still return LFA_BUSY. Handle it explicitly so it is not silently
379+
* treated as a terminal failure — catching it here may also indicate a
380+
* bug in the driver or firmware.
381+
*/
382+
if (ret == -LFA_BUSY) {
383+
if (ktime_before(ktime_get(), end)) {
384+
msleep_interruptible(LFA_ACTIVATE_DELAY_MS);
385+
goto retry;
386+
}
387+
388+
ret = -LFA_TIMED_OUT;
389+
}
390+
374391
lfa_cancel(image);
375392

376393
pr_err("LFA_ACTIVATE for image %s failed: %s\n",
@@ -406,6 +423,17 @@ static int prime_fw_image(struct fw_image *image)
406423
arm_smccc_1_2_invoke(&reg, &res);
407424
up_read(&smc_lock);
408425

426+
/*
427+
* DEN0147 §2.5: LFA_BUSY from PRIME means another CPU is concurrently
428+
* running LFA_PRIME. This driver never issues parallel PRIME, so this
429+
* is unexpected and likely indicates a firmware or driver bug.
430+
*/
431+
if ((long)res.a0 == -LFA_BUSY) {
432+
pr_warn("LFA_PRIME for image %s returned LFA_BUSY (concurrent PRIME unexpected; possible firmware or driver bug)\n",
433+
get_image_name(image));
434+
return res.a0;
435+
}
436+
409437
if ((long)res.a0 < 0) {
410438
pr_err("LFA_PRIME for image %s failed: %s\n",
411439
get_image_name(image),

0 commit comments

Comments
 (0)