From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj1-f51.google.com (mail-pj1-f51.google.com [209.85.216.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 18DC33515E7 for ; Tue, 4 Aug 2026 18:20:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.51 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785867603; cv=none; b=juq1ZxZOspBbiE5x6Blst6Z4CQY/yWqXMvNaSTEnGO7CHPhh/lkp8HvH2FLaAUHilowNsrUJjdoozGAMeRrdNRdGDx9NXqCSLwSz1iDPMYq10P4NkUSELH4Ved5jKMDMRgZQkOcFg3u4ANthnkYttfWcvw4qnobqbIFspEKLmGU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785867603; c=relaxed/simple; bh=PtRqzhQRb7bU7mah6yGiifES/yEQ4XiEOjC7ACQkKnQ=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=s/pZQ6fpSDusLaUgNtR2RokroiOKfQOeZCXoBlGYWz5aNzAucC/6kCqRvMwmS3kWu7VJJrWQPl1RReTaR5j9sjE97pom9JhvaR/R/VhQHheVPkO1TtL90XUODD1dB68EHUFAGDDJYUMvcjQ+vSeIHXUZrHsnT0tyG2WlzKTzjRM= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=HOZkSBS9; arc=none smtp.client-ip=209.85.216.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="HOZkSBS9" Received: by mail-pj1-f51.google.com with SMTP id 98e67ed59e1d1-38eca09faa2so19793a91.3 for ; Tue, 04 Aug 2026 11:20:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785867601; x=1786472401; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=jw7e5Rfr9nTLu9Xi7DMR9VP2hbwdbhAjZW2kw4eVdlQ=; b=HOZkSBS94JF7pNhIcibw0zVV1uPoLMNsSB1b28wUWyRBIWgCTAlib3GyFEDp1ZaMi+ PIx1iGaHBaXR7sSX2Xk3zSk1Ik6SouVh42HrmExX3+8YasT7axsDjG4jnryYzpw17btN CDX8TzKQxPDene03awLrz8PpijfJSPCory9DWiaQrTOeuN4lGkcjiUaumtRYrB7zQSJP 3ggXgJh6XAUvclu103+0ZnCeaWlcWaewcDa0T6UBt3soBZz/ZJiHwvZmmGHWB8kVn0tN Fgg9Pr7lqOfjD6JIUuWiJQlKqa8w3Y4ntnk6UBqeysRUblY/nvDdJ9Uu9Vbc3BUcC/Qy aysQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785867601; x=1786472401; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=jw7e5Rfr9nTLu9Xi7DMR9VP2hbwdbhAjZW2kw4eVdlQ=; b=ewOrIs+2j0janOcs8CpvdGca7z1LUmBK3KrqBq2gqOMP12VAWEuwHXp2jUvwXFdrXg AMTdqGm46hcde40BXr1stiWpd5Djyxp/MfKkZuqHRuLa77RW23Xz6OgadQeA8cSoK3sh jUDPLwx7jy7uuTs3rXgT2y98mQeyh1Dn5jmWdhVp03JdgBlYbezyVEVncosaEgyrn8LW ntlwe4QegUmbR5ZSfpU36Ri6B3rUb7B5v6C+3elt9z46I0bGQULwZ1NvVNwVHMHpFPNF +zCbkagBXVBBuzB61Nb5VolRcjar6cUfqQTOqhmrAsztRUR98F7CntR0/c33CL7TKS5Q g0Xg== X-Forwarded-Encrypted: i=1; AHgh+RrLy95B+SFRHDtG+ij60D8M7s5BcBxgBXqtxkPA5wXl3r1noJZB0CmJ7UBzlSpR+ld3K26LnPrCbyB8974=@vger.kernel.org X-Gm-Message-State: AOJu0Yxpid+l4ilM+AOzNCfeG2BEXqxr/KS3aZtOsh9hPRvdDo72UiBd LH5QXv9Xs3Nxh3766zc+SbWtc09UZThHY3M34EPsn0BT75jra7Sw5CEp X-Gm-Gg: AR+sD13eMMPNhzFbLwwGhprvbSXLlIt/x20x3i2/wMk/WlsYcJs/FkV9R/+NwejkJYH 2pJ9ELQE9G4WqxTjdUMdgdJujYvoRDmxBL5eQQrJ7LhlaidPIM1QoRsCE+B8frO2u7XVGOeJEk/ WtKXo/zW2RJEFDdcHz7+eBionZmHmxwIlAvsrSJz+AOgtl1qyzzwKiQylN0hROE1TYpIOnSG816 SflovFqgUmAsr79DeOG6SjXmeSBDAemdssOBuhiZwxbap+o2Xg0/26VMQ/JQJbKwdHHzgemUbZf E/LHsGKGhW9WB/VOtz0anTdpIeXuh04DX60pdci85g/cFleGIQFOtZ1YS0TG21EHA8DSxcM38e9 OcspKMm48heg3gllkqIRu8Aj+tbDm2SlT/eL42+8AP9qBVGMZjKoKnVX0PjlHzJGtQ0Wq5zf8kg t5v5s3U5WHYbNXDuaMckAEFaYlqWlVj7OUX74VZJYa2nb3jBSqimbfnvQOxCeTQjlw1E1NB/o4O GmFDbTPyb4pg2s= X-Received: by 2002:a17:90b:4410:b0:38e:6d4c:14df with SMTP id 98e67ed59e1d1-3903c5bff9dmr807451a91.1.1785867601383; Tue, 04 Aug 2026 11:20:01 -0700 (PDT) Received: from localhost.localdomain ([202.164.135.140]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-13fca8e969esm4967976c88.10.2026.08.04.11.19.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Aug 2026 11:20:00 -0700 (PDT) From: Sailesh Nandanavanam To: andersson@kernel.org, mathieu.poirier@linaro.org Cc: neil.armstrong@linaro.org, linux-arm-msm@vger.kernel.org, linux-remoteproc@vger.kernel.org, linux-kernel@vger.kernel.org, Sailesh Nandanavanam Subject: [PATCH v4] remoteproc: qcom_q6v5_pas: Fix dtb firmware lifecycle and leak Date: Tue, 4 Aug 2026 23:49:51 +0530 Message-Id: <20260804181951.5206-1-saileshnandanavanam@gmail.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit DTB co-firmware was previously requested and loaded in qcom_pas_load(), but its lifetime did not match the actual start/stop lifecycle of the remoteproc. As a result, the firmware reference could be retained across restart cycles, leading to a leak for each successful boot. Additionally, if qcom_pas_start() failed after loading the DTB firmware, the remoteproc core would not invoke .stop(), leaving no opportunity to release the associated firmware reference. Fix this by moving DTB firmware request and loading into qcom_pas_start(), so that its lifetime is strictly tied to the remoteproc start sequence. Update qcom_pas_start() to ensure proper cleanup on all paths: - release PAS metadata on failure - release DTB firmware on both success and failure paths - unmap DTB carveout where applicable Remove DTB firmware handling from qcom_pas_load(), as it does not match the correct ownership and lifecycle model. With this change, request_firmware() and release_firmware() are properly paired within the start path, avoiding leaks and ensuring consistent behavior across restart and failure scenarios. Fixes: 29814986b82e ("remoteproc: qcom_q6v5_pas: add support for dtb co-firmware loading") Signed-off-by: Sailesh Nandanavanam --- v4: - Rebase onto linux-next - Remove unused int ret from qcom_pas_load() v3: - Remove the unused release_dtb_firmware label - Release DTB firmware under the existing dtb_pas_id check v2: - Move DTB firmware request/load from qcom_pas_load() to qcom_pas_start() - Fix firmware reference leak across restart cycles - Handle start() failure paths where .stop() is not invoked - Ensure firmware is released on all success and failure paths - Remove DTB handling from load() and drop release from stop() --- drivers/remoteproc/qcom_q6v5_pas.c | 47 +++++++++++++++++------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index ca8e61254c44..864446a484f1 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -231,7 +231,6 @@ static int qcom_pas_unprepare(struct rproc *rproc) static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw) { struct qcom_pas *pas = rproc->priv; - int ret; /* Store firmware handle to be used in qcom_pas_start() */ pas->firmware = fw; @@ -241,23 +240,6 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw) if (pas->lite_dtb_pas_id) qcom_pas_shutdown(pas->lite_dtb_pas_id); - if (pas->dtb_pas_id) { - ret = request_firmware(&pas->dtb_firmware, pas->dtb_firmware_name, pas->dev); - if (ret) { - dev_err(pas->dev, "request_firmware failed for %s: %d\n", - pas->dtb_firmware_name, ret); - return ret; - } - - ret = qcom_mdt_pas_load(pas->dtb_pas_ctx, pas->dtb_firmware, - pas->dtb_firmware_name, &pas->dtb_mem_reloc); - if (ret) { - qcom_pas_metadata_release(pas->dtb_pas_ctx); - release_firmware(pas->dtb_firmware); - return ret; - } - } - return 0; } @@ -282,9 +264,23 @@ static int qcom_pas_start(struct rproc *rproc) struct qcom_pas *pas = rproc->priv; int ret; + if (pas->dtb_pas_id) { + ret = request_firmware(&pas->dtb_firmware, pas->dtb_firmware_name, pas->dev); + if (ret) { + dev_err(pas->dev, "request_firmware failed for %s: %d\n", + pas->dtb_firmware_name, ret); + return ret; + } + + ret = qcom_mdt_pas_load(pas->dtb_pas_ctx, pas->dtb_firmware, + pas->dtb_firmware_name, &pas->dtb_mem_reloc); + if (ret) + goto release_dtb_metadata; + } + ret = qcom_q6v5_prepare(&pas->q6v5); if (ret) - return ret; + goto release_dtb_metadata; ret = qcom_pas_pds_enable(pas, pas->proxy_pds, pas->proxy_pd_count); if (ret < 0) @@ -352,6 +348,11 @@ static int qcom_pas_start(struct rproc *rproc) if (pas->dtb_pas_id) qcom_pas_metadata_release(pas->dtb_pas_ctx); + if (pas->dtb_pas_id) { + release_firmware(pas->dtb_firmware); + pas->dtb_firmware = NULL; + } + /* firmware is used to pass reference from qcom_pas_start(), drop it now */ pas->firmware = NULL; @@ -361,8 +362,6 @@ static int qcom_pas_start(struct rproc *rproc) qcom_pas_unmap_carveout(rproc, pas->mem_phys, pas->mem_size); release_pas_metadata: qcom_pas_metadata_release(pas->pas_ctx); - if (pas->dtb_pas_id) - qcom_pas_metadata_release(pas->dtb_pas_ctx); unmap_dtb_carveout: if (pas->dtb_pas_id) @@ -381,6 +380,12 @@ static int qcom_pas_start(struct rproc *rproc) qcom_pas_pds_disable(pas, pas->proxy_pds, pas->proxy_pd_count); disable_irqs: qcom_q6v5_unprepare(&pas->q6v5); +release_dtb_metadata: + if (pas->dtb_pas_id) { + qcom_pas_metadata_release(pas->dtb_pas_ctx); + release_firmware(pas->dtb_firmware); + pas->dtb_firmware = NULL; + } /* firmware is used to pass reference from qcom_pas_start(), drop it now */ pas->firmware = NULL; -- 2.34.1