[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [MINI-OS PATCH 06/19] mm: don't add module pages to free memory
When initializing the memory allocator, don't add memory pages of modules and the initial boot info structure to the free memory. This is relevant only when running in PVH mode, as in PV mode only memory above the initial page tables is added to free memory, and the module and start_info pages are below the page tables. Signed-off-by: Juergen Gross <jgross@xxxxxxxx> --- arch/x86/mm.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/mm.h | 1 + mm.c | 21 +++++++++++++- 3 files changed, 101 insertions(+), 1 deletion(-) diff --git a/arch/x86/mm.c b/arch/x86/mm.c index 26ede6f4..7c3c83be 100644 --- a/arch/x86/mm.c +++ b/arch/x86/mm.c @@ -78,6 +78,10 @@ void arch_mm_preinit(void *p) last_free_pfn = si->nr_pages; balloon_set_nr_pages(last_free_pfn, last_free_pfn); } + +void check_memory_range(unsigned long *from, unsigned long *to) +{ +} #else #include <mini-os/desc.h> user_desc gdt[NR_GDT_ENTRIES] = @@ -125,6 +129,78 @@ void arch_mm_preinit(void *p) last_free_pfn = e820_get_maxpfn(pages); balloon_set_nr_pages(pages, last_free_pfn); } + +static void check_memory_range_conflict(unsigned long *from, unsigned long *to, + unsigned long chk, unsigned long sz) +{ + unsigned long chk_end = chk + sz; + + if ( *to <= chk || *from >= chk_end ) + return; + + if ( chk <= *from ) + *from = (chk_end >= *to) ? *to : chk_end; + else + *to = chk; +} + +/* Reserved memory ranges not added to free memory. */ +#define MAX_RSV_RANGES 1 +static struct { + unsigned long start; + unsigned long size; +} reserved_range[MAX_RSV_RANGES]; + +void check_memory_range(unsigned long *from, unsigned long *to) +{ + unsigned int m; + struct hvm_modlist_entry *mod; + + for ( m = 0; m < MAX_RSV_RANGES && reserved_range[m].size; m++ ) + check_memory_range_conflict(from, to, reserved_range[m].start, + reserved_range[m].size); + + mod = (struct hvm_modlist_entry *)(unsigned long) + hvm_start_info_ptr->modlist_paddr; + for ( m = 0; m < hvm_start_info_ptr->nr_modules; m++ ) + check_memory_range_conflict(from, to, mod[m].paddr, mod[m].size); +} + +#define max(a, b) ((a) < (b) ? (b) : (a)) + +static void pvh_reserve_start_info(unsigned long *start_pfn) +{ + unsigned long end = 0; + unsigned long start = (unsigned long)hvm_start_info_ptr; + unsigned long end_pfn; + unsigned int m; + struct hvm_modlist_entry *mod; + char *cmdline; + + mod = (void *)(unsigned long)hvm_start_info_ptr->modlist_paddr; + + end = max(end, start + sizeof(struct hvm_start_info)); + end = max(end, hvm_start_info_ptr->modlist_paddr + + hvm_start_info_ptr->nr_modules * + sizeof(struct hvm_modlist_entry)); + for ( m = 0; m < hvm_start_info_ptr->nr_modules; m++ ) + { + cmdline = (char *)(unsigned long)mod[m].cmdline_paddr; + if ( cmdline ) + end = max(end, (unsigned long)cmdline + strlen(cmdline) + 1); + } + cmdline = (char *)(unsigned long)hvm_start_info_ptr->cmdline_paddr; + if ( cmdline ) + end = max(end, (unsigned long)cmdline + strlen(cmdline) + 1); + if ( hvm_start_info_ptr->version >= 1 ) + end = max(end, hvm_start_info_ptr->memmap_paddr + + hvm_start_info_ptr->memmap_entries * + sizeof(struct hvm_memmap_table_entry)); + + end_pfn = PFN_UP(end); + if ( end_pfn > *start_pfn ) + *start_pfn = end_pfn; +} #endif static const struct { @@ -888,6 +964,10 @@ void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p) if ( max_pfn >= MAX_MEM_SIZE / PAGE_SIZE ) max_pfn = MAX_MEM_SIZE / PAGE_SIZE - 1; +#ifndef CONFIG_PARAVIRT + pvh_reserve_start_info(&start_pfn); +#endif + printk(" start_pfn: %lx\n", start_pfn); printk(" max_pfn: %lx\n", max_pfn); diff --git a/include/mm.h b/include/mm.h index 1dc89ddb..995e9862 100644 --- a/include/mm.h +++ b/include/mm.h @@ -74,6 +74,7 @@ static __inline__ int get_order(unsigned long size) void arch_init_demand_mapping_area(void); void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p); +void check_memory_range(unsigned long *from, unsigned long *to); unsigned long allocate_ondemand(unsigned long n, unsigned long alignment); /* map f[i*stride]+i*increment for i in 0..n-1, aligned on alignment pages */ diff --git a/mm.c b/mm.c index 858dc108..8c41d2f2 100644 --- a/mm.c +++ b/mm.c @@ -185,6 +185,25 @@ static void add_memory_range(unsigned long r_min, unsigned long r_max) } } +static void consider_memory_range(unsigned long r_min, unsigned long r_max, + void (*func)(unsigned long, unsigned long)) +{ + unsigned long from = r_min; + unsigned long to = r_max; + + while ( true ) + { + check_memory_range(&from, &to); + if ( from == to ) + return; + + func(from, to); + + from = to; + to = r_max; + } +} + void iterate_memory_range(unsigned long min, unsigned long max, void (*func)(unsigned long, unsigned long)) { @@ -207,7 +226,7 @@ void iterate_memory_range(unsigned long min, unsigned long max, if ( r_max > max ) r_max = max; - func(r_min, r_max); + consider_memory_range(r_min, r_max, func); } } -- 2.43.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |