我有一个非常简单的问题,QEMU是否模仿TLB?当guest linux系统执行“invlpg”指令时,会发生什么,因为它是TLB条目的无效。我知道QEMU有softmmu link,它用于将来宾虚拟地址转换为主机虚拟地址,但是QEMU模拟实际的TLB,以及“invlpg”指令的作用是什么。或者QEMU是否忽略了这条指令?
答案 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_page
,INVLPG
。
因此,您可以看到是,{{1}}指令将刷新TLB以获取地址。