> I've made a test from the grub multiboot sample, you may find it here: > http://jcmvbkbc.spb.ru/git/?p=dumb/qemu-test-kernel.git;a=summary > > With it I see that an attempt to execute a TB that spans two pages causes > an exception when the second page is unmapped. It happens because both > tlb_flush and tlb_flush_page invalidate relevant tb_jmp_cache entries: > the former flushes all of them, the latter flushes them for two adjacent pages > around the given address. Later tb_find_fast fails to find a TB in the > tb_jmp_cache and has to call tb_find_slow which retranslates TB, triggering > a pagefault.
Thanks for the example, Max. But..., I want to repeat the experiment you did and cannot figure out how to do that. Would you mind to give me some hints? For example, how did you locate the TB spanning pages whose second page happened to be unmapped? Also, I found something interesting in function cpu_exec (cpu-exec.c). The code snip below will do block linking only when the target tb does NOT span guest pages. Is it necessary? According to your observation, it seems QEMU handle tb spanning pages appropriately, why it still needs to check if the target tb spanning guest pages? --- if (next_tb != 0 && tb->page_addr[1] == -1) { ^^^^^^^^^^^^^^^^^^^^^^ tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb); } --- Finally, does the comment on gen_goto_tb (target-i386/translate.c) still hold? Maybe we should change it to something like "we handle the case where the block linking spans two pages here"? --- /* NOTE: we handle the case where the TB spans two pages here */ if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) || (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK)) { } --- Thanks! Regards, chenwj -- Wei-Ren Chen (陳韋任) Computer Systems Lab, Institute of Information Science, Academia Sinica, Taiwan (R.O.C.) Tel:886-2-2788-3799 #1667 Homepage: http://people.cs.nctu.edu.tw/~chenwj