extern struct boot_info xen_boot_info;
unsigned long initial_images_nrpages(nodeid_t node);
-void discard_initial_images(void);
+void free_boot_modules(void);
struct boot_module;
void *bootstrap_map_bm(const struct boot_module *bm);
void *bootstrap_map(const module_t *mod);
void bootstrap_unmap(void);
+void release_boot_module(struct boot_module *bm);
+
struct rangeset;
int remove_xen_ranges(struct rangeset *r);
}
memcpy(page_to_virt(page), mfn_to_virt(initrd->mod->mod_start),
initrd_len);
- mpt_alloc = pfn_to_paddr(initrd->mod->mod_start);
- init_domheap_pages(mpt_alloc,
- mpt_alloc + PAGE_ALIGN(initrd_len));
+ /*
+ * The initrd was copied but the initrd variable is reused in the
+ * calculations below. As to not leak the memory used for the
+ * module free at this time.
+ */
+ release_boot_module(initrd);
initrd_mfn = mfn_x(page_to_mfn(page));
initrd->mod->mod_start = initrd_mfn;
}
while ( count-- )
if ( assign_pages(mfn_to_page(_mfn(mfn++)), 1, d, 0) )
BUG();
+ /*
+ * We have mapped the initrd directly into dom0, and assigned the
+ * pages. Tell the boot_module handling that we've freed it, so the
+ * memory is left alone.
+ */
+ initrd->released = true;
}
- /*
- * We have either:
- * - Mapped the initrd directly into dom0, or
- * - Copied it and freed the module.
- *
- * Either way, tell discard_initial_images() to not free it a second
- * time.
- */
- initrd->mod->mod_end = 0;
-
iommu_memory_setup(d, "initrd", mfn_to_page(_mfn(initrd_mfn)),
PFN_UP(initrd_len), &flush_flags);
}
}
/* Free temporary buffers. */
- discard_initial_images();
+ free_boot_modules();
/* Set up start info area. */
si = (start_info_t *)vstartinfo_start;
return nr;
}
-void __init discard_initial_images(void) /* a.k.a. Free boot modules */
+void __init release_boot_module(struct boot_module *bm)
+{
+ uint64_t start = pfn_to_paddr(bm->mod->mod_start);
+ uint64_t size = bm->mod->mod_end;
+
+ ASSERT(!bm->released);
+
+ init_domheap_pages(start, start + PAGE_ALIGN(size));
+
+ bm->released = true;
+}
+
+void __init free_boot_modules(void)
{
struct boot_info *bi = &xen_boot_info;
unsigned int i;
for ( i = 0; i < bi->nr_modules; ++i )
{
- uint64_t start = pfn_to_paddr(bi->mods[i].mod->mod_start);
- uint64_t size = bi->mods[i].mod->mod_end;
-
- /*
- * Sometimes the initrd is mapped, rather than copied, into dom0.
- * Size being 0 is how we're instructed to leave the module alone.
- */
- if ( size == 0 )
+ if ( bi->mods[i].released )
continue;
- init_domheap_pages(start, start + PAGE_ALIGN(size));
+ release_boot_module(&bi->mods[i]);
}
-
- bi->nr_modules = 0;
}
static void __init init_idle_domain(void)