Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F164379316
D39547.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D39547.id.diff
View Options
diff --git a/usr.sbin/bhyve/e820.h b/usr.sbin/bhyve/e820.h
--- a/usr.sbin/bhyve/e820.h
+++ b/usr.sbin/bhyve/e820.h
@@ -18,11 +18,27 @@
E820_TYPE_NVS = 4
};
+enum e820_allocation_strategy {
+ /* allocate any address */
+ E820_ALLOCATE_ANY,
+ /* allocate lowest address larger than address */
+ E820_ALLOCATE_LOWEST,
+ /* allocate highest address lower than address */
+ E820_ALLOCATE_HIGHEST,
+ /* allocate a specific address */
+ E820_ALLOCATE_SPECIFIC
+};
+
struct e820_entry {
uint64_t base;
uint64_t length;
uint32_t type;
} __packed;
+#define E820_ALIGNMENT_NONE 1
+
+uint64_t e820_alloc(const uint64_t address, const uint64_t length,
+ const uint64_t alignment, const enum e820_memory_type type,
+ const enum e820_allocation_strategy strategy);
struct qemu_fwcfg_item *e820_get_fwcfg_item(void);
int e820_init(struct vmctx *const ctx);
diff --git a/usr.sbin/bhyve/e820.c b/usr.sbin/bhyve/e820.c
--- a/usr.sbin/bhyve/e820.c
+++ b/usr.sbin/bhyve/e820.c
@@ -20,6 +20,14 @@
#include "e820.h"
#include "qemu_fwcfg.h"
+/*
+ * E820 always uses 64 bit entries. Emulation code will use vm_paddr_t since it
+ * works on physical addresses. If vm_paddr_t is larger than uint64_t E820 can't
+ * hold all possible physical addresses and we can get into trouble.
+ */
+static_assert(sizeof(vm_paddr_t) <= sizeof(uint64_t),
+ "Unable to represent physical memory by E820 table");
+
#define E820_FWCFG_FILE_NAME "etc/e820"
#define KB (1024UL)
@@ -282,6 +290,102 @@
return (0);
}
+static uint64_t
+e820_alloc_highest(const uint64_t max_address, const uint64_t length,
+ const uint64_t alignment, const enum e820_memory_type type)
+{
+ struct e820_element *element;
+
+ TAILQ_FOREACH_REVERSE(element, &e820_table, e820_table, chain) {
+ uint64_t address, base, end;
+
+ end = MIN(max_address, element->end);
+ base = roundup2(element->base, alignment);
+
+ /*
+ * If end - length == 0, we would allocate memory at address 0. This
+ * address is mostly unusable and we should avoid allocating it.
+ * Therefore, search for another block in that case.
+ */
+ if (element->type != E820_TYPE_MEMORY || end < base ||
+ end - base < length || end - length == 0) {
+ continue;
+ }
+
+ address = rounddown2(end - length, alignment);
+
+ if (e820_add_entry(address, address + length, type) != 0) {
+ return (0);
+ }
+
+ return (address);
+ }
+
+ return (0);
+}
+
+static uint64_t
+e820_alloc_lowest(const uint64_t min_address, const uint64_t length,
+ const uint64_t alignment, const enum e820_memory_type type)
+{
+ struct e820_element *element;
+
+ TAILQ_FOREACH(element, &e820_table, chain) {
+ uint64_t base, end;
+
+ end = element->end;
+ base = MAX(min_address, roundup2(element->base, alignment));
+
+ /*
+ * If base == 0, we would allocate memory at address 0. This
+ * address is mostly unusable and we should avoid allocating it.
+ * Therefore, search for another block in that case.
+ */
+ if (element->type != E820_TYPE_MEMORY || end < base ||
+ end - base < length || base == 0) {
+ continue;
+ }
+
+ if (e820_add_entry(base, base + length, type) != 0) {
+ return (0);
+ }
+
+ return (base);
+ }
+
+ return (0);
+}
+
+uint64_t
+e820_alloc(const uint64_t address, const uint64_t length,
+ const uint64_t alignment, const enum e820_memory_type type,
+ const enum e820_allocation_strategy strategy)
+{
+ assert(powerof2(alignment));
+ assert((address & (alignment - 1)) == 0);
+
+ switch (strategy) {
+ case E820_ALLOCATE_ANY:
+ /*
+ * Allocate any address. Therefore, ignore the address parameter
+ * and reuse the code path for allocating the lowest address.
+ */
+ return (e820_alloc_lowest(0, length, alignment, type));
+ case E820_ALLOCATE_LOWEST:
+ return (e820_alloc_lowest(address, length, alignment, type));
+ case E820_ALLOCATE_HIGHEST:
+ return (e820_alloc_highest(address, length, alignment, type));
+ case E820_ALLOCATE_SPECIFIC:
+ if (e820_add_entry(address, address + length, type) != 0) {
+ return (0);
+ }
+
+ return (address);
+ }
+
+ return (0);
+}
+
int
e820_init(struct vmctx *const ctx)
{
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Aug 1, 7:54 AM (20 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35794362
Default Alt Text
D39547.id.diff (4 KB)
Attached To
Mode
D39547: bhyve: add allocation function to E820
Attached
Detach File
Event Timeline
Log In to Comment