feat: exhaustive STUB instrumentation - 241 panic sites across VMM/kernel + whitelist alignment
- VMM cluster: XJ3-E/LIN-E/VMM-E/VMX-E/EPT-E/IPC-E/VVB-E (124 sites) - kernel cluster: TST-E/MM-E/UTRW-E/LAPIC-E/IDT-E/SAS-E/PRB-E/NETST-E/DKM-E (117 sites) - whitelist fixes: vmm_init env probes E10-E14 fallback, disk_log read-only block path, DSL-E05 non-FAT32 device 0 probe - QEMU smoke: wizard -> USER.CONF -> login -> desktop ready, zero spurious panic
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -16,6 +16,7 @@
|
||||
#include <utsm/idt.h>
|
||||
#include <utsm/dkm.h>
|
||||
#include <utsm/log.h>
|
||||
#include <utsm/panic.h>
|
||||
|
||||
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;
|
||||
|
||||
@@ -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:
|
||||
@@ -1,7 +1,8 @@
|
||||
#include <utsm/dkm.h>
|
||||
#include <utsm/dkm.h>
|
||||
#include <utsm/log.h>
|
||||
#include <utsm/types.h>
|
||||
#include <utsm/arena.h>
|
||||
#include <utsm/panic.h>
|
||||
#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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
Binary file not shown.
@@ -1,5 +1,6 @@
|
||||
#include <utsm/dkm.h>
|
||||
#include <utsm/dkm.h>
|
||||
#include <utsm/log.h>
|
||||
#include <utsm/panic.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
Binary file not shown.
@@ -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) {
|
||||
|
||||
Binary file not shown.
@@ -6,6 +6,7 @@
|
||||
#include <utsm/pe.h>
|
||||
#include <utsm/linux_compat.h>
|
||||
#include <utsm/instr.h>
|
||||
#include <utsm/panic.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
kernel/dsk_loader.o: kernel\dsk_loader.c include\utsm\dsk.h \
|
||||
include\utsm\types.h include\utsm\arena.h include\utsm\dkm.h \
|
||||
include\utsm\dma.h include\utsm\block.h include\utsm\net.h \
|
||||
include\utsm\paging.h include\utsm\log.h include\utsm\pe.h \
|
||||
include\utsm\linux_compat.h include\utsm\instr.h include\utsm\panic.h \
|
||||
kernel\..\arch\x86_64\limine.h kernel\..\..\tools\fat32_lfn.h
|
||||
include\utsm\dsk.h:
|
||||
include\utsm\types.h:
|
||||
include\utsm\arena.h:
|
||||
include\utsm\dkm.h:
|
||||
include\utsm\dma.h:
|
||||
include\utsm\block.h:
|
||||
include\utsm\net.h:
|
||||
include\utsm\paging.h:
|
||||
include\utsm\log.h:
|
||||
include\utsm\pe.h:
|
||||
include\utsm\linux_compat.h:
|
||||
include\utsm\instr.h:
|
||||
include\utsm\panic.h:
|
||||
kernel\..\arch\x86_64\limine.h:
|
||||
kernel\..\..\tools\fat32_lfn.h:
|
||||
Binary file not shown.
+14
-1
@@ -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 跳转失败时可见) ---- */
|
||||
|
||||
Binary file not shown.
@@ -15,6 +15,7 @@
|
||||
#include <utsm/log.h>
|
||||
#include <utsm/types.h>
|
||||
#include <utsm/arena.h>
|
||||
#include <utsm/panic.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <utsm/dma.h>
|
||||
#include <utsm/log.h>
|
||||
#include <utsm/types.h>
|
||||
#include <utsm/panic.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
mm/dma.o: mm\dma.c include\utsm\dma.h include\utsm\types.h \
|
||||
include\utsm\log.h include\utsm\panic.h mm\..\arch\x86_64\limine.h
|
||||
include\utsm\dma.h:
|
||||
include\utsm\types.h:
|
||||
include\utsm\log.h:
|
||||
include\utsm\panic.h:
|
||||
mm\..\arch\x86_64\limine.h:
|
||||
Binary file not shown.
@@ -2,6 +2,7 @@
|
||||
#include <utsm/dma.h>
|
||||
#include <utsm/log.h>
|
||||
#include <utsm/types.h>
|
||||
#include <utsm/panic.h>
|
||||
#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);
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
mm/mmio.o: mm\mmio.c include\utsm\mm.h include\utsm\types.h \
|
||||
include\utsm\dma.h include\utsm\log.h include\utsm\panic.h \
|
||||
mm\..\arch\x86_64\limine.h
|
||||
include\utsm\mm.h:
|
||||
include\utsm\types.h:
|
||||
include\utsm\dma.h:
|
||||
include\utsm\log.h:
|
||||
include\utsm\panic.h:
|
||||
mm\..\arch\x86_64\limine.h:
|
||||
+19
-3
@@ -15,6 +15,7 @@
|
||||
#include <utsm/paging.h>
|
||||
#include <utsm/dma.h>
|
||||
#include <utsm/log.h>
|
||||
#include <utsm/panic.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <utsm/log.h>
|
||||
#include <utsm/types.h>
|
||||
#include <utsm/pe.h>
|
||||
#include <utsm/panic.h>
|
||||
|
||||
/* ---- 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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <utsm/idt.h>
|
||||
#include <utsm/log.h>
|
||||
#include <utsm/types.h>
|
||||
#include <utsm/panic.h>
|
||||
|
||||
/* 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();
|
||||
|
||||
@@ -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:
|
||||
@@ -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);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <utsm/arena.h>
|
||||
#include <utsm/drr.h>
|
||||
#include <utsm/sched_ext.h>
|
||||
#include <utsm/panic.h>
|
||||
|
||||
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");
|
||||
|
||||
@@ -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:
|
||||
|
||||
Binary file not shown.
@@ -3,6 +3,7 @@
|
||||
#include <utsm/pckc.h>
|
||||
#include <utsm/crypto.h>
|
||||
#include <utsm/log.h>
|
||||
#include <utsm/panic.h>
|
||||
|
||||
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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <utsm/pckc.h>
|
||||
#include <utsm/drr.h>
|
||||
#include <utsm/log.h>
|
||||
#include <utsm/panic.h>
|
||||
|
||||
/* ===================================================================
|
||||
* 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)");
|
||||
|
||||
@@ -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:
|
||||
|
||||
Binary file not shown.
@@ -1,4 +1,5 @@
|
||||
#include <utsm/ept.h>
|
||||
#include <utsm/panic.h>
|
||||
#include <utsm/vmx.h>
|
||||
#include <utsm/log.h>
|
||||
#include <utsm/types.h>
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
@@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
#include <utsm/ipc_shm.h>
|
||||
#include <utsm/panic.h>
|
||||
#include <utsm/vmx.h>
|
||||
#include <utsm/ept.h>
|
||||
#include <utsm/log.h>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
@@ -13,6 +13,7 @@
|
||||
*/
|
||||
|
||||
#include <utsm/linux_loader.h>
|
||||
#include <utsm/panic.h>
|
||||
#include <utsm/linux_xsave.h>
|
||||
#include <utsm/vmx.h>
|
||||
#include <utsm/ept.h>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#include <utsm/linux_compat.h>
|
||||
#include <utsm/panic.h>
|
||||
#include <utsm/linux_resume.h>
|
||||
#include <utsm/linux_loader.h> /* VSCode Phase 5: linux_find_vscode_module */
|
||||
#include <utsm/ipc_shm.h>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
@@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
#include <utsm/linux_loader.h>
|
||||
#include <utsm/panic.h>
|
||||
#include <utsm/vmx.h>
|
||||
#include <utsm/ept.h>
|
||||
#include <utsm/log.h>
|
||||
@@ -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++;
|
||||
|
||||
@@ -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:
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#include <utsm/virtio_mmio.h>
|
||||
#include <utsm/panic.h>
|
||||
#include <utsm/linux_loader.h>
|
||||
#include <utsm/block.h>
|
||||
#include <utsm/log.h>
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
#include <utsm/virtio_mmio.h>
|
||||
#include <utsm/panic.h>
|
||||
#include <utsm/linux_loader.h>
|
||||
#include <utsm/net.h>
|
||||
#include <utsm/log.h>
|
||||
|
||||
@@ -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:
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <utsm/vmx.h>
|
||||
#include <utsm/panic.h>
|
||||
#include <utsm/ept.h>
|
||||
#include <utsm/vmm.h>
|
||||
#include <utsm/hypercall.h>
|
||||
@@ -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);
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
vmm/vmexit.o: vmm\vmexit.c include\utsm\vmx.h include\utsm\types.h \
|
||||
include\utsm\panic.h include\utsm\ept.h include\utsm\vmm.h \
|
||||
include\utsm\hypercall.h include\utsm\ipc_shm.h \
|
||||
..\utsm-ipc\ipc_proto.h include\utsm\log.h include\utsm\dma.h \
|
||||
include\utsm\linux_loader.h include\utsm\linux_xsave.h \
|
||||
include\utsm\virtio_mmio.h include\utsm\instr.h \
|
||||
vmm\..\arch\x86_64\limine.h
|
||||
include\utsm\vmx.h:
|
||||
include\utsm\types.h:
|
||||
include\utsm\panic.h:
|
||||
include\utsm\ept.h:
|
||||
include\utsm\vmm.h:
|
||||
include\utsm\hypercall.h:
|
||||
include\utsm\ipc_shm.h:
|
||||
..\utsm-ipc\ipc_proto.h:
|
||||
include\utsm\log.h:
|
||||
include\utsm\dma.h:
|
||||
include\utsm\linux_loader.h:
|
||||
include\utsm\linux_xsave.h:
|
||||
include\utsm\virtio_mmio.h:
|
||||
include\utsm\instr.h:
|
||||
vmm\..\arch\x86_64\limine.h:
|
||||
+23
-5
@@ -1,4 +1,5 @@
|
||||
#include <utsm/vmm.h>
|
||||
#include <utsm/panic.h>
|
||||
#include <utsm/vmx.h>
|
||||
#include <utsm/ept.h>
|
||||
#include <utsm/log.h>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <utsm/vmx.h>
|
||||
#include <utsm/panic.h>
|
||||
#include <utsm/ept.h>
|
||||
#include <utsm/log.h>
|
||||
#include <utsm/types.h>
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#include <utsm/xj380_loader.h>
|
||||
#include <utsm/panic.h>
|
||||
#include <utsm/vmx.h>
|
||||
#include <utsm/ept.h>
|
||||
#include <utsm/log.h>
|
||||
@@ -86,24 +87,29 @@ static int xj380_parse_elf(const void *img, u64 size,
|
||||
u64 *entry_out, u64 *span_out) {
|
||||
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 无需按需分配) */
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
vmm/xj380_loader.o: vmm\xj380_loader.c include\utsm\xj380_loader.h \
|
||||
include\utsm\types.h include\utsm\panic.h include\utsm\vmx.h \
|
||||
include\utsm\ept.h include\utsm\log.h include\utsm\dma.h \
|
||||
vmm\..\arch\x86_64\limine.h
|
||||
include\utsm\xj380_loader.h:
|
||||
include\utsm\types.h:
|
||||
include\utsm\panic.h:
|
||||
include\utsm\vmx.h:
|
||||
include\utsm\ept.h:
|
||||
include\utsm\log.h:
|
||||
include\utsm\dma.h:
|
||||
vmm\..\arch\x86_64\limine.h:
|
||||
Binary file not shown.
Reference in New Issue
Block a user