From patchwork Mon Oct 8 18:33:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 148425 Delivered-To: patch@linaro.org Received: by 2002:a2e:8595:0:0:0:0:0 with SMTP id b21-v6csp3982062lji; Mon, 8 Oct 2018 11:36:15 -0700 (PDT) X-Google-Smtp-Source: ACcGV61FfKIXFS6N2LDhcbkIusu/PcH0QAqLV+DcI/JKznXzF1qS/HiRiQ8/3981kZ+//T8cxSIk X-Received: by 2002:a6b:f919:: with SMTP id j25-v6mr15285633iog.280.1539023775816; Mon, 08 Oct 2018 11:36:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539023775; cv=none; d=google.com; s=arc-20160816; b=JfkAxC2RDufi9sEdKz3Qr3liwfNkUufYs7NUvC1N2rYld+kfg8gJO3jfdS/tt4E/bn HKxvYtSx9GRtq8Z0+g/yUowQ5bOjHMF+8aOK+xK4unHRza9xDbQWYW/wOvs0kDyoAxCi St8CfZQzk7CN32H2b7GtOiEsDV9oKZq+/UTVQixd3yveUFRSqWmJ1AOen6p8BypCQjQe iam+2Zslf8eAc9Mw42HzqDU0DtitGo2DnkcrN0Y3Ap9FGAqUdBJmLj/WMsWJNiFJM4gC 9yqELM3AVxF0t/U9/UhoLPm6kRY4IydeYLhaTm641F4JA3uDd5eU8lAVpKZwxVqypB0S 5Z1w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc :list-subscribe:list-help:list-post:list-unsubscribe:list-id :precedence:subject:references:in-reply-to:message-id:date:to:from; bh=eo6o0cn4A3QV/iGDzrBmKXT38/RatXTtxAp8GNzN0WM=; b=xNDBa6jthbzzNmnJTlh/4t6G6JapnmJvn6V51e5pxO7BLSl4v8jP/u8gfii28QFJVL ie9yvL5yTxc8bE3BtGm1GACxroIdS/KyKB8kzub6efpEyFMWIU0+P1YmmXWCGEYGxN2a agg2NAHomVkSAVHhYB5NIXn3QIXWz8wAJESZqTdH7QAx14q/pOs8xXwbTQvDEBfr4Zwm sA8msSrTUpOx4P/wcX8bwFXEmY5mbPEV1TX5Eg2hLvbFh3hM5PiLf0UqTrS4HOWBtUF2 KBoqWtVs2KqSnK/EsuyuH0SmQ/NS9cfq58D0aeCM5N9ITpGbUKij0WB9wPlD1CNPrjja eeHw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org. [192.237.175.120]) by mx.google.com with ESMTPS id b63-v6si11317654iof.71.2018.10.08.11.36.15 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 08 Oct 2018 11:36:15 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1g9aM3-0005eR-J9; Mon, 08 Oct 2018 18:34:07 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1g9aM1-0005e5-Ul for xen-devel@lists.xen.org; Mon, 08 Oct 2018 18:34:05 +0000 X-Inumbo-ID: e99036c7-cb28-11e8-a6a9-d7ebe60f679a Received: from foss.arm.com (unknown [217.140.101.70]) by us1-amaz-eas1.inumbo.com (Halon) with ESMTP id e99036c7-cb28-11e8-a6a9-d7ebe60f679a; Mon, 08 Oct 2018 18:35:21 +0000 (UTC) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 5C616ED1; Mon, 8 Oct 2018 11:34:04 -0700 (PDT) Received: from e108454-lin.cambridge.arm.com (e108454-lin.cambridge.arm.com [10.1.196.50]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 728E33F5B3; Mon, 8 Oct 2018 11:34:03 -0700 (PDT) From: Julien Grall To: xen-devel@lists.xen.org Date: Mon, 8 Oct 2018 19:33:39 +0100 Message-Id: <20181008183352.16291-4-julien.grall@arm.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20181008183352.16291-1-julien.grall@arm.com> References: <20181008183352.16291-1-julien.grall@arm.com> Subject: [Xen-devel] [RFC 03/16] xen/arm: Allow lpae_is_{table, mapping} helpers to work on invalid entry X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Julien Grall , sstabellini@kernel.org, andre.przywara@linaro.org MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Currently, lpae_is_{table, mapping} helpers will always return false on entries with the valid bit unset. However, it would be useful to have them operating on any entry. For instance to store information in advance but still request a fault. With that change, the p2m is now providing an overlay for *_is_{table, mapping} that will check the valid bit of the entry. Signed-off-by: Julien Grall Reviewed-by: Stefano Stabellini --- The patch was previously sent separately. --- xen/arch/arm/guest_walk.c | 2 +- xen/arch/arm/mm.c | 2 +- xen/arch/arm/p2m.c | 22 ++++++++++++++++++---- xen/include/asm-arm/lpae.h | 11 +++++++---- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/xen/arch/arm/guest_walk.c b/xen/arch/arm/guest_walk.c index e3e21bdad3..4a1b4cf2c8 100644 --- a/xen/arch/arm/guest_walk.c +++ b/xen/arch/arm/guest_walk.c @@ -566,7 +566,7 @@ static int guest_walk_ld(const struct vcpu *v, * PTE is invalid or holds a reserved entry (PTE<1:0> == x0)) or if the PTE * maps a memory block at level 3 (PTE<1:0> == 01). */ - if ( !lpae_is_mapping(pte, level) ) + if ( !lpae_is_valid(pte) || !lpae_is_mapping(pte, level) ) return -EFAULT; /* Make sure that the lower bits of the PTE's base address are zero. */ diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c index 0bc31b1d9b..987fcb9162 100644 --- a/xen/arch/arm/mm.c +++ b/xen/arch/arm/mm.c @@ -996,7 +996,7 @@ static int create_xen_entries(enum xenmap_operation op, for(; addr < addr_end; addr += PAGE_SIZE, mfn = mfn_add(mfn, 1)) { entry = &xen_second[second_linear_offset(addr)]; - if ( !lpae_is_table(*entry, 2) ) + if ( !lpae_is_valid(*entry) || !lpae_is_table(*entry, 2) ) { rc = create_xen_table(entry); if ( rc < 0 ) { diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index f8a2f6459e..8fffb42889 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -219,6 +219,20 @@ static p2m_access_t p2m_mem_access_radix_get(struct p2m_domain *p2m, gfn_t gfn) return radix_tree_ptr_to_int(ptr); } +/* + * lpae_is_* helpers don't check whether the valid bit is set in the + * PTE. Provide our own overlay to check the valid bit. + */ +static inline bool p2m_is_mapping(lpae_t pte, unsigned int level) +{ + return lpae_is_valid(pte) && lpae_is_mapping(pte, level); +} + +static inline bool p2m_is_superpage(lpae_t pte, unsigned int level) +{ + return lpae_is_valid(pte) && lpae_is_superpage(pte, level); +} + #define GUEST_TABLE_MAP_FAILED 0 #define GUEST_TABLE_SUPER_PAGE 1 #define GUEST_TABLE_NORMAL_PAGE 2 @@ -262,7 +276,7 @@ static int p2m_next_level(struct p2m_domain *p2m, bool read_only, /* The function p2m_next_level is never called at the 3rd level */ ASSERT(level < 3); - if ( lpae_is_mapping(*entry, level) ) + if ( p2m_is_mapping(*entry, level) ) return GUEST_TABLE_SUPER_PAGE; mfn = lpae_get_mfn(*entry); @@ -642,7 +656,7 @@ static void p2m_free_entry(struct p2m_domain *p2m, return; /* Nothing to do but updating the stats if the entry is a super-page. */ - if ( lpae_is_superpage(entry, level) ) + if ( p2m_is_superpage(entry, level) ) { p2m->stats.mappings[level]--; return; @@ -697,7 +711,7 @@ static bool p2m_split_superpage(struct p2m_domain *p2m, lpae_t *entry, * a superpage. */ ASSERT(level < target); - ASSERT(lpae_is_superpage(*entry, level)); + ASSERT(p2m_is_superpage(*entry, level)); page = alloc_domheap_page(NULL, 0); if ( !page ) @@ -836,7 +850,7 @@ static int __p2m_set_entry(struct p2m_domain *p2m, /* We need to split the original page. */ lpae_t split_pte = *entry; - ASSERT(lpae_is_superpage(*entry, level)); + ASSERT(p2m_is_superpage(*entry, level)); if ( !p2m_split_superpage(p2m, &split_pte, level, target, offsets) ) { diff --git a/xen/include/asm-arm/lpae.h b/xen/include/asm-arm/lpae.h index 17fdc6074f..545b0c8f24 100644 --- a/xen/include/asm-arm/lpae.h +++ b/xen/include/asm-arm/lpae.h @@ -133,16 +133,19 @@ static inline bool lpae_is_valid(lpae_t pte) return pte.walk.valid; } +/* + * lpae_is_* don't check the valid bit. This gives an opportunity for the + * callers to operate on the entry even if they are not valid. For + * instance to store information in advance. + */ static inline bool lpae_is_table(lpae_t pte, unsigned int level) { - return (level < 3) && lpae_is_valid(pte) && pte.walk.table; + return (level < 3) && pte.walk.table; } static inline bool lpae_is_mapping(lpae_t pte, unsigned int level) { - if ( !lpae_is_valid(pte) ) - return false; - else if ( level == 3 ) + if ( level == 3 ) return pte.walk.table; else return !pte.walk.table;