git: 023a025b5cb1 - main - x86: Add support for PVH version 1 memmap
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 18 Oct 2022 06:03:14 UTC
The branch main has been updated by cperciva:
URL: https://cgit.FreeBSD.org/src/commit/?id=023a025b5cb1534f98f387e41911bbdeba06684e
commit 023a025b5cb1534f98f387e41911bbdeba06684e
Author: Colin Percival <cperciva@FreeBSD.org>
AuthorDate: 2022-07-13 00:45:41 +0000
Commit: Colin Percival <cperciva@FreeBSD.org>
CommitDate: 2022-10-18 06:02:22 +0000
x86: Add support for PVH version 1 memmap
Version 0 of PVH booting uses a Xen hypercall to retrieve the system
memory map; in version 1 the memory map can be provided via the
start_info structure.
Using the memory map from the version 1 start_info structure allows
FreeBSD to use PVH booting on systems other than Xen, e.g. on the
Firecracker VM.
Reviewed by: royger
Sponsored by: https://www.patreon.com/cperciva
Differential Revision: https://reviews.freebsd.org/D35800
---
sys/x86/xen/pv.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 47 insertions(+), 2 deletions(-)
diff --git a/sys/x86/xen/pv.c b/sys/x86/xen/pv.c
index 796b3ca844de..845c2d7222eb 100644
--- a/sys/x86/xen/pv.c
+++ b/sys/x86/xen/pv.c
@@ -94,7 +94,7 @@ uint64_t hammer_time_xen(vm_paddr_t);
/*--------------------------- Forward Declarations ---------------------------*/
static caddr_t xen_pvh_parse_preload_data(uint64_t);
-static void xen_pvh_parse_memmap(caddr_t, vm_paddr_t *, int *);
+static void pvh_parse_memmap(caddr_t, vm_paddr_t *, int *);
/*---------------------------- Extern Declarations ---------------------------*/
/*
@@ -108,7 +108,7 @@ struct init_ops xen_pvh_init_ops = {
.parse_preload_data = xen_pvh_parse_preload_data,
.early_clock_source_init = xen_clock_init,
.early_delay = xen_delay,
- .parse_memmap = xen_pvh_parse_memmap,
+ .parse_memmap = pvh_parse_memmap,
};
static struct bios_smap xen_smap[MAX_E820_ENTRIES];
@@ -395,6 +395,36 @@ xen_pvh_parse_preload_data(uint64_t modulep)
return (kmdp);
}
+static void
+pvh_parse_memmap_start_info(caddr_t kmdp, vm_paddr_t *physmap,
+ int *physmap_idx)
+{
+ const struct hvm_memmap_table_entry * entries;
+ size_t nentries;
+ size_t i;
+
+ /* Extract from HVM start_info. */
+ entries = (struct hvm_memmap_table_entry *)(start_info->memmap_paddr + KERNBASE);
+ nentries = start_info->memmap_entries;
+
+ /* Convert into E820 format and handle one by one. */
+ for (i = 0; i < nentries; i++) {
+ struct bios_smap entry;
+
+ entry.base = entries[i].addr;
+ entry.length = entries[i].size;
+
+ /*
+ * Luckily for us, the XEN_HVM_MEMMAP_TYPE_* values exactly
+ * match the SMAP_TYPE_* values so we don't need to translate
+ * anything here.
+ */
+ entry.type = entries[i].type;
+
+ bios_add_smap_entries(&entry, 1, physmap, physmap_idx);
+ }
+}
+
static void
xen_pvh_parse_memmap(caddr_t kmdp, vm_paddr_t *physmap, int *physmap_idx)
{
@@ -416,3 +446,18 @@ xen_pvh_parse_memmap(caddr_t kmdp, vm_paddr_t *physmap, int *physmap_idx)
bios_add_smap_entries(xen_smap, size, physmap, physmap_idx);
}
+
+static void
+pvh_parse_memmap(caddr_t kmdp, vm_paddr_t *physmap, int *physmap_idx)
+{
+
+ /*
+ * If version >= 1 and memmap_paddr != 0, use the memory map provided
+ * in the start_info structure; if not, we're running under legacy
+ * Xen and need to use the Xen hypercall.
+ */
+ if ((start_info->version >= 1) && (start_info->memmap_paddr != 0))
+ pvh_parse_memmap_start_info(kmdp, physmap, physmap_idx);
+ else
+ xen_pvh_parse_memmap(kmdp, physmap, physmap_idx);
+}