When restoring an incoming block set via kho_block_set_restore(), the physical chain of blocks is already linked and bs->head_pa is already set. However, kho_block_add() unconditionally rewrites last->ser->next and bs->head_pa, and kho_block_set_shrink_one() clears new_last->ser->next even when operating on an incoming block set.
In the upcoming KHO read-only mode, incoming serialized blocks are mapped read-only and must not be modified. Guard the ser->next and bs->head_pa updates in kho_block_add() and kho_block_set_shrink_one() with !bs->incoming. Signed-off-by: Pasha Tatashin <[email protected]> --- kernel/liveupdate/kho_block.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/kernel/liveupdate/kho_block.c b/kernel/liveupdate/kho_block.c index 0d2a342ef422..a4e945f28fad 100644 --- a/kernel/liveupdate/kho_block.c +++ b/kernel/liveupdate/kho_block.c @@ -93,10 +93,12 @@ static int kho_block_add(struct kho_block_set *bs, list_add_tail(&block->list, &bs->blocks); bs->nblocks++; - if (last) - last->ser->next = virt_to_phys(ser); - else - bs->head_pa = virt_to_phys(ser); + if (!bs->incoming) { + if (last) + last->ser->next = virt_to_phys(ser); + else + bs->head_pa = virt_to_phys(ser); + } return 0; } @@ -133,10 +135,10 @@ static void kho_block_set_shrink_one(struct kho_block_set *bs) kfree(last); new_last = list_last_entry_or_null(&bs->blocks, struct kho_block, list); - if (new_last) - new_last->ser->next = 0; - else + if (!new_last) bs->head_pa = 0; + else if (!bs->incoming) + new_last->ser->next = 0; } /** -- 2.56.0.176.g3575e65682-goog

