From patchwork Fri Jul 8 20:38:39 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 9221793 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 215376044F for ; Fri, 8 Jul 2016 20:43:32 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 13702284DD for ; Fri, 8 Jul 2016 20:43:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 08079284DF; Fri, 8 Jul 2016 20:43:32 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7BC61284DD for ; Fri, 8 Jul 2016 20:43:31 +0000 (UTC) Received: from localhost ([::1]:47789 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bLccU-0005N3-MR for patchwork-qemu-devel@patchwork.kernel.org; Fri, 08 Jul 2016 16:43:30 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58403) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bLcYQ-0000T0-U1 for qemu-devel@nongnu.org; Fri, 08 Jul 2016 16:39:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bLcYP-0003PH-LF for qemu-devel@nongnu.org; Fri, 08 Jul 2016 16:39:18 -0400 Received: from mail-qt0-x244.google.com ([2607:f8b0:400d:c0d::244]:34702) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bLcYP-0003P1-GY for qemu-devel@nongnu.org; Fri, 08 Jul 2016 16:39:17 -0400 Received: by mail-qt0-x244.google.com with SMTP id c52so152416qte.1 for ; Fri, 08 Jul 2016 13:39:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=L7BlY6ffvC12FPGe55OHo/BHSv7pfNTMet6cwwLOw60=; b=wOdom4co4bqAbA9r/4NomWfEsdm2lkowhwMtZCZ2630XXNS/b5kEdmiAVOZVo7LS6M 5oBAZE7N83faDaYqWxWi2vgTSry6hxnPliP1DjoVdL53+u3zcOrGcBidzYAN2UGgtvJE oeplXNF9SVLPi+JW2TfoAYibXf/a4MRNrAcIfTEJfc/z5Nskb/PyEWL7BavKxQP12qbC GfzjKSGtHfcHDSHYAxKEycFopgxBDrsSdcJiZoEX2+zEP36SBZjy/ydxOnyAVPJg58cT 3R60GYWN7/q0YTntBvbtX2phMlVHoCGdwZmFiygwsS+srbV/AbvhPn+HeFK0G6OhzmGr doPg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=L7BlY6ffvC12FPGe55OHo/BHSv7pfNTMet6cwwLOw60=; b=f9mg+EkHu1GjOur4/aVansvTUvYhCcm4/hf/Q7EX/oTmlxEajf0uEMAcuM5JVTtBYy Ixh/dVyklIH9L01lyQhcQSMegWUA+tnVCYUvwhMQVXSZZEgRTHbH9UMx987u8YMNto1e VUwDc0Qvs+a92r/2OV+2G85oe8ckAjk72Nuw+4/DEBp8jrXCzttq+LAJwnRtXLQm11OD sx3TkJe6PmCJZvhU8MdOnXo3hiVKIHlh5eD1njTwfSz4RPkPe3KoAVRre6z4AjlVp3To U/cNg3/RZYHwecL17k8D/hy4/XtN1ttsekTYDjb2dF/b5fS1/57wXRJOo4za/gVLFVN5 /PBQ== X-Gm-Message-State: ALyK8tKIvimI7kRQL/FNsYeraKKSt6eOm6f7eh7KZ7F74k+QhZbK84HgHLbvk5k4s+jM0Q== X-Received: by 10.200.45.178 with SMTP id p47mr11674194qta.27.1468010356949; Fri, 08 Jul 2016 13:39:16 -0700 (PDT) Received: from bigtime.com (71-37-54-227.tukw.qwest.net. [71.37.54.227]) by smtp.gmail.com with ESMTPSA id f53sm1359944qtf.25.2016.07.08.13.39.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 08 Jul 2016 13:39:16 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Fri, 8 Jul 2016 13:38:39 -0700 Message-Id: <1468010319-16494-5-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1468010319-16494-1-git-send-email-rth@twiddle.net> References: <1468010319-16494-1-git-send-email-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400d:c0d::244 Subject: [Qemu-devel] [PULL 4/4] translate-all: Fix user-mode self-modifying code in 2 page long TB 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: peter.maydell@linaro.org, Stanislav Shmarov Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Stanislav Shmarov In user-mode emulation Translation Block can consist of 2 guest pages. In that case QEMU also mprotects 2 host pages that are dedicated for guest memory, containing instructions. QEMU detects self-modifying code with SEGFAULT signal processing. In case if instruction in 1st page is modifying memory of 2nd page (or vice versa) QEMU will mark 2nd page with PAGE_WRITE, invalidate TB, generate new TB contatining 1 guest instruction and exit to CPU loop. QEMU won't call mprotect, and new TB will cause same SEGFAULT. Page will have both PAGE_WRITE_ORG and PAGE_WRITE flags, so QEMU will handle the signal as guest binary problem, and exit with guest SEGFAULT. Solution is to do following: In case if current TB was invalidated continue to invalidate TBs from remaining guest pages and mark pages as PAGE_WRITE. After that disable host page protection with mprotect. If current tb was invalidated longjmp to main loop. That is more efficient, since we won't get SEGFAULT when executing new TB. Reviewed-by: Sergey Fedorov Signed-off-by: Stanislav Shmarov Message-Id: <1467880392-1043630-1-git-send-email-snarpix@gmail.com> Signed-off-by: Richard Henderson --- translate-all.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/translate-all.c b/translate-all.c index eaa95e4..0d47c1c 100644 --- a/translate-all.c +++ b/translate-all.c @@ -2000,6 +2000,7 @@ int page_check_range(target_ulong start, target_ulong len, int flags) int page_unprotect(target_ulong address, uintptr_t pc) { unsigned int prot; + bool current_tb_invalidated; PageDesc *p; target_ulong host_start, host_end, addr; @@ -2021,6 +2022,7 @@ int page_unprotect(target_ulong address, uintptr_t pc) host_end = host_start + qemu_host_page_size; prot = 0; + current_tb_invalidated = false; for (addr = host_start ; addr < host_end ; addr += TARGET_PAGE_SIZE) { p = page_find(addr >> TARGET_PAGE_BITS); p->flags |= PAGE_WRITE; @@ -2028,10 +2030,7 @@ int page_unprotect(target_ulong address, uintptr_t pc) /* and since the content will be modified, we must invalidate the corresponding translated code. */ - if (tb_invalidate_phys_page(addr, pc)) { - mmap_unlock(); - return 2; - } + current_tb_invalidated |= tb_invalidate_phys_page(addr, pc); #ifdef DEBUG_TB_CHECK tb_invalidate_check(addr); #endif @@ -2040,7 +2039,8 @@ int page_unprotect(target_ulong address, uintptr_t pc) prot & PAGE_BITS); mmap_unlock(); - return 1; + /* If current TB was invalidated return to main loop */ + return current_tb_invalidated ? 2 : 1; } mmap_unlock(); return 0;