diff options
author | 2024-04-05 08:59:40 +0200 | |
---|---|---|
committer | 2024-04-05 08:59:40 +0200 | |
commit | d0ce95087288b30e5e211bac8e9a0817f2effcf5 (patch) | |
tree | ce2e128cfdf8d491a494d6583979bc5330db21e2 /0031-xen-livepatch-search-for-symbols-in-all-loaded-paylo.patch | |
parent | Xen 4.17.4-pre-patchset-0 (diff) | |
download | xen-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.patch | 149 |
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 + |