summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomáš Mózes <hydrapolic@gmail.com>2024-04-05 08:59:40 +0200
committerTomáš Mózes <hydrapolic@gmail.com>2024-04-05 08:59:40 +0200
commitd0ce95087288b30e5e211bac8e9a0817f2effcf5 (patch)
treece2e128cfdf8d491a494d6583979bc5330db21e2 /0031-xen-livepatch-search-for-symbols-in-all-loaded-paylo.patch
parentXen 4.17.4-pre-patchset-0 (diff)
downloadxen-upstream-patches-d0ce95087288b30e5e211bac8e9a0817f2effcf5.tar.gz
xen-upstream-patches-d0ce95087288b30e5e211bac8e9a0817f2effcf5.tar.bz2
xen-upstream-patches-d0ce95087288b30e5e211bac8e9a0817f2effcf5.zip
Xen 4.17.4-pre-patchset-14.17.4-pre-patchset-14.17
Signed-off-by: Tomáš Mózes <hydrapolic@gmail.com>
Diffstat (limited to '0031-xen-livepatch-search-for-symbols-in-all-loaded-paylo.patch')
-rw-r--r--0031-xen-livepatch-search-for-symbols-in-all-loaded-paylo.patch149
1 files changed, 149 insertions, 0 deletions
diff --git a/0031-xen-livepatch-search-for-symbols-in-all-loaded-paylo.patch b/0031-xen-livepatch-search-for-symbols-in-all-loaded-paylo.patch
new file mode 100644
index 0000000..c778639
--- /dev/null
+++ b/0031-xen-livepatch-search-for-symbols-in-all-loaded-paylo.patch
@@ -0,0 +1,149 @@
+From c54cf903b06fb1933fad053cc547580c92c856ea Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= <roger.pau@citrix.com>
+Date: Tue, 5 Mar 2024 11:59:35 +0100
+Subject: [PATCH 31/67] xen/livepatch: search for symbols in all loaded
+ payloads
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When checking if an address belongs to a patch, or when resolving a symbol,
+take into account all loaded livepatch payloads, even if not applied.
+
+This is required in order for the pre-apply and post-revert hooks to work
+properly, or else Xen won't detect the instruction pointer belonging to those
+hooks as being part of the currently active text.
+
+Move the RCU handling to be used for payload_list instead of applied_list, as
+now the calls from trap code will iterate over the payload_list.
+
+Fixes: 8313c864fa95 ('livepatch: Implement pre-|post- apply|revert hooks')
+Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
+Reviewed-by: Ross Lagerwall <ross.lagerwall@citrix.com>
+master commit: d2daa40fb3ddb8f83e238e57854bd878924cde90
+master date: 2024-02-28 16:57:25 +0000
+---
+ xen/common/livepatch.c | 49 +++++++++++++++---------------------------
+ 1 file changed, 17 insertions(+), 32 deletions(-)
+
+diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c
+index 537e9f33e4..a129ab9973 100644
+--- a/xen/common/livepatch.c
++++ b/xen/common/livepatch.c
+@@ -36,13 +36,14 @@
+ * caller in schedule_work.
+ */
+ static DEFINE_SPINLOCK(payload_lock);
+-static LIST_HEAD(payload_list);
+-
+ /*
+- * Patches which have been applied. Need RCU in case we crash (and then
+- * traps code would iterate via applied_list) when adding entries on the list.
++ * Need RCU in case we crash (and then traps code would iterate via
++ * payload_list) when adding entries on the list.
+ */
+-static DEFINE_RCU_READ_LOCK(rcu_applied_lock);
++static DEFINE_RCU_READ_LOCK(rcu_payload_lock);
++static LIST_HEAD(payload_list);
++
++/* Patches which have been applied. Only modified from stop machine context. */
+ static LIST_HEAD(applied_list);
+
+ static unsigned int payload_cnt;
+@@ -111,12 +112,8 @@ bool_t is_patch(const void *ptr)
+ const struct payload *data;
+ bool_t r = 0;
+
+- /*
+- * Only RCU locking since this list is only ever changed during apply
+- * or revert context. And in case it dies there we need an safe list.
+- */
+- rcu_read_lock(&rcu_applied_lock);
+- list_for_each_entry_rcu ( data, &applied_list, applied_list )
++ rcu_read_lock(&rcu_payload_lock);
++ list_for_each_entry_rcu ( data, &payload_list, list )
+ {
+ if ( (ptr >= data->rw_addr &&
+ ptr < (data->rw_addr + data->rw_size)) ||
+@@ -130,7 +127,7 @@ bool_t is_patch(const void *ptr)
+ }
+
+ }
+- rcu_read_unlock(&rcu_applied_lock);
++ rcu_read_unlock(&rcu_payload_lock);
+
+ return r;
+ }
+@@ -166,12 +163,8 @@ static const char *cf_check livepatch_symbols_lookup(
+ const void *va = (const void *)addr;
+ const char *n = NULL;
+
+- /*
+- * Only RCU locking since this list is only ever changed during apply
+- * or revert context. And in case it dies there we need an safe list.
+- */
+- rcu_read_lock(&rcu_applied_lock);
+- list_for_each_entry_rcu ( data, &applied_list, applied_list )
++ rcu_read_lock(&rcu_payload_lock);
++ list_for_each_entry_rcu ( data, &payload_list, list )
+ {
+ if ( va < data->text_addr ||
+ va >= (data->text_addr + data->text_size) )
+@@ -200,7 +193,7 @@ static const char *cf_check livepatch_symbols_lookup(
+ n = data->symtab[best].name;
+ break;
+ }
+- rcu_read_unlock(&rcu_applied_lock);
++ rcu_read_unlock(&rcu_payload_lock);
+
+ return n;
+ }
+@@ -1016,7 +1009,8 @@ static void free_payload(struct payload *data)
+ {
+ ASSERT(spin_is_locked(&payload_lock));
+ unregister_virtual_region(&data->region);
+- list_del(&data->list);
++ list_del_rcu(&data->list);
++ rcu_barrier();
+ payload_cnt--;
+ payload_version++;
+ free_payload_data(data);
+@@ -1116,7 +1110,7 @@ static int livepatch_upload(struct xen_sysctl_livepatch_upload *upload)
+ INIT_LIST_HEAD(&data->applied_list);
+
+ register_virtual_region(&data->region);
+- list_add_tail(&data->list, &payload_list);
++ list_add_tail_rcu(&data->list, &payload_list);
+ payload_cnt++;
+ payload_version++;
+ }
+@@ -1327,11 +1321,7 @@ static int apply_payload(struct payload *data)
+
+ 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.
+- */
+- list_add_tail_rcu(&data->applied_list, &applied_list);
++ list_add_tail(&data->applied_list, &applied_list);
+
+ data->state = LIVEPATCH_STATE_APPLIED;
+ }
+@@ -1371,12 +1361,7 @@ static int revert_payload(struct payload *data)
+
+ static inline void revert_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.
+- */
+- list_del_rcu(&data->applied_list);
++ list_del(&data->applied_list);
+
+ data->reverted = true;
+ data->state = LIVEPATCH_STATE_CHECKED;
+--
+2.44.0
+