ohhhhhhhhhhh (exclude linux-extra-rootfs.img build artifact)

This commit is contained in:
Linehu
2026-10-01 23:13:42 +08:00
parent 737a2cb0db
commit 1074962546
533 changed files with 133239 additions and 5460 deletions
+405 -3
View File
@@ -10,6 +10,14 @@
#include <utsm/drr.h>
#include <utsm/log.h>
#include <utsm/dma.h>
#include <utsm/segment.h>
#include <utsm/config.h>
#include <utsm/dkm.h>
#include <utsm/crypto.h>
#include <utsm/blake2b.h>
extern void outb(u16 port, u8 value);
/* ---- 内部内存操作(不依赖 libc) ---- */
static void drr_memzero(void *dst, u64 n) {
@@ -71,14 +79,118 @@ u64 drr_crc64(const void *data, u64 len) {
/* ---- 全局 DRR 状态 ---- */
static drr_state g_drr;
/* ---- Root key(最终应从安全启动链获取) ---- */
static const u64 g_root_key[4] = {
/* ---- Phase 8: 快照区 / 看门狗 / 恢复行为控制 ---- */
#define DRR_SNAP_MAGIC 0x445252534E415021ULL /* "DRRSNAP!" */
#define DRR_SNAP_VERSION 1u
typedef struct {
u64 magic;
u32 version;
u32 capacity; /* 条目容量(page0 空间决定) */
u32 used;
u32 generation;
u64 crc;
} drr_snap_header;
static dkm_dma_buffer g_snap_region;
static int g_snap_ok = 0;
static u32 g_snap_capacity = 0;
static int g_reboot_enabled = 1;
static void (*g_sched_fault_cb)(u32 task_slot) = 0;
typedef struct {
u32 task_slot; /* 0xFFFFFFFF = 空闲 */
u32 timeout_ticks;
u64 last_kick_tick;
} drr_watchdog_entry;
static drr_watchdog_entry g_drr_wd[DRR_WATCHDOG_MAX];
static drr_snap_header *snap_header(void) {
return (drr_snap_header *)g_snap_region.virt;
}
static drr_ckpt_page_entry *snap_entries(void) {
return (drr_ckpt_page_entry *)((u8 *)g_snap_region.virt + 64);
}
static u8 *snap_page_ptr(u32 idx) {
return (u8 *)g_snap_region.virt + 4096ULL * (1ULL + (u64)idx);
}
/* ---- Root key(Phase 9: RDRAND + TSC jitter 混合,boot 生成一次)
* 生成一次后固化:drr_init 可重入(emergency reset),root key 不换,
* 否则旧 segment key 全部失效。持久化(sealed disk region)留待后续。 ---- */
static u64 g_root_key_storage[4];
static int g_root_key_ready = 0;
static const u64 g_root_key_fallback[4] = {
0x4452525554534D31ULL, /* "DRRUTSM1" */
0xFEEDFACECAFEF00DULL,
0x0123456789ABCDEFULL,
0xFEDCBA9876543210ULL
};
static u64 drr_tsc(void) {
u64 v;
__asm__ volatile("rdtsc" : "=A"(v));
return v;
}
static int drr_have_rdrand(void) {
u32 a, b, c, d;
__asm__ volatile("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "a"(1u), "c"(0u));
return (int)((c >> 30) & 1u);
}
static int drr_rdrand64(u64 *out) {
u8 ok;
u64 v;
__asm__ volatile("rdrand %0; setc %1" : "=r"(v), "=qm"(ok) :: "cc");
if (!ok) return 0;
*out = v;
return 1;
}
static void drr_root_key_generate(void) {
if (g_root_key_ready) {
g_drr.root_key = g_root_key_storage;
return;
}
int rdrand_ok = 1;
if (drr_have_rdrand()) {
for (int i = 0; i < 4; i++) {
if (!drr_rdrand64(&g_root_key_storage[i])) {
rdrand_ok = 0;
break;
}
}
} else {
rdrand_ok = 0;
}
if (rdrand_ok) {
/* 纵深:混入 TSC jitter,防 RDRAND 单点失效 */
for (int i = 0; i < 4; i++) {
g_root_key_storage[i] ^= drr_tsc() * 0x9e3779b97f4a7c15ULL;
}
} else {
/* 无 RDRAND:常量基底 + 多轮 TSC jitter 混合 */
for (int i = 0; i < 4; i++) {
g_root_key_storage[i] = g_root_key_fallback[i];
}
for (int r = 0; r < 16; r++) {
u64 j = drr_tsc();
for (int i = 0; i < 4; i++) {
j = (j ^ drr_tsc()) * 0x9e3779b97f4a7c15ULL;
g_root_key_storage[i] ^= j;
for (volatile int d = 0; d < 50; d++) { }
}
}
}
g_root_key_ready = 1;
g_drr.root_key = g_root_key_storage;
log_info("[DRR] root key generated");
log_hex64("[DRR] rdrand=", (u64)rdrand_ok);
}
/* ---- Emergency Pool 内部分配 ---- */
static void *pool_alloc_internal(u64 size, u64 alignment) {
u64 current = (u64)&g_drr.pool[0] + g_drr.pool_offset;
@@ -112,7 +224,7 @@ void drr_init(void) {
g_drr.pool_offset = 0;
g_drr.pool_limit = DRR_EMERGENCY_POOL_SIZE;
g_drr.root_key = g_root_key;
drr_root_key_generate();
g_drr.recovery_generation = 1;
g_drr.heartbeat_interval = 1000;
g_drr.active_slot = 0; /* A */
@@ -142,6 +254,38 @@ void drr_init(void) {
g_drr.ckpt_b.version = DRR_CKPT_VERSION;
g_drr.initialized = 1;
/* ---- Phase 8: 快照区(dma 页,独立于普通堆;失败降级 metadata-only) ---- */
g_snap_ok = 0;
g_snap_capacity = 0;
g_reboot_enabled = 1;
g_sched_fault_cb = 0;
for (int wdi = 0; wdi < DRR_WATCHDOG_MAX; wdi++) {
g_drr_wd[wdi].task_slot = 0xFFFFFFFFu;
g_drr_wd[wdi].timeout_ticks = 0;
g_drr_wd[wdi].last_kick_tick = 0;
}
{
/* page0 = 头 + 条目数组,其后 128 页快照数据(共 129 页) */
dkm_dma_buffer buf;
if (dma_alloc_pages(1 + 128, 4096, 0xFFFFFFFFULL, &buf) == 0 && buf.virt) {
g_snap_region = buf;
u32 cap = (u32)((4096 - 64) / sizeof(drr_ckpt_page_entry));
drr_snap_header *h = (drr_snap_header *)buf.virt;
drr_memzero(h, 4096);
h->magic = DRR_SNAP_MAGIC;
h->version = DRR_SNAP_VERSION;
h->capacity = cap;
h->used = 0;
g_snap_capacity = cap;
g_snap_ok = 1;
log_info("[DRR] snapshot region ok");
log_hex64("[DRR] pages=", 1 + 128);
} else {
log_warn("[DRR] snapshot region unavailable (metadata-only mode)");
}
}
log_info("[DRR] init ok");
}
@@ -314,3 +458,261 @@ void drr_heartbeat_tick(void) {
u64 drr_heartbeat_get(void) {
return g_drr.heartbeat_counter;
}
/* ===================================================================
* Phase 8: 真实脏页快照 / 页级回滚 / 看门狗 / system rollback
* =================================================================== */
int drr_ckpt_snapshot_dirty(void) {
if (!g_drr.initialized) return -1;
if (!g_snap_ok) return -2; /* metadata-only 模式不支持页快照 */
drr_checkpoint_begin(DRR_CKPT_DIRTY_PAGE);
drr_snap_header *h = snap_header();
drr_ckpt_page_entry *entries = snap_entries();
u32 used = 0;
for (u32 slot = 0; slot < g_utsm_max_segments; slot++) {
utsm_segment_desc *desc = utsm_get_segment(slot);
if (!desc || desc->state != UTSM_SEG_ACTIVE) continue;
desc->state = UTSM_SEG_CHECKPOINTING;
for (u32 s = 0; s < desc->dirty_shard_count && desc->dirty_shards; s++) {
utsm_dirty_shard *shard = &desc->dirty_shards[s];
if (!shard->bitmap) continue;
u64 words = (shard->page_count + 63) / 64;
for (u64 w = 0; w < words && used < g_snap_capacity; w++) {
u64 word = shard->bitmap[w];
while (word && used < g_snap_capacity) {
u64 bit = (u64)__builtin_ctzll(word);
u64 page = w * 64 + bit;
u8 *src = desc->cipher_base + page * UTSM_PAGE_SIZE;
u8 *dst = snap_page_ptr(used);
drr_memcpy(dst, src, UTSM_PAGE_SIZE);
entries[used].seg_slot = slot;
entries[used].page_index = (u32)page;
entries[used].cipher_vaddr = (u64)src;
entries[used].crc = drr_crc64(dst, UTSM_PAGE_SIZE);
entries[used].key_epoch = desc->key_epoch;
entries[used].mac = utsm_page_mac(g_drr.root_key, slot, page,
desc->key_epoch, dst);
entries[used].region_idx = used;
entries[used].used = 1;
used++;
/* 快照成功才清脏位;区满时保留脏位(部分提交,下轮重试) */
shard->bitmap[w] &= ~(1ULL << bit);
if (shard->dirty_count > 0) shard->dirty_count--;
word &= ~(1ULL << bit);
}
}
shard->last_checkpoint_epoch = g_drr.recovery_generation;
}
desc->state = UTSM_SEG_ACTIVE;
desc->checkpoint_generation = g_drr.recovery_generation;
if (used >= g_snap_capacity) break;
}
/* 区域头(crc 不含自身字段) */
h->used = used;
h->generation = (u32)g_drr.recovery_generation;
h->crc = drr_crc64(h, sizeof(drr_snap_header) - sizeof(u64));
/* 元数据 + A/B 原子切换(begin 已选好 inactive slot,同一表达式取回) */
drr_checkpoint_meta *target = (g_drr.active_slot == 0) ? &g_drr.ckpt_b : &g_drr.ckpt_a;
target->dirty_page_count = used;
/* Phase 9: mac_root = keyed BLAKE2b 链(root_key 派生,绑定全部页 MAC) */
{
u8 kb[32];
u8 chain[64];
for (int i = 0; i < 4; i++) utsm_store64_le(kb + 8 * i, g_drr.root_key[i]);
utsm_blake2b_ctx mc;
utsm_blake2b_init(&mc, 64, kb, 32);
for (u32 i = 0; i < used; i++) {
u8 rec[8 + 8 + 8 + 8];
utsm_store64_le(rec + 0, 0x544F4F524D535455ULL); /* "UTSMROOT" LE */
utsm_store64_le(rec + 8, ((u64)entries[i].seg_slot) |
((u64)entries[i].page_index << 32));
utsm_store64_le(rec + 16, entries[i].key_epoch);
utsm_store64_le(rec + 24, entries[i].mac);
utsm_blake2b_update(&mc, rec, sizeof(rec));
}
utsm_blake2b_final(&mc, chain);
target->mac_root = utsm_load64_le(chain);
}
target->segment_count = 0;
drr_checkpoint_finish();
log_info("[DRR] ckpt snapshot ok");
log_hex64("[DRR] pages=", used);
return (int)used;
}
int drr_rollback_pages(void) {
if (!g_drr.initialized) return -1;
if (!g_snap_ok) return -2;
drr_checkpoint_meta meta;
if (drr_checkpoint_recover(&meta) != 0) return -3;
if (meta.type != DRR_CKPT_DIRTY_PAGE) return -4;
drr_snap_header *h = snap_header();
if (h->magic != DRR_SNAP_MAGIC || h->version != DRR_SNAP_VERSION) return -5;
u32 used = h->used;
if (used > h->capacity) used = h->capacity;
drr_ckpt_page_entry *entries = snap_entries();
/* 触碰段先置 RECOVERING */
for (u32 i = 0; i < used; i++) {
utsm_segment_desc *d = utsm_get_segment(entries[i].seg_slot);
if (d && d->state == UTSM_SEG_ACTIVE) d->state = UTSM_SEG_RECOVERING;
}
int failed = 0;
u32 restored = 0;
for (u32 i = 0; i < used; i++) {
drr_ckpt_page_entry *e = &entries[i];
u8 *snap = snap_page_ptr(e->region_idx);
utsm_segment_desc *d = utsm_get_segment(e->seg_slot);
if (drr_crc64(snap, UTSM_PAGE_SIZE) != e->crc) {
failed = 1;
if (d) d->state = UTSM_SEG_POISONED;
log_error("[DRR] rollback crc fail");
log_hex64("[DRR] seg_slot=", e->seg_slot);
log_hex64("[DRR] page=", e->page_index);
continue;
}
/* Phase 9: 页 MAC 校验(伪造/跨纪元重放/区域篡改在此被拒) */
u64 mac = utsm_page_mac(g_drr.root_key, e->seg_slot, e->page_index,
e->key_epoch, snap);
if (mac != e->mac) {
failed = 1;
if (d) d->state = UTSM_SEG_POISONED;
log_error("[DRR] rollback mac fail");
log_hex64("[DRR] seg_slot=", e->seg_slot);
log_hex64("[DRR] page=", e->page_index);
continue;
}
drr_memcpy((void *)e->cipher_vaddr, snap, UTSM_PAGE_SIZE);
restored++;
/* 清除该页脏位(P2 之类的回写不再被误判为未 checkpoint) */
if (d && d->dirty_shard_count > 0 && d->dirty_shards && d->dirty_shards[0].bitmap) {
utsm_dirty_shard *sh = &d->dirty_shards[0];
u64 page = e->page_index;
if (page < sh->page_count && (sh->bitmap[page / 64] & (1ULL << (page % 64)))) {
sh->bitmap[page / 64] &= ~(1ULL << (page % 64));
if (sh->dirty_count > 0) sh->dirty_count--;
}
}
if (d && d->state == UTSM_SEG_RECOVERING) d->state = UTSM_SEG_ACTIVE;
}
log_info("[DRR] rollback done");
log_hex64("[DRR] pages=", restored);
return failed ? -2 : (int)restored;
}
void drr_system_rollback(const char *reason) {
log_error("[DRR] SYSTEM ROLLBACK");
if (reason) log_error(reason);
log_hex64("[DRR] generation=", g_drr.recovery_generation);
log_hex64("[DRR] heartbeat=", g_drr.heartbeat_counter);
log_error("[DRR] rebooting (8042 reset)");
for (;;) {
__asm__ volatile("cli");
outb(0x64, 0xFE); /* 8042 复位(A20 gate 已无关紧要) */
for (volatile u32 i = 0; i < 1000000u; i++) { }
__asm__ volatile("hlt");
}
}
void drr_handle_task_fault(u32 task_slot, const char *reason) {
log_error("[DRR] FAULT");
if (reason) log_error(reason);
log_hex64("[DRR] task_slot=", task_slot);
drr_report_fault(reason ? reason : "task fault");
drr_log_write_intent(task_slot, 0, 0);
int pages = drr_rollback_pages();
log_hex64("[DRR] rollback_pages=", (u64)(i64)pages);
if (g_sched_fault_cb) {
g_sched_fault_cb(task_slot); /* 可能不返回(当前任务被杀+切换) */
drr_log_write_commit(task_slot, 0, 0);
return;
}
if (g_reboot_enabled) {
drr_system_rollback(reason ? reason : "task fault (no sched cb)");
}
/* reboot disabled(selftest):仅留日志 */
}
int drr_watchdog_register(u32 task_slot, u32 timeout_ticks) {
if (!g_drr.initialized || timeout_ticks == 0) return -1;
for (int i = 0; i < DRR_WATCHDOG_MAX; i++) {
if (g_drr_wd[i].task_slot == task_slot) {
g_drr_wd[i].timeout_ticks = timeout_ticks;
g_drr_wd[i].last_kick_tick = g_drr.heartbeat_counter;
return 0;
}
}
for (int i = 0; i < DRR_WATCHDOG_MAX; i++) {
if (g_drr_wd[i].task_slot == 0xFFFFFFFFu) {
g_drr_wd[i].task_slot = task_slot;
g_drr_wd[i].timeout_ticks = timeout_ticks;
g_drr_wd[i].last_kick_tick = g_drr.heartbeat_counter;
return 0;
}
}
return -2;
}
int drr_watchdog_unregister(u32 task_slot) {
for (int i = 0; i < DRR_WATCHDOG_MAX; i++) {
if (g_drr_wd[i].task_slot == task_slot) {
g_drr_wd[i].task_slot = 0xFFFFFFFFu;
return 0;
}
}
return -1;
}
void drr_watchdog_kick(u32 task_slot) {
for (int i = 0; i < DRR_WATCHDOG_MAX; i++) {
if (g_drr_wd[i].task_slot == task_slot) {
g_drr_wd[i].last_kick_tick = g_drr.heartbeat_counter;
return;
}
}
}
void drr_watchdog_check(void) {
if (!g_drr.initialized) return;
for (int i = 0; i < DRR_WATCHDOG_MAX; i++) {
u32 slot = g_drr_wd[i].task_slot;
if (slot == 0xFFFFFFFFu) continue;
u64 now = g_drr.heartbeat_counter;
if (now - g_drr_wd[i].last_kick_tick > g_drr_wd[i].timeout_ticks) {
g_drr_wd[i].last_kick_tick = now; /* 防重复触发 */
drr_handle_task_fault(slot, "watchdog timeout");
}
}
}
void drr_set_reboot_enabled(int enabled) {
g_reboot_enabled = enabled;
}
void drr_set_sched_fault_cb(void (*cb)(u32 task_slot)) {
g_sched_fault_cb = cb;
}
/* kernel_api.drr 服务表(dkm_fill_platform_info 挂入) */
static const drr_recovery_api g_drr_api = {
.report_fault = drr_report_fault,
.heartbeat_get = drr_heartbeat_get,
.emergency_alloc = drr_emergency_alloc,
.ckpt_snapshot_dirty = drr_ckpt_snapshot_dirty,
.rollback_pages = drr_rollback_pages
};
const drr_recovery_api *drr_get_recovery_api(void) {
return &g_drr_api;
}
+17 -1
View File
@@ -1,6 +1,22 @@
drr/drr_stub.o: drr\drr_stub.c include\utsm\drr.h include\utsm\types.h \
include\utsm\config.h include\utsm\log.h
include\utsm\config.h include\utsm\log.h include\utsm\dma.h \
include\utsm\segment.h include\utsm\uuid.h include\utsm\status.h \
include\utsm\capability.h include\utsm\dirty.h include\utsm\dkm.h \
include\utsm\block.h include\utsm\net.h include\utsm\paging.h \
include\utsm\crypto.h include\utsm\blake2b.h
include\utsm\drr.h:
include\utsm\types.h:
include\utsm\config.h:
include\utsm\log.h:
include\utsm\dma.h:
include\utsm\segment.h:
include\utsm\uuid.h:
include\utsm\status.h:
include\utsm\capability.h:
include\utsm\dirty.h:
include\utsm\dkm.h:
include\utsm\block.h:
include\utsm\net.h:
include\utsm\paging.h:
include\utsm\crypto.h:
include\utsm\blake2b.h:
Binary file not shown.