Skip to content

Commit a10d648

Browse files
rleonmszyprow
authored andcommitted
powerpc: Convert to physical address DMA mapping
Adapt PowerPC DMA to use physical addresses in order to prepare code to removal .map_page and .unmap_page. Signed-off-by: Leon Romanovsky <leonro@nvidia.com> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Link: https://lore.kernel.org/r/20251015-remove-map-page-v5-10-3bbfe3a25cdf@kernel.org
1 parent 96ddf2e commit a10d648

6 files changed

Lines changed: 60 additions & 53 deletions

File tree

arch/powerpc/include/asm/iommu.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -274,12 +274,12 @@ extern void *iommu_alloc_coherent(struct device *dev, struct iommu_table *tbl,
274274
unsigned long mask, gfp_t flag, int node);
275275
extern void iommu_free_coherent(struct iommu_table *tbl, size_t size,
276276
void *vaddr, dma_addr_t dma_handle);
277-
extern dma_addr_t iommu_map_page(struct device *dev, struct iommu_table *tbl,
278-
struct page *page, unsigned long offset,
279-
size_t size, unsigned long mask,
277+
extern dma_addr_t iommu_map_phys(struct device *dev, struct iommu_table *tbl,
278+
phys_addr_t phys, size_t size,
279+
unsigned long mask,
280280
enum dma_data_direction direction,
281281
unsigned long attrs);
282-
extern void iommu_unmap_page(struct iommu_table *tbl, dma_addr_t dma_handle,
282+
extern void iommu_unmap_phys(struct iommu_table *tbl, dma_addr_t dma_handle,
283283
size_t size, enum dma_data_direction direction,
284284
unsigned long attrs);
285285

arch/powerpc/kernel/dma-iommu.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -93,28 +93,26 @@ static void dma_iommu_free_coherent(struct device *dev, size_t size,
9393

9494
/* Creates TCEs for a user provided buffer. The user buffer must be
9595
* contiguous real kernel storage (not vmalloc). The address passed here
96-
* comprises a page address and offset into that page. The dma_addr_t
97-
* returned will point to the same byte within the page as was passed in.
96+
* is a physical address to that page. The dma_addr_t returned will point
97+
* to the same byte within the page as was passed in.
9898
*/
99-
static dma_addr_t dma_iommu_map_page(struct device *dev, struct page *page,
100-
unsigned long offset, size_t size,
99+
static dma_addr_t dma_iommu_map_phys(struct device *dev, phys_addr_t phys,
100+
size_t size,
101101
enum dma_data_direction direction,
102102
unsigned long attrs)
103103
{
104-
return iommu_map_page(dev, get_iommu_table_base(dev), page, offset,
105-
size, dma_get_mask(dev), direction, attrs);
104+
return iommu_map_phys(dev, get_iommu_table_base(dev), phys, size,
105+
dma_get_mask(dev), direction, attrs);
106106
}
107107

108-
109-
static void dma_iommu_unmap_page(struct device *dev, dma_addr_t dma_handle,
108+
static void dma_iommu_unmap_phys(struct device *dev, dma_addr_t dma_handle,
110109
size_t size, enum dma_data_direction direction,
111110
unsigned long attrs)
112111
{
113-
iommu_unmap_page(get_iommu_table_base(dev), dma_handle, size, direction,
112+
iommu_unmap_phys(get_iommu_table_base(dev), dma_handle, size, direction,
114113
attrs);
115114
}
116115

117-
118116
static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist,
119117
int nelems, enum dma_data_direction direction,
120118
unsigned long attrs)
@@ -211,8 +209,8 @@ const struct dma_map_ops dma_iommu_ops = {
211209
.map_sg = dma_iommu_map_sg,
212210
.unmap_sg = dma_iommu_unmap_sg,
213211
.dma_supported = dma_iommu_dma_supported,
214-
.map_page = dma_iommu_map_page,
215-
.unmap_page = dma_iommu_unmap_page,
212+
.map_phys = dma_iommu_map_phys,
213+
.unmap_phys = dma_iommu_unmap_phys,
216214
.get_required_mask = dma_iommu_get_required_mask,
217215
.mmap = dma_common_mmap,
218216
.get_sgtable = dma_common_get_sgtable,

arch/powerpc/kernel/iommu.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -848,12 +848,12 @@ EXPORT_SYMBOL_GPL(iommu_tce_table_put);
848848

849849
/* Creates TCEs for a user provided buffer. The user buffer must be
850850
* contiguous real kernel storage (not vmalloc). The address passed here
851-
* comprises a page address and offset into that page. The dma_addr_t
852-
* returned will point to the same byte within the page as was passed in.
851+
* is physical address into that page. The dma_addr_t returned will point
852+
* to the same byte within the page as was passed in.
853853
*/
854-
dma_addr_t iommu_map_page(struct device *dev, struct iommu_table *tbl,
855-
struct page *page, unsigned long offset, size_t size,
856-
unsigned long mask, enum dma_data_direction direction,
854+
dma_addr_t iommu_map_phys(struct device *dev, struct iommu_table *tbl,
855+
phys_addr_t phys, size_t size, unsigned long mask,
856+
enum dma_data_direction direction,
857857
unsigned long attrs)
858858
{
859859
dma_addr_t dma_handle = DMA_MAPPING_ERROR;
@@ -863,7 +863,7 @@ dma_addr_t iommu_map_page(struct device *dev, struct iommu_table *tbl,
863863

864864
BUG_ON(direction == DMA_NONE);
865865

866-
vaddr = page_address(page) + offset;
866+
vaddr = phys_to_virt(phys);
867867
uaddr = (unsigned long)vaddr;
868868

869869
if (tbl) {
@@ -890,7 +890,7 @@ dma_addr_t iommu_map_page(struct device *dev, struct iommu_table *tbl,
890890
return dma_handle;
891891
}
892892

893-
void iommu_unmap_page(struct iommu_table *tbl, dma_addr_t dma_handle,
893+
void iommu_unmap_phys(struct iommu_table *tbl, dma_addr_t dma_handle,
894894
size_t size, enum dma_data_direction direction,
895895
unsigned long attrs)
896896
{

arch/powerpc/platforms/ps3/system-bus.c

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -551,18 +551,20 @@ static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr,
551551

552552
/* Creates TCEs for a user provided buffer. The user buffer must be
553553
* contiguous real kernel storage (not vmalloc). The address passed here
554-
* comprises a page address and offset into that page. The dma_addr_t
555-
* returned will point to the same byte within the page as was passed in.
554+
* is physical address to that hat page. The dma_addr_t returned will point
555+
* to the same byte within the page as was passed in.
556556
*/
557557

558-
static dma_addr_t ps3_sb_map_page(struct device *_dev, struct page *page,
559-
unsigned long offset, size_t size, enum dma_data_direction direction,
560-
unsigned long attrs)
558+
static dma_addr_t ps3_sb_map_phys(struct device *_dev, phys_addr_t phys,
559+
size_t size, enum dma_data_direction direction, unsigned long attrs)
561560
{
562561
struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
563562
int result;
564563
dma_addr_t bus_addr;
565-
void *ptr = page_address(page) + offset;
564+
void *ptr = phys_to_virt(phys);
565+
566+
if (unlikely(attrs & DMA_ATTR_MMIO))
567+
return DMA_MAPPING_ERROR;
566568

567569
result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
568570
&bus_addr,
@@ -577,16 +579,19 @@ static dma_addr_t ps3_sb_map_page(struct device *_dev, struct page *page,
577579
return bus_addr;
578580
}
579581

580-
static dma_addr_t ps3_ioc0_map_page(struct device *_dev, struct page *page,
581-
unsigned long offset, size_t size,
582+
static dma_addr_t ps3_ioc0_map_phys(struct device *_dev, phys_addr_t phys,
583+
size_t size,
582584
enum dma_data_direction direction,
583585
unsigned long attrs)
584586
{
585587
struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
586588
int result;
587589
dma_addr_t bus_addr;
588590
u64 iopte_flag;
589-
void *ptr = page_address(page) + offset;
591+
void *ptr = phys_to_virt(phys);
592+
593+
if (unlikely(attrs & DMA_ATTR_MMIO))
594+
return DMA_MAPPING_ERROR;
590595

591596
iopte_flag = CBE_IOPTE_M;
592597
switch (direction) {
@@ -613,7 +618,7 @@ static dma_addr_t ps3_ioc0_map_page(struct device *_dev, struct page *page,
613618
return bus_addr;
614619
}
615620

616-
static void ps3_unmap_page(struct device *_dev, dma_addr_t dma_addr,
621+
static void ps3_unmap_phys(struct device *_dev, dma_addr_t dma_addr,
617622
size_t size, enum dma_data_direction direction, unsigned long attrs)
618623
{
619624
struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
@@ -690,8 +695,8 @@ static const struct dma_map_ops ps3_sb_dma_ops = {
690695
.map_sg = ps3_sb_map_sg,
691696
.unmap_sg = ps3_sb_unmap_sg,
692697
.dma_supported = ps3_dma_supported,
693-
.map_page = ps3_sb_map_page,
694-
.unmap_page = ps3_unmap_page,
698+
.map_phys = ps3_sb_map_phys,
699+
.unmap_phys = ps3_unmap_phys,
695700
.mmap = dma_common_mmap,
696701
.get_sgtable = dma_common_get_sgtable,
697702
.alloc_pages_op = dma_common_alloc_pages,
@@ -704,8 +709,8 @@ static const struct dma_map_ops ps3_ioc0_dma_ops = {
704709
.map_sg = ps3_ioc0_map_sg,
705710
.unmap_sg = ps3_ioc0_unmap_sg,
706711
.dma_supported = ps3_dma_supported,
707-
.map_page = ps3_ioc0_map_page,
708-
.unmap_page = ps3_unmap_page,
712+
.map_phys = ps3_ioc0_map_phys,
713+
.unmap_phys = ps3_unmap_phys,
709714
.mmap = dma_common_mmap,
710715
.get_sgtable = dma_common_get_sgtable,
711716
.alloc_pages_op = dma_common_alloc_pages,

arch/powerpc/platforms/pseries/ibmebus.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,17 +86,18 @@ static void ibmebus_free_coherent(struct device *dev,
8686
kfree(vaddr);
8787
}
8888

89-
static dma_addr_t ibmebus_map_page(struct device *dev,
90-
struct page *page,
91-
unsigned long offset,
89+
static dma_addr_t ibmebus_map_phys(struct device *dev, phys_addr_t phys,
9290
size_t size,
9391
enum dma_data_direction direction,
9492
unsigned long attrs)
9593
{
96-
return (dma_addr_t)(page_address(page) + offset);
94+
if (attrs & DMA_ATTR_MMIO)
95+
return DMA_MAPPING_ERROR;
96+
97+
return (dma_addr_t)(phys_to_virt(phys));
9798
}
9899

99-
static void ibmebus_unmap_page(struct device *dev,
100+
static void ibmebus_unmap_phys(struct device *dev,
100101
dma_addr_t dma_addr,
101102
size_t size,
102103
enum dma_data_direction direction,
@@ -146,8 +147,8 @@ static const struct dma_map_ops ibmebus_dma_ops = {
146147
.unmap_sg = ibmebus_unmap_sg,
147148
.dma_supported = ibmebus_dma_supported,
148149
.get_required_mask = ibmebus_dma_get_required_mask,
149-
.map_page = ibmebus_map_page,
150-
.unmap_page = ibmebus_unmap_page,
150+
.map_phys = ibmebus_map_phys,
151+
.unmap_phys = ibmebus_unmap_phys,
151152
};
152153

153154
static int ibmebus_match_path(struct device *dev, const void *data)

arch/powerpc/platforms/pseries/vio.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -512,18 +512,21 @@ static void vio_dma_iommu_free_coherent(struct device *dev, size_t size,
512512
vio_cmo_dealloc(viodev, roundup(size, PAGE_SIZE));
513513
}
514514

515-
static dma_addr_t vio_dma_iommu_map_page(struct device *dev, struct page *page,
516-
unsigned long offset, size_t size,
517-
enum dma_data_direction direction,
518-
unsigned long attrs)
515+
static dma_addr_t vio_dma_iommu_map_phys(struct device *dev, phys_addr_t phys,
516+
size_t size,
517+
enum dma_data_direction direction,
518+
unsigned long attrs)
519519
{
520520
struct vio_dev *viodev = to_vio_dev(dev);
521521
struct iommu_table *tbl = get_iommu_table_base(dev);
522522
dma_addr_t ret = DMA_MAPPING_ERROR;
523523

524+
if (unlikely(attrs & DMA_ATTR_MMIO))
525+
return ret;
526+
524527
if (vio_cmo_alloc(viodev, roundup(size, IOMMU_PAGE_SIZE(tbl))))
525528
goto out_fail;
526-
ret = iommu_map_page(dev, tbl, page, offset, size, dma_get_mask(dev),
529+
ret = iommu_map_phys(dev, tbl, phys, size, dma_get_mask(dev),
527530
direction, attrs);
528531
if (unlikely(ret == DMA_MAPPING_ERROR))
529532
goto out_deallocate;
@@ -536,15 +539,15 @@ static dma_addr_t vio_dma_iommu_map_page(struct device *dev, struct page *page,
536539
return DMA_MAPPING_ERROR;
537540
}
538541

539-
static void vio_dma_iommu_unmap_page(struct device *dev, dma_addr_t dma_handle,
542+
static void vio_dma_iommu_unmap_phys(struct device *dev, dma_addr_t dma_handle,
540543
size_t size,
541544
enum dma_data_direction direction,
542545
unsigned long attrs)
543546
{
544547
struct vio_dev *viodev = to_vio_dev(dev);
545548
struct iommu_table *tbl = get_iommu_table_base(dev);
546549

547-
iommu_unmap_page(tbl, dma_handle, size, direction, attrs);
550+
iommu_unmap_phys(tbl, dma_handle, size, direction, attrs);
548551
vio_cmo_dealloc(viodev, roundup(size, IOMMU_PAGE_SIZE(tbl)));
549552
}
550553

@@ -605,8 +608,8 @@ static const struct dma_map_ops vio_dma_mapping_ops = {
605608
.free = vio_dma_iommu_free_coherent,
606609
.map_sg = vio_dma_iommu_map_sg,
607610
.unmap_sg = vio_dma_iommu_unmap_sg,
608-
.map_page = vio_dma_iommu_map_page,
609-
.unmap_page = vio_dma_iommu_unmap_page,
611+
.map_phys = vio_dma_iommu_map_phys,
612+
.unmap_phys = vio_dma_iommu_unmap_phys,
610613
.dma_supported = dma_iommu_dma_supported,
611614
.get_required_mask = dma_iommu_get_required_mask,
612615
.mmap = dma_common_mmap,

0 commit comments

Comments
 (0)