diff --git a/CODE/UTSM/arch/x86_64/idt.c b/CODE/UTSM/arch/x86_64/idt.c index b5c2448..8b0afc7 100644 --- a/CODE/UTSM/arch/x86_64/idt.c +++ b/CODE/UTSM/arch/x86_64/idt.c @@ -560,6 +560,8 @@ int irq_vector_alloc(void) { return vec; } 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; } diff --git a/CODE/UTSM/arch/x86_64/idt.o b/CODE/UTSM/arch/x86_64/idt.o index fac639f..d7d62d1 100644 Binary files a/CODE/UTSM/arch/x86_64/idt.o and b/CODE/UTSM/arch/x86_64/idt.o differ diff --git a/CODE/UTSM/arch/x86_64/lapic_timer.c b/CODE/UTSM/arch/x86_64/lapic_timer.c index 2b0ecce..3e39f19 100644 --- a/CODE/UTSM/arch/x86_64/lapic_timer.c +++ b/CODE/UTSM/arch/x86_64/lapic_timer.c @@ -16,6 +16,7 @@ #include #include #include +#include extern void outb(u16 port, u8 value); extern u8 inb(u16 port); @@ -63,6 +64,7 @@ int lapic_timer_init(u32 freq_hz) { base = rdmsr_(MSR_IA32_APIC_BASE); } if (base & APIC_BASE_X2APIC) { + /* 【插桩白名单】设计内降级:x2APIC 不支持 MMIO timer,降级协作模式 */ log_warn("[LAPIC] x2APIC mode, MMIO timer unsupported"); return -1; } @@ -73,6 +75,8 @@ int lapic_timer_init(u32 freq_hz) { if (!mm || !mm->map_mmio) return -2; if (mm->map_mmio(phys, 0x1000) != 0) { log_warn("[LAPIC] map_mmio failed"); + panic_full("LAPIC-E01 MAP_MMIO FAILED", + "lapic_timer_init: LAPIC MMIO mapping failed", 0); return -3; } u64 hhdm = 0; @@ -82,6 +86,8 @@ int lapic_timer_init(u32 freq_hz) { if (mm->is_mapped && !mm->is_mapped((u64)g_lapic)) { g_lapic = 0; 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; } @@ -121,6 +127,8 @@ int lapic_timer_init(u32 freq_hz) { u64 delta = (u64)ccr0 - (u64)ccr1; /* 16 分频时钟 10ms tick 数 */ if (delta < 1000) { log_warn("[LAPIC] timer calibration implausible"); + panic_full("LAPIC-E03 CALIBRATION IMPLAUSIBLE", + "lapic_timer_init: PIT-vs-LAPIC calibration implausible", 0); lapic_timer_stop(); return -5; } @@ -134,6 +142,8 @@ int lapic_timer_init(u32 freq_hz) { int vec = irq_vector_alloc(); if (vec < 0) { 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; } g_timer_vector = vec; diff --git a/CODE/UTSM/arch/x86_64/lapic_timer.d b/CODE/UTSM/arch/x86_64/lapic_timer.d new file mode 100644 index 0000000..534c800 --- /dev/null +++ b/CODE/UTSM/arch/x86_64/lapic_timer.d @@ -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: diff --git a/CODE/UTSM/dkm/boot_modules.c b/CODE/UTSM/dkm/boot_modules.c index 79e3737..ada86ab 100644 --- a/CODE/UTSM/dkm/boot_modules.c +++ b/CODE/UTSM/dkm/boot_modules.c @@ -1,7 +1,8 @@ -#include +#include #include #include #include +#include #include "../arch/x86_64/limine.h" #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)) { 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; } if (!range_ok(ehdr->shoff, (u64)ehdr->shnum * ehdr->shentsize, size)) { 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; } @@ -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) { log_error("[DKM] missing symtab/strtab"); + panic_full("DKM-E32 ELF MISSING SYMTAB", + "dkm_scan_symbols: symtab/strtab missing or invalid", 0); return -1; } 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"); + panic_full("DKM-E33 ELF SYMTAB RANGE INVALID", + "dkm_scan_symbols: symtab/strtab out of file range", 0); return -1; } @@ -241,6 +250,8 @@ int dkm_scan_symbols(const void *address, u64 size, struct dkm_symbol_scan *out) return 0; } 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; } @@ -271,12 +282,16 @@ int dkm_load_elf_rel(const void *address, u64 size, const struct dkm_symbol_scan if (total_size == 0) { log_error("[DKM] no allocatable sections"); + panic_full("DKM-E35 ELF NO ALLOC SECTIONS", + "dkm_load_elf_rel: no allocatable sections", 0); return -1; } u8 *image = (u8 *)kmem_alloc_aligned(total_size, max_align); if (!image) { 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; } 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 { log_error("[DKM] unsupported relocation 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; } @@ -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); if (desc->magic != DKM_DRIVER_MAGIC) { 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; } @@ -397,6 +416,8 @@ int dkm_load_elf_rel(const void *address, u64 size, const struct dkm_symbol_scan if (result != 0) { handle.state = DKM_STATE_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; } handle.state = DKM_STATE_ACTIVE; @@ -408,6 +429,8 @@ void dkm_scan_boot_modules(void) { struct limine_module_response *response = g_module_request.response; if (!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; } @@ -418,6 +441,8 @@ void dkm_scan_boot_modules(void) { struct limine_file *file = response->modules[i]; if (!file) { log_warn("[DKM] null module entry"); + panic_full("DKM-E41 NULL MODULE ENTRY", + "dkm_scan_boot_modules: null boot module entry", 0); continue; } @@ -439,11 +464,15 @@ void dkm_scan_boot_modules(void) { int load_result = dkm_load_elf_rel(file->address, file->size, &symbols); if (load_result != 0) { 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 { log_error("[DKM] module ELF64 rejected"); 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); } } diff --git a/CODE/UTSM/dkm/boot_modules.d b/CODE/UTSM/dkm/boot_modules.d index aff84b6..3572e84 100644 --- a/CODE/UTSM/dkm/boot_modules.d +++ b/CODE/UTSM/dkm/boot_modules.d @@ -1,7 +1,7 @@ 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\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\types.h: include\utsm\dma.h: @@ -10,4 +10,5 @@ include\utsm\net.h: include\utsm\paging.h: include\utsm\log.h: include\utsm\arena.h: +include\utsm\panic.h: dkm\..\arch\x86_64\limine.h: diff --git a/CODE/UTSM/dkm/boot_modules.o b/CODE/UTSM/dkm/boot_modules.o index 9ddf1be..aa6971b 100644 Binary files a/CODE/UTSM/dkm/boot_modules.o and b/CODE/UTSM/dkm/boot_modules.o differ diff --git a/CODE/UTSM/dkm/dkm_core.c b/CODE/UTSM/dkm/dkm_core.c index 3bbe75c..bd447e1 100644 --- a/CODE/UTSM/dkm/dkm_core.c +++ b/CODE/UTSM/dkm/dkm_core.c @@ -1,5 +1,6 @@ -#include +#include #include +#include static int dkm_validate_desc(const dkm_driver_desc *desc) { if (!desc) { @@ -27,18 +28,24 @@ void dkm_init(void) { log_info("[DKM] init ok"); } else { 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) { if (!driver || !driver->desc || !driver->init) { log_error("[DKM] invalid builtin driver"); + panic_full("DKM-E51 INVALID BUILTIN DRIVER", + "dkm_load_builtin: builtin driver descriptor invalid", 0); return -1; } int status = dkm_validate_desc(driver->desc); if (status != 0) { log_error("[DKM] driver_desc rejected"); + panic_full("DKM-E52 DRIVER DESC REJECTED", + "dkm_load_builtin: builtin driver_desc validation failed", 0); return status; } @@ -60,6 +67,8 @@ int dkm_load_builtin(const dkm_builtin_driver *driver) { if (status != 0) { handle.state = DKM_STATE_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; } diff --git a/CODE/UTSM/dkm/dkm_core.d b/CODE/UTSM/dkm/dkm_core.d index d076779..1403200 100644 --- a/CODE/UTSM/dkm/dkm_core.d +++ b/CODE/UTSM/dkm/dkm_core.d @@ -1,6 +1,6 @@ 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\paging.h include\utsm\log.h + include\utsm\paging.h include\utsm\log.h include\utsm\panic.h include\utsm\dkm.h: include\utsm\types.h: include\utsm\dma.h: @@ -8,3 +8,4 @@ include\utsm\block.h: include\utsm\net.h: include\utsm\paging.h: include\utsm\log.h: +include\utsm\panic.h: diff --git a/CODE/UTSM/dkm/dkm_core.o b/CODE/UTSM/dkm/dkm_core.o index 5baca00..58dd3a7 100644 Binary files a/CODE/UTSM/dkm/dkm_core.o and b/CODE/UTSM/dkm/dkm_core.o differ diff --git a/CODE/UTSM/dkm/manifest.c b/CODE/UTSM/dkm/manifest.c index 94b9da2..f6e2b44 100644 --- a/CODE/UTSM/dkm/manifest.c +++ b/CODE/UTSM/dkm/manifest.c @@ -267,7 +267,12 @@ static int dsm_parse_manifest(const char *text, u64 size) { dsm_expect(&p, ':'); 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) { dsm_skip_ws(&p); if (*p == ']') { p++; break; } @@ -300,6 +305,9 @@ static int dsm_ensure_manifest(void) { rsp = g_module_request.response; if (!rsp) { 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; } @@ -314,6 +322,9 @@ static int dsm_ensure_manifest(void) { if (!manifest_file) { 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; } @@ -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) { - 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++) { 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) { log_warn("[DSM] named module not found"); 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; } f = drv->boot_module; @@ -437,15 +456,24 @@ void dsm_load_named(const ini_config *cfg, const char *name) { log_info(drv->name); if (dkm_check_elf64(f->address, f->size) != 0) { 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; } if (dkm_scan_symbols(f->address, f->size, &symbols) != 0) { 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; } result = dkm_load_elf_rel(f->address, f->size, &symbols); if (result != 0) { 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; } 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_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) { diff --git a/CODE/UTSM/dkm/manifest.o b/CODE/UTSM/dkm/manifest.o index b584dcf..a351f22 100644 Binary files a/CODE/UTSM/dkm/manifest.o and b/CODE/UTSM/dkm/manifest.o differ diff --git a/CODE/UTSM/kernel/dsk_loader.c b/CODE/UTSM/kernel/dsk_loader.c index 3a5577a..38a41a2 100644 --- a/CODE/UTSM/kernel/dsk_loader.c +++ b/CODE/UTSM/kernel/dsk_loader.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "../arch/x86_64/limine.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_hex64("[UTSM] FAT32: fat_sec_lba=", fat_sec_lba); 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 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) { const dkm_kernel_api *api = dkm_get_kernel_api(); if (!api || !api->block || !api->block->device_count) { + /* 【插桩白名单】设计内双路径回退:无块设备时由调用方回退 + * Limine boot module(CLAUDE.md 两阶段 DSK 加载设计)。 */ log_error("[UTSM] FAT32: no block api available"); return -1; } u32 count = api->block->device_count(); if (count == 0 || api->block->sector_size(0) != 512) { + /* 【插桩白名单】同上:无块设备属设计内回退路径。 */ log_error("[UTSM] FAT32: no block device or wrong sector size"); log_hex64("[UTSM] FAT32: device_count=", count); return -1; @@ -239,12 +245,17 @@ static int dsk_load_from_block_fat32(const void **out_addr, u64 *out_size) { if (st != 0) { log_error("[UTSM] FAT32: BPB read failed"); 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; } const fat32_bpb *bpb = (const fat32_bpb *)disk; 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: bps=", bpb->bytes_per_sector); 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_hex64("[UTSM] FAT32: clus=", clus); 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; } @@ -294,6 +307,8 @@ static int dsk_load_from_block_fat32(const void **out_addr, u64 *out_size) { if (!found_clus || found_size == 0) { 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; } 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)) { 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; } 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_hex64("[UTSM] FAT32: fc=", fc); 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; } 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) { log_error("[UTSM] FAT32: arena alloc failed"); 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; } 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) { log_info("[UTSM] DSK loaded from FAT32 block provider"); } 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"); struct limine_file *file = dsk_find_module(); if (!file) { @@ -1086,6 +1109,8 @@ int dsk_load_and_jump(void) { if (status != 0) { log_error("[UTSM] DSK ELF rejected"); 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; } @@ -1094,12 +1119,16 @@ int dsk_load_and_jump(void) { if (status != 0) { log_error("[UTSM] DSK load failed"); 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; } dsk_boot_context *ctx = (dsk_boot_context *)kmem_alloc_aligned(sizeof(dsk_boot_context), 16); if (!ctx) { 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; } dsk_fill_boot_context(ctx); @@ -1169,5 +1198,7 @@ int dsk_load_and_jump(void) { entry(ctx); log_error("[UTSM] DSK returned unexpectedly"); + panic_full("DSL-E14 DSK RETURNED UNEXPECTEDLY", + "dsk entry point returned to UTSM", 0); return -1; } diff --git a/CODE/UTSM/kernel/dsk_loader.d b/CODE/UTSM/kernel/dsk_loader.d new file mode 100644 index 0000000..40b8164 --- /dev/null +++ b/CODE/UTSM/kernel/dsk_loader.d @@ -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: diff --git a/CODE/UTSM/kernel/dsk_loader.o b/CODE/UTSM/kernel/dsk_loader.o index 9c6855f..b7fcd34 100644 Binary files a/CODE/UTSM/kernel/dsk_loader.o and b/CODE/UTSM/kernel/dsk_loader.o differ diff --git a/CODE/UTSM/kernel/main.c b/CODE/UTSM/kernel/main.c index ce03136..4c54518 100644 --- a/CODE/UTSM/kernel/main.c +++ b/CODE/UTSM/kernel/main.c @@ -190,7 +190,10 @@ static void disk_log_flush(void) { log_info("[UTSM] disk_log: BOOTLOG.TXT written"); log_hex64("[UTSM] disk_log: bytes=", len); } 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); } } @@ -258,6 +261,8 @@ void kernel_main(void) { if (cr4 & (1ULL << 12)) { log_error("[UTSM] LA57 is ACTIVE — this kernel requires 4-level paging"); 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(); } } @@ -404,6 +409,8 @@ void kernel_main(void) { * (configured separately) may still work. Force-continue regardless. */ if (vmm_st != 0) { 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 */ } if (vmm_st == 0) { @@ -476,6 +483,8 @@ void kernel_main(void) { INSTR_TS_END(ts_vmm, "vmm_init+selftest"); log_error("[UTSM] VMM self-test FAIL"); 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 跳过 === @@ -532,6 +541,8 @@ void kernel_main(void) { log_info("[UTSM] SELFTEST PASS"); } else { log_error("[UTSM] SELFTEST FAIL"); + panic_full("VMM-E14 SELFTEST FAIL", + "utsm_selftest_run returned non-zero", 0); arch_halt_forever(); } } @@ -570,6 +581,8 @@ void kernel_main(void) { if (dsk_load_and_jump() != 0) { log_error("[UTSM] DSK jump failed"); + panic_full("VMM-E15 DSK JUMP FAILED", + "dsk_load_and_jump returned non-zero", 0); } /* ---- 插桩: 启动总耗时(仅在 DSK 跳转失败时可见) ---- */ diff --git a/CODE/UTSM/kernel/main.o b/CODE/UTSM/kernel/main.o index 933f9a7..9f91c31 100644 Binary files a/CODE/UTSM/kernel/main.o and b/CODE/UTSM/kernel/main.o differ diff --git a/CODE/UTSM/kernel/probe.c b/CODE/UTSM/kernel/probe.c index 6490fb2..7505d3c 100644 --- a/CODE/UTSM/kernel/probe.c +++ b/CODE/UTSM/kernel/probe.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "ini_parser.h" /* ---- 探测缓冲状态 ---- */ @@ -39,6 +40,8 @@ void probe_init(const void *cfg_ptr) { if (!g_probe_buf) { g_instr_probe_enable = 0; 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; } diff --git a/CODE/UTSM/kernel/probe.d b/CODE/UTSM/kernel/probe.d new file mode 100644 index 0000000..36eb103 --- /dev/null +++ b/CODE/UTSM/kernel/probe.d @@ -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: diff --git a/CODE/UTSM/mm/dma.c b/CODE/UTSM/mm/dma.c index 931db26..8bcb63c 100644 --- a/CODE/UTSM/mm/dma.c +++ b/CODE/UTSM/mm/dma.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "../arch/x86_64/limine.h" #define PAGE_SIZE 4096ULL @@ -54,6 +55,8 @@ void dma_init(void) { } if (!g_hhdm_offset || !g_memmap_request.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; } @@ -84,6 +87,8 @@ void dma_init(void) { if (g_free_pages == 0) { 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; } @@ -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_hex64("[DMA] req pages=", page_count); 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; } diff --git a/CODE/UTSM/mm/dma.d b/CODE/UTSM/mm/dma.d new file mode 100644 index 0000000..14f51d0 --- /dev/null +++ b/CODE/UTSM/mm/dma.d @@ -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: diff --git a/CODE/UTSM/mm/dma.o b/CODE/UTSM/mm/dma.o index 1bd2923..3657b3a 100644 Binary files a/CODE/UTSM/mm/dma.o and b/CODE/UTSM/mm/dma.o differ diff --git a/CODE/UTSM/mm/mmio.c b/CODE/UTSM/mm/mmio.c index d60ac34..cd5a117 100644 --- a/CODE/UTSM/mm/mmio.c +++ b/CODE/UTSM/mm/mmio.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "../arch/x86_64/limine.h" #define MM_PAGE_SIZE 4096ULL @@ -79,11 +80,15 @@ static void mm_lazy_init(void) { g_max_phys_addr_bits = 0; if (!g_hhdm_request.response) { log_warn("[MM] missing HHDM response"); + panic_full("MM-E10 MISSING HHDM RESPONSE", + "mm_lazy_init: Limine HHDM response missing", 0); return; } g_hhdm = g_hhdm_request.response->offset; if (!g_hhdm) { log_warn("[MM] null HHDM offset"); + panic_full("MM-E11 NULL HHDM OFFSET", + "mm_lazy_init: HHDM offset is zero", 0); 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] This kernel requires 4-level paging (48-bit virtual)"); 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; } @@ -113,6 +120,8 @@ static void mm_lazy_init(void) { log_hex64("[MM] CPU MaxPhysAddr bits=", g_max_phys_addr_bits); if (g_max_phys_addr_bits > 52) { 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; } } else { @@ -126,6 +135,8 @@ static void mm_lazy_init(void) { g_window_base = mm_find_window(); if (!g_window_base) { 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; } g_window_end = g_window_base + MM_WINDOW_SIZE; @@ -153,6 +164,8 @@ static u64 *mm_walk_create(u64 virt) { dkm_dma_buffer buf; if (dma_alloc_pages(1, MM_PAGE_SIZE, 0, &buf) != 0) { 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; } 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_hex64("[MM] phys=", 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; } } @@ -197,6 +212,8 @@ void *mm_map_mmio(u64 phys, u64 size) { u64 vbase = g_window_next; if (vbase < g_window_base || vbase + total > g_window_end) { log_error("[MM] mmio window exhausted"); + panic_full("MM-E17 MMIO WINDOW EXHAUSTED", + "mm_map_mmio: MMIO virtual window exhausted", 0); return 0; } @@ -207,6 +224,8 @@ void *mm_map_mmio(u64 phys, u64 size) { if (!pte || (*pte & PTE_PRESENT)) { /* 冲突/失败:回滚本次已建立的映射 */ 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++) { u64 v = vbase + j * MM_PAGE_SIZE; u64 *p = mm_walk_query(v); diff --git a/CODE/UTSM/mm/mmio.d b/CODE/UTSM/mm/mmio.d new file mode 100644 index 0000000..74d9bd5 --- /dev/null +++ b/CODE/UTSM/mm/mmio.d @@ -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: diff --git a/CODE/UTSM/mm/paging.c b/CODE/UTSM/mm/paging.c index 961dd90..2a05352 100644 --- a/CODE/UTSM/mm/paging.c +++ b/CODE/UTSM/mm/paging.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "../arch/x86_64/limine.h" 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; if (!(pml4[idx4] & PTE_PRESENT)) { 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; } @@ -100,7 +106,12 @@ static int paging_map_mmio_impl(u64 phys, u64 size) { if (pdpt[idx3] & PTE_PS) { skipped++; continue; } /* 1G 大页已覆盖 */ } else { 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; } @@ -110,7 +121,12 @@ static int paging_map_mmio_impl(u64 phys, u64 size) { if (pd[idx2] & PTE_PS) { skipped++; continue; } /* 2M 大页已覆盖 */ } else { 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; } diff --git a/CODE/UTSM/mm/paging.d b/CODE/UTSM/mm/paging.d new file mode 100644 index 0000000..e61d958 --- /dev/null +++ b/CODE/UTSM/mm/paging.d @@ -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: diff --git a/CODE/UTSM/pe/pe_dll_manager.c b/CODE/UTSM/pe/pe_dll_manager.c index d5590bf..077ab88 100644 --- a/CODE/UTSM/pe/pe_dll_manager.c +++ b/CODE/UTSM/pe/pe_dll_manager.c @@ -18,6 +18,7 @@ #include #include #include +#include /* ---- PE 导出目录结构(packed,与 pe_loader.h 风格一致) ---- */ 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) { if (depth > PE_DLL_FWD_DEPTH_MAX) { 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; } 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++; if (buf[dot] != '.' || dot == 0 || buf[dot + 1] == 0) { log_warn("[PE] malformed forwarder string"); + panic_full("PE-E21 MALFORMED FORWARDER STRING", + "resolve_forwarded_export: malformed forwarder string", 0); return 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); if (addr == 0) { 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; } @@ -368,6 +375,8 @@ int pe_dll_load(const char *dll_name, u64 *out_base) { idx = dll_cache_alloc(); if (idx < 0) { 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; 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) { log_warn("[PE] DLL load failed: pe_load_image error"); 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; if (out_base) *out_base = 0; return -5; @@ -436,6 +447,8 @@ int pe_dll_load(const char *dll_name, u64 *out_base) { log_info("[PE] DllMain deferred"); } else { 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 { typedef int (__attribute__((ms_abi)) *dllmain_fn)(u64, u32, u64); diff --git a/CODE/UTSM/pe/pe_dll_manager.d b/CODE/UTSM/pe/pe_dll_manager.d index 02f6211..c20e825 100644 --- a/CODE/UTSM/pe/pe_dll_manager.d +++ b/CODE/UTSM/pe/pe_dll_manager.d @@ -1,6 +1,6 @@ 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\arena.h include\utsm\log.h + include\utsm\arena.h include\utsm\log.h include\utsm\panic.h pe\pe_dll_manager.h: include\utsm\types.h: pe\pe_loader.h: @@ -8,3 +8,4 @@ include\utsm\pe.h: pe\pe_shim.h: include\utsm\arena.h: include\utsm\log.h: +include\utsm\panic.h: diff --git a/CODE/UTSM/pe/pe_service.c b/CODE/UTSM/pe/pe_service.c index 73607b7..5e330bd 100644 --- a/CODE/UTSM/pe/pe_service.c +++ b/CODE/UTSM/pe/pe_service.c @@ -21,6 +21,7 @@ #include #include #include +#include /* 32位 PE 用的栈与堆 */ #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) { pe_dll_defer_dllmain(0); log_error("[PE] PE32+ load failed"); + panic_full("PE-E10 PE32+ LOAD FAILED", + "pe_service_run: PE32+ image load failed", 0); return -5; } 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); if (!pe_stack) { 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; } 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) { log_error("[PE] PE32 interp load failed"); 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; } 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); if (irc != 0) { log_error("[PE32] emu init failed"); + panic_full("PE-E13 EMU INIT FAILED", + "pe_service_run: x86emu32 init failed", 0); return -7; } 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); if (rrc != 0) { log_error("[PE32] emulator error"); + panic_full("PE-E14 EMULATOR ERROR", + "pe_service_run: x86emu32_run returned error", 0); code = 0xFFFFFFFFULL; } /* emu 字段只在未发生 longjmp 的正常返回路径读取 * (setjmp 语义:longjmp 后被修改的自动变量值不确定) */ if (emu.error && !emu.exited) { 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 { code = pe_shim_get_exit_code(); diff --git a/CODE/UTSM/pe/pe_service.d b/CODE/UTSM/pe/pe_service.d new file mode 100644 index 0000000..2da0ab8 --- /dev/null +++ b/CODE/UTSM/pe/pe_service.d @@ -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: diff --git a/CODE/UTSM/sched/sched.c b/CODE/UTSM/sched/sched.c index a5ef816..12bde81 100644 --- a/CODE/UTSM/sched/sched.c +++ b/CODE/UTSM/sched/sched.c @@ -546,12 +546,16 @@ int utsm_sched_enable(u32 tick_hz) { if (lapic_timer_init(tick_hz) != 0) { 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; } int vec = lapic_timer_vector(); if (vec < 0 || irq_register((u8)vec, utsm_tick_handler) != 0) { lapic_timer_stop(); 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; } idt_set_exception_hook(utsm_sched_exc_hook); diff --git a/CODE/UTSM/test/utsm_selftest.c b/CODE/UTSM/test/utsm_selftest.c index ef77158..c54ec03 100644 --- a/CODE/UTSM/test/utsm_selftest.c +++ b/CODE/UTSM/test/utsm_selftest.c @@ -8,6 +8,7 @@ #include #include #include +#include int memcmp(const void *a, const void *b, usize len); 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)); if (!process) { 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; } 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); if (status != UTSM_OK) { log_error("[UTSM] selftest create segment failed"); + panic_full("TST-E02 SELFTEST CREATE SEGMENT FAILED", + "utsm_selftest: create segment failed", 0); return status; } @@ -49,16 +54,22 @@ int utsm_selftest_run(void) { status = utsm_write(cap, 128, message, len); if (status != UTSM_OK) { log_error("[UTSM] selftest write failed"); + panic_full("TST-E03 SELFTEST WRITE FAILED", + "utsm_selftest: sealed write failed", 0); return status; } log_info("[UTSM] selftest write ok"); utsm_segment_desc *desc = utsm_get_segment(cap.segment_slot); if (!desc) { + panic_full("TST-E04 SELFTEST SEG DESC MISSING", + "utsm_selftest: segment desc lookup failed", 0); return UTSM_ERR_INVALID; } if (memcmp(desc->cipher_base + 128, message, len) == 0) { 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; } log_info("[UTSM] raw cipher check ok"); @@ -67,10 +78,14 @@ int utsm_selftest_run(void) { status = utsm_read(cap, 128, readback, len); if (status != UTSM_OK) { log_error("[UTSM] selftest read failed"); + panic_full("TST-E06 SELFTEST READ FAILED", + "utsm_selftest: sealed read failed", 0); return status; } if (memcmp(readback, message, len) != 0) { log_error("[UTSM] selftest read mismatch"); + panic_full("TST-E07 SELFTEST READ MISMATCH", + "utsm_selftest: readback mismatch", 0); return UTSM_ERR_INVALID; } 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); if (memcmp(ks, kat_expect, 64) != 0) { 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; } 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); if (m1 != m2 || m1 == m3) { 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; } 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); if (dst != UTSM_OK) { log_error("[UTSM] selftest cipher dump failed"); + panic_full("TST-E10 SELFTEST CIPHER DUMP FAILED", + "utsm_selftest: cipher page dump failed", 0); return dst; } } @@ -129,12 +150,16 @@ int utsm_selftest_run(void) { UTSM_ERR_EPOCH, &refreshed); if (status != UTSM_OK) { 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; } char slow_rb[64]; status = utsm_read(refreshed, 128, slow_rb, len); if (status != UTSM_OK || memcmp(slow_rb, message, len) != 0) { 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; } log_info("[UTSM] selftest slow EPOCH ok"); @@ -145,11 +170,15 @@ int utsm_selftest_run(void) { UTSM_ERR_KEY_MISS, 0); if (status != UTSM_OK) { 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; } status = utsm_read(refreshed, 128, slow_rb, len); if (status != UTSM_OK || memcmp(slow_rb, message, len) != 0) { 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; } log_info("[UTSM] selftest slow KEY_MISS ok"); @@ -160,6 +189,8 @@ int utsm_selftest_run(void) { UTSM_ERR_POISONED, 0); if (status != UTSM_ERR_POISONED) { 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; } log_info("[UTSM] selftest slow POISONED ok"); @@ -174,6 +205,8 @@ int utsm_selftest_run(void) { &ucap); if (status != UTSM_OK) { 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; } const char *upl = "unsealed plain text 00"; @@ -181,19 +214,29 @@ int utsm_selftest_run(void) { status = utsm_write(ucap, 128, upl, ulen); if (status != UTSM_OK) { log_error("[UTSM] selftest unsealed write failed"); + panic_full("TST-E17 UNSEALED WRITE FAILED", + "utsm_selftest: unsealed plain write failed", 0); return status; } 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 开销的可观察证据) */ if (memcmp(udesc->cipher_base + 128, upl, ulen) != 0) { 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; } char urb[64]; status = utsm_read(ucap, 128, urb, ulen); if (status != UTSM_OK || memcmp(urb, upl, ulen) != 0) { 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; } 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(); if (!api->kapi || api->kapi->magic != DKM_KAPI_MAGIC) { 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; } void *fn = 0; if (api->kapi->lookup("log.info", &fn) != 0) { 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; } void (*klog)(const char *) = (void (*)(const char *))fn; klog("[UTSM] selftest kapi: log.info via export table"); if (api->kapi->lookup("dma.alloc_pages", &fn) != 0) { 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; } int (*kalloc)(u64, u64, u64, dkm_dma_buffer *) = (int (*)(u64, u64, u64, dkm_dma_buffer *))fn; dkm_dma_buffer kbuf; if (kalloc(1, 4096, 0xFFFFFFFFULL, &kbuf) != 0 || !kbuf.virt) { 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; } if (api->kapi->lookup("no.such.service", &fn) == 0) { 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; } log_hex64("[UTSM] selftest kapi entries=", api->kapi->count); @@ -240,11 +293,15 @@ int utsm_selftest_run(void) { selftest_irq_restore(st_flags); if (rq_rc != 0) { 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; } log_info("[SCHED] selftest: runqueue O(1) PASS"); if (bw_rc != 0) { 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; } log_info("[SCHED] selftest: block/wake PASS"); @@ -259,34 +316,46 @@ int utsm_selftest_run(void) { status = utsm_write(cap, 512, p1, plen); if (status != UTSM_OK) { 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; } int snap = drr_ckpt_snapshot_dirty(); log_hex64("[DRR] ckpt snapshot pages=", (u64)(i64)snap); if (snap < 1) { log_error("[DRR] selftest snapshot failed"); + panic_full("TST-E29 DRR SNAPSHOT FAILED", + "utsm_selftest: dirty page snapshot failed", 0); return UTSM_ERR_INVALID; } drr_checkpoint_meta meta; if (drr_checkpoint_recover(&meta) != 0 || meta.type != DRR_CKPT_DIRTY_PAGE || meta.dirty_page_count < 1) { 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; } status = utsm_write(cap, 512, p2, plen); if (status != UTSM_OK) { log_error("[DRR] selftest P2 write failed"); + panic_full("TST-E31 DRR P2 WRITE FAILED", + "utsm_selftest: DRR overwrite write failed", 0); return status; } int rb = drr_rollback_pages(); log_hex64("[DRR] rollback pages=", (u64)(i64)rb); if (rb < 1) { log_error("[DRR] selftest rollback failed"); + panic_full("TST-E32 DRR ROLLBACK FAILED", + "utsm_selftest: page rollback failed", 0); return UTSM_ERR_INVALID; } status = utsm_read(cap, 512, readback, plen); if (status != UTSM_OK || memcmp(readback, p1, plen) != 0) { log_error("[DRR] rollback verify FAIL"); + panic_full("TST-E33 DRR ROLLBACK VERIFY FAIL", + "utsm_selftest: rollback verify mismatch", 0); return UTSM_ERR_INVALID; } log_info("[DRR] rollback verify ok"); diff --git a/CODE/UTSM/test/utsm_selftest.d b/CODE/UTSM/test/utsm_selftest.d index e22314d..337df55 100644 --- a/CODE/UTSM/test/utsm_selftest.d +++ b/CODE/UTSM/test/utsm_selftest.d @@ -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\block.h include\utsm\net.h include\utsm\paging.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\types.h: include\utsm\status.h: @@ -35,4 +36,5 @@ include\utsm\arena.h: include\utsm\drr.h: include\utsm\sched_ext.h: include\utsm\sched.h: +include\utsm\panic.h: test\chacha_kat.inc: diff --git a/CODE/UTSM/test/utsm_selftest.o b/CODE/UTSM/test/utsm_selftest.o index 64d9b1b..f718229 100644 Binary files a/CODE/UTSM/test/utsm_selftest.o and b/CODE/UTSM/test/utsm_selftest.o differ diff --git a/CODE/UTSM/utrw/debug.c b/CODE/UTSM/utrw/debug.c index 8239a14..ba0bd5f 100644 --- a/CODE/UTSM/utrw/debug.c +++ b/CODE/UTSM/utrw/debug.c @@ -3,6 +3,7 @@ #include #include #include +#include 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); if (st != UTSM_OK) { 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; } u64 dump_line = (page_off + offset_in_page) / UTSM_CACHE_LINE_SIZE; diff --git a/CODE/UTSM/utrw/debug.d b/CODE/UTSM/utrw/debug.d index 94ef866..e372687 100644 --- a/CODE/UTSM/utrw/debug.d +++ b/CODE/UTSM/utrw/debug.d @@ -1,7 +1,8 @@ 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\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\types.h: include\utsm\status.h: @@ -13,3 +14,4 @@ include\utsm\pckc.h: include\utsm\config.h: include\utsm\crypto.h: include\utsm\log.h: +include\utsm\panic.h: diff --git a/CODE/UTSM/utrw/slow_path.c b/CODE/UTSM/utrw/slow_path.c index a72975a..24b7a90 100644 --- a/CODE/UTSM/utrw/slow_path.c +++ b/CODE/UTSM/utrw/slow_path.c @@ -3,6 +3,7 @@ #include #include #include +#include /* =================================================================== * 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); if (st != UTSM_OK) { 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; } log_warn("[UTRW] slow: KEY_MISS -> key re-derived (retry)"); diff --git a/CODE/UTSM/utrw/slow_path.d b/CODE/UTSM/utrw/slow_path.d index ca05671..4cfee79 100644 --- a/CODE/UTSM/utrw/slow_path.d +++ b/CODE/UTSM/utrw/slow_path.d @@ -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\segment.h include\utsm\uuid.h include\utsm\dirty.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\types.h: include\utsm\status.h: @@ -15,3 +15,4 @@ include\utsm\config.h: include\utsm\crypto.h: include\utsm\drr.h: include\utsm\log.h: +include\utsm\panic.h: diff --git a/CODE/UTSM/utrw/slow_path.o b/CODE/UTSM/utrw/slow_path.o index 4035e5e..dc8317b 100644 Binary files a/CODE/UTSM/utrw/slow_path.o and b/CODE/UTSM/utrw/slow_path.o differ diff --git a/CODE/UTSM/vmm/ept.c b/CODE/UTSM/vmm/ept.c index f5258fa..5288586 100644 --- a/CODE/UTSM/vmm/ept.c +++ b/CODE/UTSM/vmm/ept.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -41,6 +42,7 @@ static u64 ept_alloc_page(void) { dkm_dma_buffer buf; if (dma_alloc_pages(1, EPT_PAGE_SIZE, 0x100000000ULL, &buf) != 0) { 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; } /* dma_alloc_pages 已清零 */ @@ -51,6 +53,7 @@ int ept_init(void) { g_ept_pml4_phys = ept_alloc_page(); if (g_ept_pml4_phys == 0) { log_error("[EPT] failed to alloc PML4"); + panic_full("EPT-E02 ALLOC PML4 FAILED", "ept root pml4 page allocation failed", 0); return -1; } 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)) || (size & (EPT_PAGE_SIZE - 1))) { 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; } @@ -132,6 +136,7 @@ int ept_map_range(u64 gpa, u64 hpa, u64 size, u64 flags) { u64 *entry = ept_walk(cur_gpa, 1); if (!entry) { log_error("[EPT] walk failed"); + panic_full("EPT-E04 EPT WALK FAILED", "ept_walk could not allocate intermediate page tables", 0); return -3; } *entry = ept_make_leaf(cur_hpa, flags, EPT_MEMORY_TYPE_WB); diff --git a/CODE/UTSM/vmm/ept.d b/CODE/UTSM/vmm/ept.d new file mode 100644 index 0000000..8a406c2 --- /dev/null +++ b/CODE/UTSM/vmm/ept.d @@ -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: diff --git a/CODE/UTSM/vmm/ipc_shm.c b/CODE/UTSM/vmm/ipc_shm.c index 6198c03..1520430 100644 --- a/CODE/UTSM/vmm/ipc_shm.c +++ b/CODE/UTSM/vmm/ipc_shm.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include @@ -48,6 +49,7 @@ int ipc_shm_init(void) { u64 page_count = UTSM_IPC_SHM_SIZE / 4096; if (dma_alloc_pages(page_count, 4096, 0, &g_shm_buf) != 0) { 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; } 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, UTSM_IPC_SHM_SIZE, EPT_READ | EPT_WRITE) != 0) { 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; } 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 */ if (!g_shm->header.linux_ready) { 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; } @@ -169,6 +173,7 @@ int ipc_shm_send(u32 msg_type, const void *data, u32 data_len) { /* Enqueue into utsm_to_linux ring */ if (utsm_ipc_ring_push(&g_shm->utsm_to_linux, &msg) != 0) { 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; } diff --git a/CODE/UTSM/vmm/ipc_shm.d b/CODE/UTSM/vmm/ipc_shm.d new file mode 100644 index 0000000..13f162b --- /dev/null +++ b/CODE/UTSM/vmm/ipc_shm.d @@ -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: diff --git a/CODE/UTSM/vmm/linux_boot.c b/CODE/UTSM/vmm/linux_boot.c index c9f8c2d..67ce9d5 100644 --- a/CODE/UTSM/vmm/linux_boot.c +++ b/CODE/UTSM/vmm/linux_boot.c @@ -13,6 +13,7 @@ */ #include +#include #include #include #include @@ -440,11 +441,13 @@ int linux_launch(void) { const struct linux_guest_info *gi = linux_get_guest_info(); if (!gi || !gi->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; } if (!vmm_is_ready()) { log_error("[LINUX] VMM not ready"); + panic_full("LNX-E21 VMM NOT READY", "linux_launch invoked before vmm_init succeeded", 0); return -2; } @@ -487,10 +490,12 @@ int linux_launch(void) { * 内容不受影响:VMCLEAR 只回写内存并改状态,VMPTRLD 再挂载。 */ if (vmx_vmcs_clear(vmm_get_vmcs_phys()) != 0) { log_error("[LINUX] vmclear failed"); + panic_full("LNX-E22 VMCLEAR FAILED", "vmclear failed on the linux guest vmcs before launch", 0); return -4; } if (vmx_vmcs_load(vmm_get_vmcs_phys()) != 0) { 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; } @@ -621,6 +626,7 @@ int linux_launch(void) { } log_hex64("[LINUX] vmlaunch failed, error=", error); g_linux_guest_active = 0; + panic_full("LNX-E24 VMLAUNCH FAILED", "vmlaunch failed for the linux guest", 0); return -3; } @@ -632,6 +638,7 @@ int linux_launch(void) { log_hex64("[LINUX] vmexit count=", vmexit_get_count()); if (!g_guest_parked) { 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; } @@ -653,6 +660,7 @@ int linux_launch(void) { if (!got_ready) { g_guest_parked = 0; 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; } } diff --git a/CODE/UTSM/vmm/linux_boot.d b/CODE/UTSM/vmm/linux_boot.d new file mode 100644 index 0000000..f18b989 --- /dev/null +++ b/CODE/UTSM/vmm/linux_boot.d @@ -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: diff --git a/CODE/UTSM/vmm/linux_compat.c b/CODE/UTSM/vmm/linux_compat.c index 6d48764..effd982 100644 --- a/CODE/UTSM/vmm/linux_compat.c +++ b/CODE/UTSM/vmm/linux_compat.c @@ -15,6 +15,7 @@ */ #include +#include #include #include /* VSCode Phase 5: linux_find_vscode_module */ #include @@ -196,6 +197,7 @@ static int lxc_exec_internal(const char *path, int argc, /* 2. 发送 EXEC_REQUEST */ if (ipc_shm_send(UTSM_MSG_EXEC_REQUEST, &req, sizeof(req)) != 0) { 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; } @@ -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) { 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; } @@ -798,11 +801,13 @@ int lxc_sync_lib_dir(const char *guest_lib_path) { if (!guest_lib_path) return -1; if (!lxc_is_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; } int rc = lxc_f32_ensure(); if (rc != 0) { 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; } @@ -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) { log_warn("[LNXC] sync_lib_dir: lib dir not found:"); 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; /* 目录不存在(容忍:可能是首次启动未放库) */ } 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) { if (!lxc_is_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; } log_info("[LNXC] vscode: probe /opt/vscode/bin/code"); @@ -894,6 +901,7 @@ int lxc_vscode_install(void) { if (rc != 0 || written != chunk) { log_warn("[LNXC] vscode: tarball push failed"); 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; } off += written; @@ -910,6 +918,7 @@ int lxc_vscode_install(void) { int rc = lxc_exec("/bin/mkdir", 3, argv, 0, 0, 0, &ec); if (rc != 0 || ec != 0) { 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; } } @@ -956,12 +965,14 @@ int lxc_vscode_install(void) { if (!unpacked) { 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; } /* 7. 验证:/opt/vscode/bin/code 存在即可启动 */ if (!lxc_guest_path_exists("/opt/vscode/bin/code")) { 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; } diff --git a/CODE/UTSM/vmm/linux_compat.d b/CODE/UTSM/vmm/linux_compat.d new file mode 100644 index 0000000..ee4fad1 --- /dev/null +++ b/CODE/UTSM/vmm/linux_compat.d @@ -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: diff --git a/CODE/UTSM/vmm/linux_loader.c b/CODE/UTSM/vmm/linux_loader.c index 73fd2b9..3677a9a 100644 --- a/CODE/UTSM/vmm/linux_loader.c +++ b/CODE/UTSM/vmm/linux_loader.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include @@ -472,6 +473,7 @@ int linux_parse_bzimage(const void *bzimage, u64 size, if (size < 0x300) { log_error("[LINUX] bzImage too small"); + panic_full("LIN-E01 BZIMAGE TOO SMALL", "bzImage smaller than the real-mode setup header", 0); return -1; } @@ -494,6 +496,7 @@ int linux_parse_bzimage(const void *bzimage, u64 size, log_hex64("[LINUX] boot protocol version=", version); if (version < 0x020c) { 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; } @@ -502,6 +505,7 @@ int linux_parse_bzimage(const void *bzimage, u64 size, log_hex64("[LINUX] xloadflags=", xloadflags); if (!(xloadflags & XLF_KERNEL_64)) { 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; } @@ -514,6 +518,7 @@ int linux_parse_bzimage(const void *bzimage, u64 size, u64 setup_size = ((u64)setup_sects + 1) * 512; if (setup_size >= size) { 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; } @@ -523,6 +528,7 @@ int linux_parse_bzimage(const void *bzimage, u64 size, if (payload_file_offset > size || payload_length > size - payload_file_offset) { log_error("[LINUX] compressed payload exceeds bzImage"); + panic_full("LIN-E05 PAYLOAD EXCEEDS BZIMAGE", "compressed payload extends beyond the bzImage size", 0); return -7; } log_hex64("[LINUX] payload_offset(in protected image)=", payload_offset); @@ -642,6 +648,7 @@ int linux_loader_init(void) { &kernel_offset, &kernel_length, &init_size, &entry_offset) != 0) { log_error("[LINUX] bzImage parse failed"); + panic_full("LIN-E06 BZIMAGE PARSE FAILED", "linux_parse_bzimage rejected the bzImage header", 0); return -2; } @@ -653,6 +660,7 @@ int linux_loader_init(void) { dkm_dma_buffer kernel_buf; if (dma_alloc_pages(kernel_alloc_size / 4096, 2 * 1024 * 1024, 0, &kernel_buf) != 0) { 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; } log_hex64("[LINUX] kernel HPA=", kernel_buf.phys); @@ -662,6 +670,7 @@ int linux_loader_init(void) { dkm_dma_buffer bp_buf; if (dma_alloc_pages(1, 4096, 0, &bp_buf) != 0) { 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; } @@ -669,6 +678,7 @@ int linux_loader_init(void) { dkm_dma_buffer pgt_buf; if (dma_alloc_pages(PGT_TOTAL_PAGES, 4096, 0, &pgt_buf) != 0) { 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; } @@ -676,6 +686,7 @@ int linux_loader_init(void) { dkm_dma_buffer gdt_buf; if (dma_alloc_pages(1, 4096, 0, &gdt_buf) != 0) { 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; } @@ -683,6 +694,7 @@ int linux_loader_init(void) { dkm_dma_buffer stack_buf; if (dma_alloc_pages(1, 4096, 0, &stack_buf) != 0) { 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; } @@ -690,6 +702,7 @@ int linux_loader_init(void) { dkm_dma_buffer cmdline_buf; if (dma_alloc_pages(1, 4096, 0, &cmdline_buf) != 0) { 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; } @@ -708,6 +721,7 @@ int linux_loader_init(void) { 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) { 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; } } @@ -759,12 +773,14 @@ int linux_loader_init(void) { dkm_dma_buffer initrd_buf; if (dma_alloc_pages(initrd_pages, 4096, 0, &initrd_buf) != 0) { 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; } mem_copy(initrd_buf.virt, initrd, initrd_size); if (ept_map_range(LINUX_GUEST_INITRD_GPA, initrd_buf.phys, initrd_pages * 4096, EPT_READ | EPT_WRITE) != 0) { 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; } 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, kernel_alloc_size, EPT_RWX) != 0) { 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; } @@ -797,6 +814,7 @@ int linux_loader_init(void) { if (ept_map_range(g_guest.bootparams_gpa, bp_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) { 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; } @@ -804,6 +822,7 @@ int linux_loader_init(void) { if (ept_map_range(g_guest.pgt_gpa, pgt_buf.phys, PGT_TOTAL_SIZE, EPT_READ | EPT_WRITE) != 0) { 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; } @@ -811,6 +830,7 @@ int linux_loader_init(void) { if (ept_map_range(g_guest.gdt_gpa, gdt_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) { 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; } @@ -818,6 +838,7 @@ int linux_loader_init(void) { if (ept_map_range(LINUX_GUEST_STACK_GPA, stack_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) { 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; } @@ -825,6 +846,7 @@ int linux_loader_init(void) { if (ept_map_range(g_guest.cmdline_gpa, cmdline_buf.phys, 4096, EPT_READ) != 0) { 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; } @@ -840,6 +862,7 @@ int linux_loader_init(void) { u64 ram_gpa = LINUX_GUEST_RAM_GPA; if (ept_map_range(ram_gpa, ram_buf.phys, ram_size, EPT_RWX) != 0) { 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; } log_hex64("[LINUX] guest RAM mapped GPA=", ram_gpa); @@ -890,10 +913,12 @@ int linux_loader_init(void) { dkm_dma_buffer hole; if (dma_alloc_pages(1, EPT_PAGE_SIZE, 0, &hole) != 0) { 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; } if (ept_map_range(gpa, hole.phys, EPT_PAGE_SIZE, EPT_RWX) != 0) { 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; } filled++; diff --git a/CODE/UTSM/vmm/linux_loader.d b/CODE/UTSM/vmm/linux_loader.d new file mode 100644 index 0000000..58a3686 --- /dev/null +++ b/CODE/UTSM/vmm/linux_loader.d @@ -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: diff --git a/CODE/UTSM/vmm/virtio_blk.c b/CODE/UTSM/vmm/virtio_blk.c index 1dd6178..23807ee 100644 --- a/CODE/UTSM/vmm/virtio_blk.c +++ b/CODE/UTSM/vmm/virtio_blk.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -690,6 +691,7 @@ static int xrootfs_map_esp_file(void) { if (nclus == 0 || nclus > XROOTFS_MAX_CLUSTERS) { log_error("[VBLK] extra-rootfs cluster map too large"); 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; } @@ -697,6 +699,7 @@ static int xrootfs_map_esp_file(void) { for (i = 0; i < nclus; i++) { if (fc_cur < 2 || fc_cur >= 0x0FFFFFF8u) { 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; } g_xrootfs_clus_lba[i] = (u32)vol + data_start + (fc_cur - 2u) * spc; diff --git a/CODE/UTSM/vmm/virtio_blk.d b/CODE/UTSM/vmm/virtio_blk.d index 9826b17..de9def7 100644 --- a/CODE/UTSM/vmm/virtio_blk.d +++ b/CODE/UTSM/vmm/virtio_blk.d @@ -1,9 +1,10 @@ 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\log.h vmm\..\..\tools\fat32_lfn.h \ + include\utsm\types.h include\utsm\panic.h include\utsm\linux_loader.h \ + include\utsm\block.h include\utsm\log.h vmm\..\..\tools\fat32_lfn.h \ vmm\..\..\tools\fat32_part.h include\utsm\virtio_mmio.h: include\utsm\types.h: +include\utsm\panic.h: include\utsm\linux_loader.h: include\utsm\block.h: include\utsm\log.h: diff --git a/CODE/UTSM/vmm/virtio_net.c b/CODE/UTSM/vmm/virtio_net.c index 7676186..cb11cc5 100644 --- a/CODE/UTSM/vmm/virtio_net.c +++ b/CODE/UTSM/vmm/virtio_net.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include diff --git a/CODE/UTSM/vmm/virtio_net.d b/CODE/UTSM/vmm/virtio_net.d new file mode 100644 index 0000000..42db745 --- /dev/null +++ b/CODE/UTSM/vmm/virtio_net.d @@ -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: diff --git a/CODE/UTSM/vmm/vmexit.c b/CODE/UTSM/vmm/vmexit.c index b1fa03e..ec45423 100644 --- a/CODE/UTSM/vmm/vmexit.c +++ b/CODE/UTSM/vmm/vmexit.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -98,10 +99,12 @@ static int ept_map_guest_ram_page(u64 gpa_page) { dkm_dma_buffer buf; if (dma_alloc_pages(1, EPT_PAGE_SIZE, 0, &buf) != 0) { 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; } if (ept_map_range(gpa_page, buf.phys, EPT_PAGE_SIZE, EPT_RWX) != 0) { 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 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_hex64("[VMEXIT] rip=", rip); *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; } @@ -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_hex64("[VMEXIT] gpa=", gpa); *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; } 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_hex64("[VMEXIT] gpa=", gpa); *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; } *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 idtl=", vmx_vmcs_read(VMCS_GUEST_IDTR_LIMIT)); *out_resume = 0; + panic_full("VMX-E15 GUEST DOUBLE FAULT", "guest took a double fault which will not be reinjected", 0); return 0; } if (g_linux_guest_active) { @@ -1461,6 +1468,7 @@ int vmexit_dispatch(void) { if (ept_map_guest_ram_page(page) != 0) { log_error("[VMEXIT] EPT misconfig repair failed"); 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; } 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 idtl=", vmx_vmcs_read(VMCS_GUEST_IDTR_LIMIT)); resume = 0; + panic_full("VMX-E17 GUEST TRIPLE FAULT", "guest cpu entered a triple fault", 0); break; case EXIT_EXTERNAL_INTERRUPT: INSTR_STAT_INC(ext_irq); diff --git a/CODE/UTSM/vmm/vmexit.d b/CODE/UTSM/vmm/vmexit.d new file mode 100644 index 0000000..9557df0 --- /dev/null +++ b/CODE/UTSM/vmm/vmexit.d @@ -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: diff --git a/CODE/UTSM/vmm/vmm.c b/CODE/UTSM/vmm/vmm.c index c398774..608161c 100644 --- a/CODE/UTSM/vmm/vmm.c +++ b/CODE/UTSM/vmm/vmm.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -412,23 +413,28 @@ int vmm_init(void) { log_info("[VMM] init begin"); 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; } 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; } 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; } log_hex64("[VMM] VMCS phys=", g_vmcs_phys); 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; } @@ -436,7 +442,8 @@ int vmm_init(void) { vmx_vmcs_write(VMCS_VPID, 0x1234); u64 vpid_readback = vmx_vmcs_read(VMCS_VPID); 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); return -5; } @@ -550,6 +557,7 @@ static void vmm_dump_guest_state(void) { int vmm_self_test(void) { if (!g_vmm_ready) { log_error("[VMM] not ready"); + panic_full("VMM-E15 VMM NOT READY", "self test invoked before vmm_init succeeded", 0); return -1; } @@ -573,18 +581,22 @@ int vmm_self_test(void) { if (ept_map_range(0x1000, guest_code_phys, 4096, EPT_RWX) != 0) { 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; } if (ept_map_range(0x8000, guest_stack_phys, 4096, EPT_RWX) != 0) { 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; } if (ept_map_range(0x3000, guest_gdt_phys, 4096, EPT_READ | EPT_WRITE) != 0) { 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; } if (ept_map_range(0x4000, guest_tss_phys, 4096, EPT_READ | EPT_WRITE) != 0) { 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; } /* 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; if (ept_map_range(0x5000, guest_idt_phys, 4096, EPT_READ | EPT_WRITE) != 0) { 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; } } @@ -616,6 +629,7 @@ int vmm_self_test(void) { ept_map_range(0x7000, pdpt_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"); + panic_full("VMM-E21 MAP GUEST PAGE TABLES FAILED", "ept_map_range failed for the self test page tables", 0); return -12; } } @@ -629,10 +643,12 @@ int vmm_self_test(void) { * Without this, VMLAUNCH fails (error 4 or silent failure under KVM). */ if (vmx_vmcs_clear(g_vmcs_phys) != 0) { log_error("[VMM] vmclear failed"); + panic_full("VMM-E22 VMCLEAR FAILED", "vmclear failed on the self test vmcs", 0); return -10; } if (vmx_vmcs_load(g_vmcs_phys) != 0) { 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; } @@ -725,6 +741,7 @@ int vmm_self_test(void) { log_hex64("[VMM] CR4 missing(need)=", cr4_missing); log_hex64("[VMM] CR4 extra(forbid)=", cr4_extra); } + panic_full("VMM-E24 VMLAUNCH FAILED", "vmlaunch failed during the self test launch", 0); return -7; } @@ -735,6 +752,7 @@ int vmm_self_test(void) { if (g_last_exit_reason != EXIT_HLT) { 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; } diff --git a/CODE/UTSM/vmm/vmm.d b/CODE/UTSM/vmm/vmm.d new file mode 100644 index 0000000..6480222 --- /dev/null +++ b/CODE/UTSM/vmm/vmm.d @@ -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: diff --git a/CODE/UTSM/vmm/vmx.c b/CODE/UTSM/vmm/vmx.c index 97dd40c..786ddbb 100644 --- a/CODE/UTSM/vmm/vmx.c +++ b/CODE/UTSM/vmm/vmx.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -41,10 +42,12 @@ u64 vmx_kernel_virt_to_phys(const void *address) { if (!response) { 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; } if (virt < response->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; } @@ -235,6 +238,7 @@ int vmx_enable(void) { dkm_dma_buffer vmxon_buf; if (dma_alloc_pages(1, EPT_PAGE_SIZE, 0x100000000ULL, &vmxon_buf) != 0) { 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; } g_vmxon_phys = vmxon_buf.phys; @@ -276,6 +280,7 @@ int vmx_enable(void) { /* 第二次尝试:读 vmx instruction error 通过 VMCS 不适用 vmxon; * 简化:返回失败。 */ log_error("[VMX] vmxon failed"); + panic_full("VMX-E04 VMXON FAILED", "the vmxon instruction failed to enter vmx root mode", 0); return -3; } @@ -301,6 +306,7 @@ int vmx_vmcs_alloc(u64 *phys_out) { dkm_dma_buffer buf; if (dma_alloc_pages(1, EPT_PAGE_SIZE, 0x100000000ULL, &buf) != 0) { 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; } /* 偏移 0 写入 VMCS revision ID */ @@ -328,6 +334,7 @@ int vmx_vmcs_load(u64 phys) { ); if (err) { log_error("[VMX] vmptrld failed"); + panic_full("VMX-E06 VMPTRLD FAILED", "the vmptrld instruction failed to load the vmcs", 0); return -1; } return 0; @@ -352,6 +359,7 @@ int vmx_vmcs_clear(u64 phys) { ); if (err) { log_error("[VMX] vmclear failed"); + panic_full("VMX-E07 VMCLEAR FAILED", "the vmclear instruction failed on the vmcs", 0); return -1; } return 0; diff --git a/CODE/UTSM/vmm/vmx.d b/CODE/UTSM/vmm/vmx.d new file mode 100644 index 0000000..717a0bc --- /dev/null +++ b/CODE/UTSM/vmm/vmx.d @@ -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: diff --git a/CODE/UTSM/vmm/xj380_loader.c b/CODE/UTSM/vmm/xj380_loader.c index 645172e..1842736 100644 --- a/CODE/UTSM/vmm/xj380_loader.c +++ b/CODE/UTSM/vmm/xj380_loader.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -86,24 +87,29 @@ static int xj380_parse_elf(const void *img, u64 size, u64 *entry_out, u64 *span_out) { if (size < sizeof(xj_elf64_ehdr)) { 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; } const xj_elf64_ehdr *eh = (const xj_elf64_ehdr *)img; if (*(u32 *)eh->e_ident != (u32)ELF_MAGIC) { log_error("[XJ380] bad ELF magic"); + panic_full("XJ3-E02 BAD ELF MAGIC", "kernel.krl elf magic mismatch", 0); return -2; } if (eh->e_ident[4] != 2) { /* ELFCLASS64 */ 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; } if (eh->e_type != ELF_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; } if (eh->e_phnum == 0 || eh->e_phentsize != sizeof(xj_elf64_phdr) || eh->e_phoff + (u64)eh->e_phnum * sizeof(xj_elf64_phdr) > size) { 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; } @@ -114,21 +120,25 @@ static int xj380_parse_elf(const void *img, u64 size, if (ph[i].p_vaddr < XJ380_KERNEL_VADDR) { log_error("[XJ380] PT_LOAD below kernel base"); 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; } u64 off = ph[i].p_vaddr - XJ380_KERNEL_VADDR; if (off + ph[i].p_memsz > XJ380_GUEST_KERNEL_MAX) { 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; } if (ph[i].p_offset + ph[i].p_filesz > size) { 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; } if (off + ph[i].p_memsz > span) span = off + ph[i].p_memsz; } if (span == 0) { 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; } @@ -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) { if (!g_module_request.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; } @@ -525,34 +536,37 @@ int xj380_loader_init(void) { u64 entry, span; if (xj380_parse_elf(krl, krl_size, &entry, &span) != 0) { 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; } if (entry < XJ380_KERNEL_VADDR || entry >= XJ380_KERNEL_VADDR + span) { 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; } /* 3. 分配 boot area 缓冲(按页) */ 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; - if (dma_alloc_pages(8, 4096, 0, &pgt_buf) != 0) { log_error("[XJ380] alloc pgt failed"); 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, &madt_buf) != 0) { log_error("[XJ380] alloc madt failed"); 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, &mcfg_buf) != 0) { log_error("[XJ380] alloc mcfg failed"); 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, &memmap_buf) != 0) { log_error("[XJ380] alloc memmap failed"); 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, &mtrr_buf) != 0) { log_error("[XJ380] alloc mtrr failed"); return -12; } - if (dma_alloc_pages(2, 4096, 0, &stack_buf) != 0) { log_error("[XJ380] alloc stack failed"); 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, &fbc_buf) != 0) { log_error("[XJ380] alloc fbc failed"); return -15; } + 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"); 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"); 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"); 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"); 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"); 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"); 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"); 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"); 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"); 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"); 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"); panic_full("XJ3-E24 ALLOC FBC FAILED", "dma_alloc_pages failed for the framebuffer config page", 0); return -15; } /* 4. 分配内核缓冲并装入 PT_LOAD 段 */ u64 kernel_alloc = (span + 4095) & ~4095ULL; dkm_dma_buffer kernel_buf; if (dma_alloc_pages(kernel_alloc / 4096, 2 * 1024 * 1024, 0, &kernel_buf) != 0) { 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; } { @@ -573,6 +587,7 @@ int xj380_loader_init(void) { dkm_dma_buffer fb_buf; if (dma_alloc_pages((XJ380_FB_SIZE + 4095) / 4096, 4096, 0, &fb_buf) != 0) { 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; } { @@ -591,6 +606,7 @@ int xj380_loader_init(void) { ram_size = XJ380_GUEST_RAM_MIN; if (dma_alloc_pages(ram_size / 4096, 2 * 1024 * 1024, 0, &ram_buf) != 0) { 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; } } @@ -630,65 +646,80 @@ int xj380_loader_init(void) { * boot area 各缓冲独立分配,逐个按自身 GPA 映射。 */ 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"); + panic_full("XJ3-E28 EPT MAP PAGE TABLES FAILED", "ept_map_range failed for guest page tables", 0); return -19; } if (ept_map_range(XJ380_GDT_GPA, gdt_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) { 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; } if (ept_map_range(XJ380_MADT_GPA, madt_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) { 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; } if (ept_map_range(XJ380_FADT_GPA, fadt_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) { 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; } if (ept_map_range(XJ380_MCFG_GPA, mcfg_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) { 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; } if (ept_map_range(XJ380_HPET_GPA, hpet_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) { 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; } if (ept_map_range(XJ380_MEMMAP_GPA, memmap_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) { 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; } if (ept_map_range(XJ380_BOOTCFG_GPA, bootcfg_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) { 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; } if (ept_map_range(XJ380_MTRR_GPA, mtrr_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) { 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; } if (ept_map_range(XJ380_STACK_GPA, stack_buf.phys, 8192, EPT_READ | EPT_WRITE) != 0) { 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; } 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"); + panic_full("XJ3-E38 EPT MAP FAKE EFI FAILED", "ept_map_range failed for the fake efi table", 0); return -29; } if (ept_map_range(XJ380_FBC_GPA, fbc_buf.phys, 4096, EPT_READ | EPT_WRITE) != 0) { 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; } if (ept_map_range(g_guest.fb_gpa, fb_buf.phys, XJ380_FB_SIZE, EPT_READ | EPT_WRITE) != 0) { 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; } if (ept_map_range(g_guest.kernel_gpa, kernel_buf.phys, kernel_alloc, EPT_RWX) != 0) { 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; } if (ept_map_range(g_guest.ram_gpa, ram_buf.phys, ram_size, EPT_RWX) != 0) { 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; } /* 低 1MB 恒等映射(BIOS 区,与 linux_loader 一致;<1MB 无需按需分配) */ diff --git a/CODE/UTSM/vmm/xj380_loader.d b/CODE/UTSM/vmm/xj380_loader.d new file mode 100644 index 0000000..1293b15 --- /dev/null +++ b/CODE/UTSM/vmm/xj380_loader.d @@ -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: diff --git a/SYSTEM/boot/utsm.elf b/SYSTEM/boot/utsm.elf index 522a73f..1b805ca 100755 Binary files a/SYSTEM/boot/utsm.elf and b/SYSTEM/boot/utsm.elf differ