Received: by 2002:a25:824b:0:0:0:0:0 with SMTP id d11csp94740ybn; Thu, 3 Oct 2019 02:04:14 -0700 (PDT) X-Google-Smtp-Source: APXvYqxhjuI85O+asIHxLG+32xe7hg731qNfrQX+7YppRKgfAnXHFduOdkTvbFuNhPHTnxGtnwQX X-Received: by 2002:a17:906:ce46:: with SMTP id se6mr6750732ejb.198.1570093454413; Thu, 03 Oct 2019 02:04:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1570093454; cv=none; d=google.com; s=arc-20160816; b=PlD4A8b3P0vPXvzMG7lBoZbGGL6ma1Lqt4t5Z6sID7sawMal5TcQGeXAuoQDocroUh /QRA7L3Z11pu+SRoO5KmOm13WRmWkjxa8AzsfuvhRj5ttn5hiTje91KCnCKm24gEVs9L N3l4ps2ES4FKr4R2B9457pV5wmhagHbYmODyNVZFld26sLgX2iXDmNZ9wKxx8/sircs8 ZLRqLbnViOkj4TIP69EFnQuKSutlE53//JBKIsQc7p7ZS+qiVaUNAQfYOXH4VOqhCXPK Qa4+H9XW5BrvLM9XxrjKqWBqtYf4rGACVAwEdKsArxLlKha6vLeXgJC+l1yow5nqpGe0 mWZA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=JOy2yXqH+vQ/SRAjxLSUfnheEb+bfenDlPnzAYLd82I=; b=nnLheGco6yOrNxNgVdJk1jBntZweuYNvugAgVRiJThjRmG1NsAkAr3fcOi2bcN4MHX kzADeV6HZ9j9zvyV//rvO3Vwt5L1ZhMCedH8yQ8Due+6chz/cBbn74w8AhjdvHWcQg/E TkW5otEp65pnUYmetj093EdUwNEAewOMe+fQeeoPKlF5hEWRI4pGiZNw5qsgkYW46Er0 P/9ZZR6MZ4gBwMf9GbI8ZqMBnInW+2yX0AvpthEPRxSaV6SgKrGmkudXiPfFqm5kkPnz ohkJyqsR7/i3MCcNl4K9YtyiZL0SvDU+WPX544JyGVU+0oz9CMGQAiHPH1+WK+Txqa7H +mIQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y19si884533ejp.196.2019.10.03.02.03.49; Thu, 03 Oct 2019 02:04:14 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729145AbfJCJCH (ORCPT + 99 others); Thu, 3 Oct 2019 05:02:07 -0400 Received: from mx2.suse.de ([195.135.220.15]:50358 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729021AbfJCJCB (ORCPT ); Thu, 3 Oct 2019 05:02:01 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 75BA2B147; Thu, 3 Oct 2019 09:01:58 +0000 (UTC) From: Petr Mladek To: Jiri Kosina , Josh Poimboeuf , Miroslav Benes Cc: Joe Lawrence , Kamalesh Babulal , Nicolai Stange , live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, Petr Mladek Subject: [PATCH v3 4/5] livepatch: Documentation of the new API for tracking system state changes Date: Thu, 3 Oct 2019 11:01:36 +0200 Message-Id: <20191003090137.6874-5-pmladek@suse.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20191003090137.6874-1-pmladek@suse.com> References: <20191003090137.6874-1-pmladek@suse.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Documentation explaining the motivation, capabilities, and usage of the new API for tracking system state changes. Signed-off-by: Petr Mladek Acked-by: Miroslav Benes --- Documentation/livepatch/index.rst | 1 + Documentation/livepatch/system-state.rst | 167 +++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 Documentation/livepatch/system-state.rst diff --git a/Documentation/livepatch/index.rst b/Documentation/livepatch/index.rst index 17674a9e21b2..525944063be7 100644 --- a/Documentation/livepatch/index.rst +++ b/Documentation/livepatch/index.rst @@ -12,6 +12,7 @@ Kernel Livepatching cumulative-patches module-elf-format shadow-vars + system-state .. only:: subproject and html diff --git a/Documentation/livepatch/system-state.rst b/Documentation/livepatch/system-state.rst new file mode 100644 index 000000000000..56a3f4d16e8b --- /dev/null +++ b/Documentation/livepatch/system-state.rst @@ -0,0 +1,167 @@ +==================== +System State Changes +==================== + +Some users are really reluctant to reboot a system. This brings the need +to provide more livepatches and maintain some compatibility between them. + +Maintaining more livepatches is much easier with cumulative livepatches. +Each new livepatch completely replaces any older one. It can keep, +add, and even remove fixes. And it is typically safe to replace any version +of the livepatch with any other one thanks to the atomic replace feature. + +The problems might come with shadow variables and callbacks. They might +change the system behavior or state so that it is no longer safe to +go back and use an older livepatch or the original kernel code. Also +any new livepatch must be able to detect what changes have already been +done by the already installed livepatches. + +This is where the livepatch system state tracking gets useful. It +allows to: + + - store data needed to manipulate and restore the system state + + - define compatibility between livepatches using a change id + and version + + +1. Livepatch system state API +============================= + +The state of the system might get modified either by several livepatch callbacks +or by the newly used code. Also it must be possible to find changes done by +already installed livepatches. + +Each modified state is described by struct klp_state, see +include/linux/livepatch.h. + +Each livepatch defines an array of struct klp_states. They mention +all states that the livepatch modifies. + +The livepatch author must define the following two fields for each +struct klp_state: + + - *id* + + - Non-zero number used to identify the affected system state. + + - *version* + + - Number describing the variant of the system state change that + is supported by the given livepatch. + +The state can be manipulated using two functions: + + - *klp_get_state(patch, id)* + + - Get struct klp_state associated with the given livepatch + and state id. + + - *klp_get_prev_state(id)* + + - Get struct klp_state associated with the given feature id and + already installed livepatches. + +2. Livepatch compatibility +========================== + +The system state version is used to prevent loading incompatible livepatches. +The check is done when the livepatch is enabled. The rules are: + + - Any completely new system state modification is allowed. + + - System state modifications with the same or higher version are allowed + for already modified system states. + + - Cumulative livepatches must handle all system state modifications from + already installed livepatches. + + - Non-cumulative livepatches are allowed to touch already modified + system states. + +3. Supported scenarios +====================== + +Livepatches have their life-cycle and the same is true for the system +state changes. Every compatible livepatch has to support the following +scenarios: + + - Modify the system state when the livepatch gets enabled and the state + has not been already modified by a livepatches that are being + replaced. + + - Take over or update the system state modification when is has already + been done by a livepatch that is being replaced. + + - Restore the original state when the livepatch is disabled. + + - Restore the previous state when the transition is reverted. + It might be the orignal system state or the state modification + done by livepatches that were being replaced. + + - Remove any already made changes when error occurs and the livepatch + cannot get enabled. + +4. Expected usage +================= + +System states are usually modified by livepatch callbacks. The expected +role of each callback is as follows: + +*pre_patch()* + + - Allocate *state->data* when necessary. The allocation might fail + and *pre_patch()* is the only callback that could stop loading + of the livepatch. The allocation is not needed when the data + are already provided by previously installed livepatches. + + - Do any other preparatory action that is needed by + the new code even before the transition gets finished. + For example, initialize *state->data*. + + The system state itself is typically modified in *post_patch()* + when the entire system is able to handle it. + + - Clean up its own mess in case of error. It might be done by a custom + code or by calling *post_unpatch()* explicitly. + +*post_patch()* + + - Copy *state->data* from the previous livepatch when they are + compatible. + + - Do the actual system state modification. Eventually allow + the new code to use it. + + - Make sure that *state->data* has all necessary information. + + - Free *state->data* from replaces livepatches when they are + not longer needed. + +*pre_unpatch()* + + - Prevent the code, added by the livepatch, relying on the system + state change. + + - Revert the system state modification.. + +*post_unpatch()* + + - Distinguish transition reverse and livepatch disabling by + checking *klp_get_prev_state()*. + + - In case of transition reverse, restore the previous system + state. It might mean doing nothing. + + - Remove any not longer needed setting or data. + +.. note:: + + *pre_unpatch()* typically does symmetric operations to *post_patch()*. + Except that it is called only when the livepatch is being disabled. + Therefore it does not need to care about any previously installed + livepatch. + + *post_unpatch()* typically does symmetric operations to *pre_patch()*. + It might be called also during the transition reverse. Therefore it + has to handle the state of the previously installed livepatches. -- 2.16.4