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); +}