From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:45814) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QusYa-0007oG-GG for qemu-devel@nongnu.org; Sat, 20 Aug 2011 16:54:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QusYY-0001pp-BN for qemu-devel@nongnu.org; Sat, 20 Aug 2011 16:54:16 -0400 Received: from mail-gw0-f45.google.com ([74.125.83.45]:50814) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QusYY-0001oy-8l for qemu-devel@nongnu.org; Sat, 20 Aug 2011 16:54:14 -0400 Received: by gwb19 with SMTP id 19so2794009gwb.4 for ; Sat, 20 Aug 2011 13:54:12 -0700 (PDT) Message-ID: <4E501EF2.6050406@landley.net> Date: Sat, 20 Aug 2011 15:54:10 -0500 From: Rob Landley MIME-Version: 1.0 References: <20110818063338.GA69924@cs.nctu.edu.tw> In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] The reason behind block linking constraint? List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Max Filippov Cc: qemu-devel@nongnu.org, =?UTF-8?B?6Zmz6Z+L5Lu7?= On 08/18/2011 04:31 AM, Max Filippov wrote: >> Hi, all >> >> I am trying to figure out why QEMU put some constraints on block >> linking (chaining). Take x86 as an example, there are two places >> put constraints on block linking, gen_goto_tb and cpu_exec. >> >> ----------------- gen_goto_tb (target-i386/translate.c) --------------- >> /* 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)) { >> /* jump to same page: we can use a direct jump */ >> tcg_gen_goto_tb(tb_num); >> gen_jmp_im(eip); >> tcg_gen_exit_tb((tcg_target_long)tb + tb_num); >> } else { >> /* jump to another page: currently not optimized */ >> gen_jmp_im(eip); >> gen_eob(s); >> } >> ----------------------------------------------------------------------- >> >> ----------------------- cpu_exec (cpu-exec.c) ------------------------- >> /* see if we can patch the calling TB. When the TB >> spans two pages, we cannot safely do a direct >> jump. */ >> if (next_tb != 0 && tb->page_addr[1] == -1) { >> tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb); >> } >> ----------------------------------------------------------------------- >> >> Is it just because we cannot optimize block linking which crosses page >> boundary, or there are some correctness/safety issues should be considered? > > If we link a TB with another TB from the different page, then the > second TB may disappear when the memory mapping changes and the > subsequent direct jump from the first TB will crash qemu. > > I guess that this usually does not happen in usermode, because the > guest would not modify executable code memory mapping. However I > suppose that this is also possible. Dynamic linking modifies guest code, requiring the page to be retranslated. With lazy binding this can happen at any time, and without PIE executables this can happen to just about any executable page. Rob