QEMU是否模拟TLB?

9
我有一个非常简单的问题,QEMU是否模拟TLB?当客户Linux系统执行“invlpg”指令以使TLB条目无效时会发生什么?我知道QEMU有用于将客户虚拟地址转换为主机虚拟地址的softmmu link,但是QEMU是否模拟实际的TLB,以及“invlpg”指令的效果是什么?还是QEMU只是忽略此指令?
2个回答

11
答案介于“是”和“否”之间。QEMU不尝试模拟实际客户CPU的TLB(这是一种加速从客户虚拟地址到客户物理地址查找的硬件)。但是它实现了自己相当类似的数据结构,称为TLB - 这加速了从客户虚拟地址直接到主机虚拟地址的RAM的查找,或从客户虚拟地址到模拟设备的读/写函数的查找。
由于CPU TLB和QEMU的TLB之间存在相似之处,我们可以使用客户指令使TLB失效或以其他方式操作TLB,作为执行QEMU TLB失效的触发器(这就是helper_invlpg()中tlb_flush_page()调用的操作); 因此,这些指令不是简单的无操作。我们也欺骗客户端并告诉它关于其TLB大小的合理信息,如果它使用cpuid指令查询缓存和TLB信息。但是我们实际上没有对客户端TLB进行建模 - 因此您不会看到与客户端TLB大小相关的性能变化,并且您无法记录有关客户端TLB命中和未命中的信息,并且我们不在具有TLB锁定功能的CPU架构上实施TLB锁定。
最后,“info tlb”监视器命令名称相当错误,因为它实际上显示有关客户端页面表设置的信息,与TLB状态无关。

当您说客户CPU的TLB时,它是否指向在带有vCPU的客户环境中虚拟化的TLB? - Amit Singh Tomar

4

QEMU是否模拟TLB?

是的。


QEMU监视器控制台提供了一个info tlb命令,该命令将

列出TLB(转换后备缓存),即物理内存和虚拟内存之间的映射


CPU仿真文档中有一节说

页面高速缓存在QEMU源代码中称为“TLB”。


在源代码中,即target-i386/cpu.c,我们看到与TLB相关的以下定义:

/* TLB definitions: */

#define L1_DTLB_2M_ASSOC       1
#define L1_DTLB_2M_ENTRIES   255
#define L1_DTLB_4K_ASSOC       1
#define L1_DTLB_4K_ENTRIES   255

#define L1_ITLB_2M_ASSOC       1
#define L1_ITLB_2M_ENTRIES   255
#define L1_ITLB_4K_ASSOC       1
#define L1_ITLB_4K_ENTRIES   255

#define L2_DTLB_2M_ASSOC       0 /* disabled */
#define L2_DTLB_2M_ENTRIES     0 /* disabled */
#define L2_DTLB_4K_ASSOC       4
#define L2_DTLB_4K_ENTRIES   512

#define L2_ITLB_2M_ASSOC       0 /* disabled */
#define L2_ITLB_2M_ENTRIES     0 /* disabled */
#define L2_ITLB_4K_ASSOC       4
#define L2_ITLB_4K_ENTRIES   512

target-i386/translate.c中,我们看到以下代码处理INVLPG指令:

    case 7:
        if (mod != 3) { /* invlpg */
            if (s->cpl != 0) { 
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
            } else {
                gen_update_cc_op(s);
                gen_jmp_im(pc_start - s->cs_base);
                gen_lea_modrm(env, s, modrm);
                gen_helper_invlpg(cpu_env, cpu_A0);
                gen_jmp_im(s->pc - s->cs_base);
                gen_eob(s);
            }
        }

gen_helper_invlpg是在target-i386/misc_helper.c中实现的:

void helper_invlpg(CPUX86State *env, target_ulong addr)
{
    X86CPU *cpu = x86_env_get_cpu(env);

    cpu_svm_check_intercept_param(env, SVM_EXIT_INVLPG, 0); 
    tlb_flush_page(CPU(cpu), addr);
}

这里调用了 tlb_flush_page,该函数实现在cputlb.c中。


所以可以看出,是的INVLPG指令会刷新地址的TLB。


只是一个问题,我想知道是否可以使用QEMU管理和模拟虚拟缓存系统?就像这样的系统:“来自CPU的虚拟地址”->“虚拟缓存(VIVT或VIPT)”->“TLB”->“内存(DRAM)”。而不是传统的系统,即“来自CPU的虚拟地址”->“TLB”->“缓存(PIPT)”->“内存”。 - Alireza Sanaee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接