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

Starts glue for PMFS.

Sets up vfs klcd, and most of the code in place in boot module
for setting up pmfs and vfs.

(Need to squash and merge some code from the mainline.)
parent 18fc3b79
......@@ -5,18 +5,9 @@
#ifndef LCD_DOMAINS_DISPATCH_LOOP_H
#define LCD_DOMAINS_DISPATCH_LOOP_H
#ifdef LCD_ISOLATE
#include <lcd-domains/liblcd-config.h>
#endif
#include <linux/list.h>
#include <lcd-domains/types.h>
#ifdef LCD_ISOLATE
#include <lcd-domains/liblcd-hacks.h>
#endif
/**
* This represents an ipc channel.
*
......
......@@ -56,7 +56,7 @@ int klcd_create_module_lcd(cptr_t *slot_out, char *mname,
void klcd_destroy_module_lcd(cptr_t lcd, struct lcd_info *mi,
cptr_t mloader_endpoint);
int klcd_dump_boot_info(struct lcd_info *mi);
struct lcd_utcb * klcd_get_utcb(void);
/* DEBUG ------------------------------------------------------------ */
......@@ -125,6 +125,13 @@ KLCD_MK_REG_ACCESS(5)
KLCD_MK_REG_ACCESS(6)
KLCD_MK_REG_ACCESS(7)
/* GET UTCB -------------------------------------------------- */
static inline struct lcd_utcb * lcd_get_utcb(void)
{
return klcd_get_utcb();
}
/* KLCD SPECIFICS -------------------------------------------------- */
/**
......@@ -385,6 +392,7 @@ static inline int lcd_init_cptr(void)
static inline void lcd_destroy_cptr(void)
{
klcd_destroy_cptr(current->cptr_cache);
current->cptr_cache = NULL;
}
/**
* Find an unused cptr (a cptr that refers to an unused cnode).
......
......@@ -210,6 +210,7 @@ void lcd_free_memcg_kmem_pages(unsigned long addr, unsigned int order);
/**
* Create a synchronous endpoint, capability stored in slot_out.
*/
int __lcd_create_sync_endpoint(cptr_t slot);
int lcd_create_sync_endpoint(cptr_t *slot_out);
/**
* Synchronous send. Set message registers using lcd_set_r0(), lcd_set_r1(),
......
......@@ -20,6 +20,15 @@ int lcd_enter(void)
goto fail;
}
LIBLCD_MSG("cptr cache ready");
/*
* Create our call endpoint (for call/reply interactions)
*/
ret = __lcd_create_sync_endpoint(LCD_CPTR_CALL_ENDPOINT);
if (ret) {
LIBLCD_ERR("creating call endpoint");
goto fail;
}
LIBLCD_MSG("call endpoint created and installed");
/*
* Set up page alloc and kmalloc
*/
......
......@@ -4,6 +4,15 @@
#include <lcd-domains/liblcd-hacks.h>
int __lcd_create_sync_endpoint(cptr_t slot)
{
/*
* Get new endpoint
*/
lcd_set_cr0(slot);
return LCD_DO_SYSCALL(LCD_SYSCALL_SYNC_EP);
}
int lcd_create_sync_endpoint(cptr_t *slot_out)
{
int ret;
......@@ -18,10 +27,9 @@ int lcd_create_sync_endpoint(cptr_t *slot_out)
/*
* Get new endpoint
*/
lcd_set_cr0(*slot_out);
ret = LCD_DO_SYSCALL(LCD_SYSCALL_SYNC_EP);
ret = __lcd_create_sync_endpoint(*slot_out);
if (ret) {
LIBLCD_ERR("create sync ep syscall");
LIBLCD_ERR("create sync endpoint");
goto fail2;
}
......
......@@ -142,25 +142,6 @@ config LCD_TEST_MOD_CREATE_KLCD_KLCD
# --------------------------------------------------
config LCD_TEST_MOD_PMFS
bool "Persistent Memory File System (PMFS) Example"
depends on LCD_DOMAINS
depends on HAS_IOMEM
select CRC16
default y
select LCD_TEST_MOD_PMFS_BOOT
select LCD_TEST_MOD_PMFS_LCD
---help---
Isolation of PMFS file system.
config LCD_TEST_MOD_PMFS_BOOT
tristate
depends on LCD_TEST_MOD_PMFS
default m
config LCD_TEST_MOD_PMFS_LCD
tristate
depends on LCD_TEST_MOD_PMFS
menuconfig LCD_TEST_MOD_GLUE_EXAMPLE
bool "Example exercising IDL and glue"
......@@ -199,6 +180,34 @@ config LCD_TEST_MOD_GLUE_EXAMPLE_BOOT
default m
endif
# --------------------------------------------------
config LCD_TEST_MOD_PMFS
bool "Persistent Memory File System (PMFS) Example"
depends on LCD_DOMAINS
depends on HAS_IOMEM
select CRC16
default y
select LCD_TEST_MOD_PMFS_BOOT
select LCD_TEST_MOD_PMFS_LCD
select LCD_TEST_MOD_PMFS_VFS
---help---
Isolation of PMFS file system.
config LCD_TEST_MOD_PMFS_BOOT
tristate
depends on LCD_TEST_MOD_PMFS
default m
config LCD_TEST_MOD_PMFS_LCD
tristate
depends on LCD_TEST_MOD_PMFS
default m
config LCD_TEST_MOD_PMFS_VFS
tristate
depends on LCD_TEST_MOD_PMFS
default m
# --------------------------------------------------
......
......@@ -232,6 +232,7 @@ void __lcd_cnode_put(struct cnode *c);
enum lcd_type {
LCD_TYPE_ISOLATED,
LCD_TYPE_NONISOLATED,
LCD_TYPE_TOP,
};
enum lcd_xmit_status {
......
......@@ -1375,44 +1375,6 @@ fail1:
return ret;
}
int __klcd_do_call_endpoint(cptr_t lcd)
{
cptr_t call_endpoint;
int ret;
/*
* Create an endpoint for the lcd, for its call endpoint.
*
* This will temporarily go in the caller's (the code creating the
* lcd) cspace.
*/
ret = lcd_create_sync_endpoint(&call_endpoint);
if (ret) {
LCD_ERR("failed to create call endpoint");
goto fail1;
}
/*
* Grant access to call endpoint in reserved slot
*/
ret = lcd_cap_grant(lcd, call_endpoint, LCD_CPTR_CALL_ENDPOINT);
if (ret) {
LCD_ERR("failed to grant call endpoint");
goto fail2;
}
ret = 0;
goto out;
out:
fail2:
/*
* Delete cap to call endpoint, lcd becomes sole owner (or if
* we failed, endpoint gets freed)
*/
lcd_cap_delete(call_endpoint);
fail1:
return ret;
}
int klcd_create_module_lcd(cptr_t *slot_out, char *mname,
cptr_t mloader_endpoint, struct lcd_info **mi)
......@@ -1455,20 +1417,11 @@ int klcd_create_module_lcd(cptr_t *slot_out, char *mname,
LCD_ERR("failed to config lcd");
goto fail3;
}
/*
* Provide the lcd with a call endpoint
*/
ret = __klcd_do_call_endpoint(*slot_out);
if (ret) {
LCD_ERR("failed to set up call endpoint");
goto fail4;
}
/*
* Done!
*/
return 0;
fail4:
fail3:
fail2:
/*
......
......@@ -81,20 +81,11 @@ int klcd_create_module_klcd(cptr_t *slot_out, char *mname)
LCD_ERR("failed to config lcd");
goto fail2;
}
/*
* Provide the lcd with a call endpoint
*/
ret = __klcd_do_call_endpoint(*slot_out);
if (ret) {
LCD_ERR("failed to set up call endpoint");
goto fail3;
}
/*
* Done!
*/
return 0;
fail3:
fail2:
/*
* Remove module from host
......
......@@ -14,23 +14,44 @@ int klcd_enter(void)
{
int ret;
/*
* Set up cptr cache
* This sets up the runtime environment for non-isolated
* threads.
*
* First, if we weren't created by another klcd, then
* we should do __klcd_enter to set up our cspace, utcb,
* and so on.
*/
if (!current->lcd) {
ret = __klcd_enter();
if (ret) {
LCD_ERR("enter");
goto fail1;
}
}
/*
* Set up our cptr cache
*/
ret = lcd_init_cptr();
if (ret) {
LCD_ERR("cptr cache init");
goto fail1;
}
ret = __klcd_enter();
if (ret) {
LCD_ERR("enter");
goto fail2;
}
/*
* Create our call endpoint (for receing rpc replies)
*/
ret = __lcd_create_sync_endpoint(current->lcd, LCD_CPTR_CALL_ENDPOINT);
if (ret) {
LIBLCD_ERR("creating call endpoint");
goto fail3;
}
return 0;
fail3:
fail2:
lcd_destroy_cptr();
fail1:
/* This will do teardown */
klcd_exit(ret);
return ret;
}
......@@ -40,14 +61,21 @@ void klcd_exit(int retval)
* Return value is ignored for now
*/
/*
* Exit from lcd mode
*/
__klcd_exit();
/*
* Destroy cptr cache
*/
lcd_destroy_cptr();
if (current->lcd) {
/*
* Exit from lcd mode
*/
__klcd_exit();
}
if (current->cptr_cache) {
/*
* Destroy cptr cache
*/
lcd_destroy_cptr();
}
/* (Call endpoint should be auto-destroyed when we do
* __klcd_exit and destroy the cspace.) */
}
/* EXPORTS -------------------------------------------------- */
......
......@@ -43,6 +43,13 @@ __KLCD_MK_REG_ACCESS(5)
__KLCD_MK_REG_ACCESS(6)
__KLCD_MK_REG_ACCESS(7)
/* UTCB -------------------------------------------------- */
struct lcd_utcb *klcd_get_utcb(void)
{
return current->lcd->utcb;
}
/* IPC -------------------------------------------------- */
int klcd_create_sync_endpoint(cptr_t *slot_out)
......@@ -100,3 +107,4 @@ EXPORT_SYMBOL(klcd_send);
EXPORT_SYMBOL(klcd_recv);
EXPORT_SYMBOL(klcd_call);
EXPORT_SYMBOL(klcd_reply);
EXPORT_SYMBOL(klcd_get_utcb);
......@@ -587,9 +587,9 @@ int __klcd_enter(void)
*/
set_lcd_status(lcd, LCD_STATUS_RUNNING);
/*
* Set type as non-isolated
* Set type as "top" - a "root" LCD owned by no one (gasp!)
*/
lcd->type = LCD_TYPE_NONISOLATED;
lcd->type = LCD_TYPE_TOP;
return 0;
......@@ -602,8 +602,17 @@ fail1:
void __klcd_exit(void)
{
struct lcd *lcd;
lcd = current->lcd;
if (lcd->type != LCD_TYPE_TOP) {
/*
* The caller is a klcd that was created by someone
* else. We will let their creator destroy them (when
* they delete the capability to the klcd).
*/
return;
}
BUG_ON(lcd_status_dead(lcd)); /* lcd shouldn't be dead already */
......
vfs_callee.lds
\ No newline at end of file
#---------- PMFS LCD ----------
obj-$(CONFIG_LCD_TEST_MOD_PMFS_BOOT) += boot/
obj-$(CONFIG_LCD_TEST_MOD_PMFS_LCD) += pmfs-lcd/
obj-$(CONFIG_LCD_TEST_MOD_PMFS_VFS) += vfs-klcd/
# Flag to toggle some coditional compilation in the original source code
# for isolation
ccflags-y := -DLCD_ISOLATE
# The original code
obj-$(CONFIG_LCD_TEST_MOD_PMFS_LCD) += lcd-test-mod-pmfs-lcd.o
lcd-test-mod-pmfs-lcd-y += $(addprefix pmfs/, bbuild.o \
balloc.o \
dir.o \
file.o \
inode.o \
namei.o \
super.o \
symlink.o \
ioctl.o \
journal.o \
xip.o \
wprotect.o)
# LCD Main
lcd-test-mod-pmfs-lcd-y += $(addprefix lcd/, main.o)
# LIBLCD
lcd-test-mod-pmfs-lcd-y += $(LIBLCD)
# Glue
lcd-test-mod-pmfs-lcd-y += $(addprefix glue/, vfs_caller.o \
bdi_caller.o)
#---------- BOOT ----------
obj-$(CONFIG_LCD_TEST_MOD_PMFS_BOOT) += lcd-test-mod-pmfs-boot.o
lcd-test-mod-pmfs-boot-y += $(addprefix boot/, main.o)
obj-$(CONFIG_LCD_TEST_MOD_PMFS_BOOT) += lcd-test-mod-pmfs-boot.o
lcd-test-mod-pmfs-boot-y += main.o
......@@ -13,6 +13,9 @@ static int boot_main(void)
int ret;
struct lcd_info *mi;
cptr_t lcd;
cptr_t vfs;
cptr_t endpoint;
cptr_t dest1, dest2;
/*
* Enter lcd mode
......@@ -23,34 +26,96 @@ static int boot_main(void)
goto fail1;
}
/*
* Create a new lcd
* Create VFS channel
*/
ret = lcd_create_sync_endpoint(&endpoint);
if (ret) {
LIBLCD_ERR("create endpoint");
goto fail2;
}
/* CREATE LCDS -------------------------------------------------- */
/*
* Create vfs klcd
*/
ret = klcd_create_module_klcd(&vfs, "lcd_test_mod_pmfs_vfs");
if (ret) {
LIBLCD_ERR("create vfs klcd");
goto fail2;
}
/*
* Create pmfs lcd
*/
ret = lcd_create_module_lcd(&lcd, "lcd_test_mod_pmfs_lcd",
LCD_CPTR_NULL, &mi);
if (ret) {
LIBLCD_ERR("create module lcd");
goto fail2;
goto fail3;
}
/* GRANT ENDPOINT TO PMFS ------------------------------ */
/*
* Alloc dest slot
*/
ret = __lcd_alloc_cptr(mi->cache, &dest1);
if (ret) {
LIBLCD_ERR("failed to alloc cptr");
goto fail4;
}
/*
* Grant
*/
ret = lcd_cap_grant(lcd, endpoint, dest1);
if (ret) {
LIBLCD_ERR("failed to grant endpoint to lcd1");
goto fail5;
}
/* GRANT ENDPOINT TO VFS ------------------------------ */
dest2 = __cptr(3);
ret = lcd_cap_grant(vfs, endpoint, dest2);
if (ret) {
LIBLCD_ERR("failed to grant endpoint to vfs");
goto fail6;
}
/* DUMP BOOT INFO FOR PMFS ------------------------------ */
/*
* Set up boot info
*/
ret = lcd_dump_boot_info(mi);
if (ret) {
LIBLCD_ERR("dump boot info");
goto fail3;
goto fail7;
}
/* RUN -------------------------------------------------- */
/*
* Run vfs
*/
ret = lcd_run(vfs);
if (ret) {
LIBLCD_ERR("run vfs");
goto fail8;
}
/*
* Run it
* Run pmfs
*/
ret = lcd_run(lcd);
if (ret) {
LIBLCD_ERR("run lcd");
goto fail4;
LIBLCD_ERR("run pmfs");
goto fail9;
}
/*
* Wait for 1 second
* Wait for 2 seconds
*/
msleep(1000);
msleep(2000);
/*
* Tear everything down
*/
......@@ -58,10 +123,17 @@ static int boot_main(void)
goto out;
out:
fail9:
fail8:
fail7:
fail6:
fail5:
fail4:
fail3:
lcd_destroy_module_lcd(lcd, mi, LCD_CPTR_NULL);
fail3:
klcd_destroy_module_klcd(vfs, "lcd_test_mod_pmfs_vfs");
fail2:
/* frees endpoint */
lcd_exit(0);
fail1:
return ret;
......
/* REGISTER_FILESYSTEM */
rpc int register_filesystem(projection <struct file_system_type> *fs);
# Flag to toggle some coditional compilation in the original source code
# for isolation
ccflags-y := -DLCD_ISOLATE
obj-$(CONFIG_LCD_TEST_MOD_PMFS_LCD) += lcd-test-mod-pmfs-lcd.o
# LCD Main
lcd-test-mod-pmfs-lcd-y += main.o
# The original code
lcd-test-mod-pmfs-lcd-y += $(addprefix pmfs/, bbuild.o \
balloc.o \
dir.o \
file.o \
inode.o \
namei.o \
super.o \
symlink.o \
ioctl.o \
journal.o \
xip.o \
wprotect.o)
# LIBLCD
lcd-test-mod-pmfs-lcd-y += ../$(LIBLCD)
# Glue
lcd-test-mod-pmfs-lcd-y += $(addprefix glue/, \
vfs_caller.o \
bdi_caller.o)
......@@ -7,9 +7,75 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <lcd-domains/liblcd.h>
#include <lcd-domains/dispatch_loop.h>
#include <lcd-domains/liblcd-hacks.h>
/* LOOP ---------------------------------------- */
#if 0
static int dispatch_minix_channel(struct ipc_channel *channel)
{
switch (lcd_r0()) {
default:
LIBLCD_ERR("unexpected function label %d",
lcd_r0());
return -EINVAL;
}
return 0;
}
static int dispatch_channel(struct ipc_channel *channel)
{
switch (channel->type) {
default:
LIBLCD_ERR("unexpected channel type %d",
channel->type);
return -EINVAL;
}
}
static void loop(struct dispatch_ctx *ctx)
{
struct list_head *cursor;
struct ipc_channel *channel;
int ret;
int count = 0;
for (;;) {
count += 1;
list_for_each(cursor, &ctx->channel_list) {
channel = list_entry(cursor,
struct ipc_channel,
channel_list);
ret = lcd_recv(channel->channel_cptr);
if (ret) {
LIBLCD_ERR("lcd recv");
return;
}
ret = dispatch_channel(channel);
if (ret) {
LIBLCD_ERR("dispatch channel");
return;
}
}
}
}
#endif
/* INIT/EXIT -------------------------------------------------- */
int init_pmfs_fs(void);
void exit_pmfs_fs(void);
......
obj-$(CONFIG_LCD_TEST_MOD_PMFS_VFS) += lcd-test-mod-pmfs-vfs.o
# Dispatch loop, etc.
lcd-test-mod-pmfs-vfs-y += main.o
# Glue
lcd-test-mod-pmfs-vfs-y += $(addprefix glue/, vfs_callee.o)
#include <lcd-domains/dispatch_loop.h>
#include "../internal.h"