diff options
11 files changed, 586 insertions, 0 deletions
diff --git a/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0001-swiotlb-xen-use-vmalloc_to_page-on-vmalloc-virt-addr.patch b/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0001-swiotlb-xen-use-vmalloc_to_page-on-vmalloc-virt-addr.patch new file mode 100644 index 00000000..09144ced --- /dev/null +++ b/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0001-swiotlb-xen-use-vmalloc_to_page-on-vmalloc-virt-addr.patch | |||
@@ -0,0 +1,44 @@ | |||
1 | From f5f4de59377afdd9a80e0f47df109eacf427c203 Mon Sep 17 00:00:00 2001 | ||
2 | From: Boris Ostrovsky <boris.ostrovsky@oracle.com> | ||
3 | Date: Wed, 20 May 2020 16:42:06 -0700 | ||
4 | Subject: [PATCH 01/10] swiotlb-xen: use vmalloc_to_page on vmalloc virt | ||
5 | addresses | ||
6 | |||
7 | Don't just assume that virt_to_page works on all virtual addresses. | ||
8 | Instead add a is_vmalloc_addr check and use vmalloc_to_page on vmalloc | ||
9 | virt addresses. | ||
10 | |||
11 | Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> | ||
12 | Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
13 | --- | ||
14 | drivers/xen/swiotlb-xen.c | 5 ++++- | ||
15 | 1 file changed, 4 insertions(+), 1 deletion(-) | ||
16 | |||
17 | diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c | ||
18 | index b6d27762c6f8..a42129cba36e 100644 | ||
19 | --- a/drivers/xen/swiotlb-xen.c | ||
20 | +++ b/drivers/xen/swiotlb-xen.c | ||
21 | @@ -335,6 +335,7 @@ xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, | ||
22 | int order = get_order(size); | ||
23 | phys_addr_t phys; | ||
24 | u64 dma_mask = DMA_BIT_MASK(32); | ||
25 | + struct page *pg; | ||
26 | |||
27 | if (hwdev && hwdev->coherent_dma_mask) | ||
28 | dma_mask = hwdev->coherent_dma_mask; | ||
29 | @@ -346,9 +347,11 @@ xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, | ||
30 | /* Convert the size to actually allocated. */ | ||
31 | size = 1UL << (order + XEN_PAGE_SHIFT); | ||
32 | |||
33 | + pg = is_vmalloc_addr(vaddr) ? vmalloc_to_page(vaddr) : | ||
34 | + virt_to_page(vaddr); | ||
35 | if (!WARN_ON((dev_addr + size - 1 > dma_mask) || | ||
36 | range_straddles_page_boundary(phys, size)) && | ||
37 | - TestClearPageXenRemapped(virt_to_page(vaddr))) | ||
38 | + TestClearPageXenRemapped(pg)) | ||
39 | xen_destroy_contiguous_region(phys, order); | ||
40 | |||
41 | xen_free_coherent_pages(hwdev, size, vaddr, (dma_addr_t)phys, attrs); | ||
42 | -- | ||
43 | 2.15.4 | ||
44 | |||
diff --git a/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0002-swiotlb-xen-remove-start_dma_addr.patch b/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0002-swiotlb-xen-remove-start_dma_addr.patch new file mode 100644 index 00000000..9c572a11 --- /dev/null +++ b/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0002-swiotlb-xen-remove-start_dma_addr.patch | |||
@@ -0,0 +1,47 @@ | |||
1 | From d078eac368946990c27b86198d2a37416ea02002 Mon Sep 17 00:00:00 2001 | ||
2 | From: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
3 | Date: Wed, 20 May 2020 16:42:11 -0700 | ||
4 | Subject: [PATCH 02/10] swiotlb-xen: remove start_dma_addr | ||
5 | |||
6 | It is not strictly needed. Call virt_to_phys on xen_io_tlb_start | ||
7 | instead. It will be useful not to have a start_dma_addr around with the | ||
8 | next patches. | ||
9 | |||
10 | Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
11 | --- | ||
12 | drivers/xen/swiotlb-xen.c | 5 +---- | ||
13 | 1 file changed, 1 insertion(+), 4 deletions(-) | ||
14 | |||
15 | diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c | ||
16 | index a42129cba36e..b5e0492b07b9 100644 | ||
17 | --- a/drivers/xen/swiotlb-xen.c | ||
18 | +++ b/drivers/xen/swiotlb-xen.c | ||
19 | @@ -52,8 +52,6 @@ static unsigned long xen_io_tlb_nslabs; | ||
20 | * Quick lookup value of the bus address of the IOTLB. | ||
21 | */ | ||
22 | |||
23 | -static u64 start_dma_addr; | ||
24 | - | ||
25 | /* | ||
26 | * Both of these functions should avoid XEN_PFN_PHYS because phys_addr_t | ||
27 | * can be 32bit when dma_addr_t is 64bit leading to a loss in | ||
28 | @@ -241,7 +239,6 @@ int __ref xen_swiotlb_init(int verbose, bool early) | ||
29 | m_ret = XEN_SWIOTLB_EFIXUP; | ||
30 | goto error; | ||
31 | } | ||
32 | - start_dma_addr = xen_virt_to_bus(xen_io_tlb_start); | ||
33 | if (early) { | ||
34 | if (swiotlb_init_with_tbl(xen_io_tlb_start, xen_io_tlb_nslabs, | ||
35 | verbose)) | ||
36 | @@ -389,7 +386,7 @@ static dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page, | ||
37 | */ | ||
38 | trace_swiotlb_bounced(dev, dev_addr, size, swiotlb_force); | ||
39 | |||
40 | - map = swiotlb_tbl_map_single(dev, start_dma_addr, phys, | ||
41 | + map = swiotlb_tbl_map_single(dev, virt_to_phys(xen_io_tlb_start), phys, | ||
42 | size, size, dir, attrs); | ||
43 | if (map == (phys_addr_t)DMA_MAPPING_ERROR) | ||
44 | return DMA_MAPPING_ERROR; | ||
45 | -- | ||
46 | 2.15.4 | ||
47 | |||
diff --git a/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0003-swiotlb-xen-add-struct-device-parameter-to-xen_phys_.patch b/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0003-swiotlb-xen-add-struct-device-parameter-to-xen_phys_.patch new file mode 100644 index 00000000..d90701ba --- /dev/null +++ b/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0003-swiotlb-xen-add-struct-device-parameter-to-xen_phys_.patch | |||
@@ -0,0 +1,78 @@ | |||
1 | From 5ef503632a8df9be70f3c1ff828780e4348a03dc Mon Sep 17 00:00:00 2001 | ||
2 | From: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
3 | Date: Wed, 20 May 2020 16:42:11 -0700 | ||
4 | Subject: [PATCH 03/10] swiotlb-xen: add struct device* parameter to | ||
5 | xen_phys_to_bus | ||
6 | |||
7 | The parameter is unused in this patch. | ||
8 | No functional changes. | ||
9 | |||
10 | Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
11 | --- | ||
12 | drivers/xen/swiotlb-xen.c | 14 +++++++------- | ||
13 | 1 file changed, 7 insertions(+), 7 deletions(-) | ||
14 | |||
15 | diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c | ||
16 | index b5e0492b07b9..958ee5517e0b 100644 | ||
17 | --- a/drivers/xen/swiotlb-xen.c | ||
18 | +++ b/drivers/xen/swiotlb-xen.c | ||
19 | @@ -57,7 +57,7 @@ static unsigned long xen_io_tlb_nslabs; | ||
20 | * can be 32bit when dma_addr_t is 64bit leading to a loss in | ||
21 | * information if the shift is done before casting to 64bit. | ||
22 | */ | ||
23 | -static inline dma_addr_t xen_phys_to_bus(phys_addr_t paddr) | ||
24 | +static inline dma_addr_t xen_phys_to_bus(struct device *dev, phys_addr_t paddr) | ||
25 | { | ||
26 | unsigned long bfn = pfn_to_bfn(XEN_PFN_DOWN(paddr)); | ||
27 | dma_addr_t dma = (dma_addr_t)bfn << XEN_PAGE_SHIFT; | ||
28 | @@ -78,9 +78,9 @@ static inline phys_addr_t xen_bus_to_phys(dma_addr_t baddr) | ||
29 | return paddr; | ||
30 | } | ||
31 | |||
32 | -static inline dma_addr_t xen_virt_to_bus(void *address) | ||
33 | +static inline dma_addr_t xen_virt_to_bus(struct device *dev, void *address) | ||
34 | { | ||
35 | - return xen_phys_to_bus(virt_to_phys(address)); | ||
36 | + return xen_phys_to_bus(dev, virt_to_phys(address)); | ||
37 | } | ||
38 | |||
39 | static inline int range_straddles_page_boundary(phys_addr_t p, size_t size) | ||
40 | @@ -309,7 +309,7 @@ xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size, | ||
41 | * Do not use virt_to_phys(ret) because on ARM it doesn't correspond | ||
42 | * to *dma_handle. */ | ||
43 | phys = *dma_handle; | ||
44 | - dev_addr = xen_phys_to_bus(phys); | ||
45 | + dev_addr = xen_phys_to_bus(hwdev, phys); | ||
46 | if (((dev_addr + size - 1 <= dma_mask)) && | ||
47 | !range_straddles_page_boundary(phys, size)) | ||
48 | *dma_handle = dev_addr; | ||
49 | @@ -367,7 +367,7 @@ static dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page, | ||
50 | unsigned long attrs) | ||
51 | { | ||
52 | phys_addr_t map, phys = page_to_phys(page) + offset; | ||
53 | - dma_addr_t dev_addr = xen_phys_to_bus(phys); | ||
54 | + dma_addr_t dev_addr = xen_phys_to_bus(dev, phys); | ||
55 | |||
56 | BUG_ON(dir == DMA_NONE); | ||
57 | /* | ||
58 | @@ -392,7 +392,7 @@ static dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page, | ||
59 | return DMA_MAPPING_ERROR; | ||
60 | |||
61 | phys = map; | ||
62 | - dev_addr = xen_phys_to_bus(map); | ||
63 | + dev_addr = xen_phys_to_bus(dev, map); | ||
64 | |||
65 | /* | ||
66 | * Ensure that the address returned is DMA'ble | ||
67 | @@ -536,7 +536,7 @@ xen_swiotlb_sync_sg_for_device(struct device *dev, struct scatterlist *sgl, | ||
68 | static int | ||
69 | xen_swiotlb_dma_supported(struct device *hwdev, u64 mask) | ||
70 | { | ||
71 | - return xen_virt_to_bus(xen_io_tlb_end - 1) <= mask; | ||
72 | + return xen_virt_to_bus(hwdev, xen_io_tlb_end - 1) <= mask; | ||
73 | } | ||
74 | |||
75 | const struct dma_map_ops xen_swiotlb_dma_ops = { | ||
76 | -- | ||
77 | 2.15.4 | ||
78 | |||
diff --git a/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0004-swiotlb-xen-add-struct-device-parameter-to-xen_bus_t.patch b/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0004-swiotlb-xen-add-struct-device-parameter-to-xen_bus_t.patch new file mode 100644 index 00000000..ccd03f1c --- /dev/null +++ b/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0004-swiotlb-xen-add-struct-device-parameter-to-xen_bus_t.patch | |||
@@ -0,0 +1,66 @@ | |||
1 | From ed2cec0f196028f4eaed0951f1f82efd9e6b1b67 Mon Sep 17 00:00:00 2001 | ||
2 | From: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
3 | Date: Wed, 20 May 2020 16:42:12 -0700 | ||
4 | Subject: [PATCH 04/10] swiotlb-xen: add struct device* parameter to | ||
5 | xen_bus_to_phys | ||
6 | |||
7 | The parameter is unused in this patch. | ||
8 | No functional changes. | ||
9 | |||
10 | Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
11 | --- | ||
12 | drivers/xen/swiotlb-xen.c | 10 +++++----- | ||
13 | 1 file changed, 5 insertions(+), 5 deletions(-) | ||
14 | |||
15 | diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c | ||
16 | index 958ee5517e0b..9b4306a56feb 100644 | ||
17 | --- a/drivers/xen/swiotlb-xen.c | ||
18 | +++ b/drivers/xen/swiotlb-xen.c | ||
19 | @@ -67,7 +67,7 @@ static inline dma_addr_t xen_phys_to_bus(struct device *dev, phys_addr_t paddr) | ||
20 | return dma; | ||
21 | } | ||
22 | |||
23 | -static inline phys_addr_t xen_bus_to_phys(dma_addr_t baddr) | ||
24 | +static inline phys_addr_t xen_bus_to_phys(struct device *dev, dma_addr_t baddr) | ||
25 | { | ||
26 | unsigned long xen_pfn = bfn_to_pfn(XEN_PFN_DOWN(baddr)); | ||
27 | dma_addr_t dma = (dma_addr_t)xen_pfn << XEN_PAGE_SHIFT; | ||
28 | @@ -339,7 +339,7 @@ xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, | ||
29 | |||
30 | /* do not use virt_to_phys because on ARM it doesn't return you the | ||
31 | * physical address */ | ||
32 | - phys = xen_bus_to_phys(dev_addr); | ||
33 | + phys = xen_bus_to_phys(hwdev, dev_addr); | ||
34 | |||
35 | /* Convert the size to actually allocated. */ | ||
36 | size = 1UL << (order + XEN_PAGE_SHIFT); | ||
37 | @@ -420,7 +420,7 @@ static dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page, | ||
38 | static void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr, | ||
39 | size_t size, enum dma_data_direction dir, unsigned long attrs) | ||
40 | { | ||
41 | - phys_addr_t paddr = xen_bus_to_phys(dev_addr); | ||
42 | + phys_addr_t paddr = xen_bus_to_phys(hwdev, dev_addr); | ||
43 | |||
44 | BUG_ON(dir == DMA_NONE); | ||
45 | |||
46 | @@ -436,7 +436,7 @@ static void | ||
47 | xen_swiotlb_sync_single_for_cpu(struct device *dev, dma_addr_t dma_addr, | ||
48 | size_t size, enum dma_data_direction dir) | ||
49 | { | ||
50 | - phys_addr_t paddr = xen_bus_to_phys(dma_addr); | ||
51 | + phys_addr_t paddr = xen_bus_to_phys(dev, dma_addr); | ||
52 | |||
53 | if (!dev_is_dma_coherent(dev)) | ||
54 | xen_dma_sync_for_cpu(dma_addr, paddr, size, dir); | ||
55 | @@ -449,7 +449,7 @@ static void | ||
56 | xen_swiotlb_sync_single_for_device(struct device *dev, dma_addr_t dma_addr, | ||
57 | size_t size, enum dma_data_direction dir) | ||
58 | { | ||
59 | - phys_addr_t paddr = xen_bus_to_phys(dma_addr); | ||
60 | + phys_addr_t paddr = xen_bus_to_phys(dev, dma_addr); | ||
61 | |||
62 | if (is_xen_swiotlb_buffer(dma_addr)) | ||
63 | swiotlb_tbl_sync_single(dev, paddr, size, dir, SYNC_FOR_DEVICE); | ||
64 | -- | ||
65 | 2.15.4 | ||
66 | |||
diff --git a/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0007-swiotlb-xen-add-struct-device-parameter-to-is_xen_sw.patch b/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0007-swiotlb-xen-add-struct-device-parameter-to-is_xen_sw.patch new file mode 100644 index 00000000..9ef40598 --- /dev/null +++ b/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0007-swiotlb-xen-add-struct-device-parameter-to-is_xen_sw.patch | |||
@@ -0,0 +1,57 @@ | |||
1 | From f19187658bc7625f5e3ef89f56d599552b37a497 Mon Sep 17 00:00:00 2001 | ||
2 | From: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
3 | Date: Wed, 20 May 2020 16:42:15 -0700 | ||
4 | Subject: [PATCH 07/10] swiotlb-xen: add struct device* parameter to | ||
5 | is_xen_swiotlb_buffer | ||
6 | |||
7 | The parameter is unused in this patch. | ||
8 | No functional changes. | ||
9 | |||
10 | Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
11 | --- | ||
12 | drivers/xen/swiotlb-xen.c | 8 ++++---- | ||
13 | 1 file changed, 4 insertions(+), 4 deletions(-) | ||
14 | |||
15 | diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c | ||
16 | index ef58f05ae445..c50448fd9b75 100644 | ||
17 | --- a/drivers/xen/swiotlb-xen.c | ||
18 | +++ b/drivers/xen/swiotlb-xen.c | ||
19 | @@ -97,7 +97,7 @@ static inline int range_straddles_page_boundary(phys_addr_t p, size_t size) | ||
20 | return 0; | ||
21 | } | ||
22 | |||
23 | -static int is_xen_swiotlb_buffer(dma_addr_t dma_addr) | ||
24 | +static int is_xen_swiotlb_buffer(struct device *dev, dma_addr_t dma_addr) | ||
25 | { | ||
26 | unsigned long bfn = XEN_PFN_DOWN(dma_addr); | ||
27 | unsigned long xen_pfn = bfn_to_local_pfn(bfn); | ||
28 | @@ -428,7 +428,7 @@ static void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr, | ||
29 | xen_dma_sync_for_cpu(hwdev, dev_addr, paddr, size, dir); | ||
30 | |||
31 | /* NOTE: We use dev_addr here, not paddr! */ | ||
32 | - if (is_xen_swiotlb_buffer(dev_addr)) | ||
33 | + if (is_xen_swiotlb_buffer(hwdev, dev_addr)) | ||
34 | swiotlb_tbl_unmap_single(hwdev, paddr, size, size, dir, attrs); | ||
35 | } | ||
36 | |||
37 | @@ -441,7 +441,7 @@ xen_swiotlb_sync_single_for_cpu(struct device *dev, dma_addr_t dma_addr, | ||
38 | if (!dev_is_dma_coherent(dev)) | ||
39 | xen_dma_sync_for_cpu(dev, dma_addr, paddr, size, dir); | ||
40 | |||
41 | - if (is_xen_swiotlb_buffer(dma_addr)) | ||
42 | + if (is_xen_swiotlb_buffer(dev, dma_addr)) | ||
43 | swiotlb_tbl_sync_single(dev, paddr, size, dir, SYNC_FOR_CPU); | ||
44 | } | ||
45 | |||
46 | @@ -451,7 +451,7 @@ xen_swiotlb_sync_single_for_device(struct device *dev, dma_addr_t dma_addr, | ||
47 | { | ||
48 | phys_addr_t paddr = xen_bus_to_phys(dev, dma_addr); | ||
49 | |||
50 | - if (is_xen_swiotlb_buffer(dma_addr)) | ||
51 | + if (is_xen_swiotlb_buffer(dev, dma_addr)) | ||
52 | swiotlb_tbl_sync_single(dev, paddr, size, dir, SYNC_FOR_DEVICE); | ||
53 | |||
54 | if (!dev_is_dma_coherent(dev)) | ||
55 | -- | ||
56 | 2.15.4 | ||
57 | |||
diff --git a/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0008-swiotlb-xen-introduce-phys_to_dma-dma_to_phys-transl.patch b/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0008-swiotlb-xen-introduce-phys_to_dma-dma_to_phys-transl.patch new file mode 100644 index 00000000..2b59e180 --- /dev/null +++ b/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0008-swiotlb-xen-introduce-phys_to_dma-dma_to_phys-transl.patch | |||
@@ -0,0 +1,88 @@ | |||
1 | From 9838cc0b60a4287034ac3bc94a3adf08bc1c3858 Mon Sep 17 00:00:00 2001 | ||
2 | From: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
3 | Date: Wed, 20 May 2020 16:42:57 -0700 | ||
4 | Subject: [PATCH 08/10] swiotlb-xen: introduce phys_to_dma/dma_to_phys | ||
5 | translations | ||
6 | |||
7 | Call dma_to_phys in is_xen_swiotlb_buffer. | ||
8 | Call phys_to_dma in xen_phys_to_bus. | ||
9 | Call dma_to_phys in xen_bus_to_phys. | ||
10 | |||
11 | Everything is taken care of by these changes except for | ||
12 | xen_swiotlb_alloc_coherent and xen_swiotlb_free_coherent, which need a | ||
13 | few explicit phys_to_dma/dma_to_phys calls. | ||
14 | |||
15 | Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
16 | --- | ||
17 | drivers/xen/swiotlb-xen.c | 20 ++++++++++++-------- | ||
18 | 1 file changed, 12 insertions(+), 8 deletions(-) | ||
19 | |||
20 | diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c | ||
21 | index c50448fd9b75..d011c4c7aa72 100644 | ||
22 | --- a/drivers/xen/swiotlb-xen.c | ||
23 | +++ b/drivers/xen/swiotlb-xen.c | ||
24 | @@ -64,14 +64,16 @@ static inline dma_addr_t xen_phys_to_bus(struct device *dev, phys_addr_t paddr) | ||
25 | |||
26 | dma |= paddr & ~XEN_PAGE_MASK; | ||
27 | |||
28 | - return dma; | ||
29 | + return phys_to_dma(dev, dma); | ||
30 | } | ||
31 | |||
32 | -static inline phys_addr_t xen_bus_to_phys(struct device *dev, dma_addr_t baddr) | ||
33 | +static inline phys_addr_t xen_bus_to_phys(struct device *dev, | ||
34 | + dma_addr_t dma_addr) | ||
35 | { | ||
36 | + phys_addr_t baddr = dma_to_phys(dev, dma_addr); | ||
37 | unsigned long xen_pfn = bfn_to_pfn(XEN_PFN_DOWN(baddr)); | ||
38 | - dma_addr_t dma = (dma_addr_t)xen_pfn << XEN_PAGE_SHIFT; | ||
39 | - phys_addr_t paddr = dma; | ||
40 | + phys_addr_t paddr = (xen_pfn << XEN_PAGE_SHIFT) | | ||
41 | + (baddr & ~XEN_PAGE_MASK); | ||
42 | |||
43 | paddr |= baddr & ~XEN_PAGE_MASK; | ||
44 | |||
45 | @@ -99,7 +101,7 @@ static inline int range_straddles_page_boundary(phys_addr_t p, size_t size) | ||
46 | |||
47 | static int is_xen_swiotlb_buffer(struct device *dev, dma_addr_t dma_addr) | ||
48 | { | ||
49 | - unsigned long bfn = XEN_PFN_DOWN(dma_addr); | ||
50 | + unsigned long bfn = XEN_PFN_DOWN(dma_to_phys(dev, dma_addr)); | ||
51 | unsigned long xen_pfn = bfn_to_local_pfn(bfn); | ||
52 | phys_addr_t paddr = XEN_PFN_PHYS(xen_pfn); | ||
53 | |||
54 | @@ -304,11 +306,11 @@ xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size, | ||
55 | if (hwdev && hwdev->coherent_dma_mask) | ||
56 | dma_mask = hwdev->coherent_dma_mask; | ||
57 | |||
58 | - /* At this point dma_handle is the physical address, next we are | ||
59 | + /* At this point dma_handle is the dma address, next we are | ||
60 | * going to set it to the machine address. | ||
61 | * Do not use virt_to_phys(ret) because on ARM it doesn't correspond | ||
62 | * to *dma_handle. */ | ||
63 | - phys = *dma_handle; | ||
64 | + phys = dma_to_phys(hwdev, *dma_handle); | ||
65 | dev_addr = xen_phys_to_bus(hwdev, phys); | ||
66 | if (((dev_addr + size - 1 <= dma_mask)) && | ||
67 | !range_straddles_page_boundary(phys, size)) | ||
68 | @@ -319,6 +321,7 @@ xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size, | ||
69 | xen_free_coherent_pages(hwdev, size, ret, (dma_addr_t)phys, attrs); | ||
70 | return NULL; | ||
71 | } | ||
72 | + *dma_handle = phys_to_dma(hwdev, *dma_handle); | ||
73 | SetPageXenRemapped(virt_to_page(ret)); | ||
74 | } | ||
75 | memset(ret, 0, size); | ||
76 | @@ -351,7 +354,8 @@ xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, | ||
77 | TestClearPageXenRemapped(pg)) | ||
78 | xen_destroy_contiguous_region(phys, order); | ||
79 | |||
80 | - xen_free_coherent_pages(hwdev, size, vaddr, (dma_addr_t)phys, attrs); | ||
81 | + xen_free_coherent_pages(hwdev, size, vaddr, phys_to_dma(hwdev, phys), | ||
82 | + attrs); | ||
83 | } | ||
84 | |||
85 | /* | ||
86 | -- | ||
87 | 2.15.4 | ||
88 | |||
diff --git a/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0009-xen-arm-introduce-phys-dma-translations-in-xen_dma_s_kernel_5.4.patch b/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0009-xen-arm-introduce-phys-dma-translations-in-xen_dma_s_kernel_5.4.patch new file mode 100644 index 00000000..9676698f --- /dev/null +++ b/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0009-xen-arm-introduce-phys-dma-translations-in-xen_dma_s_kernel_5.4.patch | |||
@@ -0,0 +1,68 @@ | |||
1 | From 9749386d4ba0adb545cfad494b312894909cc7a4 Mon Sep 17 00:00:00 2001 | ||
2 | From: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
3 | Date: Wed, 20 May 2020 16:43:07 -0700 | ||
4 | Subject: [PATCH 09/10] xen/arm: introduce phys/dma translations in | ||
5 | xen_dma_sync_for_* | ||
6 | |||
7 | Add phys_to_dma/dma_to_phys calls to | ||
8 | xen_dma_sync_for_cpu, xen_dma_sync_for_device, and | ||
9 | xen_arch_need_swiotlb. | ||
10 | |||
11 | In xen_arch_need_swiotlb, take the opportunity to switch to the simpler | ||
12 | pfn_valid check we use everywhere else. | ||
13 | |||
14 | dma_cache_maint is fixed by the next patch. | ||
15 | |||
16 | Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
17 | Rebased onto 5.4 by: Christoher Clark <christopher.w.clark@gmail.com> | ||
18 | --- | ||
19 | arch/arm/xen/mm.c | 10 +++++----- | ||
20 | 1 file changed, 5 insertions(+), 5 deletions(-) | ||
21 | |||
22 | diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c | ||
23 | index 38fa917c8585..dc1fb57d2e12 100644 | ||
24 | --- a/arch/arm/xen/mm.c | ||
25 | +++ b/arch/arm/xen/mm.c | ||
26 | @@ -1,5 +1,6 @@ | ||
27 | // SPDX-License-Identifier: GPL-2.0-only | ||
28 | #include <linux/cpu.h> | ||
29 | +#include <linux/dma-direct.h> | ||
30 | #include <linux/dma-noncoherent.h> | ||
31 | #include <linux/gfp.h> | ||
32 | #include <linux/highmem.h> | ||
33 | @@ -73,7 +74,7 @@ static void dma_cache_maint(dma_addr_t handle, size_t size, u32 op) | ||
34 | void xen_dma_sync_for_cpu(struct device *dev, dma_addr_t handle, | ||
35 | phys_addr_t paddr, size_t size, enum dma_data_direction dir) | ||
36 | { | ||
37 | - if (pfn_valid(PFN_DOWN(handle))) | ||
38 | + if (pfn_valid(PFN_DOWN(dma_to_phys(dev, handle)))) | ||
39 | arch_sync_dma_for_cpu(dev, paddr, size, dir); | ||
40 | else if (dir != DMA_TO_DEVICE) | ||
41 | dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL); | ||
42 | @@ -82,7 +83,7 @@ void xen_dma_sync_for_cpu(struct device *dev, dma_addr_t handle, | ||
43 | void xen_dma_sync_for_device(struct device *dev, dma_addr_t handle, | ||
44 | phys_addr_t paddr, size_t size, enum dma_data_direction dir) | ||
45 | { | ||
46 | - if (pfn_valid(PFN_DOWN(handle))) | ||
47 | + if (pfn_valid(PFN_DOWN(dma_to_phys(dev, handle)))) | ||
48 | arch_sync_dma_for_device(dev, paddr, size, dir); | ||
49 | else if (dir == DMA_FROM_DEVICE) | ||
50 | dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL); | ||
51 | @@ -95,7 +96,7 @@ bool xen_arch_need_swiotlb(struct device *dev, | ||
52 | dma_addr_t dev_addr) | ||
53 | { | ||
54 | unsigned int xen_pfn = XEN_PFN_DOWN(phys); | ||
55 | - unsigned int bfn = XEN_PFN_DOWN(dev_addr); | ||
56 | + unsigned int bfn = XEN_PFN_DOWN(dma_to_phys(dev, dev_addr)); | ||
57 | |||
58 | /* | ||
59 | * The swiotlb buffer should be used if | ||
60 | @@ -112,7 +113,7 @@ bool xen_arch_need_swiotlb(struct device *dev, | ||
61 | * require a bounce buffer because the device doesn't support coherent | ||
62 | * memory and we are not able to flush the cache. | ||
63 | */ | ||
64 | - return (!hypercall_cflush && (xen_pfn != bfn) && | ||
65 | + return (!hypercall_cflush && !pfn_valid(bfn) && | ||
66 | !dev_is_dma_coherent(dev)); | ||
67 | } | ||
68 | |||
diff --git a/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0010-xen-arm-call-dma_to_phys-on-the-dma_addr_t-parameter.patch b/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0010-xen-arm-call-dma_to_phys-on-the-dma_addr_t-parameter.patch new file mode 100644 index 00000000..8e2dc3c1 --- /dev/null +++ b/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0010-xen-arm-call-dma_to_phys-on-the-dma_addr_t-parameter.patch | |||
@@ -0,0 +1,75 @@ | |||
1 | From 1f1182bf84ec7a6d1ec74c56fccd66ff013077af Mon Sep 17 00:00:00 2001 | ||
2 | From: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
3 | Date: Wed, 20 May 2020 16:43:08 -0700 | ||
4 | Subject: [PATCH 10/10] xen/arm: call dma_to_phys on the dma_addr_t parameter | ||
5 | of dma_cache_maint | ||
6 | |||
7 | Add a struct device* parameter to dma_cache_maint. | ||
8 | |||
9 | Translate the dma_addr_t parameter of dma_cache_maint by calling | ||
10 | dma_to_phys. Do it for the first page and all the following pages, in | ||
11 | case of multipage handling. | ||
12 | |||
13 | Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
14 | --- | ||
15 | arch/arm/xen/mm.c | 15 +++++++++------ | ||
16 | 1 file changed, 9 insertions(+), 6 deletions(-) | ||
17 | |||
18 | diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c | ||
19 | index 7639251bcc79..6ddf3b3c1ab5 100644 | ||
20 | --- a/arch/arm/xen/mm.c | ||
21 | +++ b/arch/arm/xen/mm.c | ||
22 | @@ -43,15 +43,18 @@ unsigned long xen_get_swiotlb_free_pages(unsigned int order) | ||
23 | static bool hypercall_cflush = false; | ||
24 | |||
25 | /* buffers in highmem or foreign pages cannot cross page boundaries */ | ||
26 | -static void dma_cache_maint(dma_addr_t handle, size_t size, u32 op) | ||
27 | +static void dma_cache_maint(struct device *dev, dma_addr_t handle, | ||
28 | + size_t size, u32 op) | ||
29 | { | ||
30 | struct gnttab_cache_flush cflush; | ||
31 | |||
32 | - cflush.a.dev_bus_addr = handle & XEN_PAGE_MASK; | ||
33 | cflush.offset = xen_offset_in_page(handle); | ||
34 | cflush.op = op; | ||
35 | + handle &= XEN_PAGE_MASK; | ||
36 | |||
37 | do { | ||
38 | + cflush.a.dev_bus_addr = dma_to_phys(dev, handle); | ||
39 | + | ||
40 | if (size + cflush.offset > XEN_PAGE_SIZE) | ||
41 | cflush.length = XEN_PAGE_SIZE - cflush.offset; | ||
42 | else | ||
43 | @@ -60,7 +63,7 @@ static void dma_cache_maint(dma_addr_t handle, size_t size, u32 op) | ||
44 | HYPERVISOR_grant_table_op(GNTTABOP_cache_flush, &cflush, 1); | ||
45 | |||
46 | cflush.offset = 0; | ||
47 | - cflush.a.dev_bus_addr += cflush.length; | ||
48 | + handle += cflush.length; | ||
49 | size -= cflush.length; | ||
50 | } while (size); | ||
51 | } | ||
52 | @@ -79,7 +82,7 @@ void xen_dma_sync_for_cpu(struct device *dev, dma_addr_t handle, | ||
53 | if (pfn_valid(PFN_DOWN(dma_to_phys(dev, handle)))) | ||
54 | arch_sync_dma_for_cpu(paddr, size, dir); | ||
55 | else if (dir != DMA_TO_DEVICE) | ||
56 | - dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL); | ||
57 | + dma_cache_maint(dev, handle, size, GNTTAB_CACHE_INVAL); | ||
58 | } | ||
59 | |||
60 | void xen_dma_sync_for_device(struct device *dev, dma_addr_t handle, | ||
61 | @@ -89,9 +92,9 @@ void xen_dma_sync_for_device(struct device *dev, dma_addr_t handle, | ||
62 | if (pfn_valid(PFN_DOWN(dma_to_phys(dev, handle)))) | ||
63 | arch_sync_dma_for_device(paddr, size, dir); | ||
64 | else if (dir == DMA_FROM_DEVICE) | ||
65 | - dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL); | ||
66 | + dma_cache_maint(dev, handle, size, GNTTAB_CACHE_INVAL); | ||
67 | else | ||
68 | - dma_cache_maint(handle, size, GNTTAB_CACHE_CLEAN); | ||
69 | + dma_cache_maint(dev, handle, size, GNTTAB_CACHE_CLEAN); | ||
70 | } | ||
71 | |||
72 | bool xen_arch_need_swiotlb(struct device *dev, | ||
73 | -- | ||
74 | 2.15.4 | ||
75 | |||
diff --git a/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0011-adding-page-coherent-patch.patch b/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0011-adding-page-coherent-patch.patch new file mode 100644 index 00000000..a84ae742 --- /dev/null +++ b/dynamic-layers/raspberrypi/recipes-kernel/linux/files/0011-adding-page-coherent-patch.patch | |||
@@ -0,0 +1,39 @@ | |||
1 | From 1f1182bf84ec7a6d1ec74c56fccd66ff013077af Mon Sep 17 00:00:00 2001 | ||
2 | From: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
3 | Date: Wed, 20 May 2020 16:43:08 -0700 | ||
4 | Subject: [PATCH 11/11] xen/arm: call dma_to_phys on the dma_addr_t parameter | ||
5 | of dma_cache_maint | ||
6 | |||
7 | Add a struct device* parameter to dma_cache_maint. | ||
8 | |||
9 | Translate the dma_addr_t parameter of dma_cache_maint by calling | ||
10 | dma_to_phys. Do it for the first page and all the following pages, in | ||
11 | case of multipage handling. | ||
12 | |||
13 | Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com> | ||
14 | --- | ||
15 | include/xen/arm/page-coherent.h | 15 +++++++++------ | ||
16 | 1 file changed, 9 insertions(+), 6 deletions(-) | ||
17 | |||
18 | diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c | ||
19 | index 7639251bcc79..6ddf3b3c1ab5 100644 | ||
20 | --- a/include/xen/arm/page-coherent.h 2020-05-20 06:22:38.000000000 +0000 | ||
21 | +++ b/include/xen/arm/page-coherent.h 2020-05-29 00:37:15.604981421 +0000 | ||
22 | @@ -8,12 +8,17 @@ | ||
23 | static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size, | ||
24 | dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs) | ||
25 | { | ||
26 | + void *cpu_addr; | ||
27 | + if (dma_alloc_from_dev_coherent(hwdev, size, dma_handle, &cpu_addr)) | ||
28 | + return cpu_addr; | ||
29 | return dma_direct_alloc(hwdev, size, dma_handle, flags, attrs); | ||
30 | } | ||
31 | |||
32 | static inline void xen_free_coherent_pages(struct device *hwdev, size_t size, | ||
33 | void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs) | ||
34 | { | ||
35 | + if (dma_release_from_dev_coherent(hwdev, get_order(size), cpu_addr)) | ||
36 | + return; | ||
37 | dma_direct_free(hwdev, size, cpu_addr, dma_handle, attrs); | ||
38 | } | ||
39 | |||
diff --git a/dynamic-layers/raspberrypi/recipes-kernel/linux/linux-raspberrypi_%.bbappend b/dynamic-layers/raspberrypi/recipes-kernel/linux/linux-raspberrypi_%.bbappend new file mode 100644 index 00000000..25979e2c --- /dev/null +++ b/dynamic-layers/raspberrypi/recipes-kernel/linux/linux-raspberrypi_%.bbappend | |||
@@ -0,0 +1,5 @@ | |||
1 | # For a Xen-enabled distro, override the contents of cmdline.txt | ||
2 | |||
3 | DEFAULT_CMDLINE := "${CMDLINE}" | ||
4 | XEN_LINUX_CMDLINE ?= "console=hvc0 clk_ignore_unused earlyprintk=xen debug root=/dev/mmcblk0p2 rootwait" | ||
5 | CMDLINE = "${@bb.utils.contains('DISTRO_FEATURES', 'xen', '${XEN_LINUX_CMDLINE}', '${DEFAULT_CMDLINE}', d)}" | ||
diff --git a/dynamic-layers/raspberrypi/recipes-kernel/linux/linux-raspberrypi_5.4.bbappend b/dynamic-layers/raspberrypi/recipes-kernel/linux/linux-raspberrypi_5.4.bbappend new file mode 100644 index 00000000..ec8d677b --- /dev/null +++ b/dynamic-layers/raspberrypi/recipes-kernel/linux/linux-raspberrypi_5.4.bbappend | |||
@@ -0,0 +1,19 @@ | |||
1 | FILESEXTRAPATHS_prepend := "${THISDIR}/files:" | ||
2 | |||
3 | SRC_URI += " \ | ||
4 | file://0001-swiotlb-xen-use-vmalloc_to_page-on-vmalloc-virt-addr.patch \ | ||
5 | file://0002-swiotlb-xen-remove-start_dma_addr.patch \ | ||
6 | file://0003-swiotlb-xen-add-struct-device-parameter-to-xen_phys_.patch \ | ||
7 | file://0004-swiotlb-xen-add-struct-device-parameter-to-xen_bus_t.patch \ | ||
8 | file://0007-swiotlb-xen-add-struct-device-parameter-to-is_xen_sw.patch \ | ||
9 | file://0008-swiotlb-xen-introduce-phys_to_dma-dma_to_phys-transl.patch \ | ||
10 | file://0009-xen-arm-introduce-phys-dma-translations-in-xen_dma_s_kernel_5.4.patch \ | ||
11 | file://0010-xen-arm-call-dma_to_phys-on-the-dma_addr_t-parameter.patch \ | ||
12 | file://0011-adding-page-coherent-patch.patch \ | ||
13 | " | ||
14 | |||
15 | # Add support for virtio.scc which linux-yocto_virtualization adds | ||
16 | SRCREV_meta = "aafb8f095e97013d6e55b09ed150369cbe0c6476" | ||
17 | SRC_URI_append += " \ | ||
18 | git://git.yoctoproject.org/yocto-kernel-cache;type=kmeta;name=meta;branch=yocto-5.4;destsuffix=kernel-meta \ | ||
19 | " | ||