QEMU是否模仿TLB?

时间:2015-03-16 06:21:35

标签: x86 qemu emulation tlb device-emulation

我有一个非常简单的问题,QEMU是否模仿TLB?当guest linux系统执行“invlpg”指令时,会发生什么,因为它是TLB条目的无效。我知道QEMU有softmmu link,它用于将来宾虚拟地址转换为主机虚拟地址,但是QEMU模拟实际的TLB,以及“invlpg”指令的作用是什么。或者QEMU是否忽略了这条指令?

2 个答案:

答案 0 :(得分:4)

答案介于“是”和“否”之间。 QEMU不会尝试模拟实际访客CPU的TLB(这是一个加速从访客虚拟地址到访客物理地址查找的硬件)。然而,它确实实现了自己的相当类似的数据结构,它称之为TLB - 这会加速从客户虚拟地址到RAM的主机虚拟地址的查找,或者从客户虚拟地址到模拟设备的读/写功能。

由于CPU TLB和QEMU的TLB之间存在相似之处,我们可以使用guest虚拟机指令使TLB无效或以其他方式操作作为执行QEMU TLB失效的触发器(这是tlb_flush_page()在helper_invlpg()中调用的内容是在做);所以这些说明不是简单的无操作。如果它使用查询缓存和TLB信息的cpuid指令,我们也会对客户说谎并告诉它有关TLB大小的合理信息。但是我们实际上并没有对来宾TLB进行建模 - 因此您不会看到围绕来宾TLB大小的性能变化,并且您无法记录有关来宾TLB命中和未命中的信息,并且我们没有实现TLB锁定在拥有它的CPU架构上。

最后,监视器“info tlb”命名错误,因为它实际上显示了有关guest虚拟机页面设置的信息,这与TLB状态无关。

答案 1 :(得分:3)

  

QEMU是否模仿TLB?


QEMU监视器控制台提供info tlb命令

  

列出TLB(Translation Lookaside Buffer),即物理内存和虚拟内存之间的映射


CPU emulation documentation有一节说

  

页面缓存称为" TLB"在QEMU来源中。


在源代码中,即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_pageINVLPG


因此,您可以看到,{{1}}指令刷新TLB以获取地址。