Commit a94f0e92 authored by Charlie Jacobsen's avatar Charlie Jacobsen Committed by Vikram Narayanan

liblcd-v2: RAM map allocator internals set up.

parent 2979d763
......@@ -233,7 +233,27 @@ heap_free_unmap_metadata_memory_chunk(struct lcd_page_allocator_cbs *cbs,
unsigned long metadata_sz,
unsigned int alloc_order)
{
do_one_heap_free(lcd_gva2gpa(__gva((unsigned long)metadata_addr)));
unsigned long i;
unsigned long nr_frees;
unsigned total;
gpa_t dest;
/*
* Ignore the metadata address; should be at predefined spot.
*
* We alloc'd the metadata in chunks; free them.
*/
total = ALIGN(metadata_sz, (1UL << (alloc_order + PAGE_SHIFT)));
nr_allocs = total >> (alloc_order + PAGE_SHIFT); /* > 0 */
for (i = 0; i < nr_allocs; i++) {
dest = gpa_add(LCD_HEAP_GP_ADDR,
i * (1UL << (alloc_order + PAGE_SHIFT)));
do_one_heap_free(dest);
}
return;
}
static int
......
......@@ -71,153 +71,61 @@ void _lcd_munmap(cptr_t mo, gpa_t base)
/* RAM MAP INTERNALS ---------------------------------------- */
static int
ram_alloc_map_metadata_memory_chunk(struct lcd_page_allocator_cbs *cbs,
unsigned long mapping_offset,
unsigned int alloc_order,
struct lcd_resource_node **n_out)
ram_alloc_map_metadata_memory(struct lcd_page_allocator_cbs *cbs,
unsigned int alloc_order,
unsigned long metadata_sz,
void **metadata_addr)
{
int ret;
cptr_t pages;
static int nr_calls = 0; /* should only be called once */
gpa_t dest = gpa_add(LCD_RAM_MAP_GP_ADDR, mapping_offset);
/*
* Just do a kmalloc
*/
/*
* Do low-level page alloc out into microkernel
*/
ret = _lcd_alloc_pages(0, alloc_order, &pages);
if (ret) {
LIBLCD_ERR("low level alloc failed");
*metadata_addr = kmalloc(metadata_sz, GFP_KERNEL);
if (!*metadata_addr) {
LIBLCD_ERR("error getting metadata mem for ram map");
ret = -ENOMEM;
goto fail1;
}
/*
* Map in guest physical at the right offset into the heap region
*/
ret = _lcd_mmap(pages, alloc_order, dest);
if (ret) {
LIBLCD_ERR("low level mmap failed");
goto fail2;
}
/*
* Look up resource node for new pages
*/
ret = lcd_phys_to_resource_node(dest, n_out);
if (ret) {
LIBLCD_ERR("failed to get new resource node");
goto fail3;
}
return 0;
fail3:
_lcd_munmap(pages, dest);
fail2:
lcd_cap_delete(pages);
fail1:
return ret;
}
static void
heap_free_unmap_metadata_memory_chunk(struct lcd_page_allocator_cbs *cbs,
struct lcd_resource_node *n_to_delete)
ram_free_unmap_metadata_memory(struct lcd_page_allocator_cbs *cbs,
void *metadata_addr,
unsigned long metadata_sz,
unsigned int alloc_order)
{
cptr_t pages = n_to_delete->cptr;
gpa_t base = __gpa(lcd_resource_node_start(n_to_delete));
/*
* Unmap from guest physical
*/
_lcd_munmap(pages, base);
/*
* Remove from resource tree
*/
__liblcd_mem_itree_delete(n_to_delete);
/*
* Free pages from host
* We alloc'd metadata with kmalloc (above)
*/
lcd_cap_delete(pages);
kfree(metadata_addr);
}
static int
heap_alloc_map_regular_mem_chunk(struct lcd_page_allocator *pa,
struct lcd_page_block *dest_blocks,
unsigned long mapping_offset,
unsigned int alloc_order,
struct lcd_resource_node **n_out)
{
/*
* For now, we just re-use the metadata func, since there
* is no difference.
*/
return heap_alloc_map_metadata_memory_chunk(&pa->cbs, mapping_offset,
alloc_order, n_out);
}
static void
heap_free_unmap_regular_mem_chunk(struct lcd_page_allocator *pa,
struct lcd_page_block *page_blocks,
struct lcd_resource_node *n_to_delete,
unsigned long mapping_offset,
unsigned int order)
{
/*
* Again, we re-use the metadata funcs since they're the same
* right now.
*/
heap_free_unmap_metadata_memory_chunk(&pa->cbs, n_to_delete);
}
static inline gva_t heap_page_block_to_addr(struct lcd_page_block *pb)
static inline gva_t ram_page_block_to_addr(struct lcd_page_block *pb)
{
return gva_add(LCD_HEAP_GV_ADDR,
lcd_page_block_to_offset(heap_allocator, pb));
return gva_add(LCD_RAM_MAP_GV_ADDR,
lcd_page_block_to_offset(ram_map_allocator, pb));
}
static inline struct lcd_page_block *heap_addr_to_page_block(gva_t addr)
static inline struct lcd_page_block *ram_addr_to_page_block(gva_t addr)
{
return lcd_offset_to_page_block(
heap_allocator,
gva_val(addr) - gva_val(LCD_HEAP_GV_ADDR));
ram_map_allocator,
gva_val(addr) - gva_val(LCD_RAM_MAP_GV_ADDR));
}
static inline struct page *heap_addr_to_struct_page(gva_t addr)
{
unsigned long idx;
idx = (gva_val(addr) - gva_val(LCD_HEAP_GV_ADDR)) >> PAGE_SHIFT;
return &heap_page_array[idx];
}
/* INTERFACE -------------------------------------------------- */
static inline gva_t heap_struct_page_to_addr(struct page *p)
{
unsigned long idx;
idx = p - heap_page_array;
return gva_add(LCD_HEAP_GV_ADDR, idx * PAGE_SIZE);
}
static inline struct page *heap_page_block_to_struct_page(
struct lcd_page_block *pb)
{
return heap_addr_to_struct_page(
heap_page_block_to_addr(pb));
}
static inline struct lcd_page_block *heap_struct_page_to_page_block(
struct page *p)
{
return heap_addr_to_page_block(
heap_struct_page_to_addr(p));
}
/* INIT/EXIT ---------------------------------------- */
struct lcd_page_allocator_cbs ram_map_page_allocator_cbs = {
.alloc_map_metadata_memory_chunk = ram_alloc_map_metadata_memory_chunk,
.free_unmap_metadata_memory_chunk = ram_free_unmap_metadata_memory_chunk,
.alloc_map_metadata_memory = ram_alloc_map_metadata_memory,
.free_unmap_metadata_memory = ram_free_unmap_metadata_memory,
};
int __liblcd_ram_map_init(void)
......@@ -228,7 +136,6 @@ int __liblcd_ram_map_init(void)
*/
ret = lcd_page_allocator_create(LCD_RAM_MAP_NR_PAGES_ORDER,
LCD_RAM_MAP_MIN_ORDER,
1, /* 2^1 = 2 pages */
LCD_RAM_MAP_MAX_ORDER,
&ram_map_page_allocator_cbs,
0, /* don't embed metadata */
......@@ -237,7 +144,4 @@ int __liblcd_ram_map_init(void)
LIBLCD_ERR("failed to initialize RAM map allocator");
goto fail1;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment