feat: exhaustive STUB instrumentation - 241 panic sites across VMM/kernel + whitelist alignment

- VMM cluster: XJ3-E/LIN-E/VMM-E/VMX-E/EPT-E/IPC-E/VVB-E (124 sites)

- kernel cluster: TST-E/MM-E/UTRW-E/LAPIC-E/IDT-E/SAS-E/PRB-E/NETST-E/DKM-E (117 sites)

- whitelist fixes: vmm_init env probes E10-E14 fallback, disk_log read-only block path, DSL-E05 non-FAT32 device 0 probe

- QEMU smoke: wizard -> USER.CONF -> login -> desktop ready, zero spurious panic
This commit is contained in:
Linehu
2026-10-03 21:26:04 +08:00
parent 506d1b18c6
commit 174af71b39
62 changed files with 667 additions and 36 deletions
+2
View File
@@ -560,6 +560,8 @@ int irq_vector_alloc(void) {
return vec; return vec;
} }
log_warn("[IDT] vector alloc failed: pool exhausted"); log_warn("[IDT] vector alloc failed: pool exhausted");
panic_full("IDT-E01 VECTOR POOL EXHAUSTED",
"irq_vector_alloc: dynamic vector pool exhausted", 0);
return -1; return -1;
} }
Binary file not shown.
+10
View File
@@ -16,6 +16,7 @@
#include <utsm/idt.h> #include <utsm/idt.h>
#include <utsm/dkm.h> #include <utsm/dkm.h>
#include <utsm/log.h> #include <utsm/log.h>
#include <utsm/panic.h>
extern void outb(u16 port, u8 value); extern void outb(u16 port, u8 value);
extern u8 inb(u16 port); extern u8 inb(u16 port);
@@ -63,6 +64,7 @@ int lapic_timer_init(u32 freq_hz) {
base = rdmsr_(MSR_IA32_APIC_BASE); base = rdmsr_(MSR_IA32_APIC_BASE);
} }
if (base & APIC_BASE_X2APIC) { if (base & APIC_BASE_X2APIC) {
/* 【插桩白名单】设计内降级:x2APIC 不支持 MMIO timer,降级协作模式 */
log_warn("[LAPIC] x2APIC mode, MMIO timer unsupported"); log_warn("[LAPIC] x2APIC mode, MMIO timer unsupported");
return -1; return -1;
} }
@@ -73,6 +75,8 @@ int lapic_timer_init(u32 freq_hz) {
if (!mm || !mm->map_mmio) return -2; if (!mm || !mm->map_mmio) return -2;
if (mm->map_mmio(phys, 0x1000) != 0) { if (mm->map_mmio(phys, 0x1000) != 0) {
log_warn("[LAPIC] map_mmio failed"); log_warn("[LAPIC] map_mmio failed");
panic_full("LAPIC-E01 MAP_MMIO FAILED",
"lapic_timer_init: LAPIC MMIO mapping failed", 0);
return -3; return -3;
} }
u64 hhdm = 0; u64 hhdm = 0;
@@ -82,6 +86,8 @@ int lapic_timer_init(u32 freq_hz) {
if (mm->is_mapped && !mm->is_mapped((u64)g_lapic)) { if (mm->is_mapped && !mm->is_mapped((u64)g_lapic)) {
g_lapic = 0; g_lapic = 0;
log_warn("[LAPIC] mapped page not reachable"); log_warn("[LAPIC] mapped page not reachable");
panic_full("LAPIC-E02 MAPPED PAGE NOT REACHABLE",
"lapic_timer_init: mapped LAPIC page not reachable", 0);
return -4; return -4;
} }
@@ -121,6 +127,8 @@ int lapic_timer_init(u32 freq_hz) {
u64 delta = (u64)ccr0 - (u64)ccr1; /* 16 分频时钟 10ms tick 数 */ u64 delta = (u64)ccr0 - (u64)ccr1; /* 16 分频时钟 10ms tick 数 */
if (delta < 1000) { if (delta < 1000) {
log_warn("[LAPIC] timer calibration implausible"); log_warn("[LAPIC] timer calibration implausible");
panic_full("LAPIC-E03 CALIBRATION IMPLAUSIBLE",
"lapic_timer_init: PIT-vs-LAPIC calibration implausible", 0);
lapic_timer_stop(); lapic_timer_stop();
return -5; return -5;
} }
@@ -134,6 +142,8 @@ int lapic_timer_init(u32 freq_hz) {
int vec = irq_vector_alloc(); int vec = irq_vector_alloc();
if (vec < 0) { if (vec < 0) {
log_warn("[LAPIC] irq_vector_alloc failed"); log_warn("[LAPIC] irq_vector_alloc failed");
panic_full("LAPIC-E04 IRQ VECTOR ALLOC FAILED",
"lapic_timer_init: dynamic vector allocation failed", 0);
return -6; return -6;
} }
g_timer_vector = vec; g_timer_vector = vec;
+16
View File
@@ -0,0 +1,16 @@
arch/x86_64/lapic_timer.o: arch\x86_64\lapic_timer.c \
include\utsm\lapic_timer.h include\utsm\types.h include\utsm\pit.h \
include\utsm\paging.h include\utsm\idt.h include\utsm\dkm.h \
include\utsm\dma.h include\utsm\block.h include\utsm\net.h \
include\utsm\log.h include\utsm\panic.h
include\utsm\lapic_timer.h:
include\utsm\types.h:
include\utsm\pit.h:
include\utsm\paging.h:
include\utsm\idt.h:
include\utsm\dkm.h:
include\utsm\dma.h:
include\utsm\block.h:
include\utsm\net.h:
include\utsm\log.h:
include\utsm\panic.h:
+30 -1
View File
@@ -1,7 +1,8 @@
#include <utsm/dkm.h> #include <utsm/dkm.h>
#include <utsm/log.h> #include <utsm/log.h>
#include <utsm/types.h> #include <utsm/types.h>
#include <utsm/arena.h> #include <utsm/arena.h>
#include <utsm/panic.h>
#include "../arch/x86_64/limine.h" #include "../arch/x86_64/limine.h"
#define ELF_MAGIC0 0x7f #define ELF_MAGIC0 0x7f
@@ -178,10 +179,14 @@ int dkm_scan_symbols(const void *address, u64 size, struct dkm_symbol_scan *out)
if (ehdr->shoff == 0 || ehdr->shnum == 0 || ehdr->shentsize < sizeof(elf64_shdr)) { if (ehdr->shoff == 0 || ehdr->shnum == 0 || ehdr->shentsize < sizeof(elf64_shdr)) {
log_error("[DKM] ELF has no section table"); log_error("[DKM] ELF has no section table");
panic_full("DKM-E30 ELF NO SECTION TABLE",
"dkm_scan_symbols: driver ELF has no section table", 0);
return -1; return -1;
} }
if (!range_ok(ehdr->shoff, (u64)ehdr->shnum * ehdr->shentsize, size)) { if (!range_ok(ehdr->shoff, (u64)ehdr->shnum * ehdr->shentsize, size)) {
log_error("[DKM] ELF section table out of range"); log_error("[DKM] ELF section table out of range");
panic_full("DKM-E31 ELF SECTION TABLE OUT OF RANGE",
"dkm_scan_symbols: section table out of file range", 0);
return -1; return -1;
} }
@@ -202,10 +207,14 @@ int dkm_scan_symbols(const void *address, u64 size, struct dkm_symbol_scan *out)
if (!symtab || !strtab || strtab->type != SHT_STRTAB) { if (!symtab || !strtab || strtab->type != SHT_STRTAB) {
log_error("[DKM] missing symtab/strtab"); log_error("[DKM] missing symtab/strtab");
panic_full("DKM-E32 ELF MISSING SYMTAB",
"dkm_scan_symbols: symtab/strtab missing or invalid", 0);
return -1; return -1;
} }
if (symtab->entsize < sizeof(elf64_sym) || !range_ok(symtab->offset, symtab->size, size) || !range_ok(strtab->offset, strtab->size, size)) { if (symtab->entsize < sizeof(elf64_sym) || !range_ok(symtab->offset, symtab->size, size) || !range_ok(strtab->offset, strtab->size, size)) {
log_error("[DKM] invalid symtab/strtab range"); log_error("[DKM] invalid symtab/strtab range");
panic_full("DKM-E33 ELF SYMTAB RANGE INVALID",
"dkm_scan_symbols: symtab/strtab out of file range", 0);
return -1; return -1;
} }
@@ -241,6 +250,8 @@ int dkm_scan_symbols(const void *address, u64 size, struct dkm_symbol_scan *out)
return 0; return 0;
} }
log_error("[DKM] required driver symbols missing"); log_error("[DKM] required driver symbols missing");
panic_full("DKM-E34 REQUIRED DRIVER SYMBOLS MISSING",
"dkm_scan_symbols: driver_desc/init/exit symbol missing", 0);
return -1; return -1;
} }
@@ -271,12 +282,16 @@ int dkm_load_elf_rel(const void *address, u64 size, const struct dkm_symbol_scan
if (total_size == 0) { if (total_size == 0) {
log_error("[DKM] no allocatable sections"); log_error("[DKM] no allocatable sections");
panic_full("DKM-E35 ELF NO ALLOC SECTIONS",
"dkm_load_elf_rel: no allocatable sections", 0);
return -1; return -1;
} }
u8 *image = (u8 *)kmem_alloc_aligned(total_size, max_align); u8 *image = (u8 *)kmem_alloc_aligned(total_size, max_align);
if (!image) { if (!image) {
log_error("[DKM] failed to allocate module memory"); log_error("[DKM] failed to allocate module memory");
panic_full("DKM-E36 MODULE MEM ALLOC FAILED",
"dkm_load_elf_rel: module memory allocation failed", 0);
return -1; return -1;
} }
memset(image, 0, total_size); memset(image, 0, total_size);
@@ -353,6 +368,8 @@ int dkm_load_elf_rel(const void *address, u64 size, const struct dkm_symbol_scan
} else { } else {
log_error("[DKM] unsupported relocation type"); log_error("[DKM] unsupported relocation type");
log_hex64("[DKM] reloc type=", (u64)reloc_type); log_hex64("[DKM] reloc type=", (u64)reloc_type);
panic_full("DKM-E37 UNSUPPORTED RELOCATION",
"dkm_load_elf_rel: unsupported relocation type", 0);
return -1; return -1;
} }
@@ -373,6 +390,8 @@ int dkm_load_elf_rel(const void *address, u64 size, const struct dkm_symbol_scan
const dkm_driver_desc *desc = (const dkm_driver_desc *)(image + image_offset[desc_sym->shndx] + desc_sym->value); const dkm_driver_desc *desc = (const dkm_driver_desc *)(image + image_offset[desc_sym->shndx] + desc_sym->value);
if (desc->magic != DKM_DRIVER_MAGIC) { if (desc->magic != DKM_DRIVER_MAGIC) {
log_error("[DKM] external driver_desc magic mismatch"); log_error("[DKM] external driver_desc magic mismatch");
panic_full("DKM-E38 DRIVER DESC MAGIC MISMATCH",
"dkm_load_elf_rel: external driver_desc magic mismatch", 0);
return -1; return -1;
} }
@@ -397,6 +416,8 @@ int dkm_load_elf_rel(const void *address, u64 size, const struct dkm_symbol_scan
if (result != 0) { if (result != 0) {
handle.state = DKM_STATE_FAILED; handle.state = DKM_STATE_FAILED;
log_error("[DKM] external driver init failed"); log_error("[DKM] external driver init failed");
panic_full("DKM-E39 EXTERNAL DRIVER INIT FAILED",
"dkm_load_elf_rel: external driver_init returned non-zero", 0);
return result; return result;
} }
handle.state = DKM_STATE_ACTIVE; handle.state = DKM_STATE_ACTIVE;
@@ -408,6 +429,8 @@ void dkm_scan_boot_modules(void) {
struct limine_module_response *response = g_module_request.response; struct limine_module_response *response = g_module_request.response;
if (!response) { if (!response) {
log_warn("[DKM] no Limine module response"); log_warn("[DKM] no Limine module response");
panic_full("DKM-E40 NO LIMINE MODULE RESPONSE",
"dkm_scan_boot_modules: no Limine module response", 0);
return; return;
} }
@@ -418,6 +441,8 @@ void dkm_scan_boot_modules(void) {
struct limine_file *file = response->modules[i]; struct limine_file *file = response->modules[i];
if (!file) { if (!file) {
log_warn("[DKM] null module entry"); log_warn("[DKM] null module entry");
panic_full("DKM-E41 NULL MODULE ENTRY",
"dkm_scan_boot_modules: null boot module entry", 0);
continue; continue;
} }
@@ -439,11 +464,15 @@ void dkm_scan_boot_modules(void) {
int load_result = dkm_load_elf_rel(file->address, file->size, &symbols); int load_result = dkm_load_elf_rel(file->address, file->size, &symbols);
if (load_result != 0) { if (load_result != 0) {
log_error("[DKM] external driver load failed"); log_error("[DKM] external driver load failed");
panic_full("DKM-E42 EXTERNAL DRIVER LOAD FAILED",
"dkm_scan_boot_modules: external driver load failed", 0);
} }
} }
} else { } else {
log_error("[DKM] module ELF64 rejected"); log_error("[DKM] module ELF64 rejected");
log_hex64("[DKM] elf status=", (u64)(i64)status); log_hex64("[DKM] elf status=", (u64)(i64)status);
panic_full("DKM-E43 MODULE ELF64 REJECTED",
"dkm_scan_boot_modules: boot module ELF64 check rejected", 0);
} }
} }
+2 -1
View File
@@ -1,7 +1,7 @@
dkm/boot_modules.o: dkm\boot_modules.c include\utsm\dkm.h \ dkm/boot_modules.o: dkm\boot_modules.c include\utsm\dkm.h \
include\utsm\types.h include\utsm\dma.h include\utsm\block.h \ include\utsm\types.h include\utsm\dma.h include\utsm\block.h \
include\utsm\net.h include\utsm\paging.h include\utsm\log.h \ include\utsm\net.h include\utsm\paging.h include\utsm\log.h \
include\utsm\arena.h dkm\..\arch\x86_64\limine.h include\utsm\arena.h include\utsm\panic.h dkm\..\arch\x86_64\limine.h
include\utsm\dkm.h: include\utsm\dkm.h:
include\utsm\types.h: include\utsm\types.h:
include\utsm\dma.h: include\utsm\dma.h:
@@ -10,4 +10,5 @@ include\utsm\net.h:
include\utsm\paging.h: include\utsm\paging.h:
include\utsm\log.h: include\utsm\log.h:
include\utsm\arena.h: include\utsm\arena.h:
include\utsm\panic.h:
dkm\..\arch\x86_64\limine.h: dkm\..\arch\x86_64\limine.h:
Binary file not shown.
+10 -1
View File
@@ -1,5 +1,6 @@
#include <utsm/dkm.h> #include <utsm/dkm.h>
#include <utsm/log.h> #include <utsm/log.h>
#include <utsm/panic.h>
static int dkm_validate_desc(const dkm_driver_desc *desc) { static int dkm_validate_desc(const dkm_driver_desc *desc) {
if (!desc) { if (!desc) {
@@ -27,18 +28,24 @@ void dkm_init(void) {
log_info("[DKM] init ok"); log_info("[DKM] init ok");
} else { } else {
log_error("[DKM] init failed"); log_error("[DKM] init failed");
panic_full("DKM-E50 BUILTIN INIT FAILED",
"dkm_init: builtin console_early load failed", 0);
} }
} }
int dkm_load_builtin(const dkm_builtin_driver *driver) { int dkm_load_builtin(const dkm_builtin_driver *driver) {
if (!driver || !driver->desc || !driver->init) { if (!driver || !driver->desc || !driver->init) {
log_error("[DKM] invalid builtin driver"); log_error("[DKM] invalid builtin driver");
panic_full("DKM-E51 INVALID BUILTIN DRIVER",
"dkm_load_builtin: builtin driver descriptor invalid", 0);
return -1; return -1;
} }
int status = dkm_validate_desc(driver->desc); int status = dkm_validate_desc(driver->desc);
if (status != 0) { if (status != 0) {
log_error("[DKM] driver_desc rejected"); log_error("[DKM] driver_desc rejected");
panic_full("DKM-E52 DRIVER DESC REJECTED",
"dkm_load_builtin: builtin driver_desc validation failed", 0);
return status; return status;
} }
@@ -60,6 +67,8 @@ int dkm_load_builtin(const dkm_builtin_driver *driver) {
if (status != 0) { if (status != 0) {
handle.state = DKM_STATE_FAILED; handle.state = DKM_STATE_FAILED;
log_error("[DKM] builtin driver init failed"); log_error("[DKM] builtin driver init failed");
panic_full("DKM-E53 BUILTIN DRIVER INIT FAILED",
"dkm_load_builtin: builtin driver_init returned non-zero", 0);
return status; return status;
} }
+2 -1
View File
@@ -1,6 +1,6 @@
dkm/dkm_core.o: dkm\dkm_core.c include\utsm\dkm.h include\utsm\types.h \ dkm/dkm_core.o: dkm\dkm_core.c include\utsm\dkm.h include\utsm\types.h \
include\utsm\dma.h include\utsm\block.h include\utsm\net.h \ include\utsm\dma.h include\utsm\block.h include\utsm\net.h \
include\utsm\paging.h include\utsm\log.h include\utsm\paging.h include\utsm\log.h include\utsm\panic.h
include\utsm\dkm.h: include\utsm\dkm.h:
include\utsm\types.h: include\utsm\types.h:
include\utsm\dma.h: include\utsm\dma.h:
@@ -8,3 +8,4 @@ include\utsm\block.h:
include\utsm\net.h: include\utsm\net.h:
include\utsm\paging.h: include\utsm\paging.h:
include\utsm\log.h: include\utsm\log.h:
include\utsm\panic.h:
Binary file not shown.
+33 -2
View File
@@ -267,7 +267,12 @@ static int dsm_parse_manifest(const char *text, u64 size) {
dsm_expect(&p, ':'); dsm_expect(&p, ':');
if (streq_static(key, "stages")) { if (streq_static(key, "stages")) {
if (dsm_expect(&p, '[') != 0) return -1; if (dsm_expect(&p, '[') != 0) {
/* 严格错误策略插桩:stage 解析失败零降级(DKM-E08) */
panic_full("DKM-E08 MANIFEST STAGES PARSE FAILED",
"dsm_parse_manifest: stages array malformed", 0);
return -1;
}
while (p < end && *p) { while (p < end && *p) {
dsm_skip_ws(&p); dsm_skip_ws(&p);
if (*p == ']') { p++; break; } if (*p == ']') { p++; break; }
@@ -300,6 +305,9 @@ static int dsm_ensure_manifest(void) {
rsp = g_module_request.response; rsp = g_module_request.response;
if (!rsp) { if (!rsp) {
log_warn("[DSM] no Limine module response"); log_warn("[DSM] no Limine module response");
/* 严格错误策略插桩:manifest 缺失零降级(DKM-E09) */
panic_full("DKM-E09 NO LIMINE MODULE RESPONSE",
"dsm_ensure_manifest: no Limine module response", 0);
return -1; return -1;
} }
@@ -314,6 +322,9 @@ static int dsm_ensure_manifest(void) {
if (!manifest_file) { if (!manifest_file) {
log_warn("[DSM] manifest not found in boot modules"); log_warn("[DSM] manifest not found in boot modules");
/* 严格错误策略插桩:manifest 缺失零降级(DKM-E10) */
panic_full("DKM-E10 MANIFEST NOT FOUND",
"dsm_ensure_manifest: dkm:manifest boot module missing", 0);
return -1; return -1;
} }
@@ -409,7 +420,12 @@ void dsm_load_by_manifest_upto(const ini_config *cfg, u32 max_stage_id) {
} }
void dsm_load_named(const ini_config *cfg, const char *name) { void dsm_load_named(const ini_config *cfg, const char *name) {
if (!name || dsm_ensure_manifest() != 0) return; if (!name || dsm_ensure_manifest() != 0) {
/* 严格错误策略插桩:按名加载 manifest 缺失零降级(DKM-E11) */
panic_full("DKM-E11 NAMED LOAD MANIFEST MISSING",
"dsm_load_named: null name or manifest unavailable", 0);
return;
}
for (u32 si = 0; si < g_stage_count; si++) { for (u32 si = 0; si < g_stage_count; si++) {
dsm_stage_entry *stage = &g_stages[si]; dsm_stage_entry *stage = &g_stages[si];
@@ -430,6 +446,9 @@ void dsm_load_named(const ini_config *cfg, const char *name) {
if (!drv->boot_module) { if (!drv->boot_module) {
log_warn("[DSM] named module not found"); log_warn("[DSM] named module not found");
log_info(name); log_info(name);
/* 严格错误策略插桩:named 驱动缺模块零降级(DKM-E12) */
panic_full("DKM-E12 NAMED DRIVER MODULE MISSING",
"dsm_load_named: named driver boot module not found", 0);
return; return;
} }
f = drv->boot_module; f = drv->boot_module;
@@ -437,15 +456,24 @@ void dsm_load_named(const ini_config *cfg, const char *name) {
log_info(drv->name); log_info(drv->name);
if (dkm_check_elf64(f->address, f->size) != 0) { if (dkm_check_elf64(f->address, f->size) != 0) {
log_error("[DSM] ELF check failed"); log_error("[DSM] ELF check failed");
/* 严格错误策略插桩:named 驱动 ELF 校验失败零降级(DKM-E13) */
panic_full("DKM-E13 NAMED DRIVER ELF INVALID",
"dsm_load_named: named driver failed ELF64 check", 0);
return; return;
} }
if (dkm_scan_symbols(f->address, f->size, &symbols) != 0) { if (dkm_scan_symbols(f->address, f->size, &symbols) != 0) {
log_error("[DSM] symbol scan failed"); log_error("[DSM] symbol scan failed");
/* 严格错误策略插桩:named 驱动符号扫描失败零降级(DKM-E14) */
panic_full("DKM-E14 NAMED DRIVER SYMBOL SCAN FAILED",
"dsm_load_named: named driver symbol scan failed", 0);
return; return;
} }
result = dkm_load_elf_rel(f->address, f->size, &symbols); result = dkm_load_elf_rel(f->address, f->size, &symbols);
if (result != 0) { if (result != 0) {
log_error("[DSM] load failed"); log_error("[DSM] load failed");
/* 严格错误策略插桩:named 驱动加载失败零降级(DKM-E15) */
panic_full("DKM-E15 NAMED DRIVER LOAD FAILED",
"dsm_load_named: named driver relocation/load failed", 0);
return; return;
} }
drv->loaded = 1; drv->loaded = 1;
@@ -454,6 +482,9 @@ void dsm_load_named(const ini_config *cfg, const char *name) {
} }
log_warn("[DSM] named driver not in manifest"); log_warn("[DSM] named driver not in manifest");
log_info(name); log_info(name);
/* 严格错误策略插桩:named 驱动不在 manifest 零降级(DKM-E16) */
panic_full("DKM-E16 NAMED DRIVER NOT IN MANIFEST",
"dsm_load_named: named driver not found in manifest", 0);
} }
void dsm_load_by_manifest_ex(const ini_config *cfg) { void dsm_load_by_manifest_ex(const ini_config *cfg) {
Binary file not shown.
+33 -2
View File
@@ -6,6 +6,7 @@
#include <utsm/pe.h> #include <utsm/pe.h>
#include <utsm/linux_compat.h> #include <utsm/linux_compat.h>
#include <utsm/instr.h> #include <utsm/instr.h>
#include <utsm/panic.h>
#include "../arch/x86_64/limine.h" #include "../arch/x86_64/limine.h"
#include "../../tools/fat32_lfn.h" #include "../../tools/fat32_lfn.h"
@@ -215,6 +216,8 @@ static u32 fat32_get_next_cluster(u32 fat_start_byte, u32 clus,
log_error("[UTSM] FAT32: on-demand FAT sector read failed"); log_error("[UTSM] FAT32: on-demand FAT sector read failed");
log_hex64("[UTSM] FAT32: fat_sec_lba=", fat_sec_lba); log_hex64("[UTSM] FAT32: fat_sec_lba=", fat_sec_lba);
log_hex64("[UTSM] FAT32: clus=", clus); log_hex64("[UTSM] FAT32: clus=", clus);
panic_full("DSL-E01 FAT SECTOR READ FAILED",
"fat32_get_next_cluster: on-demand FAT sector read failed", 0);
return 0x0FFFFFFF; return 0x0FFFFFFF;
} }
return fat32_read_u32(g_dsk_fat32_fat_sec + ent_off_in_sec) & 0x0FFFFFFF; return fat32_read_u32(g_dsk_fat32_fat_sec + ent_off_in_sec) & 0x0FFFFFFF;
@@ -223,11 +226,14 @@ static u32 fat32_get_next_cluster(u32 fat_start_byte, u32 clus,
static int dsk_load_from_block_fat32(const void **out_addr, u64 *out_size) { static int dsk_load_from_block_fat32(const void **out_addr, u64 *out_size) {
const dkm_kernel_api *api = dkm_get_kernel_api(); const dkm_kernel_api *api = dkm_get_kernel_api();
if (!api || !api->block || !api->block->device_count) { if (!api || !api->block || !api->block->device_count) {
/* 【插桩白名单】设计内双路径回退:无块设备时由调用方回退
* Limine boot module(CLAUDE.md 两阶段 DSK 加载设计)。 */
log_error("[UTSM] FAT32: no block api available"); log_error("[UTSM] FAT32: no block api available");
return -1; return -1;
} }
u32 count = api->block->device_count(); u32 count = api->block->device_count();
if (count == 0 || api->block->sector_size(0) != 512) { if (count == 0 || api->block->sector_size(0) != 512) {
/* 【插桩白名单】同上:无块设备属设计内回退路径。 */
log_error("[UTSM] FAT32: no block device or wrong sector size"); log_error("[UTSM] FAT32: no block device or wrong sector size");
log_hex64("[UTSM] FAT32: device_count=", count); log_hex64("[UTSM] FAT32: device_count=", count);
return -1; return -1;
@@ -239,12 +245,17 @@ static int dsk_load_from_block_fat32(const void **out_addr, u64 *out_size) {
if (st != 0) { if (st != 0) {
log_error("[UTSM] FAT32: BPB read failed"); log_error("[UTSM] FAT32: BPB read failed");
log_hex64("[UTSM] FAT32: read status=", (u64)(i64)st); log_hex64("[UTSM] FAT32: read status=", (u64)(i64)st);
panic_full("DSL-E04 BPB READ FAILED",
"dsk_load_from_block_fat32: BPB 256-sector read failed", 0);
return -1; return -1;
} }
const fat32_bpb *bpb = (const fat32_bpb *)disk; const fat32_bpb *bpb = (const fat32_bpb *)disk;
if (bpb->boot_sig != 0xAA55 || bpb->bytes_per_sector != 512) { if (bpb->boot_sig != 0xAA55 || bpb->bytes_per_sector != 512) {
log_error("[UTSM] FAT32: invalid BPB signature or sector size"); /* 【插桩白名单】设计内设备探测:device 0 可能是 GPT 主盘(LBA0 为
* 保护性 MBR,带 0x55AA 签名但非 FAT32 VBR)。非 FAT32 卷时由调用
* 方回退 Limine boot module(CLAUDE.md 两阶段 DSK 加载设计)。 */
log_error("[UTSM] FAT32: not a FAT32 volume on device 0 (fallback to boot module)");
log_hex64("[UTSM] FAT32: boot_sig=", bpb->boot_sig); log_hex64("[UTSM] FAT32: boot_sig=", bpb->boot_sig);
log_hex64("[UTSM] FAT32: bps=", bpb->bytes_per_sector); log_hex64("[UTSM] FAT32: bps=", bpb->bytes_per_sector);
return -1; return -1;
@@ -271,6 +282,8 @@ static int dsk_load_from_block_fat32(const void **out_addr, u64 *out_size) {
log_error("[UTSM] FAT32: dir cluster read failed"); log_error("[UTSM] FAT32: dir cluster read failed");
log_hex64("[UTSM] FAT32: clus=", clus); log_hex64("[UTSM] FAT32: clus=", clus);
log_hex64("[UTSM] FAT32: lba=", clus_lba); log_hex64("[UTSM] FAT32: lba=", clus_lba);
panic_full("DSL-E06 DIR CLUSTER READ FAILED",
"dsk_load_from_block_fat32: root dir cluster read failed", 0);
return -1; return -1;
} }
@@ -294,6 +307,8 @@ static int dsk_load_from_block_fat32(const void **out_addr, u64 *out_size) {
if (!found_clus || found_size == 0) { if (!found_clus || found_size == 0) {
log_error("[UTSM] FAT32: DESHAB.ELF not found in root dir"); log_error("[UTSM] FAT32: DESHAB.ELF not found in root dir");
panic_full("DSL-E07 DESHAB ELF NOT FOUND",
"dsk_load_from_block_fat32: DESHAB.ELF not found in root dir", 0);
return -1; return -1;
} }
log_hex64("[UTSM] FAT32: found_clus=", found_clus); log_hex64("[UTSM] FAT32: found_clus=", found_clus);
@@ -301,6 +316,8 @@ static int dsk_load_from_block_fat32(const void **out_addr, u64 *out_size) {
if (found_size > sizeof(g_dsk_fat32_filedata)) { if (found_size > sizeof(g_dsk_fat32_filedata)) {
log_error("[UTSM] FAT32: file exceeds 2MB buffer"); log_error("[UTSM] FAT32: file exceeds 2MB buffer");
panic_full("DSL-E08 DSK FILE EXCEEDS BUFFER",
"dsk_load_from_block_fat32: deshab.elf exceeds file buffer", 0);
return -1; return -1;
} }
u8 *dst = g_dsk_fat32_filedata; u8 *dst = g_dsk_fat32_filedata;
@@ -319,6 +336,8 @@ static int dsk_load_from_block_fat32(const void **out_addr, u64 *out_size) {
log_error("[UTSM] FAT32: data cluster read failed"); log_error("[UTSM] FAT32: data cluster read failed");
log_hex64("[UTSM] FAT32: fc=", fc); log_hex64("[UTSM] FAT32: fc=", fc);
log_hex64("[UTSM] FAT32: lba=", fc_lba); log_hex64("[UTSM] FAT32: lba=", fc_lba);
panic_full("DSL-E09 DATA CLUSTER READ FAILED",
"dsk_load_from_block_fat32: file data cluster read failed", 0);
return -1; return -1;
} }
for (u32 b = 0; b < fc_bytes; b++) dst[b] = chunk[b]; for (u32 b = 0; b < fc_bytes; b++) dst[b] = chunk[b];
@@ -334,6 +353,8 @@ static int dsk_load_from_block_fat32(const void **out_addr, u64 *out_size) {
if (!file_buf) { if (!file_buf) {
log_error("[UTSM] FAT32: arena alloc failed"); log_error("[UTSM] FAT32: arena alloc failed");
log_hex64("[UTSM] FAT32: size=", found_size); log_hex64("[UTSM] FAT32: size=", found_size);
panic_full("DSL-E10 ARENA ALLOC FAILED",
"dsk_load_from_block_fat32: arena alloc for DSK image failed", 0);
return -1; return -1;
} }
for (u32 i = 0; i < found_size; i++) file_buf[i] = g_dsk_fat32_filedata[i]; for (u32 i = 0; i < found_size; i++) file_buf[i] = g_dsk_fat32_filedata[i];
@@ -1070,7 +1091,9 @@ int dsk_load_and_jump(void) {
if (fat32_ok == 0) { if (fat32_ok == 0) {
log_info("[UTSM] DSK loaded from FAT32 block provider"); log_info("[UTSM] DSK loaded from FAT32 block provider");
} else { } else {
/* 2) fallback: Limine boot module */ /* 2) fallback: Limine boot module
* 【插桩白名单】设计内双路径回退:块设备读 deshab.elf 失败时
* 回退 Limine boot module 预加载,按任务要求保持原样不插桩。 */
log_info("[UTSM] FAT32 block path unavailable; trying Limine module"); log_info("[UTSM] FAT32 block path unavailable; trying Limine module");
struct limine_file *file = dsk_find_module(); struct limine_file *file = dsk_find_module();
if (!file) { if (!file) {
@@ -1086,6 +1109,8 @@ int dsk_load_and_jump(void) {
if (status != 0) { if (status != 0) {
log_error("[UTSM] DSK ELF rejected"); log_error("[UTSM] DSK ELF rejected");
log_hex64("[UTSM] DSK ELF status=", (u64)(i64)status); log_hex64("[UTSM] DSK ELF status=", (u64)(i64)status);
panic_full("DSL-E11 DSK ELF REJECTED",
"dsk_load_and_jump: deshab.elf ELF check rejected", 0);
return status; return status;
} }
@@ -1094,12 +1119,16 @@ int dsk_load_and_jump(void) {
if (status != 0) { if (status != 0) {
log_error("[UTSM] DSK load failed"); log_error("[UTSM] DSK load failed");
log_hex64("[UTSM] DSK load status=", (u64)(i64)status); log_hex64("[UTSM] DSK load status=", (u64)(i64)status);
panic_full("DSL-E12 DSK LOAD FAILED",
"dsk_load_and_jump: DSK ELF image load failed", 0);
return status; return status;
} }
dsk_boot_context *ctx = (dsk_boot_context *)kmem_alloc_aligned(sizeof(dsk_boot_context), 16); dsk_boot_context *ctx = (dsk_boot_context *)kmem_alloc_aligned(sizeof(dsk_boot_context), 16);
if (!ctx) { if (!ctx) {
log_error("[UTSM] DSK context allocation failed"); log_error("[UTSM] DSK context allocation failed");
panic_full("DSL-E13 DSK CONTEXT ALLOC FAILED",
"dsk_load_and_jump: boot context allocation failed", 0);
return -1; return -1;
} }
dsk_fill_boot_context(ctx); dsk_fill_boot_context(ctx);
@@ -1169,5 +1198,7 @@ int dsk_load_and_jump(void) {
entry(ctx); entry(ctx);
log_error("[UTSM] DSK returned unexpectedly"); log_error("[UTSM] DSK returned unexpectedly");
panic_full("DSL-E14 DSK RETURNED UNEXPECTEDLY",
"dsk entry point returned to UTSM", 0);
return -1; return -1;
} }
+21
View File
@@ -0,0 +1,21 @@
kernel/dsk_loader.o: kernel\dsk_loader.c include\utsm\dsk.h \
include\utsm\types.h include\utsm\arena.h include\utsm\dkm.h \
include\utsm\dma.h include\utsm\block.h include\utsm\net.h \
include\utsm\paging.h include\utsm\log.h include\utsm\pe.h \
include\utsm\linux_compat.h include\utsm\instr.h include\utsm\panic.h \
kernel\..\arch\x86_64\limine.h kernel\..\..\tools\fat32_lfn.h
include\utsm\dsk.h:
include\utsm\types.h:
include\utsm\arena.h:
include\utsm\dkm.h:
include\utsm\dma.h:
include\utsm\block.h:
include\utsm\net.h:
include\utsm\paging.h:
include\utsm\log.h:
include\utsm\pe.h:
include\utsm\linux_compat.h:
include\utsm\instr.h:
include\utsm\panic.h:
kernel\..\arch\x86_64\limine.h:
kernel\..\..\tools\fat32_lfn.h:
Binary file not shown.
+14 -1
View File
@@ -190,7 +190,10 @@ static void disk_log_flush(void) {
log_info("[UTSM] disk_log: BOOTLOG.TXT written"); log_info("[UTSM] disk_log: BOOTLOG.TXT written");
log_hex64("[UTSM] disk_log: bytes=", len); log_hex64("[UTSM] disk_log: bytes=", len);
} else { } else {
log_error("[UTSM] disk_log: FAT32 write failed"); /* 【插桩白名单】设计内只读块路径:AHCI provider 当前仅注册最小
* read(CLAUDE.md ahci 驱动说明),write 恒为空,bootlog 落盘
* 失败属环境能力缺失而非数据读写错误。诊断日志不得阻断启动。 */
log_error("[UTSM] disk_log: FAT32 write failed (read-only block path, skip)");
log_hex64("[UTSM] disk_log: rc=", (u64)(i64)rc); log_hex64("[UTSM] disk_log: rc=", (u64)(i64)rc);
} }
} }
@@ -258,6 +261,8 @@ void kernel_main(void) {
if (cr4 & (1ULL << 12)) { if (cr4 & (1ULL << 12)) {
log_error("[UTSM] LA57 is ACTIVE — this kernel requires 4-level paging"); log_error("[UTSM] LA57 is ACTIVE — this kernel requires 4-level paging");
log_error("[UTSM] Refusing to boot. Disable LA57 in firmware settings."); log_error("[UTSM] Refusing to boot. Disable LA57 in firmware settings.");
panic_full("VMM-E11 LA57 ACTIVE REFUSE BOOT",
"5-level paging active; kernel requires 4-level paging", 0);
arch_halt_forever(); arch_halt_forever();
} }
} }
@@ -404,6 +409,8 @@ void kernel_main(void) {
* (configured separately) may still work. Force-continue regardless. */ * (configured separately) may still work. Force-continue regardless. */
if (vmm_st != 0) { if (vmm_st != 0) {
log_warn("[UTSM] VMM self-test FAIL, but continuing to Linux guest"); log_warn("[UTSM] VMM self-test FAIL, but continuing to Linux guest");
panic_full("VMM-E12 VMM SELFTEST FAIL",
"VMM self-test failed; force-continue removed by instrumentation", 0);
vmm_st = 0; /* force pass to continue to Linux guest */ vmm_st = 0; /* force pass to continue to Linux guest */
} }
if (vmm_st == 0) { if (vmm_st == 0) {
@@ -476,6 +483,8 @@ void kernel_main(void) {
INSTR_TS_END(ts_vmm, "vmm_init+selftest"); INSTR_TS_END(ts_vmm, "vmm_init+selftest");
log_error("[UTSM] VMM self-test FAIL"); log_error("[UTSM] VMM self-test FAIL");
log_hex64("[UTSM] VMM st=", (u64)(i64)vmm_st); log_hex64("[UTSM] VMM st=", (u64)(i64)vmm_st);
panic_full("VMM-E13 VMM SELFTEST FAIL",
"VMM self-test failed (non-zero status)", 0);
} }
/* === OpenXJ380 guest — 可通过 FUCK [boot] xj380_guest=0 跳过 === /* === OpenXJ380 guest — 可通过 FUCK [boot] xj380_guest=0 跳过 ===
@@ -532,6 +541,8 @@ void kernel_main(void) {
log_info("[UTSM] SELFTEST PASS"); log_info("[UTSM] SELFTEST PASS");
} else { } else {
log_error("[UTSM] SELFTEST FAIL"); log_error("[UTSM] SELFTEST FAIL");
panic_full("VMM-E14 SELFTEST FAIL",
"utsm_selftest_run returned non-zero", 0);
arch_halt_forever(); arch_halt_forever();
} }
} }
@@ -570,6 +581,8 @@ void kernel_main(void) {
if (dsk_load_and_jump() != 0) { if (dsk_load_and_jump() != 0) {
log_error("[UTSM] DSK jump failed"); log_error("[UTSM] DSK jump failed");
panic_full("VMM-E15 DSK JUMP FAILED",
"dsk_load_and_jump returned non-zero", 0);
} }
/* ---- 插桩: 启动总耗时(仅在 DSK 跳转失败时可见) ---- */ /* ---- 插桩: 启动总耗时(仅在 DSK 跳转失败时可见) ---- */
Binary file not shown.
+3
View File
@@ -15,6 +15,7 @@
#include <utsm/log.h> #include <utsm/log.h>
#include <utsm/types.h> #include <utsm/types.h>
#include <utsm/arena.h> #include <utsm/arena.h>
#include <utsm/panic.h>
#include "ini_parser.h" #include "ini_parser.h"
/* ---- 探测缓冲状态 ---- */ /* ---- 探测缓冲状态 ---- */
@@ -39,6 +40,8 @@ void probe_init(const void *cfg_ptr) {
if (!g_probe_buf) { if (!g_probe_buf) {
g_instr_probe_enable = 0; g_instr_probe_enable = 0;
log_warn("[PROBE] arena alloc failed, probe disabled"); log_warn("[PROBE] arena alloc failed, probe disabled");
panic_full("PRB-E01 PROBE ARENA ALLOC FAILED",
"probe_init: probe buffer arena allocation failed", 0);
return; return;
} }
+9
View File
@@ -0,0 +1,9 @@
kernel/probe.o: kernel\probe.c include\utsm\instr.h include\utsm\types.h \
include\utsm\log.h include\utsm\arena.h include\utsm\panic.h \
kernel\ini_parser.h
include\utsm\instr.h:
include\utsm\types.h:
include\utsm\log.h:
include\utsm\arena.h:
include\utsm\panic.h:
kernel\ini_parser.h:
+7
View File
@@ -1,6 +1,7 @@
#include <utsm/dma.h> #include <utsm/dma.h>
#include <utsm/log.h> #include <utsm/log.h>
#include <utsm/types.h> #include <utsm/types.h>
#include <utsm/panic.h>
#include "../arch/x86_64/limine.h" #include "../arch/x86_64/limine.h"
#define PAGE_SIZE 4096ULL #define PAGE_SIZE 4096ULL
@@ -54,6 +55,8 @@ void dma_init(void) {
} }
if (!g_hhdm_offset || !g_memmap_request.response) { if (!g_hhdm_offset || !g_memmap_request.response) {
log_warn("[DMA] missing HHDM or memmap response"); log_warn("[DMA] missing HHDM or memmap response");
panic_full("MM-E20 MISSING HHDM OR MEMMAP",
"dma_init: HHDM or memmap response missing", 0);
return; return;
} }
@@ -84,6 +87,8 @@ void dma_init(void) {
if (g_free_pages == 0) { if (g_free_pages == 0) {
log_warn("[DMA] no usable low pages found"); log_warn("[DMA] no usable low pages found");
panic_full("MM-E21 NO USABLE LOW PAGES",
"dma_init: no usable low-4G pages in memmap", 0);
return; return;
} }
@@ -133,6 +138,8 @@ int dma_alloc_pages(u64 page_count, u64 alignment, u64 max_phys, dkm_dma_buffer
log_warn("[DMA] alloc failed"); log_warn("[DMA] alloc failed");
log_hex64("[DMA] req pages=", page_count); log_hex64("[DMA] req pages=", page_count);
log_hex64("[DMA] free pages=", g_free_pages); log_hex64("[DMA] free pages=", g_free_pages);
panic_full("MM-E22 DMA ALLOC FAILED",
"dma_alloc_pages: no free pages satisfying request", 0);
return -2; return -2;
} }
+7
View File
@@ -0,0 +1,7 @@
mm/dma.o: mm\dma.c include\utsm\dma.h include\utsm\types.h \
include\utsm\log.h include\utsm\panic.h mm\..\arch\x86_64\limine.h
include\utsm\dma.h:
include\utsm\types.h:
include\utsm\log.h:
include\utsm\panic.h:
mm\..\arch\x86_64\limine.h:
Binary file not shown.
+19
View File
@@ -2,6 +2,7 @@
#include <utsm/dma.h> #include <utsm/dma.h>
#include <utsm/log.h> #include <utsm/log.h>
#include <utsm/types.h> #include <utsm/types.h>
#include <utsm/panic.h>
#include "../arch/x86_64/limine.h" #include "../arch/x86_64/limine.h"
#define MM_PAGE_SIZE 4096ULL #define MM_PAGE_SIZE 4096ULL
@@ -79,11 +80,15 @@ static void mm_lazy_init(void) {
g_max_phys_addr_bits = 0; g_max_phys_addr_bits = 0;
if (!g_hhdm_request.response) { if (!g_hhdm_request.response) {
log_warn("[MM] missing HHDM response"); log_warn("[MM] missing HHDM response");
panic_full("MM-E10 MISSING HHDM RESPONSE",
"mm_lazy_init: Limine HHDM response missing", 0);
return; return;
} }
g_hhdm = g_hhdm_request.response->offset; g_hhdm = g_hhdm_request.response->offset;
if (!g_hhdm) { if (!g_hhdm) {
log_warn("[MM] null HHDM offset"); log_warn("[MM] null HHDM offset");
panic_full("MM-E11 NULL HHDM OFFSET",
"mm_lazy_init: HHDM offset is zero", 0);
return; return;
} }
@@ -95,6 +100,8 @@ static void mm_lazy_init(void) {
log_error("[MM] LA57 5-level paging ACTIVE — REFUSING to proceed"); log_error("[MM] LA57 5-level paging ACTIVE — REFUSING to proceed");
log_error("[MM] This kernel requires 4-level paging (48-bit virtual)"); log_error("[MM] This kernel requires 4-level paging (48-bit virtual)");
log_error("[MM] Disable LA57 in BIOS/firmware settings"); log_error("[MM] Disable LA57 in BIOS/firmware settings");
panic_full("MM-E12 LA57 ACTIVE REFUSE",
"mm_lazy_init: 5-level paging active; 4-level walk required", 0);
return; return;
} }
@@ -113,6 +120,8 @@ static void mm_lazy_init(void) {
log_hex64("[MM] CPU MaxPhysAddr bits=", g_max_phys_addr_bits); log_hex64("[MM] CPU MaxPhysAddr bits=", g_max_phys_addr_bits);
if (g_max_phys_addr_bits > 52) { if (g_max_phys_addr_bits > 52) {
log_error("[MM] physical address width > 52 bits — PTE cannot represent"); log_error("[MM] physical address width > 52 bits — PTE cannot represent");
panic_full("MM-E13 PHYS ADDR WIDTH EXCEEDED",
"mm_lazy_init: physical address width exceeds 52 bits", 0);
return; return;
} }
} else { } else {
@@ -126,6 +135,8 @@ static void mm_lazy_init(void) {
g_window_base = mm_find_window(); g_window_base = mm_find_window();
if (!g_window_base) { if (!g_window_base) {
log_error("[MM] no free PML4 slot for mmio window"); log_error("[MM] no free PML4 slot for mmio window");
panic_full("MM-E14 NO FREE PML4 SLOT",
"mm_lazy_init: no free PML4 slot for mmio window", 0);
return; return;
} }
g_window_end = g_window_base + MM_WINDOW_SIZE; g_window_end = g_window_base + MM_WINDOW_SIZE;
@@ -153,6 +164,8 @@ static u64 *mm_walk_create(u64 virt) {
dkm_dma_buffer buf; dkm_dma_buffer buf;
if (dma_alloc_pages(1, MM_PAGE_SIZE, 0, &buf) != 0) { if (dma_alloc_pages(1, MM_PAGE_SIZE, 0, &buf) != 0) {
log_warn("[MM] page table alloc failed"); log_warn("[MM] page table alloc failed");
panic_full("MM-E15 PAGE TABLE ALLOC FAILED",
"mm_walk_create: page table page alloc failed", 0);
return 0; return 0;
} }
table[idx] = buf.phys | PTE_PRESENT | PTE_RW; table[idx] = buf.phys | PTE_PRESENT | PTE_RW;
@@ -185,6 +198,8 @@ void *mm_map_mmio(u64 phys, u64 size) {
log_error("[MM] phys address exceeds CPU MaxPhysAddr"); log_error("[MM] phys address exceeds CPU MaxPhysAddr");
log_hex64("[MM] phys=", phys); log_hex64("[MM] phys=", phys);
log_hex64("[MM] max_phys=", max_phys); log_hex64("[MM] max_phys=", max_phys);
panic_full("MM-E16 PHYS EXCEEDS MAXADDR",
"mm_map_mmio: physical address exceeds CPU MaxPhysAddr", 0);
return 0; return 0;
} }
} }
@@ -197,6 +212,8 @@ void *mm_map_mmio(u64 phys, u64 size) {
u64 vbase = g_window_next; u64 vbase = g_window_next;
if (vbase < g_window_base || vbase + total > g_window_end) { if (vbase < g_window_base || vbase + total > g_window_end) {
log_error("[MM] mmio window exhausted"); log_error("[MM] mmio window exhausted");
panic_full("MM-E17 MMIO WINDOW EXHAUSTED",
"mm_map_mmio: MMIO virtual window exhausted", 0);
return 0; return 0;
} }
@@ -207,6 +224,8 @@ void *mm_map_mmio(u64 phys, u64 size) {
if (!pte || (*pte & PTE_PRESENT)) { if (!pte || (*pte & PTE_PRESENT)) {
/* 冲突/失败:回滚本次已建立的映射 */ /* 冲突/失败:回滚本次已建立的映射 */
log_error("[MM] map conflict"); log_error("[MM] map conflict");
panic_full("MM-E18 MAP CONFLICT",
"mm_map_mmio: page table walk conflict or failure", 0);
for (u64 j = 0; j < mapped; j++) { for (u64 j = 0; j < mapped; j++) {
u64 v = vbase + j * MM_PAGE_SIZE; u64 v = vbase + j * MM_PAGE_SIZE;
u64 *p = mm_walk_query(v); u64 *p = mm_walk_query(v);
+9
View File
@@ -0,0 +1,9 @@
mm/mmio.o: mm\mmio.c include\utsm\mm.h include\utsm\types.h \
include\utsm\dma.h include\utsm\log.h include\utsm\panic.h \
mm\..\arch\x86_64\limine.h
include\utsm\mm.h:
include\utsm\types.h:
include\utsm\dma.h:
include\utsm\log.h:
include\utsm\panic.h:
mm\..\arch\x86_64\limine.h:
+19 -3
View File
@@ -15,6 +15,7 @@
#include <utsm/paging.h> #include <utsm/paging.h>
#include <utsm/dma.h> #include <utsm/dma.h>
#include <utsm/log.h> #include <utsm/log.h>
#include <utsm/panic.h>
#include "../arch/x86_64/limine.h" #include "../arch/x86_64/limine.h"
extern volatile struct limine_hhdm_request g_hhdm_request; extern volatile struct limine_hhdm_request g_hhdm_request;
@@ -90,7 +91,12 @@ static int paging_map_mmio_impl(u64 phys, u64 size) {
u64 idx4 = (v >> 39) & 0x1FF; u64 idx4 = (v >> 39) & 0x1FF;
if (!(pml4[idx4] & PTE_PRESENT)) { if (!(pml4[idx4] & PTE_PRESENT)) {
u64 t = paging_alloc_table(); u64 t = paging_alloc_table();
if (!t) { log_error("[PAGING] alloc PDPT failed"); return -2; } if (!t) {
log_error("[PAGING] alloc PDPT failed");
panic_full("MM-E01 PDPT ALLOC FAILED",
"paging_map_mmio: PDPT page alloc failed", 0);
return -2;
}
pml4[idx4] = t | PTE_PRESENT | PTE_RW; pml4[idx4] = t | PTE_PRESENT | PTE_RW;
} }
@@ -100,7 +106,12 @@ static int paging_map_mmio_impl(u64 phys, u64 size) {
if (pdpt[idx3] & PTE_PS) { skipped++; continue; } /* 1G 大页已覆盖 */ if (pdpt[idx3] & PTE_PS) { skipped++; continue; } /* 1G 大页已覆盖 */
} else { } else {
u64 t = paging_alloc_table(); u64 t = paging_alloc_table();
if (!t) { log_error("[PAGING] alloc PD failed"); return -3; } if (!t) {
log_error("[PAGING] alloc PD failed");
panic_full("MM-E02 PD ALLOC FAILED",
"paging_map_mmio: PD page alloc failed", 0);
return -3;
}
pdpt[idx3] = t | PTE_PRESENT | PTE_RW; pdpt[idx3] = t | PTE_PRESENT | PTE_RW;
} }
@@ -110,7 +121,12 @@ static int paging_map_mmio_impl(u64 phys, u64 size) {
if (pd[idx2] & PTE_PS) { skipped++; continue; } /* 2M 大页已覆盖 */ if (pd[idx2] & PTE_PS) { skipped++; continue; } /* 2M 大页已覆盖 */
} else { } else {
u64 t = paging_alloc_table(); u64 t = paging_alloc_table();
if (!t) { log_error("[PAGING] alloc PT failed"); return -4; } if (!t) {
log_error("[PAGING] alloc PT failed");
panic_full("MM-E03 PT ALLOC FAILED",
"paging_map_mmio: PT page alloc failed", 0);
return -4;
}
pd[idx2] = t | PTE_PRESENT | PTE_RW; pd[idx2] = t | PTE_PRESENT | PTE_RW;
} }
+9
View File
@@ -0,0 +1,9 @@
mm/paging.o: mm\paging.c include\utsm\paging.h include\utsm\types.h \
include\utsm\dma.h include\utsm\log.h include\utsm\panic.h \
mm\..\arch\x86_64\limine.h
include\utsm\paging.h:
include\utsm\types.h:
include\utsm\dma.h:
include\utsm\log.h:
include\utsm\panic.h:
mm\..\arch\x86_64\limine.h:
+13
View File
@@ -18,6 +18,7 @@
#include <utsm/log.h> #include <utsm/log.h>
#include <utsm/types.h> #include <utsm/types.h>
#include <utsm/pe.h> #include <utsm/pe.h>
#include <utsm/panic.h>
/* ---- PE 导出目录结构(packed,与 pe_loader.h 风格一致) ---- */ /* ---- PE 导出目录结构(packed,与 pe_loader.h 风格一致) ---- */
typedef struct __attribute__((packed)) { typedef struct __attribute__((packed)) {
@@ -263,6 +264,8 @@ static u64 resolve_export_by_name(u64 image_base, u32 export_dir_rva,
static u64 resolve_forwarded_export(u64 image_base, u32 func_rva, int depth) { static u64 resolve_forwarded_export(u64 image_base, u32 func_rva, int depth) {
if (depth > PE_DLL_FWD_DEPTH_MAX) { if (depth > PE_DLL_FWD_DEPTH_MAX) {
log_warn("[PE] forwarded export chain too deep"); log_warn("[PE] forwarded export chain too deep");
panic_full("PE-E20 FORWARD CHAIN TOO DEEP",
"resolve_forwarded_export: forwarded export chain too deep", 0);
return 0; return 0;
} }
const char *fwd = (const char *)(image_base + func_rva); const char *fwd = (const char *)(image_base + func_rva);
@@ -280,6 +283,8 @@ static u64 resolve_forwarded_export(u64 image_base, u32 func_rva, int depth) {
while (buf[dot] && buf[dot] != '.') dot++; while (buf[dot] && buf[dot] != '.') dot++;
if (buf[dot] != '.' || dot == 0 || buf[dot + 1] == 0) { if (buf[dot] != '.' || dot == 0 || buf[dot + 1] == 0) {
log_warn("[PE] malformed forwarder string"); log_warn("[PE] malformed forwarder string");
panic_full("PE-E21 MALFORMED FORWARDER STRING",
"resolve_forwarded_export: malformed forwarder string", 0);
return 0; return 0;
} }
buf[dot] = 0; buf[dot] = 0;
@@ -318,6 +323,8 @@ static u64 resolve_forwarded_export(u64 image_base, u32 func_rva, int depth) {
u64 addr = resolve_export_by_ordinal(base, g_dll_cache[idx].export_dir_rva, ord); u64 addr = resolve_export_by_ordinal(base, g_dll_cache[idx].export_dir_rva, ord);
if (addr == 0) { if (addr == 0) {
log_warn("[PE] ordinal forward target not found"); log_warn("[PE] ordinal forward target not found");
panic_full("PE-E22 ORDINAL FORWARD NOT FOUND",
"resolve_forwarded_export: ordinal forward target missing", 0);
} }
return addr; return addr;
} }
@@ -368,6 +375,8 @@ int pe_dll_load(const char *dll_name, u64 *out_base) {
idx = dll_cache_alloc(); idx = dll_cache_alloc();
if (idx < 0) { if (idx < 0) {
log_warn("[PE] DLL cache full, cannot load"); log_warn("[PE] DLL cache full, cannot load");
panic_full("PE-E23 DLL CACHE FULL",
"pe_dll_load: DLL cache exhausted", 0);
if (out_base) *out_base = 0; if (out_base) *out_base = 0;
return -2; return -2;
} }
@@ -402,6 +411,8 @@ int pe_dll_load(const char *dll_name, u64 *out_base) {
if (pe_load_image(file_copy, file_size, &info) != 0) { if (pe_load_image(file_copy, file_size, &info) != 0) {
log_warn("[PE] DLL load failed: pe_load_image error"); log_warn("[PE] DLL load failed: pe_load_image error");
log_info(dll_name); log_info(dll_name);
panic_full("PE-E24 DLL IMAGE LOAD FAILED",
"pe_dll_load: pe_load_image failed for DLL", 0);
entry->state = DLL_STATE_NONE; entry->state = DLL_STATE_NONE;
if (out_base) *out_base = 0; if (out_base) *out_base = 0;
return -5; return -5;
@@ -436,6 +447,8 @@ int pe_dll_load(const char *dll_name, u64 *out_base) {
log_info("[PE] DllMain deferred"); log_info("[PE] DllMain deferred");
} else { } else {
log_warn("[PE] DllMain pending queue full, skipped"); log_warn("[PE] DllMain pending queue full, skipped");
panic_full("PE-E25 DLLMAIN PENDING QUEUE FULL",
"pe_dll_load: DllMain pending queue full", 0);
} }
} else { } else {
typedef int (__attribute__((ms_abi)) *dllmain_fn)(u64, u32, u64); typedef int (__attribute__((ms_abi)) *dllmain_fn)(u64, u32, u64);
+2 -1
View File
@@ -1,6 +1,6 @@
pe/pe_dll_manager.o: pe\pe_dll_manager.c pe\pe_dll_manager.h \ pe/pe_dll_manager.o: pe\pe_dll_manager.c pe\pe_dll_manager.h \
include\utsm\types.h pe\pe_loader.h include\utsm\pe.h pe\pe_shim.h \ include\utsm\types.h pe\pe_loader.h include\utsm\pe.h pe\pe_shim.h \
include\utsm\arena.h include\utsm\log.h include\utsm\arena.h include\utsm\log.h include\utsm\panic.h
pe\pe_dll_manager.h: pe\pe_dll_manager.h:
include\utsm\types.h: include\utsm\types.h:
pe\pe_loader.h: pe\pe_loader.h:
@@ -8,3 +8,4 @@ include\utsm\pe.h:
pe\pe_shim.h: pe\pe_shim.h:
include\utsm\arena.h: include\utsm\arena.h:
include\utsm\log.h: include\utsm\log.h:
include\utsm\panic.h:
+13
View File
@@ -21,6 +21,7 @@
#include <utsm/idt.h> #include <utsm/idt.h>
#include <utsm/log.h> #include <utsm/log.h>
#include <utsm/types.h> #include <utsm/types.h>
#include <utsm/panic.h>
/* 32位 PE 用的栈与堆 */ /* 32位 PE 用的栈与堆 */
#define PE32_STACK_SIZE (64 * 1024) /* 64KB 栈 */ #define PE32_STACK_SIZE (64 * 1024) /* 64KB 栈 */
@@ -293,6 +294,8 @@ int pe_service_run(const void *pe_data, u64 size, const char *cmdline, u64 *exit
if (rc != 0) { if (rc != 0) {
pe_dll_defer_dllmain(0); pe_dll_defer_dllmain(0);
log_error("[PE] PE32+ load failed"); log_error("[PE] PE32+ load failed");
panic_full("PE-E10 PE32+ LOAD FAILED",
"pe_service_run: PE32+ image load failed", 0);
return -5; return -5;
} }
log_info("[PE] running PE32+ natively"); log_info("[PE] running PE32+ natively");
@@ -307,6 +310,8 @@ int pe_service_run(const void *pe_data, u64 size, const char *cmdline, u64 *exit
u8 *pe_stack = (u8 *)kmem_alloc_aligned(PE_STACK_BYTES, 4096); u8 *pe_stack = (u8 *)kmem_alloc_aligned(PE_STACK_BYTES, 4096);
if (!pe_stack) { if (!pe_stack) {
log_error("[PE] stack alloc failed"); log_error("[PE] stack alloc failed");
panic_full("PE-E11 PE STACK ALLOC FAILED",
"pe_service_run: 1MB PE stack allocation failed", 0);
return -9; return -9;
} }
u64 stack_top = (u64)pe_stack + PE_STACK_BYTES; /* 4096 对齐 -> 16 对齐 */ u64 stack_top = (u64)pe_stack + PE_STACK_BYTES; /* 4096 对齐 -> 16 对齐 */
@@ -339,6 +344,8 @@ int pe_service_run(const void *pe_data, u64 size, const char *cmdline, u64 *exit
if (rc != 0) { if (rc != 0) {
log_error("[PE] PE32 interp load failed"); log_error("[PE] PE32 interp load failed");
log_hex64("[PE] rc=", (u64)(i64)rc); log_hex64("[PE] rc=", (u64)(i64)rc);
panic_full("PE-E12 PE32 INTERP LOAD FAILED",
"pe_service_run: PE32 interpreter load failed", 0);
return -6; return -6;
} }
log_info("[PE] running PE32 via x86emu32"); log_info("[PE] running PE32 via x86emu32");
@@ -351,6 +358,8 @@ int pe_service_run(const void *pe_data, u64 size, const char *cmdline, u64 *exit
img.iat, img.iat_count, stack_top); img.iat, img.iat_count, stack_top);
if (irc != 0) { if (irc != 0) {
log_error("[PE32] emu init failed"); log_error("[PE32] emu init failed");
panic_full("PE-E13 EMU INIT FAILED",
"pe_service_run: x86emu32 init failed", 0);
return -7; return -7;
} }
emu.eip = img.entry_point; emu.eip = img.entry_point;
@@ -367,12 +376,16 @@ int pe_service_run(const void *pe_data, u64 size, const char *cmdline, u64 *exit
int rrc = x86emu32_run(&emu, &code); int rrc = x86emu32_run(&emu, &code);
if (rrc != 0) { if (rrc != 0) {
log_error("[PE32] emulator error"); log_error("[PE32] emulator error");
panic_full("PE-E14 EMULATOR ERROR",
"pe_service_run: x86emu32_run returned error", 0);
code = 0xFFFFFFFFULL; code = 0xFFFFFFFFULL;
} }
/* emu 字段只在未发生 longjmp 的正常返回路径读取 /* emu 字段只在未发生 longjmp 的正常返回路径读取
* (setjmp 语义:longjmp 后被修改的自动变量值不确定) */ * (setjmp 语义:longjmp 后被修改的自动变量值不确定) */
if (emu.error && !emu.exited) { if (emu.error && !emu.exited) {
log_warn("[PE32] emulator stopped with error"); log_warn("[PE32] emulator stopped with error");
panic_full("PE-E15 EMULATOR STOPPED WITH ERROR",
"pe_service_run: emulator stopped in error state", 0);
} }
} else { } else {
code = pe_shim_get_exit_code(); code = pe_shim_get_exit_code();
+15
View File
@@ -0,0 +1,15 @@
pe/pe_service.o: pe\pe_service.c pe\pe_loader.h include\utsm\types.h \
include\utsm\pe.h pe\pe_shim.h pe\pe_dll_manager.h pe\x86emu32.h \
pe\..\include\utsm\pe.h include\utsm\arena.h include\utsm\idt.h \
include\utsm\log.h include\utsm\panic.h
pe\pe_loader.h:
include\utsm\types.h:
include\utsm\pe.h:
pe\pe_shim.h:
pe\pe_dll_manager.h:
pe\x86emu32.h:
pe\..\include\utsm\pe.h:
include\utsm\arena.h:
include\utsm\idt.h:
include\utsm\log.h:
include\utsm\panic.h:
+4
View File
@@ -546,12 +546,16 @@ int utsm_sched_enable(u32 tick_hz) {
if (lapic_timer_init(tick_hz) != 0) { if (lapic_timer_init(tick_hz) != 0) {
log_error("[SCHED] lapic timer init failed, stays cooperative"); log_error("[SCHED] lapic timer init failed, stays cooperative");
panic_full("SAS-E04 LAPIC TIMER INIT FAILED",
"utsm_sched_enable: lapic_timer_init failed", 0);
return -1; return -1;
} }
int vec = lapic_timer_vector(); int vec = lapic_timer_vector();
if (vec < 0 || irq_register((u8)vec, utsm_tick_handler) != 0) { if (vec < 0 || irq_register((u8)vec, utsm_tick_handler) != 0) {
lapic_timer_stop(); lapic_timer_stop();
log_error("[SCHED] tick handler registration failed"); log_error("[SCHED] tick handler registration failed");
panic_full("SAS-E05 TICK HANDLER REGISTER FAILED",
"utsm_sched_enable: tick handler registration failed", 0);
return -2; return -2;
} }
idt_set_exception_hook(utsm_sched_exc_hook); idt_set_exception_hook(utsm_sched_exc_hook);
+70 -1
View File
@@ -8,6 +8,7 @@
#include <utsm/arena.h> #include <utsm/arena.h>
#include <utsm/drr.h> #include <utsm/drr.h>
#include <utsm/sched_ext.h> #include <utsm/sched_ext.h>
#include <utsm/panic.h>
int memcmp(const void *a, const void *b, usize len); int memcmp(const void *a, const void *b, usize len);
usize strlen(const char *s); usize strlen(const char *s);
@@ -33,6 +34,8 @@ int utsm_selftest_run(void) {
utsm_process_context *process = (utsm_process_context *)kmem_alloc(sizeof(utsm_process_context)); utsm_process_context *process = (utsm_process_context *)kmem_alloc(sizeof(utsm_process_context));
if (!process) { if (!process) {
log_error("[UTSM] selftest: failed to allocate process context"); log_error("[UTSM] selftest: failed to allocate process context");
panic_full("TST-E01 SELFTEST CTX ALLOC FAILED",
"utsm_selftest: process context allocation failed", 0);
return UTSM_ERR_NO_MEMORY; return UTSM_ERR_NO_MEMORY;
} }
utsm_process_create_test(process, 1); utsm_process_create_test(process, 1);
@@ -41,6 +44,8 @@ int utsm_selftest_run(void) {
int status = utsm_create_segment(process, UTSM_PAGE_SIZE, UTSM_SEG_F_READ | UTSM_SEG_F_WRITE | UTSM_SEG_F_STRONG_RECOVERY, &cap); int status = utsm_create_segment(process, UTSM_PAGE_SIZE, UTSM_SEG_F_READ | UTSM_SEG_F_WRITE | UTSM_SEG_F_STRONG_RECOVERY, &cap);
if (status != UTSM_OK) { if (status != UTSM_OK) {
log_error("[UTSM] selftest create segment failed"); log_error("[UTSM] selftest create segment failed");
panic_full("TST-E02 SELFTEST CREATE SEGMENT FAILED",
"utsm_selftest: create segment failed", 0);
return status; return status;
} }
@@ -49,16 +54,22 @@ int utsm_selftest_run(void) {
status = utsm_write(cap, 128, message, len); status = utsm_write(cap, 128, message, len);
if (status != UTSM_OK) { if (status != UTSM_OK) {
log_error("[UTSM] selftest write failed"); log_error("[UTSM] selftest write failed");
panic_full("TST-E03 SELFTEST WRITE FAILED",
"utsm_selftest: sealed write failed", 0);
return status; return status;
} }
log_info("[UTSM] selftest write ok"); log_info("[UTSM] selftest write ok");
utsm_segment_desc *desc = utsm_get_segment(cap.segment_slot); utsm_segment_desc *desc = utsm_get_segment(cap.segment_slot);
if (!desc) { if (!desc) {
panic_full("TST-E04 SELFTEST SEG DESC MISSING",
"utsm_selftest: segment desc lookup failed", 0);
return UTSM_ERR_INVALID; return UTSM_ERR_INVALID;
} }
if (memcmp(desc->cipher_base + 128, message, len) == 0) { if (memcmp(desc->cipher_base + 128, message, len) == 0) {
log_error("[UTSM] raw cipher equals plaintext"); log_error("[UTSM] raw cipher equals plaintext");
panic_full("TST-E05 SELFTEST CIPHER PLAINTEXT LEAK",
"utsm_selftest: raw cipher equals plaintext", 0);
return UTSM_ERR_INVALID; return UTSM_ERR_INVALID;
} }
log_info("[UTSM] raw cipher check ok"); log_info("[UTSM] raw cipher check ok");
@@ -67,10 +78,14 @@ int utsm_selftest_run(void) {
status = utsm_read(cap, 128, readback, len); status = utsm_read(cap, 128, readback, len);
if (status != UTSM_OK) { if (status != UTSM_OK) {
log_error("[UTSM] selftest read failed"); log_error("[UTSM] selftest read failed");
panic_full("TST-E06 SELFTEST READ FAILED",
"utsm_selftest: sealed read failed", 0);
return status; return status;
} }
if (memcmp(readback, message, len) != 0) { if (memcmp(readback, message, len) != 0) {
log_error("[UTSM] selftest read mismatch"); log_error("[UTSM] selftest read mismatch");
panic_full("TST-E07 SELFTEST READ MISMATCH",
"utsm_selftest: readback mismatch", 0);
return UTSM_ERR_INVALID; return UTSM_ERR_INVALID;
} }
log_info("[UTSM] selftest read ok"); log_info("[UTSM] selftest read ok");
@@ -86,6 +101,8 @@ int utsm_selftest_run(void) {
utsm_chacha20_block(kat_key, kat_nonce, kat_counter, ks); utsm_chacha20_block(kat_key, kat_nonce, kat_counter, ks);
if (memcmp(ks, kat_expect, 64) != 0) { if (memcmp(ks, kat_expect, 64) != 0) {
log_error("[UTSM] selftest chacha20 KAT FAIL (RFC 8439 §2.4.2)"); log_error("[UTSM] selftest chacha20 KAT FAIL (RFC 8439 §2.4.2)");
panic_full("TST-E08 CHACHA20 KAT FAIL",
"utsm_selftest: chacha20 KAT mismatch (RFC 8439 2.4.2)", 0);
return UTSM_ERR_INVALID; return UTSM_ERR_INVALID;
} }
log_info("[UTSM] selftest chacha20 KAT ok (RFC 8439 §2.4.2)"); log_info("[UTSM] selftest chacha20 KAT ok (RFC 8439 §2.4.2)");
@@ -97,6 +114,8 @@ int utsm_selftest_run(void) {
u64 m3 = utsm_page_mac(rk, 0, 1, 0, desc->cipher_base); u64 m3 = utsm_page_mac(rk, 0, 1, 0, desc->cipher_base);
if (m1 != m2 || m1 == m3) { if (m1 != m2 || m1 == m3) {
log_error("[UTSM] selftest page MAC determinism FAIL"); log_error("[UTSM] selftest page MAC determinism FAIL");
panic_full("TST-E09 PAGE MAC DETERMINISM FAIL",
"utsm_selftest: page MAC determinism broken", 0);
return UTSM_ERR_INVALID; return UTSM_ERR_INVALID;
} }
log_info("[UTSM] selftest page MAC determinism ok"); log_info("[UTSM] selftest page MAC determinism ok");
@@ -114,6 +133,8 @@ int utsm_selftest_run(void) {
int dst = utrw_debug_dump_page(cap.segment_slot, 0, 128); int dst = utrw_debug_dump_page(cap.segment_slot, 0, 128);
if (dst != UTSM_OK) { if (dst != UTSM_OK) {
log_error("[UTSM] selftest cipher dump failed"); log_error("[UTSM] selftest cipher dump failed");
panic_full("TST-E10 SELFTEST CIPHER DUMP FAILED",
"utsm_selftest: cipher page dump failed", 0);
return dst; return dst;
} }
} }
@@ -129,12 +150,16 @@ int utsm_selftest_run(void) {
UTSM_ERR_EPOCH, &refreshed); UTSM_ERR_EPOCH, &refreshed);
if (status != UTSM_OK) { if (status != UTSM_OK) {
log_error("[UTSM] selftest slow EPOCH recover failed"); log_error("[UTSM] selftest slow EPOCH recover failed");
panic_full("TST-E11 SLOW EPOCH RECOVER FAILED",
"utsm_selftest: slow path EPOCH recovery failed", 0);
return status; return status;
} }
char slow_rb[64]; char slow_rb[64];
status = utsm_read(refreshed, 128, slow_rb, len); status = utsm_read(refreshed, 128, slow_rb, len);
if (status != UTSM_OK || memcmp(slow_rb, message, len) != 0) { if (status != UTSM_OK || memcmp(slow_rb, message, len) != 0) {
log_error("[UTSM] selftest slow EPOCH retry read failed"); log_error("[UTSM] selftest slow EPOCH retry read failed");
panic_full("TST-E12 SLOW EPOCH RETRY FAILED",
"utsm_selftest: read after EPOCH refresh failed", 0);
return (status == UTSM_OK) ? UTSM_ERR_INVALID : status; return (status == UTSM_OK) ? UTSM_ERR_INVALID : status;
} }
log_info("[UTSM] selftest slow EPOCH ok"); log_info("[UTSM] selftest slow EPOCH ok");
@@ -145,11 +170,15 @@ int utsm_selftest_run(void) {
UTSM_ERR_KEY_MISS, 0); UTSM_ERR_KEY_MISS, 0);
if (status != UTSM_OK) { if (status != UTSM_OK) {
log_error("[UTSM] selftest slow KEY_MISS recover failed"); log_error("[UTSM] selftest slow KEY_MISS recover failed");
panic_full("TST-E13 SLOW KEY_MISS RECOVER FAILED",
"utsm_selftest: slow path KEY_MISS re-derive failed", 0);
return status; return status;
} }
status = utsm_read(refreshed, 128, slow_rb, len); status = utsm_read(refreshed, 128, slow_rb, len);
if (status != UTSM_OK || memcmp(slow_rb, message, len) != 0) { if (status != UTSM_OK || memcmp(slow_rb, message, len) != 0) {
log_error("[UTSM] selftest slow KEY_MISS retry read failed"); log_error("[UTSM] selftest slow KEY_MISS retry read failed");
panic_full("TST-E14 SLOW KEY_MISS RETRY FAILED",
"utsm_selftest: read after KEY_MISS re-derive failed", 0);
return (status == UTSM_OK) ? UTSM_ERR_INVALID : status; return (status == UTSM_OK) ? UTSM_ERR_INVALID : status;
} }
log_info("[UTSM] selftest slow KEY_MISS ok"); log_info("[UTSM] selftest slow KEY_MISS ok");
@@ -160,6 +189,8 @@ int utsm_selftest_run(void) {
UTSM_ERR_POISONED, 0); UTSM_ERR_POISONED, 0);
if (status != UTSM_ERR_POISONED) { if (status != UTSM_ERR_POISONED) {
log_error("[UTSM] selftest slow POISONED passthrough failed"); log_error("[UTSM] selftest slow POISONED passthrough failed");
panic_full("TST-E15 SLOW POISONED PASSTHROUGH FAILED",
"utsm_selftest: POISONED not passed through", 0);
return UTSM_ERR_INVALID; return UTSM_ERR_INVALID;
} }
log_info("[UTSM] selftest slow POISONED ok"); log_info("[UTSM] selftest slow POISONED ok");
@@ -174,6 +205,8 @@ int utsm_selftest_run(void) {
&ucap); &ucap);
if (status != UTSM_OK) { if (status != UTSM_OK) {
log_error("[UTSM] selftest unsealed segment create failed"); log_error("[UTSM] selftest unsealed segment create failed");
panic_full("TST-E16 UNSEALED SEGMENT CREATE FAILED",
"utsm_selftest: unsealed segment create failed", 0);
return status; return status;
} }
const char *upl = "unsealed plain text 00"; const char *upl = "unsealed plain text 00";
@@ -181,19 +214,29 @@ int utsm_selftest_run(void) {
status = utsm_write(ucap, 128, upl, ulen); status = utsm_write(ucap, 128, upl, ulen);
if (status != UTSM_OK) { if (status != UTSM_OK) {
log_error("[UTSM] selftest unsealed write failed"); log_error("[UTSM] selftest unsealed write failed");
panic_full("TST-E17 UNSEALED WRITE FAILED",
"utsm_selftest: unsealed plain write failed", 0);
return status; return status;
} }
utsm_segment_desc *udesc = utsm_get_segment(ucap.segment_slot); utsm_segment_desc *udesc = utsm_get_segment(ucap.segment_slot);
if (!udesc) return UTSM_ERR_INVALID; if (!udesc) {
panic_full("TST-E18 UNSEALED DESC MISSING",
"utsm_selftest: unsealed segment desc lookup failed", 0);
return UTSM_ERR_INVALID;
}
/* 明文直存:存储区内容必须与明文完全一致(0 开销的可观察证据) */ /* 明文直存:存储区内容必须与明文完全一致(0 开销的可观察证据) */
if (memcmp(udesc->cipher_base + 128, upl, ulen) != 0) { if (memcmp(udesc->cipher_base + 128, upl, ulen) != 0) {
log_error("[UTSM] selftest unsealed store not plaintext"); log_error("[UTSM] selftest unsealed store not plaintext");
panic_full("TST-E19 UNSEALED STORE NOT PLAINTEXT",
"utsm_selftest: unsealed storage differs from plaintext", 0);
return UTSM_ERR_INVALID; return UTSM_ERR_INVALID;
} }
char urb[64]; char urb[64];
status = utsm_read(ucap, 128, urb, ulen); status = utsm_read(ucap, 128, urb, ulen);
if (status != UTSM_OK || memcmp(urb, upl, ulen) != 0) { if (status != UTSM_OK || memcmp(urb, upl, ulen) != 0) {
log_error("[UTSM] selftest unsealed read failed"); log_error("[UTSM] selftest unsealed read failed");
panic_full("TST-E20 UNSEALED READ FAILED",
"utsm_selftest: unsealed readback mismatch", 0);
return (status == UTSM_OK) ? UTSM_ERR_INVALID : status; return (status == UTSM_OK) ? UTSM_ERR_INVALID : status;
} }
log_info("[UTSM] selftest unsealed segment ok (plain storage)"); log_info("[UTSM] selftest unsealed segment ok (plain storage)");
@@ -204,27 +247,37 @@ int utsm_selftest_run(void) {
const dkm_kernel_api *api = dkm_get_kernel_api(); const dkm_kernel_api *api = dkm_get_kernel_api();
if (!api->kapi || api->kapi->magic != DKM_KAPI_MAGIC) { if (!api->kapi || api->kapi->magic != DKM_KAPI_MAGIC) {
log_error("[UTSM] selftest kapi table missing"); log_error("[UTSM] selftest kapi table missing");
panic_full("TST-E21 KAPI TABLE MISSING",
"utsm_selftest: kapi export table missing or bad magic", 0);
return UTSM_ERR_INVALID; return UTSM_ERR_INVALID;
} }
void *fn = 0; void *fn = 0;
if (api->kapi->lookup("log.info", &fn) != 0) { if (api->kapi->lookup("log.info", &fn) != 0) {
log_error("[UTSM] selftest kapi lookup log.info failed"); log_error("[UTSM] selftest kapi lookup log.info failed");
panic_full("TST-E22 KAPI LOOKUP LOG FAILED",
"utsm_selftest: kapi lookup log.info failed", 0);
return UTSM_ERR_INVALID; return UTSM_ERR_INVALID;
} }
void (*klog)(const char *) = (void (*)(const char *))fn; void (*klog)(const char *) = (void (*)(const char *))fn;
klog("[UTSM] selftest kapi: log.info via export table"); klog("[UTSM] selftest kapi: log.info via export table");
if (api->kapi->lookup("dma.alloc_pages", &fn) != 0) { if (api->kapi->lookup("dma.alloc_pages", &fn) != 0) {
log_error("[UTSM] selftest kapi lookup dma failed"); log_error("[UTSM] selftest kapi lookup dma failed");
panic_full("TST-E23 KAPI LOOKUP DMA FAILED",
"utsm_selftest: kapi lookup dma.alloc_pages failed", 0);
return UTSM_ERR_INVALID; return UTSM_ERR_INVALID;
} }
int (*kalloc)(u64, u64, u64, dkm_dma_buffer *) = (int (*)(u64, u64, u64, dkm_dma_buffer *))fn; int (*kalloc)(u64, u64, u64, dkm_dma_buffer *) = (int (*)(u64, u64, u64, dkm_dma_buffer *))fn;
dkm_dma_buffer kbuf; dkm_dma_buffer kbuf;
if (kalloc(1, 4096, 0xFFFFFFFFULL, &kbuf) != 0 || !kbuf.virt) { if (kalloc(1, 4096, 0xFFFFFFFFULL, &kbuf) != 0 || !kbuf.virt) {
log_error("[UTSM] selftest kapi dma alloc failed"); log_error("[UTSM] selftest kapi dma alloc failed");
panic_full("TST-E24 KAPI DMA ALLOC FAILED",
"utsm_selftest: kapi dma.alloc_pages call failed", 0);
return UTSM_ERR_INVALID; return UTSM_ERR_INVALID;
} }
if (api->kapi->lookup("no.such.service", &fn) == 0) { if (api->kapi->lookup("no.such.service", &fn) == 0) {
log_error("[UTSM] selftest kapi negative lookup failed"); log_error("[UTSM] selftest kapi negative lookup failed");
panic_full("TST-E25 KAPI NEGATIVE LOOKUP FAILED",
"utsm_selftest: negative lookup unexpectedly succeeded", 0);
return UTSM_ERR_INVALID; return UTSM_ERR_INVALID;
} }
log_hex64("[UTSM] selftest kapi entries=", api->kapi->count); log_hex64("[UTSM] selftest kapi entries=", api->kapi->count);
@@ -240,11 +293,15 @@ int utsm_selftest_run(void) {
selftest_irq_restore(st_flags); selftest_irq_restore(st_flags);
if (rq_rc != 0) { if (rq_rc != 0) {
log_error("[SCHED] selftest: runqueue O(1) FAIL"); log_error("[SCHED] selftest: runqueue O(1) FAIL");
panic_full("TST-E26 RUNQUEUE SELFTEST FAIL",
"utsm_selftest: O(1) runqueue semantics broken", 0);
return UTSM_ERR_INVALID; return UTSM_ERR_INVALID;
} }
log_info("[SCHED] selftest: runqueue O(1) PASS"); log_info("[SCHED] selftest: runqueue O(1) PASS");
if (bw_rc != 0) { if (bw_rc != 0) {
log_error("[SCHED] selftest: block/wake FAIL"); log_error("[SCHED] selftest: block/wake FAIL");
panic_full("TST-E27 BLOCKWAKE SELFTEST FAIL",
"utsm_selftest: block/wake semantics broken", 0);
return UTSM_ERR_INVALID; return UTSM_ERR_INVALID;
} }
log_info("[SCHED] selftest: block/wake PASS"); log_info("[SCHED] selftest: block/wake PASS");
@@ -259,34 +316,46 @@ int utsm_selftest_run(void) {
status = utsm_write(cap, 512, p1, plen); status = utsm_write(cap, 512, p1, plen);
if (status != UTSM_OK) { if (status != UTSM_OK) {
log_error("[DRR] selftest P1 write failed"); log_error("[DRR] selftest P1 write failed");
panic_full("TST-E28 DRR P1 WRITE FAILED",
"utsm_selftest: DRR pre-snapshot write failed", 0);
return status; return status;
} }
int snap = drr_ckpt_snapshot_dirty(); int snap = drr_ckpt_snapshot_dirty();
log_hex64("[DRR] ckpt snapshot pages=", (u64)(i64)snap); log_hex64("[DRR] ckpt snapshot pages=", (u64)(i64)snap);
if (snap < 1) { if (snap < 1) {
log_error("[DRR] selftest snapshot failed"); log_error("[DRR] selftest snapshot failed");
panic_full("TST-E29 DRR SNAPSHOT FAILED",
"utsm_selftest: dirty page snapshot failed", 0);
return UTSM_ERR_INVALID; return UTSM_ERR_INVALID;
} }
drr_checkpoint_meta meta; drr_checkpoint_meta meta;
if (drr_checkpoint_recover(&meta) != 0 || meta.type != DRR_CKPT_DIRTY_PAGE || if (drr_checkpoint_recover(&meta) != 0 || meta.type != DRR_CKPT_DIRTY_PAGE ||
meta.dirty_page_count < 1) { meta.dirty_page_count < 1) {
log_error("[DRR] selftest meta verify failed"); log_error("[DRR] selftest meta verify failed");
panic_full("TST-E30 DRR META VERIFY FAILED",
"utsm_selftest: checkpoint meta verify failed", 0);
return UTSM_ERR_INVALID; return UTSM_ERR_INVALID;
} }
status = utsm_write(cap, 512, p2, plen); status = utsm_write(cap, 512, p2, plen);
if (status != UTSM_OK) { if (status != UTSM_OK) {
log_error("[DRR] selftest P2 write failed"); log_error("[DRR] selftest P2 write failed");
panic_full("TST-E31 DRR P2 WRITE FAILED",
"utsm_selftest: DRR overwrite write failed", 0);
return status; return status;
} }
int rb = drr_rollback_pages(); int rb = drr_rollback_pages();
log_hex64("[DRR] rollback pages=", (u64)(i64)rb); log_hex64("[DRR] rollback pages=", (u64)(i64)rb);
if (rb < 1) { if (rb < 1) {
log_error("[DRR] selftest rollback failed"); log_error("[DRR] selftest rollback failed");
panic_full("TST-E32 DRR ROLLBACK FAILED",
"utsm_selftest: page rollback failed", 0);
return UTSM_ERR_INVALID; return UTSM_ERR_INVALID;
} }
status = utsm_read(cap, 512, readback, plen); status = utsm_read(cap, 512, readback, plen);
if (status != UTSM_OK || memcmp(readback, p1, plen) != 0) { if (status != UTSM_OK || memcmp(readback, p1, plen) != 0) {
log_error("[DRR] rollback verify FAIL"); log_error("[DRR] rollback verify FAIL");
panic_full("TST-E33 DRR ROLLBACK VERIFY FAIL",
"utsm_selftest: rollback verify mismatch", 0);
return UTSM_ERR_INVALID; return UTSM_ERR_INVALID;
} }
log_info("[DRR] rollback verify ok"); log_info("[DRR] rollback verify ok");
+3 -1
View File
@@ -7,7 +7,8 @@ test/utsm_selftest.o: test\utsm_selftest.c include\utsm\utsm.h \
include\utsm\crypto.h include\utsm\dma.h include\utsm\dkm.h \ include\utsm\crypto.h include\utsm\dma.h include\utsm\dkm.h \
include\utsm\block.h include\utsm\net.h include\utsm\paging.h \ include\utsm\block.h include\utsm\net.h include\utsm\paging.h \
include\utsm\log.h include\utsm\arena.h include\utsm\drr.h \ include\utsm\log.h include\utsm\arena.h include\utsm\drr.h \
include\utsm\sched_ext.h include\utsm\sched.h test\chacha_kat.inc include\utsm\sched_ext.h include\utsm\sched.h include\utsm\panic.h \
test\chacha_kat.inc
include\utsm\utsm.h: include\utsm\utsm.h:
include\utsm\types.h: include\utsm\types.h:
include\utsm\status.h: include\utsm\status.h:
@@ -35,4 +36,5 @@ include\utsm\arena.h:
include\utsm\drr.h: include\utsm\drr.h:
include\utsm\sched_ext.h: include\utsm\sched_ext.h:
include\utsm\sched.h: include\utsm\sched.h:
include\utsm\panic.h:
test\chacha_kat.inc: test\chacha_kat.inc:
Binary file not shown.
+3
View File
@@ -3,6 +3,7 @@
#include <utsm/pckc.h> #include <utsm/pckc.h>
#include <utsm/crypto.h> #include <utsm/crypto.h>
#include <utsm/log.h> #include <utsm/log.h>
#include <utsm/panic.h>
void *memcpy(void *dst, const void *src, usize len); void *memcpy(void *dst, const void *src, usize len);
@@ -66,6 +67,8 @@ int utrw_debug_dump_page(u32 segment_slot, u64 page_index, u64 offset_in_page) {
int st = utsm_pckc_get_or_derive(segment_slot, desc, &key); int st = utsm_pckc_get_or_derive(segment_slot, desc, &key);
if (st != UTSM_OK) { if (st != UTSM_OK) {
log_warn("[UTRW] dump: key derive failed"); log_warn("[UTRW] dump: key derive failed");
panic_full("UTRW-E10 DUMP KEY DERIVE FAILED",
"utrw_debug_dump_page: PCKC key derivation failed", 0);
return st; return st;
} }
u64 dump_line = (page_off + offset_in_page) / UTSM_CACHE_LINE_SIZE; u64 dump_line = (page_off + offset_in_page) / UTSM_CACHE_LINE_SIZE;
+3 -1
View File
@@ -1,7 +1,8 @@
utrw/debug.o: utrw\debug.c include\utsm\utrw.h include\utsm\types.h \ utrw/debug.o: utrw\debug.c include\utsm\utrw.h include\utsm\types.h \
include\utsm\status.h include\utsm\capability.h include\utsm\segment.h \ include\utsm\status.h include\utsm\capability.h include\utsm\segment.h \
include\utsm\uuid.h include\utsm\dirty.h include\utsm\pckc.h \ include\utsm\uuid.h include\utsm\dirty.h include\utsm\pckc.h \
include\utsm\config.h include\utsm\crypto.h include\utsm\log.h include\utsm\config.h include\utsm\crypto.h include\utsm\log.h \
include\utsm\panic.h
include\utsm\utrw.h: include\utsm\utrw.h:
include\utsm\types.h: include\utsm\types.h:
include\utsm\status.h: include\utsm\status.h:
@@ -13,3 +14,4 @@ include\utsm\pckc.h:
include\utsm\config.h: include\utsm\config.h:
include\utsm\crypto.h: include\utsm\crypto.h:
include\utsm\log.h: include\utsm\log.h:
include\utsm\panic.h:
+3
View File
@@ -3,6 +3,7 @@
#include <utsm/pckc.h> #include <utsm/pckc.h>
#include <utsm/drr.h> #include <utsm/drr.h>
#include <utsm/log.h> #include <utsm/log.h>
#include <utsm/panic.h>
/* =================================================================== /* ===================================================================
* U2: UTRW Slow Path 真分支 * U2: UTRW Slow Path 真分支
@@ -53,6 +54,8 @@ int utsm_slow_path(utsm_capability cap, u32 rights, u64 offset, u64 len,
st = utsm_pckc_get_or_derive(cap.segment_slot, desc, &key); st = utsm_pckc_get_or_derive(cap.segment_slot, desc, &key);
if (st != UTSM_OK) { if (st != UTSM_OK) {
log_warn("[UTRW] slow: KEY_MISS re-derive failed"); log_warn("[UTRW] slow: KEY_MISS re-derive failed");
panic_full("UTRW-E01 KEY_MISS RE-DERIVE FAILED",
"utsm_slow_path: KEY_MISS key re-derivation failed", 0);
return st; return st;
} }
log_warn("[UTRW] slow: KEY_MISS -> key re-derived (retry)"); log_warn("[UTRW] slow: KEY_MISS -> key re-derived (retry)");
+2 -1
View File
@@ -2,7 +2,7 @@ utrw/slow_path.o: utrw\slow_path.c include\utsm\utrw.h \
include\utsm\types.h include\utsm\status.h include\utsm\capability.h \ include\utsm\types.h include\utsm\status.h include\utsm\capability.h \
include\utsm\segment.h include\utsm\uuid.h include\utsm\dirty.h \ include\utsm\segment.h include\utsm\uuid.h include\utsm\dirty.h \
include\utsm\pckc.h include\utsm\config.h include\utsm\crypto.h \ include\utsm\pckc.h include\utsm\config.h include\utsm\crypto.h \
include\utsm\drr.h include\utsm\log.h include\utsm\drr.h include\utsm\log.h include\utsm\panic.h
include\utsm\utrw.h: include\utsm\utrw.h:
include\utsm\types.h: include\utsm\types.h:
include\utsm\status.h: include\utsm\status.h:
@@ -15,3 +15,4 @@ include\utsm\config.h:
include\utsm\crypto.h: include\utsm\crypto.h:
include\utsm\drr.h: include\utsm\drr.h:
include\utsm\log.h: include\utsm\log.h:
include\utsm\panic.h:
Binary file not shown.
+5
View File
@@ -1,4 +1,5 @@
#include <utsm/ept.h> #include <utsm/ept.h>
#include <utsm/panic.h>
#include <utsm/vmx.h> #include <utsm/vmx.h>
#include <utsm/log.h> #include <utsm/log.h>
#include <utsm/types.h> #include <utsm/types.h>
@@ -41,6 +42,7 @@ static u64 ept_alloc_page(void) {
dkm_dma_buffer buf; dkm_dma_buffer buf;
if (dma_alloc_pages(1, EPT_PAGE_SIZE, 0x100000000ULL, &buf) != 0) { if (dma_alloc_pages(1, EPT_PAGE_SIZE, 0x100000000ULL, &buf) != 0) {
log_error("[EPT] alloc page failed"); log_error("[EPT] alloc page failed");
panic_full("EPT-E01 EPT PAGE ALLOC FAILED", "dma_alloc_pages failed for an ept page table page", 0);
return 0; return 0;
} }
/* dma_alloc_pages 已清零 */ /* dma_alloc_pages 已清零 */
@@ -51,6 +53,7 @@ int ept_init(void) {
g_ept_pml4_phys = ept_alloc_page(); g_ept_pml4_phys = ept_alloc_page();
if (g_ept_pml4_phys == 0) { if (g_ept_pml4_phys == 0) {
log_error("[EPT] failed to alloc PML4"); log_error("[EPT] failed to alloc PML4");
panic_full("EPT-E02 ALLOC PML4 FAILED", "ept root pml4 page allocation failed", 0);
return -1; return -1;
} }
g_ept_pml4_virt = (u64)phys_to_virt(g_ept_pml4_phys); g_ept_pml4_virt = (u64)phys_to_virt(g_ept_pml4_phys);
@@ -122,6 +125,7 @@ int ept_map_range(u64 gpa, u64 hpa, u64 size, u64 flags) {
if ((gpa & (EPT_PAGE_SIZE - 1)) || (hpa & (EPT_PAGE_SIZE - 1)) || if ((gpa & (EPT_PAGE_SIZE - 1)) || (hpa & (EPT_PAGE_SIZE - 1)) ||
(size & (EPT_PAGE_SIZE - 1))) { (size & (EPT_PAGE_SIZE - 1))) {
log_error("[EPT] unaligned map request"); log_error("[EPT] unaligned map request");
panic_full("EPT-E03 UNALIGNED MAP REQUEST", "ept map request got a non page aligned gpa hpa or size", 0);
return -2; return -2;
} }
@@ -132,6 +136,7 @@ int ept_map_range(u64 gpa, u64 hpa, u64 size, u64 flags) {
u64 *entry = ept_walk(cur_gpa, 1); u64 *entry = ept_walk(cur_gpa, 1);
if (!entry) { if (!entry) {
log_error("[EPT] walk failed"); log_error("[EPT] walk failed");
panic_full("EPT-E04 EPT WALK FAILED", "ept_walk could not allocate intermediate page tables", 0);
return -3; return -3;
} }
*entry = ept_make_leaf(cur_hpa, flags, EPT_MEMORY_TYPE_WB); *entry = ept_make_leaf(cur_hpa, flags, EPT_MEMORY_TYPE_WB);
+10
View File
@@ -0,0 +1,10 @@
vmm/ept.o: vmm\ept.c include\utsm\ept.h include\utsm\types.h \
include\utsm\panic.h include\utsm\vmx.h include\utsm\log.h \
include\utsm\dma.h vmm\..\arch\x86_64\limine.h
include\utsm\ept.h:
include\utsm\types.h:
include\utsm\panic.h:
include\utsm\vmx.h:
include\utsm\log.h:
include\utsm\dma.h:
vmm\..\arch\x86_64\limine.h:
+5
View File
@@ -14,6 +14,7 @@
*/ */
#include <utsm/ipc_shm.h> #include <utsm/ipc_shm.h>
#include <utsm/panic.h>
#include <utsm/vmx.h> #include <utsm/vmx.h>
#include <utsm/ept.h> #include <utsm/ept.h>
#include <utsm/log.h> #include <utsm/log.h>
@@ -48,6 +49,7 @@ int ipc_shm_init(void) {
u64 page_count = UTSM_IPC_SHM_SIZE / 4096; u64 page_count = UTSM_IPC_SHM_SIZE / 4096;
if (dma_alloc_pages(page_count, 4096, 0, &g_shm_buf) != 0) { if (dma_alloc_pages(page_count, 4096, 0, &g_shm_buf) != 0) {
log_error("[IPC] failed to alloc shared memory (1MB)"); log_error("[IPC] failed to alloc shared memory (1MB)");
panic_full("IPC-E01 ALLOC SHARED MEMORY FAILED", "dma_alloc_pages failed for the 1mb ipc shared memory region", 0);
return -1; return -1;
} }
log_hex64("[IPC] shm HPA=", g_shm_buf.phys); log_hex64("[IPC] shm HPA=", g_shm_buf.phys);
@@ -84,6 +86,7 @@ int ipc_shm_init(void) {
if (ept_map_range(LINUX_GUEST_IPC_SHM_GPA, g_shm_buf.phys, if (ept_map_range(LINUX_GUEST_IPC_SHM_GPA, g_shm_buf.phys,
UTSM_IPC_SHM_SIZE, EPT_READ | EPT_WRITE) != 0) { UTSM_IPC_SHM_SIZE, EPT_READ | EPT_WRITE) != 0) {
log_error("[IPC] EPT map shared memory failed"); log_error("[IPC] EPT map shared memory failed");
panic_full("IPC-E02 EPT MAP SHARED MEMORY FAILED", "ept_map_range failed for the ipc shared memory region", 0);
return -2; return -2;
} }
log_hex64("[IPC] shm mapped GPA=", LINUX_GUEST_IPC_SHM_GPA); log_hex64("[IPC] shm mapped GPA=", LINUX_GUEST_IPC_SHM_GPA);
@@ -143,6 +146,7 @@ int ipc_shm_send(u32 msg_type, const void *data, u32 data_len) {
/* Check if Linux is ready to receive */ /* Check if Linux is ready to receive */
if (!g_shm->header.linux_ready) { if (!g_shm->header.linux_ready) {
log_warn("[IPC] send: Linux not ready, dropping message"); log_warn("[IPC] send: Linux not ready, dropping message");
panic_full("IPC-E03 SEND WITH LINUX NOT READY", "message dropped because the linux side never became ready", 0);
return -1; return -1;
} }
@@ -169,6 +173,7 @@ int ipc_shm_send(u32 msg_type, const void *data, u32 data_len) {
/* Enqueue into utsm_to_linux ring */ /* Enqueue into utsm_to_linux ring */
if (utsm_ipc_ring_push(&g_shm->utsm_to_linux, &msg) != 0) { if (utsm_ipc_ring_push(&g_shm->utsm_to_linux, &msg) != 0) {
log_warn("[IPC] send: ring full, dropping message"); log_warn("[IPC] send: ring full, dropping message");
panic_full("IPC-E04 SEND RING FULL", "message dropped because the utsm to linux ring is full", 0);
return -1; return -1;
} }
+14
View File
@@ -0,0 +1,14 @@
vmm/ipc_shm.o: vmm\ipc_shm.c include\utsm\ipc_shm.h include\utsm\types.h \
..\utsm-ipc\ipc_proto.h include\utsm\panic.h include\utsm\vmx.h \
include\utsm\ept.h include\utsm\log.h include\utsm\dma.h \
include\utsm\linux_loader.h vmm\..\arch\x86_64\limine.h
include\utsm\ipc_shm.h:
include\utsm\types.h:
..\utsm-ipc\ipc_proto.h:
include\utsm\panic.h:
include\utsm\vmx.h:
include\utsm\ept.h:
include\utsm\log.h:
include\utsm\dma.h:
include\utsm\linux_loader.h:
vmm\..\arch\x86_64\limine.h:
+8
View File
@@ -13,6 +13,7 @@
*/ */
#include <utsm/linux_loader.h> #include <utsm/linux_loader.h>
#include <utsm/panic.h>
#include <utsm/linux_xsave.h> #include <utsm/linux_xsave.h>
#include <utsm/vmx.h> #include <utsm/vmx.h>
#include <utsm/ept.h> #include <utsm/ept.h>
@@ -440,11 +441,13 @@ int linux_launch(void) {
const struct linux_guest_info *gi = linux_get_guest_info(); const struct linux_guest_info *gi = linux_get_guest_info();
if (!gi || !gi->loaded) { if (!gi || !gi->loaded) {
log_error("[LINUX] guest not loaded"); log_error("[LINUX] guest not loaded");
panic_full("LNX-E20 LINUX GUEST NOT LOADED", "linux_launch invoked before linux_loader_init loaded a guest", 0);
return -1; return -1;
} }
if (!vmm_is_ready()) { if (!vmm_is_ready()) {
log_error("[LINUX] VMM not ready"); log_error("[LINUX] VMM not ready");
panic_full("LNX-E21 VMM NOT READY", "linux_launch invoked before vmm_init succeeded", 0);
return -2; return -2;
} }
@@ -487,10 +490,12 @@ int linux_launch(void) {
* 内容不受影响:VMCLEAR 只回写内存并改状态,VMPTRLD 再挂载。 */ * 内容不受影响:VMCLEAR 只回写内存并改状态,VMPTRLD 再挂载。 */
if (vmx_vmcs_clear(vmm_get_vmcs_phys()) != 0) { if (vmx_vmcs_clear(vmm_get_vmcs_phys()) != 0) {
log_error("[LINUX] vmclear failed"); log_error("[LINUX] vmclear failed");
panic_full("LNX-E22 VMCLEAR FAILED", "vmclear failed on the linux guest vmcs before launch", 0);
return -4; return -4;
} }
if (vmx_vmcs_load(vmm_get_vmcs_phys()) != 0) { if (vmx_vmcs_load(vmm_get_vmcs_phys()) != 0) {
log_error("[LINUX] vmptrld after vmclear failed"); log_error("[LINUX] vmptrld after vmclear failed");
panic_full("LNX-E23 VMPTRLD FAILED", "vmptrld failed after vmclear on the linux guest vmcs", 0);
return -5; return -5;
} }
@@ -621,6 +626,7 @@ int linux_launch(void) {
} }
log_hex64("[LINUX] vmlaunch failed, error=", error); log_hex64("[LINUX] vmlaunch failed, error=", error);
g_linux_guest_active = 0; g_linux_guest_active = 0;
panic_full("LNX-E24 VMLAUNCH FAILED", "vmlaunch failed for the linux guest", 0);
return -3; return -3;
} }
@@ -632,6 +638,7 @@ int linux_launch(void) {
log_hex64("[LINUX] vmexit count=", vmexit_get_count()); log_hex64("[LINUX] vmexit count=", vmexit_get_count());
if (!g_guest_parked) { if (!g_guest_parked) {
log_error("[LINUX] guest terminated before daemon park"); log_error("[LINUX] guest terminated before daemon park");
panic_full("LNX-E25 GUEST TERMINATED BEFORE PARK", "linux guest terminated before the daemon parked", 0);
return -6; return -6;
} }
@@ -653,6 +660,7 @@ int linux_launch(void) {
if (!got_ready) { if (!got_ready) {
g_guest_parked = 0; g_guest_parked = 0;
log_error("[LINUX] HLT without EXEC_READY handshake"); log_error("[LINUX] HLT without EXEC_READY handshake");
panic_full("LNX-E26 HLT WITHOUT EXEC READY", "guest parked without the daemon publishing exec_ready", 0);
return -7; return -7;
} }
} }
+17
View File
@@ -0,0 +1,17 @@
vmm/linux_boot.o: vmm\linux_boot.c include\utsm\linux_loader.h \
include\utsm\types.h include\utsm\panic.h include\utsm\linux_xsave.h \
include\utsm\vmx.h include\utsm\ept.h include\utsm\vmm.h \
include\utsm\virtio_mmio.h include\utsm\ipc_shm.h \
..\utsm-ipc\ipc_proto.h include\utsm\log.h vmm\..\arch\x86_64\limine.h
include\utsm\linux_loader.h:
include\utsm\types.h:
include\utsm\panic.h:
include\utsm\linux_xsave.h:
include\utsm\vmx.h:
include\utsm\ept.h:
include\utsm\vmm.h:
include\utsm\virtio_mmio.h:
include\utsm\ipc_shm.h:
..\utsm-ipc\ipc_proto.h:
include\utsm\log.h:
vmm\..\arch\x86_64\limine.h:
+11
View File
@@ -15,6 +15,7 @@
*/ */
#include <utsm/linux_compat.h> #include <utsm/linux_compat.h>
#include <utsm/panic.h>
#include <utsm/linux_resume.h> #include <utsm/linux_resume.h>
#include <utsm/linux_loader.h> /* VSCode Phase 5: linux_find_vscode_module */ #include <utsm/linux_loader.h> /* VSCode Phase 5: linux_find_vscode_module */
#include <utsm/ipc_shm.h> #include <utsm/ipc_shm.h>
@@ -196,6 +197,7 @@ static int lxc_exec_internal(const char *path, int argc,
/* 2. 发送 EXEC_REQUEST */ /* 2. 发送 EXEC_REQUEST */
if (ipc_shm_send(UTSM_MSG_EXEC_REQUEST, &req, sizeof(req)) != 0) { if (ipc_shm_send(UTSM_MSG_EXEC_REQUEST, &req, sizeof(req)) != 0) {
log_warn("[LNXC] exec: failed to enqueue request"); log_warn("[LNXC] exec: failed to enqueue request");
panic_full("LNX-E10 EXEC ENQUEUE FAILED", "ipc_shm_send rejected the exec request", 0);
return -2; return -2;
} }
@@ -287,6 +289,7 @@ static int lxc_file_roundtrip(u32 msg_type, const char *path, u64 offset,
if (ipc_shm_send(msg_type, &req, sizeof(req)) != 0) { if (ipc_shm_send(msg_type, &req, sizeof(req)) != 0) {
log_warn("[LNXC] file: failed to enqueue request"); log_warn("[LNXC] file: failed to enqueue request");
panic_full("LNX-E11 FILE ENQUEUE FAILED", "ipc_shm_send rejected the file request", 0);
return -2; return -2;
} }
@@ -798,11 +801,13 @@ int lxc_sync_lib_dir(const char *guest_lib_path) {
if (!guest_lib_path) return -1; if (!guest_lib_path) return -1;
if (!lxc_is_available()) { if (!lxc_is_available()) {
log_warn("[LNXC] sync_lib_dir: service not available"); log_warn("[LNXC] sync_lib_dir: service not available");
panic_full("LNX-E12 SYNC LIB SERVICE UNAVAILABLE", "lib sync invoked while the compat service is unavailable", 0);
return -1; return -1;
} }
int rc = lxc_f32_ensure(); int rc = lxc_f32_ensure();
if (rc != 0) { if (rc != 0) {
log_warn("[LNXC] sync_lib_dir: FAT32 not available"); log_warn("[LNXC] sync_lib_dir: FAT32 not available");
panic_full("LNX-E13 SYNC LIB FAT32 UNAVAILABLE", "lib sync invoked without a usable fat32 block device", 0);
return rc; return rc;
} }
@@ -811,6 +816,7 @@ int lxc_sync_lib_dir(const char *guest_lib_path) {
if (f32_find_path_dir_lfn(g_compat_lib_path, &lib_clus) != 0) { if (f32_find_path_dir_lfn(g_compat_lib_path, &lib_clus) != 0) {
log_warn("[LNXC] sync_lib_dir: lib dir not found:"); log_warn("[LNXC] sync_lib_dir: lib dir not found:");
log_warn(g_compat_lib_path); log_warn(g_compat_lib_path);
panic_full("LNX-E14 LIB DIR NOT FOUND", "fat32 lib directory for the guest is missing on the system disk", 0);
return -2; /* 目录不存在(容忍:可能是首次启动未放库) */ return -2; /* 目录不存在(容忍:可能是首次启动未放库) */
} }
log_info("[LNXC] sync_lib_dir: lib dir found"); log_info("[LNXC] sync_lib_dir: lib dir found");
@@ -862,6 +868,7 @@ static int lxc_guest_path_exists(const char *path) {
int lxc_vscode_install(void) { int lxc_vscode_install(void) {
if (!lxc_is_available()) { if (!lxc_is_available()) {
log_warn("[LNXC] vscode install: service not available"); log_warn("[LNXC] vscode install: service not available");
panic_full("LNX-E15 VSCODE SERVICE UNAVAILABLE", "vscode install invoked while the compat service is unavailable", 0);
return -1; return -1;
} }
log_info("[LNXC] vscode: probe /opt/vscode/bin/code"); log_info("[LNXC] vscode: probe /opt/vscode/bin/code");
@@ -894,6 +901,7 @@ int lxc_vscode_install(void) {
if (rc != 0 || written != chunk) { if (rc != 0 || written != chunk) {
log_warn("[LNXC] vscode: tarball push failed"); log_warn("[LNXC] vscode: tarball push failed");
log_hex64("[LNXC] vscode: push off=", off); log_hex64("[LNXC] vscode: push off=", off);
panic_full("LNX-E16 VSCODE TARBALL PUSH FAILED", "streaming the vscode tarball into the guest failed", 0);
return -12; return -12;
} }
off += written; off += written;
@@ -910,6 +918,7 @@ int lxc_vscode_install(void) {
int rc = lxc_exec("/bin/mkdir", 3, argv, 0, 0, 0, &ec); int rc = lxc_exec("/bin/mkdir", 3, argv, 0, 0, 0, &ec);
if (rc != 0 || ec != 0) { if (rc != 0 || ec != 0) {
log_warn("[LNXC] vscode: mkdir /opt/vscode failed"); log_warn("[LNXC] vscode: mkdir /opt/vscode failed");
panic_full("LNX-E17 VSCODE MKDIR FAILED", "mkdir -p /opt/vscode failed inside the guest", 0);
return -13; return -13;
} }
} }
@@ -956,12 +965,14 @@ int lxc_vscode_install(void) {
if (!unpacked) { if (!unpacked) {
log_warn("[LNXC] vscode: extract failed"); log_warn("[LNXC] vscode: extract failed");
panic_full("LNX-E18 VSCODE EXTRACT FAILED", "tar extraction of the vscode tarball failed in the guest", 0);
return -13; return -13;
} }
/* 7. 验证:/opt/vscode/bin/code 存在即可启动 */ /* 7. 验证:/opt/vscode/bin/code 存在即可启动 */
if (!lxc_guest_path_exists("/opt/vscode/bin/code")) { if (!lxc_guest_path_exists("/opt/vscode/bin/code")) {
log_warn("[LNXC] vscode: verify failed (bin/code missing)"); log_warn("[LNXC] vscode: verify failed (bin/code missing)");
panic_full("LNX-E19 VSCODE VERIFY FAILED", "/opt/vscode/bin/code missing after the install", 0);
return -14; return -14;
} }
+20
View File
@@ -0,0 +1,20 @@
vmm/linux_compat.o: vmm\linux_compat.c include\utsm\linux_compat.h \
include\utsm\types.h include\utsm\panic.h include\utsm\linux_resume.h \
include\utsm\linux_loader.h include\utsm\ipc_shm.h \
..\utsm-ipc\ipc_proto.h include\utsm\vmm.h include\utsm\virtio_mmio.h \
include\utsm\log.h include\utsm\block.h vmm\..\..\tools\fat32_io.h \
vmm\..\..\tools\fat32_lfn.h vmm\..\..\tools\fat32_part.h
include\utsm\linux_compat.h:
include\utsm\types.h:
include\utsm\panic.h:
include\utsm\linux_resume.h:
include\utsm\linux_loader.h:
include\utsm\ipc_shm.h:
..\utsm-ipc\ipc_proto.h:
include\utsm\vmm.h:
include\utsm\virtio_mmio.h:
include\utsm\log.h:
include\utsm\block.h:
vmm\..\..\tools\fat32_io.h:
vmm\..\..\tools\fat32_lfn.h:
vmm\..\..\tools\fat32_part.h:
+25
View File
@@ -14,6 +14,7 @@
*/ */
#include <utsm/linux_loader.h> #include <utsm/linux_loader.h>
#include <utsm/panic.h>
#include <utsm/vmx.h> #include <utsm/vmx.h>
#include <utsm/ept.h> #include <utsm/ept.h>
#include <utsm/log.h> #include <utsm/log.h>
@@ -472,6 +473,7 @@ int linux_parse_bzimage(const void *bzimage, u64 size,
if (size < 0x300) { if (size < 0x300) {
log_error("[LINUX] bzImage too small"); log_error("[LINUX] bzImage too small");
panic_full("LIN-E01 BZIMAGE TOO SMALL", "bzImage smaller than the real-mode setup header", 0);
return -1; return -1;
} }
@@ -494,6 +496,7 @@ int linux_parse_bzimage(const void *bzimage, u64 size,
log_hex64("[LINUX] boot protocol version=", version); log_hex64("[LINUX] boot protocol version=", version);
if (version < 0x020c) { if (version < 0x020c) {
log_error("[LINUX] boot protocol too old"); log_error("[LINUX] boot protocol too old");
panic_full("LIN-E02 BOOT PROTOCOL TOO OLD", "bzImage boot protocol older than 2.12", 0);
return -4; return -4;
} }
@@ -502,6 +505,7 @@ int linux_parse_bzimage(const void *bzimage, u64 size,
log_hex64("[LINUX] xloadflags=", xloadflags); log_hex64("[LINUX] xloadflags=", xloadflags);
if (!(xloadflags & XLF_KERNEL_64)) { if (!(xloadflags & XLF_KERNEL_64)) {
log_error("[LINUX] not a 64-bit kernel"); log_error("[LINUX] not a 64-bit kernel");
panic_full("LIN-E03 NOT A 64-BIT KERNEL", "bzImage xloadflags lacks the 64-bit kernel flag", 0);
return -5; return -5;
} }
@@ -514,6 +518,7 @@ int linux_parse_bzimage(const void *bzimage, u64 size,
u64 setup_size = ((u64)setup_sects + 1) * 512; u64 setup_size = ((u64)setup_sects + 1) * 512;
if (setup_size >= size) { if (setup_size >= size) {
log_error("[LINUX] setup sectors exceed bzImage"); log_error("[LINUX] setup sectors exceed bzImage");
panic_full("LIN-E04 SETUP SECTORS EXCEED BZIMAGE", "setup sector count extends beyond the bzImage size", 0);
return -6; return -6;
} }
@@ -523,6 +528,7 @@ int linux_parse_bzimage(const void *bzimage, u64 size,
if (payload_file_offset > size || if (payload_file_offset > size ||
payload_length > size - payload_file_offset) { payload_length > size - payload_file_offset) {
log_error("[LINUX] compressed payload exceeds bzImage"); log_error("[LINUX] compressed payload exceeds bzImage");
panic_full("LIN-E05 PAYLOAD EXCEEDS BZIMAGE", "compressed payload extends beyond the bzImage size", 0);
return -7; return -7;
} }
log_hex64("[LINUX] payload_offset(in protected image)=", payload_offset); log_hex64("[LINUX] payload_offset(in protected image)=", payload_offset);
@@ -642,6 +648,7 @@ int linux_loader_init(void) {
&kernel_offset, &kernel_length, &kernel_offset, &kernel_length,
&init_size, &entry_offset) != 0) { &init_size, &entry_offset) != 0) {
log_error("[LINUX] bzImage parse failed"); log_error("[LINUX] bzImage parse failed");
panic_full("LIN-E06 BZIMAGE PARSE FAILED", "linux_parse_bzimage rejected the bzImage header", 0);
return -2; return -2;
} }
@@ -653,6 +660,7 @@ int linux_loader_init(void) {
dkm_dma_buffer kernel_buf; dkm_dma_buffer kernel_buf;
if (dma_alloc_pages(kernel_alloc_size / 4096, 2 * 1024 * 1024, 0, &kernel_buf) != 0) { if (dma_alloc_pages(kernel_alloc_size / 4096, 2 * 1024 * 1024, 0, &kernel_buf) != 0) {
log_error("[LINUX] failed to alloc kernel memory"); log_error("[LINUX] failed to alloc kernel memory");
panic_full("LIN-E07 ALLOC KERNEL MEMORY FAILED", "dma_alloc_pages failed for the guest kernel image", 0);
return -3; return -3;
} }
log_hex64("[LINUX] kernel HPA=", kernel_buf.phys); log_hex64("[LINUX] kernel HPA=", kernel_buf.phys);
@@ -662,6 +670,7 @@ int linux_loader_init(void) {
dkm_dma_buffer bp_buf; dkm_dma_buffer bp_buf;
if (dma_alloc_pages(1, 4096, 0, &bp_buf) != 0) { if (dma_alloc_pages(1, 4096, 0, &bp_buf) != 0) {
log_error("[LINUX] failed to alloc boot_params"); log_error("[LINUX] failed to alloc boot_params");
panic_full("LIN-E08 ALLOC BOOT PARAMS FAILED", "dma_alloc_pages failed for boot_params", 0);
return -4; return -4;
} }
@@ -669,6 +678,7 @@ int linux_loader_init(void) {
dkm_dma_buffer pgt_buf; dkm_dma_buffer pgt_buf;
if (dma_alloc_pages(PGT_TOTAL_PAGES, 4096, 0, &pgt_buf) != 0) { if (dma_alloc_pages(PGT_TOTAL_PAGES, 4096, 0, &pgt_buf) != 0) {
log_error("[LINUX] failed to alloc page tables"); log_error("[LINUX] failed to alloc page tables");
panic_full("LIN-E09 ALLOC PAGE TABLES FAILED", "dma_alloc_pages failed for guest page tables", 0);
return -5; return -5;
} }
@@ -676,6 +686,7 @@ int linux_loader_init(void) {
dkm_dma_buffer gdt_buf; dkm_dma_buffer gdt_buf;
if (dma_alloc_pages(1, 4096, 0, &gdt_buf) != 0) { if (dma_alloc_pages(1, 4096, 0, &gdt_buf) != 0) {
log_error("[LINUX] failed to alloc GDT"); log_error("[LINUX] failed to alloc GDT");
panic_full("LIN-E10 ALLOC GDT FAILED", "dma_alloc_pages failed for the guest gdt", 0);
return -6; return -6;
} }
@@ -683,6 +694,7 @@ int linux_loader_init(void) {
dkm_dma_buffer stack_buf; dkm_dma_buffer stack_buf;
if (dma_alloc_pages(1, 4096, 0, &stack_buf) != 0) { if (dma_alloc_pages(1, 4096, 0, &stack_buf) != 0) {
log_error("[LINUX] failed to alloc stack"); log_error("[LINUX] failed to alloc stack");
panic_full("LIN-E11 ALLOC STACK FAILED", "dma_alloc_pages failed for the guest boot stack", 0);
return -7; return -7;
} }
@@ -690,6 +702,7 @@ int linux_loader_init(void) {
dkm_dma_buffer cmdline_buf; dkm_dma_buffer cmdline_buf;
if (dma_alloc_pages(1, 4096, 0, &cmdline_buf) != 0) { if (dma_alloc_pages(1, 4096, 0, &cmdline_buf) != 0) {
log_error("[LINUX] failed to alloc cmdline"); log_error("[LINUX] failed to alloc cmdline");
panic_full("LIN-E12 ALLOC CMDLINE FAILED", "dma_alloc_pages failed for the kernel command line", 0);
return -8; return -8;
} }
@@ -708,6 +721,7 @@ int linux_loader_init(void) {
ram_size = 512 * 1024 * 1024; /* 512MB floor for Phase 3 MVP */ ram_size = 512 * 1024 * 1024; /* 512MB floor for Phase 3 MVP */
if (dma_alloc_pages(ram_size / 4096, 2 * 1024 * 1024, 0, &ram_buf) != 0) { if (dma_alloc_pages(ram_size / 4096, 2 * 1024 * 1024, 0, &ram_buf) != 0) {
log_error("[LINUX] failed to alloc guest RAM (512MB minimum)"); log_error("[LINUX] failed to alloc guest RAM (512MB minimum)");
panic_full("LIN-E13 ALLOC GUEST RAM MINIMUM FAILED", "dma_alloc_pages failed even for the 512mb guest ram floor", 0);
return -9; return -9;
} }
} }
@@ -759,12 +773,14 @@ int linux_loader_init(void) {
dkm_dma_buffer initrd_buf; dkm_dma_buffer initrd_buf;
if (dma_alloc_pages(initrd_pages, 4096, 0, &initrd_buf) != 0) { if (dma_alloc_pages(initrd_pages, 4096, 0, &initrd_buf) != 0) {
log_error("[LINUX] failed to alloc initrd memory"); log_error("[LINUX] failed to alloc initrd memory");
panic_full("LIN-E14 ALLOC INITRD MEMORY FAILED", "dma_alloc_pages failed for the initrd image", 0);
return -17; return -17;
} }
mem_copy(initrd_buf.virt, initrd, initrd_size); mem_copy(initrd_buf.virt, initrd, initrd_size);
if (ept_map_range(LINUX_GUEST_INITRD_GPA, initrd_buf.phys, if (ept_map_range(LINUX_GUEST_INITRD_GPA, initrd_buf.phys,
initrd_pages * 4096, EPT_READ | EPT_WRITE) != 0) { initrd_pages * 4096, EPT_READ | EPT_WRITE) != 0) {
log_error("[LINUX] EPT map initrd failed"); log_error("[LINUX] EPT map initrd failed");
panic_full("LIN-E15 EPT MAP INITRD FAILED", "ept_map_range failed for the initrd image", 0);
return -18; return -18;
} }
g_guest.initrd_gpa = LINUX_GUEST_INITRD_GPA; g_guest.initrd_gpa = LINUX_GUEST_INITRD_GPA;
@@ -790,6 +806,7 @@ int linux_loader_init(void) {
if (ept_map_range(g_guest.kernel_gpa, kernel_buf.phys, if (ept_map_range(g_guest.kernel_gpa, kernel_buf.phys,
kernel_alloc_size, EPT_RWX) != 0) { kernel_alloc_size, EPT_RWX) != 0) {
log_error("[LINUX] EPT map kernel failed"); log_error("[LINUX] EPT map kernel failed");
panic_full("LIN-E16 EPT MAP KERNEL FAILED", "ept_map_range failed for the guest kernel image", 0);
return -10; return -10;
} }
@@ -797,6 +814,7 @@ int linux_loader_init(void) {
if (ept_map_range(g_guest.bootparams_gpa, bp_buf.phys, if (ept_map_range(g_guest.bootparams_gpa, bp_buf.phys,
4096, EPT_READ | EPT_WRITE) != 0) { 4096, EPT_READ | EPT_WRITE) != 0) {
log_error("[LINUX] EPT map boot_params failed"); log_error("[LINUX] EPT map boot_params failed");
panic_full("LIN-E17 EPT MAP BOOT PARAMS FAILED", "ept_map_range failed for boot_params", 0);
return -11; return -11;
} }
@@ -804,6 +822,7 @@ int linux_loader_init(void) {
if (ept_map_range(g_guest.pgt_gpa, pgt_buf.phys, if (ept_map_range(g_guest.pgt_gpa, pgt_buf.phys,
PGT_TOTAL_SIZE, EPT_READ | EPT_WRITE) != 0) { PGT_TOTAL_SIZE, EPT_READ | EPT_WRITE) != 0) {
log_error("[LINUX] EPT map page tables failed"); log_error("[LINUX] EPT map page tables failed");
panic_full("LIN-E18 EPT MAP PAGE TABLES FAILED", "ept_map_range failed for guest page tables", 0);
return -12; return -12;
} }
@@ -811,6 +830,7 @@ int linux_loader_init(void) {
if (ept_map_range(g_guest.gdt_gpa, gdt_buf.phys, if (ept_map_range(g_guest.gdt_gpa, gdt_buf.phys,
4096, EPT_READ | EPT_WRITE) != 0) { 4096, EPT_READ | EPT_WRITE) != 0) {
log_error("[LINUX] EPT map GDT failed"); log_error("[LINUX] EPT map GDT failed");
panic_full("LIN-E19 EPT MAP GDT FAILED", "ept_map_range failed for the guest gdt", 0);
return -13; return -13;
} }
@@ -818,6 +838,7 @@ int linux_loader_init(void) {
if (ept_map_range(LINUX_GUEST_STACK_GPA, stack_buf.phys, if (ept_map_range(LINUX_GUEST_STACK_GPA, stack_buf.phys,
4096, EPT_READ | EPT_WRITE) != 0) { 4096, EPT_READ | EPT_WRITE) != 0) {
log_error("[LINUX] EPT map stack failed"); log_error("[LINUX] EPT map stack failed");
panic_full("LIN-E20 EPT MAP STACK FAILED", "ept_map_range failed for the guest boot stack", 0);
return -14; return -14;
} }
@@ -825,6 +846,7 @@ int linux_loader_init(void) {
if (ept_map_range(g_guest.cmdline_gpa, cmdline_buf.phys, if (ept_map_range(g_guest.cmdline_gpa, cmdline_buf.phys,
4096, EPT_READ) != 0) { 4096, EPT_READ) != 0) {
log_error("[LINUX] EPT map cmdline failed"); log_error("[LINUX] EPT map cmdline failed");
panic_full("LIN-E21 EPT MAP CMDLINE FAILED", "ept_map_range failed for the kernel command line", 0);
return -15; return -15;
} }
@@ -840,6 +862,7 @@ int linux_loader_init(void) {
u64 ram_gpa = LINUX_GUEST_RAM_GPA; u64 ram_gpa = LINUX_GUEST_RAM_GPA;
if (ept_map_range(ram_gpa, ram_buf.phys, ram_size, EPT_RWX) != 0) { if (ept_map_range(ram_gpa, ram_buf.phys, ram_size, EPT_RWX) != 0) {
log_error("[LINUX] EPT map guest RAM failed"); log_error("[LINUX] EPT map guest RAM failed");
panic_full("LIN-E22 EPT MAP GUEST RAM FAILED", "ept_map_range failed for guest ram", 0);
return -16; return -16;
} }
log_hex64("[LINUX] guest RAM mapped GPA=", ram_gpa); log_hex64("[LINUX] guest RAM mapped GPA=", ram_gpa);
@@ -890,10 +913,12 @@ int linux_loader_init(void) {
dkm_dma_buffer hole; dkm_dma_buffer hole;
if (dma_alloc_pages(1, EPT_PAGE_SIZE, 0, &hole) != 0) { if (dma_alloc_pages(1, EPT_PAGE_SIZE, 0, &hole) != 0) {
log_warn("[LINUX] low-RAM hole fill OOM"); log_warn("[LINUX] low-RAM hole fill OOM");
panic_full("LIN-E23 LOW RAM HOLE FILL OOM", "dma_alloc_pages failed while filling low ram ept holes", 0);
break; break;
} }
if (ept_map_range(gpa, hole.phys, EPT_PAGE_SIZE, EPT_RWX) != 0) { if (ept_map_range(gpa, hole.phys, EPT_PAGE_SIZE, EPT_RWX) != 0) {
log_warn("[LINUX] low-RAM hole fill map failed"); log_warn("[LINUX] low-RAM hole fill map failed");
panic_full("LIN-E24 LOW RAM HOLE FILL MAP FAILED", "ept_map_range failed while filling low ram ept holes", 0);
break; break;
} }
filled++; filled++;
+12
View File
@@ -0,0 +1,12 @@
vmm/linux_loader.o: vmm\linux_loader.c include\utsm\linux_loader.h \
include\utsm\types.h include\utsm\panic.h include\utsm\vmx.h \
include\utsm\ept.h include\utsm\log.h include\utsm\dma.h \
vmm\..\arch\x86_64\limine.h
include\utsm\linux_loader.h:
include\utsm\types.h:
include\utsm\panic.h:
include\utsm\vmx.h:
include\utsm\ept.h:
include\utsm\log.h:
include\utsm\dma.h:
vmm\..\arch\x86_64\limine.h:
+3
View File
@@ -15,6 +15,7 @@
*/ */
#include <utsm/virtio_mmio.h> #include <utsm/virtio_mmio.h>
#include <utsm/panic.h>
#include <utsm/linux_loader.h> #include <utsm/linux_loader.h>
#include <utsm/block.h> #include <utsm/block.h>
#include <utsm/log.h> #include <utsm/log.h>
@@ -690,6 +691,7 @@ static int xrootfs_map_esp_file(void) {
if (nclus == 0 || nclus > XROOTFS_MAX_CLUSTERS) { if (nclus == 0 || nclus > XROOTFS_MAX_CLUSTERS) {
log_error("[VBLK] extra-rootfs cluster map too large"); log_error("[VBLK] extra-rootfs cluster map too large");
log_hex64("[VBLK] nclus=", nclus); log_hex64("[VBLK] nclus=", nclus);
panic_full("VVB-E10 EXTRA ROOTFS CLUSTER MAP TOO LARGE", "extra rootfs image cluster count exceeds the static map limit", 0);
return -7; return -7;
} }
@@ -697,6 +699,7 @@ static int xrootfs_map_esp_file(void) {
for (i = 0; i < nclus; i++) { for (i = 0; i < nclus; i++) {
if (fc_cur < 2 || fc_cur >= 0x0FFFFFF8u) { if (fc_cur < 2 || fc_cur >= 0x0FFFFFF8u) {
log_error("[VBLK] extra-rootfs FAT chain short"); log_error("[VBLK] extra-rootfs FAT chain short");
panic_full("VVB-E11 EXTRA ROOTFS FAT CHAIN SHORT", "fat chain of the extra rootfs image ended before covering the file", 0);
return -8; return -8;
} }
g_xrootfs_clus_lba[i] = (u32)vol + data_start + (fc_cur - 2u) * spc; g_xrootfs_clus_lba[i] = (u32)vol + data_start + (fc_cur - 2u) * spc;
+3 -2
View File
@@ -1,9 +1,10 @@
vmm/virtio_blk.o: vmm\virtio_blk.c include\utsm\virtio_mmio.h \ vmm/virtio_blk.o: vmm\virtio_blk.c include\utsm\virtio_mmio.h \
include\utsm\types.h include\utsm\linux_loader.h include\utsm\block.h \ include\utsm\types.h include\utsm\panic.h include\utsm\linux_loader.h \
include\utsm\log.h vmm\..\..\tools\fat32_lfn.h \ include\utsm\block.h include\utsm\log.h vmm\..\..\tools\fat32_lfn.h \
vmm\..\..\tools\fat32_part.h vmm\..\..\tools\fat32_part.h
include\utsm\virtio_mmio.h: include\utsm\virtio_mmio.h:
include\utsm\types.h: include\utsm\types.h:
include\utsm\panic.h:
include\utsm\linux_loader.h: include\utsm\linux_loader.h:
include\utsm\block.h: include\utsm\block.h:
include\utsm\log.h: include\utsm\log.h:
+1
View File
@@ -14,6 +14,7 @@
*/ */
#include <utsm/virtio_mmio.h> #include <utsm/virtio_mmio.h>
#include <utsm/panic.h>
#include <utsm/linux_loader.h> #include <utsm/linux_loader.h>
#include <utsm/net.h> #include <utsm/net.h>
#include <utsm/log.h> #include <utsm/log.h>
+9
View File
@@ -0,0 +1,9 @@
vmm/virtio_net.o: vmm\virtio_net.c include\utsm\virtio_mmio.h \
include\utsm\types.h include\utsm\panic.h include\utsm\linux_loader.h \
include\utsm\net.h include\utsm\log.h
include\utsm\virtio_mmio.h:
include\utsm\types.h:
include\utsm\panic.h:
include\utsm\linux_loader.h:
include\utsm\net.h:
include\utsm\log.h:
+9
View File
@@ -1,4 +1,5 @@
#include <utsm/vmx.h> #include <utsm/vmx.h>
#include <utsm/panic.h>
#include <utsm/ept.h> #include <utsm/ept.h>
#include <utsm/vmm.h> #include <utsm/vmm.h>
#include <utsm/hypercall.h> #include <utsm/hypercall.h>
@@ -98,10 +99,12 @@ static int ept_map_guest_ram_page(u64 gpa_page) {
dkm_dma_buffer buf; dkm_dma_buffer buf;
if (dma_alloc_pages(1, EPT_PAGE_SIZE, 0, &buf) != 0) { if (dma_alloc_pages(1, EPT_PAGE_SIZE, 0, &buf) != 0) {
log_error("[VMEXIT] OOM for guest RAM page"); log_error("[VMEXIT] OOM for guest RAM page");
panic_full("VMX-E10 OOM FOR GUEST RAM PAGE", "dma_alloc_pages failed for a demand mapped guest ram page", 0);
return -1; return -1;
} }
if (ept_map_range(gpa_page, buf.phys, EPT_PAGE_SIZE, EPT_RWX) != 0) { if (ept_map_range(gpa_page, buf.phys, EPT_PAGE_SIZE, EPT_RWX) != 0) {
log_error("[VMEXIT] EPT map guest RAM page failed"); log_error("[VMEXIT] EPT map guest RAM page failed");
panic_full("VMX-E11 EPT MAP GUEST RAM PAGE FAILED", "ept_map_range failed for a demand mapped guest ram page", 0);
return -1; return -1;
} }
return 0; return 0;
@@ -1091,6 +1094,7 @@ static int handle_virtio_mmio_access(u64 gpa, u64 rip, int *out_resume) {
log_error("[VMEXIT] virtio-mmio: cannot decode access insn"); log_error("[VMEXIT] virtio-mmio: cannot decode access insn");
log_hex64("[VMEXIT] rip=", rip); log_hex64("[VMEXIT] rip=", rip);
*out_resume = 0; *out_resume = 0;
panic_full("VMX-E12 CANNOT DECODE VIRTIO MMIO INSN", "instruction fetch or decode failed for a virtio mmio access", 0);
return -1; return -1;
} }
@@ -1146,6 +1150,7 @@ static int handle_ept_violation(u64 qualification, u64 rip, int *out_resume) {
log_error("[VMEXIT] EPT upgrade existing page failed"); log_error("[VMEXIT] EPT upgrade existing page failed");
log_hex64("[VMEXIT] gpa=", gpa); log_hex64("[VMEXIT] gpa=", gpa);
*out_resume = 0; *out_resume = 0;
panic_full("VMX-E13 EPT UPGRADE EXISTING PAGE FAILED", "ept_map_range failed while upgrading an existing ept leaf", 0);
return -1; return -1;
} }
ept_flush_ept(); ept_flush_ept();
@@ -1161,6 +1166,7 @@ static int handle_ept_violation(u64 qualification, u64 rip, int *out_resume) {
log_error("[VMEXIT] EPT violation: guest RAM map failed"); log_error("[VMEXIT] EPT violation: guest RAM map failed");
log_hex64("[VMEXIT] gpa=", gpa); log_hex64("[VMEXIT] gpa=", gpa);
*out_resume = 0; *out_resume = 0;
panic_full("VMX-E14 EPT VIOLATION GUEST RAM MAP FAILED", "demand mapping a guest ram page on ept violation failed", 0);
return -1; return -1;
} }
*out_resume = 1; *out_resume = 1;
@@ -1322,6 +1328,7 @@ static int handle_exception(u64 qualification, u64 rip, int *out_resume) {
log_hex64("[VMEXIT] df idtr=", vmx_vmcs_read(VMCS_GUEST_IDTR_BASE)); log_hex64("[VMEXIT] df idtr=", vmx_vmcs_read(VMCS_GUEST_IDTR_BASE));
log_hex64("[VMEXIT] df idtl=", vmx_vmcs_read(VMCS_GUEST_IDTR_LIMIT)); log_hex64("[VMEXIT] df idtl=", vmx_vmcs_read(VMCS_GUEST_IDTR_LIMIT));
*out_resume = 0; *out_resume = 0;
panic_full("VMX-E15 GUEST DOUBLE FAULT", "guest took a double fault which will not be reinjected", 0);
return 0; return 0;
} }
if (g_linux_guest_active) { if (g_linux_guest_active) {
@@ -1461,6 +1468,7 @@ int vmexit_dispatch(void) {
if (ept_map_guest_ram_page(page) != 0) { if (ept_map_guest_ram_page(page) != 0) {
log_error("[VMEXIT] EPT misconfig repair failed"); log_error("[VMEXIT] EPT misconfig repair failed");
resume = 0; resume = 0;
panic_full("VMX-E16 EPT MISCONFIG REPAIR FAILED", "both ept_repair_leaf and a fresh page alloc failed on ept misconfig", 0);
break; break;
} }
if (misconfig_logs <= 16) if (misconfig_logs <= 16)
@@ -1484,6 +1492,7 @@ int vmexit_dispatch(void) {
log_hex64("[VMEXIT] triple idtr=", vmx_vmcs_read(VMCS_GUEST_IDTR_BASE)); log_hex64("[VMEXIT] triple idtr=", vmx_vmcs_read(VMCS_GUEST_IDTR_BASE));
log_hex64("[VMEXIT] triple idtl=", vmx_vmcs_read(VMCS_GUEST_IDTR_LIMIT)); log_hex64("[VMEXIT] triple idtl=", vmx_vmcs_read(VMCS_GUEST_IDTR_LIMIT));
resume = 0; resume = 0;
panic_full("VMX-E17 GUEST TRIPLE FAULT", "guest cpu entered a triple fault", 0);
break; break;
case EXIT_EXTERNAL_INTERRUPT: case EXIT_EXTERNAL_INTERRUPT:
INSTR_STAT_INC(ext_irq); INSTR_STAT_INC(ext_irq);
+22
View File
@@ -0,0 +1,22 @@
vmm/vmexit.o: vmm\vmexit.c include\utsm\vmx.h include\utsm\types.h \
include\utsm\panic.h include\utsm\ept.h include\utsm\vmm.h \
include\utsm\hypercall.h include\utsm\ipc_shm.h \
..\utsm-ipc\ipc_proto.h include\utsm\log.h include\utsm\dma.h \
include\utsm\linux_loader.h include\utsm\linux_xsave.h \
include\utsm\virtio_mmio.h include\utsm\instr.h \
vmm\..\arch\x86_64\limine.h
include\utsm\vmx.h:
include\utsm\types.h:
include\utsm\panic.h:
include\utsm\ept.h:
include\utsm\vmm.h:
include\utsm\hypercall.h:
include\utsm\ipc_shm.h:
..\utsm-ipc\ipc_proto.h:
include\utsm\log.h:
include\utsm\dma.h:
include\utsm\linux_loader.h:
include\utsm\linux_xsave.h:
include\utsm\virtio_mmio.h:
include\utsm\instr.h:
vmm\..\arch\x86_64\limine.h:
+23 -5
View File
@@ -1,4 +1,5 @@
#include <utsm/vmm.h> #include <utsm/vmm.h>
#include <utsm/panic.h>
#include <utsm/vmx.h> #include <utsm/vmx.h>
#include <utsm/ept.h> #include <utsm/ept.h>
#include <utsm/log.h> #include <utsm/log.h>
@@ -412,23 +413,28 @@ int vmm_init(void) {
log_info("[VMM] init begin"); log_info("[VMM] init begin");
if (vmx_enable() != 0) { if (vmx_enable() != 0) {
log_error("[VMM] VMX enable failed"); /* 【插桩白名单】设计内环境探测:WHPX/无嵌套 VMX 等 VMX 不可用属
* CLAUDE.md §3 白名单"VMX/bzImage/kernel.krl 未配置跳过"。 */
log_error("[VMM] VMX enable failed (environment probe, skipping)");
return -1; return -1;
} }
if (ept_init() != 0) { if (ept_init() != 0) {
log_error("[VMM] EPT init failed"); /* 【插桩白名单】同上:EPT 不可用走 shadow paging 回退,由外层门跳过 guest 段。 */
log_error("[VMM] EPT init failed (environment probe, skipping)");
return -2; return -2;
} }
if (vmx_vmcs_alloc(&g_vmcs_phys) != 0) { if (vmx_vmcs_alloc(&g_vmcs_phys) != 0) {
log_error("[VMM] VMCS alloc failed"); /* 【插桩白名单】同上:init 期资源探测失败,非运行期语义错误。 */
log_error("[VMM] VMCS alloc failed (environment probe, skipping)");
return -3; return -3;
} }
log_hex64("[VMM] VMCS phys=", g_vmcs_phys); log_hex64("[VMM] VMCS phys=", g_vmcs_phys);
if (vmx_vmcs_load(g_vmcs_phys) != 0) { if (vmx_vmcs_load(g_vmcs_phys) != 0) {
log_error("[VMM] VMCS load failed"); /* 【插桩白名单】同上。 */
log_error("[VMM] VMCS load failed (environment probe, skipping)");
return -4; return -4;
} }
@@ -436,7 +442,8 @@ int vmm_init(void) {
vmx_vmcs_write(VMCS_VPID, 0x1234); vmx_vmcs_write(VMCS_VPID, 0x1234);
u64 vpid_readback = vmx_vmcs_read(VMCS_VPID); u64 vpid_readback = vmx_vmcs_read(VMCS_VPID);
if (vpid_readback != 0x1234) { if (vpid_readback != 0x1234) {
log_error("[VMM] VMCS read/write verify failed"); /* 【插桩白名单】同上:init 期硬件回读探测,异常环境交外层门跳过。 */
log_error("[VMM] VMCS read/write verify failed (environment probe, skipping)");
log_hex64("[VMM] wrote=0x1234 read=", vpid_readback); log_hex64("[VMM] wrote=0x1234 read=", vpid_readback);
return -5; return -5;
} }
@@ -550,6 +557,7 @@ static void vmm_dump_guest_state(void) {
int vmm_self_test(void) { int vmm_self_test(void) {
if (!g_vmm_ready) { if (!g_vmm_ready) {
log_error("[VMM] not ready"); log_error("[VMM] not ready");
panic_full("VMM-E15 VMM NOT READY", "self test invoked before vmm_init succeeded", 0);
return -1; return -1;
} }
@@ -573,18 +581,22 @@ int vmm_self_test(void) {
if (ept_map_range(0x1000, guest_code_phys, 4096, EPT_RWX) != 0) { if (ept_map_range(0x1000, guest_code_phys, 4096, EPT_RWX) != 0) {
log_error("[VMM] map guest code failed"); log_error("[VMM] map guest code failed");
panic_full("VMM-E16 MAP GUEST CODE FAILED", "ept_map_range failed for the self test code page", 0);
return -3; return -3;
} }
if (ept_map_range(0x8000, guest_stack_phys, 4096, EPT_RWX) != 0) { if (ept_map_range(0x8000, guest_stack_phys, 4096, EPT_RWX) != 0) {
log_error("[VMM] map guest stack failed"); log_error("[VMM] map guest stack failed");
panic_full("VMM-E17 MAP GUEST STACK FAILED", "ept_map_range failed for the self test stack page", 0);
return -4; return -4;
} }
if (ept_map_range(0x3000, guest_gdt_phys, 4096, EPT_READ | EPT_WRITE) != 0) { if (ept_map_range(0x3000, guest_gdt_phys, 4096, EPT_READ | EPT_WRITE) != 0) {
log_error("[VMM] map guest GDT failed"); log_error("[VMM] map guest GDT failed");
panic_full("VMM-E18 MAP GUEST GDT FAILED", "ept_map_range failed for the self test gdt page", 0);
return -5; return -5;
} }
if (ept_map_range(0x4000, guest_tss_phys, 4096, EPT_READ | EPT_WRITE) != 0) { if (ept_map_range(0x4000, guest_tss_phys, 4096, EPT_READ | EPT_WRITE) != 0) {
log_error("[VMM] map guest TSS failed"); log_error("[VMM] map guest TSS failed");
panic_full("VMM-E19 MAP GUEST TSS FAILED", "ept_map_range failed for the self test tss page", 0);
return -6; return -6;
} }
/* P8.4: Map IDT page for KVM nested VMX (IDTR base = 0x5000) */ /* P8.4: Map IDT page for KVM nested VMX (IDTR base = 0x5000) */
@@ -593,6 +605,7 @@ int vmm_self_test(void) {
for (int i = 0; i < 4096; i++) g_guest_idt[i] = 0; for (int i = 0; i < 4096; i++) g_guest_idt[i] = 0;
if (ept_map_range(0x5000, guest_idt_phys, 4096, EPT_READ | EPT_WRITE) != 0) { if (ept_map_range(0x5000, guest_idt_phys, 4096, EPT_READ | EPT_WRITE) != 0) {
log_error("[VMM] map guest IDT failed"); log_error("[VMM] map guest IDT failed");
panic_full("VMM-E20 MAP GUEST IDT FAILED", "ept_map_range failed for the self test idt page", 0);
return -9; return -9;
} }
} }
@@ -616,6 +629,7 @@ int vmm_self_test(void) {
ept_map_range(0x7000, pdpt_phys, 4096, EPT_READ | EPT_WRITE) != 0 || ept_map_range(0x7000, pdpt_phys, 4096, EPT_READ | EPT_WRITE) != 0 ||
ept_map_range(0x9000, pd_phys, 4096, EPT_READ | EPT_WRITE) != 0) { ept_map_range(0x9000, pd_phys, 4096, EPT_READ | EPT_WRITE) != 0) {
log_error("[VMM] map guest page tables failed"); log_error("[VMM] map guest page tables failed");
panic_full("VMM-E21 MAP GUEST PAGE TABLES FAILED", "ept_map_range failed for the self test page tables", 0);
return -12; return -12;
} }
} }
@@ -629,10 +643,12 @@ int vmm_self_test(void) {
* Without this, VMLAUNCH fails (error 4 or silent failure under KVM). */ * Without this, VMLAUNCH fails (error 4 or silent failure under KVM). */
if (vmx_vmcs_clear(g_vmcs_phys) != 0) { if (vmx_vmcs_clear(g_vmcs_phys) != 0) {
log_error("[VMM] vmclear failed"); log_error("[VMM] vmclear failed");
panic_full("VMM-E22 VMCLEAR FAILED", "vmclear failed on the self test vmcs", 0);
return -10; return -10;
} }
if (vmx_vmcs_load(g_vmcs_phys) != 0) { if (vmx_vmcs_load(g_vmcs_phys) != 0) {
log_error("[VMM] vmptrld after vmclear failed"); log_error("[VMM] vmptrld after vmclear failed");
panic_full("VMM-E23 VMPTRLD FAILED", "vmptrld failed after vmclear on the self test vmcs", 0);
return -11; return -11;
} }
@@ -725,6 +741,7 @@ int vmm_self_test(void) {
log_hex64("[VMM] CR4 missing(need)=", cr4_missing); log_hex64("[VMM] CR4 missing(need)=", cr4_missing);
log_hex64("[VMM] CR4 extra(forbid)=", cr4_extra); log_hex64("[VMM] CR4 extra(forbid)=", cr4_extra);
} }
panic_full("VMM-E24 VMLAUNCH FAILED", "vmlaunch failed during the self test launch", 0);
return -7; return -7;
} }
@@ -735,6 +752,7 @@ int vmm_self_test(void) {
if (g_last_exit_reason != EXIT_HLT) { if (g_last_exit_reason != EXIT_HLT) {
log_warn("[VMM] expected HLT exit"); log_warn("[VMM] expected HLT exit");
panic_full("VMM-E25 UNEXPECTED EXIT REASON", "self test guest exited with a reason other than hlt", 0);
return -8; return -8;
} }
+11
View File
@@ -0,0 +1,11 @@
vmm/vmm.o: vmm\vmm.c include\utsm\vmm.h include\utsm\types.h \
include\utsm\panic.h include\utsm\vmx.h include\utsm\ept.h \
include\utsm\log.h include\utsm\dma.h vmm\..\arch\x86_64\limine.h
include\utsm\vmm.h:
include\utsm\types.h:
include\utsm\panic.h:
include\utsm\vmx.h:
include\utsm\ept.h:
include\utsm\log.h:
include\utsm\dma.h:
vmm\..\arch\x86_64\limine.h:
+8
View File
@@ -1,4 +1,5 @@
#include <utsm/vmx.h> #include <utsm/vmx.h>
#include <utsm/panic.h>
#include <utsm/ept.h> #include <utsm/ept.h>
#include <utsm/log.h> #include <utsm/log.h>
#include <utsm/types.h> #include <utsm/types.h>
@@ -41,10 +42,12 @@ u64 vmx_kernel_virt_to_phys(const void *address) {
if (!response) { if (!response) {
log_error("[VMX] Limine kernel-address response missing"); log_error("[VMX] Limine kernel-address response missing");
panic_full("VMX-E01 KERNEL ADDRESS RESPONSE MISSING", "limine did not return a kernel address response", 0);
return 0; return 0;
} }
if (virt < response->virtual_base) { if (virt < response->virtual_base) {
log_error("[VMX] address is below kernel virtual base"); log_error("[VMX] address is below kernel virtual base");
panic_full("VMX-E02 ADDRESS BELOW KERNEL VIRTUAL BASE", "kernel virtual to physical conversion got an address below the kernel base", 0);
return 0; return 0;
} }
@@ -235,6 +238,7 @@ int vmx_enable(void) {
dkm_dma_buffer vmxon_buf; dkm_dma_buffer vmxon_buf;
if (dma_alloc_pages(1, EPT_PAGE_SIZE, 0x100000000ULL, &vmxon_buf) != 0) { if (dma_alloc_pages(1, EPT_PAGE_SIZE, 0x100000000ULL, &vmxon_buf) != 0) {
log_error("[VMX] failed to alloc VMXON region"); log_error("[VMX] failed to alloc VMXON region");
panic_full("VMX-E03 ALLOC VMXON REGION FAILED", "dma_alloc_pages failed for the vmxon region", 0);
return -2; return -2;
} }
g_vmxon_phys = vmxon_buf.phys; g_vmxon_phys = vmxon_buf.phys;
@@ -276,6 +280,7 @@ int vmx_enable(void) {
/* 第二次尝试:读 vmx instruction error 通过 VMCS 不适用 vmxon; /* 第二次尝试:读 vmx instruction error 通过 VMCS 不适用 vmxon;
* 简化:返回失败。 */ * 简化:返回失败。 */
log_error("[VMX] vmxon failed"); log_error("[VMX] vmxon failed");
panic_full("VMX-E04 VMXON FAILED", "the vmxon instruction failed to enter vmx root mode", 0);
return -3; return -3;
} }
@@ -301,6 +306,7 @@ int vmx_vmcs_alloc(u64 *phys_out) {
dkm_dma_buffer buf; dkm_dma_buffer buf;
if (dma_alloc_pages(1, EPT_PAGE_SIZE, 0x100000000ULL, &buf) != 0) { if (dma_alloc_pages(1, EPT_PAGE_SIZE, 0x100000000ULL, &buf) != 0) {
log_error("[VMX] failed to alloc VMCS region"); log_error("[VMX] failed to alloc VMCS region");
panic_full("VMX-E05 ALLOC VMCS REGION FAILED", "dma_alloc_pages failed for the vmcs region", 0);
return -2; return -2;
} }
/* 偏移 0 写入 VMCS revision ID */ /* 偏移 0 写入 VMCS revision ID */
@@ -328,6 +334,7 @@ int vmx_vmcs_load(u64 phys) {
); );
if (err) { if (err) {
log_error("[VMX] vmptrld failed"); log_error("[VMX] vmptrld failed");
panic_full("VMX-E06 VMPTRLD FAILED", "the vmptrld instruction failed to load the vmcs", 0);
return -1; return -1;
} }
return 0; return 0;
@@ -352,6 +359,7 @@ int vmx_vmcs_clear(u64 phys) {
); );
if (err) { if (err) {
log_error("[VMX] vmclear failed"); log_error("[VMX] vmclear failed");
panic_full("VMX-E07 VMCLEAR FAILED", "the vmclear instruction failed on the vmcs", 0);
return -1; return -1;
} }
return 0; return 0;
+10
View File
@@ -0,0 +1,10 @@
vmm/vmx.o: vmm\vmx.c include\utsm\vmx.h include\utsm\types.h \
include\utsm\panic.h include\utsm\ept.h include\utsm\log.h \
include\utsm\dma.h vmm\..\arch\x86_64\limine.h
include\utsm\vmx.h:
include\utsm\types.h:
include\utsm\panic.h:
include\utsm\ept.h:
include\utsm\log.h:
include\utsm\dma.h:
vmm\..\arch\x86_64\limine.h:
+43 -12
View File
@@ -15,6 +15,7 @@
*/ */
#include <utsm/xj380_loader.h> #include <utsm/xj380_loader.h>
#include <utsm/panic.h>
#include <utsm/vmx.h> #include <utsm/vmx.h>
#include <utsm/ept.h> #include <utsm/ept.h>
#include <utsm/log.h> #include <utsm/log.h>
@@ -86,24 +87,29 @@ static int xj380_parse_elf(const void *img, u64 size,
u64 *entry_out, u64 *span_out) { u64 *entry_out, u64 *span_out) {
if (size < sizeof(xj_elf64_ehdr)) { if (size < sizeof(xj_elf64_ehdr)) {
log_error("[XJ380] kernel.krl too small"); log_error("[XJ380] kernel.krl too small");
panic_full("XJ3-E01 KRL IMAGE TOO SMALL", "kernel.krl image smaller than an elf64 header", 0);
return -1; return -1;
} }
const xj_elf64_ehdr *eh = (const xj_elf64_ehdr *)img; const xj_elf64_ehdr *eh = (const xj_elf64_ehdr *)img;
if (*(u32 *)eh->e_ident != (u32)ELF_MAGIC) { if (*(u32 *)eh->e_ident != (u32)ELF_MAGIC) {
log_error("[XJ380] bad ELF magic"); log_error("[XJ380] bad ELF magic");
panic_full("XJ3-E02 BAD ELF MAGIC", "kernel.krl elf magic mismatch", 0);
return -2; return -2;
} }
if (eh->e_ident[4] != 2) { /* ELFCLASS64 */ if (eh->e_ident[4] != 2) { /* ELFCLASS64 */
log_error("[XJ380] not a 64-bit ELF"); log_error("[XJ380] not a 64-bit ELF");
panic_full("XJ3-E03 NOT A 64-BIT ELF", "kernel.krl is not a 64-bit elf image", 0);
return -3; return -3;
} }
if (eh->e_type != ELF_ET_EXEC) { if (eh->e_type != ELF_ET_EXEC) {
log_error("[XJ380] kernel.krl not ET_EXEC"); log_error("[XJ380] kernel.krl not ET_EXEC");
panic_full("XJ3-E04 KRL NOT ET_EXEC", "kernel.krl is not an ET_EXEC elf image", 0);
return -4; return -4;
} }
if (eh->e_phnum == 0 || eh->e_phentsize != sizeof(xj_elf64_phdr) || if (eh->e_phnum == 0 || eh->e_phentsize != sizeof(xj_elf64_phdr) ||
eh->e_phoff + (u64)eh->e_phnum * sizeof(xj_elf64_phdr) > size) { eh->e_phoff + (u64)eh->e_phnum * sizeof(xj_elf64_phdr) > size) {
log_error("[XJ380] bad program header table"); log_error("[XJ380] bad program header table");
panic_full("XJ3-E05 BAD PROGRAM HEADER TABLE", "kernel.krl program header table is invalid", 0);
return -5; return -5;
} }
@@ -114,21 +120,25 @@ static int xj380_parse_elf(const void *img, u64 size,
if (ph[i].p_vaddr < XJ380_KERNEL_VADDR) { if (ph[i].p_vaddr < XJ380_KERNEL_VADDR) {
log_error("[XJ380] PT_LOAD below kernel base"); log_error("[XJ380] PT_LOAD below kernel base");
log_hex64("[XJ380] vaddr=", ph[i].p_vaddr); log_hex64("[XJ380] vaddr=", ph[i].p_vaddr);
panic_full("XJ3-E06 PT_LOAD BELOW KERNEL BASE", "pt_load segment mapped below the xj380 kernel base", 0);
return -6; return -6;
} }
u64 off = ph[i].p_vaddr - XJ380_KERNEL_VADDR; u64 off = ph[i].p_vaddr - XJ380_KERNEL_VADDR;
if (off + ph[i].p_memsz > XJ380_GUEST_KERNEL_MAX) { if (off + ph[i].p_memsz > XJ380_GUEST_KERNEL_MAX) {
log_error("[XJ380] kernel exceeds reserved window (32MB)"); log_error("[XJ380] kernel exceeds reserved window (32MB)");
panic_full("XJ3-E07 KERNEL EXCEEDS RESERVED WINDOW", "kernel span exceeds the 32mb reserved window", 0);
return -7; return -7;
} }
if (ph[i].p_offset + ph[i].p_filesz > size) { if (ph[i].p_offset + ph[i].p_filesz > size) {
log_error("[XJ380] PT_LOAD filesz beyond image"); log_error("[XJ380] PT_LOAD filesz beyond image");
panic_full("XJ3-E08 PT_LOAD FILESZ BEYOND IMAGE", "pt_load file size extends beyond the kernel.krl image", 0);
return -8; return -8;
} }
if (off + ph[i].p_memsz > span) span = off + ph[i].p_memsz; if (off + ph[i].p_memsz > span) span = off + ph[i].p_memsz;
} }
if (span == 0) { if (span == 0) {
log_error("[XJ380] no PT_LOAD segments"); log_error("[XJ380] no PT_LOAD segments");
panic_full("XJ3-E09 NO PT_LOAD SEGMENTS", "kernel.krl contains no pt_load segments", 0);
return -9; return -9;
} }
@@ -474,6 +484,7 @@ static int xj380_build_boot_config(u64 hpa, u64 mtrr_hpa, u64 stack_gpa, u64 fbc
void *xj380_find_kernel_module(u64 *size_out) { void *xj380_find_kernel_module(u64 *size_out) {
if (!g_module_request.response) { if (!g_module_request.response) {
log_error("[XJ380] no Limine module response"); log_error("[XJ380] no Limine module response");
panic_full("XJ3-E10 NO LIMINE MODULE RESPONSE", "limine did not return a boot module response", 0);
return (void *)0; return (void *)0;
} }
@@ -525,34 +536,37 @@ int xj380_loader_init(void) {
u64 entry, span; u64 entry, span;
if (xj380_parse_elf(krl, krl_size, &entry, &span) != 0) { if (xj380_parse_elf(krl, krl_size, &entry, &span) != 0) {
log_error("[XJ380] kernel.krl parse failed"); log_error("[XJ380] kernel.krl parse failed");
panic_full("XJ3-E11 KRL PARSE FAILED", "xj380_parse_elf rejected the kernel.krl image", 0);
return -2; return -2;
} }
if (entry < XJ380_KERNEL_VADDR || entry >= XJ380_KERNEL_VADDR + span) { if (entry < XJ380_KERNEL_VADDR || entry >= XJ380_KERNEL_VADDR + span) {
log_error("[XJ380] entry outside kernel window"); log_error("[XJ380] entry outside kernel window");
panic_full("XJ3-E12 ENTRY OUTSIDE KERNEL WINDOW", "kernel entry point lies outside the reserved kernel window", 0);
return -3; return -3;
} }
/* 3. 分配 boot area 缓冲(按页) */ /* 3. 分配 boot area 缓冲(按页) */
dkm_dma_buffer pgt_buf, gdt_buf, madt_buf, fadt_buf, mcfg_buf, hpet_buf; dkm_dma_buffer pgt_buf, gdt_buf, madt_buf, fadt_buf, mcfg_buf, hpet_buf;
dkm_dma_buffer memmap_buf, bootcfg_buf, mtrr_buf, stack_buf, fakeefi_buf, fbc_buf; dkm_dma_buffer memmap_buf, bootcfg_buf, mtrr_buf, stack_buf, fakeefi_buf, fbc_buf;
if (dma_alloc_pages(8, 4096, 0, &pgt_buf) != 0) { log_error("[XJ380] alloc pgt failed"); return -4; } if (dma_alloc_pages(8, 4096, 0, &pgt_buf) != 0) { log_error("[XJ380] alloc pgt failed"); panic_full("XJ3-E13 ALLOC PGT FAILED", "dma_alloc_pages failed for guest page tables", 0); return -4; }
if (dma_alloc_pages(1, 4096, 0, &gdt_buf) != 0) { log_error("[XJ380] alloc gdt failed"); return -5; } if (dma_alloc_pages(1, 4096, 0, &gdt_buf) != 0) { log_error("[XJ380] alloc gdt failed"); panic_full("XJ3-E14 ALLOC GDT FAILED", "dma_alloc_pages failed for the guest gdt page", 0); return -5; }
if (dma_alloc_pages(1, 4096, 0, &madt_buf) != 0) { log_error("[XJ380] alloc madt failed"); return -6; } if (dma_alloc_pages(1, 4096, 0, &madt_buf) != 0) { log_error("[XJ380] alloc madt failed"); panic_full("XJ3-E15 ALLOC MADT FAILED", "dma_alloc_pages failed for the madt stub", 0); return -6; }
if (dma_alloc_pages(1, 4096, 0, &fadt_buf) != 0) { log_error("[XJ380] alloc fadt failed"); return -7; } if (dma_alloc_pages(1, 4096, 0, &fadt_buf) != 0) { log_error("[XJ380] alloc fadt failed"); panic_full("XJ3-E16 ALLOC FADT FAILED", "dma_alloc_pages failed for the fadt stub", 0); return -7; }
if (dma_alloc_pages(1, 4096, 0, &mcfg_buf) != 0) { log_error("[XJ380] alloc mcfg failed"); return -8; } if (dma_alloc_pages(1, 4096, 0, &mcfg_buf) != 0) { log_error("[XJ380] alloc mcfg failed"); panic_full("XJ3-E17 ALLOC MCFG FAILED", "dma_alloc_pages failed for the mcfg stub", 0); return -8; }
if (dma_alloc_pages(1, 4096, 0, &hpet_buf) != 0) { log_error("[XJ380] alloc hpet failed"); return -9; } if (dma_alloc_pages(1, 4096, 0, &hpet_buf) != 0) { log_error("[XJ380] alloc hpet failed"); panic_full("XJ3-E18 ALLOC HPET FAILED", "dma_alloc_pages failed for the hpet stub", 0); return -9; }
if (dma_alloc_pages(1, 4096, 0, &memmap_buf) != 0) { log_error("[XJ380] alloc memmap failed"); return -10; } if (dma_alloc_pages(1, 4096, 0, &memmap_buf) != 0) { log_error("[XJ380] alloc memmap failed"); panic_full("XJ3-E19 ALLOC MEMMAP FAILED", "dma_alloc_pages failed for the efi memmap page", 0); return -10; }
if (dma_alloc_pages(1, 4096, 0, &bootcfg_buf) != 0) { log_error("[XJ380] alloc bootcfg failed"); return -11; } if (dma_alloc_pages(1, 4096, 0, &bootcfg_buf) != 0) { log_error("[XJ380] alloc bootcfg failed"); panic_full("XJ3-E20 ALLOC BOOTCFG FAILED", "dma_alloc_pages failed for the boot_config page", 0); return -11; }
if (dma_alloc_pages(1, 4096, 0, &mtrr_buf) != 0) { log_error("[XJ380] alloc mtrr failed"); return -12; } if (dma_alloc_pages(1, 4096, 0, &mtrr_buf) != 0) { log_error("[XJ380] alloc mtrr failed"); panic_full("XJ3-E21 ALLOC MTRR FAILED", "dma_alloc_pages failed for the mtrr buffer", 0); return -12; }
if (dma_alloc_pages(2, 4096, 0, &stack_buf) != 0) { log_error("[XJ380] alloc stack failed"); return -13; } if (dma_alloc_pages(2, 4096, 0, &stack_buf) != 0) { log_error("[XJ380] alloc stack failed"); panic_full("XJ3-E22 ALLOC STACK FAILED", "dma_alloc_pages failed for the guest boot stack", 0); return -13; }
if (dma_alloc_pages(1, 4096, 0, &fakeefi_buf) != 0) { log_error("[XJ380] alloc fake efi failed"); return -14; } if (dma_alloc_pages(1, 4096, 0, &fakeefi_buf) != 0) { log_error("[XJ380] alloc fake efi failed"); panic_full("XJ3-E23 ALLOC FAKE EFI FAILED", "dma_alloc_pages failed for the fake efi table", 0); return -14; }
if (dma_alloc_pages(1, 4096, 0, &fbc_buf) != 0) { log_error("[XJ380] alloc fbc failed"); return -15; } if (dma_alloc_pages(1, 4096, 0, &fbc_buf) != 0) { log_error("[XJ380] alloc fbc failed"); panic_full("XJ3-E24 ALLOC FBC FAILED", "dma_alloc_pages failed for the framebuffer config page", 0); return -15; }
/* 4. 分配内核缓冲并装入 PT_LOAD 段 */ /* 4. 分配内核缓冲并装入 PT_LOAD 段 */
u64 kernel_alloc = (span + 4095) & ~4095ULL; u64 kernel_alloc = (span + 4095) & ~4095ULL;
dkm_dma_buffer kernel_buf; dkm_dma_buffer kernel_buf;
if (dma_alloc_pages(kernel_alloc / 4096, 2 * 1024 * 1024, 0, &kernel_buf) != 0) { if (dma_alloc_pages(kernel_alloc / 4096, 2 * 1024 * 1024, 0, &kernel_buf) != 0) {
log_error("[XJ380] failed to alloc kernel memory"); log_error("[XJ380] failed to alloc kernel memory");
panic_full("XJ3-E25 ALLOC KERNEL MEMORY FAILED", "dma_alloc_pages failed for the loaded kernel image", 0);
return -16; return -16;
} }
{ {
@@ -573,6 +587,7 @@ int xj380_loader_init(void) {
dkm_dma_buffer fb_buf; dkm_dma_buffer fb_buf;
if (dma_alloc_pages((XJ380_FB_SIZE + 4095) / 4096, 4096, 0, &fb_buf) != 0) { if (dma_alloc_pages((XJ380_FB_SIZE + 4095) / 4096, 4096, 0, &fb_buf) != 0) {
log_error("[XJ380] failed to alloc framebuffer"); log_error("[XJ380] failed to alloc framebuffer");
panic_full("XJ3-E26 ALLOC FRAMEBUFFER FAILED", "dma_alloc_pages failed for the guest framebuffer", 0);
return -17; return -17;
} }
{ {
@@ -591,6 +606,7 @@ int xj380_loader_init(void) {
ram_size = XJ380_GUEST_RAM_MIN; ram_size = XJ380_GUEST_RAM_MIN;
if (dma_alloc_pages(ram_size / 4096, 2 * 1024 * 1024, 0, &ram_buf) != 0) { if (dma_alloc_pages(ram_size / 4096, 2 * 1024 * 1024, 0, &ram_buf) != 0) {
log_error("[XJ380] failed to alloc guest RAM (256MB minimum)"); log_error("[XJ380] failed to alloc guest RAM (256MB minimum)");
panic_full("XJ3-E27 ALLOC GUEST RAM MINIMUM FAILED", "dma_alloc_pages failed even for the 256mb guest ram floor", 0);
return -18; return -18;
} }
} }
@@ -630,65 +646,80 @@ int xj380_loader_init(void) {
* boot area 各缓冲独立分配,逐个按自身 GPA 映射。 */ * boot area 各缓冲独立分配,逐个按自身 GPA 映射。 */
if (ept_map_range(XJ380_PGT_GPA, pgt_buf.phys, XJ380_PGT_SIZE, EPT_READ | EPT_WRITE) != 0) { if (ept_map_range(XJ380_PGT_GPA, pgt_buf.phys, XJ380_PGT_SIZE, EPT_READ | EPT_WRITE) != 0) {
log_error("[XJ380] EPT map page tables failed"); log_error("[XJ380] EPT map page tables failed");
panic_full("XJ3-E28 EPT MAP PAGE TABLES FAILED", "ept_map_range failed for guest page tables", 0);
return -19; return -19;
} }
if (ept_map_range(XJ380_GDT_GPA, gdt_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) { if (ept_map_range(XJ380_GDT_GPA, gdt_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) {
log_error("[XJ380] EPT map GDT failed"); log_error("[XJ380] EPT map GDT failed");
panic_full("XJ3-E29 EPT MAP GDT FAILED", "ept_map_range failed for the guest gdt", 0);
return -20; return -20;
} }
if (ept_map_range(XJ380_MADT_GPA, madt_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) { if (ept_map_range(XJ380_MADT_GPA, madt_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) {
log_error("[XJ380] EPT map MADT failed"); log_error("[XJ380] EPT map MADT failed");
panic_full("XJ3-E30 EPT MAP MADT FAILED", "ept_map_range failed for the madt stub", 0);
return -21; return -21;
} }
if (ept_map_range(XJ380_FADT_GPA, fadt_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) { if (ept_map_range(XJ380_FADT_GPA, fadt_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) {
log_error("[XJ380] EPT map FADT failed"); log_error("[XJ380] EPT map FADT failed");
panic_full("XJ3-E31 EPT MAP FADT FAILED", "ept_map_range failed for the fadt stub", 0);
return -22; return -22;
} }
if (ept_map_range(XJ380_MCFG_GPA, mcfg_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) { if (ept_map_range(XJ380_MCFG_GPA, mcfg_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) {
log_error("[XJ380] EPT map MCFG failed"); log_error("[XJ380] EPT map MCFG failed");
panic_full("XJ3-E32 EPT MAP MCFG FAILED", "ept_map_range failed for the mcfg stub", 0);
return -23; return -23;
} }
if (ept_map_range(XJ380_HPET_GPA, hpet_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) { if (ept_map_range(XJ380_HPET_GPA, hpet_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) {
log_error("[XJ380] EPT map HPET failed"); log_error("[XJ380] EPT map HPET failed");
panic_full("XJ3-E33 EPT MAP HPET FAILED", "ept_map_range failed for the hpet stub", 0);
return -24; return -24;
} }
if (ept_map_range(XJ380_MEMMAP_GPA, memmap_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) { if (ept_map_range(XJ380_MEMMAP_GPA, memmap_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) {
log_error("[XJ380] EPT map memory map failed"); log_error("[XJ380] EPT map memory map failed");
panic_full("XJ3-E34 EPT MAP MEMMAP FAILED", "ept_map_range failed for the efi memmap", 0);
return -25; return -25;
} }
if (ept_map_range(XJ380_BOOTCFG_GPA, bootcfg_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) { if (ept_map_range(XJ380_BOOTCFG_GPA, bootcfg_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) {
log_error("[XJ380] EPT map BOOT_CONFIG failed"); log_error("[XJ380] EPT map BOOT_CONFIG failed");
panic_full("XJ3-E35 EPT MAP BOOT CONFIG FAILED", "ept_map_range failed for the boot_config page", 0);
return -26; return -26;
} }
if (ept_map_range(XJ380_MTRR_GPA, mtrr_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) { if (ept_map_range(XJ380_MTRR_GPA, mtrr_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) {
log_error("[XJ380] EPT map MTRR buffer failed"); log_error("[XJ380] EPT map MTRR buffer failed");
panic_full("XJ3-E36 EPT MAP MTRR BUFFER FAILED", "ept_map_range failed for the mtrr buffer", 0);
return -27; return -27;
} }
if (ept_map_range(XJ380_STACK_GPA, stack_buf.phys, 8192, EPT_READ | EPT_WRITE) != 0) { if (ept_map_range(XJ380_STACK_GPA, stack_buf.phys, 8192, EPT_READ | EPT_WRITE) != 0) {
log_error("[XJ380] EPT map stack failed"); log_error("[XJ380] EPT map stack failed");
panic_full("XJ3-E37 EPT MAP STACK FAILED", "ept_map_range failed for the guest boot stack", 0);
return -28; return -28;
} }
if (ept_map_range(XJ380_FAKEEFI_GPA, fakeefi_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) { if (ept_map_range(XJ380_FAKEEFI_GPA, fakeefi_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) {
log_error("[XJ380] EPT map fake EFI table failed"); log_error("[XJ380] EPT map fake EFI table failed");
panic_full("XJ3-E38 EPT MAP FAKE EFI FAILED", "ept_map_range failed for the fake efi table", 0);
return -29; return -29;
} }
if (ept_map_range(XJ380_FBC_GPA, fbc_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) { if (ept_map_range(XJ380_FBC_GPA, fbc_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) {
log_error("[XJ380] EPT map FrameBufferConfig failed"); log_error("[XJ380] EPT map FrameBufferConfig failed");
panic_full("XJ3-E39 EPT MAP FRAMEBUFFER CONFIG FAILED", "ept_map_range failed for the framebuffer config page", 0);
return -30; return -30;
} }
if (ept_map_range(g_guest.fb_gpa, fb_buf.phys, XJ380_FB_SIZE, if (ept_map_range(g_guest.fb_gpa, fb_buf.phys, XJ380_FB_SIZE,
EPT_READ | EPT_WRITE) != 0) { EPT_READ | EPT_WRITE) != 0) {
log_error("[XJ380] EPT map framebuffer failed"); log_error("[XJ380] EPT map framebuffer failed");
panic_full("XJ3-E40 EPT MAP FRAMEBUFFER FAILED", "ept_map_range failed for the guest framebuffer", 0);
return -31; return -31;
} }
if (ept_map_range(g_guest.kernel_gpa, kernel_buf.phys, kernel_alloc, if (ept_map_range(g_guest.kernel_gpa, kernel_buf.phys, kernel_alloc,
EPT_RWX) != 0) { EPT_RWX) != 0) {
log_error("[XJ380] EPT map kernel failed"); log_error("[XJ380] EPT map kernel failed");
panic_full("XJ3-E41 EPT MAP KERNEL FAILED", "ept_map_range failed for the loaded kernel image", 0);
return -32; return -32;
} }
if (ept_map_range(g_guest.ram_gpa, ram_buf.phys, ram_size, if (ept_map_range(g_guest.ram_gpa, ram_buf.phys, ram_size,
EPT_RWX) != 0) { EPT_RWX) != 0) {
log_error("[XJ380] EPT map guest RAM failed"); log_error("[XJ380] EPT map guest RAM failed");
panic_full("XJ3-E42 EPT MAP GUEST RAM FAILED", "ept_map_range failed for guest ram", 0);
return -33; return -33;
} }
/* 低 1MB 恒等映射(BIOS 区,与 linux_loader 一致;<1MB 无需按需分配) */ /* 低 1MB 恒等映射(BIOS 区,与 linux_loader 一致;<1MB 无需按需分配) */
+12
View File
@@ -0,0 +1,12 @@
vmm/xj380_loader.o: vmm\xj380_loader.c include\utsm\xj380_loader.h \
include\utsm\types.h include\utsm\panic.h include\utsm\vmx.h \
include\utsm\ept.h include\utsm\log.h include\utsm\dma.h \
vmm\..\arch\x86_64\limine.h
include\utsm\xj380_loader.h:
include\utsm\types.h:
include\utsm\panic.h:
include\utsm\vmx.h:
include\utsm\ept.h:
include\utsm\log.h:
include\utsm\dma.h:
vmm\..\arch\x86_64\limine.h:
Binary file not shown.