Received: by 10.223.164.202 with SMTP id h10csp6308651wrb; Wed, 22 Nov 2017 02:31:39 -0800 (PST) X-Google-Smtp-Source: AGs4zMY/OyoRsMm1BaHBouBo6CYoU583YvQ59j+BSNROQJQQjfxxF7LbTCFaLlxYEQ/IH2OjLZnl X-Received: by 10.99.134.73 with SMTP id x70mr20632921pgd.130.1511346699262; Wed, 22 Nov 2017 02:31:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1511346699; cv=none; d=google.com; s=arc-20160816; b=k1XwIX8QDcCCplSKMhFzxrM6TrWoW5r6uC5GXHEbY3ndFDK6geNi+RHPsLc7wE2gss EVqgiUQmTOXXVeRZNJFnewCwhWwPEEJ3bTU7IRC8ATaEleNsbNVwLjUN/DEwpWxEImO/ 1tuUrurgXckQdQBphgszABd5OE3TfTeAIz5hoAIpOYewlI8/3iMPf3O2meM7JM9tjtzN 3N0c//1r9XNbDk4GI9v0V/54T5zgn7QGTVkcd5f3wxVHLo23P+2Jq0oLrmO7eYJ8giy5 UXnyQhVKujqFiToHuROS+fl1SeffhkeTuNQSqw0LXxBEAfv6/VplWff4ujhhP9YdKPDB sktg== 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:arc-authentication-results; bh=9AbkGZ6lt6ogVUZpy0Zsz6av/b2ezCZx4B83RUcCNMc=; b=fJD/4hXe1dCfPjt59sccPA5PElrHOdAeIBQ9dB2CCz7am3oaLA2O/+Eu6UMDh2kIuF 8OxDJAfk5IQ0Q9yqJhvDKZmFQdK8Nf7g6OgzNBru73Q5hFTcE5SsXScg22/iEuyXrnqh K2Yoy/LdyfaPWt9zGUGC6kKP3YagVhYflaq+23udrkfoeX8uk9uMwrfhXex1Tii97Gia N1fSUX637ddRMQ+SX/QA4uGN2wXkii61JEqQir1L5HP/ctaQQ3lukJQ+WUrZFeNLLwqN L4WmCTVR3b3oN9810DmjBFlJn/DmBLZR17hjklfoGKgszhYCwMMQK4wlRSUvOcFEIraJ 9Kzg== 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 91si13169040ply.129.2017.11.22.02.31.28; Wed, 22 Nov 2017 02:31:39 -0800 (PST) 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 S1753322AbdKVK31 (ORCPT + 76 others); Wed, 22 Nov 2017 05:29:27 -0500 Received: from mx2.suse.de ([195.135.220.15]:47579 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753214AbdKVK3Z (ORCPT ); Wed, 22 Nov 2017 05:29:25 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 3A17AAAB5; Wed, 22 Nov 2017 10:29:24 +0000 (UTC) From: Miroslav Benes To: jpoimboe@redhat.com, jeyu@kernel.org, jikos@kernel.org Cc: pmladek@suse.com, lpechacek@suse.cz, pavel@ucw.cz, live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, Miroslav Benes Subject: [PATCH v4.1 2/2] livepatch: force transition to finish Date: Wed, 22 Nov 2017 11:29:21 +0100 Message-Id: <20171122102921.12289-1-mbenes@suse.cz> X-Mailer: git-send-email 2.15.0 In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org If a task sleeps in a set of patched functions uninterruptedly, it could block the whole transition indefinitely. Thus it may be useful to clear its TIF_PATCH_PENDING to allow the process to finish. Admin can do that now by writing to force sysfs attribute in livepatch sysfs directory. TIF_PATCH_PENDING is then cleared for all tasks and the transition can finish successfully. Important note! Administrator should not use this feature without a clearance from a patch distributor. It must be checked that by doing so the consistency model guarantees are not violated. Removal (rmmod) of patch modules is permanently disabled when the feature is used. It cannot be guaranteed there is no task sleeping in such module. Signed-off-by: Miroslav Benes Acked-by: Josh Poimboeuf Reviewed-by: Petr Mladek --- Documentation/ABI/testing/sysfs-kernel-livepatch | 14 ++++++++++ Documentation/livepatch/livepatch.txt | 18 ++++++++++-- kernel/livepatch/core.c | 30 ++++++++++++++++++++ kernel/livepatch/transition.c | 35 +++++++++++++++++++++++- kernel/livepatch/transition.h | 1 + 5 files changed, 95 insertions(+), 3 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-kernel-livepatch b/Documentation/ABI/testing/sysfs-kernel-livepatch index 3bb9d5bc1ce3..dac7e1e62a8b 100644 --- a/Documentation/ABI/testing/sysfs-kernel-livepatch +++ b/Documentation/ABI/testing/sysfs-kernel-livepatch @@ -45,6 +45,20 @@ Contact: live-patching@vger.kernel.org signal pending structures). Tasks are interrupted or woken up, and forced to change their patched state. +What: /sys/kernel/livepatch//force +Date: Nov 2017 +KernelVersion: 4.15.0 +Contact: live-patching@vger.kernel.org +Description: + A writable attribute that allows administrator to affect the + course of an existing transition. Writing 1 clears + TIF_PATCH_PENDING flag of all tasks and thus forces the tasks to + the patched or unpatched state. Administrator should not + use this feature without a clearance from a patch + distributor. Removal (rmmod) of patch modules is permanently + disabled when the feature is used. See + Documentation/livepatch/livepatch.txt for more information. + What: /sys/kernel/livepatch// Date: Nov 2014 KernelVersion: 3.19.0 diff --git a/Documentation/livepatch/livepatch.txt b/Documentation/livepatch/livepatch.txt index 9bcdef277a36..896ba8941702 100644 --- a/Documentation/livepatch/livepatch.txt +++ b/Documentation/livepatch/livepatch.txt @@ -183,6 +183,20 @@ tasks. No proper signal is actually delivered (there is no data in signal pending structures). Tasks are interrupted or woken up, and forced to change their patched state. +Administrator can also affect a transition through +/sys/kernel/livepatch//force attribute. Writing 1 there clears +TIF_PATCH_PENDING flag of all tasks and thus forces the tasks to the patched +state. Important note! The force attribute is intended for cases when the +transition gets stuck for a long time because of a blocking task. Administrator +is expected to collect all necessary data (namely stack traces of such blocking +tasks) and request a clearance from a patch distributor to force the transition. +Unauthorized usage may cause harm to the system. It depends on the nature of the +patch, which functions are (un)patched, and which functions the blocking tasks +are sleeping in (/proc//stack may help here). Removal (rmmod) of patch +modules is permanently disabled when the force feature is used. It cannot be +guaranteed there is no task sleeping in such module. It implies unbounded +reference count if a patch module is disabled and enabled in a loop. + 3.1 Adding consistency model support to new architectures --------------------------------------------------------- @@ -439,8 +453,8 @@ Information about the registered patches can be found under /sys/kernel/livepatch. The patches could be enabled and disabled by writing there. -/sys/kernel/livepatch//signal attribute allows administrator to affect a -patching operation. +/sys/kernel/livepatch//signal and /sys/kernel/livepatch//force +attributes allow administrator to affect a patching operation. See Documentation/ABI/testing/sysfs-kernel-livepatch for more details. diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index e772be452462..c19c6c32c47e 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -441,6 +441,7 @@ EXPORT_SYMBOL_GPL(klp_enable_patch); * /sys/kernel/livepatch//enabled * /sys/kernel/livepatch//transition * /sys/kernel/livepatch//signal + * /sys/kernel/livepatch//force * /sys/kernel/livepatch// * /sys/kernel/livepatch/// */ @@ -542,13 +543,42 @@ static ssize_t signal_store(struct kobject *kobj, struct kobj_attribute *attr, return count; } +static ssize_t force_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + struct klp_patch *patch; + int ret; + bool val; + + patch = container_of(kobj, struct klp_patch, kobj); + + /* + * klp_mutex lock is not grabbed here intentionally. It is not really + * needed. The race window is harmless and grabbing the lock would only + * hold the action back. + */ + if (patch != klp_transition_patch) + return -EINVAL; + + ret = kstrtobool(buf, &val); + if (ret) + return ret; + + if (val) + klp_force_transition(); + + return count; +} + static struct kobj_attribute enabled_kobj_attr = __ATTR_RW(enabled); static struct kobj_attribute transition_kobj_attr = __ATTR_RO(transition); static struct kobj_attribute signal_kobj_attr = __ATTR_WO(signal); +static struct kobj_attribute force_kobj_attr = __ATTR_WO(force); static struct attribute *klp_patch_attrs[] = { &enabled_kobj_attr.attr, &transition_kobj_attr.attr, &signal_kobj_attr.attr, + &force_kobj_attr.attr, NULL }; diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c index 095aa8d864f5..abdb15e24b20 100644 --- a/kernel/livepatch/transition.c +++ b/kernel/livepatch/transition.c @@ -33,6 +33,8 @@ struct klp_patch *klp_transition_patch; static int klp_target_state = KLP_UNDEFINED; +static bool klp_forced = false; + /* * This work can be performed periodically to finish patching or unpatching any * "straggler" tasks which failed to transition in the first attempt. @@ -109,7 +111,11 @@ static void klp_complete_transition(void) } } - if (klp_target_state == KLP_UNPATCHED && !immediate_func) + /* + * klp_forced or immediate_func set implies unbounded increase of + * module's ref count if the module is disabled/enabled in a loop. + */ + if (klp_target_state == KLP_UNPATCHED && !klp_forced && !immediate_func) module_put(klp_transition_patch->mod); /* Prevent klp_ftrace_handler() from seeing KLP_UNDEFINED state */ @@ -618,3 +624,30 @@ void klp_send_signals(void) } read_unlock(&tasklist_lock); } + +/* + * Drop TIF_PATCH_PENDING of all tasks on admin's request. This forces an + * existing transition to finish. + * + * NOTE: klp_update_patch_state(task) requires the task to be inactive or + * 'current'. This is not the case here and the consistency model could be + * broken. Administrator, who is the only one to execute the + * klp_force_transitions(), has to be aware of this. + */ +void klp_force_transition(void) +{ + struct task_struct *g, *task; + unsigned int cpu; + + pr_warn("forcing remaining tasks to the patched state\n"); + + read_lock(&tasklist_lock); + for_each_process_thread(g, task) + klp_update_patch_state(task); + read_unlock(&tasklist_lock); + + for_each_possible_cpu(cpu) + klp_update_patch_state(idle_task(cpu)); + + klp_forced = true; +} diff --git a/kernel/livepatch/transition.h b/kernel/livepatch/transition.h index 47c335f7c04c..837e51ee30fd 100644 --- a/kernel/livepatch/transition.h +++ b/kernel/livepatch/transition.h @@ -11,5 +11,6 @@ void klp_start_transition(void); void klp_try_complete_transition(void); void klp_reverse_transition(void); void klp_send_signals(void); +void klp_force_transition(void); #endif /* _LIVEPATCH_TRANSITION_H */ -- 2.15.0 From 1584669647469728099@xxx Tue Nov 21 10:05:42 +0000 2017 X-GM-THRID: 1584140406062067527 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread