From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:42789) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R7wYA-0006Ev-Ey for qemu-devel@nongnu.org; Sun, 25 Sep 2011 17:47:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1R7wY2-0003rl-8w for qemu-devel@nongnu.org; Sun, 25 Sep 2011 17:47:50 -0400 Received: from mail-bw0-f45.google.com ([209.85.214.45]:56548) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R7wY2-0003rf-44 for qemu-devel@nongnu.org; Sun, 25 Sep 2011 17:47:42 -0400 Received: by bkbzv15 with SMTP id zv15so5278437bkb.4 for ; Sun, 25 Sep 2011 14:47:40 -0700 (PDT) From: Max Filippov Date: Mon, 26 Sep 2011 01:47:36 +0400 References: <20110818063338.GA69924@cs.nctu.edu.tw> <20110924070021.GA18146@cs.nctu.edu.tw> In-Reply-To: <20110924070021.GA18146@cs.nctu.edu.tw> MIME-Version: 1.0 Content-Type: Text/Plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <201109260147.37212.jcmvbkbc@gmail.com> Subject: Re: [Qemu-devel] The reason behind block linking constraint? List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: =?utf-8?q?=E9=99=B3=E9=9F=8B=E4=BB=BB?= Cc: qemu-devel@nongnu.org > > I meant TLB change by e.g. tlb_set_page. If you change single page > > mapping then all TBs in that page will be gone. > > This may be the result of e.g. a page swapping, or a task switch. > > You said "all TBs in that page will be gone". Does it mean QEMU will > invalidate those TBs by for example, tb_invalidate_phys_page_range? Or > it just leave those TBs there (without executing them)? Because I don't > see functions like tb_invalidate_phys_page_range are called after > tlb_set_page, I am not sure what "gone" actually means. Well, my explanation sucks. Let's say it other way, more precisely: - you have two pieces of code in different pages, one of them jumps to the other; - and you have two TBs, tb1 for the first piece and tb2 for the second; - and you link them and there's direct jump from tb1 to tb2; - now you change the mapping of the code page that contains second piece of code; - after that there's another code (or no code at all) at the place where the second piece of code used to be; - but the jump to tb2 still remains in tb1. > > If there's no direct link between TBs then softmmu will be used during > > the target TB search and softmmu will generate an appropriate guest > > exception. See cpu_exec -> tb_find_fast -> tb_find_slow -> > > get_page_addr_code. > > > > But if there is a direct link, then softmmu has no chance to do it. > > Let me try to describe the flow. Correct me if I am wrong. Assume tb1 > and tb2 belong to different guest pages. > > If there's NO direct link between tb1 and tb2. After executing tb1, > the control is transfered back to QEMU (cpu_exec), QEMU then call > tb_find_fast to find the next TB, i.e., tb2. Right. > I assume that "all TBs in that page will be gone" means QEMU will > invalidate those TBs. No, it won't. I had to say "all code in that page will be gone", sorry for the confusion. > If not, I think tb_find_fast will return tb2 which should not be executed. It won't either. tb_find_fast searches tb this way: tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)]; but 'page mapping change' implies TLB flush, at least for that page. Both tlb_flush and tlb_flush_page will clear env->tb_jmp_cache and tb_find_fast will have to call tb_find_slow. > So, tb_find_fast calls tb_find_slow, > then tb_find_slow calls get_page_addr_code. > > get_page_addr_code return the guest physical address which > corresponds to the pc (tb2). It looks up TLB (env1->tlb_table), and > get a TLB miss since tlb_set_page has changed the mapping. > > if (unlikely(env1->tlb_table[mmu_idx][page_index].addr_code != > (addr & TARGET_PAGE_MASK))) { > ldub_code(addr); > } > > But I am not sure what happen after the TLB miss. You said the > softmmu will generate a guest exception. Take x86 as an example, > do you mean the raise_exception_err in tlb_fill? > > void tlb_fill(target_ulong addr, ...) { > ret = cpu_x86_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); > if (ret) { > if (retaddr) { > } > } > raise_exception_err(env->exception_index, env->error_code); > } Exactly. The exception will be raised inside the guest and the guest will execute its page fault handler or whatever. Thanks. -- Max