LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH v2 0/3] xen/swiotlb: fix an issue and improve swiotlb-xen
@ 2019-05-29  9:04 Juergen Gross
  2019-05-29  9:04 ` [PATCH v2 1/3] xen/swiotlb: fix condition for calling xen_destroy_contiguous_region() Juergen Gross
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Juergen Gross @ 2019-05-29  9:04 UTC (permalink / raw)
  To: linux-kernel, iommu
  Cc: Juergen Gross, Konrad Rzeszutek Wilk, Boris Ostrovsky,
	Stefano Stabellini, xen-devel, stable

While hunting an issue in swiotlb-xen I stumbled over a wrong test
and found some areas for improvement.

Juergen Gross (3):
  xen/swiotlb: fix condition for calling xen_destroy_contiguous_region()
  xen/swiotlb: simplify range_straddles_page_boundary()
  xen/swiotlb: remember having called xen_create_contiguous_region()

 drivers/xen/swiotlb-xen.c  | 36 ++++++++++++------------------------
 include/linux/page-flags.h |  3 +++
 2 files changed, 15 insertions(+), 24 deletions(-)

-- 
2.16.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 1/3] xen/swiotlb: fix condition for calling xen_destroy_contiguous_region()
  2019-05-29  9:04 [PATCH v2 0/3] xen/swiotlb: fix an issue and improve swiotlb-xen Juergen Gross
@ 2019-05-29  9:04 ` Juergen Gross
  2019-05-29  9:52   ` [Xen-devel] " Jan Beulich
  2019-05-29  9:04 ` [PATCH v2 2/3] xen/swiotlb: simplify range_straddles_page_boundary() Juergen Gross
  2019-05-29  9:04 ` [PATCH v2 3/3] xen/swiotlb: remember having called xen_create_contiguous_region() Juergen Gross
  2 siblings, 1 reply; 11+ messages in thread
From: Juergen Gross @ 2019-05-29  9:04 UTC (permalink / raw)
  To: linux-kernel, iommu
  Cc: Juergen Gross, Konrad Rzeszutek Wilk, Boris Ostrovsky,
	Stefano Stabellini, xen-devel, stable

The condition in xen_swiotlb_free_coherent() for deciding whether to
call xen_destroy_contiguous_region() is wrong: in case the region to
be freed is not contiguous calling xen_destroy_contiguous_region() is
the wrong thing to do: it would result in inconsistent mappings of
multiple PFNs to the same MFN. This will lead to various strange
crashes or data corruption.

Instead of calling xen_destroy_contiguous_region() in that case a
warning should be issued as that situation should never occur.

Cc: stable@vger.kernel.org
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
---
V2: always issue a warning in case xen_destroy_contiguous_region()
    isn't called (Jan Beulich)
---
 drivers/xen/swiotlb-xen.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 5dcb06fe9667..1caadca124b3 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -360,8 +360,8 @@ xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
 	/* Convert the size to actually allocated. */
 	size = 1UL << (order + XEN_PAGE_SHIFT);
 
-	if (((dev_addr + size - 1 <= dma_mask)) ||
-	    range_straddles_page_boundary(phys, size))
+	if (!WARN_ON((dev_addr + size - 1 > dma_mask) ||
+		     range_straddles_page_boundary(phys, size)))
 		xen_destroy_contiguous_region(phys, order);
 
 	xen_free_coherent_pages(hwdev, size, vaddr, (dma_addr_t)phys, attrs);
-- 
2.16.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 2/3] xen/swiotlb: simplify range_straddles_page_boundary()
  2019-05-29  9:04 [PATCH v2 0/3] xen/swiotlb: fix an issue and improve swiotlb-xen Juergen Gross
  2019-05-29  9:04 ` [PATCH v2 1/3] xen/swiotlb: fix condition for calling xen_destroy_contiguous_region() Juergen Gross
@ 2019-05-29  9:04 ` Juergen Gross
  2019-05-29  9:04 ` [PATCH v2 3/3] xen/swiotlb: remember having called xen_create_contiguous_region() Juergen Gross
  2 siblings, 0 replies; 11+ messages in thread
From: Juergen Gross @ 2019-05-29  9:04 UTC (permalink / raw)
  To: linux-kernel, iommu
  Cc: Juergen Gross, Konrad Rzeszutek Wilk, Boris Ostrovsky,
	Stefano Stabellini, xen-devel

range_straddles_page_boundary() is open coding several macros from
include/xen/page.h. Use those instead. Additionally there is no need
to have check_pages_physically_contiguous() as a separate function as
it is used only once, so merge it into range_straddles_page_boundary().

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
---
 drivers/xen/swiotlb-xen.c | 28 ++++++----------------------
 1 file changed, 6 insertions(+), 22 deletions(-)

diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 1caadca124b3..aba5247b9145 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -92,34 +92,18 @@ static inline dma_addr_t xen_virt_to_bus(void *address)
 	return xen_phys_to_bus(virt_to_phys(address));
 }
 
-static int check_pages_physically_contiguous(unsigned long xen_pfn,
-					     unsigned int offset,
-					     size_t length)
+static inline int range_straddles_page_boundary(phys_addr_t p, size_t size)
 {
-	unsigned long next_bfn;
-	int i;
-	int nr_pages;
+	unsigned long next_bfn, xen_pfn = XEN_PFN_DOWN(p);
+	unsigned int i, nr_pages = XEN_PFN_UP(xen_offset_in_page(p) + size);
 
 	next_bfn = pfn_to_bfn(xen_pfn);
-	nr_pages = (offset + length + XEN_PAGE_SIZE-1) >> XEN_PAGE_SHIFT;
 
-	for (i = 1; i < nr_pages; i++) {
+	for (i = 1; i < nr_pages; i++)
 		if (pfn_to_bfn(++xen_pfn) != ++next_bfn)
-			return 0;
-	}
-	return 1;
-}
+			return 1;
 
-static inline int range_straddles_page_boundary(phys_addr_t p, size_t size)
-{
-	unsigned long xen_pfn = XEN_PFN_DOWN(p);
-	unsigned int offset = p & ~XEN_PAGE_MASK;
-
-	if (offset + size <= XEN_PAGE_SIZE)
-		return 0;
-	if (check_pages_physically_contiguous(xen_pfn, offset, size))
-		return 0;
-	return 1;
+	return 0;
 }
 
 static int is_xen_swiotlb_buffer(dma_addr_t dma_addr)
-- 
2.16.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 3/3] xen/swiotlb: remember having called xen_create_contiguous_region()
  2019-05-29  9:04 [PATCH v2 0/3] xen/swiotlb: fix an issue and improve swiotlb-xen Juergen Gross
  2019-05-29  9:04 ` [PATCH v2 1/3] xen/swiotlb: fix condition for calling xen_destroy_contiguous_region() Juergen Gross
  2019-05-29  9:04 ` [PATCH v2 2/3] xen/swiotlb: simplify range_straddles_page_boundary() Juergen Gross
@ 2019-05-29  9:04 ` Juergen Gross
  2019-05-29  9:57   ` [Xen-devel] " Jan Beulich
  2019-05-30  9:04   ` Christoph Hellwig
  2 siblings, 2 replies; 11+ messages in thread
From: Juergen Gross @ 2019-05-29  9:04 UTC (permalink / raw)
  To: linux-kernel, iommu
  Cc: Juergen Gross, Konrad Rzeszutek Wilk, Boris Ostrovsky,
	Stefano Stabellini, xen-devel

Instead of always calling xen_destroy_contiguous_region() in case the
memory is DMA-able for the used device, do so only in case it has been
made DMA-able via xen_create_contiguous_region() before.

This will avoid a lot of xen_destroy_contiguous_region() calls for
64-bit capable devices.

As the memory in question is owned by swiotlb-xen the PG_owner_priv_1
flag of the first allocated page can be used for remembering.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
V2: add PG_xen_remapped alias for PG_owner_priv_1 (Boris Ostrovsky)
    only clear page flag in case of sane conditions (Jan Beulich)
---
 drivers/xen/swiotlb-xen.c  | 6 +++++-
 include/linux/page-flags.h | 3 +++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index aba5247b9145..7e2d9d1b6f63 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -321,6 +321,7 @@ xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
 			xen_free_coherent_pages(hwdev, size, ret, (dma_addr_t)phys, attrs);
 			return NULL;
 		}
+		SetPageXenRemapped(virt_to_page(ret));
 	}
 	memset(ret, 0, size);
 	return ret;
@@ -345,8 +346,11 @@ xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
 	size = 1UL << (order + XEN_PAGE_SHIFT);
 
 	if (!WARN_ON((dev_addr + size - 1 > dma_mask) ||
-		     range_straddles_page_boundary(phys, size)))
+		     range_straddles_page_boundary(phys, size)) &&
+	    PageXenRemapped(virt_to_page(vaddr))) {
 		xen_destroy_contiguous_region(phys, order);
+		ClearPageXenRemapped(virt_to_page(vaddr));
+	}
 
 	xen_free_coherent_pages(hwdev, size, vaddr, (dma_addr_t)phys, attrs);
 }
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 9f8712a4b1a5..296480e990f2 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -152,6 +152,8 @@ enum pageflags {
 	PG_savepinned = PG_dirty,
 	/* Has a grant mapping of another (foreign) domain's page. */
 	PG_foreign = PG_owner_priv_1,
+	/* Remapped by swiotlb-xen. */
+	PG_xen_remapped = PG_owner_priv_1,
 
 	/* SLOB */
 	PG_slob_free = PG_private,
@@ -329,6 +331,7 @@ PAGEFLAG(Pinned, pinned, PF_NO_COMPOUND)
 	TESTSCFLAG(Pinned, pinned, PF_NO_COMPOUND)
 PAGEFLAG(SavePinned, savepinned, PF_NO_COMPOUND);
 PAGEFLAG(Foreign, foreign, PF_NO_COMPOUND);
+PAGEFLAG(XenRemapped, xen_remapped, PF_NO_COMPOUND);
 
 PAGEFLAG(Reserved, reserved, PF_NO_COMPOUND)
 	__CLEARPAGEFLAG(Reserved, reserved, PF_NO_COMPOUND)
-- 
2.16.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Xen-devel] [PATCH v2 1/3] xen/swiotlb: fix condition for calling xen_destroy_contiguous_region()
  2019-05-29  9:04 ` [PATCH v2 1/3] xen/swiotlb: fix condition for calling xen_destroy_contiguous_region() Juergen Gross
@ 2019-05-29  9:52   ` Jan Beulich
  0 siblings, 0 replies; 11+ messages in thread
From: Jan Beulich @ 2019-05-29  9:52 UTC (permalink / raw)
  To: Juergen Gross
  Cc: Stefano Stabellini, iommu, xen-devel, Boris Ostrovsky,
	Konrad Rzeszutek Wilk, linux-kernel, stable

>>> On 29.05.19 at 11:04, <jgross@suse.com> wrote:
> The condition in xen_swiotlb_free_coherent() for deciding whether to
> call xen_destroy_contiguous_region() is wrong: in case the region to
> be freed is not contiguous calling xen_destroy_contiguous_region() is
> the wrong thing to do: it would result in inconsistent mappings of
> multiple PFNs to the same MFN. This will lead to various strange
> crashes or data corruption.
> 
> Instead of calling xen_destroy_contiguous_region() in that case a
> warning should be issued as that situation should never occur.
> 
> Cc: stable@vger.kernel.org 
> Signed-off-by: Juergen Gross <jgross@suse.com>
> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>

Reviewed-by: Jan Beulich <jbeulich@suse.com>



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Xen-devel] [PATCH v2 3/3] xen/swiotlb: remember having called xen_create_contiguous_region()
  2019-05-29  9:04 ` [PATCH v2 3/3] xen/swiotlb: remember having called xen_create_contiguous_region() Juergen Gross
@ 2019-05-29  9:57   ` Jan Beulich
  2019-05-29 10:21     ` Juergen Gross
  2019-05-30  9:04   ` Christoph Hellwig
  1 sibling, 1 reply; 11+ messages in thread
From: Jan Beulich @ 2019-05-29  9:57 UTC (permalink / raw)
  To: Juergen Gross
  Cc: Stefano Stabellini, iommu, xen-devel, Boris Ostrovsky,
	Konrad Rzeszutek Wilk, linux-kernel

>>> On 29.05.19 at 11:04, <jgross@suse.com> wrote:
> @@ -345,8 +346,11 @@ xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
>  	size = 1UL << (order + XEN_PAGE_SHIFT);
>  
>  	if (!WARN_ON((dev_addr + size - 1 > dma_mask) ||
> -		     range_straddles_page_boundary(phys, size)))
> +		     range_straddles_page_boundary(phys, size)) &&
> +	    PageXenRemapped(virt_to_page(vaddr))) {
>  		xen_destroy_contiguous_region(phys, order);
> +		ClearPageXenRemapped(virt_to_page(vaddr));
> +	}

To be symmetric with setting the flag only after having made the region
contiguous, and to avoid (perhaps just theoretical) races, wouldn't it be
better to clear the flag before calling xen_destroy_contiguous_region()?
Even better would be a TestAndClear...() operation.

Jan



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Xen-devel] [PATCH v2 3/3] xen/swiotlb: remember having called xen_create_contiguous_region()
  2019-05-29  9:57   ` [Xen-devel] " Jan Beulich
@ 2019-05-29 10:21     ` Juergen Gross
  0 siblings, 0 replies; 11+ messages in thread
From: Juergen Gross @ 2019-05-29 10:21 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Stefano Stabellini, iommu, xen-devel, Boris Ostrovsky,
	Konrad Rzeszutek Wilk, linux-kernel

On 29/05/2019 11:57, Jan Beulich wrote:
>>>> On 29.05.19 at 11:04, <jgross@suse.com> wrote:
>> @@ -345,8 +346,11 @@ xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
>>  	size = 1UL << (order + XEN_PAGE_SHIFT);
>>  
>>  	if (!WARN_ON((dev_addr + size - 1 > dma_mask) ||
>> -		     range_straddles_page_boundary(phys, size)))
>> +		     range_straddles_page_boundary(phys, size)) &&
>> +	    PageXenRemapped(virt_to_page(vaddr))) {
>>  		xen_destroy_contiguous_region(phys, order);
>> +		ClearPageXenRemapped(virt_to_page(vaddr));
>> +	}
> 
> To be symmetric with setting the flag only after having made the region
> contiguous, and to avoid (perhaps just theoretical) races, wouldn't it be
> better to clear the flag before calling xen_destroy_contiguous_region()?
> Even better would be a TestAndClear...() operation.

I like that idea.


Juergen

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 3/3] xen/swiotlb: remember having called xen_create_contiguous_region()
  2019-05-29  9:04 ` [PATCH v2 3/3] xen/swiotlb: remember having called xen_create_contiguous_region() Juergen Gross
  2019-05-29  9:57   ` [Xen-devel] " Jan Beulich
@ 2019-05-30  9:04   ` Christoph Hellwig
  2019-05-30 12:46     ` Boris Ostrovsky
  1 sibling, 1 reply; 11+ messages in thread
From: Christoph Hellwig @ 2019-05-30  9:04 UTC (permalink / raw)
  To: Juergen Gross
  Cc: linux-kernel, iommu, Konrad Rzeszutek Wilk, Boris Ostrovsky,
	Stefano Stabellini, xen-devel

Please don't add your private flag to page-flags.h.  The whole point of
the private flag is that you can use it in any way you want withou
touching the common code.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 3/3] xen/swiotlb: remember having called xen_create_contiguous_region()
  2019-05-30  9:04   ` Christoph Hellwig
@ 2019-05-30 12:46     ` Boris Ostrovsky
  2019-05-31 11:38       ` Juergen Gross
  0 siblings, 1 reply; 11+ messages in thread
From: Boris Ostrovsky @ 2019-05-30 12:46 UTC (permalink / raw)
  To: Christoph Hellwig, Juergen Gross
  Cc: linux-kernel, iommu, Konrad Rzeszutek Wilk, Stefano Stabellini,
	xen-devel

On 5/30/19 5:04 AM, Christoph Hellwig wrote:
> Please don't add your private flag to page-flags.h.  The whole point of
> the private flag is that you can use it in any way you want withou
> touching the common code.


There is already a bunch of aliases for various sub-components
(including Xen) in page-flags.h for private flags, which is why I
suggested we do the same for the new use case. Adding this new alias
will keep flag usage consistent.

-boris

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 3/3] xen/swiotlb: remember having called xen_create_contiguous_region()
  2019-05-30 12:46     ` Boris Ostrovsky
@ 2019-05-31 11:38       ` Juergen Gross
  2019-06-05  8:37         ` Juergen Gross
  0 siblings, 1 reply; 11+ messages in thread
From: Juergen Gross @ 2019-05-31 11:38 UTC (permalink / raw)
  To: Boris Ostrovsky, Christoph Hellwig
  Cc: linux-kernel, iommu, Konrad Rzeszutek Wilk, Stefano Stabellini,
	xen-devel

On 30/05/2019 14:46, Boris Ostrovsky wrote:
> On 5/30/19 5:04 AM, Christoph Hellwig wrote:
>> Please don't add your private flag to page-flags.h.  The whole point of
>> the private flag is that you can use it in any way you want withou
>> touching the common code.
> 
> 
> There is already a bunch of aliases for various sub-components
> (including Xen) in page-flags.h for private flags, which is why I
> suggested we do the same for the new use case. Adding this new alias
> will keep flag usage consistent.

What about me adding another patch moving those Xen private aliases
into arch/x86/include/asm/xen/page.h ?


Juergen


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 3/3] xen/swiotlb: remember having called xen_create_contiguous_region()
  2019-05-31 11:38       ` Juergen Gross
@ 2019-06-05  8:37         ` Juergen Gross
  0 siblings, 0 replies; 11+ messages in thread
From: Juergen Gross @ 2019-06-05  8:37 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Boris Ostrovsky, linux-kernel, iommu, Konrad Rzeszutek Wilk,
	Stefano Stabellini, xen-devel

On 31.05.19 13:38, Juergen Gross wrote:
> On 30/05/2019 14:46, Boris Ostrovsky wrote:
>> On 5/30/19 5:04 AM, Christoph Hellwig wrote:
>>> Please don't add your private flag to page-flags.h.  The whole point of
>>> the private flag is that you can use it in any way you want withou
>>> touching the common code.
>>
>>
>> There is already a bunch of aliases for various sub-components
>> (including Xen) in page-flags.h for private flags, which is why I
>> suggested we do the same for the new use case. Adding this new alias
>> will keep flag usage consistent.
> 
> What about me adding another patch moving those Xen private aliases
> into arch/x86/include/asm/xen/page.h ?

This is becoming difficult.

I'd need to remove the "#undef PF_NO_COMPOUND" from page-flags.h or to
#include a (new) xen/page-flags.h from page-flags.h after all the
defines are ready. Is that really worth the effort given that other
components (e.g. file systems) are doing the same?


Juergen

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2019-06-05  8:37 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-29  9:04 [PATCH v2 0/3] xen/swiotlb: fix an issue and improve swiotlb-xen Juergen Gross
2019-05-29  9:04 ` [PATCH v2 1/3] xen/swiotlb: fix condition for calling xen_destroy_contiguous_region() Juergen Gross
2019-05-29  9:52   ` [Xen-devel] " Jan Beulich
2019-05-29  9:04 ` [PATCH v2 2/3] xen/swiotlb: simplify range_straddles_page_boundary() Juergen Gross
2019-05-29  9:04 ` [PATCH v2 3/3] xen/swiotlb: remember having called xen_create_contiguous_region() Juergen Gross
2019-05-29  9:57   ` [Xen-devel] " Jan Beulich
2019-05-29 10:21     ` Juergen Gross
2019-05-30  9:04   ` Christoph Hellwig
2019-05-30 12:46     ` Boris Ostrovsky
2019-05-31 11:38       ` Juergen Gross
2019-06-05  8:37         ` Juergen Gross

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).