The branch main has been updated by cperciva:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=023a025b5cb1534f98f387e41911bbdeba06684e

commit 023a025b5cb1534f98f387e41911bbdeba06684e
Author:     Colin Percival <[email protected]>
AuthorDate: 2022-07-13 00:45:41 +0000
Commit:     Colin Percival <[email protected]>
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);
+}

Reply via email to