* 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;
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)) ||
}
}
- rcu_read_unlock(&rcu_applied_lock);
+ rcu_read_unlock(&rcu_payload_lock);
return r;
}
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) )
n = data->symtab[best].name;
break;
}
- rcu_read_unlock(&rcu_applied_lock);
+ rcu_read_unlock(&rcu_payload_lock);
return n;
}
{
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);
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++;
}
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;
}
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;