У меня очень простой вопрос, QEMU эмулирует TLB? Что происходит, когда гостевая система Linux выполняет инструкцию «invlpg», поскольку она предназначена для аннулирования записи TLB. Я знаю, что в QEMU есть ссылка, который используется для преобразования виртуального адреса гостя в виртуальный адрес хоста, но QEMU эмулирует фактический TLB, и каков эффект инструкции «invlpg». Или QEMU просто игнорирует эту инструкцию?
Эмулирует ли QEMU TLB?
Ответы (2)
Ответ находится где-то между «да» и «нет». QEMU не пытается эмулировать фактический TLB гостевого процессора (который представляет собой аппаратное обеспечение, ускоряющее поиск с виртуальных гостевых адресов на гостевые физические адреса). Однако он реализует свою собственную довольно похожую структуру данных, которую он называет TLB — это ускоряет поиск с гостевых виртуальных адресов непосредственно на виртуальные адреса хоста для оперативной памяти или с гостевых виртуальных адресов на функции чтения/записи для эмулируемых устройств.
Поскольку между CPU TLB и TLB QEMU есть сходство, мы можем использовать гостевые инструкции для аннулирования TLB или иных операций с TLB в качестве триггеров для выполнения аннулирования QEMU TLB (что и делает вызов tlb_flush_page() в helper_invlpg()). ; так что эти инструкции не простые бездействия. Мы также лжем гостю и сообщаем ему правдоподобные вещи о размере его TLB, если он использует инструкции cpuid, которые запрашивают информацию о кеше и TLB. Но на самом деле мы не моделируем гостевой TLB, поэтому вы не увидите изменений производительности в зависимости от размера гостевого TLB, и вы не можете регистрировать информацию о попаданиях и промахах гостевого TLB, и мы не реализуем блокировку TLB. на архитектурах ЦП, в которых он есть.
Наконец, команда монитора «info tlb» названа довольно неправильно, поскольку на самом деле она отображает информацию о настройке таблицы страниц гостя, которая не имеет ничего общего с состоянием TLB.
QEMU эмулирует TLB?
Да
Консоль монитора QEMU предоставляет команду info tlb
, которая
перечислить TLB (трансляционный резервный буфер), то есть сопоставления между физической памятью и виртуальной памятью
В документации по эмуляции процессора есть раздел, в котором говорится
Кэш страниц называется «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
, который реализован в cputlb.c
.
Итак, вы видите, что да, инструкция INVLPG
будет очищать TLB для адреса.