当前位置:首页>Linux>Linux KVM的初始化过程

Linux KVM的初始化过程

  • 2026-02-07 06:52:25
Linux KVM的初始化过程

kvm_arm_init的初始化过程如下:

static __initintkvm_arm_init(void){    int err;    bool in_hyp_mode;    // 1. 检查硬件虚拟化支持    if (!is_hyp_mode_available()) {        kvm_info("HYP mode not available\n");        return -ENODEV;    }    // 2. 检查KVM是否被禁用    if (kvm_get_mode() == KVM_MODE_NONE) {        kvm_info("KVM disabled from command line\n");        return -ENODEV;    }    // 3. 初始化系统寄存器表    err = kvm_sys_reg_table_init();    in_hyp_mode = is_kernel_in_hyp_mode();    // 4. 设置IPA(中间物理地址)大小限制    err = kvm_set_ipa_limit();    // 5. 初始化SVE支持    err = kvm_arm_init_sve();    // 6. 初始化VMID分配器    err = kvm_arm_vmid_alloc_init();    // 7. 初始化Hypervisor模式(非VHE模式)    if (!in_hyp_mode) {        err = init_hyp_mode();        if (err)            goto out_err;    }    // 8. 初始化向量槽(用于Spectre缓解)    err = kvm_init_vector_slots();    // 9. 初始化子系统(VGIC, timer等)    err = init_subsystems();    // 10. 注册到通用KVM框架    err = kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE);    // 11. 完成Hypervisor初始化    if (!in_hyp_mode)        finalize_init_hyp_mode();    kvm_arm_initialised = true;    return 0;}

首先会调用is_hyp_mode_available,检查硬件虚拟化支持:

/* Reports the availability of HYP mode */staticinlineboolis_hyp_mode_available(void){    /*     * If KVM protected mode is initialized, all CPUs must have been booted     * in EL2. Avoid checking __boot_cpu_mode as CPUs now come up in EL1.     */    if (is_pkvm_initialized())        return true;    return (__boot_cpu_mode[0] == BOOT_CPU_MODE_EL2 &&        __boot_cpu_mode[1] == BOOT_CPU_MODE_EL2);}

__boot_cpu_mode在刚刚进入Linux的汇编代码/arch/arm64/kernel/head.S设置:

SYM_FUNC_START(init_kernel_el)	mrs	x1, CurrentEL	cmp	x1, #CurrentEL_EL2	b.eq	init_el2        ........./* * Sets the __boot_cpu_mode flag depending on the CPU boot mode passed * in w0. See arch/arm64/include/asm/virt.h for more info. */SYM_FUNC_START_LOCAL(set_cpu_boot_mode_flag)	adr_l	x1, __boot_cpu_mode	cmp	w0, #BOOT_CPU_MODE_EL2	b.ne	1fadd	x1, x1, #41:	str	w0, [x1]			// Save CPU boot moderetSYM_FUNC_END(set_cpu_boot_mode_flag)
为什么要判断 "Booted in EL2"? ARM 架构规定:如果你想运行KVM,Linux 内核必须在启动时就已经处于EL2模式。
  • 如果内核启动时在EL1:它只能作为一个普通的操作系统,没有权限去配置Stage-2页表或拦截其他虚拟机的异常。即使硬件支持虚拟化,Linux也无法启动 KVM。

  • 如果内核启动时在EL2:它拥有“最高统治权”。它可以把自己降级到EL1 运行(经典 KVM),或者保持在EL2运行(开启VHE 模式),同时拥有管理虚拟机的权力。

简单说下VHE。VHE (Virtualization Host Extensions) 是 ARMv8.1 架构引入的特性。它的核心目的是:让Type-2 型Hypervisor(如 Linux KVM)能够以近乎原生的性能运行。在没有 VHE 之前,Linux 内核必须运行在 EL1,而 KVM 的核心控制逻辑必须运行在 EL2。这种“跨级办公”导致了巨大的上下文切换开销。

只有启动的时候Linux在EL2才可能开启KVM支持,主要是因为虚拟化需要EL2的例程的支持,但是Linux Kernel是运行在EL1的,那么这里意味着:

  • 安装Hyp Stub:如果探测到是 EL2 启动,内核会安装一套精简的异常向量表(Stub),以便之后KVM能通过HVC指令接管EL2。

  • 开启VHE:如果硬件支持且处于EL2,内核会将变量升级为VHE模式,使得内核可以直接操作虚拟化寄存器。

/arch/arm64/kernel/head.S:

/* Hypervisor stub */adr_l	x0, __hyp_stub_vectorsmsr	vbar_el2, x0isb

Hyp Stub定义在/arch/arm64/kernel/hyp-stub.S,主要是HVC调用elx_sync:

SYM_CODE_START(__hyp_stub_vectors)	ventry	el2_sync_invalid		// Synchronous EL2t	ventry	el2_irq_invalid			// IRQ EL2t	ventry	el2_fiq_invalid			// FIQ EL2t	ventry	el2_error_invalid		// Error EL2t	ventry	elx_sync			// Synchronous EL2h	ventry	el2_irq_invalid			// IRQ EL2h	ventry	el2_fiq_invalid			// FIQ EL2h	ventry	el2_error_invalid		// Error EL2h	ventry	elx_sync			// Synchronous 64-bit EL1	ventry	el1_irq_invalid			// IRQ 64-bit EL1	ventry	el1_fiq_invalid			// FIQ 64-bit EL1	ventry	el1_error_invalid		// Error 64-bit EL1	ventry	el1_sync_invalid		// Synchronous 32-bit EL1	ventry	el1_irq_invalid			// IRQ 32-bit EL1	ventry	el1_fiq_invalid			// FIQ 32-bit EL1	ventry	el1_error_invalid		// Error 32-bit EL1SYM_CODE_END(__hyp_stub_vectors)
接着,kvm_arm_init会判断kvm_mode是否被设置成了NONE。kvm_mode可以在Linux内核启动的命令行参数设置:
staticint __init early_kvm_mode_cfg(char *arg){    if (!arg)        return -EINVAL;    if (strcmp(arg, "none") == 0) {        kvm_mode = KVM_MODE_NONE;        return 0;    }    if (!is_hyp_mode_available()) {        pr_warn_once("KVM is not available. Ignoring kvm-arm.mode\n");        return 0;    }    if (strcmp(arg, "protected") == 0) {        if (!is_kernel_in_hyp_mode())            kvm_mode = KVM_MODE_PROTECTED;        else            pr_warn_once("Protected KVM not available with VHE\n");        return 0;    }    if (strcmp(arg, "nvhe") == 0 && !WARN_ON(is_kernel_in_hyp_mode())) {        kvm_mode = KVM_MODE_DEFAULT;        return 0;    }    if (strcmp(arg, "nested") == 0 && !WARN_ON(!is_kernel_in_hyp_mode())) {        kvm_mode = KVM_MODE_NV;        return 0;    }    return -EINVAL;}early_param("kvm-arm.mode", early_kvm_mode_cfg);
这几种模式总结如下:
模式描述运行级别核心语义

KVM_MODE_DEFAULT 

VHELinux Kernel @ EL2高性能模式。内核直接跑在EL2,Host 和Guest 切换开销极小。ARMv8.1+ 标配。
Non-VHELinux Kernel @ EL1传统模式。内核跑在 EL1,通过 Hyp-stub 与 EL2 交互。适用于较旧的 ARMv8.0 硬件。
ProtectedpKVM (Protected KVM)Linux Kernel@ EL1 / Hyp @ EL2Google 为Android 设计的安全加强模式。EL2 变成了一个“安全代理”,即使Host内核(Linux)被攻破,也无法访问Guest虚拟机的内存。
NestedNested VirtualizationGuest @ EL1/EL2嵌套虚拟化。允许在虚拟机里再跑一个虚拟机(在 VM 里跑 KVM)。需要硬件支持 ARMv8.3+。
接下来调用kvm_sys_reg_table_init。ARM处理器的寄存器排序成列表的形式,虚拟机访问的时候,会Trap到Linux Kernel,进行处理。kvm_sys_reg_table_init检查列表是否按照一定顺序
int __initkvm_sys_reg_table_init(void){    const struct sys_reg_desc *gicv3_regs;    bool valid = true;    unsigned int i, sz;    int ret = 0;    /* ========== 步骤1: 验证所有系统寄存器表 ========== */    // 验证主系统寄存器表(需要reset检查)    valid &= check_sysreg_table(sys_reg_descs,                                 ARRAY_SIZE(sys_reg_descs),                                 true);    // 验证CP14协处理器寄存器表(用于AArch32兼容)    valid &= check_sysreg_table(cp14_regs,                                 ARRAY_SIZE(cp14_regs),                                 false);    // 验证CP14 64位寄存器表    valid &= check_sysreg_table(cp14_64_regs,                                 ARRAY_SIZE(cp14_64_regs),                                 false);    // 验证CP15协处理器寄存器表    valid &= check_sysreg_table(cp15_regs,                                 ARRAY_SIZE(cp15_regs),                                 false);    // 验证CP15 64位寄存器表    valid &= check_sysreg_table(cp15_64_regs,                                 ARRAY_SIZE(cp15_64_regs),                                 false);    // 验证系统指令描述符表    valid &= check_sysreg_table(sys_insn_descs,                                 ARRAY_SIZE(sys_insn_descs),                                 false);    // 获取并验证GICv3系统寄存器表    gicv3_regs = vgic_v3_get_sysreg_table(&sz);    valid &= check_sysreg_table(gicv3_regs, sz, false);    // 如果任何表验证失败,返回错误    if (!valid)        return -EINVAL;    /* ========== 步骤2: 初始化实现相关ID寄存器 ========== */    init_imp_id_regs();    /* ========== 步骤3: 配置嵌套虚拟化陷入 ========== */    ret = populate_nv_trap_config();    /* ========== 步骤4: 检查特性映射完整性 ========== */    check_feature_map();    /* ========== 步骤5: 为系统寄存器填充配置 ========== */    // 填充主系统寄存器表的配置    for (i = 0; !ret && i < ARRAY_SIZE(sys_reg_descs); i++)        ret = populate_sysreg_config(sys_reg_descs + i, i);    // 填充系统指令表的配置    for (i = 0; !ret && i < ARRAY_SIZE(sys_insn_descs); i++)        ret = populate_sysreg_config(sys_insn_descs + i, i);    return ret;}
其中sys_reg_descs列表示例如下,是个大数组:
static const struct sys_reg_desc sys_reg_descs[] = {    // 1. 调试寄存器 (DBGBCR, DBGBVR, DBGWCR, DBGWVR)    DBG_BCR_BVR_WCR_WVR_EL1(0),    DBG_BCR_BVR_WCR_WVR_EL1(1),    // ... 共16组    // 2. 调试控制寄存器    { SYS_DESC(SYS_MDCCINT_EL1), trap_debug_regs, reset_val, ... },    { SYS_DESC(SYS_MDSCR_EL1), trap_debug_regs, reset_val, ... },    // 3. 实现相关ID寄存器    IMPLEMENTATION_ID(MIDR_EL1, GENMASK_ULL(310)),    { SYS_DESC(SYS_MPIDR_EL1), NULL, reset_mpidr, MPIDR_EL1 },    IMPLEMENTATION_ID(REVIDR_EL1, GENMASK_ULL(630)),    // 4. AArch32 ID寄存器映射    AA32_ID_WRITABLE(ID_PFR0_EL1),    AA32_ID_WRITABLE(ID_PFR1_EL1),    // ...    // 5. AArch64 ID寄存器    ID_FILTERED(ID_AA64PFR0_EL1, id_aa64pfr0_el1, ~(...)),    ID_FILTERED(ID_AA64PFR1_EL1, id_aa64pfr1_el1, ~(...)),    // ...    // 6. 通用系统控制寄存器    { SYS_DESC(SYS_SCTLR_EL1), access_vm_reg, reset_val, SCTLR_EL1, 0x00C50078 },    { SYS_DESC(SYS_CPACR_EL1), NULL, reset_val, CPACR_EL1, 0 },    { SYS_DESC(SYS_TTBR0_EL1), access_vm_reg, reset_unknown, TTBR0_EL1 },    { SYS_DESC(SYS_TTBR1_EL1), access_vm_reg, reset_unknown, TTBR1_EL1 },    { SYS_DESC(SYS_TCR_EL1), access_vm_reg, reset_val, TCR_EL1, 0 },    // 7. 异常处理寄存器    { SYS_DESC(SYS_ESR_EL1), access_vm_reg, reset_unknown, ESR_EL1 },    { SYS_DESC(SYS_FAR_EL1), access_vm_reg, reset_unknown, FAR_EL1 },    { SYS_DESC(SYS_PAR_EL1), NULL, reset_unknown, PAR_EL1 },    // 8. 内存属性寄存器    { SYS_DESC(SYS_MAIR_EL1), access_vm_reg, reset_unknown, MAIR_EL1 },    { SYS_DESC(SYS_AMAIR_EL1), access_vm_reg, reset_amair_el1, AMAIR_EL1 },    // 9. 上下文ID寄存器    { SYS_DESC(SYS_CONTEXTIDR_EL1), access_vm_reg, reset_val, CONTEXTIDR_EL1, 0 },    { SYS_DESC(SYS_TPIDR_EL1), NULL, reset_unknown, TPIDR_EL1 },    // 10. 性能监控寄存器    { PMU_SYS_REG(PMCR_EL0), .access = access_pmcr, .reset = reset_pmcr, ... },    { PMU_SYS_REG(PMCNTENSET_EL0), .access = access_pmcnten, ... },    // ...    // 11. 通用定时器寄存器    { SYS_DESC(SYS_CNTKCTL_EL1), NULL, reset_val, CNTKCTL_EL10},    { SYS_DESC(SYS_CNTP_TVAL_EL0), access_arch_timer },    { SYS_DESC(SYS_CNTP_CTL_EL0), access_arch_timer },    { SYS_DESC(SYS_CNTP_CVAL_EL0), access_arch_timer },    // 12. 虚拟定时器寄存器    { SYS_DESC(SYS_CNTV_TVAL_EL0), access_arch_timer },    { SYS_DESC(SYS_CNTV_CTL_EL0), access_arch_timer },    { SYS_DESC(SYS_CNTV_CVAL_EL0), access_arch_timer },    // 13. 指针认证寄存器    { SYS_DESC(SYS_APIAKEYLO_EL1), NULL, reset_unknown, APIAKEYLO_EL1 },    { SYS_DESC(SYS_APIAKEYHI_EL1), NULL, reset_unknown, APIAKEYHI_EL1 },    // ...    // 14. SVE寄存器    { SYS_DESC(SYS_ZCR_EL1), NULL, reset_val, ZCR_EL1, 0, .visibility = sve_visibility },    // 15. MTE寄存器    { SYS_DESC(SYS_TFSRE0_EL1), undef_access },    { SYS_DESC(SYS_TFSR_EL1), undef_access },    { SYS_DESC(SYS_RGSR_EL1), undef_access },    { SYS_DESC(SYS_GCR_EL1), undef_access },    // ... 更多寄存器};

虚拟机里面CPU发出的访问,需要经过两个阶段的转换,第二个阶段GPA(Guest Physical Address或者IPA即Intermediate Physical Address)到HPA(Host Physical Address)的转换,其页表配置由KVM完成:

kvm_set_ipa_limit主要设置Linux在进行第二个阶段转换的时候的限制,要保证从Guest出来的配置比如页面大小与第二个阶段支持的配置相匹配:

int __init kvm_set_ipa_limit(void){    unsigned int parange;    u64 mmfr0;    /* ========== 步骤1: 读取CPU物理地址范围能力 ========== */    // 读取ID_AA64MMFR0_EL1寄存器    // 这个寄存器描述了ARMv8内存模型特性    mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);    // 提取PARange字段 (bits [3:0])    // PARange定义了物理地址的范围    parange = cpuid_feature_extract_unsigned_field(mmfr0,                        ID_AA64MMFR0_EL1_PARANGE_SHIFT);    /* ========== 步骤2: 检查LPA2支持并调整PARange ========== */    /*     * 对于4K和16K页面大小,超过48位的IPA大小     * 只有在LPA2可用时才支持。     * 如果我们有LPA2,启用它,否则限制到48位,     * 即使系统报告支持更大的范围。     */    if (!kvm_lpa2_is_enabled() && PAGE_SIZE != SZ_64K)        parange = min(parange, (unsigned int)ID_AA64MMFR0_EL1_PARANGE_48);    /* ========== 步骤3: 检查Stage-2页表粒度支持 ========== */    /*     * 使用ARMv8.5-GTG检查我们的PAGE_SIZE     * 在Stage-2是否被支持。如果不支持,系统将快速停止。     */    switch (cpuid_feature_extract_unsigned_field(mmfr0,                 ID_AA64MMFR0_EL1_TGRAN_2_SHIFT)) {    case ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_NONE:        // Stage-2不支持当前PAGE_SIZE        kvm_err("PAGE_SIZE not supported at Stage-2, giving up\n");        return -EINVAL;    case ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_DEFAULT:        // 使用默认支持        kvm_debug("PAGE_SIZE supported at Stage-2 (default)\n");        break;    case ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_MIN ...          ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_MAX:        // 明确声明支持        kvm_debug("PAGE_SIZE supported at Stage-2 (advertised)\n");        break;    default:        // 无效的TGRAN_2值        kvm_err("Unsupported value for TGRAN_2, giving up\n");        return -EINVAL;    }    /* ========== 步骤4: 计算并设置IPA限制 ========== */    // 将PARange值转换为实际的物理地址位数    kvm_ipa_limit = id_aa64mmfr0_parange_to_phys_shift(parange);    // 输出信息    kvm_info("IPA Size Limit: %d bits%s\n", kvm_ipa_limit,             ((kvm_ipa_limit < KVM_PHYS_SHIFT) ?              " (Reduced IPA size, limited VM/VMM compatibility)" : ""));    return 0;}

kvm_arm_init_sve 函数的主要任务是:探测物理CPU的SVE能力,并决定是否允许虚拟机使用SVE。SVE (Scalable Vector Extension)是ARMv8.2-A架构引入的一项扩展。

为什么 KVM 需要特别处理 SVE? 这涉及到上下文切换(Context Switch)的开销:SVE 寄存器(Z0-Z31)非常大,一次上下文切换要保存/恢复的数据量很大。只有当虚拟机真的在用SVE 指令时才去切换这些大寄存器,否则会严重拖慢CPU效率。

kvm_arm_vmid_alloc_init读取系统寄存器ID_AA64MMFR1_EL1,确认硬件支持多少位的VMID。初始化一个位图来记录哪些VMID已经被分配,哪些是空闲的。

staticinlineunsignedintkvm_get_vmid_bits(void){    int reg = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);    return get_vmid_bits(reg);}/* * Initialize the VMID allocator */int __init kvm_arm_vmid_alloc_init(void){    kvm_arm_vmid_bits = kvm_get_vmid_bits();    /*     * Expect allocation after rollover to fail if we don't have     * at least one more VMID than CPUs. VMID #0 is always reserved.     */    WARN_ON(NUM_USER_VMIDS - 1 <= num_possible_cpus());    atomic64_set(&vmid_generation, VMID_FIRST_VERSION);    vmid_map = bitmap_zalloc(NUM_USER_VMIDS, GFP_KERNEL);    if (!vmid_map)        return -ENOMEM;    return 0;}
kvm_arm_init在VHE模式下,Linux内核直接运行在EL2,该函数不会调用。在会VHE模式下,kvm_arm_init负责在EL2安装一个名为"World Switcher"的小程序,专门负责CPU上下文在Host和Guest之间来回切换,这里暂且略过:
static __always_inline boolis_kernel_in_hyp_mode(void){    BUILD_BUG_ON(__is_defined(__KVM_NVHE_HYPERVISOR__) ||             __is_defined(__KVM_VHE_HYPERVISOR__));    return read_sysreg(CurrentEL) == CurrentEL_EL2;}/* Initialize Hyp-mode and memory mappings on all CPUs */static __initintkvm_arm_init(void){    ...........    in_hyp_mode = is_kernel_in_hyp_mode();    ...........    if (!in_hyp_mode) {        err = init_hyp_mode();        if (err)            goto out_err;    }    ...........}
在ARM64架构中,当虚拟机发生异常退出(Trap)时,硬件会跳转到EL2的异常向量表(Exception Vector Table)。传统做法中所有CPU核心共享一个全局的异常向量表地址,这会产生漏洞风险,攻击者可以通过分支目标缓冲区(BTB)污染,预测到Host向量表的跳转地址,从而窃取Host内存数据(即Spectre变体2,幽灵漏洞)。

kvm_init_vector_slots的主要职责是为系统中的每个物理CPU分配并初始化专门的向量表插槽(Vector Slots)。

staticintkvm_init_vector_slots(void){    int err;    void *base;    /* ========== 步骤1: 初始化直接向量槽位 ========== */    // 获取主向量表的Hypervisor虚拟地址    base = kern_hyp_va(kvm_ksym_ref(__kvm_hyp_vector));    // 初始化HYP_VECTOR_DIRECT槽位    // 这是默认的向量表,不需要Spectre缓解    kvm_init_vector_slot(base, HYP_VECTOR_DIRECT);    /* ========== 步骤2: 初始化Spectre直接向量槽位 ========== */    // 获取Spectre缓解向量表的Hypervisor虚拟地址    base = kern_hyp_va(kvm_ksym_ref(__bp_harden_hyp_vecs));    // 初始化HYP_VECTOR_SPECTRE_DIRECT槽位    // 使用SMC调用进行分支预测器加固    kvm_init_vector_slot(base, HYP_VECTOR_SPECTRE_DIRECT);    /* ========== 步骤3: 创建idmap映射 (条件性) ========== */    /*     * 如果系统需要身份映射的向量表,并且不是Protected KVM模式,     * 则在idmap页面旁边创建特殊的映射     */    if (kvm_system_needs_idmapped_vectors() &&        !is_protected_kvm_enabled()) {        // 在idmap区域创建可执行映射        err = create_hyp_exec_mappings(__pa_symbol(__bp_harden_hyp_vecs),                                       __BP_HARDEN_HYP_VECS_SZ, &base);        if (err)            return err;    }    /* ========== 步骤4: 初始化间接向量槽位 ========== */    // 使用前面获取的base地址(可能是idmap映射)    // 初始化HYP_VECTOR_INDIRECT槽位    // 通过idmap区域的特殊映射间接跳转    kvm_init_vector_slot(base, HYP_VECTOR_INDIRECT);    // 初始化HYP_VECTOR_SPECTRE_INDIRECT槽位    // 结合idmap间接跳转和SMC Spectre缓解    kvm_init_vector_slot(base, HYP_VECTOR_SPECTRE_INDIRECT);    return 0;}
init_subsystems建立Host与虚拟化硬件之间的通信协议。它告诉中断控制器(GIC)、定时器(Timer)等:“我要开始搞虚拟化了,请把你们的虚拟化支持接口准备好。”
    • 初始化中断控制器 (VGIC): 探测物理GIC(如 GICv3/v4)的虚拟化控制接口,映射GICH(Hypervisor 控制寄存器)供 EL2 使用

    • 初始化通用定时器 (Arch Timer): 让虚拟机可以直接访问自己的虚拟定时器(Virtual Timer),而无需每次读取时间都 Trap 到宿主机

    ARM64的定时器分配如下:

    物理定时器 (Physical Timer):├── EL1 Physical Timer (CNTP)│   └── 宿主机和Guest都可使用└── EL2 Physical Timer (CNTHP)    └── 仅Hypervisor使用虚拟定时器 (Virtual Timer):├── EL1 Virtual Timer (CNTV)│   └── Guest使用,可以被trap└── EL2 Virtual Timer (CNTHV)    └── Nested virtualization使用
    static int __initinit_subsystems(void){    int err = 0;    /* ========== 步骤1: 在所有CPU上启用Hypervisor ========== */    /*     * 启用硬件,以便子系统初始化可以访问EL2。     */    on_each_cpu(cpu_hyp_init, NULL, 1);    /* ========== 步骤2: 注册CPU低功耗通知器 ========== */    /*     * 注册CPU低功耗通知器     */    hyp_cpu_pm_init();    /* ========== 步骤3: 初始化VGIC的Hypervisor视图 ========== */    /*     * 初始化VGIC的HYP视图     */    err = kvm_vgic_hyp_init();    switch (err) {    case 0:        // 成功初始化VGIC        vgic_present = true;        break;    case -ENODEV:    case -ENXIO:        /*         * 没有VGIC? 没有pKVM。         *         * Protected模式假设GICv3存在,所以如果vgic初始化失败,         * 就没有必要尝试继续。         */        if (is_protected_kvm_enabled())            goto out;        /*         * 否则,用户空间可以选择在非协作硬件上         * 为其guest实现GIC。         */        vgic_present = false;        err = 0;        break;    default:        // 其他错误,直接退出        goto out;    }    /* ========== 步骤4: 检查嵌套虚拟化的VGIC要求 ========== */    .........     /* ========== 步骤5: 初始化Hypervisor架构定时器支持 ========== */    /*     * 初始化HYP架构定时器支持     */    err = kvm_timer_hyp_init(vgic_present);    /* ========== 步骤6: 注册性能监控回调 ========== */    kvm_register_perf_callbacks(NULL);    return err;}
    kvm_init主要是创建vCPU的slab缓存;初始化通用KVM子系统 (irqfd、async_pf、vfio等);注册 /dev/kvm字符设备。

    async_pf是异步缺页处理;irqfd机制允许用户空间通过eventfd注入中断,绕过ioctl调用以提高性能,可用于设备直通 (VFIO):

    intkvm_init(unsigned vcpu_size, unsigned vcpu_align, structmodule *module){    int r;    int cpu;    /* ========== 步骤1: 创建vCPU slab缓存 ========== */    /* kmem cache让我们满足fx_save的对齐要求 */    if (!vcpu_align)        vcpu_align = __alignof__(struct kvm_vcpu);    kvm_vcpu_cache =        kmem_cache_create_usercopy("kvm_vcpu", vcpu_size, vcpu_align,                                   SLAB_ACCOUNT,                                   offsetof(struct kvm_vcpu, arch),                                   offsetofend(struct kvm_vcpu, stats_id)                                   - offsetof(struct kvm_vcpu, arch),                                   NULL);    /* ========== 步骤2: 为每个CPU分配kick掩码 ========== */    for_each_possible_cpu(cpu) {        if (!alloc_cpumask_var_node(&per_cpu(cpu_kick_mask, cpu),                                    GFP_KERNEL, cpu_to_node(cpu))) {            r = -ENOMEM;            goto err_cpu_kick_mask;        }    }    /* ========== 步骤3: 初始化irqfd子系统 ========== */    r = kvm_irqfd_init();    /* ========== 步骤4: 初始化异步缺页子系统 ========== */    r = kvm_async_pf_init();    /* ========== 步骤5: 设置文件操作所有者 ========== */    kvm_chardev_ops.owner = module;    kvm_vm_fops.owner = module;    kvm_vcpu_fops.owner = module;    kvm_device_fops.owner = module;    /* ========== 步骤6: 设置抢占操作 ========== */    kvm_preempt_ops.sched_in = kvm_sched_in;    kvm_preempt_ops.sched_out = kvm_sched_out;    /* ========== 步骤7: 初始化调试文件系统 ========== */    kvm_init_debug();    /* ========== 步骤8: 初始化VFIO操作 ========== */    r = kvm_vfio_ops_init();    /* ========== 步骤9: 初始化Guest内存文件 ========== */    kvm_gmem_init(module);    /* ========== 步骤10: 初始化虚拟化 ========== */    r = kvm_init_virtualization();    /* ========== 步骤11: 注册misc设备 ========== */    /*     * 注册_必须_是最后完成的事情,因为这会将/dev/kvm暴露给     * 用户空间,即所有基础设施都必须设置好!     */    r = misc_register(&kvm_dev);    return 0;}

    最新文章

    随机文章

    基本 文件 流程 错误 SQL 调试
    1. 请求信息 : 2026-02-07 19:56:37 HTTP/2.0 GET : https://f.mffb.com.cn/a/471963.html
    2. 运行时间 : 0.807465s [ 吞吐率:1.24req/s ] 内存消耗:4,991.05kb 文件加载:140
    3. 缓存信息 : 0 reads,0 writes
    4. 会话信息 : SESSION_ID=ac3c54af6ef80300de473f30aa18de37
    1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
    2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
    3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
    4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
    5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
    6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
    7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
    8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
    9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
    10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
    11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
    12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
    13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
    14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
    15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
    16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
    17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
    18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
    19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
    20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
    21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
    22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
    23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
    24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
    25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
    26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
    27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
    28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
    29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
    30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
    31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
    32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
    33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
    34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
    35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
    36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
    37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
    38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
    39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
    40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
    41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
    42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
    43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
    44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
    45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
    46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
    47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
    48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
    49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
    50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
    51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
    52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
    53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
    54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
    55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
    56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
    57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
    58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
    59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
    60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
    61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
    62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
    63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
    64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
    65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
    66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
    67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
    68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
    69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
    70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
    71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
    72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
    73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
    74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
    75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
    76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
    77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
    78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
    79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
    80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
    81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
    82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
    83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
    84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
    85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
    86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
    87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
    88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
    89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
    90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
    91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
    92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
    93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
    94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
    95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
    96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
    97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
    98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
    99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
    100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
    101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
    102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
    103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
    104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
    105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
    106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
    107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
    108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
    109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
    110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
    111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
    112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
    113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
    114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
    115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
    116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
    117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
    118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
    119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
    120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
    121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
    122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
    123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
    124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
    125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
    126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
    127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
    128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
    129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
    130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
    131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
    132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
    133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
    134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
    135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
    136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
    137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
    138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
    139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
    140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
    1. CONNECT:[ UseTime:0.000521s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
    2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000566s ]
    3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.100630s ]
    4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.100794s ]
    5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000623s ]
    6. SELECT * FROM `set` [ RunTime:0.038285s ]
    7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000599s ]
    8. SELECT * FROM `article` WHERE `id` = 471963 LIMIT 1 [ RunTime:0.100711s ]
    9. UPDATE `article` SET `lasttime` = 1770465398 WHERE `id` = 471963 [ RunTime:0.223504s ]
    10. SELECT * FROM `fenlei` WHERE `id` = 67 LIMIT 1 [ RunTime:0.016232s ]
    11. SELECT * FROM `article` WHERE `id` < 471963 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.048794s ]
    12. SELECT * FROM `article` WHERE `id` > 471963 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.001747s ]
    13. SELECT * FROM `article` WHERE `id` < 471963 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.051314s ]
    14. SELECT * FROM `article` WHERE `id` < 471963 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.026044s ]
    15. SELECT * FROM `article` WHERE `id` < 471963 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.009391s ]
    0.811210s