Received: by 2002:ac0:a581:0:0:0:0:0 with SMTP id m1-v6csp488021imm; Wed, 20 Jun 2018 01:29:46 -0700 (PDT) X-Google-Smtp-Source: ADUXVKI5WU4YYP6zn8YLLTlZNMd0GwQ5EmiRj413ufNH02p7jos1IscYWV6zmCrdmyoQ3nIZfakb X-Received: by 2002:a17:902:42e4:: with SMTP id h91-v6mr22496397pld.27.1529483386770; Wed, 20 Jun 2018 01:29:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1529483386; cv=none; d=google.com; s=arc-20160816; b=HPYKDZ7DD+Y41EleCKjhEEVx9P7h0vKlhsd1AVtnBWM8AlmTN9fJmW0vvGOBf9X/lm 9a1v1JM7IziLhSGaLQUeJuLBk/oWNh94K2K+ApdrUvYaf2bjybIdxzlMn3OZftFEZ+qr flmCttZAgUfqCGte5HZPYYahz9j6j9HHGXYTKcO3mSDYMM7owzXcwjtmL3X/4mtxE542 YhQ+gClCUbgqqdXBey1KH5y2gZpajPPgXBLjTAquWliGgoQUGkHnHfoBq4XVR48loJB1 246PcR7jR1lDUx2eEtXWTk+lJ/I6FHdjzlWKSVzzW9fIiUlzUQpC4J4PNiTUtNvouSit SmFA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:arc-authentication-results; bh=60S6SLHL4/3JsrBLTVYxNSxg1E6qpI9jEczfJBh7/nI=; b=a2Daq6HFlewrxmemLmwhHchFYyWWx4Om1UHpwYKjav7Tq2Ojnq31dzojMpXDOPQnEE DraiKCI4BkeFwn/C7SwDLZI/BwcFgxdojkIkb8cuKhjylmyHDv+CRN0EuAbNkkJKcJiw 4MxZTADVgga2osbEkTFbbyLsWwR+l2g1NpfnuN/gtAzv+m/ykIjXnLKlPp9AQcxrm8iC vqWcn2f7xRfL6hsRXwAH2hLvaD5Z92teaTQk/NHDjwJjtHGbGgW9HzxRmqtsDNNPij/l 6xEs1DlfuFvuAIFMpJxU7Fm6wFlf+SaHqsUKIRe5/JEIRqqhXf6UE1eyE5FIdxEESibj hQXw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d2-v6si1556595pge.342.2018.06.20.01.29.32; Wed, 20 Jun 2018 01:29:46 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752829AbeFTI0h (ORCPT + 99 others); Wed, 20 Jun 2018 04:26:37 -0400 Received: from foss.arm.com ([217.140.101.70]:32846 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751376AbeFTI0b (ORCPT ); Wed, 20 Jun 2018 04:26:31 -0400 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 CACF115B2; Wed, 20 Jun 2018 01:06:57 -0700 (PDT) Received: from salmiak (usa-sjc-mx-foss1.foss.arm.com [217.140.101.70]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 9DEB03F246; Wed, 20 Jun 2018 01:06:54 -0700 (PDT) Date: Wed, 20 Jun 2018 09:06:48 +0100 From: Mark Rutland To: mikelley@microsoft.com Cc: will.deacon@arm.com, catalin.marinas@arm.com, marc.zyngier@arm.com, linux-arm-kernel@lists.infradead.org, gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org, devel@linuxdriverproject.org, olaf@aepfle.de, apw@canonical.com, vkuznets@redhat.com, jasowang@redhat.com, leann.ogasawara@canonical.com, marcelo.cerri@canonical.com, sthemmin@microsoft.com, kys@microsoft.com Subject: Re: [PATCH 1/5] arm64: mm: Add slow_virt_to_phys() Message-ID: <20180620080648.yteuodd3hl7nrh35@salmiak> References: <1529443395-20874-1-git-send-email-mikelley@microsoft.com> <1529443395-20874-2-git-send-email-mikelley@microsoft.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1529443395-20874-2-git-send-email-mikelley@microsoft.com> User-Agent: NeoMutt/20170113 (1.7.2) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi, On Tue, Jun 19, 2018 at 02:23:11PM -0700, Michael Kelley wrote: > Add slow_virt_to_phys() function for ARM64 that parallels the same > function on x86/x64. This is needed by the architecture independent > Hyper-V VMbus driver at drivers/hv/channel.c. The implementation > directly translates the virtual address using the ARM64 'at' > instruction. > > Signed-off-by: Michael Kelley > Reviewed-by: James Morris > --- > arch/arm64/include/asm/memory.h | 6 ++++++ > arch/arm64/mm/pageattr.c | 37 +++++++++++++++++++++++++++++++++++++ > 2 files changed, 43 insertions(+) > > diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h > index 49d9921..3f68dcf 100644 > --- a/arch/arm64/include/asm/memory.h > +++ b/arch/arm64/include/asm/memory.h > @@ -265,6 +265,12 @@ static inline void *phys_to_virt(phys_addr_t x) > } > > /* > + * For memory where the underlying physical pages may not > + * be contiguous. > + */ > +extern phys_addr_t slow_virt_to_phys(void *vaddr); > + > +/* > * Drivers should NOT use these either. > */ > #define __pa(x) __virt_to_phys((unsigned long)(x)) > diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c > index a563593..8a42cac 100644 > --- a/arch/arm64/mm/pageattr.c > +++ b/arch/arm64/mm/pageattr.c > @@ -19,6 +19,8 @@ > #include > #include > #include > +#include > +#include > > struct page_change_data { > pgprot_t set_mask; > @@ -185,3 +187,38 @@ bool kernel_page_present(struct page *page) > } > #endif /* CONFIG_HIBERNATION */ > #endif /* CONFIG_DEBUG_PAGEALLOC */ > + > +/* > + * For virtual addresses where the underlyine physical memory may not be > + * contiguous and the normal virt_to_phys gives the wrong result. This > + * function does an actual translation using the 'at' instruction. > + */ > +phys_addr_t slow_virt_to_phys(void *virt_addr) > +{ > + phys_addr_t result; > + unsigned long input = (unsigned long)virt_addr; > + char touch; > + int i; > + > + /* Try up to 3 times (an arbitrary number) */ > + for (i = 0; i < 3; i++) { > + /* Do the translation and check that it worked */ > + asm volatile("at s1e1r, %0" : : "r" (input)); > + isb(); > + result = read_sysreg(par_el1); > + if (likely(!(result & 0x1))) > + return (result & GENMASK_ULL(51, 12)) | > + (input & GENMASK_ULL(11, 0)); > + /* > + * Something failed. Read the page to fault in anything > + * that isn't resident, then try again. "Anything" > + * could include the page itself or hypervisor page tables. > + */ > + touch = READ_ONCE(*(char *)input); > + dmb(sy); > + } > + > + /* Let the caller sort it out. */ > + return -1; AFAICT, callers of slow_virt_to_phys() don't check the value, so this doesn't seem safe, and I'm concerned by the possibility of spurious failures given we only retry a fixed number of times. I think it would be better to walk the page tables, as x86 does, as that's guaranteed to complete within a fixed bound (i.e. after we read all the levls of table). Thanks, Mark.