libcap.h 4.87 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
/* 
 * libcap primary header file and interface.
 *
 * Author: Charles Jacobsen <charlesj@cs.utah.edu>
 * Copyright: University of Utah
 *
 * This is the non-isolated code interface to the microkernel. The
 * implementation is in virt/lcd-domains/kliblcd.c.
 *
 * An LCD that runs in non-isolated code is called a klcd.
 */
#ifndef __LIBCAP_H__
#define __LIBCAP_H__

#include "libcap_types.h"

struct cnode;
struct cspace;

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);
};

/*
 * 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

void cptr_init(void);
int cptr_alloc(struct cptr_cache *cptr_cache, cptr_t *free_cptr);
void cptr_free(struct cptr_cache *cptr_cache, cptr_t c);
int cptr_cache_init(struct cptr_cache **c_out);
void cptr_cache_destroy(struct cptr_cache *c);

/**
 * Initializes caches, etc. in capability subsystem. Called when microkernel
 * intializes.
 */
int cap_init(void);
/**
 * Tears down caches, etc. in capability subsystem. Called when microkernel
 * is exiting.
 */
void cap_fini(void);
/**
 * Register a new capability object type.  If you pass type == 0, the
 * system will select the next available identifier and return it.  You
 * should use the returned value as your object identifier.  If you
 * attempt to use a type that is already in use, this returns
 * -EADDRINUSE.  If there are no types remaining or you exceed
 * CAP_TYPE_MAX, this returns -ENOMEM .
 */
cap_type_t cap_register_type(cap_type_t type, struct cap_type_ops *ops);
/**
 * Revoke all derived capabilities.
 *
 * Does not delete the caller's capability.
 *
 * This may change the state of the lcd's whose capabilities are revoked (see
 * comment lcd_cap_delete).
 */
int cap_revoke(struct cspace *cspace, cptr_t c);
/**
 * Delete the capability in slot from this cspace.
 *
 * This may change the state of the caller. (For example, if the caller is
 * a regular lcd, and if the capability is to a page, the page will be unmapped
 * from the caller's address space.)
 *
 * If this is the last capability to the object, the object will be destroyed,
 * unless it is a kernel page. See klcd_add_page and klcd_rm_page.
 */
void cap_delete(struct cspace *cspace, cptr_t c);

/**
 * Sets up cspace - initializes lock, root cnode table, etc.
 */
int cap_init_cspace(struct cspace *cspace);
/**
 * Inserts object data into cspace at cnode pointed at by c.
 */
int cap_insert(struct cspace *cspace, cptr_t c, void *object, cap_type_t type);
/**
 * Deletes object data from cspace at cnode pointed at by c.
 *
 * Updates the state of the microkernel to reflect rights change (e.g., if
 * a cnode for a page is deleted, and the page is mapped, the page will be
 * unmapped).
 *
 * If this is the last cnode that refers to the object, the object is
 * destroyed.
 */
void cap_delete(struct cspace *cspace, cptr_t c);
/**
 * Copies cnode data in src cnode at c_src to dest cnode at c_dst. The dest
 * cnode will be a child of the src cnode in the cdt containing src cnode.
 */
int cap_grant(struct cspace *cspacesrc, cptr_t c_src,
	      struct cspace *cspacedst, cptr_t c_dst);
/**
 * Equivalent to calling lcd_cap_delete on all of the cnode's children. 
 *
 * ** Does not delete the cnode itself. **
 */
int cap_revoke(struct cspace *cspace, cptr_t c);
/**
 * Equivalent to calling lcd_cap_delete on all cnodes in cspace. Frees up
 * all cnode tables, etc.
 */
void cap_destroy_cspace(struct cspace *cspace);
/**
143
 * Looks up cnode at cap in cspace.
144
 *
145
 * ** Frees the cnode lock itself without relying on user.
146 147 148 149
 *
 * ** Interrupts and preemption *are not* disabled. **
 *    (so we can easily get out of deadlocks while debugging)
 */
150
int cap_cnode_verify(struct cspace *cspace, cptr_t cap);
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
/**
 * For now, put debug macros in the user-accessible part; convenient.
 */
extern int cap_debug_level;

#define CAP_ERR __cap_err
#define CAP_WARN __cap_warn
#define CAP_MSG __cap_msg

#define CAP_DEBUG_ERR  1
#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__);				\
	}

#endif /* __LIBCAP_H__ */