diff --git a/usr.sbin/bhyve/amd64/e820.c b/usr.sbin/bhyve/amd64/e820.c --- a/usr.sbin/bhyve/amd64/e820.c +++ b/usr.sbin/bhyve/amd64/e820.c @@ -156,6 +156,7 @@ { struct e820_element *new_element; struct e820_element *element; + struct e820_element *sib_element; struct e820_element *ram_element; assert(end >= base); @@ -222,7 +223,16 @@ * [ 0x1000, 0x2000] Reserved * [ 0x2000, 0x4000] RAM <-- element */ - TAILQ_INSERT_BEFORE(element, new_element, chain); + sib_element = TAILQ_PREV(element, e820_table, chain); + if (sib_element != NULL && + sib_element->type == new_element->type && + sib_element->end == new_element->base) { + /* Merge new element into previous one. */ + sib_element->end = new_element->end; + free(new_element); + } else { + TAILQ_INSERT_BEFORE(element, new_element, chain); + } element->base = end; } else if (end == element->end) { /* @@ -236,7 +246,15 @@ * [ 0x1000, 0x3000] RAM <-- element * [ 0x3000, 0x4000] Reserved */ - TAILQ_INSERT_AFTER(&e820_table, element, new_element, chain); + sib_element = TAILQ_NEXT(element, chain); + if (sib_element != NULL && sib_element->type == new_element->type && + sib_element->base == new_element->end) { + sib_element->base = new_element->base; + free(new_element); + } else { + TAILQ_INSERT_AFTER(&e820_table, element, new_element, + chain); + } element->end = base; } else { /*