[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen staging] xen/livepatch: search for symbols in all loaded payloads
commit d2daa40fb3ddb8f83e238e57854bd878924cde90 Author: Roger Pau Monné <roger.pau@xxxxxxxxxx> AuthorDate: Tue Feb 27 12:25:25 2024 +0100 Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CommitDate: Wed Feb 28 16:57:25 2024 +0000 xen/livepatch: search for symbols in all loaded payloads 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@xxxxxxxxxx> Reviewed-by: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx> --- 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 d7f50e1018..14295bae87 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 is_patch(const void *ptr) const struct payload *data; bool r = false; - /* - * 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 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; } @@ -1072,7 +1065,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); @@ -1172,7 +1166,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++; } @@ -1383,11 +1377,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; } @@ -1427,12 +1417,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; -- generated by git-patchbot for /home/xen/git/xen.git#staging
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |