Commit 4e7bc39f authored by Charlie Jacobsen's avatar Charlie Jacobsen Committed by Vikram Narayanan

stack-trace: Add interface to remember where struct module is.

We unload the kernel module from the host after we've dup'd it
and mapped it in the LCD. This means the struct module the host
uses goes bye-bye, and address->symbol resolution for addresses
in the LCD's .ko will return "not found" or garbage if some other
.ko was loaded in its place.

Therefore, we need a way for non-isolated code to remember where
the struct module copy is. We store this in the lcd_arch so that
it can man-handle it when it does stack tracing.
parent 5c5080d9
......@@ -222,6 +222,12 @@ struct lcd_arch {
struct vmx_msr_entry *host;
#endif
} msr_autoload;
/*
* Pointer to struct module inside LCD container. We need this
* for resolving addresses to symbol names for stack traces.
*/
struct module *kernel_module;
};
/**
......
......@@ -521,6 +521,7 @@ int lcd_create_module_lcd(char *mdir, char *mname, cptr_t *lcd_out,
cptr_t m_init_cptr, m_core_cptr;
gva_t m_init_link_addr, m_core_link_addr;
unsigned long m_init_size, m_core_size;
unsigned long m_struct_module_core_offset;
struct lcd_create_ctx *ctx;
cptr_t lcd;
/*
......@@ -546,7 +547,8 @@ int lcd_create_module_lcd(char *mdir, char *mname, cptr_t *lcd_out,
&ctx->m_init_bits, &ctx->m_core_bits,
&m_init_cptr, &m_core_cptr,
&m_init_link_addr, &m_core_link_addr,
&m_init_size, &m_core_size);
&m_init_size, &m_core_size,
&m_struct_module_core_offset);
if (ret) {
LIBLCD_ERR("error loading kernel module");
goto fail3;
......@@ -585,6 +587,21 @@ int lcd_create_module_lcd(char *mdir, char *mname, cptr_t *lcd_out,
LIBLCD_ERR("error configuring LCDs registers");
goto fail6;
}
#ifndef LCD_ISOLATE
/*
* For non-isolated code running this, we also remember where
* the struct module copy is located so we can do stack traces.
*
* Recall that gva == hva for non-isolated.
*/
ret = lcd_set_struct_module_hva(lcd,
__hva(gva_val(m_core_link_addr) +
m_struct_module_core_offset));
if (ret) {
LIBLCD_ERR("error setting struct module hva");
goto fail7;
}
#endif
/*
* Return context and lcd
*/
......@@ -593,6 +610,9 @@ int lcd_create_module_lcd(char *mdir, char *mname, cptr_t *lcd_out,
return 0;
#ifdef LCD_ISOLATE
fail7:
#endif
fail6:
fail5:
lcd_cap_delete(lcd);
......
......@@ -802,6 +802,33 @@ int __lcd_console_init(void);
*/
void __lcd_console_exit(void);
/*
* --------------------------------------------------
* ADDRESS -> SYMBOL RESOLUTION
* --------------------------------------------------
*
* ksym.c
*/
/**
* __lcd_set_struct_module_hva -- Set pointer to the struct module for @lcd
* @caller: LCD doing the setting
* @lcd: LCD who is using struct module
* @module_addr: host virtual address of the struct module copy
*
* For motivation, see liblcd version of this function.
*/
int __lcd_set_struct_module_hva(struct lcd *caller, cptr_t lcd,
hva_t module_addr);
/**
* __lcd_hva_to_symbol -- Resolve a host virtual address to a symbol name
* @module: the struct module to use for module symbol resolution
* @hva: the address to resolve
*
* Returns the pointer to the symbol string.
*/
const char* __lcd_hva_to_symbol(struct module *module, hva_t hva);
/*
* --------------------------------------------------
* SYNCHRONOUS IPC
......
......@@ -105,7 +105,22 @@ int lcd_memory_grant_and_map(cptr_t lcd, cptr_t mo, cptr_t dest_slot,
* @dest: slot in LCD's cspace where capability should be stored
*/
int lcd_cap_grant(cptr_t lcd, cptr_t src, cptr_t dest);
/**
* lcd_set_struct_module_hva -- Remember the hva of the struct module copy
* @lcd: LCD that is using the module
* @hva: the host virtual address of the struct module copy
*
* Motivation: We unload the modules from the host now after they have been
* loaded into the LCD. But the struct module is still around, its just in
* the dup pages. The creator (some non-isolated code) should tell us
* where. Then, in stack traces, we can use the struct module to resolve
* addresses -> symbols.
*
* If @lcd is not isolated, this returns an error.
*
* For isolated code calling this function, also returns error.
*/
int lcd_set_struct_module_hva(cptr_t lcd, hva_t hva);
/**
* lcd_run -- Run an LCD
* @lcd: the LCD to run
......
......@@ -19,6 +19,8 @@
* @m_init_link_addr: the address that the module's init code was linked for
* @m_init_size: size in bytes of the module init part of the image
* @m_core_size: size in bytes of the module core part of the image
* @m_struct_module_core_offset: offset into .ko's core where struct module
* is located
*
* The *_core_* out params have similar meaning.
*
......@@ -39,7 +41,8 @@ int lcd_load_module(char *mdir, char *mname,
gva_t *m_init_link_addr,
gva_t *m_core_link_addr,
unsigned long *m_init_size,
unsigned long *m_core_size);
unsigned long *m_core_size,
unsigned long *m_struct_module_core_offset);
/**
* lcd_release_module -- Unmap module bits and cap delete the pages
* @m_init_bits: virtual address of pages that contain module's init
......
......@@ -1134,6 +1134,11 @@ int lcd_cap_grant(cptr_t lcd, cptr_t src, cptr_t dest)
return __lcd_cap_grant(current->lcd, lcd, src, dest);
}
int lcd_set_struct_module_hva(cptr_t lcd, hva_t hva)
{
return __lcd_set_struct_module_hva(current->lcd, lcd, hva);
}
int lcd_run(cptr_t lcd)
{
return __lcd_run(current->lcd, lcd);
......@@ -1147,3 +1152,4 @@ EXPORT_SYMBOL(lcd_config_registers);
EXPORT_SYMBOL(lcd_memory_grant_and_map);
EXPORT_SYMBOL(lcd_cap_grant);
EXPORT_SYMBOL(lcd_run);
EXPORT_SYMBOL(lcd_set_struct_module_hva);
......@@ -175,7 +175,8 @@ int lcd_load_module(char *mdir, char *mname,
gva_t *m_init_link_addr,
gva_t *m_core_link_addr,
unsigned long *m_init_size,
unsigned long *m_core_size)
unsigned long *m_core_size,
unsigned long *m_struct_module_core_offset)
{
int ret;
struct module *m;
......@@ -205,12 +206,15 @@ int lcd_load_module(char *mdir, char *mname,
}
/*
* Extract addresses where init and core should be mapped (the
* link base addresses)
* link base addresses), sizes, and location of struct
* module in .ko image.
*/
*m_init_link_addr = __gva((unsigned long)m->module_init);
*m_core_link_addr = __gva((unsigned long)m->module_core);
*m_init_size = m->init_size;
*m_core_size = m->core_size;
*m_struct_module_core_offset =
((unsigned long)m) - ((unsigned long)m->module_core);
LIBLCD_MSG("Loaded %s.ko: ", mname);
printk(" init addr 0x%p init size 0x%x\n",
......
......@@ -66,6 +66,11 @@ int lcd_cap_grant(cptr_t lcd, cptr_t src, cptr_t dest)
return lcd_syscall_cap_grant(lcd, src, dest);
}
int lcd_set_struct_module_hva(cptr_t lcd, hva_t hva)
{
return -ENOSYS; /* not allowed in isolated (for now I suppose) */
}
int lcd_run(cptr_t lcd)
{
return lcd_syscall_run(lcd);
......
......@@ -21,7 +21,8 @@ int lcd_load_module(char *mdir, char *mname,
gva_t *m_init_link_addr,
gva_t *m_core_link_addr,
unsigned long *m_init_size,
unsigned long *m_core_size)
unsigned long *m_core_size,
unsigned long *m_struct_module_core_offset)
{
return -ENOSYS; /* not implemented */
}
......
/*
* ksym.c
*
* Address -> symbol name resolution
*
* Copyright: University of Utah
*/
#include <lcd_domains/microkernel.h>
#include <linux/module.h>
int __lcd_set_struct_module_hva(struct lcd *caller, cptr_t lcd,
hva_t module_addr)
{
struct cnode *cnode;
struct lcd lcd_struct;
int ret;
/*
* Look up LCD
*/
ret = __lcd_get(caller, lcd, &cnode, &lcd_struct);
if (ret) {
LCD_ERR("lookup failed");
goto fail1;
}
/*
* If it doesn't have an lcd_arch, fail (no underlying VM)
*/
if (!lcd->lcd_arch) {
LCD_ERR("no vm");
ret = -EINVAL;
goto fail2;
}
/*
* Store module address in lcd_arch
*/
lcd->lcd_arch->kernel_module = hva2va(module_addr);
__lcd_put(caller, cnode, lcd_struct);
return 0;
fail2:
__lcd_put(caller, cnode, lcd_struct);
fail1:
return ret;
}
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