Commit 9553b4aa authored by Charlie Jacobsen's avatar Charlie Jacobsen Committed by Vikram Narayanan
Browse files

lcd-create-v2: Alloc pages for LCD, don't use creator cptr's.

parent b89e9edb
......@@ -7,12 +7,51 @@
* Copyright: University of Utah
*/
static int setup_phys_addr_space(cptr_t lcd, struct lcd_create_ctx *ctx,
gva_t m_init_link_addr, gva_t m_core_link_addr)
{
int ret;
}
static int setup_addr_spaces(cptr_t lcd, struct lcd_create_ctx *ctx,
gva_t m_init_link_addr, gva_t m_core_link_addr)
{
int ret;
/*
* Set up physical address space
*/
ret = setup_phys_addr_space(lcd, cxt, m_init_link_addr,
m_core_link_addr);
if (ret) {
LIBLCD_ERR("error setting up phys addr space");
goto fail1;
}
/*
* Set up virtual address space
*/
ret = setup_virt_addr_space(lcd, cxt, m_init_link_addr,
m_core_link_addr);
if (ret) {
LIBLCD_ERR("error setting up virt addr space");
goto fail2;
}
return 0;
fail2: /* just return non-zero ret; caller will free mem */
fail1:
return ret;
}
static int init_create_ctx(struct lcd_create_ctx **ctx_out)
{
struct lcd_create_ctx *ctx;
struct page *p;
void *boot_pages;
unsigned int order1, order2;
/*
* Alloc ctx
*/
......@@ -22,44 +61,80 @@ static int init_create_ctx(struct lcd_create_ctx **ctx_out)
ret = -ENOMEM;
goto fail1;
}
*ctx_out = ctx;
return 0;
fail1:
return ret;
}
static void destroy_create_ctx(struct lcd_create_ctx *ctx)
{
/*
* Remove pages from our address space and delete our
* capabilities to them. If these are the last caps,
* pages will be freed by microkernel.
*/
if (ctx->m_init_bits)
lcd_module_release(ctx->m_init_bits, ctx->m_core_bits);
if (ctx->stack)
lcd_free_pages(lcd_virt_to_page(ctx->stack),
LCD_STACK_ORDER);
if (ctx->gv_pgd)
lcd_free_pages(lcd_virt_to_page(ctx->gv_pgd),
LCD_BOOTSTRAP_PAGE_TABLES_ORDER);
if (ctx->lcd_boot_info)
lcd_free_pages(lcd_virt_to_page(ctx->lcd_boot_info),
LCD_BOOTSTRAP_PAGES_ORDER);
/*
* Free the ctx
*/
kfree(ctx);
}
static int get_pages_for_lcd(struct lcd_create_ctx *ctx)
{
struct page *p1, *p2, *p3;
/*
* Alloc boot pages
*/
order1 = ilog(LCD_BOOTSTRAP_PAGE_SIZE >> PAGE_SHIFT);
p = lcd_alloc_pages(0, order1);
p1 = lcd_alloc_pages(0, LCD_BOOTSTRAP_PAGES_ORDER);
if (!p1) {
LIBLCD_ERR("alloc boot pages failed");
ret = -ENOMEM;
goto fail1;
}
ctx->lcd_boot_info = lcd_page_address(p1);
/*
* Alloc boot page tables
*/
p2 = lcd_alloc_pages(0, LCD_BOOTSTRAP_PAGE_TABLES_ORDER);
if (!p) {
LIBLCD_ERR("alloc pages failed");
LIBLCD_ERR("alloc boot page tables failed");
ret = -ENOMEM;
goto fail2;
}
boot_pages = lcd_page_address(p);
ctx->gv_pgd = lcd_page_address(p2);
ctx->gv_pud = lcd_page_address(p2 + 1);
/*
* Get creator cptr
* Alloc stack
*/
ret = lcd_virt_to_cptr(__gva((unsigned long)boot_pages),
&ctx->creator_cptrs.boot_pages_cptr,
&order2);
if (ret) {
LIBLCD_ERR("error looking up cptr for boot pages");
p3 = lcd_alloc_pages(0, LCD_STACK_ORDER);
if (!p3) {
LIBLCD_ERR("alloc stack pages failed");
ret = -ENOMEM;
goto fail3;
}
if (order1 != order2) {
LIBLCD_ERR("order1 = %d, while order2 = %d; internal error",
order1, order2);
goto fail4;
}
ctx->lcd_boot_info = boot_pages;
*ctx_out = ctx;
ctx->stack = lcd_page_address(p3);
return 0;
fail4:
fail3:
lcd_free_pages(p, order1);
lcd_free_pages(p2, LCD_BOOTSTRAP_PAGE_TABLES_ORDER);
fail2:
kfree(ctx);
lcd_free_pages(p1, LCD_BOOTSTRAP_PAGES_ORDER);
fail1:
return ret;
}
......@@ -68,7 +143,7 @@ int lcd_create_module_lcd(char *mdir, char *mname, cptr_t *lcd_out,
struct lcd_create_ctx **ctx_out)
{
int ret;
void *m_init_bits, *m_core_bits;
cptr_t m_init_cptr, m_core_cptr;
gva_t m_init_link_addr, m_core_link_addr;
struct lcd_create_ctx *ctx;
cptr_t lcd;
......@@ -80,25 +155,35 @@ int lcd_create_module_lcd(char *mdir, char *mname, cptr_t *lcd_out,
LIBLCD_ERR("error creating ctx");
goto fail1;
}
/*
* Alloc boot pages, stack pages, etc. for LCD
*/
ret = get_pages_for_lcd(ctx);
if (ret) {
LIBLCD_ERR("error alloc'ing boot, stack pages for LCD");
goto fail2;
}
/*
* Load kernel module into caller's address space
*/
ret = lcd_module_load(mdir, mname,
&m_init_bits, &m_core_bits,
&ctx->creator_cptrs.module_init_cptr,
&ctx->creator_cptrs.module_core_cptr,
&ctx->m_init_bits, &ctx->m_core_bits,
&m_init_cptr, &m_core_cptr,
&m_init_link_addr, &m_core_link_addr);
if (ret) {
LIBLCD_ERR("error loading kernel module");
goto fail2;
goto fail3;
}
/*
* At this point, we have all of the data that will go in the LCD
* (the microkernel has the UTCB page)
*
* Initialize empty LCD
*/
ret = lcd_create(&lcd);
if (ret) {
LIBLCD_ERR("error creating empty LCD");
goto fail3;
goto fail4;
}
/*
* Set up address spaces
......@@ -107,14 +192,14 @@ int lcd_create_module_lcd(char *mdir, char *mname, cptr_t *lcd_out,
m_core_link_addr);
if (ret) {
LIBLCD_ERR("error setting up address spaces");
goto fail4;
goto fail5;
}
/*
* Configure initial control registers, etc. for LCD
*/
/*
* Return context
* Return context and lcd
*/
*cxt_out = cxt;
*lcd_out = lcd;
......@@ -122,10 +207,9 @@ int lcd_create_module_lcd(char *mdir, char *mname, cptr_t *lcd_out,
return 0;
fail5:
fail4:
lcd_cap_delete(lcd);
fail4:
fail3:
lcd_module_release(m_init_bits, m_core_bits);
fail2:
destroy_create_ctx(ctx);
fail1:
......
......@@ -156,6 +156,24 @@
#error "struct lcd_boot_info won't fit in bootstrap pages. Add more pages."
#endif
#if (LCD_BOOTSTRAP_PAGE_TABLES_SIZE >> PAGE_SHIFT != 2)
#error "We need exactly two page tables for the gv address space."
#endif
#if ((LCD_STACK_SIZE >> PAGE_SHIFT) & \
((LCD_STACK_SIZE >> PAGE_SHIFT) - 1))
#error "Number of LCD stack pages needs to be a power-of-two multiple."
#endif
/* Orders (for convenience) */
#define LCD_BOOTSTRAP_PAGES_ORDER \
(ilog(LCD_BOOTSTRAP_PAGES_SIZE >> PAGE_SHIFT))
#define LCD_BOOTSTRAP_PAGE_TABLES_ORDER \
(ilog(LCD_BOOTSTRAP_PAGE_TABLES_SIZE >> PAGE_SHIFT))
#define LCD_STACK_ORDER \
(ilog(LCD_STACK_SIZE >> PAGE_SHIFT))
/* Offsets. */
#define LCD_MISC_REGION_OFFSET (1UL << 30)
......
......@@ -123,14 +123,14 @@ struct lcd_create_ctx {
*/
char mname[LCD_MODULE_NAME_MAX];
/*
* cptr's to capabilities in *creator's* cspace for
* memory allocated for new LCD
*/
struct lcd_boot_cptrs creator_cptrs;
/*
* Pointer to struct lcd_boot_info pages on host
* All of these are *creator-relative* addresses
*/
struct lcd_boot_info *lcd_boot_info;
pgd_t *gv_pgd;
pgd_t *gv_pud;
void *stack;
void *m_init_bits;
void *m_core_bits;
};
/**
......
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