Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Nov 2024 07:55:45 GMT
From:      Corvin =?utf-8?Q?K=C3=B6hne?= <corvink@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 660e7182dbee - stable/14 - bhyve: merge adjacent E820 entries
Message-ID:  <202411120755.4AC7tj7P077201@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/14 has been updated by corvink:

URL: https://cgit.FreeBSD.org/src/commit/?id=660e7182dbeedea9083eb788dfcdfd17cc9ac6b6

commit 660e7182dbeedea9083eb788dfcdfd17cc9ac6b6
Author:     Corvin Köhne <corvink@FreeBSD.org>
AuthorDate: 2023-12-19 14:01:45 +0000
Commit:     Corvin Köhne <corvink@FreeBSD.org>
CommitDate: 2024-11-12 07:54:22 +0000

    bhyve: merge adjacent E820 entries
    
    EDKII can allocate adjacent E820 entries only if they are at a page
    boundary.  For some unknown and probably strange reasons, Intel puts
    it's OpRegion at an offset of 0x18 bytes. If the VBT lays directly
    behind the OpRegion, we're going to try allocating two adjacent E820
    sharing the same page. This causes EDKII to do not properly allocate
    those entries. A Linux guest then isn't able to map the VBT and those
    fails to find it.
    
    Reviewed by:            markj
    MFC after:              1 week
    Sponsored by:           Beckhoff Automation GmbH & Co. KG
    Differential Revision:  https://reviews.freebsd.org/D45336
    
    (cherry picked from commit 08139140c5f96fd9deb7a8de7a534bccf9a1d0c8)
---
 usr.sbin/bhyve/amd64/e820.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/usr.sbin/bhyve/amd64/e820.c b/usr.sbin/bhyve/amd64/e820.c
index 148cae72ca6e..2fad22865ba6 100644
--- a/usr.sbin/bhyve/amd64/e820.c
+++ b/usr.sbin/bhyve/amd64/e820.c
@@ -156,6 +156,7 @@ e820_add_entry(const uint64_t base, const uint64_t end,
 {
 	struct e820_element *new_element;
 	struct e820_element *element;
+	struct e820_element *sib_element;
 	struct e820_element *ram_element;
 
 	assert(end >= base);
@@ -273,6 +274,33 @@ e820_add_entry(const uint64_t base, const uint64_t end,
 		element->base = end;
 	}
 
+	/*
+	 * If the previous element has the same type and ends at our base
+	 * boundary, we can merge both entries.
+	 */
+	sib_element = TAILQ_PREV(new_element, e820_table, chain);
+	if (sib_element != NULL &&
+	    sib_element->type == new_element->type &&
+	    sib_element->end == new_element->base) {
+		new_element->base = sib_element->base;
+		TAILQ_REMOVE(&e820_table, sib_element, chain);
+		free(sib_element);
+	}
+
+	/*
+	 * If the next element has the same type and starts at our end
+	 * boundary, we can merge both entries.
+	 */
+	sib_element = TAILQ_NEXT(new_element, chain);
+	if (sib_element != NULL &&
+	    sib_element->type == new_element->type &&
+	    sib_element->base == new_element->end) {
+		/* Merge new element into subsequent one. */
+		new_element->end = sib_element->end;
+		TAILQ_REMOVE(&e820_table, sib_element, chain);
+		free(sib_element);
+	}
+
 	return (0);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202411120755.4AC7tj7P077201>