Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does QEMU emulate TLB?

I have a very simple question, does QEMU emulate TLB? What happens when a guest linux system executes an "invlpg" instruction as it is for the invalidation of a TLB entry. I am aware that QEMU has softmmu link which is used for translating the guest virtual address to host virtual address but does QEMU emulate an actual TLB, and what is the effect of "invlpg" instruction. Or does QEMU simply ignores this instruction?

like image 405
Naman Patel Avatar asked Mar 16 '15 06:03

Naman Patel


2 Answers

The answer is somewhere between "yes" and "no". QEMU doesn't attempt to emulate the actual guest CPU's TLB (which is a piece of hardware which accelerates lookups from guest virtual addresses to guest physical addresses). However it does implement its own rather similar data structure which it calls a TLB -- this accelerates lookups from guest virtual addresses directly to host virtual addresses for RAM, or from guest virtual addresses to the read/write functions for emulated devices.

Since there are similarities between the CPU TLB and QEMU's TLB, we can use the guest instructions to invalidate or otherwise operate on the TLB as the triggers to perform QEMU TLB invalidations (which is what the tlb_flush_page() call in helper_invlpg() is doing); so these instructions are not simple no-ops. We also lie to the guest and tell it plausible things about the size of its TLB if it uses the cpuid instructions which query cache and TLB information. But we don't actually model the guest TLB -- so you won't see performance changes around the size of the guest TLB, and you can't log information about guest TLB hits and misses, and we don't implement TLB lockdown on CPU architectures that have it.

Finally, the monitor "info tlb" command is rather misnamed, because it's actually displaying information about the guest's page table setup, which is nothing to do with the TLB state.

like image 132
Peter Maydell Avatar answered Oct 19 '22 17:10

Peter Maydell


does QEMU emulate TLB?

Yes.


The QEMU monitor console provides an info tlb command which will

list the TLB (Translation Lookaside Buffer), i.e. mappings between physical memory and virtual memory


The CPU emulation documentation has a section that says

The page cache is called the "TLB" in the QEMU sources.


In the source code, namely target-i386/cpu.c we see the following definitions related to the 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

In target-i386/translate.c, we see the following code handling the INVLPG instruction:

    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 is implemented in 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);
}

where it calls tlb_flush_page, which is implemented in cputlb.c.


So you can see that yes, the INVLPG instruction will flush the TLB for an address.

like image 24
Jonathon Reinhart Avatar answered Oct 19 '22 16:10

Jonathon Reinhart