Commit 666f9dae authored by Charles Jacobsen's avatar Charles Jacobsen Committed by Vikram Narayanan
Browse files

test-v2: Fix liblcd syscalls, gv page tables, this_module linkage.

Couple interesting issues here:

   1 - Syscalls were breaking without "asm volatile". I tried
       just plain "asm" to be more compiler-friendly (I guess that
       is more friendly), but the compiler optimized away entire
       vmcall's, haha.
   2 - Guest virtual page table set up was way off for the pud (wasn't
       pointing to the pmd's, and some of the surrounding address
       arithmetic was bad). It's still bad (too specific for x86_64
       perhaps), but that's acceptable for now.
   3 - This was the most interesting one. I didn't even think that
       when we build liblcd (the .a file), the kernel doesn't think
       we're building a kernel module, so THIS_MODULE expands to
       NULL. In order to fix this, I manually set the MODULE macro
       (via a -D cc flag) so that the module.h macros expand as
       expected (we will always link liblcd.a with a kernel module,
       so e.g. struct module __this_module will always be defined).
parent d08c3ad1
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
static inline int lcd_syscall_no_args(int id) static inline int lcd_syscall_no_args(int id)
{ {
long ret; long ret;
asm( asm volatile(
"movq %1, %%rax \n\t" "movq %1, %%rax \n\t"
"vmcall \n\t" "vmcall \n\t"
"movq %%rax, %0 \n\t" "movq %%rax, %0 \n\t"
...@@ -32,7 +32,7 @@ static inline int lcd_syscall_no_args(int id) ...@@ -32,7 +32,7 @@ static inline int lcd_syscall_no_args(int id)
static inline int lcd_syscall_one_arg(int id, unsigned long arg0) static inline int lcd_syscall_one_arg(int id, unsigned long arg0)
{ {
long ret; long ret;
asm( asm volatile(
"movq %2, %%r8 \n\t" "movq %2, %%r8 \n\t"
"movq %1, %%rax \n\t" "movq %1, %%rax \n\t"
"vmcall \n\t" "vmcall \n\t"
...@@ -48,7 +48,7 @@ static inline int lcd_syscall_two_args(int id, ...@@ -48,7 +48,7 @@ static inline int lcd_syscall_two_args(int id,
unsigned long arg1) unsigned long arg1)
{ {
long ret; long ret;
asm( asm volatile(
"movq %3, %%r9 \n\t" "movq %3, %%r9 \n\t"
"movq %2, %%r8 \n\t" "movq %2, %%r8 \n\t"
"movq %1, %%rax \n\t" "movq %1, %%rax \n\t"
...@@ -66,7 +66,7 @@ static inline int lcd_syscall_three_args(int id, ...@@ -66,7 +66,7 @@ static inline int lcd_syscall_three_args(int id,
unsigned long arg2) unsigned long arg2)
{ {
long ret; long ret;
asm( asm volatile(
"movq %4, %%r10 \n\t" "movq %4, %%r10 \n\t"
"movq %3, %%r9 \n\t" "movq %3, %%r9 \n\t"
"movq %2, %%r8 \n\t" "movq %2, %%r8 \n\t"
...@@ -86,7 +86,7 @@ static inline int lcd_syscall_four_args(int id, ...@@ -86,7 +86,7 @@ static inline int lcd_syscall_four_args(int id,
unsigned long arg3) unsigned long arg3)
{ {
long ret; long ret;
asm( asm volatile(
"movq %5, %%r11 \n\t" "movq %5, %%r11 \n\t"
"movq %4, %%r10 \n\t" "movq %4, %%r10 \n\t"
"movq %3, %%r9 \n\t" "movq %3, %%r9 \n\t"
...@@ -108,7 +108,7 @@ static inline int lcd_syscall_five_args(int id, ...@@ -108,7 +108,7 @@ static inline int lcd_syscall_five_args(int id,
unsigned long arg4) unsigned long arg4)
{ {
long ret; long ret;
asm( asm volatile(
"movq %6, %%r12 \n\t" "movq %6, %%r12 \n\t"
"movq %5, %%r11 \n\t" "movq %5, %%r11 \n\t"
"movq %4, %%r10 \n\t" "movq %4, %%r10 \n\t"
......
...@@ -74,7 +74,7 @@ static struct lcd_mem_region lcd_mem_regions[LCD_NR_MEM_REGIONS] = { ...@@ -74,7 +74,7 @@ static struct lcd_mem_region lcd_mem_regions[LCD_NR_MEM_REGIONS] = {
}, },
}; };
/* ------------------------------------------------------------ */ /* PHYSICAL ADDRESS SPACE -------------------------------------------------- */
static int do_grant_and_map_for_mem(cptr_t lcd, struct lcd_create_ctx *ctx, static int do_grant_and_map_for_mem(cptr_t lcd, struct lcd_create_ctx *ctx,
void *mem, gpa_t map_base, void *mem, gpa_t map_base,
...@@ -195,6 +195,30 @@ fail1: ...@@ -195,6 +195,30 @@ fail1:
return ret; return ret;
} }
/* VIRTUAL ADDRESS SPACE ------------------------------ */
static void dump_pg_table(unsigned long *pgtable)
{
unsigned int i;
for (i = 0; i < 512; i++)
printk(" %03u: 0x%016lx\n", i, pgtable[i]);
}
void lcd_dump_virt_addr_space(struct lcd_create_ctx *ctx)
{
unsigned int i;
LIBLCD_MSG(" DUMP LCD GUEST VIRTUAL PAGE TABLES:");
for (i = 0; i < LCD_BOOTSTRAP_PAGE_TABLES_SIZE >> PAGE_SHIFT; i++) {
/*
* XXX: Assumes 512 entries per table, 8 bytes/entry
*/
printk("\n page table %d\n -------------------\n",
i);
dump_pg_table(ctx->gv_pg_tables + i * 512 * 8);
}
}
static void setup_lcd_pmd(struct lcd_mem_region *reg, pmd_t *pmd, static void setup_lcd_pmd(struct lcd_mem_region *reg, pmd_t *pmd,
unsigned int gigabyte_idx) unsigned int gigabyte_idx)
{ {
...@@ -211,7 +235,7 @@ static void setup_lcd_pmd(struct lcd_mem_region *reg, pmd_t *pmd, ...@@ -211,7 +235,7 @@ static void setup_lcd_pmd(struct lcd_mem_region *reg, pmd_t *pmd,
*/ */
gp = LCD_PHYS_BASE + gigabyte_idx * (1UL << 30) + gp = LCD_PHYS_BASE + gigabyte_idx * (1UL << 30) +
k * (1UL << 21); k * (1UL << 21);
set_pmd(&pmd[k], __pmd(gp | reg->flags)); set_pmd(&pmd[k], __pmd(gp | reg->flags | _PAGE_PSE));
} }
} }
...@@ -245,21 +269,26 @@ static void setup_lcd_pud(pud_t *pud) ...@@ -245,21 +269,26 @@ static void setup_lcd_pud(pud_t *pud)
unsigned int i, j, lo, hi; unsigned int i, j, lo, hi;
pud_t *pud_entry; pud_t *pud_entry;
struct lcd_mem_region *reg; struct lcd_mem_region *reg;
gpa_t pmd_gpa;
/*
* pmd's come after pgd and pud
*/
pmd_gpa = gpa_add(LCD_BOOTSTRAP_PAGE_TABLES_GP_ADDR, 2 * PAGE_SIZE);
/* /*
* Map each memory region * Point to correct pmd's for each memory region
*/ */
for (i = 0; i < LCD_NR_MEM_REGIONS; i++) { for (i = 0; i < LCD_NR_MEM_REGIONS; i++) {
reg = &lcd_mem_regions[i]; reg = &lcd_mem_regions[i];
/* /*
* Map entire memory region (some are bigger than 1GB) * Point to correct pmd's
*/ */
lo = reg->offset >> 30; lo = reg->offset >> 30;
hi = lo + (reg->size >> 30); hi = lo + (reg->size >> 30);
for (j = lo; j < hi; j++) { for (j = lo; j < hi; j++) {
pud_entry = &pud[j]; pud_entry = &pud[j];
set_pud(pud_entry, set_pud(pud_entry,
__pud((LCD_PHYS_BASE + j * (1UL << 30)) | __pud(gpa_val(pmd_gpa) | reg->flags));
reg->flags)); pmd_gpa = gpa_add(pmd_gpa, PAGE_SIZE);
} }
} }
} }
...@@ -284,20 +313,28 @@ static void setup_lcd_pgd(pgd_t *pgd) ...@@ -284,20 +313,28 @@ static void setup_lcd_pgd(pgd_t *pgd)
static void setup_virt_addr_space(struct lcd_create_ctx *ctx) static void setup_virt_addr_space(struct lcd_create_ctx *ctx)
{ {
/*
* XXX: Assumes 512 entries / table
*/
void *cursor = ctx->gv_pg_tables;
/* /*
* page tables should already be zero'd out * page tables should already be zero'd out
* *
* Set up root pgd * Set up root pgd
*/ */
setup_lcd_pgd(ctx->gv_pg_tables); setup_lcd_pgd(cursor);
cursor += 512 * sizeof(pgd_t);
/* /*
* Set up pud (only one for high 512 GBs) * Set up pud (only one for high 512 GBs)
* (skip over pgd)
*/ */
setup_lcd_pud(ctx->gv_pg_tables + 512); /* skip over pgd */ setup_lcd_pud(cursor);
cursor += 512 * sizeof(pud_t);
/* /*
* Set up pmd's (one for each 1GB region) * Set up pmd's (one for each 1GB region)
* (skip over pgd and pud)
*/ */
setup_lcd_pmds(ctx->gv_pg_tables + 1024); /* skip over pgd and pud */ setup_lcd_pmds(cursor);
} }
static int setup_addr_spaces(cptr_t lcd, struct lcd_create_ctx *ctx, static int setup_addr_spaces(cptr_t lcd, struct lcd_create_ctx *ctx,
...@@ -325,6 +362,8 @@ fail1: /* just return non-zero ret; caller will free mem */ ...@@ -325,6 +362,8 @@ fail1: /* just return non-zero ret; caller will free mem */
return ret; return ret;
} }
/* -------------------------------------------------- */
static int init_create_ctx(struct lcd_create_ctx **ctx_out, char *mname) static int init_create_ctx(struct lcd_create_ctx **ctx_out, char *mname)
{ {
struct lcd_create_ctx *ctx; struct lcd_create_ctx *ctx;
...@@ -361,8 +400,8 @@ static void destroy_create_ctx(struct lcd_create_ctx *ctx) ...@@ -361,8 +400,8 @@ static void destroy_create_ctx(struct lcd_create_ctx *ctx)
if (ctx->stack) if (ctx->stack)
lcd_free_pages(lcd_virt_to_head_page(ctx->stack), lcd_free_pages(lcd_virt_to_head_page(ctx->stack),
LCD_STACK_ORDER); LCD_STACK_ORDER);
if (ctx->gv_pgd) if (ctx->gv_pg_tables)
lcd_free_pages(lcd_virt_to_head_page(ctx->gv_pgd), lcd_free_pages(lcd_virt_to_head_page(ctx->gv_pg_tables),
LCD_BOOTSTRAP_PAGE_TABLES_ORDER); LCD_BOOTSTRAP_PAGE_TABLES_ORDER);
if (ctx->lcd_boot_info) if (ctx->lcd_boot_info)
lcd_free_pages(lcd_virt_to_head_page(ctx->lcd_boot_info), lcd_free_pages(lcd_virt_to_head_page(ctx->lcd_boot_info),
......
...@@ -282,7 +282,7 @@ __lcd_build_checks__(void) ...@@ -282,7 +282,7 @@ __lcd_build_checks__(void)
/* All memory should fit into 512 GBs. This is because we only /* All memory should fit into 512 GBs. This is because we only
* use one pud (internally in common/module_create.c). */ * use one pud (internally in common/module_create.c). */
BUILD_BUG_ON((LCD_KERNEL_MODULE_REGION_OFFSET + BUILD_BUG_ON((LCD_KERNEL_MODULE_REGION_OFFSET +
LCD_KERNEL_MODULE_REGION_SIZE) >= (512UL << 30)); LCD_KERNEL_MODULE_REGION_SIZE) > (512UL << 30));
} }
/* HELPERS -------------------------------------------------- */ /* HELPERS -------------------------------------------------- */
......
...@@ -64,4 +64,5 @@ ccflags-y += \ ...@@ -64,4 +64,5 @@ ccflags-y += \
-I$(LCD_DOMAINS_TOP_SRC_DIR)/arch/$(ARCH)/include \ -I$(LCD_DOMAINS_TOP_SRC_DIR)/arch/$(ARCH)/include \
-I$(LIBLCD_BUILD_DIR)/libcap.install/include \ -I$(LIBLCD_BUILD_DIR)/libcap.install/include \
-I$(LCD_DOMAINS_TOP_SRC_DIR)/config/isolated \ -I$(LCD_DOMAINS_TOP_SRC_DIR)/config/isolated \
-DCONFIG_LAZY_THC -DCONFIG_LAZY_THC \
-DMODULE
#! /bin/bash
# Reload microkernel
scripts/rmmk
scripts/insmk
\ No newline at end of file
...@@ -14,9 +14,7 @@ static int __noreturn __init liblcd_test_lcd_init(void) ...@@ -14,9 +14,7 @@ static int __noreturn __init liblcd_test_lcd_init(void)
{ {
int r = 0; int r = 0;
r = lcd_enter(); r = lcd_enter();
goto out; goto out;
out: out:
lcd_exit(r); lcd_exit(r);
} }
......
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