ohhhhhhhhhhh (exclude linux-extra-rootfs.img build artifact)
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
#ifndef UTSM_BLAKE2B_H
|
||||
#define UTSM_BLAKE2B_H
|
||||
|
||||
#include <utsm/types.h>
|
||||
|
||||
/* ===================================================================
|
||||
* BLAKE2b(RFC 7693)— Phase 9 真实加密原语
|
||||
*
|
||||
* 纯 64-bit 整数实现(无 SSE/FPU 依赖,-mno-sse 下可用)。
|
||||
* 支持 1-64B 可变输出与 keyed 模式(key 0-64B)。
|
||||
* 角色:KDF(root→segment key)、页 MAC、mac_root 链。
|
||||
* =================================================================== */
|
||||
|
||||
#define UTSM_BLAKE2B_BLOCKBYTES 128u
|
||||
#define UTSM_BLAKE2B_MAXOUT 64u
|
||||
|
||||
typedef struct {
|
||||
u64 h[8]; /* 链值 */
|
||||
u64 t[2]; /* 已处理字节数(128 位计数器) */
|
||||
u8 buf[128]; /* 待压缩块缓冲 */
|
||||
u32 buf_len; /* buf 内有效字节数 */
|
||||
u32 out_len; /* 摘要输出长度 1-64 */
|
||||
u32 last_block; /* 最后一块标志 */
|
||||
} utsm_blake2b_ctx;
|
||||
|
||||
void utsm_blake2b_init(utsm_blake2b_ctx *ctx, u32 out_len, const void *key, u32 key_len);
|
||||
void utsm_blake2b_update(utsm_blake2b_ctx *ctx, const void *data, u64 len);
|
||||
void utsm_blake2b_final(utsm_blake2b_ctx *ctx, void *out);
|
||||
|
||||
/* one-shot:out_len 1-64,key_len 0-64(key=NULL 表示无 key) */
|
||||
void utsm_blake2b(const void *data, u64 len, const void *key, u32 key_len, void *out, u32 out_len);
|
||||
|
||||
/* ---- 小端序列化辅助(crypto 各处共用) ---- */
|
||||
static inline void utsm_store32_le(u8 *p, u32 v) {
|
||||
p[0] = (u8)(v); p[1] = (u8)(v >> 8); p[2] = (u8)(v >> 16); p[3] = (u8)(v >> 24);
|
||||
}
|
||||
static inline u32 utsm_load32_le(const u8 *p) {
|
||||
return (u32)p[0] | ((u32)p[1] << 8) | ((u32)p[2] << 16) | ((u32)p[3] << 24);
|
||||
}
|
||||
static inline void utsm_store64_le(u8 *p, u64 v) {
|
||||
utsm_store32_le(p, (u32)v);
|
||||
utsm_store32_le(p + 4, (u32)(v >> 32));
|
||||
}
|
||||
static inline u64 utsm_load64_le(const u8 *p) {
|
||||
return (u64)utsm_load32_le(p) | ((u64)utsm_load32_le(p + 4) << 32);
|
||||
}
|
||||
|
||||
#endif /* UTSM_BLAKE2B_H */
|
||||
@@ -14,4 +14,17 @@ void utsm_kdf_segment_key(uuid128_t process_uuid, uuid128_t segment_uuid, u64 ke
|
||||
u64 utsm_make_tweak(u64 tweak_seed, u64 line_index, u64 key_epoch);
|
||||
void utsm_crypt_line(const utsm_key_material *key, u64 tweak, const u8 *in, u8 *out);
|
||||
|
||||
/* ===================================================================
|
||||
* Phase 9 扩展:真实加密原语服务(尾部追加,ABI 兼容)
|
||||
* stream = ChaCha20 block(RFC 8439),hash/KDF/MAC = BLAKE2b(RFC 7693)
|
||||
* =================================================================== */
|
||||
|
||||
/* ChaCha20 block function:64B keystream。
|
||||
* counter=0 用法下 nonce=tweak 即可保证 (key,nonce) 唯一。 */
|
||||
void utsm_chacha20_block(const u32 key_words[8], u64 nonce, u64 counter, u8 out[64]);
|
||||
|
||||
/* 4KB 密文页 MAC:keyed BLAKE2b(key=root_key, domain||seg_slot||page||epoch||data),
|
||||
* 截断 64 位。root_key 为 4×u64(DRR root key)。 */
|
||||
u64 utsm_page_mac(const u64 *root_key, u32 seg_slot, u64 page_index, u64 key_epoch, const void *page);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -63,6 +63,24 @@ typedef struct dkm_driver_desc {
|
||||
typedef int (*dkm_driver_init_fn)(const struct dkm_kernel_api *api, struct dkm_driver_handle *handle);
|
||||
typedef int (*dkm_driver_exit_fn)(struct dkm_driver_handle *handle);
|
||||
|
||||
/* DRR 恢复根服务表(Phase8;驱动经 kernel_api->drr 使用) */
|
||||
typedef struct drr_recovery_api {
|
||||
void (*report_fault)(const char *reason);
|
||||
u64 (*heartbeat_get)(void);
|
||||
void *(*emergency_alloc)(u64 size, u64 alignment);
|
||||
int (*ckpt_snapshot_dirty)(void);
|
||||
int (*rollback_pages)(void);
|
||||
} drr_recovery_api;
|
||||
|
||||
/* SAS-R0-PCQ 调度器服务表(Phase7;驱动经 kernel_api->sched 使用) */
|
||||
typedef struct utsm_sched_api {
|
||||
u64 (*uptime_ns)(void);
|
||||
void (*yield)(void);
|
||||
u32 (*current_task_slot)(void);
|
||||
int (*task_create)(u32 process_slot, u32 priority, void (*entry)(void *), void *arg);
|
||||
void (*sleep_ms)(u32 ms);
|
||||
} utsm_sched_api;
|
||||
|
||||
typedef struct dkm_log_api {
|
||||
void (*info)(const char *msg);
|
||||
void (*warn)(const char *msg);
|
||||
@@ -84,7 +102,7 @@ typedef struct dkm_kernel_api {
|
||||
const void *vfs;
|
||||
const dkm_net_api *net;
|
||||
const void *timer;
|
||||
const void *drr;
|
||||
const drr_recovery_api *drr; /* 恢复根服务(原占位 void* 改具体类型,布局不变) */
|
||||
|
||||
const void *rsdp_address; /* ACPI RSDP physical address */
|
||||
const void *fb_address; /* framebuffer base */
|
||||
@@ -111,6 +129,10 @@ typedef struct dkm_kernel_api {
|
||||
* 接口已接受向量命名空间,无需新注册 ABI)。 */
|
||||
int (*irq_vector_alloc)(void);
|
||||
void (*irq_vector_free)(int vector);
|
||||
/* M4/Phase7-8: 调度器服务(尾部追加,ABI 兼容;drr 服务见上方原占位字段)。
|
||||
* 驱动可用:task_create/uptime/sleep/current_task_slot。
|
||||
* DSK 以 api+0xA8 硬偏移读 block 的约定不受影响(仅尾部追加)。 */
|
||||
const utsm_sched_api *sched;
|
||||
} dkm_kernel_api;
|
||||
|
||||
typedef enum dkm_driver_state {
|
||||
@@ -142,6 +164,10 @@ void dsm_load_by_manifest(void);
|
||||
void dkm_fill_platform_info(void);
|
||||
const dkm_kernel_api *dkm_get_kernel_api(void);
|
||||
|
||||
/* 服务表实现(drr_stub.c / sched/sched.c 提供,fill 时挂入 kernel_api) */
|
||||
const struct drr_recovery_api *drr_get_recovery_api(void);
|
||||
const struct utsm_sched_api *utsm_sched_get_api(void);
|
||||
|
||||
/* exposed for manifest parser */
|
||||
struct dkm_symbol_scan {
|
||||
const void *driver_desc;
|
||||
|
||||
@@ -124,4 +124,55 @@ u64 drr_heartbeat_get(void);
|
||||
/* CRC64 */
|
||||
u64 drr_crc64(const void *data, u64 len);
|
||||
|
||||
/* ===================================================================
|
||||
* Phase 8 扩展:真实脏页快照 / 页级回滚 / 看门狗 / system rollback
|
||||
* (尾部追加,不动既有结构与语义)
|
||||
* =================================================================== */
|
||||
|
||||
/* 快照区条目(快照区第 0 页:头(64B) + 条目数组顺序存放) */
|
||||
typedef struct {
|
||||
u32 seg_slot; /* utsm_get_segment 的 slot */
|
||||
u32 page_index; /* 段内页号 */
|
||||
u64 cipher_vaddr; /* 段内目标页虚拟地址(HHDM,回滚目标) */
|
||||
u64 crc; /* 快照数据 CRC64(drr_crc64,区域完整性) */
|
||||
u32 region_idx; /* 快照数据所在页序号(区域第 1+idx 页) */
|
||||
u32 used;
|
||||
/* Phase 9: 真实 MAC(keyed BLAKE2b,绑定 seg/page/epoch) */
|
||||
u64 key_epoch; /* 快照时刻段 key_epoch(MAC 上下文 + 防跨纪元重放) */
|
||||
u64 mac; /* 页 MAC(utsm_page_mac,截断 64 位) */
|
||||
} drr_ckpt_page_entry;
|
||||
|
||||
/* 真实脏页快照:扫描全部 ACTIVE 段的 dirty shard 位图,逐脏页复制到
|
||||
* 快照区(先快照后清位;区满则部分提交且不清位),随后走 A/B checkpoint
|
||||
* 原子切换。O(dirty_shards + dirty_pages)。
|
||||
* 返回快照页数(>=0);负数失败(未初始化/快照区不可用)。 */
|
||||
int drr_ckpt_snapshot_dirty(void);
|
||||
|
||||
/* 页级回滚:按 active slot 元数据 + 快照区逐页 CRC 校验后恢复密文页
|
||||
* 并清除对应脏位;触碰段状态 RECOVERING → ACTIVE,CRC 失败段 POISONED。
|
||||
* 返回恢复页数(>=0);失败 -2(任一页 CRC 不符)。 */
|
||||
int drr_rollback_pages(void);
|
||||
|
||||
/* 系统级回滚:crash 留痕 + 8042 复位(不返回)。
|
||||
* Emergency Pool 耗尽 / 双槽皆坏 / 无任务可切换时调用。 */
|
||||
void drr_system_rollback(const char *reason);
|
||||
|
||||
/* 统一 fault 入口:report_fault → 页级回滚 → sched fault 回调(可能不
|
||||
* 返回);回调缺失且 reboot 使能时 → system rollback。 */
|
||||
void drr_handle_task_fault(u32 task_slot, const char *reason);
|
||||
|
||||
/* 看门狗(独立于调度器:由 tick handler 直接调用 check,非调度任务) */
|
||||
#define DRR_WATCHDOG_MAX 8
|
||||
int drr_watchdog_register(u32 task_slot, u32 timeout_ticks);
|
||||
int drr_watchdog_unregister(u32 task_slot);
|
||||
void drr_watchdog_kick(u32 task_slot);
|
||||
void drr_watchdog_check(void);
|
||||
|
||||
/* 恢复行为控制:关闭后 fault 只留日志不真重启(selftest 用) */
|
||||
void drr_set_reboot_enabled(int enabled);
|
||||
|
||||
/* 调度器 fault 回调(sched enable 时注入;缺失时 fault → system rollback)。
|
||||
* DRR 独立性:对调度器只依赖这一个函数指针。 */
|
||||
void drr_set_sched_fault_cb(void (*cb)(u32 task_slot));
|
||||
|
||||
#endif /* UTSM_DRR_H */
|
||||
|
||||
@@ -31,6 +31,14 @@ int ept_identity_map(u64 gpa, u64 size, u64 flags);
|
||||
* Handles 4KB pages and 2MB large pages. */
|
||||
u64 ept_gpa_to_hpa(u64 gpa);
|
||||
|
||||
/* Rewrite an existing EPT leaf (4K or 2MB) as RWX+WB+Ignore PAT.
|
||||
* Returns 0 if a leaf was found and rewritten, -1 if unmapped.
|
||||
* Used to recover from nested-KVM EPT misconfig (guest PAT vs EPT type). */
|
||||
int ept_repair_leaf(u64 gpa, u64 flags);
|
||||
|
||||
/* Log PML4/PDPT/PD/PT entries for a GPA (misconfig diagnostics). */
|
||||
void ept_log_walk(u64 gpa);
|
||||
|
||||
/* Map a 2MB large page in EPT (PD-level direct mapping).
|
||||
* GPA and HPA must be 2MB-aligned. memtype = EPT_MEMORY_TYPE_*.
|
||||
* Required for real hardware MTRR compliance. */
|
||||
|
||||
@@ -0,0 +1,475 @@
|
||||
/* fluent_ui.h — Deshab "Win11 Fluent" 视觉组件库
|
||||
*
|
||||
* 设计目标:商业化 Windows 11 风格 —— 居中悬浮圆角任务栏、亚克力半透明
|
||||
* 弹层、圆角窗口、浅色/深色主题(见桌面重构计划第二节)。
|
||||
*
|
||||
* 分层:
|
||||
* L1 wf_theme 主题令牌(色板 + 圆角),g_wf_light / g_wf_dark 预设
|
||||
* L2 原语 du_wf_acrylic(读背景 alpha 混合圆角面板)、du_wf_shadow、
|
||||
* du_wf_line(Bresenham 带宽线)、du_wf_ring(圆环/半弧)
|
||||
* L3 组件 按钮/图标钮/开关/滑块/列表项/卡片/文本框/滚动条/提示
|
||||
* L4 图标 du_wf_icon 矢量线性图标(24 网格设计,2px 笔触)
|
||||
*
|
||||
* 约定(与 deshab_ui.h 相同):包含本头前,编译单元须已定义 g_ascii
|
||||
* (include ascii_font.h 或 ascii_bitmaps.c)。所有组件为纯绘制函数,
|
||||
* hover/press 态由调用方检测并传入。
|
||||
*
|
||||
* 中文文本:本库组件标签为 ASCII;中文请调用方用 zh_draw_string +
|
||||
* 主题令牌色绘制(zhfont.h 在 CODE/desktop/,不进 UTSM 公共头)。
|
||||
*/
|
||||
#ifndef DESHAB_FLUENT_UI_H
|
||||
#define DESHAB_FLUENT_UI_H
|
||||
|
||||
#include <utsm/deshab_ui.h>
|
||||
|
||||
/* ===================================================================
|
||||
* L1 — 主题令牌 (wf_theme)
|
||||
* =================================================================== */
|
||||
|
||||
typedef struct {
|
||||
/* 亚克力面板 */
|
||||
du_u32 acrylic_tint; /* 混入背景的 tint 色 */
|
||||
du_u32 acrylic_stroke; /* 1px 边线 */
|
||||
du_u32 acrylic_solid; /* 不透明回退底色(无 alpha 场景) */
|
||||
|
||||
/* 文本 */
|
||||
du_u32 text_primary;
|
||||
du_u32 text_secondary;
|
||||
du_u32 text_dim;
|
||||
|
||||
/* 强调色(Win11 accent) */
|
||||
du_u32 accent;
|
||||
du_u32 accent_hover;
|
||||
du_u32 accent_press;
|
||||
du_u32 on_accent; /* accent 上的文字 */
|
||||
|
||||
/* 控件 */
|
||||
du_u32 control_stroke;
|
||||
du_u32 window_border;
|
||||
du_u32 divider;
|
||||
du_u32 shadow;
|
||||
|
||||
/* 语义色 */
|
||||
du_u32 success, warning, error;
|
||||
du_u32 close_hover; /* 窗口关闭钮 hover 红 #E81123 */
|
||||
|
||||
/* 圆角 */
|
||||
int radius_sm; /* 4 按钮/输入框 */
|
||||
int radius_md; /* 8 卡片/窗口 */
|
||||
int radius_lg; /* 12 任务栏/开始菜单/弹层 */
|
||||
} wf_theme;
|
||||
|
||||
/* 浅色主题(Win11 Light:底 #F3F3F3,accent #0067C0) */
|
||||
static const wf_theme g_wf_light = {
|
||||
0xFFF3F3F3u, /* acrylic_tint */
|
||||
0xFFEDEDEDu, /* acrylic_stroke */
|
||||
0xFFF6F6F6u, /* acrylic_solid */
|
||||
0xFF1A1A1Au, 0xFF5D5D5Du, 0xFF8A8A8Au,
|
||||
0xFF0067C0u, 0xFF0078D4u, 0xFF005A9Eu, 0xFFFFFFFFu,
|
||||
0xFFD6D6D6u, /* control_stroke */
|
||||
0xFFE5E5E5u, /* window_border */
|
||||
0xFFEDEDEDu, /* divider */
|
||||
0x66000000u, /* shadow */
|
||||
0xFF0F7B0Fu, 0xFF9D5D00u, 0xFFC42B1Cu,
|
||||
0xFFC42B1Cu,
|
||||
4, 8, 12,
|
||||
};
|
||||
|
||||
/* 深色主题(Win11 Dark:底 #202020,accent #4CC2FF) */
|
||||
static const wf_theme g_wf_dark = {
|
||||
0xFF202020u,
|
||||
0xFF3C3C3Cu, /* acrylic_stroke */
|
||||
0xFF2B2B2Bu,
|
||||
0xFFFFFFFFu, 0xFFC8C8C8u, 0xFF9A9A9Au,
|
||||
0xFF4CC2FFu, 0xFF62CBFFu, 0xFF29A8E0u, 0xFF00293Cu,
|
||||
0xFF3C3C3Cu, /* control_stroke */
|
||||
0xFF3F3F3Fu, /* window_border */
|
||||
0xFF3A3A3Au, /* divider */
|
||||
0x99000000u, /* shadow */
|
||||
0xFF6CCB5Fu, 0xFFFCE100u, 0xFFFF99A4u,
|
||||
0xFFC42B1Cu,
|
||||
4, 8, 12,
|
||||
};
|
||||
|
||||
/* ===================================================================
|
||||
* L2 — 原语
|
||||
* =================================================================== */
|
||||
|
||||
/* 亚克力面板:逐像素读背景 → alpha 混合 tint → 圆角掩码。
|
||||
* 真实 backdrop blur 不可行,靠"高透 tint + 1px 边 + 壁纸层透出"模拟。
|
||||
* 仅用于弹层/任务栏(面积 <40% 屏,性能预算见计划第七节)。 */
|
||||
static inline void du_wf_acrylic(du_context *ctx, du_i64 x, du_i64 y,
|
||||
du_i64 w, du_i64 h,
|
||||
du_u32 alpha, du_u32 radius,
|
||||
const wf_theme *t) {
|
||||
du_i64 r = (du_i64)radius;
|
||||
if (r * 2 > w) r = w / 2;
|
||||
if (r * 2 > h) r = h / 2;
|
||||
for (du_i64 row = 0; row < h; row++) {
|
||||
for (du_i64 col = 0; col < w; col++) {
|
||||
du_i64 dx = 0, dy = 0;
|
||||
int corner = 0;
|
||||
if (col < r && row < r) { dx = r - 1 - col; dy = r - 1 - row; corner = 1; }
|
||||
else if (col >= w - r && row < r) { dx = col - (w - r); dy = r - 1 - row; corner = 1; }
|
||||
else if (col < r && row >= h - r) { dx = r - 1 - col; dy = row - (h - r); corner = 1; }
|
||||
else if (col >= w - r && row >= h - r) { dx = col - (w - r); dy = row - (h - r); corner = 1; }
|
||||
if (corner && dx * dx + dy * dy > r * r) continue;
|
||||
du_u32 bg = du_pixel_read(ctx, x + col, y + row);
|
||||
du_pixel(ctx, x + col, y + row, du_blend(bg, t->acrylic_tint, alpha));
|
||||
}
|
||||
}
|
||||
du_rect_outline(ctx, x, y, w, h, t->acrylic_stroke, (du_u32)r);
|
||||
}
|
||||
|
||||
/* 投影:外扩 2 圈递减 alpha 描边(比逐像素卷积便宜 100 倍) */
|
||||
static inline void du_wf_shadow(du_context *ctx, du_i64 x, du_i64 y,
|
||||
du_i64 w, du_i64 h, du_u32 radius,
|
||||
const wf_theme *t) {
|
||||
du_u32 base = du_pixel_read(ctx, x, y + h + 2);
|
||||
for (int i = 2; i >= 1; i--) {
|
||||
du_u32 alpha = (i == 2) ? 40 : 70;
|
||||
du_rect_outline(ctx, x - i, y - i, w + 2 * i, h + 2 * i,
|
||||
du_blend(base, t->shadow, alpha),
|
||||
radius + (du_u32)i);
|
||||
}
|
||||
}
|
||||
|
||||
/* 半透明控件蒙层(hover/press 态) */
|
||||
static inline void du_wf_overlay(du_context *ctx, du_i64 x, du_i64 y,
|
||||
du_i64 w, du_i64 h, du_u32 overlay) {
|
||||
du_u32 alpha = overlay >> 24;
|
||||
if (!alpha) return;
|
||||
for (du_i64 row = 0; row < h; row++)
|
||||
for (du_i64 col = 0; col < w; col++)
|
||||
du_pixel(ctx, x + col, y + row,
|
||||
du_blend(du_pixel_read(ctx, x + col, y + row),
|
||||
overlay, alpha));
|
||||
}
|
||||
|
||||
/* Bresenham 直线(带厚度 w 像素) */
|
||||
static inline void du_wf_line(du_context *ctx, du_i64 x0, du_i64 y0,
|
||||
du_i64 x1, du_i64 y1, du_i64 w, du_u32 color) {
|
||||
du_i64 dx = (x1 > x0) ? x1 - x0 : x0 - x1;
|
||||
du_i64 dy = (y1 > y0) ? y1 - y0 : y0 - y1;
|
||||
du_i64 sx = (x0 < x1) ? 1 : -1;
|
||||
du_i64 sy = (y0 < y1) ? 1 : -1;
|
||||
du_i64 err = dx - dy;
|
||||
du_i64 half = w / 2;
|
||||
for (;;) {
|
||||
du_fill_rect(ctx, x0 - half, y0 - half, w, w, color);
|
||||
if (x0 == x1 && y0 == y1) break;
|
||||
du_i64 e2 = 2 * err;
|
||||
if (e2 > -dy) { err -= dy; x0 += sx; }
|
||||
if (e2 < dx) { err += dx; y0 += sy; }
|
||||
}
|
||||
}
|
||||
|
||||
/* 圆环:中心 (cx,cy),外半径 r,厚度 s。
|
||||
* half : 0 全环,1 仅上半(dy<=0),-1 仅下半 */
|
||||
static inline void du_wf_ring(du_context *ctx, du_i64 cx, du_i64 cy,
|
||||
du_i64 r, du_i64 s, int half, du_u32 color) {
|
||||
for (du_i64 dy = -r; dy <= r; dy++) {
|
||||
if (half == 1 && dy > 0) continue;
|
||||
if (half == -1 && dy < 0) continue;
|
||||
for (du_i64 dx = -r; dx <= r; dx++) {
|
||||
du_i64 d2 = dx * dx + dy * dy;
|
||||
if (d2 <= r * r && d2 > (r - s) * (r - s))
|
||||
du_pixel(ctx, cx + dx, cy + dy, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ===================================================================
|
||||
* L3 — 组件
|
||||
* =================================================================== */
|
||||
|
||||
/* 按钮态 */
|
||||
typedef enum { WF_BTN_NORMAL = 0, WF_BTN_HOVER, WF_BTN_PRESS } wf_btn_state;
|
||||
|
||||
/* 标准按钮:圆角 4,三态底色,ASCII 标签居中(accent=1 为强调按钮) */
|
||||
static inline void du_wf_button(du_context *ctx, du_i64 x, du_i64 y, du_i64 w,
|
||||
const char *label, const wf_theme *t,
|
||||
wf_btn_state st, int accent) {
|
||||
du_i64 h = 32;
|
||||
du_u32 bg = accent ? t->accent : t->acrylic_solid;
|
||||
du_u32 fg = accent ? t->on_accent : t->text_primary;
|
||||
if (accent) {
|
||||
du_fill_rounded_rect(ctx, x, y, w, h, bg, 4);
|
||||
if (st != WF_BTN_NORMAL)
|
||||
du_wf_overlay(ctx, x + 1, y + 1, w - 2, h - 2,
|
||||
(st == WF_BTN_PRESS) ? 0x44FFFFFFu : 0x22FFFFFFu);
|
||||
} else {
|
||||
du_fill_rounded_rect(ctx, x, y, w, h, bg, 4);
|
||||
du_rect_outline(ctx, x, y, w, h, t->control_stroke, 4);
|
||||
if (st != WF_BTN_NORMAL)
|
||||
du_wf_overlay(ctx, x + 1, y + 1, w - 2, h - 2,
|
||||
(st == WF_BTN_PRESS) ? 0x33000000u : 0x22000000u);
|
||||
}
|
||||
du_i64 len = 0;
|
||||
while (label[len]) len++;
|
||||
du_draw_string(ctx, label,
|
||||
x + (w - len * (du_i64)DU_ASCII_STEP) / 2,
|
||||
y + (h - (du_i64)DU_ASCII_CELL_H) / 2,
|
||||
fg, bg, DU_ASCII_STEP);
|
||||
}
|
||||
|
||||
/* 图标按钮:圆角 4 悬停/按下蒙层(图标由调用方叠加绘制) */
|
||||
static inline void du_wf_icon_button(du_context *ctx, du_i64 x, du_i64 y,
|
||||
du_i64 size, const wf_theme *t,
|
||||
wf_btn_state st) {
|
||||
(void)t;
|
||||
if (st == WF_BTN_NORMAL) return;
|
||||
du_wf_overlay(ctx, x, y, size, size,
|
||||
(st == WF_BTN_PRESS) ? 0x33000000u : 0x22000000u);
|
||||
du_rect_outline(ctx, x, y, size, size, 0x33000000u, 4);
|
||||
}
|
||||
|
||||
/* 开关:轨道 40×20 圆角 full + 滑块 */
|
||||
static inline void du_wf_toggle(du_context *ctx, du_i64 x, du_i64 y,
|
||||
int on, const wf_theme *t) {
|
||||
du_u32 track = on ? t->accent : 0xFF8A8A8Au;
|
||||
du_fill_rounded_rect(ctx, x, y, 40, 20, track, 10);
|
||||
if (on) du_fill_rounded_rect(ctx, x + 20, y + 2, 16, 16, 0xFFFFFFFFu, 8);
|
||||
else du_fill_rounded_rect(ctx, x + 4, y + 2, 16, 16, 0xFFFFFFFFu, 8);
|
||||
}
|
||||
|
||||
/* 滑块:细轨 4px 圆头 + 圆形拇指。rect_out 返回可拖拽轨道命中区。 */
|
||||
static inline void du_wf_slider(du_context *ctx, du_i64 x, du_i64 y,
|
||||
du_i64 w, int val, const wf_theme *t,
|
||||
int rect_out[4]) {
|
||||
du_i64 ty = y + 8;
|
||||
du_fill_rounded_rect(ctx, x, ty, w, 4, t->control_stroke, 2);
|
||||
du_i64 fw = w * val / 100;
|
||||
if (fw > 2) du_fill_rounded_rect(ctx, x, ty, fw, 4, t->accent, 2);
|
||||
du_i64 kx = x + fw - 8;
|
||||
if (kx < x) kx = x;
|
||||
if (kx > x + w - 16) kx = x + w - 16;
|
||||
du_fill_rounded_rect(ctx, kx, y, 16, 16, t->accent, 8);
|
||||
if (rect_out) {
|
||||
rect_out[0] = (int)x; rect_out[1] = (int)y - 2;
|
||||
rect_out[2] = (int)w; rect_out[3] = 20;
|
||||
}
|
||||
}
|
||||
|
||||
/* 列表项:32px 行高,hover/selected 蒙层 + 左侧 3px accent 条 */
|
||||
static inline void du_wf_list_item(du_context *ctx, du_i64 x, du_i64 y,
|
||||
du_i64 w, const char *label,
|
||||
const wf_theme *t, int hover, int selected) {
|
||||
if (selected) du_wf_overlay(ctx, x, y, w, 32, 0x28000000u);
|
||||
else if (hover) du_wf_overlay(ctx, x, y, w, 32, 0x1A000000u);
|
||||
if (selected) du_fill_rect(ctx, x, y + 8, 3, 16, t->accent);
|
||||
du_draw_string(ctx, label, x + 12,
|
||||
y + (32 - (du_i64)DU_ASCII_CELL_H) / 2,
|
||||
selected ? t->text_primary : t->text_secondary,
|
||||
0, DU_ASCII_STEP);
|
||||
}
|
||||
|
||||
/* 卡片:圆角 8 + 投影 + 亚克力 */
|
||||
static inline void du_wf_card(du_context *ctx, du_i64 x, du_i64 y,
|
||||
du_i64 w, du_i64 h, du_u32 alpha,
|
||||
const wf_theme *t) {
|
||||
du_wf_shadow(ctx, x, y, w, h, (du_u32)t->radius_md, t);
|
||||
du_wf_acrylic(ctx, x, y, w, h, alpha, (du_u32)t->radius_md, t);
|
||||
}
|
||||
|
||||
/* 文本框(搜索框):圆角 4,聚焦时 accent 底边线 + 光标 */
|
||||
static inline void du_wf_textbox(du_context *ctx, du_i64 x, du_i64 y,
|
||||
du_i64 w, const char *text, int cursor_blink,
|
||||
const wf_theme *t, int focused) {
|
||||
du_i64 h = 36;
|
||||
du_fill_rounded_rect(ctx, x, y, w, h, t->acrylic_solid, 4);
|
||||
du_rect_outline(ctx, x, y, w, h, focused ? t->accent : t->control_stroke, 4);
|
||||
if (focused) du_fill_rect(ctx, x + 4, y + h - 2, w - 8, 2, t->accent);
|
||||
du_u32 fg = text[0] ? t->text_primary : t->text_dim;
|
||||
du_draw_string(ctx, text, x + 12, y + (h - (du_i64)DU_ASCII_CELL_H) / 2,
|
||||
fg, t->acrylic_solid, DU_ASCII_STEP);
|
||||
if (focused && cursor_blink) {
|
||||
du_i64 len = 0;
|
||||
while (text[len]) len++;
|
||||
du_fill_rect(ctx, x + 12 + len * (du_i64)DU_ASCII_STEP + 2,
|
||||
y + 9, 2, (du_i64)DU_ASCII_CELL_H, t->accent);
|
||||
}
|
||||
}
|
||||
|
||||
/* 滚动条:4px 覆盖式 */
|
||||
static inline void du_wf_scrollbar(du_context *ctx, du_i64 x, du_i64 y,
|
||||
du_i64 h, int pos_0_100, int ratio_0_100,
|
||||
const wf_theme *t) {
|
||||
if (ratio_0_100 >= 100) return;
|
||||
du_i64 thumb_h = h * ratio_0_100 / 100;
|
||||
if (thumb_h < 24) thumb_h = 24;
|
||||
du_i64 max_travel = h - thumb_h;
|
||||
du_i64 ty = y + max_travel * pos_0_100 / 100;
|
||||
du_fill_rounded_rect(ctx, x, ty, 4, thumb_h, t->text_dim, 2);
|
||||
}
|
||||
|
||||
/* 提示(tooltip):小圆角不透明底 */
|
||||
static inline void du_wf_tooltip(du_context *ctx, du_i64 x, du_i64 y,
|
||||
const char *label, const wf_theme *t) {
|
||||
du_i64 len = 0;
|
||||
while (label[len]) len++;
|
||||
du_i64 w = len * (du_i64)DU_ASCII_STEP + 16;
|
||||
du_fill_rounded_rect(ctx, x, y, w, 28, t->acrylic_solid, 4);
|
||||
du_rect_outline(ctx, x, y, w, 28, t->control_stroke, 4);
|
||||
du_draw_string(ctx, label, x + 8, y + (28 - (du_i64)DU_ASCII_CELL_H) / 2,
|
||||
t->text_primary, t->acrylic_solid, DU_ASCII_STEP);
|
||||
}
|
||||
|
||||
/* ===================================================================
|
||||
* L4 — 矢量图标(24 网格设计,线性 2px 笔触,Win11 Segoe 风格)
|
||||
*
|
||||
* 所有图标以 (x, y) 为左上角、size 为边长绘制,按 u = size/24 缩放
|
||||
* (u 为最小单位,笔触 s = 2u)。
|
||||
* =================================================================== */
|
||||
|
||||
typedef enum {
|
||||
WF_ICON_START = 1, /* 四方块(开始) */
|
||||
WF_ICON_SEARCH, /* 放大镜 */
|
||||
WF_ICON_NETWORK, /* WiFi 扇形 */
|
||||
WF_ICON_VOLUME, /* 喇叭 */
|
||||
WF_ICON_POWER, /* 电源 */
|
||||
WF_ICON_TASKMGR, /* 折线图 */
|
||||
WF_ICON_SETTINGS, /* 齿轮(简化) */
|
||||
WF_ICON_FOLDER, /* 文件夹 */
|
||||
WF_ICON_TERMINAL, /* 终端 >_ */
|
||||
WF_ICON_EDITOR, /* 文档横线 */
|
||||
WF_ICON_CALC, /* 计算器格子 */
|
||||
WF_ICON_BROWSER, /* 地球 */
|
||||
WF_ICON_TASKVIEW, /* 双矩形 */
|
||||
WF_ICON_WIDGETS, /* 四小件 */
|
||||
WF_ICON_NOTIFY, /* 铃铛 */
|
||||
WF_ICON_CLOSE, /* × */
|
||||
WF_ICON_MIN, /* – */
|
||||
WF_ICON_MAX, /* □ */
|
||||
WF_ICON_RESTORE, /* 双层 □ */
|
||||
WF_ICON_USER, /* 人形 */
|
||||
} wf_icon_id;
|
||||
|
||||
static inline void du_wf_icon(du_context *ctx, wf_icon_id id,
|
||||
du_i64 x, du_i64 y, du_i64 size, du_u32 color) {
|
||||
du_i64 u = size / 24;
|
||||
if (u < 1) u = 1;
|
||||
du_i64 s = u * 2; /* 笔触宽 */
|
||||
switch (id) {
|
||||
case WF_ICON_START:
|
||||
du_fill_rounded_rect(ctx, x + 3 * u, y + 3 * u, 8 * u, 8 * u, color, (du_u32)u);
|
||||
du_fill_rounded_rect(ctx, x + 13 * u, y + 3 * u, 8 * u, 8 * u, color, (du_u32)u);
|
||||
du_fill_rounded_rect(ctx, x + 3 * u, y + 13 * u, 8 * u, 8 * u, color, (du_u32)u);
|
||||
du_fill_rounded_rect(ctx, x + 13 * u, y + 13 * u, 8 * u, 8 * u, color, (du_u32)u);
|
||||
break;
|
||||
case WF_ICON_SEARCH:
|
||||
du_wf_ring(ctx, x + 10 * u, y + 10 * u, 7 * u, s, 0, color);
|
||||
du_wf_line(ctx, x + 15 * u, y + 15 * u, x + 20 * u, y + 20 * u, s, color);
|
||||
break;
|
||||
case WF_ICON_NETWORK:
|
||||
du_fill_rounded_rect(ctx, x + 10 * u, y + 17 * u, 3 * u, 3 * u, color, (du_u32)u);
|
||||
du_wf_ring(ctx, x + 11 * u, y + 19 * u, 6 * u, s, 1, color);
|
||||
du_wf_ring(ctx, x + 11 * u, y + 21 * u, 10 * u, s, 1, color);
|
||||
break;
|
||||
case WF_ICON_VOLUME:
|
||||
/* 喇叭主体:梯形 */
|
||||
du_fill_rect(ctx, x + 3 * u, y + 9 * u, 4 * u, 6 * u, color);
|
||||
du_wf_line(ctx, x + 7 * u, y + 9 * u, x + 11 * u, y + 5 * u, s, color);
|
||||
du_wf_line(ctx, x + 11 * u, y + 5 * u, x + 11 * u, y + 19 * u, s, color);
|
||||
du_wf_line(ctx, x + 11 * u, y + 19 * u, x + 7 * u, y + 15 * u, s, color);
|
||||
/* 声波弧 */
|
||||
du_wf_ring(ctx, x + 11 * u, y + 12 * u, 7 * u, s, 1, color);
|
||||
break;
|
||||
case WF_ICON_POWER:
|
||||
du_fill_rect(ctx, x + 11 * u, y + 3 * u, s, 8 * u, color);
|
||||
du_wf_ring(ctx, x + 12 * u, y + 13 * u, 8 * u, s, 0, color);
|
||||
break;
|
||||
case WF_ICON_TASKMGR:
|
||||
du_rect_outline(ctx, x + 2 * u, y + 3 * u, 20 * u, 18 * u, color, (du_u32)u);
|
||||
du_wf_line(ctx, x + 5 * u, y + 15 * u, x + 9 * u, y + 10 * u, s, color);
|
||||
du_wf_line(ctx, x + 9 * u, y + 10 * u, x + 13 * u, y + 13 * u, s, color);
|
||||
du_wf_line(ctx, x + 13 * u, y + 13 * u, x + 19 * u, y + 6 * u, s, color);
|
||||
break;
|
||||
case WF_ICON_SETTINGS:
|
||||
du_wf_ring(ctx, x + 12 * u, y + 12 * u, 5 * u, s, 0, color);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
/* 8 个齿:每 45° 一个短径向线 */
|
||||
du_i64 ax[8] = {0, 1, 1, 1, 0, -1, -1, -1};
|
||||
du_i64 ay[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
|
||||
du_wf_line(ctx, x + 12 * u + ax[i] * 7 * u, y + 12 * u + ay[i] * 7 * u,
|
||||
x + 12 * u + ax[i] * 10 * u, y + 12 * u + ay[i] * 10 * u,
|
||||
s, color);
|
||||
}
|
||||
break;
|
||||
case WF_ICON_FOLDER:
|
||||
du_fill_rect(ctx, x + 3 * u, y + 6 * u, 7 * u, 3 * u, color);
|
||||
du_rect_outline(ctx, x + 3 * u, y + 6 * u, 18 * u, 12 * u, color, (du_u32)u);
|
||||
du_fill_rect(ctx, x + 3 * u, y + 11 * u, 18 * u, u, color);
|
||||
break;
|
||||
case WF_ICON_TERMINAL:
|
||||
du_rect_outline(ctx, x + 2 * u, y + 4 * u, 20 * u, 16 * u, color, (du_u32)u);
|
||||
du_wf_line(ctx, x + 6 * u, y + 9 * u, x + 10 * u, y + 12 * u, u + 1, color);
|
||||
du_wf_line(ctx, x + 10 * u, y + 12 * u, x + 6 * u, y + 15 * u, u + 1, color);
|
||||
du_fill_rect(ctx, x + 12 * u, y + 15 * u, 5 * u, u + 1, color);
|
||||
break;
|
||||
case WF_ICON_EDITOR:
|
||||
du_rect_outline(ctx, x + 5 * u, y + 2 * u, 14 * u, 20 * u, color, (du_u32)u);
|
||||
du_fill_rect(ctx, x + 8 * u, y + 8 * u, 8 * u, u, color);
|
||||
du_fill_rect(ctx, x + 8 * u, y + 12 * u, 8 * u, u, color);
|
||||
du_fill_rect(ctx, x + 8 * u, y + 16 * u, 5 * u, u, color);
|
||||
break;
|
||||
case WF_ICON_CALC:
|
||||
du_rect_outline(ctx, x + 4 * u, y + 2 * u, 16 * u, 20 * u, color, (du_u32)u);
|
||||
du_rect_outline(ctx, x + 7 * u, y + 5 * u, 10 * u, 4 * u, color, (du_u32)u);
|
||||
for (int r = 0; r < 3; r++)
|
||||
for (int c = 0; c < 3; c++)
|
||||
du_fill_rect(ctx, x + (7 + c * 4) * u, y + (12 + r * 3) * u,
|
||||
2 * u, 2 * u, color);
|
||||
break;
|
||||
case WF_ICON_BROWSER:
|
||||
du_wf_ring(ctx, x + 12 * u, y + 12 * u, 9 * u, s, 0, color);
|
||||
du_fill_rect(ctx, x + 3 * u, y + 11 * u, 18 * u, s, color);
|
||||
du_wf_ring(ctx, x + 12 * u, y + 12 * u, 5 * u, u, 0, 0); /* 清理中圈 */
|
||||
du_wf_line(ctx, x + 8 * u, y + 4 * u, x + 8 * u, y + 20 * u, u, color);
|
||||
du_wf_line(ctx, x + 16 * u, y + 4 * u, x + 16 * u, y + 20 * u, u, color);
|
||||
break;
|
||||
case WF_ICON_TASKVIEW:
|
||||
du_rect_outline(ctx, x + 3 * u, y + 5 * u, 13 * u, 11 * u, color, (du_u32)u);
|
||||
du_rect_outline(ctx, x + 9 * u, y + 8 * u, 12 * u, 11 * u, color, (du_u32)u);
|
||||
break;
|
||||
case WF_ICON_WIDGETS:
|
||||
du_fill_rounded_rect(ctx, x + 3 * u, y + 3 * u, 8 * u, 8 * u, color, (du_u32)u);
|
||||
du_fill_rounded_rect(ctx, x + 13 * u, y + 3 * u, 8 * u, 8 * u, color, (du_u32)u);
|
||||
du_fill_rounded_rect(ctx, x + 3 * u, y + 13 * u, 5 * u, 8 * u, color, (du_u32)u);
|
||||
du_fill_rounded_rect(ctx, x + 10 * u, y + 13 * u, 11 * u, 8 * u, color, (du_u32)u);
|
||||
break;
|
||||
case WF_ICON_NOTIFY:
|
||||
/* 铃铛:拱顶 + 两侧斜线 + 底线 + 铃锤 */
|
||||
du_wf_ring(ctx, x + 12 * u, y + 14 * u, 8 * u, s, 1, color);
|
||||
du_wf_line(ctx, x + 4 * u, y + 14 * u, x + 4 * u, y + 18 * u, s, color);
|
||||
du_wf_line(ctx, x + 20 * u, y + 14 * u, x + 20 * u, y + 18 * u, s, color);
|
||||
du_fill_rect(ctx, x + 3 * u, y + 19 * u, 18 * u, s, color);
|
||||
du_fill_rounded_rect(ctx, x + 10 * u, y + 21 * u, 4 * u, 3 * u, color, (du_u32)u);
|
||||
break;
|
||||
case WF_ICON_CLOSE:
|
||||
du_wf_line(ctx, x + 6 * u, y + 6 * u, x + 18 * u, y + 18 * u, s, color);
|
||||
du_wf_line(ctx, x + 18 * u, y + 6 * u, x + 6 * u, y + 18 * u, s, color);
|
||||
break;
|
||||
case WF_ICON_MIN:
|
||||
du_fill_rect(ctx, x + 6 * u, y + 11 * u, 12 * u, s, color);
|
||||
break;
|
||||
case WF_ICON_MAX:
|
||||
du_rect_outline(ctx, x + 5 * u, y + 5 * u, 14 * u, 14 * u, color, (du_u32)u);
|
||||
break;
|
||||
case WF_ICON_RESTORE:
|
||||
du_rect_outline(ctx, x + 4 * u, y + 8 * u, 11 * u, 11 * u, color, (du_u32)u);
|
||||
du_fill_rect(ctx, x + 8 * u, y + 5 * u, 12 * u, s, color);
|
||||
du_fill_rect(ctx, x + 18 * u, y + 5 * u, s, 6 * u, color);
|
||||
du_fill_rect(ctx, x + 12 * u, y + 8 * u, 8 * u, u, color);
|
||||
break;
|
||||
case WF_ICON_USER:
|
||||
du_wf_ring(ctx, x + 12 * u, y + 8 * u, 4 * u, s, 0, color);
|
||||
du_wf_ring(ctx, x + 12 * u, y + 26 * u, 9 * u, s, 1, color);
|
||||
break;
|
||||
default:
|
||||
du_rect_outline(ctx, x + 4 * u, y + 4 * u, 16 * u, 16 * u, color, (du_u32)u);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DESHAB_FLUENT_UI_H */
|
||||
@@ -45,4 +45,17 @@ void idt_register_apic_eoi(void (*eoi_fn)(void));
|
||||
int irq_vector_alloc(void);
|
||||
void irq_vector_free(int vector);
|
||||
|
||||
/* 显式 EOI(Phase7: 调度器 tick 等可能切换任务的中断路径用)。
|
||||
* 在任何可能换栈的工作之前完成 EOI,防止 EOI 悬挂一个时间片。
|
||||
* 序列与 idt_handler 默认路径一致: LAPIC 钩子 → 8259 EOI(按向量范围)。
|
||||
* 参数兼容双命名空间(同 irq_register): 0-15=ISA IRQ, 0x20+=向量。 */
|
||||
void idt_irq_eoi(u8 vector);
|
||||
|
||||
/* CPU 异常钩子(Phase8: DRR 任务级 fault 接管)。
|
||||
* 在 idt_handler 的 vector<32 分支最前调用: 返回非 0 = 异常已被消费
|
||||
* (fault 任务被杀/切换,控制权不回到日志+停机路径);返回 0 = 走原
|
||||
* 全量日志 + cli;hlt 路径(DSK 阶段行为不变)。传 NULL 注销。 */
|
||||
typedef int (*idt_exception_hook_t)(u64 vector, u64 error_code, u64 rip);
|
||||
void idt_set_exception_hook(idt_exception_hook_t hook);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef UTSM_LAPIC_TIMER_H
|
||||
#define UTSM_LAPIC_TIMER_H
|
||||
|
||||
#include <utsm/types.h>
|
||||
|
||||
/* 宿主自持 LAPIC 定时器 —— SAS-R0-PCQ 调度器 tick 源(ROADMAP Phase 2 目标方案)。
|
||||
*
|
||||
* 动机:默认 FUCK 配置 apic_route=1 时,apic.drv 验证完 tick 链路后会把
|
||||
* GSI2(PIT IRQ0 线)重新 mask(apic.c route_switch 收尾),PIT 周期中断
|
||||
* 在该配置下不可达。LAPIC timer 不经 IOAPIC/PIC 路由,与路由模式解耦。
|
||||
*
|
||||
* 实现要点:
|
||||
* - IA32_APIC_BASE MSR (0x1B) 取 LAPIC 物理基址,经 paging map_mmio 映射
|
||||
* (SAS-R0:直接扩当前 CR3,全 CPU 可见)。
|
||||
* - x2APIC(MSR bit10)不支持 → 返回负数,调度器降级为协作模式。
|
||||
* - 频率校准:LAPIC 定时器 divide=16、initial=0xFFFFFFFF,用 PIT ch0
|
||||
* 单发 10ms 窗口采样 CCR 差值(pit.h 单发助手)。
|
||||
* - 向量来自 irq_vector_alloc(0x40-0xDF 动态池);EOI 由本模块直写
|
||||
* LAPIC EOI 寄存器(不依赖 apic.drv 钩子,PIC/IOAPIC 两模式均成立)。
|
||||
*/
|
||||
|
||||
/* 校准并配置周期定时器(LVT 保持 mask,尚未投递)。
|
||||
* 返回 0 成功,负数失败(x2APIC/映射失败/校准异常)。 */
|
||||
int lapic_timer_init(u32 freq_hz);
|
||||
|
||||
/* init 成功后返回分配到的 IDT 向量(0x40-0xDF),未初始化返回 -1 */
|
||||
int lapic_timer_vector(void);
|
||||
|
||||
/* LVT 解除 mask —— 开始周期投递(须在 irq_register 向量 handler 之后调用) */
|
||||
void lapic_timer_start(void);
|
||||
|
||||
/* 停止:LVT 置 mask + initial count 清零 + 归还动态向量 */
|
||||
void lapic_timer_stop(void);
|
||||
|
||||
/* 直写 LAPIC EOI 寄存器(tick handler 用;未初始化时为空操作) */
|
||||
void lapic_timer_eoi(void);
|
||||
|
||||
#endif /* UTSM_LAPIC_TIMER_H */
|
||||
@@ -156,6 +156,11 @@ typedef struct linux_compat_service {
|
||||
* (-1=服务不可用, -2=IPC 发送失败, -3=linux_resume 失败,
|
||||
* -4=无响应, -5=daemon 报告 spawn 失败)。 */
|
||||
int (*exec_async)(const char *path, int argc, const char *const *argv);
|
||||
|
||||
/* 不发送 IPC,只跑一段 Linux vCPU(HLT 或 preemption timeslice)。
|
||||
* KDE/Plasma 全屏循环用这个唤醒 async 子进程,避免再 exec sleep。
|
||||
* 返回 0 成功,负值同 linux_resume。 */
|
||||
int (*run_slice)(void);
|
||||
} linux_compat_service;
|
||||
|
||||
/* ===== UTSM 内部接口(不进服务表,供 hypercall.c 等内核代码使用) =====
|
||||
|
||||
@@ -49,6 +49,9 @@ struct linux_setup_header {
|
||||
/* boot_params is 4096 bytes. The setup_header is at offset 0x1f1. */
|
||||
#define BOOT_PARAMS_SIZE 4096
|
||||
#define SETUP_HEADER_OFFSET 0x1f1
|
||||
#define BOOT_PARAMS_ACPI_RSDP_ADDR_OFF 0x070
|
||||
#define BOOT_PARAMS_RSDP_COPY_OFF 0x800
|
||||
#define BOOT_PARAMS_RSDP_COPY_SIZE 36
|
||||
|
||||
/* Key field offsets within bzImage / boot_params */
|
||||
#define BZ_BOOT_FLAG_OFF 0x1fe
|
||||
@@ -88,11 +91,10 @@ struct linux_setup_header {
|
||||
#define E820_TYPE_UNUSABLE 5
|
||||
#define E820_TYPE_PMEM 7
|
||||
|
||||
/* e820_table entry in boot_params at offset 0x2e0 (actually 0x2d0 in older,
|
||||
* 0x2e0 in newer). We use 0x2e0 and the e820_entries count at 0x1e8.
|
||||
* Each entry is 20 bytes: u64 addr, u64 size, u32 type. */
|
||||
/* e820_table is at 0x2d0 in Linux 6.6 boot_params (arch/x86/include/uapi/asm/bootparam.h).
|
||||
* e820_entries count is at 0x1e8. Each entry is 20 bytes: u64 addr, u64 size, u32 type. */
|
||||
#define E820_ENTRIES_OFFSET 0x1e8
|
||||
#define E820_TABLE_OFFSET 0x2e0
|
||||
#define E820_TABLE_OFFSET 0x2d0
|
||||
#define E820_MAX_ENTRIES 128
|
||||
#define E820_ENTRY_SIZE 20
|
||||
|
||||
@@ -215,10 +217,13 @@ void *linux_find_extra_rootfs_module(u64 *size_out);
|
||||
* Returns NULL when the module is absent (install skipped, non-fatal). */
|
||||
void *linux_find_vscode_module(u64 *size_out);
|
||||
|
||||
/* Parse bzImage header and extract key parameters.
|
||||
/* Parse bzImage header and return the protected-mode image's file offset,
|
||||
* load length, decompression allocation size, and startup_64 entry offset.
|
||||
* The protected-mode image starts after setup sectors; setup_header's
|
||||
* payload_offset instead locates compressed data inside that image.
|
||||
* Returns 0 on success, negative on error. */
|
||||
int linux_parse_bzimage(const void *bzimage, u64 size,
|
||||
u64 *payload_offset_out, u64 *payload_length_out,
|
||||
u64 *kernel_offset_out, u64 *kernel_length_out,
|
||||
u64 *init_size_out, u64 *entry_offset_out);
|
||||
|
||||
/* Initialize the Linux guest: parse bzImage, allocate guest memory,
|
||||
@@ -249,9 +254,9 @@ void *linux_get_surface_vaddr(void);
|
||||
int linux_launch(void);
|
||||
|
||||
/* Default Linux command line (can be overridden).
|
||||
* nohlt: prevent kernel idle loop from using HLT — only the exec daemon's
|
||||
* explicit ioctl(PARK) HLT should trigger VM-Exit park, so that
|
||||
* linux_launch() returns only after the daemon is ready.
|
||||
* Daemon PARK is a VMCALL. Guest idle may HLT; that stays in the
|
||||
* guest (wait-for-IRQ). Do not use nohlt/idle=poll — poll idle
|
||||
* NULL-derefs current after the first real sleep.
|
||||
* noapic/nolapic/nosmp: UTSM VMM 只模拟 legacy PIC(8259) + PIT(8254),
|
||||
* 不提供 LAPIC/IOAPIC;guest 走 XT-PIC 模式,IRQ vector = 0x30+irq。
|
||||
* virtio_mmio.device=: 向 guest 声明 virtio-mmio 设备(blk@0xF4000000 IRQ5,
|
||||
@@ -259,12 +264,15 @@ int linux_launch(void);
|
||||
* VSCode Phase 2: kbd@0xF4003000 IRQ8, mouse@0xF4004000 IRQ9 (virtio-input)。
|
||||
* VSCode Phase 3: gpu@0xF4005000 IRQ10 (virtio-gpu 2D, /dev/dri/card0)。
|
||||
* VSCode Phase 4: xrootfs@0xF4006000 IRQ11 (可写 virtio-blk, /dev/vdc)。
|
||||
* 注:slot6 无对应 boot module 时后端不注册,guest 探测会超时跳过,
|
||||
* 不影响启动(virtio_mmio 对无响应设备只打一条 warn)。 */
|
||||
* 注:无 extra-rootfs boot module 时,后端改映射 ESP 上的
|
||||
* boot/linux-extra-rootfs.img(AHCI+FAT32),避免 Limine 把 4GiB
|
||||
* 打进 RAM。文件也没有则不注册,guest 探测超时跳过。 */
|
||||
#define LINUX_DEFAULT_CMDLINE \
|
||||
"console=ttyS0,115200 earlyprintk=serial nokaslr " \
|
||||
"no_timer_check loglevel=7 nohlt idle=poll " \
|
||||
"noapic nolapic nosmp " \
|
||||
"earlyprintk=serial,ttyS0,115200 console=ttyS0,115200 " \
|
||||
"nokaslr debug loglevel=8 noinvpcid nopcid nopti pti=off nogbpages " \
|
||||
"tsc_early_khz=2000000 lpj=4000000 i8042.nokbd i8042.noaux " \
|
||||
"no_timer_check " \
|
||||
"noapic nolapic nosmp ibt=off user_shstk=off " \
|
||||
"virtio_mmio.device=4K@0xF4000000:5 " \
|
||||
"virtio_mmio.device=4K@0xF4001000:6 " \
|
||||
"virtio_mmio.device=4K@0xF4002000:7 " \
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef UTSM_LINUX_XSAVE_H
|
||||
#define UTSM_LINUX_XSAVE_H
|
||||
|
||||
#include <utsm/types.h>
|
||||
|
||||
/* L2 Linux XSAVE (x87+SSE first). UTSM is built -mno-sse, so every
|
||||
* XSAVE/XRSTOR/XSETBV goes through raw opcodes. Guest state must be
|
||||
* saved before returning to DSK/desktop and restored on linux_resume. */
|
||||
|
||||
int linux_xsave_available(void);
|
||||
void linux_xsave_init(void);
|
||||
void linux_xsave_save_guest(void);
|
||||
void linux_xsave_load_guest(void);
|
||||
void linux_xsave_save_host(void);
|
||||
void linux_xsave_load_host(void);
|
||||
void linux_xsave_set_guest_xcr0(u64 xcr0);
|
||||
void linux_xsave_adjust_cpuid(u32 leaf, u32 subleaf,
|
||||
u32 *eax, u32 *ebx, u32 *ecx, u32 *edx,
|
||||
u64 guest_cr4);
|
||||
|
||||
#endif
|
||||
@@ -26,4 +26,7 @@ typedef struct {
|
||||
void utsm_pckc_init(void);
|
||||
int utsm_pckc_get_or_derive(u32 segment_slot, struct utsm_segment_desc *desc, utsm_key_material *out_key);
|
||||
|
||||
/* Phase 9: 失效某段全部缓存 key(key_epoch bump / task_kill crypto erase 用) */
|
||||
void utsm_pckc_invalidate_slot(u32 segment_slot);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef UTSM_PIT_H
|
||||
#define UTSM_PIT_H
|
||||
|
||||
#include <utsm/types.h>
|
||||
|
||||
/* PIT ch0 单发定时(LAPIC timer 校准用,见 arch/x86_64/lapic_timer.c)。
|
||||
* 模式 0(terminal count),单发不产生周期中断,不注册 IRQ handler。
|
||||
* 注意:不用 mode 3 —— B7 定论 PIT mode3 经 IOAPIC 边沿路由会双触发。 */
|
||||
|
||||
/* 编程 ch0 单发 ms 毫秒(>54ms 截断到 54ms) */
|
||||
void pit_oneshot_ms(u32 ms);
|
||||
|
||||
/* latch 并返回 ch0 当前递减计数(16 位) */
|
||||
u16 pit_latch_count(void);
|
||||
|
||||
/* 单发是否到期(两次 latch 回绕检测)。1=到期,0=未到期 */
|
||||
int pit_oneshot_expired(void);
|
||||
|
||||
/* 静默:ch0 编程 mode0 计数 0,不再产生任何输出/中断 */
|
||||
void pit_quiet(void);
|
||||
|
||||
#endif /* UTSM_PIT_H */
|
||||
@@ -0,0 +1,84 @@
|
||||
#ifndef UTSM_SCHED_EXT_H
|
||||
#define UTSM_SCHED_EXT_H
|
||||
|
||||
#include <utsm/types.h>
|
||||
#include <utsm/sched.h>
|
||||
|
||||
/*
|
||||
* SAS-R0-PCQ 调度器扩展接口(ROADMAP Phase 7)。
|
||||
*
|
||||
* 冻结 ABI(sched.h)之外的内核本体能力层,仅供 UTSM 内核与 selftest
|
||||
* 使用,不跨组件边界(DKM 驱动经 kernel_api.sched 使用精简服务表)。
|
||||
*
|
||||
* 切换模型(xv6 式栈驱动):
|
||||
* - 新任务初始栈帧由 utsm_task_create 伪造(7 个 u64):
|
||||
* sp[0..3]=r15/r14/r13/r12(0), sp[4]=rbx(task slot), sp[5]=rbp(0),
|
||||
* sp[6]=&utsm_task_trampoline —— switch 的 ret 直接落 trampoline。
|
||||
* - 抢占:IRQ 帧落在被抢占任务自己的栈上,切换只换 rsp(arch.rsp);
|
||||
* 恢复时沿原栈 iretq。TCB arch.rip/rflags 仅占位零(resume 全由 rsp 驱动)。
|
||||
* - 协作:schedule() 入口 pushfq 保存本任务 rflags → cli;恢复点 popfq。
|
||||
*/
|
||||
|
||||
/* 应用 FUCK [sched] 配置(enable 前生效;tick_hz=0 用默认 100) */
|
||||
void utsm_sched_config(u32 tick_hz, u32 timeslice_ms, u32 demo_ms, int demo_fault);
|
||||
|
||||
/* bootstrap 任务绑定:sched_init + cpu_init(0) + 当前 rsp 注册为 RUNNING
|
||||
* 任务(priority 最低,K_KERNEL|NO_MIGRATE)。不开中断、不碰定时器。
|
||||
* 返回 bootstrap slot(>=0),负数失败。 */
|
||||
int utsm_sched_bootstrap_init(void);
|
||||
|
||||
/* 创建任务:4 页任务栈(arena kmem_alloc_page)+ 伪造初始栈帧 + 入队。
|
||||
* process_slot = 0xFFFFFFFF 表示无进程关联(纯内核任务,crypto_context=NULL)。
|
||||
* 返回 task slot(>=0),负数失败。仅在未启用抢占时(bootstrap 上下文)调用。 */
|
||||
int utsm_task_create(u32 process_slot, u32 priority, void (*entry)(void *), void *arg);
|
||||
|
||||
/* 启用抢占:LAPIC timer 校准配置 → 注册 tick handler → 异常钩子 →
|
||||
* DRR fault 回调接线 → LVT 解除 mask。tick_hz=0 用配置默认。
|
||||
* 返回 0 成功;失败时调度器保持协作模式(系统继续正常启动)。 */
|
||||
int utsm_sched_enable(u32 tick_hz);
|
||||
|
||||
/* 静默:cli → 停 LAPIC timer → 异常钩子注销 → DRR 回调解绑 → 杀掉全部
|
||||
* 非 bootstrap 任务 → sti。dsk_load_and_jump 之前调用,保证 DSK 交接
|
||||
* 路径与无调度器时逐字节一致。 */
|
||||
void utsm_sched_quiesce(void);
|
||||
|
||||
/* demo 窗口:创建 3 个不同优先级 demo 任务(prio 1/20/40)→ enable →
|
||||
* bootstrap 忙等 demo_ms 毫秒(被周期抢占,demo 任务交错运行 = 抢占证据)。
|
||||
* FUCK [sched] demo_ms=0 时为空操作。 */
|
||||
void utsm_sched_demo_window(void);
|
||||
|
||||
/* 协作让出(当前任务重新入队并切换) */
|
||||
void utsm_sched_yield(void);
|
||||
|
||||
/* 睡眠 ms 毫秒(wake_deadline 到期后由 tick 唤醒) */
|
||||
void utsm_sched_sleep_ms(u32 ms);
|
||||
|
||||
/* 任务退出(trampoline 在 entry 返回后自动调用;不返回) */
|
||||
void utsm_sched_task_exit(void) __attribute__((noreturn));
|
||||
|
||||
/* DRR fault 回调:杀掉指定任务(crypto erase + FAULTED→ZOMBIE)。
|
||||
* 若 fault 任务是当前任务(tick/异常上下文)则立即切换走且不返回。 */
|
||||
void utsm_sched_fault_task(u32 task_slot);
|
||||
|
||||
/* task_kill(ROADMAP Phase7 验收项):crypto erase(key_epoch++)+
|
||||
* 摘链 + ZOMBIE。对 RUNNING(当前)任务返回 ERR_STATE。 */
|
||||
int utsm_sched_task_kill(u32 task_slot);
|
||||
|
||||
/* 当前运行任务 slot */
|
||||
u32 utsm_sched_current_slot(void);
|
||||
|
||||
/* ---- switch.S 汇编符号 ----
|
||||
* utsm_sched_switch: 保存 prev 的 callee-saved + arch.rsp,载入 next->arch.rsp
|
||||
* 恢复并 ret。调用后 volatile 视为全部破坏(C 调用约定保证)。 */
|
||||
void utsm_sched_switch(utsm_sched_tcb *prev, utsm_sched_tcb *next);
|
||||
void utsm_task_trampoline(void);
|
||||
|
||||
/* trampoline 的 C 入口(rbx 传入 task slot) */
|
||||
void utsm_task_main(u64 slot);
|
||||
|
||||
/* ---- selftest 钩子(内部状态观察,仅 test/ 使用) ---- */
|
||||
int utsm_sched_selftest_runqueue(void);
|
||||
int utsm_sched_selftest_blockwake(void);
|
||||
int utsm_sched_debug_ready_count(u32 cpu_id);
|
||||
|
||||
#endif /* UTSM_SCHED_EXT_H */
|
||||
@@ -40,6 +40,14 @@
|
||||
#define VIRTIO_MMIO_QUEUE_DRIVER_HIGH 0x094 /* W modern */
|
||||
#define VIRTIO_MMIO_QUEUE_DEVICE_LOW 0x0A0 /* W modern */
|
||||
#define VIRTIO_MMIO_QUEUE_DEVICE_HIGH 0x0A4 /* W modern */
|
||||
/* Shared-memory region (Virtio 1.1 §4.2.2). Linux virtio-gpu always probes
|
||||
* VIRTIO_GPU_SHM_ID_HOST_VISIBLE. A missing region MUST report length=-1;
|
||||
* length 0 is treated as a real window at address 0 and probe fails -EBUSY. */
|
||||
#define VIRTIO_MMIO_SHM_SEL 0x0AC /* W */
|
||||
#define VIRTIO_MMIO_SHM_LEN_LOW 0x0B0 /* R */
|
||||
#define VIRTIO_MMIO_SHM_LEN_HIGH 0x0B4 /* R */
|
||||
#define VIRTIO_MMIO_SHM_BASE_LOW 0x0B8 /* R */
|
||||
#define VIRTIO_MMIO_SHM_BASE_HIGH 0x0BC /* R */
|
||||
#define VIRTIO_MMIO_CONFIG_GENERATION 0x0FC /* R modern */
|
||||
#define VIRTIO_MMIO_CONFIG 0x100 /* RW device-specific config */
|
||||
|
||||
|
||||
@@ -91,4 +91,7 @@ u64 vmm_get_eptp(void);
|
||||
/* P8.5: VMCS 物理地址(linux_launch 前 VMCLEAR+VMPTRLD 用) */
|
||||
u64 vmm_get_vmcs_phys(void);
|
||||
|
||||
/* Walk the current guest CR3 to translate GVA→GPA. Returns 0 if unmapped. */
|
||||
u64 vmx_guest_gva_to_gpa(u64 gva);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
#define IA32_VMX_TRUE_PROCBASED_CTLS 0x48E
|
||||
#define IA32_VMX_TRUE_EXIT_CTLS 0x48F
|
||||
#define IA32_VMX_TRUE_ENTRY_CTLS 0x490
|
||||
#define IA32_VMX_CR0_FIXED0 0x486
|
||||
#define IA32_VMX_CR0_FIXED1 0x487
|
||||
#define IA32_VMX_CR4_FIXED0 0x488
|
||||
#define IA32_VMX_CR4_FIXED1 0x489
|
||||
|
||||
/* ===== CR4 / CR0 bits ===== */
|
||||
#define CR4_VMXE_BIT 13ULL
|
||||
@@ -23,8 +27,15 @@
|
||||
#define CR4_PAE (1ULL << 5)
|
||||
#define CR4_PGE (1ULL << 7)
|
||||
#define CR4_PSE (1ULL << 4)
|
||||
#define CR4_OSFXSR (1ULL << 9)
|
||||
#define CR4_OSXMMEXCPT (1ULL << 10)
|
||||
#define CR4_FSGSBASE (1ULL << 16)
|
||||
#define CR4_OSXSAVE (1ULL << 18)
|
||||
#define CR4_CET (1ULL << 23)
|
||||
|
||||
#define CR0_PE (1ULL << 0)
|
||||
#define CR0_MP (1ULL << 1)
|
||||
#define CR0_ET (1ULL << 4)
|
||||
#define CR0_NE (1ULL << 5)
|
||||
#define CR0_WP (1ULL << 16)
|
||||
#define CR0_PG (1ULL << 31)
|
||||
@@ -44,8 +55,14 @@
|
||||
#define VMCS_IO_BITMAP_A 0x2000
|
||||
#define VMCS_IO_BITMAP_B 0x2002
|
||||
#define VMCS_MSR_BITMAP 0x2004
|
||||
#define VMCS_VM_EXIT_MSR_STORE_ADDR 0x2006
|
||||
#define VMCS_VM_EXIT_MSR_LOAD_ADDR 0x2008
|
||||
#define VMCS_VM_ENTRY_MSR_LOAD_ADDR 0x200A
|
||||
#define VMCS_TSC_OFFSET 0x2010
|
||||
#define VMCS_EPT_POINTER 0x201A
|
||||
#define VMCS_VM_EXIT_MSR_STORE_COUNT 0x400E
|
||||
#define VMCS_VM_EXIT_MSR_LOAD_COUNT 0x4010
|
||||
#define VMCS_VM_ENTRY_MSR_LOAD_COUNT 0x4014
|
||||
|
||||
/* Read-only data fields */
|
||||
#define VMCS_GUEST_PHYSICAL_ADDR 0x2400
|
||||
@@ -164,6 +181,10 @@
|
||||
#define VMCS_PIN_BASED_VM_EXEC_CONTROL 0x4000
|
||||
#define VMCS_CPU_BASED_VM_EXEC_CONTROL 0x4002
|
||||
#define VMCS_EXCEPTION_BITMAP 0x4004
|
||||
#define VMCS_CR0_GUEST_HOST_MASK 0x6000
|
||||
#define VMCS_CR4_GUEST_HOST_MASK 0x6002
|
||||
#define VMCS_CR0_READ_SHADOW 0x6004
|
||||
#define VMCS_CR4_READ_SHADOW 0x6006
|
||||
#define VMCS_VM_EXIT_CONTROLS 0x400C
|
||||
#define VMCS_VM_ENTRY_CONTROLS 0x4012
|
||||
#define VMCS_VM_ENTRY_INTERRUPT_INFO 0x4016
|
||||
@@ -183,6 +204,8 @@
|
||||
#define CPU_BASED_MWAIT_EXITING (1ULL << 10)
|
||||
#define CPU_BASED_RDPMC_EXITING (1ULL << 11)
|
||||
#define CPU_BASED_RDTSC_EXITING (1ULL << 12)
|
||||
#define CPU_BASED_CR3_LOAD_EXITING (1ULL << 15)
|
||||
#define CPU_BASED_CR3_STORE_EXITING (1ULL << 16)
|
||||
#define CPU_BASED_CR8_LOAD_EXITING (1ULL << 19)
|
||||
#define CPU_BASED_CR8_STORE_EXITING (1ULL << 20)
|
||||
#define CPU_BASED_MOV_DR_EXITING (1ULL << 23)
|
||||
@@ -194,6 +217,7 @@
|
||||
|
||||
/* ===== Secondary processor-based controls ===== */
|
||||
#define SEC_EXEC_ENABLE_EPT (1ULL << 1)
|
||||
#define SEC_EXEC_ENABLE_RDTSCP (1ULL << 3)
|
||||
#define SEC_EXEC_ENABLE_VPID (1ULL << 5)
|
||||
#define SEC_EXEC_UNRESTRICTED_GUEST (1ULL << 7)
|
||||
|
||||
@@ -204,11 +228,21 @@
|
||||
#define VM_EXIT_ACK_INTR_ON_EXIT (1ULL << 15)
|
||||
#define VM_EXIT_SAVE_GUEST_EFER (1ULL << 20)
|
||||
#define VM_EXIT_LOAD_HOST_EFER (1ULL << 21)
|
||||
#define VM_EXIT_SAVE_CET_STATE (1ULL << 28)
|
||||
#define VM_EXIT_LOAD_CET_STATE (1ULL << 29)
|
||||
|
||||
/* ===== VM-entry controls ===== */
|
||||
#define VM_ENTRY_LOAD_DEBUG_CONTROLS (1ULL << 2)
|
||||
#define VM_ENTRY_IA32E_MODE_GUEST (1ULL << 9)
|
||||
#define VM_ENTRY_LOAD_GUEST_EFER (1ULL << 15)
|
||||
#define VM_ENTRY_LOAD_CET_STATE (1ULL << 20)
|
||||
|
||||
#define VMCS_GUEST_S_CET 0x2828
|
||||
#define VMCS_GUEST_SSP 0x282A
|
||||
#define VMCS_GUEST_INTR_SSP_TABLE 0x282C
|
||||
#define VMCS_HOST_S_CET 0x2C28
|
||||
#define VMCS_HOST_SSP 0x2C2A
|
||||
#define VMCS_HOST_INTR_SSP_TABLE 0x2C2C
|
||||
|
||||
/* ===== Exit reasons ===== */
|
||||
#define EXIT_EXCEPTION_NMI 0
|
||||
@@ -220,6 +254,8 @@
|
||||
#define EXIT_INVD 13
|
||||
#define EXIT_RDMSR 31
|
||||
#define EXIT_WRMSR 32
|
||||
#define EXIT_ENTRY_FAIL_GUEST_STATE 33
|
||||
#define EXIT_ENTRY_FAIL_MSR_LOADING 34
|
||||
#define EXIT_MONITOR 39
|
||||
#define EXIT_MWAIT 36
|
||||
#define EXIT_VMCALL 18
|
||||
@@ -240,6 +276,8 @@
|
||||
#define EXIT_INVLPG 14
|
||||
#define EXIT_EPT_VIOLATION 48
|
||||
#define EXIT_EPT_MISCONFIG 49
|
||||
#define EXIT_WBINVD 54
|
||||
#define EXIT_XSETBV 55
|
||||
#define EXIT_VMX_PREEMPTION_TIMER 52
|
||||
#define EXIT_APIC_ACCESS 44
|
||||
|
||||
@@ -259,6 +297,7 @@
|
||||
#define EPT_WRITE (1ULL << 1)
|
||||
#define EPT_EXECUTE (1ULL << 2)
|
||||
#define EPT_RWX (EPT_READ | EPT_WRITE | EPT_EXECUTE)
|
||||
#define EPT_IGNORE_PAT (1ULL << 6)
|
||||
#define EPT_LARGE_PAGE (1ULL << 7)
|
||||
|
||||
/* ===== VMX instruction errors ===== */
|
||||
@@ -281,6 +320,7 @@ int vmx_vmlaunch(void);
|
||||
int vmx_vmresume(void);
|
||||
|
||||
u64 vmx_read_msr(u32 msr);
|
||||
void vmx_write_msr(u32 msr, u64 value);
|
||||
/* Capability polarity used by KVM and verified under nested KVM:
|
||||
* low bit=1 => must be 1; high bit=0 => must be 0.
|
||||
* Formula: (desired | allowed0) & allowed1. */
|
||||
@@ -291,6 +331,13 @@ u64 vmx_get_host_cr3(void);
|
||||
* distinct from the HHDM and must never be translated by subtracting HHDM. */
|
||||
u64 vmx_kernel_virt_to_phys(const void *address);
|
||||
|
||||
/* Nested KVM leaks host CET into L2 unless VMCS switches CET state. */
|
||||
extern int g_linux_cet_vmcs;
|
||||
extern int g_linux_cet_force;
|
||||
void linux_cet_vmcs_sync_host(void);
|
||||
void linux_cet_restore_host(void);
|
||||
void linux_cet_force_guest_off(void);
|
||||
|
||||
/* ===== 虚拟中断注入(vmexit.c 实现) ===== */
|
||||
/* 向 guest 队列注入一个 ISA IRQ 向量(legacy PIC:vector = 0x30 + irq)。
|
||||
* 仅排队;实际在下一次 vmresume 前(guest RFLAGS.IF=1 且无阻塞时)注入,
|
||||
@@ -302,5 +349,11 @@ void vmx_guest_queue_irq(u32 vector);
|
||||
u64 vmx_preemption_quantum(void);
|
||||
/* 检查 CPU 是否支持 VMX preemption timer。 */
|
||||
int vmx_preemption_timer_supported(void);
|
||||
/* linux_resume() 入口清零 timeslice 计数,避免上次 HLT 残留导致立刻归还。 */
|
||||
void vmx_linux_timeslice_reset(void);
|
||||
/* linux_resume() 返回后关闭 timeslice,避免 linux_launch 早期误归还。 */
|
||||
void vmx_linux_timeslice_disarm(void);
|
||||
/* linux_resume() vmresume 前:arm timer + 注入 pending virtio/PIT IRQ。 */
|
||||
void vmx_linux_prepare_entry(void);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user