diff --git a/tools/firmware/hvmloader/e820.c b/tools/firmware/hvmloader/e820.c index 2e05e93a52..7a414ab9ce 100644 --- a/tools/firmware/hvmloader/e820.c +++ b/tools/firmware/hvmloader/e820.c @@ -23,6 +23,38 @@ #include "config.h" #include "util.h" +struct e820map memory_map; + +void memory_map_setup(void) +{ + unsigned int nr_entries = E820MAX, i; + int rc; + uint64_t alloc_addr = RESERVED_MEMORY_DYNAMIC_START; + uint64_t alloc_size = RESERVED_MEMORY_DYNAMIC_END - alloc_addr; + + rc = get_mem_mapping_layout(memory_map.map, &nr_entries); + + if ( rc || !nr_entries ) + { + printf("Get guest memory maps[%d] failed. (%d)\n", nr_entries, rc); + BUG(); + } + + memory_map.nr_map = nr_entries; + + for ( i = 0; i < nr_entries; i++ ) + { + if ( memory_map.map[i].type == E820_RESERVED && + check_overlap(alloc_addr, alloc_size, + memory_map.map[i].addr, memory_map.map[i].size) ) + { + printf("Fail to setup memory map due to conflict"); + printf(" on dynamic reserved memory range.\n"); + BUG(); + } + } +} + void dump_e820_table(struct e820entry *e820, unsigned int nr) { uint64_t last_end = 0, start, end; diff --git a/tools/firmware/hvmloader/e820.h b/tools/firmware/hvmloader/e820.h index b2ead7f109..8b5a9e0b13 100644 --- a/tools/firmware/hvmloader/e820.h +++ b/tools/firmware/hvmloader/e820.h @@ -15,6 +15,13 @@ struct e820entry { uint32_t type; } __attribute__((packed)); +#define E820MAX 128 + +struct e820map { + unsigned int nr_map; + struct e820entry map[E820MAX]; +}; + #endif /* __HVMLOADER_E820_H__ */ /* diff --git a/tools/firmware/hvmloader/hvmloader.c b/tools/firmware/hvmloader/hvmloader.c index 25b7f08652..84c588ca83 100644 --- a/tools/firmware/hvmloader/hvmloader.c +++ b/tools/firmware/hvmloader/hvmloader.c @@ -262,6 +262,8 @@ int main(void) init_hypercalls(); + memory_map_setup(); + xenbus_setup(); bios = detect_bios(); diff --git a/tools/firmware/hvmloader/util.c b/tools/firmware/hvmloader/util.c index 80d822f75c..122e3fa4ca 100644 --- a/tools/firmware/hvmloader/util.c +++ b/tools/firmware/hvmloader/util.c @@ -27,6 +27,17 @@ #include #include +/* + * Check whether there exists overlap in the specified memory range. + * Returns true if exists, else returns false. + */ +bool check_overlap(uint64_t start, uint64_t size, + uint64_t reserved_start, uint64_t reserved_size) +{ + return (start + size > reserved_start) && + (start < reserved_start + reserved_size); +} + void wrmsr(uint32_t idx, uint64_t v) { asm volatile ( @@ -368,6 +379,21 @@ uuid_to_string(char *dest, uint8_t *uuid) *p = '\0'; } +int get_mem_mapping_layout(struct e820entry entries[], uint32_t *max_entries) +{ + int rc; + struct xen_memory_map memmap = { + .nr_entries = *max_entries + }; + + set_xen_guest_handle(memmap.buffer, entries); + + rc = hypercall_memory_op(XENMEM_memory_map, &memmap); + *max_entries = memmap.nr_entries; + + return rc; +} + void mem_hole_populate_ram(xen_pfn_t mfn, uint32_t nr_mfns) { static int over_allocated; diff --git a/tools/firmware/hvmloader/util.h b/tools/firmware/hvmloader/util.h index f99c0f19a8..1100a3bdab 100644 --- a/tools/firmware/hvmloader/util.h +++ b/tools/firmware/hvmloader/util.h @@ -4,8 +4,10 @@ #include #include #include +#include #include #include +#include "e820.h" #define __STR(...) #__VA_ARGS__ #define STR(...) __STR(__VA_ARGS__) @@ -222,6 +224,9 @@ int hvm_param_set(uint32_t index, uint64_t value); /* Setup PCI bus */ void pci_setup(void); +/* Setup memory map */ +void memory_map_setup(void); + /* Prepare the 32bit BIOS */ uint32_t rombios_highbios_setup(void); @@ -249,6 +254,13 @@ void perform_tests(void); extern char _start[], _end[]; +int get_mem_mapping_layout(struct e820entry entries[], + unsigned int *max_entries); + +extern struct e820map memory_map; +bool check_overlap(uint64_t start, uint64_t size, + uint64_t reserved_start, uint64_t reserved_size); + #endif /* __HVMLOADER_UTIL_H__ */ /*