Commit 29605fc1 authored by Charlie Jacobsen's avatar Charlie Jacobsen

Merges reorganize into master. Not tested yet.

parents bfea6263 f49008eb
# Ignore most files made by `bootstrap'.
Makefile.in
*Makefile.in
aclocal.m4
autom4te.cache
config.h.in
configure
src/kernel/Makefile.in
src/user/Makefile.in
src/Makefile.in
include/Makefile.in
Makefile.in
test/kernel/Makefile.in
test/user/Makefile.in
test/Makefile.in
*top_level.in
# Ignore other files.
config.log
......
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = include src test
SUBDIRS = src
DIST_DIRS = src
......@@ -5,13 +5,133 @@ AC_PREREQ([2.69])
AC_INIT([libcap], [0.1])
AC_CONFIG_SRCDIR([src/common/cptr_cache.c])
AC_CONFIG_AUX_DIR(autoconf)
AC_CONFIG_HEADERS([include/libcap_config.h])
AC_CONFIG_HEADERS([config.h])
LT_INIT
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([subdir-objects foreign])
# --------------------------------------------------
# Host check
# --------------------------------------------------
AC_CANONICAL_HOST
AC_MSG_CHECKING([for OS X host])
AS_CASE([$host],
[-*-*-darwin*],
[
AC_MSG_RESULT([yes])
AC_DEFINE(CAP_OS_DARWIN, 1, [Build for OS X host])
AC_SUBST(CAP_OS_DARWIN)
],
[*],
[
AC_MSG_RESULT([no])
])
# --------------------------------------------------
# libcap features, packages, and config
# --------------------------------------------------
# Platform = user xor kernel
AC_ARG_VAR([PLATFORM],
[The platform to build for @{:@user|kernel@:}@ (default=user)])
AS_CASE([$PLATFORM],
[user],
[PLATFORM_DIR=platform/user],
[kernel],
[PLATFORM_DIR=platform/kernel],
[*],
[
AC_MSG_NOTICE([PLATFORM (val=$PLATFORM) unset or invalid.])
AC_MSG_NOTICE([Defaulting to PLATFORM=user.])
PLATFORM=user
PLATFORM_DIR=platform/user
])
AC_MSG_NOTICE([Building for PLATFORM=$PLATFORM.])
AC_SUBST(PLATFORM)
AC_SUBST(PLATFORM_DIR)
# CSpace depth. We use bits to enforce that the depth is a power of 2.
AC_ARG_VAR([CSPACE_DEPTH_BITS],
[Set CSPACE depth to 2^CSPACE_DEPTH_BITS (default=2, default depth=4)])
AS_IF([test "x$CSPACE_DEPTH_BITS" = "x"],
[CSPACE_DEPTH_BITS="2"]) # default
AS_CASE([$CSPACE_DEPTH_BITS],
[@<:@0-8@:>@],
[CAP_CSPACE_DEPTH_BITS=$CSPACE_DEPTH_BITS],
[*],
[
AC_MSG_ERROR([CSpace depth bits (val=$CSPACE_DEPTH_BITS) invalid. Please choose a value between 0 and 8.])
])
AC_MSG_NOTICE([CSpace depth bits = $CAP_CSPACE_DEPTH_BITS.])
AC_SUBST(CAP_CSPACE_DEPTH_BITS)
# CNode table size. Again, we use bits to enforce that it's a power of 2.
AC_ARG_VAR([CSPACE_CNODE_TABLE_BITS],
[CNode tables have 2^CSPACE_CNODE_TABLE_BITS total slots (default=6, default size=64)])
AS_IF([test "x$CSPACE_CNODE_TABLE_BITS" = "x"],
[CSPACE_CNODE_TABLE_BITS="6"]) # default
AS_CASE([$CSPACE_CNODE_TABLE_BITS],
[@<:@1-9@:>@],
[CAP_CSPACE_CNODE_TABLE_BITS=$CSPACE_CNODE_TABLE_BITS],
[*],
[
AC_MSG_ERROR([CSpace cnode table bits (val=$CSPACE_CNODE_TABLE_BITS) invalid. Please choose a value between 1 and 9.])
])
AC_MSG_NOTICE([CNode table bits = $CAP_CSPACE_CNODE_TABLE_BITS.])
AC_SUBST(CAP_CSPACE_CNODE_TABLE_BITS)
# Kernel module build?
AS_IF([test "x$PLATFORM" = "xkernel"],
[
# Build libcap as kernel module, in addition to static lib.a
AC_ARG_ENABLE([kernel_module],
[AS_HELP_STRING([--disable-kernel-module],
[Disable kernel module build (default=no)])],
[],
[enable_kernel_module="yes"])
AM_CONDITIONAL(ENABLE_KERNEL_MODULE,
[test "x$enable_kernel_module" = "xyes"])
AM_COND_IF([ENABLE_KERNEL_MODULE],
[AC_MSG_NOTICE([Building kernel module.])],
[AC_MSG_NOTICE([Not building kernel module.])])
],
[
AM_CONDITIONAL(ENABLE_KERNEL_MODULE,
[false])
])
AC_ARG_ENABLE([test_build],
[AS_HELP_STRING([--enable-test-build],
[Enable building test applications (default=no)])],
[],
[enable_test_build="no"])
AM_CONDITIONAL(ENABLE_TEST_BUILD,
[test "x$enable_test_build" = "xyes"])
AM_COND_IF([ENABLE_TEST_BUILD],
[AC_MSG_NOTICE([Building tests.])],
[AC_MSG_NOTICE([Not building tests.])])
# --------------------------------------------------
# Checks for programs.
# --------------------------------------------------
AC_PROG_CC
AC_PROG_CPP
AC_PROG_CXX
......@@ -19,99 +139,135 @@ AC_PROG_LIBTOOL
AC_PROG_LN_S
AC_PROG_MKDIR_P
AC_PROG_INSTALL
AC_PROG_AWK # for a calculation below
# --------------------------------------------------
# Checks for libraries.
# FIXME: Replace `main' with a function in `-lpthread':
AC_CHECK_LIB([pthread], [pthread_create])
# --------------------------------------------------
# Check for pthreads
AS_IF([test "x$PLATFORM" = "xuser"],
[AC_CHECK_LIB([pthread], [pthread_create])])
# Check glib (the gangsta lib)
AS_IF([test "x$PLATFORM" = "xuser"],
[
GLIB=/usr # default prefix
AC_ARG_WITH([glib],
[AS_HELP_STRING([--with-glib=DIRECTORY],
[find glib install in DIRECTORY])],
[MAYBE_GLIB="$with_glib"])
# Set up vars for the glib check
old_CFLAGS=$CFLAGS
old_LDFLAGS=$LDFLAGS
old_PKG_CONFIG_PATH=$PKG_CONFIG_PATH
# (It's tricky to try to locate the .pc file, so we don't
# try to do the absolute path with the call to pkg-config)
GLIB_INCLUDES=`pkg-config --cflags glib-2.0`
GLIB_LIBS=`pkg-config --libs glib-2.0`
CFLAGS="${GLIB_INCLUDES} $CFLAGS"
LDFLAGS="${GLIB_LIBS} $LDFLAGS"
AC_CHECK_TYPE(gpointer,
[],
[AC_MSG_ERROR([Your glib includes seem wrong!])],
[[#include <glib.h>]])
AC_CHECK_LIB(glib-2.0,
g_slice_alloc0,
[],
[AC_MSG_ERROR(Your glib does not have g_slice_alloc0; upgrade to 2.10+)])
# Restore vars
CFLAGS="$old_CFLAGS"
LDFLAGS="$old_LDFLAGS"
PKG_CONFIG_PATH="$old_PKG_CONFIG_PATH"
AC_SUBST(GLIB_INCLUDES)
AC_SUBST(GLIB_LIBS)
])
# Check for kernel build system
AS_IF([test "x$PLATFORM" = "xkernel"],
[
KDIR=/lib/modules/`uname -r`/build # default location of build system
AC_ARG_WITH([kernel-headers],
[AS_HELP_STRING([--with-kernel-headers=DIRECTORY],
[find Linux kernel build stuff in DIRECTORY])],
[KDIR="$with_kernel_headers"])
# Sanity check it (in the future, we could maybe check the
# kernel version in the top of the kernel Makefile)
AC_CHECK_FILE($KDIR/Makefile,
[AC_MSG_NOTICE([Found kernel Makefile in $KDIR])],
[AC_MSG_ERROR([Could not find kernel Makefile in $KDIR!])])
AC_SUBST(KDIR)
])
# --------------------------------------------------
# Checks for header files.
# --------------------------------------------------
AC_CHECK_HEADERS([stdint.h stdlib.h string.h unistd.h])
# Checks for typedefs, structures, and compiler characteristics.
# --------------------------------------------------
# Checks for types
# --------------------------------------------------
AC_CHECK_HEADER_STDBOOL
AC_C_INLINE
AC_TYPE_SIZE_T
AC_TYPE_UINT8_T
AC_CHECK_SIZEOF([unsigned long])
# Sanity check cspace depth and cnode table size, now that we
# have the size of an unsigned long.
AC_MSG_CHECKING([that cspace config is sane])
cptr_size=`$AWK "BEGIN { print (2 ** $CAP_CSPACE_DEPTH_BITS) * ($CAP_CSPACE_CNODE_TABLE_BITS - 1) + $CAP_CSPACE_DEPTH_BITS }"`
long_size=`$AWK "BEGIN { print $ac_cv_sizeof_unsigned_long * 8 }"`
AS_IF([test "$cptr_size" -gt "$long_size"],
[
AC_MSG_RESULT([no])
AC_MSG_NOTICE([The cspace configuration you chose won't work.])
AC_MSG_NOTICE([Your choice must fulfill this:])
AC_MSG_NOTICE([ let a = 2^cspace depth bits])
AC_MSG_NOTICE([ let b = a * (table bits - 1) + cspace depth bits])
AC_MSG_NOTICE([ let c = bits in an unsigned long])
AC_MSG_NOTICE([ require: b <= c])
AC_MSG_NOTICE([(This has to do with packing bits into an unsigned long for cptr's.)])
AC_MSG_NOTICE([FYI - The default (depth bits = 2, table bits = 6) should work on 64- and 32-bit.])
AC_MSG_ERROR([Please re-configure with different cspace settings.])
])
AC_MSG_RESULT([yes])
# --------------------------------------------------
# Checks for structures
# --------------------------------------------------
# --------------------------------------------------
# Checks for compiler characteristics
# --------------------------------------------------
AC_C_INLINE
# --------------------------------------------------
# Checks for library functions.
# --------------------------------------------------
AC_FUNC_MALLOC
AC_CHECK_FUNCS([memset strdup])
# Check size of unsigned long (determines cspace sizing, cptr ABI, and so on)
AC_CHECK_SIZEOF([unsigned long])
#
# Check glib.
#
GLIB=/usr
AC_ARG_WITH([glib],
AS_HELP_STRING([--with-glib=DIRECTORY],
[find glib install in DIRECTORY]),
[GLIB="$with_glib"])
if test ! "$GLIB" = "/usr" ; then
old_PKG_CONFIG_PATH="$PKG_CONFIG_PATH"
export PKG_CONFIG_PATH="$GLIB/lib/pkgconfig"
fi
old_CFLAGS=$CFLAGS
old_LDFLAGS=$LDFLAGS
GLIB_INCLUDES=`pkg-config --cflags glib-2.0`
GLIB_LIBS=`pkg-config --libs glib-2.0`
CFLAGS="${GLIB_INCLUDES} $CFLAGS"
LDFLAGS="${GLIB_LIBS} $LDFLAGS"
AC_CHECK_TYPE(gpointer,
[],
[AC_MSG_ERROR([Your glib includes seem wrong!])],
[[#include <glib.h>]])
AC_CHECK_LIB(glib-2.0,g_slice_alloc0,[],[AC_MSG_ERROR(Your glib does not have g_slice_alloc0; upgrade to 2.10+)])
if test ! "$GLIB" = "/usr" ; then
export PKG_CONFIG_PATH="$old_PKG_CONFIG_PATH"
fi
CFLAGS="$old_CFLAGS"
LDFLAGS="$old_LDFLAGS"
AC_SUBST(GLIB_INCLUDES)
AC_SUBST(GLIB_LIBS)
#
# Check kernel
#
if test "x$KDIR" = "x" ; then
KDIR=/lib/modules/`uname -r`/build
fi
AC_ARG_WITH([kernel],
AS_HELP_STRING([--with-kernel=DIRECTORY],
[find Linux kernel build stuff in DIRECTORY]),
[KDIR="$with_kernel"])
AC_ARG_ENABLE(kernel,
AS_HELP_STRING([--disable-kernel],
[Disable kernel module build and test]))
if test "x$enableval" = "xno"; then
ENABLE_KERNEL=0;
MAYBE_KERNEL=
else
ENABLE_KERNEL=1;
MAYBE_KERNEL=kernel
fi
AC_SUBST(ENABLE_KERNEL)
AC_SUBST(MAYBE_KERNEL)
if test ${ENABLE_KERNEL} -eq 1 ; then
if test ! -f $KDIR/Makefile ; then
AC_MSG_ERROR([Could not find kernel Makefile in $KDIR!])
else
AC_MSG_NOTICE([Found kernel Makefile in $KDIR])
fi
fi
if test ${ENABLE_KERNEL} -eq 1 ; then
#
# This is pretty horrible, but I can't find a way to tell the kernel
# build that 1) Makefile is in the object tree (the output dir); and 2)
# the sources are in the source tree. The kernel expects the Makefile
# to be with the sources. So, ugh, but oh well.
#
AC_CONFIG_LINKS([src/kernel/cap.c:src/common/cap.c
src/kernel/cptr_cache.c:src/common/cptr_cache.c
src/kernel/cap_module.c:src/kernel/cap_module.c])
fi
# --------------------------------------------------
# Config files
# --------------------------------------------------
AC_CONFIG_COMMANDS([privconfigh],
[egrep 'define (PACKAGE|VERSION)' include/libcap_config.h > include/libcap_config_internal.h
......@@ -120,12 +276,26 @@ AC_CONFIG_COMMANDS([privconfigh],
AC_CONFIG_FILES(
Makefile
include/Makefile
src/Makefile
src/user/Makefile
src/kernel/Makefile
test/Makefile
test/user/Makefile
test/kernel/Makefile
src/common/Makefile
src/include/Makefile
src/include/libcap_config.h
src/platform/Makefile
src/platform/kernel/Makefile
src/platform/kernel/src/Makefile
src/platform/kernel/module/Makefile
src/platform/kernel/module/Kbuild
src/platform/kernel/Kbuild
src/platform/kernel/include/Makefile
src/platform/kernel/test/Makefile
src/platform/user/Makefile
src/platform/user/src/Makefile
src/platform/user/include/Makefile
src/platform/user/test/Makefile
)
AC_OUTPUT
SUBDIRS = user $(MAYBE_KERNEL)
DIST_SUBDIRS = user kernel
#include_HEADERS= $(top_srcdir)/include
COMMON_SRCS = \
common/cap.o \
common/cptr_cache.o
COMMON_INCLUDES = include
SUBDIRS = common include $(PLATFORM_DIR)
DIST_SUBDIRS = common include platform
......@@ -6,12 +6,9 @@
* Anton Burtsev <aburtsev@flux.utah.edu>
* Charles Jacobsen <charlesj@cs.utah.edu>
* Copyright: University of Utah
*
* See Documentation/lcd-domains/cap.txt for extensive info.
*/
#include "libcap.h"
#include "libcap_types.h"
#include "libcap_internal.h"
#include <libcap.h>
#include <libcap_internal.h>
struct cdt_cache {
cap_mutex_t lock;
......@@ -33,20 +30,40 @@ static unsigned long long cspace_id = 0;
int cap_init(void)
{
int ret;
/*
* Initialize cptr cache subsystem
*/
ret = __cptr_init();
if (ret) {
CAP_ERR("failed to initialize cptr cache subsystem");
goto fail1;
}
/*
* Initialize cdt cache
*/
cdt_cache.cdt_root_cache = cap_cache_create(cdt_root_node);
if (!cdt_cache.cdt_root_cache) {
CAP_ERR("failed to initialize cdt_root_node allocator");
return -ENOMEM;
return -1;
ret = -ENOMEM;
goto fail2;
}
/*
* Initialize locks
*/
cap_mutex_init(&cdt_cache.lock);
cap_mutex_init(&global_lock);
/*
* Zero out types
*/
memset(cap_types, 0, sizeof(cap_types));
return 0;
fail2:
__cptr_fini();
fail1:
return ret;
}
void cap_fini(void)
......@@ -62,6 +79,10 @@ void cap_fini(void)
for (i = CAP_TYPE_FIRST_NONBUILTIN; i < CAP_TYPE_MAX; ++i)
if (cap_types[i].name)
free(cap_types[i].name);
/*
* Tear down cptr cache subsystem
*/
__cptr_fini();
}
cap_type_t cap_register_type(cap_type_t type, const struct cap_type_ops *ops)
......@@ -447,7 +468,7 @@ static int __cap_cnode_get(struct cspace *cspace, cptr_t c,
ret = __cap_cnode_lookup(cspace, c, alloc, cnode);
if (ret) {
CAP_DEBUG(CAP_DEBUG_MSG,
"cnode lookup failed with ret = %d\n", ret)
"cnode lookup failed with ret = %d\n", ret);
goto fail2;
}
......@@ -956,7 +977,7 @@ static int try_revoke(struct cspace *cspace, struct cnode *cnode)
* If the child is in the cdt, its type should match cnode's
* type (it shouldn't be invalid, free, or a cnode).
*/
BUG_ON(child->type != cnode->type);
CAP_BUG_ON(child->type != cnode->type);
/*
* Delete from cdt.
*/
......
......@@ -6,9 +6,8 @@
* Pankaj Kumar <pankajk@cs.utah.edu>
*/
#include "libcap.h"
#include "libcap_types.h"
#include "libcap_internal.h"
#include <libcap.h>
#include <libcap_internal.h>
#if (CAP_CSPACE_DEPTH == 4)
static inline unsigned long*
......
nobase_include_HEADERS = libcap.h libcap_types.h libcap_list.h libcap_config.h
noinst_HEADERS = libcap_internal.h
/*
* libcap primary header file and interface.
*
* Author: Charles Jacobsen <charlesj@cs.utah.edu>
* Copyright: University of Utah
/*
* libcap.h
*
* This is the non-isolated code interface to the microkernel. The
* implementation is in virt/lcd-domains/kliblcd.c.
* Main include for libcap library. This is the only file
* you need to include to get the whole interface. All of
* the other headers are sucked in along with it.
*
* An LCD that runs in non-isolated code is called a klcd.
* Copyright: University of Utah
*/
#ifndef __LIBCAP_H__
#define __LIBCAP_H__
#include "libcap_types.h"
struct cnode;
struct cspace;
#include <libcap_config.h>
#include <libcap_platform.h>
#include <libcap_types.h>
#include <libcap_platform_types.h>
struct cap_type_ops {
char *name;
int (*delete)(struct cspace *cspace, struct cnode *cnode, void *object);
int (*revoke)(struct cspace *cspace, struct cnode *cnode, void *object);
};
/* DEBUGGING ---------------------------------------- */
/*
* Add some macros to generate built-in capability object type. Not
* ideal to put this here, but don't want to expose internal headers,
* and have to give per-platform a chance to change them.
*/
#define CAP_BUILD_CORE_TYPES(PT) \
typedef enum cap_type { \
CAP_TYPE_ERR = -1, \
CAP_TYPE_NONE = 0, \
CAP_TYPE_INVALID, \
CAP_TYPE_FREE, \
CAP_TYPE_CNODE, \
PT, \
CAP_TYPE_FIRST_NONBUILTIN \
} cap_type_t
#define CAP_BUILD_CORE_TYPES_NOBUILTIN() \
typedef enum cap_type { \
CAP_TYPE_NONE = 0, \
CAP_TYPE_INVALID, \
CAP_TYPE_FREE, \
CAP_TYPE_CNODE, \
CAP_TYPE_FIRST_NONBUILTIN \
} cap_type_t
#ifdef __KERNEL__
#include "libcap_kernel.h"
#else
#include "libcap_user.h"
#endif
#ifndef CAP_TYPE_MAX
#define CAP_TYPE_MAX 256
#endif
/* For now, put debug macros in the user-accessible part; convenient. */
#define CAP_BUG() __cap_bug()
/* This is near the top so we can use it in any static inlines below. */
/**
* For now, put debug macros in the user-accessible part; convenient.
*/
extern int cap_debug_level;
#define CAP_ERR __cap_err
......@@ -72,10 +31,13 @@ extern int cap_debug_level;
#define CAP_DEBUG_WARN 2
#define CAP_DEBUG_MSG 3
#define CAP_DEBUG(lvl, msg, ...) { \
if (lvl <= cap_debug_level) \
__cap_debug(msg,## __VA_ARGS__); \
}
#define CAP_DEBUG(lvl,msg,...) do { \
if (lvl <= cap_debug_level) \
__cap_debug(msg,##__VA_ARGS__); \
} while(0)
#define CAP_BUG() do { __cap_bug(); } while(0)
#define CAP_BUG_ON(cond) do { __cap_bug_on(cond); } while(0)
/* CPTRs -------------------------------------------------- */
......@@ -186,33 +148,6 @@ static inline int cptr_is_null(cptr_t c)
/* CPTR CACHEs -------------------------------------------------- */
#if (CAP_CSPACE_DEPTH == 4)
struct cptr_cache {
/* lock */
cap_mutex_t lock;
/* level 0 bitmap */
unsigned long bmap0[CAP_BITS_TO_LONGS(CAP_CSPACE_SLOTS_IN_LEVEL(0))];
/* level 1 bitmap */
unsigned long bmap1[CAP_BITS_TO_LONGS(CAP_CSPACE_SLOTS_IN_LEVEL(1))];
/* level 2 bitmap */
unsigned long bmap2[CAP_BITS_TO_LONGS(CAP_CSPACE_SLOTS_IN_LEVEL(2))];
/* level 3 bitmap */
unsigned long bmap3[CAP_BITS_TO_LONGS(CAP_CSPACE_SLOTS_IN_LEVEL(3))];
};
#else
#error "You need to adjust the cptr cache def."
#endif
/**
* cptr_init -- Initalize the cptr cache subsystem
*/
int cptr_init(void);
/**
* cptr_fini -- Tear down the cptr cache subsystem.
*/
void cptr_fini(void);
/**
* cptr_cache_alloc -- Allocate a cptr cache data structure (not initialized)
* @out: out param, pointer to newly alloc'd cache
......@@ -264,16 +199,18 @@ void cptr_free(struct cptr_cache *cptr_cache, cptr_t c);
/* CSPACES -------------------------------------------------- */
/**
* Initializes caches, etc. in capability subsystem. Called when microkernel
* intializes.
* cap_init -- Initializes caches, etc. in capability subsystem.
*
* IMPORTANT: You should call this before any other functions in libcap.
*/
int cap_init(void);
/**