Record networking and DMA development progress
Add the current OS source tree, build scripts, system image layout, and development notes covering DMA page allocation, e1000 bring-up, net API dispatch, and DHCP work in progress.
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
#include <utsm/capability.h>
|
||||
#include <utsm/segment.h>
|
||||
|
||||
int utsm_cap_validate(utsm_capability cap, u32 required_rights, u64 offset, u64 len, utsm_segment_desc **out_desc) {
|
||||
utsm_segment_desc *desc = utsm_get_segment(cap.segment_slot);
|
||||
if (!desc) {
|
||||
return UTSM_ERR_INVALID;
|
||||
}
|
||||
if (desc->state == UTSM_SEG_POISONED) {
|
||||
return UTSM_ERR_POISONED;
|
||||
}
|
||||
if (desc->state != UTSM_SEG_ACTIVE) {
|
||||
return UTSM_ERR_STATE;
|
||||
}
|
||||
if (desc->generation != cap.generation) {
|
||||
return UTSM_ERR_STALE_CAP;
|
||||
}
|
||||
if ((cap.rights & required_rights) != required_rights) {
|
||||
return UTSM_ERR_ACCESS;
|
||||
}
|
||||
if ((u32)desc->key_epoch != cap.epoch) {
|
||||
return UTSM_ERR_EPOCH;
|
||||
}
|
||||
if (offset > desc->cipher_length || len > desc->cipher_length || offset + len > desc->cipher_length) {
|
||||
return UTSM_ERR_BOUNDS;
|
||||
}
|
||||
*out_desc = desc;
|
||||
return UTSM_OK;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,47 @@
|
||||
#include <utsm/dirty.h>
|
||||
#include <utsm/segment.h>
|
||||
#include <utsm/arena.h>
|
||||
#include <utsm/config.h>
|
||||
|
||||
static void bitmap_set(u64 *bitmap, u64 bit) {
|
||||
bitmap[bit / 64] |= 1ULL << (bit % 64);
|
||||
}
|
||||
|
||||
static bool bitmap_test(u64 *bitmap, u64 bit) {
|
||||
return (bitmap[bit / 64] & (1ULL << (bit % 64))) != 0;
|
||||
}
|
||||
|
||||
void utsm_dirty_init(utsm_segment_desc *desc, u64 page_count) {
|
||||
desc->dirty_shard_count = 1;
|
||||
desc->dirty_shards = (utsm_dirty_shard *)kmem_alloc(sizeof(utsm_dirty_shard));
|
||||
if (!desc->dirty_shards) {
|
||||
return;
|
||||
}
|
||||
u64 words = (page_count + 63) / 64;
|
||||
desc->dirty_shards[0].dirty_count = 0;
|
||||
desc->dirty_shards[0].shard_id = 0;
|
||||
desc->dirty_shards[0].page_base = 0;
|
||||
desc->dirty_shards[0].page_count = page_count;
|
||||
desc->dirty_shards[0].last_checkpoint_epoch = 0;
|
||||
desc->dirty_shards[0].bitmap = (u64 *)kmem_alloc_aligned(words * sizeof(u64), 8);
|
||||
if (desc->dirty_shards[0].bitmap) {
|
||||
for (u64 i = 0; i < words; i++) {
|
||||
desc->dirty_shards[0].bitmap[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void utsm_mark_dirty(utsm_segment_desc *desc, u64 offset, u64 len) {
|
||||
if (!desc || !desc->dirty_shards || !desc->dirty_shards[0].bitmap || len == 0) {
|
||||
return;
|
||||
}
|
||||
u64 first = offset / UTSM_PAGE_SIZE;
|
||||
u64 last = (offset + len - 1) / UTSM_PAGE_SIZE;
|
||||
utsm_dirty_shard *shard = &desc->dirty_shards[0];
|
||||
for (u64 page = first; page <= last && page < shard->page_count; page++) {
|
||||
if (!bitmap_test(shard->bitmap, page)) {
|
||||
bitmap_set(shard->bitmap, page);
|
||||
shard->dirty_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,20 @@
|
||||
#include <utsm/dmp.h>
|
||||
#include <utsm/segment.h>
|
||||
|
||||
#define UTSM_DMP_MAGIC 0x5554534d444d5031ULL
|
||||
|
||||
void utsm_dmp_init(utsm_dmp *dmp, utsm_segment_desc *desc, u32 slot) {
|
||||
dmp->magic = UTSM_DMP_MAGIC;
|
||||
dmp->version = 1;
|
||||
dmp->segment_slot = slot;
|
||||
dmp->fast_base = (u64)desc->cipher_base;
|
||||
dmp->fast_limit = (u64)desc->cipher_base + desc->cipher_length;
|
||||
dmp->fast_tweak_seed = desc->tweak_seed;
|
||||
dmp->fast_key_epoch = desc->key_epoch;
|
||||
dmp->dirty_bitmap_base = desc->dirty_shards ? (u64)desc->dirty_shards[0].bitmap : 0;
|
||||
dmp->mac_table_base = (u64)desc->mac_table;
|
||||
dmp->last_writer_seq = desc->writer_seq;
|
||||
dmp->last_cpu = desc->last_cpu;
|
||||
dmp->flags = desc->flags;
|
||||
dmp->crc = dmp->magic ^ dmp->fast_base ^ dmp->fast_limit ^ dmp->fast_tweak_seed;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,11 @@
|
||||
#include <utsm/process.h>
|
||||
#include <utsm/drr.h>
|
||||
|
||||
void utsm_process_create_test(utsm_process_context *process, u64 seed) {
|
||||
process->process_uuid = uuid_make_test(seed);
|
||||
process->crypto_epoch = 1;
|
||||
process->recovery_generation = drr_recovery_generation();
|
||||
process->capability_table_slot = 0;
|
||||
process->capability_count = 0;
|
||||
process->flags = 0;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,80 @@
|
||||
#include <utsm/segment.h>
|
||||
#include <utsm/process.h>
|
||||
#include <utsm/arena.h>
|
||||
#include <utsm/dmp.h>
|
||||
#include <utsm/config.h>
|
||||
|
||||
u64 utsm_next_generation(void);
|
||||
|
||||
static u64 digest_uuid(uuid128_t id) {
|
||||
return id.hi ^ id.lo ^ (id.hi >> 32) ^ (id.lo << 17);
|
||||
}
|
||||
|
||||
static u64 make_tweak_seed(uuid128_t process_uuid, uuid128_t segment_uuid, u64 epoch) {
|
||||
return process_uuid.hi ^ process_uuid.lo ^ segment_uuid.hi ^ segment_uuid.lo ^ (epoch * 0x9e3779b97f4a7c15ULL);
|
||||
}
|
||||
|
||||
int utsm_create_segment(utsm_process_context *process, u64 size, u32 flags, utsm_capability *out_cap) {
|
||||
if (!process || !out_cap || size == 0) {
|
||||
return UTSM_ERR_INVALID;
|
||||
}
|
||||
|
||||
u32 slot = UTSM_MAX_SEGMENTS;
|
||||
utsm_segment_desc *desc = NULL;
|
||||
for (u32 i = 0; i < UTSM_MAX_SEGMENTS; i++) {
|
||||
utsm_segment_desc *candidate = utsm_get_segment(i);
|
||||
if (candidate->state == UTSM_SEG_FREE) {
|
||||
slot = i;
|
||||
desc = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!desc) {
|
||||
return UTSM_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
u64 length = utsm_align_up_u64(size, UTSM_CACHE_LINE_SIZE);
|
||||
u64 pages = utsm_align_up_u64(length, UTSM_PAGE_SIZE) / UTSM_PAGE_SIZE;
|
||||
u8 *cipher = (u8 *)kmem_alloc_page(pages);
|
||||
utsm_dmp *dmp = (utsm_dmp *)kmem_alloc_aligned(sizeof(utsm_dmp), 64);
|
||||
void *mac_table = kmem_alloc_aligned(pages * sizeof(u64), 8);
|
||||
if (!cipher || !dmp || !mac_table) {
|
||||
return UTSM_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
for (u64 i = 0; i < pages * UTSM_PAGE_SIZE; i++) {
|
||||
cipher[i] = 0;
|
||||
}
|
||||
|
||||
desc->segment_uuid = uuid_make_test(utsm_next_generation() + slot);
|
||||
desc->owner_process_uuid = process->process_uuid;
|
||||
desc->cipher_base = cipher;
|
||||
desc->cipher_length = length;
|
||||
desc->dmp_base = dmp;
|
||||
desc->key_epoch = process->crypto_epoch;
|
||||
desc->tweak_seed = make_tweak_seed(process->process_uuid, desc->segment_uuid, desc->key_epoch);
|
||||
desc->mac_table = mac_table;
|
||||
desc->generation++;
|
||||
desc->flags = flags;
|
||||
desc->state = UTSM_SEG_ACTIVE;
|
||||
desc->last_cpu = 0;
|
||||
desc->writer_seq = 0;
|
||||
desc->checkpoint_generation = process->recovery_generation;
|
||||
|
||||
utsm_dirty_init(desc, pages);
|
||||
utsm_dmp_init(dmp, desc, slot);
|
||||
|
||||
out_cap->segment_slot = slot;
|
||||
out_cap->generation = desc->generation;
|
||||
out_cap->rights = 0;
|
||||
if (flags & UTSM_SEG_F_READ) out_cap->rights |= UTSM_RIGHT_READ;
|
||||
if (flags & UTSM_SEG_F_WRITE) out_cap->rights |= UTSM_RIGHT_WRITE;
|
||||
if (flags & UTSM_SEG_F_EXEC) out_cap->rights |= UTSM_RIGHT_EXEC;
|
||||
if (flags & UTSM_SEG_F_DMA) out_cap->rights |= UTSM_RIGHT_DMA;
|
||||
out_cap->epoch = (u32)desc->key_epoch;
|
||||
out_cap->uuid_digest = digest_uuid(desc->segment_uuid);
|
||||
out_cap->auth_tag = out_cap->uuid_digest ^ digest_uuid(process->process_uuid) ^ desc->key_epoch;
|
||||
|
||||
process->capability_count++;
|
||||
return UTSM_OK;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,32 @@
|
||||
#include <utsm/utsm.h>
|
||||
#include <utsm/segment.h>
|
||||
#include <utsm/pckc.h>
|
||||
#include <utsm/log.h>
|
||||
|
||||
static utsm_segment_desc g_segments[UTSM_MAX_SEGMENTS];
|
||||
static u64 g_generation = 1;
|
||||
|
||||
void utsm_init(void) {
|
||||
log_info("[UTSM] segment table reset begin");
|
||||
for (u32 i = 0; i < UTSM_MAX_SEGMENTS; i++) {
|
||||
g_segments[i].state = UTSM_SEG_FREE;
|
||||
g_segments[i].generation = 1;
|
||||
}
|
||||
log_info("[UTSM] segment table reset ok");
|
||||
|
||||
g_generation = 1;
|
||||
log_info("[UTSM] pckc init begin");
|
||||
utsm_pckc_init();
|
||||
log_info("[UTSM] pckc init ok");
|
||||
}
|
||||
|
||||
utsm_segment_desc *utsm_get_segment(u32 slot) {
|
||||
if (slot >= UTSM_MAX_SEGMENTS) {
|
||||
return NULL;
|
||||
}
|
||||
return &g_segments[slot];
|
||||
}
|
||||
|
||||
u64 utsm_next_generation(void) {
|
||||
return g_generation++;
|
||||
}
|
||||
Binary file not shown.
Reference in New Issue
Block a user