Xen-Devel Archive on lore.kernel.org
 help / color / Atom feed
From: Pawel Wieczorkiewicz <wipawel@amazon.de>
To: <xen-devel@lists.xen.org>, <xen-devel@lists.xenproject.org>
Cc: Pawel Wieczorkiewicz <wipawel@amazon.de>,
	wipawel@amazon.com, Ross Lagerwall <ross.lagerwall@citrix.com>,
	mpohlack@amazon.com,
	Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Subject: [Xen-devel] [PATCH 06/14] livepatch: Add support for apply|revert action replacement hooks
Date: Wed, 21 Aug 2019 08:19:23 +0000
Message-ID: <20190821081931.90887-7-wipawel@amazon.de> (raw)
In-Reply-To: <20190821081931.90887-1-wipawel@amazon.de>

By default, in the quiescing zone, a hotpatch payload is applied with
apply_payload() and reverted with revert_payload() functions. Both of
the functions receive the payload struct pointer as a parameter. The
functions are also a place where standard 'load' and 'unload' module
hooks are executed.

To increase hotpatching system's agility and provide more flexiable
long-term hotpatch solution, allow to overwrite the default apply
and revert action functions with hook-like supplied alternatives.
The alternative functions are optional and the default functions are
used by default.

Since the alternative functions have direct access to the hotpatch
payload structure, they can better control context of the 'load' and
'unload' hooks execution as well as exact instructions replacement
workflows. They can be also easily extended to support extra features
in the future.

To simplify the alternative function generation move code responsible
for payload and hotpatch region registration outside of the function.
That way it is guaranteed that the registration step occurs even for
newly supplied functions.

Signed-off-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
Reviewed-by: Petre Eftime <epetre@amazon.com>
Reviewed-by: Martin Pohlack <mpohlack@amazon.com>
Reviewed-by: Norbert Manthey <nmanthey@amazon.com>
Reviewed-by: Andra-Irina Paraschiv <andraprs@amazon.com>
Reviewed-by: Bjoern Doebel <doebel@amazon.com>
---
 xen/common/livepatch.c              | 66 +++++++++++++++++++++++++++++++------
 xen/include/xen/livepatch_payload.h | 10 ++++++
 2 files changed, 66 insertions(+), 10 deletions(-)

diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c
index 464c07ad28..38fab8b240 100644
--- a/xen/common/livepatch.c
+++ b/xen/common/livepatch.c
@@ -587,8 +587,11 @@ static int prepare_payload(struct payload *payload,
     LIVEPATCH_ASSIGN_MULTI_HOOK(elf, payload->unload_funcs, payload->n_unload_funcs, ".livepatch.hooks.unload");
 
     LIVEPATCH_ASSIGN_SINGLE_HOOK(elf, payload->hooks.apply.pre, ".livepatch.hooks.preapply");
+    LIVEPATCH_ASSIGN_SINGLE_HOOK(elf, payload->hooks.apply.action, ".livepatch.hooks.apply");
     LIVEPATCH_ASSIGN_SINGLE_HOOK(elf, payload->hooks.apply.post, ".livepatch.hooks.postapply");
+
     LIVEPATCH_ASSIGN_SINGLE_HOOK(elf, payload->hooks.revert.pre, ".livepatch.hooks.prerevert");
+    LIVEPATCH_ASSIGN_SINGLE_HOOK(elf, payload->hooks.revert.action, ".livepatch.hooks.revert");
     LIVEPATCH_ASSIGN_SINGLE_HOOK(elf, payload->hooks.revert.post, ".livepatch.hooks.postrevert");
 
     sec = livepatch_elf_sec_by_name(elf, ELF_BUILD_ID_NOTE);
@@ -1114,6 +1117,11 @@ static int apply_payload(struct payload *data)
 
     arch_livepatch_revive();
 
+    return 0;
+}
+
+static inline void apply_payload_tail(struct payload *data)
+{
     /*
      * We need RCU variant (which has barriers) in case we crash here.
      * The applied_list is iterated by the trap code.
@@ -1121,7 +1129,7 @@ static int apply_payload(struct payload *data)
     list_add_tail_rcu(&data->applied_list, &applied_list);
     register_virtual_region(&data->region);
 
-    return 0;
+    data->state = LIVEPATCH_STATE_APPLIED;
 }
 
 static int revert_payload(struct payload *data)
@@ -1154,6 +1162,11 @@ static int revert_payload(struct payload *data)
     ASSERT(!local_irq_is_enabled());
 
     arch_livepatch_revive();
+    return 0;
+}
+
+static inline void revert_payload_tail(struct payload *data)
+{
 
     /*
      * We need RCU variant (which has barriers) in case we crash here.
@@ -1163,7 +1176,7 @@ static int revert_payload(struct payload *data)
     unregister_virtual_region(&data->region);
 
     data->reverted = true;
-    return 0;
+    data->state = LIVEPATCH_STATE_CHECKED;
 }
 
 /*
@@ -1183,15 +1196,31 @@ static void livepatch_do_action(void)
     switch ( livepatch_work.cmd )
     {
     case LIVEPATCH_ACTION_APPLY:
-        rc = apply_payload(data);
+        if ( is_hook_enabled(data->hooks.apply.action) )
+        {
+            printk(XENLOG_INFO LIVEPATCH "%s: Calling apply action hook function\n", data->name);
+
+            rc = (*data->hooks.apply.action)(data);
+        }
+        else
+            rc = apply_payload(data);
+
         if ( rc == 0 )
-            data->state = LIVEPATCH_STATE_APPLIED;
+            apply_payload_tail(data);
         break;
 
     case LIVEPATCH_ACTION_REVERT:
-        rc = revert_payload(data);
+        if ( is_hook_enabled(data->hooks.revert.action) )
+        {
+            printk(XENLOG_INFO LIVEPATCH "%s: Calling revert action hook function\n", data->name);
+
+            rc = (*data->hooks.revert.action)(data);
+        }
+        else
+            rc = revert_payload(data);
+
         if ( rc == 0 )
-            data->state = LIVEPATCH_STATE_CHECKED;
+            revert_payload_tail(data);
         break;
 
     case LIVEPATCH_ACTION_REPLACE:
@@ -1202,9 +1231,18 @@ static void livepatch_do_action(void)
          */
         list_for_each_entry_safe_reverse ( other, tmp, &applied_list, applied_list )
         {
-            other->rc = revert_payload(other);
+            if ( is_hook_enabled(other->hooks.revert.action) )
+            {
+                printk(XENLOG_INFO LIVEPATCH "%s: Calling revert action hook function\n", other->name);
+
+                other->rc = (*other->hooks.revert.action)(other);
+            }
+            else
+                other->rc = revert_payload(other);
+
+
             if ( other->rc == 0 )
-                other->state = LIVEPATCH_STATE_CHECKED;
+                revert_payload_tail(other);
             else
             {
                 rc = -EINVAL;
@@ -1214,9 +1252,17 @@ static void livepatch_do_action(void)
 
         if ( rc == 0 )
         {
-            rc = apply_payload(data);
+            if ( is_hook_enabled(data->hooks.apply.action) )
+            {
+                printk(XENLOG_INFO LIVEPATCH "%s: Calling apply action hook function\n", data->name);
+
+                rc = (*data->hooks.apply.action)(data);
+            }
+            else
+                rc = apply_payload(data);
+
             if ( rc == 0 )
-                data->state = LIVEPATCH_STATE_APPLIED;
+                apply_payload_tail(data);
         }
         break;
 
diff --git a/xen/include/xen/livepatch_payload.h b/xen/include/xen/livepatch_payload.h
index cd20944cc4..ff16af0dd6 100644
--- a/xen/include/xen/livepatch_payload.h
+++ b/xen/include/xen/livepatch_payload.h
@@ -22,11 +22,13 @@ typedef void livepatch_loadcall_t(void);
 typedef void livepatch_unloadcall_t(void);
 
 typedef int livepatch_precall_t(livepatch_payload_t *arg);
+typedef int livepatch_actioncall_t(livepatch_payload_t *arg);
 typedef void livepatch_postcall_t(livepatch_payload_t *arg);
 
 struct livepatch_hooks {
     struct {
         livepatch_precall_t *const *pre;
+        livepatch_actioncall_t *const *action;
         livepatch_postcall_t *const *post;
     } apply, revert;
 };
@@ -91,6 +93,10 @@ struct payload {
     livepatch_precall_t *__attribute__((weak, used)) \
         const livepatch_preapply_data_##_fn __section(".livepatch.hooks.preapply") = _fn;
 
+#define LIVEPATCH_APPLY_HOOK(_fn) \
+    livepatch_actioncall_t *__attribute__((weak, used)) \
+        const livepatch_apply_data_##_fn __section(".livepatch.hooks.apply") = _fn;
+
 #define LIVEPATCH_POSTAPPLY_HOOK(_fn) \
     livepatch_postcall_t *__attribute__((weak, used)) \
         const livepatch_postapply_data_##_fn __section(".livepatch.hooks.postapply") = _fn;
@@ -99,6 +105,10 @@ struct payload {
     livepatch_precall_t *__attribute__((weak, used)) \
         const livepatch_prerevert_data_##_fn __section(".livepatch.hooks.prerevert") = _fn;
 
+#define LIVEPATCH_REVERT_HOOK(_fn) \
+    livepatch_actioncall_t *__attribute__((weak, used)) \
+        const livepatch_revert_data_##_fn __section(".livepatch.hooks.revert") = _fn;
+
 #define LIVEPATCH_POSTREVERT_HOOK(_fn) \
     livepatch_postcall_t *__attribute__((weak, used)) \
         const livepatch_postrevert_data_##_fn __section(".livepatch.hooks.postrevert") = _fn;
-- 
2.16.5




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Ralf Herbrich
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879




_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  parent reply index

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-21  8:19 [Xen-devel] [PATCH 00/14] livepatch: new features and fixes Pawel Wieczorkiewicz
2019-08-21  8:19 ` [Xen-devel] [PATCH 01/14] livepatch: Always check hypervisor build ID upon hotpatch upload Pawel Wieczorkiewicz
2019-08-21 18:16   ` Konrad Rzeszutek Wilk
2019-08-21  8:19 ` [Xen-devel] [PATCH 02/14] livepatch: Allow to override inter-modules buildid dependency Pawel Wieczorkiewicz
2019-08-21  8:19 ` [Xen-devel] [PATCH 03/14] python: Add XC binding for Xen build ID Pawel Wieczorkiewicz
2019-08-21  8:19 ` [Xen-devel] [PATCH 04/14] livepatch: Export payload structure via livepatch_payload.h Pawel Wieczorkiewicz
2019-08-21  8:19 ` [Xen-devel] [PATCH 05/14] livepatch: Implement pre-|post- apply|revert hooks Pawel Wieczorkiewicz
2019-08-21  8:19 ` Pawel Wieczorkiewicz [this message]
2019-08-21 18:31   ` [Xen-devel] [PATCH 06/14] livepatch: Add support for apply|revert action replacement hooks Konrad Rzeszutek Wilk
2019-08-21 19:06     ` Wieczorkiewicz, Pawel
2019-08-26 14:30       ` Konrad Rzeszutek Wilk
2019-08-21  8:19 ` [Xen-devel] [PATCH 07/14] livepatch: Do not enforce ELF_LIVEPATCH_FUNC section presence Pawel Wieczorkiewicz
2019-08-21  8:19 ` [Xen-devel] [PATCH 08/14] livepatch: always print XENLOG_ERR information Pawel Wieczorkiewicz
2019-08-21  8:19 ` [Xen-devel] [PATCH 09/14] livepatch: Add per-function applied/reverted state tracking marker Pawel Wieczorkiewicz
2019-08-21 18:28   ` Konrad Rzeszutek Wilk
2019-08-21 19:00     ` Wieczorkiewicz, Pawel
2019-08-21 21:34   ` Julien Grall
2019-08-22  7:44     ` Wieczorkiewicz, Pawel
2019-08-22 10:07       ` Julien Grall
2019-08-22 10:20         ` Wieczorkiewicz, Pawel
2019-08-22 10:43           ` Julien Grall
2019-08-22 11:15             ` Wieczorkiewicz, Pawel
2019-08-22 15:02               ` Julien Grall
2019-08-22 10:29   ` Julien Grall
2019-08-22 11:02     ` Wieczorkiewicz, Pawel
2019-08-22 15:30       ` Julien Grall
2019-08-22 15:42         ` Wieczorkiewicz, Pawel
2019-08-21  8:19 ` [Xen-devel] [PATCH 10/14] livepatch: Add support for inline asm hotpatching expectations Pawel Wieczorkiewicz
2019-08-21 18:30   ` Konrad Rzeszutek Wilk
2019-08-21 19:02     ` Wieczorkiewicz, Pawel
2019-08-22 10:31   ` Julien Grall
2019-08-22 11:03     ` Wieczorkiewicz, Pawel
2019-08-21  8:19 ` [Xen-devel] [PATCH 11/14] livepatch: Add support for modules .modinfo section metadata Pawel Wieczorkiewicz
2019-08-21  8:19 ` [Xen-devel] [PATCH 12/14] livepatch: Handle arbitrary size names with the list operation Pawel Wieczorkiewicz
2019-08-21  8:19 ` [Xen-devel] [PATCH 13/14] livepatch: Add metadata runtime retrieval mechanism Pawel Wieczorkiewicz
2019-08-21  8:19 ` [Xen-devel] [PATCH 14/14] livepatch: Add python bindings for livepatch operations Pawel Wieczorkiewicz
2019-08-22 21:55   ` Marek Marczykowski-Górecki
2019-08-27  8:46 ` [Xen-devel] [PATCH v2 00/12] livepatch: new features and fixes Pawel Wieczorkiewicz
2019-08-27  8:46   ` [Xen-devel] [PATCH v2 01/12] livepatch: Always check hypervisor build ID upon hotpatch upload Pawel Wieczorkiewicz
2019-08-27  8:46   ` [Xen-devel] [PATCH v2 02/12] livepatch: Allow to override inter-modules buildid dependency Pawel Wieczorkiewicz
2019-08-27  8:46   ` [Xen-devel] [PATCH v2 03/12] livepatch: Export payload structure via livepatch_payload.h Pawel Wieczorkiewicz
2019-08-27  8:46   ` [Xen-devel] [PATCH v2 04/12] livepatch: Implement pre-|post- apply|revert hooks Pawel Wieczorkiewicz
2019-08-27  8:46   ` [Xen-devel] [PATCH v2 05/12] livepatch: Add support for apply|revert action replacement hooks Pawel Wieczorkiewicz
2019-08-27 16:58     ` Konrad Rzeszutek Wilk
2019-08-28  7:37       ` Wieczorkiewicz, Pawel
2019-08-27  8:46   ` [Xen-devel] [PATCH v2 06/12] livepatch: Do not enforce ELF_LIVEPATCH_FUNC section presence Pawel Wieczorkiewicz
2019-08-27  8:46   ` [Xen-devel] [PATCH v2 07/12] livepatch: Add per-function applied/reverted state tracking marker Pawel Wieczorkiewicz
2019-08-27  8:46   ` [Xen-devel] [PATCH v2 08/12] livepatch: Add support for inline asm hotpatching expectations Pawel Wieczorkiewicz
2019-08-29 14:34     ` Konrad Rzeszutek Wilk
2019-08-29 15:29       ` Wieczorkiewicz, Pawel
2019-08-29 15:58     ` Konrad Rzeszutek Wilk
2019-08-29 16:16       ` Wieczorkiewicz, Pawel
2019-08-29 17:49         ` Konrad Rzeszutek Wilk
2019-08-29 19:07           ` Wieczorkiewicz, Pawel
2019-08-29 20:48             ` Konrad Rzeszutek Wilk
2019-09-05 18:05     ` Konrad Rzeszutek Wilk
2019-08-27  8:46   ` [Xen-devel] [PATCH v2 09/12] livepatch: Add support for modules .modinfo section metadata Pawel Wieczorkiewicz
2019-08-27  8:46   ` [Xen-devel] [PATCH v2 10/12] livepatch: Handle arbitrary size names with the list operation Pawel Wieczorkiewicz
2019-08-27  8:46   ` [Xen-devel] [PATCH v2 11/12] livepatch: Add metadata runtime retrieval mechanism Pawel Wieczorkiewicz
2019-08-29 20:48     ` Konrad Rzeszutek Wilk
2019-08-27  8:46   ` [Xen-devel] [PATCH v2 12/12] livepatch: Add python bindings for livepatch operations Pawel Wieczorkiewicz
2019-08-28 13:21     ` Marek Marczykowski-Górecki
2019-08-29 19:23   ` [Xen-devel] [PATCH v2 00/12] livepatch: new features and fixes Konrad Rzeszutek Wilk
2019-09-05 19:13   ` Konrad Rzeszutek Wilk
2019-09-06 22:52     ` Julien Grall
2019-09-06 22:42   ` Julien Grall

Reply instructions:

You may reply publically to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190821081931.90887-7-wipawel@amazon.de \
    --to=wipawel@amazon.de \
    --cc=konrad.wilk@oracle.com \
    --cc=mpohlack@amazon.com \
    --cc=ross.lagerwall@citrix.com \
    --cc=wipawel@amazon.com \
    --cc=xen-devel@lists.xen.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Xen-Devel Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/xen-devel/0 xen-devel/git/0.git
	git clone --mirror https://lore.kernel.org/xen-devel/1 xen-devel/git/1.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 xen-devel xen-devel/ https://lore.kernel.org/xen-devel \
		xen-devel@lists.xenproject.org xen-devel@lists.xen.org
	public-inbox-index xen-devel

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.xenproject.lists.xen-devel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git