From patchwork Fri Nov 10 17:04:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Petr Mladek X-Patchwork-Id: 16449 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b129:0:b0:403:3b70:6f57 with SMTP id q9csp1276383vqs; Fri, 10 Nov 2023 09:44:10 -0800 (PST) X-Google-Smtp-Source: AGHT+IFH9UFxUTaETtTfH4LxmrNuERrzIKOZ9sBQ/Z1H4ghK+nZdo/KgoErjwLVdeEX4E2TZ+syd X-Received: by 2002:a05:6a20:549f:b0:174:2286:81f4 with SMTP id i31-20020a056a20549f00b00174228681f4mr9643708pzk.14.1699638250064; Fri, 10 Nov 2023 09:44:10 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1699638250; cv=none; d=google.com; s=arc-20160816; b=alAjnG/Thwv2Z9/C1vrhUAVyQPqKOY2gZgA503bWjk0rCbKRHAdip7L51mmeEtTznM OQfj4g0NBTb/HY04AEeaQ5arEH3EhENzUMp74OX9iwZ8LzMkq2sYBXb8xbvVN/bLZ1aB a7rnaefHG4BDcxs/jIvo6CvS2zIiS8BooxLsUlDKE9x44lN+h+gqnnT0Al5k5KX1TlO1 F3s1rD6apgVHKvl7KD3ej8FoBwW4exUm5+znNrxJ5xNAfuuDmQ4HDVwxv557KkHbcimi ROxtfGA8JL1SV0VKUizspRh35AcC7rZed4gX1RzcH649EpAmZXGx4yipdGppIvlklZf3 uCwA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=Gco73RSfTN8/boy1pLt5p6ChVwATofQd6fACfgYTWTQ=; fh=QymmJNL7ujK3TnGI4h4gU4MUoBxgM24tOQOHGCebULU=; b=C8MgykDj5qQIn1/oe5emRexKxU4fBwI79kvKHgJHIgYgTZ+Y0CpqfGlnufbuChx5p8 E6wgAhNSevBqPXAxEDIkHFfajjEZuFckqvYwwirvbI8QOcFk9t828bmt9YII0JcuqKCd yfEXBSwpanDyeWiqi5uMMzECeAX2pcXbscMVkPXSRjYLOtaBd/yKJHpobIcDe/Ppy3OR RxchV85tVzxqpTN5o9pjgF1QSKh2GhBUU/mhaQMjCtxPy3ETLYbGUgW4aC9TTOYICLKD OvD42uOt6Jz80MRTR47ka+BCu0maNvYku0yh3EJvANhclHj/jG9cfKGM0JaXB9fAOuxx 77Ew== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@suse.com header.s=susede1 header.b="ufL3/mwT"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:2 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=suse.com Received: from agentk.vger.email (agentk.vger.email. [2620:137:e000::3:2]) by mx.google.com with ESMTPS id d24-20020a17090ad3d800b002683f507990si4659131pjw.109.2023.11.10.09.44.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Nov 2023 09:44:10 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:2 as permitted sender) client-ip=2620:137:e000::3:2; Authentication-Results: mx.google.com; dkim=pass header.i=@suse.com header.s=susede1 header.b="ufL3/mwT"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:2 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=suse.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by agentk.vger.email (Postfix) with ESMTP id F2F6F801B49D; Fri, 10 Nov 2023 09:42:32 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at agentk.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231706AbjKJRl7 (ORCPT + 30 others); Fri, 10 Nov 2023 12:41:59 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46456 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230157AbjKJRli (ORCPT ); Fri, 10 Nov 2023 12:41:38 -0500 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4B97842C3B; Fri, 10 Nov 2023 09:04:48 -0800 (PST) Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out2.suse.de (Postfix) with ESMTP id 70A551F8BB; Fri, 10 Nov 2023 17:04:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1699635886; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=Gco73RSfTN8/boy1pLt5p6ChVwATofQd6fACfgYTWTQ=; b=ufL3/mwTE+4mCIbIPd+1IEJW7k2lVhoUQMg21AwxEphiSdKftZ1sKZIMUpFvumAf9vpcsb hyzlerKcwXy2CL2wx9b8skryI3QTq/8AQ8w3t+b/4bANpuir9D4TQdu0IDW5DvcnBTGLg+ 7Gli9bzuFUNAaDoQ4c4DStgAyBVoX0A= Received: from alley.suse.cz (pmladek.udp.ovpn2.prg.suse.de [10.100.201.202]) by relay2.suse.de (Postfix) with ESMTP id 12A182C289; Fri, 10 Nov 2023 17:04:46 +0000 (UTC) From: Petr Mladek To: Josh Poimboeuf , Miroslav Benes Cc: Joe Lawrence , Nicolai Stange , live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, Petr Mladek Subject: [POC 0/7] livepatch: Make livepatch states, callbacks, and shadow variables work together Date: Fri, 10 Nov 2023 18:04:21 +0100 Message-Id: <20231110170428.6664-1-pmladek@suse.com> X-Mailer: git-send-email 2.35.3 MIME-Version: 1.0 X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on agentk.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (agentk.vger.email [0.0.0.0]); Fri, 10 Nov 2023 09:42:33 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1782199877821384981 X-GMAIL-MSGID: 1782199877821384981 This POC is a material for the discussion "Simplify Livepatch Callbacks, Shadow Variables, and States handling" at LPC 2013, see https://lpc.events/event/17/contributions/1541/ It obsoletes the patchset adding the garbage collection of shadow variables. This new solution is based on ideas from Nicolai Stange. And it should also be in sync with Josh's ideas mentioned into the thread about the garbage collection, see https://lore.kernel.org/r/20230204235910.4j4ame5ntqogqi7m@treble What is this all about? There are three features provided by the kernel livepatching support: + callbacks: They allow doing system modifications where the "simple" redirection to the fixed code is not enough. For example, allocate some data and allow to use them when all processes are patched. There are four optional callbacks which might be called either when the livepatch or the livepatched object is loaded. It depends who is loaded first. The are called at different stages of the livepatch transition: pre_enable, post_enable, pre_disable, post_disable. Only callbacks from the new livepatch are called during atomic replace. The motivation was that new livepatches should know how to handle the existing changes correctly. Also it simplified the semantic because it would be horrible when both callbacks from the old and new livepatch are called. The later one might break changes done by the earlier one. They are defined per-object. The idea was that they might be needed when a livepatched module is loaded or unloaded. + shadow variables: They allow attaching extra data to any existing data. For example, they allow to extend a structure. Or they allow to create a spin lock which might stay even when the livepatch gets atomically replaced. They are defined per-patch but there is no real connection. There is just an allocate/get/free API. + states: They were introduced to manage the life-cycle of changes done by the callbacks and shadow variables. They should help especially when atomic replace is used. The new livepatch need to know what changes have already been done or which need to be reverted. The states are defined per-patch. There was proposal to make them per-object but it was decided that it was not worth the complexity. Each state might have a version which allows to maintain compatibility between the livepatches. Otherwise, there is no connection with the other features. The is just an API to check whether the state was in the previous patch so that the callbacks might do an informed decisions. Observation: + States were supposed to help with the life-time of changes done by callbacks. But states are per-patch and callbacks are per-object. Also the API is hard to use. + Shadow variables were not connected with the states at all. It needs to be done by callbacks. + The decision that only the callbacks from the new livepatch gets called during atomic replace make downgrades complicated. Better solution implemented by this POC: + Transform per-object callbacks to per-state callbacks so that the state might really control the life-cycle of the changes. + Change the semantic of the callbacks, so that they are called when the state is introduced or removed. No callbacks are called when the state is just transferred during the atomic replace. + The disable/remove callbacks from the old livepatch are called from the old livepatch when the new one does not support them. These callbacks have to be there anyway so that the livepatch can get disabled. This nicely solves the problem with downgrades while keeping simple semantic. + A state might be associated with a shadow variable with the same ID. It helps to maintain the life-cycle of the shadow variable. The variable is automatically freed when the state is not longer supported during atomic replace or when the livepatch gets disabled. Also the state callbacks might help to allocate the variable do do some checks before the transition starts. But it can be enabled only after all processes are transitioned. It would prevent loading the livepatch when the shadow variable could not be used and the livepatch could cause problems. + State version is replaced with "block_disable" flag. The versions are too generic and make things complicated. In practice, the main question is whether the changes introduced by the state (callbacks) can be reverted or not. The livepatch could not be disabled or downgraded when the revert (state disable) is not supported. What is done in this POC: + All changes in livepatch code are implemented. + The existing selftests are migrated [*] What is missing: + The documentation is not updated. + More selftest might be needed [**] [*] There is some mystery in a selftest when the migration gets blocked, see the comments in the 5th patch. [**] In fact, many selftests would deserve some cleanup and better split into categories. Petr Mladek (7): livepatch: Add callbacks for introducing and removing states livepatch: Allow to handle lifetime of shadow variables using the livepatch state livepatch: Use per-state callbacks in state API tests livepatch: Do not use callbacks when testing sysfs interface livepatch: Convert klp module callbacks tests into livepatch module tests livepatch: Remove the obsolete per-object callbacks livepatching: Remove per-state version Documentation/livepatch/callbacks.rst | 133 ----- Documentation/livepatch/index.rst | 1 - include/linux/livepatch.h | 75 ++- kernel/livepatch/core.c | 61 +- kernel/livepatch/core.h | 33 -- kernel/livepatch/state.c | 151 ++++- kernel/livepatch/state.h | 10 + kernel/livepatch/transition.c | 13 +- lib/livepatch/Makefile | 8 +- lib/livepatch/test_klp_callbacks_busy.c | 70 --- lib/livepatch/test_klp_callbacks_demo.c | 121 ---- lib/livepatch/test_klp_callbacks_demo2.c | 93 --- lib/livepatch/test_klp_callbacks_mod.c | 24 - lib/livepatch/test_klp_speaker.c | 185 ++++++ lib/livepatch/test_klp_speaker_livepatch.c | 253 ++++++++ lib/livepatch/test_klp_state.c | 178 ++++-- lib/livepatch/test_klp_state2.c | 190 +----- lib/livepatch/test_klp_state3.c | 2 +- samples/livepatch/Makefile | 3 - .../livepatch/livepatch-callbacks-busymod.c | 60 -- samples/livepatch/livepatch-callbacks-demo.c | 196 ------- samples/livepatch/livepatch-callbacks-mod.c | 41 -- tools/testing/selftests/livepatch/Makefile | 2 +- .../testing/selftests/livepatch/functions.sh | 46 ++ .../selftests/livepatch/test-callbacks.sh | 553 ------------------ .../selftests/livepatch/test-modules.sh | 539 +++++++++++++++++ .../testing/selftests/livepatch/test-state.sh | 80 ++- .../testing/selftests/livepatch/test-sysfs.sh | 48 +- 28 files changed, 1436 insertions(+), 1733 deletions(-) delete mode 100644 Documentation/livepatch/callbacks.rst delete mode 100644 lib/livepatch/test_klp_callbacks_busy.c delete mode 100644 lib/livepatch/test_klp_callbacks_demo.c delete mode 100644 lib/livepatch/test_klp_callbacks_demo2.c delete mode 100644 lib/livepatch/test_klp_callbacks_mod.c create mode 100644 lib/livepatch/test_klp_speaker.c create mode 100644 lib/livepatch/test_klp_speaker_livepatch.c delete mode 100644 samples/livepatch/livepatch-callbacks-busymod.c delete mode 100644 samples/livepatch/livepatch-callbacks-demo.c delete mode 100644 samples/livepatch/livepatch-callbacks-mod.c delete mode 100755 tools/testing/selftests/livepatch/test-callbacks.sh create mode 100755 tools/testing/selftests/livepatch/test-modules.sh