From b7b8fdaa13f8702a6e98148d0ff007e6e8347ea2 Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Thu, 18 Jan 2018 19:09:30 +0200 Subject: 8973 efi_copy_finish() fails to pick the next item from the list Reviewed by: Alexander Eremin Reviewed by: Yuri Pankov Approved by: Dan McDonald --- usr/src/boot/sys/boot/efi/loader/copy.c | 37 ++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/usr/src/boot/sys/boot/efi/loader/copy.c b/usr/src/boot/sys/boot/efi/loader/copy.c index a091d70484..a4f44bc072 100644 --- a/usr/src/boot/sys/boot/efi/loader/copy.c +++ b/usr/src/boot/sys/boot/efi/loader/copy.c @@ -137,8 +137,7 @@ efi_copy_finish(struct relocator *relocator) multiboot2_info_header_t *mbi; struct chunk *chunk, *c; struct chunk_head *head; - UINT64 size; - int done = 0; + bool done = false; void (*move)(void *s1, const void *s2, size_t n); move = (void *)relocator->rel_memmove; @@ -153,18 +152,23 @@ efi_copy_finish(struct relocator *relocator) * If all chunks are in place, we are done. */ chunk = NULL; - while (done == 0) { - /* First check if we have anything to do. */ - if (chunk == NULL) { - done = 1; - STAILQ_FOREACH(chunk, head, chunk_next) { - if (chunk->chunk_paddr != chunk->chunk_vaddr) { - done = 0; - break; - } + while (!done) { + /* Advance to next item in list. */ + if (chunk != NULL) + chunk = STAILQ_NEXT(chunk, chunk_next); + + /* + * First check if we have anything to do. + * We set chunk to NULL every time we move the data. + */ + done = true; + STAILQ_FOREACH_FROM(chunk, head, chunk_next) { + if (chunk->chunk_paddr != chunk->chunk_vaddr) { + done = false; + break; } } - if (done == 1) + if (done) break; /* @@ -175,18 +179,24 @@ efi_copy_finish(struct relocator *relocator) /* Moved already? */ if (c->chunk_vaddr == c->chunk_paddr) continue; + /* Is it the chunk itself? */ if (c->chunk_vaddr == chunk->chunk_vaddr && c->chunk_size == chunk->chunk_size) continue; + + /* + * Check for overlaps. + */ if ((c->chunk_vaddr >= chunk->chunk_paddr && c->chunk_vaddr <= chunk->chunk_paddr + chunk->chunk_size) || (c->chunk_vaddr + c->chunk_size >= chunk->chunk_paddr && c->chunk_vaddr + c->chunk_size <= - chunk->chunk_paddr + chunk->chunk_size)) + chunk->chunk_paddr + chunk->chunk_size)) { break; + } } /* If there are no conflicts, move to place and restart. */ if (c == NULL) { @@ -197,7 +207,6 @@ efi_copy_finish(struct relocator *relocator) chunk = NULL; continue; } - chunk = STAILQ_NEXT(chunk, chunk_next); } return (mbi); -- cgit v1.2.3