From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 56EFD60A261B for ; Thu, 22 Oct 2026 22:50:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=xx3twlGs; dkim=pass (2048-bit key, unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20251104 header.b=HDlXTrq9 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type:Cc:To:From: Subject:Message-ID:References:Mime-Version:In-Reply-To:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Unsubscribe-Post:List-Owner; bh=ZxtqEGpizmVFkbAIWqB2ioSJ0+pXS1WhHyAhjSgL0fY=; b=xx3twlGsT7Jni45uboLEhUeN0n RzTI/uHoffUKSe4U4FqBMlkPqYc6FLOa12ECfkg7NSHyz2uVUZcu1Xx0mGAOaLPlp8tAeEO0JgK4L AyKdcK5IAbOeaPuUu2c+dbhcaL8VcdKR6wDfgKceM84txA1lK9CT7FBNk3gHvbUrPKPUH1kyfAlL4 YJsHKebEvjPEYJ+T5eJ7w3OkNpbCq7euFbGbkIyE8huzuTMeN4LWs7DDf+GLr5i2F86yCG4zKvj8q szZoRMBGRtLpguJjC6sQuArWVwLbuwn2pV4xqcFEtD4PVplaRo3OGH+3XlVSN5iNVbf1M6Rmo3YdT gjr/cfzA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.100.1 #2 (Red Hat Linux)) id 1xK1cS-0000000F5tg-2xdS; Thu, 22 Oct 2026 22:50:44 +0000 Received: from mail-pf1-x447.google.com ([2607:f8b0:4864:20::447]) by bombadil.infradead.org with esmtps (Exim 4.100.1 #2 (Red Hat Linux)) id 1xK1cQ-0000000F5s0-2BPK for kexec@lists.infradead.org; Thu, 22 Oct 2026 22:50:43 +0000 Received: by mail-pf1-x447.google.com with SMTP id d2e1a72fcca58-89e6ddd4554so212301b3a.3 for ; Thu, 22 Oct 2026 15:50:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1792709441; x=1793314241; darn=lists.infradead.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=ZxtqEGpizmVFkbAIWqB2ioSJ0+pXS1WhHyAhjSgL0fY=; b=HDlXTrq9uNWdnYil06Rp3/EVPDX48v2o0j/gdo6dGTRJhbx0p2vH6csJpdMbBQVfab kw4B+qwGVG3691elm44odetVucPiFyViDG77FUeh31oHcH+PBnFKciCBOoPF6RhHVz5h KJn4hkVwGIS80CmEA1fD+mRAF9mjAbacsQUQP2qH9BBhAkLAg7vCnNLuRnWyPQGYtNEH BqSuJEoD33Nb/iSd09BzHJggw/mom20orhGl2BgGVgfpswdyxZlrnlWo6QchtHAo0Lgq TdOkImVH03tMiaEuIR2p9hpYdugz6YPyv9ubTctzQYZ8iok5BsSGCAYJwd1TJE8oa5GL 7doQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1792709441; x=1793314241; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=ZxtqEGpizmVFkbAIWqB2ioSJ0+pXS1WhHyAhjSgL0fY=; b=rrF5hLxw92xoWeeuCHZrT22XL000jn+NixfrP7FAYZVByVm9T3baKmTOu6xAl0rC5W sUayJ3OAk1nWEqlZ3ZbHBYr+X26DZjlApi8h7RPDcTwlu7sUrXGI2pmoQ+Fbgwy2Cv/D ZU6iUjqzbMl5coYOb3lrWCHrJm1GpKgubrBsrH8DQqaZfSo6+Na/jbjXh79FtO79/diM v1N18Thny3yXFzQnqgTH5uJ7gfO1HafkipOJH6xiWskSYztN6H3zHZ64l2+6OsA/GTlo pKlaoNmuvPzbppUW8NKmOMt8reO0cBcjwU7IZ75eZRfalhgX/Cr4n3AXiFQLxQrELrqG Mxtg== X-Gm-Message-State: AFq9FYJJSbdQuyJcyIDpDAqtljTkFkJ5LYzv/6LekgODPfmNGawcBdDV 4XC2vty5A/RhKMSiVpYjDlhyH9r3TICeTedyiITCSUvC7etyk5+fo/nLST/VvJQgLE5PoIK8c4Y tEmkCbzUKLtS8dyWqKQMPpEJLpw95KTN5EUIc3GKmrNb1dTssK46bKWnV7rnaAtsxNPGArCPfyu kM1dckrlWDZHWHvdgR9EwaaXaaJSb77+8CpCfPS4Wys/oH20xO+Wo= X-Received: from pgfd7-n1.prod.google.com ([2002:a05:6a02:6547:10b0:cc7:d1fb:4ccd]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:d81a:b0:3e2:6825:beec with SMTP id adf61e73a8af0-3e369227d0bmr279978637.19.1792709440800; Thu, 22 Oct 2026 15:50:40 -0700 (PDT) Date: Thu, 22 Oct 2026 22:50:28 +0000 In-Reply-To: <20261022225035.377445-1-dmatlack@google.com> X-Archived-By: Mime-Version: 1.0 References: <20261022225035.377445-1-dmatlack@google.com> X-Mailer: git-send-email 2.56.0.257.gf7497c7d27-goog Message-ID: <20261022225035.377445-4-dmatlack@google.com> Subject: [PATCH v2 03/10] liveupdate: Allow file handlers to mark retrieve failures as retryable From: David Matlack To: kexec@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org Cc: Alexander Graf , Andrew Morton , Baolin Wang , Christian Brauner , David Hildenbrand , Hugh Dickins , Jonathan Corbet , "Liam R. Howlett" , Lorenzo Stoakes , Michal Hocko , Mike Rapoport , Pasha Tatashin , Pratyush Yadav , Randy Dunlap , Samiullah Khawaja , Shuah Khan , Suren Baghdasaryan , Vlastimil Babka , David Matlack Content-Type: text/plain; charset="UTF-8" X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20261022_155042_585534_3E91E658 X-CRM114-Status: GOOD ( 28.39 ) X-Spam-Score: -9.5 (---------) X-BeenThere: kexec@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "kexec" X-Spam-Status: No, score=-26.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIMWL_WL_MED,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT, USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=4.0.1 X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on aws-us-west-2-korg-listserv-alma10-1 From: Pasha Tatashin When luo_retrieve_file() invokes a handler's .retrieve() callback and it returns an error, LUO currently records the error in luo_file->retrieve_status and blocks any subsequent retrieve attempts. This is necessary when the handler has already partially consumed or freed the preserved KHO state. However, with user arguments passed to .retrieve(), a handler may fail early while validating caller-supplied parameters (such as a missing argument, an invalid or read-only target file descriptor, or a non-empty target file) before touching any preserved KHO state. In such cases, userspace should be able to fix the argument and retry LIVEUPDATE_SESSION_RETRIEVE_FD, and if the file is never retrieved, .finish() must still run to release the preserved KHO state. Add a retryable output flag to struct liveupdate_file_op_args. When a handler sets args->retryable = true on error, luo_retrieve_file() leaves luo_file->retrieve_status at 0 so the retrieve operation can be retried and .finish() will still clean up the unconsumed preserved state if the session is finished without retrieving the file. Signed-off-by: Pasha Tatashin Signed-off-by: David Matlack --- include/linux/liveupdate.h | 11 ++++++++--- include/uapi/linux/liveupdate.h | 7 ++++--- kernel/liveupdate/luo_file.c | 20 ++++++++++++++------ 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/include/linux/liveupdate.h b/include/linux/liveupdate.h index 7543f5d648d3..e4ad0bf78a5c 100644 --- a/include/linux/liveupdate.h +++ b/include/linux/liveupdate.h @@ -58,9 +58,13 @@ struct liveupdate_arg_spec { * @session: The session this file belongs to. * @retrieve_status: The retrieve status for the 'can_finish / finish' * operation. A value of 0 means the retrieve has not been - * attempted, a positive value means the retrieve was - * successful, and a negative value means the retrieve failed, - * and the value is the error code of the call. + * attempted (or only failed with a retryable error), a + * positive value means the retrieve was successful, and a + * negative value means the retrieve permanently failed, and + * the value is the error code of the call. + * @retryable: For .retrieve(): [OUT] Set to true by the callback on + * error when the preserved state has not been consumed and + * retrieval may be retried. * @file: The file object. For retrieve: [OUT] The callback sets * this to the new file. For other ops: [IN] The caller sets * this to the file being operated on. @@ -83,6 +87,7 @@ struct liveupdate_file_op_args { struct liveupdate_file_handler *handler; struct liveupdate_session *session; int retrieve_status; + bool retryable; struct file *file; u64 serialized_data; void *private_data; diff --git a/include/uapi/linux/liveupdate.h b/include/uapi/linux/liveupdate.h index e806752c2fc6..953ffe0823be 100644 --- a/include/uapi/linux/liveupdate.h +++ b/include/uapi/linux/liveupdate.h @@ -174,9 +174,10 @@ struct liveupdate_session_preserve_fd { * associated with the token and populates the @fd field with a new file * descriptor referencing the restored resource in the current (new) kernel. * This operation must be performed *before* signaling completion via - * %LIVEUPDATE_IOCTL_FINISH. If a retrieve of a token fails, subsequent - * attempts to retrieve the token fail with the same error code. Failed - * retrieves are not retried. + * %LIVEUPDATE_IOCTL_FINISH. If a retrieve of a token fails after consuming + * preserved state, subsequent attempts to retrieve the token fail with the + * same error code. Early argument or target validation errors before + * preserved state is consumed leave the token intact and may be retried. * * Retrieving a token that was already retrieved successfully returns a new file * descriptor for the same file. The @arg only applies to the retrieve that diff --git a/kernel/liveupdate/luo_file.c b/kernel/liveupdate/luo_file.c index eeeb3b5ff2fa..908ae124ea5e 100644 --- a/kernel/liveupdate/luo_file.c +++ b/kernel/liveupdate/luo_file.c @@ -152,9 +152,10 @@ static DEFINE_XARRAY(luo_preserved_files); * @retrieve_status: Status code indicating whether a user/kernel in the new kernel has * successfully called retrieve() on this file. This prevents * multiple retrieval attempts. A value of 0 means a retrieve() - * has not been attempted, a positive value means the retrieve() - * was successful, and a negative value means the retrieve() - * failed, and the value is the error code of the call. + * has not been attempted (or only failed with a retryable + * error), a positive value means the retrieve() was successful, + * and a negative value means the retrieve() permanently failed, + * and the value is the error code of the call. * @mutex: A mutex that protects the fields of this specific instance * (e.g., @retrieved, @file), ensuring that operations like * retrieving or finishing a file are atomic. @@ -604,7 +605,9 @@ void luo_file_unfreeze(struct luo_file_set *file_set, * The operation is idempotent: if a file has already been successfully * retrieved, this function will simply return a pointer to the existing * 'struct file' and report success without re-executing the retrieve - * operation. This is handled by checking the 'retrieved' flag under a lock. + * operation. If a previous retrieve failed permanently, it returns that + * saved error code; if a previous retrieve failed with a retryable error + * before consuming preserved state, the retrieve operation is re-attempted. * * File retrieval can happen in any order; it is not bound by the order of * preservation. @@ -671,8 +674,13 @@ int luo_retrieve_file(struct luo_file_set *file_set, u64 token, u64 arg, err = luo_file->fh->ops->retrieve(&args); kfree(args.arg); if (err) { - /* Keep the error code for later use. */ - luo_file->retrieve_status = err; + /* + * Keep the error code for later use unless the handler marked + * the failure as retryable (e.g. invalid user argument before + * preserved state was consumed). + */ + if (!args.retryable) + luo_file->retrieve_status = err; return err; } -- 2.56.0.257.gf7497c7d27-goog