All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

Commit 33293c86 authored by root's avatar root

Added cspace related files

parent 181c1cc2
This diff is collapsed.
This diff is collapsed.
/*
* types.h
*
* Author: Charles Jacobsen <charlesj@cs.utah.edu>
* Copyright: University of Utah
*
*/
#ifndef LCD_DOMAINS_TYPES_H
#define LCD_DOMAINS_TYPES_H
#include <linux/kernel.h>
#include <asm/page.h>
/* CPTRs -------------------------------------------------- */
typedef struct { unsigned long cptr; } cptr_t;
static inline cptr_t __cptr(unsigned long cptr)
{
return (cptr_t){ cptr };
}
static inline unsigned long cptr_val(cptr_t c)
{
return c.cptr;
}
/*
* Reserved cnodes:
*
* cptr = 0 is always null
* cptr = 1 is the lcd's call endpoint
* cptr = 2 points to an endpoint if the lcd did a receive, and the sender did
* a call (so the lcd can do a reply)
*
* So, if lcd A does a call on endpoint #1 and lcd B does a receive on endpoint
* #1, the endpoint at LCD_CAP_CALL_ENDPOINT in A's cspace will be granted
* to lcd B in B's cspace at cptr LCD_CAP_REPLY_ENDPOINT. lcd B can do a reply
* (one time and then it's revoked).
*/
#define LCD_CPTR_NULL __cptr(0)
#define LCD_CPTR_CALL_ENDPOINT __cptr(1)
#define LCD_CPTR_REPLY_ENDPOINT __cptr(2)
static inline int cptr_is_null(cptr_t c)
{
return cptr_val(c) == cptr_val(LCD_CPTR_NULL);
}
#define LCD_CPTR_DEPTH_BITS 2 /* max depth of 3, zero indexed */
#define LCD_CPTR_FANOUT_BITS 2 /* each level fans out by a factor of 4 */
#define LCD_CPTR_SLOT_BITS 2 /* each node contains 4 cap slots */
#define LCD_CNODE_TABLE_NUM_SLOTS ((1 << LCD_CPTR_SLOT_BITS) + \
(1 << LCD_CPTR_FANOUT_BITS))
#define LCD_CPTR_LEVEL_SHIFT (((1 << LCD_CPTR_DEPTH_BITS) - 1) * \
LCD_CPTR_FANOUT_BITS + LCD_CPTR_SLOT_BITS)
static inline unsigned long lcd_cptr_slot(cptr_t c)
{
/*
* Mask off low bits
*/
return cptr_val(c) & ((1 << LCD_CPTR_SLOT_BITS) - 1);
}
/*
* Gives fanout index for going *from* lvl to lvl + 1, where
* 0 <= lvl < 2^LCD_CPTR_DEPTH_BITS - 1 (i.e., we can't go anywhere
* if lvl = 2^LCD_CPTR_DEPTH_BITS - 1, because we are at the deepest
* level).
*/
static inline unsigned long lcd_cptr_fanout(cptr_t c, int lvl)
{
unsigned long i;
i = cptr_val(c);
/*
* Shift and mask off bits at correct section
*/
i >>= (lvl * LCD_CPTR_FANOUT_BITS + LCD_CPTR_SLOT_BITS);
i &= ((1 << LCD_CPTR_FANOUT_BITS) - 1);
return i;
}
/*
* Gives depth/level of cptr, zero indexed (0 means the root cnode table)
*/
static inline unsigned long lcd_cptr_level(cptr_t c)
{
unsigned long i;
i = cptr_val(c);
/*
* Shift and mask
*/
i >>= LCD_CPTR_LEVEL_SHIFT;
i &= ((1 << LCD_CPTR_DEPTH_BITS) - 1);
return i;
}
/* CPTR CACHE -------------------------------------------------- */
struct cptr_cache {
unsigned long *bmaps[1 << LCD_CPTR_DEPTH_BITS];
};
/* ADDRESS SPACE TYPES ---------------------------------------- */
/* XXX: Assumes host and guest run in 64-bit mode */
typedef struct { unsigned long gva; } gva_t;
typedef struct { unsigned long hva; } hva_t;
typedef struct { unsigned long gpa; } gpa_t;
typedef struct { unsigned long hpa; } hpa_t;
static inline gva_t __gva(unsigned long gva)
{
return (gva_t){ gva };
}
static inline unsigned long gva_val(gva_t gva)
{
return gva.gva;
}
static inline unsigned long * gva_ptr(gva_t * gva)
{
return &(gva->gva);
}
static inline gva_t gva_add(gva_t gva, unsigned long off)
{
return __gva(gva_val(gva) + off);
}
static inline hva_t __hva(unsigned long hva)
{
return (hva_t){ hva };
}
static inline unsigned long hva_val(hva_t hva)
{
return hva.hva;
}
static inline unsigned long * hva_ptr(hva_t * hva)
{
return &(hva->hva);
}
static inline hva_t hva_add(hva_t hva, unsigned long off)
{
return __hva(hva_val(hva) + off);
}
static inline gpa_t __gpa(unsigned long gpa)
{
return (gpa_t){ gpa };
}
static inline unsigned long gpa_val(gpa_t gpa)
{
return gpa.gpa;
}
static inline unsigned long * gpa_ptr(gpa_t * gpa)
{
return &(gpa->gpa);
}
static inline gpa_t gpa_add(gpa_t gpa, unsigned long off)
{
return __gpa(gpa_val(gpa) + off);
}
static inline hpa_t __hpa(unsigned long hpa)
{
return (hpa_t){ hpa };
}
static inline unsigned long hpa_val(hpa_t hpa)
{
return hpa.hpa;
}
static inline unsigned long * hpa_ptr(hpa_t * hpa)
{
return &(hpa->hpa);
}
static inline hpa_t hpa_add(hpa_t hpa, unsigned long off)
{
return __hpa(hpa_val(hpa) + off);
}
static inline hpa_t pa2hpa(unsigned long pa)
{
return (hpa_t){ pa };
}
static inline hpa_t va2hpa(void *va)
{
return (hpa_t){ __pa(va) };
}
static inline void * hpa2va(hpa_t hpa)
{
return __va(hpa_val(hpa));
}
static inline hva_t hpa2hva(hpa_t hpa)
{
return (hva_t){ (unsigned long)__va(hpa.hpa) };
}
static inline void * hva2va(hva_t hva)
{
return (void *)hva_val(hva);
}
static inline hva_t va2hva(void *va)
{
return __hva((unsigned long)va);
}
static inline hpa_t hva2hpa(hva_t hva)
{
return (hpa_t){ (unsigned long)__pa(hva2va(hva)) };
}
/* BOOT ADDRESS SPACE & INFO ------------------------------------------- */
#define LCD_BOOT_PAGES_ORDER 2
#define LCD_GV_PAGING_MEM_GPA __gpa(1 << 20)
#define LCD_GV_PAGING_MEM_SIZE (4 << 20)
#define LCD_BOOT_PAGES_GPA gpa_add(LCD_GV_PAGING_MEM_GPA, \
LCD_GV_PAGING_MEM_SIZE)
#define LCD_BOOT_PAGES_SIZE ((1 << LCD_BOOT_PAGES_ORDER) * (4 << 10))
#define LCD_STACK_GPA gpa_add(LCD_BOOT_PAGES_GPA, LCD_BOOT_PAGES_SIZE)
#define LCD_STACK_SIZE (4 << 10)
#define LCD_MODULE_GPA gpa_add(LCD_STACK_GPA, LCD_STACK_SIZE)
#define LCD_GV_PAGING_MEM_GVA __gva(gpa_val(LCD_GV_PAGING_MEM_GPA))
#define LCD_BOOT_PAGES_GVA __gva(gpa_val(LCD_BOOT_PAGES_GPA))
#define LCD_STACK_GVA __gva(gpa_val(LCD_STACK_GPA))
#define LCD_NUM_BOOT_CPTRS 8
struct lcd_boot_info_for_page {
cptr_t my_cptr;
gpa_t page_gpa;
};
/*
* Hack for now to make boot easier, used in liblcd/lcd/cap.c for cptr
* cache.
*/
#define LCD_BMAP0_SIZE (1 << (LCD_CPTR_SLOT_BITS + 0 * LCD_CPTR_FANOUT_BITS))
#define LCD_BMAP1_SIZE (1 << (LCD_CPTR_SLOT_BITS + 1 * LCD_CPTR_FANOUT_BITS))
#define LCD_BMAP2_SIZE (1 << (LCD_CPTR_SLOT_BITS + 2 * LCD_CPTR_FANOUT_BITS))
#define LCD_BMAP3_SIZE (1 << (LCD_CPTR_SLOT_BITS + 3 * LCD_CPTR_FANOUT_BITS))
#define LCD_BMAP0_NUM_LONGS BITS_TO_LONGS(LCD_BMAP0_SIZE)
#define LCD_BMAP1_NUM_LONGS BITS_TO_LONGS(LCD_BMAP1_SIZE)
#define LCD_BMAP2_NUM_LONGS BITS_TO_LONGS(LCD_BMAP2_SIZE)
#define LCD_BMAP3_NUM_LONGS BITS_TO_LONGS(LCD_BMAP3_SIZE)
struct lcd_boot_info {
/*
* Bootstrap cptr cache --------------------
*
* level 0
*/
unsigned long bmap0[LCD_BMAP0_NUM_LONGS];
/* level 1 */
unsigned long bmap1[LCD_BMAP1_NUM_LONGS];
/* level 2 */
unsigned long bmap2[LCD_BMAP2_NUM_LONGS];
/* level 3 */
unsigned long bmap3[LCD_BMAP3_NUM_LONGS];
/*
* Bootstrap page info --------------------
*/
unsigned num_boot_mem_pi;
unsigned num_paging_mem_pi;
unsigned num_free_mem_pi;
struct lcd_boot_info_for_page *boot_mem_pi_start;
struct lcd_boot_info_for_page *paging_mem_pi_start;
struct lcd_boot_info_for_page *free_mem_pi_start;
/*
* Other capabilities (e.g., endpoints)
*/
cptr_t cptrs[LCD_NUM_BOOT_CPTRS];
};
#endif /* LCD_DOMAINS_TYPES_H */
This diff is collapsed.
/**
* cptr_cache.c
*
* Authors:
* Charlie Jacobsen <charlesj@cs.utah.edu>
*/
#include <linux/slab.h>
#include <lcd-domains/kliblcd.h>
#include <lcd-domains/utcb.h>
#include <lcd-domains/types.h>
#include <linux/mutex.h>
#include "../internal.h"
static int cptr_cache_init(struct cptr_cache **out)
{
struct cptr_cache *cache;
int ret;
int i, j;
int nbits;
/*
* Allocate the container
*/
cache = kzalloc(sizeof(*cache), GFP_KERNEL);
if (!cache) {
ret = -ENOMEM;
goto fail1;
}
/*
* Allocate the bitmaps
*/
for (i = 0; i < (1 << LCD_CPTR_DEPTH_BITS); i++) {
/*
* For level i, we use the slot bits plus i * fanout bits
*
* So e.g. for level 0, we use only slot bits, so there
* are only 2^(num slot bits) cap slots at level 0.
*/
nbits = 1 << (LCD_CPTR_SLOT_BITS + i * LCD_CPTR_FANOUT_BITS);
/*
* Alloc bitmap
*/
cache->bmaps[i] = kzalloc(sizeof(unsigned long) *
BITS_TO_LONGS(nbits),
GFP_KERNEL);
if (!cache->bmaps[i]) {
ret = -ENOMEM;
goto fail2; /* i = level we failed at */
}
}
/*
* Mark reserved cptr's as allocated
*/
set_bit(0, cache->bmaps[0]);
set_bit(1, cache->bmaps[0]);
set_bit(2, cache->bmaps[0]);
*out = cache;
return 0;
fail2:
for (j = 0; j < i; j++)
kfree(cache->bmaps[j]);
kfree(cache);
fail1:
return ret;
}
static void cptr_cache_destroy(struct cptr_cache *cache)
{
int i;
/*
* Free bitmaps
*/
for (i = 0; i < (1 << LCD_CPTR_DEPTH_BITS); i++)
kfree(cache->bmaps[i]);
/*
* Free container
*/
kfree(cache);
}
static int __lcd_alloc_cptr_from_bmap(unsigned long *bmap, int size,
unsigned long *out)
{
unsigned long idx;
/*
* Find next zero bit
*/
idx = find_first_zero_bit(bmap, size);
if (idx >= size)
return 0; /* signal we are full */
/*
* Set bit to mark cptr as in use
*/
set_bit(idx, bmap);
*out = idx;
return 1; /* signal we are done */
}
int __klcd_alloc_cptr(struct cptr_cache *cptr_cache, cptr_t *free_cptr)
{
int ret;
int depth;
int done;
unsigned long *bmap;
unsigned long idx;
int size;
depth = 0;
do {
bmap = cptr_cache->bmaps[depth];
size = 1 << (LCD_CPTR_SLOT_BITS +
depth * LCD_CPTR_FANOUT_BITS);
done = __lcd_alloc_cptr_from_bmap(bmap, size, &idx);
depth++;
} while (!done && depth < (1 << LCD_CPTR_DEPTH_BITS));
if (!done) {
/*
* Didn't find one
*/
LCD_ERR("out of cptrs");
ret = -ENOMEM;
goto fail2;
}
/*
* Found one; dec depth back to what it was, and encode
* depth in cptr
*/
depth--;
idx |= (depth << LCD_CPTR_LEVEL_SHIFT);
*free_cptr = __cptr(idx);
return 0;
fail2:
return ret;
}
void __klcd_free_cptr(struct cptr_cache *cptr_cache, cptr_t c)
{
unsigned long *bmap;
unsigned long bmap_idx;
unsigned long level;
/*
* Get the correct level bitmap
*/
level = lcd_cptr_level(c);
bmap = cptr_cache->bmaps[level];
/*
* The bitmap index includes all fanout bits and the slot bits
*/
bmap_idx = ((1 << (LCD_CPTR_FANOUT_BITS * level + LCD_CPTR_SLOT_BITS))
- 1) & cptr_val(c);
/*
* Clear the bit in the bitmap
*/
clear_bit(bmap_idx, bmap);
return;
}
int klcd_alloc_cptr(cptr_t *free_slot)
{
return __lcd_alloc_cptr(current->cptr_cache, free_slot);
}
void klcd_free_cptr(cptr_t c)
{
__lcd_free_cptr(current->cptr_cache, c);
}
int klcd_init_cptr(struct cptr_cache **c_out)
{
return cptr_cache_init(c_out);
}
void klcd_destroy_cptr(struct cptr_cache *c)
{
cptr_cache_destroy(c);
}
/* EXPORTS -------------------------------------------------- */
EXPORT_SYMBOL(__klcd_alloc_cptr);
EXPORT_SYMBOL(__klcd_free_cptr);
EXPORT_SYMBOL(klcd_alloc_cptr);
EXPORT_SYMBOL(klcd_free_cptr);
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