From patchwork Wed Jul 6 13:01:04 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 71454 Delivered-To: patch@linaro.org Received: by 10.140.28.4 with SMTP id 4csp854026qgy; Wed, 6 Jul 2016 06:04:01 -0700 (PDT) X-Received: by 10.107.140.148 with SMTP id o142mr20836508iod.42.1467810241764; Wed, 06 Jul 2016 06:04:01 -0700 (PDT) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org. [192.237.175.120]) by mx.google.com with ESMTPS id 68si4311033iop.188.2016.07.06.06.04.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 06 Jul 2016 06:04:01 -0700 (PDT) Received-SPF: neutral (google.com: 192.237.175.120 is neither permitted nor denied by best guess record for domain of xen-devel-bounces@lists.xen.org) client-ip=192.237.175.120; Authentication-Results: mx.google.com; spf=neutral (google.com: 192.237.175.120 is neither permitted nor denied by best guess record for domain of xen-devel-bounces@lists.xen.org) smtp.mailfrom=xen-devel-bounces@lists.xen.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bKmSM-0000B0-0J; Wed, 06 Jul 2016 13:01:34 +0000 Received: from mail6.bemta14.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bKmSL-00009Y-1R for xen-devel@lists.xen.org; Wed, 06 Jul 2016 13:01:33 +0000 Received: from [193.109.254.147] by server-11.bemta-14.messagelabs.com id 49/A8-01707-C210D775; Wed, 06 Jul 2016 13:01:32 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrGLMWRWlGSWpSXmKPExsVysyfVTVebsTb c4MN3E4slHxezODB6HN39mymAMYo1My8pvyKBNaNn5gPWgl6nio6uBawNjC+Nuhg5OYQENjFK TPpk3sXIBWSfZpTY8uoWO0iCTUBT4s7nT0wgtoiAtMS1z5cZQWxmAQeJNx/vsYDYwgJJEtfev wWzWQRUJV7vPs0GYvMKuEgc+DkFLC4hICdx8thkVhCbU8BVYvq1x+wQi10kti+exDyBkXsBI8 MqRo3i1KKy1CJdQwu9pKLM9IyS3MTMHF1DQxO93NTi4sT01JzEpGK95PzcTYxA/9YzMDDuYDy y3fMQoyQHk5IoL8u36nAhvqT8lMqMxOKM+KLSnNTiQ4wyHBxKEryf/teECwkWpaanVqRl5gAD DSYtwcGjJML7CCTNW1yQmFucmQ6ROsWoKCXOy8dQGy4kAJLIKM2Da4MF9yVGWSlhXkYGBgYhn oLUotzMElT5V4ziHIxKwrw9ION5MvNK4Ka/AlrMBLT4p0s1yOKSRISUVAPjyqv21rcspnzl/7 jzaY+Gr21f8QbT/A8HPp5s7yy3zvuyb5L6xpi7a36GCeuwWexasqK04u5izesvT6z/H5MhXP8 nVDO9fXXhIytzr2+Wj3+3m3j6KS2fol0gkLCtIn7WH9nVprd+31v0/u3jmwcU0hbZPWM+f0nN wLPyHcP9eie2yhdV9vx2SizFGYmGWsxFxYkAQ3IAlGkCAAA= X-Env-Sender: julien.grall@arm.com X-Msg-Ref: server-10.tower-27.messagelabs.com!1467810090!52242031!1 X-Originating-IP: [217.140.101.70] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 8.46; banners=-,-,- X-VirusChecked: Checked Received: (qmail 30801 invoked from network); 6 Jul 2016 13:01:31 -0000 Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by server-10.tower-27.messagelabs.com with SMTP; 6 Jul 2016 13:01:31 -0000 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 98F0CBB1; Wed, 6 Jul 2016 06:02:29 -0700 (PDT) Received: from e108454-lin.cambridge.arm.com (e108454-lin.cambridge.arm.com [10.1.215.28]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 1B3053F21A; Wed, 6 Jul 2016 06:01:29 -0700 (PDT) From: Julien Grall To: xen-devel@lists.xen.org Date: Wed, 6 Jul 2016 14:01:04 +0100 Message-Id: <1467810073-27971-6-git-send-email-julien.grall@arm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1467810073-27971-1-git-send-email-julien.grall@arm.com> References: <1467810073-27971-1-git-send-email-julien.grall@arm.com> Cc: Julien Grall , sstabellini@kernel.org Subject: [Xen-devel] [PATCH v6 05/14] xen/arm: Rework the interface of p2m_lookup and use typesafe gfn and mfn X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" The prototype and the declaration of p2m_lookup disagree on how the function should be used. One expect a frame number whilst the other an address. Thankfully, everyone is using with an address today. However, most of the callers have to convert a guest frame to an address. Modify the interface to take a guest physical frame in parameter and return a machine frame. Whilst modifying the interface, use typesafe gfn and mfn for clarity and catching possible misusage. Signed-off-by: Julien Grall Acked-by: Stefano Stabellini --- Changes in v6: - Add Stefano's acked-by Changes in v4: - Use INVALID_MFN_T when possible --- xen/arch/arm/p2m.c | 43 +++++++++++++++++++++++-------------------- xen/arch/arm/traps.c | 21 +++++++++++---------- xen/include/asm-arm/p2m.h | 7 +++---- 3 files changed, 37 insertions(+), 34 deletions(-) diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index c938dde..54a363a 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -140,14 +140,15 @@ void flush_tlb_domain(struct domain *d) } /* - * Lookup the MFN corresponding to a domain's PFN. + * Lookup the MFN corresponding to a domain's GFN. * * There are no processor functions to do a stage 2 only lookup therefore we * do a a software walk. */ -static paddr_t __p2m_lookup(struct domain *d, paddr_t paddr, p2m_type_t *t) +static mfn_t __p2m_lookup(struct domain *d, gfn_t gfn, p2m_type_t *t) { struct p2m_domain *p2m = &d->arch.p2m; + const paddr_t paddr = pfn_to_paddr(gfn_x(gfn)); const unsigned int offsets[4] = { zeroeth_table_offset(paddr), first_table_offset(paddr), @@ -158,7 +159,7 @@ static paddr_t __p2m_lookup(struct domain *d, paddr_t paddr, p2m_type_t *t) ZEROETH_MASK, FIRST_MASK, SECOND_MASK, THIRD_MASK }; lpae_t pte, *map; - paddr_t maddr = INVALID_PADDR; + mfn_t mfn = INVALID_MFN; paddr_t mask = 0; p2m_type_t _t; unsigned int level, root_table; @@ -216,21 +217,22 @@ static paddr_t __p2m_lookup(struct domain *d, paddr_t paddr, p2m_type_t *t) { ASSERT(mask); ASSERT(pte.p2m.type != p2m_invalid); - maddr = (pte.bits & PADDR_MASK & mask) | (paddr & ~mask); + mfn = _mfn(paddr_to_pfn((pte.bits & PADDR_MASK & mask) | + (paddr & ~mask))); *t = pte.p2m.type; } err: - return maddr; + return mfn; } -paddr_t p2m_lookup(struct domain *d, paddr_t paddr, p2m_type_t *t) +mfn_t p2m_lookup(struct domain *d, gfn_t gfn, p2m_type_t *t) { - paddr_t ret; + mfn_t ret; struct p2m_domain *p2m = &d->arch.p2m; spin_lock(&p2m->lock); - ret = __p2m_lookup(d, paddr, t); + ret = __p2m_lookup(d, gfn, t); spin_unlock(&p2m->lock); return ret; @@ -493,8 +495,9 @@ static int __p2m_get_mem_access(struct domain *d, gfn_t gfn, * No setting was found in the Radix tree. Check if the * entry exists in the page-tables. */ - paddr_t maddr = __p2m_lookup(d, gfn_x(gfn) << PAGE_SHIFT, NULL); - if ( INVALID_PADDR == maddr ) + mfn_t mfn = __p2m_lookup(d, gfn, NULL); + + if ( mfn_eq(mfn, INVALID_MFN) ) return -ESRCH; /* If entry exists then its rwx. */ @@ -1483,8 +1486,7 @@ int p2m_cache_flush(struct domain *d, xen_pfn_t start_mfn, xen_pfn_t end_mfn) mfn_t gfn_to_mfn(struct domain *d, gfn_t gfn) { - paddr_t p = p2m_lookup(d, pfn_to_paddr(gfn_x(gfn)), NULL); - return _mfn(p >> PAGE_SHIFT); + return p2m_lookup(d, gfn, NULL); } /* @@ -1498,8 +1500,8 @@ p2m_mem_access_check_and_get_page(vaddr_t gva, unsigned long flag) { long rc; paddr_t ipa; - unsigned long maddr; - unsigned long mfn; + gfn_t gfn; + mfn_t mfn; xenmem_access_t xma; p2m_type_t t; struct page_info *page = NULL; @@ -1508,11 +1510,13 @@ p2m_mem_access_check_and_get_page(vaddr_t gva, unsigned long flag) if ( rc < 0 ) goto err; + gfn = _gfn(paddr_to_pfn(ipa)); + /* * We do this first as this is faster in the default case when no * permission is set on the page. */ - rc = __p2m_get_mem_access(current->domain, _gfn(paddr_to_pfn(ipa)), &xma); + rc = __p2m_get_mem_access(current->domain, gfn, &xma); if ( rc < 0 ) goto err; @@ -1561,12 +1565,11 @@ p2m_mem_access_check_and_get_page(vaddr_t gva, unsigned long flag) * We had a mem_access permission limiting the access, but the page type * could also be limiting, so we need to check that as well. */ - maddr = __p2m_lookup(current->domain, ipa, &t); - if ( maddr == INVALID_PADDR ) + mfn = __p2m_lookup(current->domain, gfn, &t); + if ( mfn_eq(mfn, INVALID_MFN) ) goto err; - mfn = maddr >> PAGE_SHIFT; - if ( !mfn_valid(mfn) ) + if ( !mfn_valid(mfn_x(mfn)) ) goto err; /* @@ -1575,7 +1578,7 @@ p2m_mem_access_check_and_get_page(vaddr_t gva, unsigned long flag) if ( t != p2m_ram_rw ) goto err; - page = mfn_to_page(mfn); + page = mfn_to_page(mfn_x(mfn)); if ( unlikely(!get_page(page, current->domain)) ) page = NULL; diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index 44926ca..b653f61 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -2319,14 +2319,16 @@ void dump_guest_s1_walk(struct domain *d, vaddr_t addr) { register_t ttbcr = READ_SYSREG(TCR_EL1); uint64_t ttbr0 = READ_SYSREG64(TTBR0_EL1); - paddr_t paddr; uint32_t offset; uint32_t *first = NULL, *second = NULL; + mfn_t mfn; + + mfn = p2m_lookup(d, _gfn(paddr_to_pfn(ttbr0)), NULL); printk("dom%d VA 0x%08"PRIvaddr"\n", d->domain_id, addr); printk(" TTBCR: 0x%08"PRIregister"\n", ttbcr); printk(" TTBR0: 0x%016"PRIx64" = 0x%"PRIpaddr"\n", - ttbr0, p2m_lookup(d, ttbr0 & PAGE_MASK, NULL)); + ttbr0, pfn_to_paddr(mfn_x(mfn))); if ( ttbcr & TTBCR_EAE ) { @@ -2339,32 +2341,31 @@ void dump_guest_s1_walk(struct domain *d, vaddr_t addr) return; } - paddr = p2m_lookup(d, ttbr0 & PAGE_MASK, NULL); - if ( paddr == INVALID_PADDR ) + if ( mfn_eq(mfn, INVALID_MFN) ) { printk("Failed TTBR0 maddr lookup\n"); goto done; } - first = map_domain_page(_mfn(paddr_to_pfn(paddr))); + first = map_domain_page(mfn); offset = addr >> (12+10); printk("1ST[0x%"PRIx32"] (0x%"PRIpaddr") = 0x%08"PRIx32"\n", - offset, paddr, first[offset]); + offset, pfn_to_paddr(mfn_x(mfn)), first[offset]); if ( !(first[offset] & 0x1) || !(first[offset] & 0x2) ) goto done; - paddr = p2m_lookup(d, first[offset] & PAGE_MASK, NULL); + mfn = p2m_lookup(d, _gfn(paddr_to_pfn(first[offset])), NULL); - if ( paddr == INVALID_PADDR ) + if ( mfn_eq(mfn, INVALID_MFN) ) { printk("Failed L1 entry maddr lookup\n"); goto done; } - second = map_domain_page(_mfn(paddr_to_pfn(paddr))); + second = map_domain_page(mfn); offset = (addr >> 12) & 0x3FF; printk("2ND[0x%"PRIx32"] (0x%"PRIpaddr") = 0x%08"PRIx32"\n", - offset, paddr, second[offset]); + offset, pfn_to_paddr(mfn_x(mfn)), second[offset]); done: if (second) unmap_domain_page(second); diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h index 0d1e61e..f204482 100644 --- a/xen/include/asm-arm/p2m.h +++ b/xen/include/asm-arm/p2m.h @@ -135,8 +135,8 @@ void p2m_restore_state(struct vcpu *n); /* Print debugging/statistial info about a domain's p2m */ void p2m_dump_info(struct domain *d); -/* Look up the MFN corresponding to a domain's PFN. */ -paddr_t p2m_lookup(struct domain *d, paddr_t gpfn, p2m_type_t *t); +/* Look up the MFN corresponding to a domain's GFN. */ +mfn_t p2m_lookup(struct domain *d, gfn_t gfn, p2m_type_t *t); /* Clean & invalidate caches corresponding to a region of guest address space */ int p2m_cache_flush(struct domain *d, xen_pfn_t start_mfn, xen_pfn_t end_mfn); @@ -201,8 +201,7 @@ static inline struct page_info *get_page_from_gfn( { struct page_info *page; p2m_type_t p2mt; - paddr_t maddr = p2m_lookup(d, pfn_to_paddr(gfn), &p2mt); - unsigned long mfn = maddr >> PAGE_SHIFT; + unsigned long mfn = mfn_x(p2m_lookup(d, _gfn(gfn), &p2mt)); if (t) *t = p2mt;