From patchwork Fri Jan 15 16:04:17 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 8042861 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 0DFB5BEEED for ; Fri, 15 Jan 2016 16:05:03 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 71F2D2040F for ; Fri, 15 Jan 2016 16:04:57 +0000 (UTC) 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.kernel.org (Postfix) with ESMTPS id B7CFC203E1 for ; Fri, 15 Jan 2016 16:04:56 +0000 (UTC) Received: from localhost ([::1]:47769 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aK6rw-0007XQ-2X for patchwork-qemu-devel@patchwork.kernel.org; Fri, 15 Jan 2016 11:04:56 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58982) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aK6rh-0007Wb-P0 for qemu-devel@nongnu.org; Fri, 15 Jan 2016 11:04:43 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aK6rf-0003Gm-Sz for qemu-devel@nongnu.org; Fri, 15 Jan 2016 11:04:41 -0500 Received: from mail-wm0-x22d.google.com ([2a00:1450:400c:c09::22d]:35723) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aK6rf-0003Gi-IT for qemu-devel@nongnu.org; Fri, 15 Jan 2016 11:04:39 -0500 Received: by mail-wm0-x22d.google.com with SMTP id f206so26179576wmf.0 for ; Fri, 15 Jan 2016 08:04:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:subject:date:message-id:in-reply-to:references; bh=ivJlD8zPGB4fJC5S1MqrN+Ubx9kSGYm/98JLOF+5+20=; b=USJbQqFuOLxiBCa1lCbOyDb5BD606RRTseViGKSpAR3msMXsts90A9tgiyqDqSkPqx hCwBNWOiNsuWkCqXOPVgeBGqieDrkVocqSWBfzTqZ0xiTk6Zwrb9s3SSb6z64CwUAMDP CrsaaTwfKgGx1bkjyTum+HNwoOCSHICetpQa5QJ1+3pJB6O8Sre8VchUymTDIKtMrLPM 1EfiPf0RxJ5Xjq4xKsFqXij3IQqgltiTX+A4RMPG/1soUVqkUI+2kfYBBhQhaTEsfOL+ 9NPkf/leVwQmwvCeB8v1jcEHNoZCnNnjoZMdK7u9MUR38mQQr0YWwCmrqLxG7ez8Lex2 ZURg== 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:subject:date:message-id :in-reply-to:references; bh=ivJlD8zPGB4fJC5S1MqrN+Ubx9kSGYm/98JLOF+5+20=; b=VZUFwtqXKDgk3UWxPwyKVxm3pmNFfEaYBMTseRg6zyBD31U7aaeJOHqZelsYHmrBFg s84h+kz4Dlzh4XhRzZyTiN1xqFJW9mDvciLGEW0hG1pDQagun4VRpv4DtGCOWEc3zsXL XUVO+aLEJYHK3+X07WpA8EzjjrG+3RmoOxAA6tpHidhz0MhbscTDIAaBOGEAYL4gZVUp T6Eiy5iv6NVLdMluOZnL1ABBDRywJ4JgX6axA4UIFH1IdHv968j2sHj97sUy7iopXThQ aoHTd8Zg/otBMjiiyEl7JfTgXiMy8DkcO3gPf3OEYV6DxAmRXPfz5TVY6X2HzOwhNqSy y1RQ== X-Gm-Message-State: ALoCoQnWE73+kzXqkGs76APXe9ZCdz+6d3JjP42MuEvFHILQ6dbE2hepOZULO4cXvK8R0h6iJEXnX4uIhHfEoVRvj3jrqgvqLw== X-Received: by 10.194.9.98 with SMTP id y2mr10735918wja.105.1452873878929; Fri, 15 Jan 2016 08:04:38 -0800 (PST) Received: from 640k.lan (94-39-195-126.adsl-ull.clienti.tiscali.it. [94.39.195.126]) by smtp.gmail.com with ESMTPSA id c15sm3103036wmd.19.2016.01.15.08.04.37 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 15 Jan 2016 08:04:37 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Fri, 15 Jan 2016 17:04:17 +0100 Message-Id: <1452873871-138914-3-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1452873871-138914-1-git-send-email-pbonzini@redhat.com> References: <1452873871-138914-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:400c:c09::22d Subject: [Qemu-devel] [PULL 02/15] target-i386: do not duplicate page protection checks X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP x86_cpu_handle_mmu_fault is currently checking twice for writability and executability of pages; the first time to decide whether to trigger a page fault, the second time to compute the "prot" argument to tlb_set_page_with_attrs. Reorganize code so that first "prot" is computed, then it is used to check whether to raise a page fault, then finally PROT_WRITE is removed if the D bit will have to be set. Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- target-i386/helper.c | 65 +++++++++++++++++++--------------------------------- 1 file changed, 23 insertions(+), 42 deletions(-) diff --git a/target-i386/helper.c b/target-i386/helper.c index d18be95..bf58242 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -890,38 +890,30 @@ do_check_protect_pse36: goto do_fault_rsvd; } ptep ^= PG_NX_MASK; - if ((ptep & PG_NX_MASK) && is_write1 == 2) { + + /* can the page can be put in the TLB? prot will tell us */ + if (is_user && !(ptep & PG_USER_MASK)) { goto do_fault_protect; } - switch (mmu_idx) { - case MMU_USER_IDX: - if (!(ptep & PG_USER_MASK)) { - goto do_fault_protect; - } - if (is_write && !(ptep & PG_RW_MASK)) { - goto do_fault_protect; - } - break; - case MMU_KSMAP_IDX: - if (is_write1 != 2 && (ptep & PG_USER_MASK)) { - goto do_fault_protect; + prot = 0; + if (mmu_idx != MMU_KSMAP_IDX || !(ptep & PG_USER_MASK)) { + prot |= PAGE_READ; + if ((ptep & PG_RW_MASK) || (!is_user && !(env->cr[0] & CR0_WP_MASK))) { + prot |= PAGE_WRITE; } - /* fall through */ - case MMU_KNOSMAP_IDX: - if (is_write1 == 2 && (env->cr[4] & CR4_SMEP_MASK) && - (ptep & PG_USER_MASK)) { - goto do_fault_protect; - } - if ((env->cr[0] & CR0_WP_MASK) && - is_write && !(ptep & PG_RW_MASK)) { - goto do_fault_protect; - } - break; + } + if (!(ptep & PG_NX_MASK) && + (mmu_idx == MMU_USER_IDX || + !((env->cr[4] & CR4_SMEP_MASK) && (ptep & PG_USER_MASK)))) { + prot |= PAGE_EXEC; + } - default: /* cannot happen */ - break; + if ((prot & (1 << is_write1)) == 0) { + goto do_fault_protect; } + + /* yes, it can! */ is_dirty = is_write && !(pte & PG_DIRTY_MASK); if (!(pte & PG_ACCESSED_MASK) || is_dirty) { pte |= PG_ACCESSED_MASK; @@ -931,25 +923,13 @@ do_check_protect_pse36: x86_stl_phys_notdirty(cs, pte_addr, pte); } - /* the page can be put in the TLB */ - prot = PAGE_READ; - if (!(ptep & PG_NX_MASK) && - (mmu_idx == MMU_USER_IDX || - !((env->cr[4] & CR4_SMEP_MASK) && (ptep & PG_USER_MASK)))) { - prot |= PAGE_EXEC; - } - if (pte & PG_DIRTY_MASK) { + if (!(pte & PG_DIRTY_MASK)) { /* only set write access if already dirty... otherwise wait for dirty access */ - if (is_user) { - if (ptep & PG_RW_MASK) - prot |= PAGE_WRITE; - } else { - if (!(env->cr[0] & CR0_WP_MASK) || - (ptep & PG_RW_MASK)) - prot |= PAGE_WRITE; - } + assert(!is_write); + prot &= ~PROT_WRITE; } + do_mapping: pte = pte & env->a20_mask; @@ -962,6 +942,7 @@ do_check_protect_pse36: page_offset = vaddr & (page_size - 1); paddr = pte + page_offset; + assert(prot & (1 << is_write1)); tlb_set_page_with_attrs(cs, vaddr, paddr, cpu_get_mem_attrs(env), prot, mmu_idx, page_size); return 0;