From nobody Mon Nov 3 18:05:24 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1529944371960428.1714156486413; Mon, 25 Jun 2018 09:32:51 -0700 (PDT) Received: from localhost ([::1]:48252 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fXUQ3-0000uE-8O for importer@patchew.org; Mon, 25 Jun 2018 12:32:47 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33003) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fXUP7-0000aS-7g for qemu-devel@nongnu.org; Mon, 25 Jun 2018 12:31:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fXUP3-0004Hl-6z for qemu-devel@nongnu.org; Mon, 25 Jun 2018 12:31:49 -0400 Received: from out2-smtp.messagingengine.com ([66.111.4.26]:45527) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fXUP2-0004HE-Vo for qemu-devel@nongnu.org; Mon, 25 Jun 2018 12:31:45 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 7843121B90; Mon, 25 Jun 2018 12:31:43 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Mon, 25 Jun 2018 12:31:43 -0400 Received: from localhost (flamenco.cs.columbia.edu [128.59.20.216]) by mail.messagingengine.com (Postfix) with ESMTPA id D838510268; Mon, 25 Jun 2018 12:31:42 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=braap.org; h=cc :date:from:message-id:subject:to:x-me-sender:x-me-sender :x-sasl-enc; s=mesmtp; bh=CBN4Iy47jmPyaQOztyihOVxwO03iil5RQl0v7s eRTh8=; b=YwvQZTpuopHAgbXhtXo8xzpA8NCW5QSwd8bBz4kKgwBmID4v+eN69U JiaboYgsoRgwqRvPj2dxTVr/yEP4OUkcpXrCFVLGyH/SyI6Z32zxt8bio0ZDNpI9 cRCfwKOj/YsvBE39HuPdkpFLToOJkdDPj8hfRc7d/PY71ab+Zz6FQ= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:date:from:message-id:subject:to :x-me-sender:x-me-sender:x-sasl-enc; s=fm3; bh=CBN4Iy47jmPyaQOzt yihOVxwO03iil5RQl0v7seRTh8=; b=Fprg5b4eJAcM6Gl3mFR3E4Bs4G1BOufDw uxVgHlOYbGOJmcj1g/5DTwJhnI9aEdJ5KaQNRyLMj3Z35UDlxGCTI/nX3l0U1NyM jsHCCNOtQhb/4gvmSDQ/vQe/OTydmeeNcKf+Mjx0nJr0q9ZhifEiOK9WxQMMtEqD V+mP7vtBHEfg2xlgGXleOm3NMB2Ueb3bCtu30nLi3l60b3LJUphEps1rpDDMOq0O tXGD+VWN+6Lc9hTdFnWMzAm07EzuEuB6r8Ygs1r/X/qvG82O/lIlSSVcpqXy9av2 BC28tI0tgtbdeTfhCl+OUZOKZfxclaXXeJVwrbXbTKD58GAIaaP8g== X-ME-Proxy: X-ME-Sender: From: "Emilio G. Cota" To: qemu-devel@nongnu.org Date: Mon, 25 Jun 2018 12:31:42 -0400 Message-Id: <1529944302-14186-1-git-send-email-cota@braap.org> X-Mailer: git-send-email 2.7.4 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.111.4.26 Subject: [Qemu-devel] [PATCH] translate-all: fix locking of TBs whose two pages share the same physical page X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Fam Zheng , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Richard Henderson , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Max Filippov Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Commit 0b5c91f ("translate-all: use per-page locking in !user-mode", 2018-06-15) introduced per-page locking. It assumed that the physical pages corresponding to a TB (at most two pages) are always distinct, which is wrong. For instance, an xtensa test provided by Max Filippov is broken by the commit, since the test maps two virtual pages to the same physical page: virt1: 7fff, virt2: 8000 phys1 6000fff, phys2 6000000 Fix it by removing the assumption from page_lock_pair. If the two physical page addresses are equal, we only lock the PageDesc once. Note that the two callers of page_lock_pair, namely page_unlock_tb and tb_link_page, are also updated so that we do not try to unlock the same PageDesc twice. Fixes: 0b5c91f74f3c83a36f37740969df8c775c997e69 Reported-by: Max Filippov Signed-off-by: Emilio G. Cota Tested-by: Max Filippov Tested-by: Philippe Mathieu-Daud=C3=A9 --- accel/tcg/translate-all.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index f0c3fd4..8e0203e 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -669,9 +669,15 @@ static inline void page_lock_tb(const TranslationBlock= *tb) =20 static inline void page_unlock_tb(const TranslationBlock *tb) { - page_unlock(page_find(tb->page_addr[0] >> TARGET_PAGE_BITS)); + PageDesc *p1 =3D page_find(tb->page_addr[0] >> TARGET_PAGE_BITS); + + page_unlock(p1); if (unlikely(tb->page_addr[1] !=3D -1)) { - page_unlock(page_find(tb->page_addr[1] >> TARGET_PAGE_BITS)); + PageDesc *p2 =3D page_find(tb->page_addr[1] >> TARGET_PAGE_BITS); + + if (p2 !=3D p1) { + page_unlock(p2); + } } } =20 @@ -850,22 +856,34 @@ static void page_lock_pair(PageDesc **ret_p1, tb_page= _addr_t phys1, PageDesc **ret_p2, tb_page_addr_t phys2, int al= loc) { PageDesc *p1, *p2; + tb_page_addr_t page1; + tb_page_addr_t page2; =20 assert_memory_lock(); - g_assert(phys1 !=3D -1 && phys1 !=3D phys2); - p1 =3D page_find_alloc(phys1 >> TARGET_PAGE_BITS, alloc); + g_assert(phys1 !=3D -1); + + page1 =3D phys1 >> TARGET_PAGE_BITS; + page2 =3D phys2 >> TARGET_PAGE_BITS; + + p1 =3D page_find_alloc(page1, alloc); if (ret_p1) { *ret_p1 =3D p1; } if (likely(phys2 =3D=3D -1)) { page_lock(p1); return; + } else if (page1 =3D=3D page2) { + page_lock(p1); + if (ret_p2) { + *ret_p2 =3D p1; + } + return; } - p2 =3D page_find_alloc(phys2 >> TARGET_PAGE_BITS, alloc); + p2 =3D page_find_alloc(page2, alloc); if (ret_p2) { *ret_p2 =3D p2; } - if (phys1 < phys2) { + if (page1 < page2) { page_lock(p1); page_lock(p2); } else { @@ -1623,7 +1641,7 @@ tb_link_page(TranslationBlock *tb, tb_page_addr_t phy= s_pc, tb =3D existing_tb; } =20 - if (p2) { + if (p2 && p2 !=3D p) { page_unlock(p2); } page_unlock(p); --=20 2.7.4