@@ -1532,11 +1532,11 @@ static int set_dma_sg(struct scatterlist *sg, u64 bar_address, u64 chunk_size,
15321532}
15331533
15341534static struct sg_table * alloc_sgt_from_device_pages (struct hl_device * hdev , u64 * pages , u64 npages ,
1535- u64 page_size , u64 exported_size ,
1535+ u64 page_size , u64 exported_size , u64 offset ,
15361536 struct device * dev , enum dma_data_direction dir )
15371537{
15381538 u64 dma_max_seg_size , curr_page , size , chunk_size , left_size_to_export , left_size_in_page ,
1539- left_size_in_dma_seg , device_address , bar_address ;
1539+ left_size_in_dma_seg , device_address , bar_address , start_page ;
15401540 struct asic_fixed_properties * prop = & hdev -> asic_prop ;
15411541 struct scatterlist * sg ;
15421542 unsigned int nents , i ;
@@ -1557,11 +1557,20 @@ static struct sg_table *alloc_sgt_from_device_pages(struct hl_device *hdev, u64
15571557 if (!sgt )
15581558 return ERR_PTR (- ENOMEM );
15591559
1560+ /* Use the offset to move to the actual first page that is exported */
1561+ for (start_page = 0 ; start_page < npages ; ++ start_page ) {
1562+ if (offset < page_size )
1563+ break ;
1564+
1565+ /* The offset value was validated so there can't be an underflow */
1566+ offset -= page_size ;
1567+ }
1568+
15601569 /* Calculate the required number of entries for the SG table */
1561- curr_page = 0 ;
1570+ curr_page = start_page ;
15621571 nents = 1 ;
15631572 left_size_to_export = exported_size ;
1564- left_size_in_page = page_size ;
1573+ left_size_in_page = page_size - offset ;
15651574 left_size_in_dma_seg = dma_max_seg_size ;
15661575 next_sg_entry = false;
15671576
@@ -1599,10 +1608,10 @@ static struct sg_table *alloc_sgt_from_device_pages(struct hl_device *hdev, u64
15991608 goto err_free_sgt ;
16001609
16011610 /* Prepare the SG table entries */
1602- curr_page = 0 ;
1603- device_address = pages [curr_page ];
1611+ curr_page = start_page ;
1612+ device_address = pages [curr_page ] + offset ;
16041613 left_size_to_export = exported_size ;
1605- left_size_in_page = page_size ;
1614+ left_size_in_page = page_size - offset ;
16061615 left_size_in_dma_seg = dma_max_seg_size ;
16071616 next_sg_entry = false;
16081617
@@ -1708,7 +1717,7 @@ static int hl_dmabuf_attach(struct dma_buf *dmabuf,
17081717static struct sg_table * hl_map_dmabuf (struct dma_buf_attachment * attachment ,
17091718 enum dma_data_direction dir )
17101719{
1711- u64 * pages , npages , page_size , exported_size ;
1720+ u64 * pages , npages , page_size , exported_size , offset ;
17121721 struct dma_buf * dma_buf = attachment -> dmabuf ;
17131722 struct hl_vm_phys_pg_pack * phys_pg_pack ;
17141723 struct hl_dmabuf_priv * hl_dmabuf ;
@@ -1724,6 +1733,7 @@ static struct sg_table *hl_map_dmabuf(struct dma_buf_attachment *attachment,
17241733 }
17251734
17261735 exported_size = hl_dmabuf -> dmabuf -> size ;
1736+ offset = hl_dmabuf -> offset ;
17271737 phys_pg_pack = hl_dmabuf -> phys_pg_pack ;
17281738
17291739 if (phys_pg_pack ) {
@@ -1736,7 +1746,7 @@ static struct sg_table *hl_map_dmabuf(struct dma_buf_attachment *attachment,
17361746 page_size = hl_dmabuf -> dmabuf -> size ;
17371747 }
17381748
1739- sgt = alloc_sgt_from_device_pages (hdev , pages , npages , page_size , exported_size ,
1749+ sgt = alloc_sgt_from_device_pages (hdev , pages , npages , page_size , exported_size , offset ,
17401750 attachment -> dev , dir );
17411751 if (IS_ERR (sgt ))
17421752 dev_err (hdev -> dev , "failed (%ld) to initialize sgt for dmabuf\n" , PTR_ERR (sgt ));
@@ -1882,12 +1892,12 @@ static int export_dmabuf(struct hl_ctx *ctx,
18821892 return rc ;
18831893}
18841894
1885- static int validate_export_params_common (struct hl_device * hdev , u64 device_addr , u64 size )
1895+ static int validate_export_params_common (struct hl_device * hdev , u64 addr , u64 size , u64 offset )
18861896{
1887- if (!PAGE_ALIGNED (device_addr )) {
1897+ if (!PAGE_ALIGNED (addr )) {
18881898 dev_dbg (hdev -> dev ,
18891899 "exported device memory address 0x%llx should be aligned to PAGE_SIZE 0x%lx\n" ,
1890- device_addr , PAGE_SIZE );
1900+ addr , PAGE_SIZE );
18911901 return - EINVAL ;
18921902 }
18931903
@@ -1898,6 +1908,13 @@ static int validate_export_params_common(struct hl_device *hdev, u64 device_addr
18981908 return - EINVAL ;
18991909 }
19001910
1911+ if (!PAGE_ALIGNED (offset )) {
1912+ dev_dbg (hdev -> dev ,
1913+ "exported device memory offset %llu should be a multiple of PAGE_SIZE %lu\n" ,
1914+ offset , PAGE_SIZE );
1915+ return - EINVAL ;
1916+ }
1917+
19011918 return 0 ;
19021919}
19031920
@@ -1907,13 +1924,13 @@ static int validate_export_params_no_mmu(struct hl_device *hdev, u64 device_addr
19071924 u64 bar_address ;
19081925 int rc ;
19091926
1910- rc = validate_export_params_common (hdev , device_addr , size );
1927+ rc = validate_export_params_common (hdev , device_addr , size , 0 );
19111928 if (rc )
19121929 return rc ;
19131930
19141931 if (device_addr < prop -> dram_user_base_address ||
1915- (device_addr + size ) > prop -> dram_end_address ||
1916- (device_addr + size ) < device_addr ) {
1932+ (device_addr + size ) > prop -> dram_end_address ||
1933+ (device_addr + size ) < device_addr ) {
19171934 dev_dbg (hdev -> dev ,
19181935 "DRAM memory range 0x%llx (+0x%llx) is outside of DRAM boundaries\n" ,
19191936 device_addr , size );
@@ -1940,36 +1957,26 @@ static int validate_export_params(struct hl_device *hdev, u64 device_addr, u64 s
19401957 u64 bar_address ;
19411958 int i , rc ;
19421959
1943- rc = validate_export_params_common (hdev , device_addr , size );
1960+ rc = validate_export_params_common (hdev , device_addr , size , offset );
19441961 if (rc )
19451962 return rc ;
19461963
1947- if (!PAGE_ALIGNED (offset )) {
1948- dev_dbg (hdev -> dev ,
1949- "exported device memory offset %llu should be a multiple of PAGE_SIZE %lu\n" ,
1950- offset , PAGE_SIZE );
1951- return - EINVAL ;
1952- }
1953-
19541964 if ((offset + size ) > phys_pg_pack -> total_size ) {
19551965 dev_dbg (hdev -> dev , "offset %#llx and size %#llx exceed total map size %#llx\n" ,
1956- offset , size , phys_pg_pack -> total_size );
1966+ offset , size , phys_pg_pack -> total_size );
19571967 return - EINVAL ;
19581968 }
19591969
19601970 for (i = 0 ; i < phys_pg_pack -> npages ; i ++ ) {
1961-
19621971 bar_address = hdev -> dram_pci_bar_start +
1963- (phys_pg_pack -> pages [i ] - prop -> dram_base_address );
1972+ (phys_pg_pack -> pages [i ] - prop -> dram_base_address );
19641973
19651974 if ((bar_address + phys_pg_pack -> page_size ) >
19661975 (hdev -> dram_pci_bar_start + prop -> dram_pci_bar_size ) ||
19671976 (bar_address + phys_pg_pack -> page_size ) < bar_address ) {
19681977 dev_dbg (hdev -> dev ,
19691978 "DRAM memory range 0x%llx (+0x%x) is outside of PCI BAR boundaries\n" ,
1970- phys_pg_pack -> pages [i ],
1971- phys_pg_pack -> page_size );
1972-
1979+ phys_pg_pack -> pages [i ], phys_pg_pack -> page_size );
19731980 return - EINVAL ;
19741981 }
19751982 }
@@ -2025,7 +2032,6 @@ static int export_dmabuf_from_addr(struct hl_ctx *ctx, u64 addr, u64 size, u64 o
20252032 struct asic_fixed_properties * prop ;
20262033 struct hl_dmabuf_priv * hl_dmabuf ;
20272034 struct hl_device * hdev ;
2028- u64 export_addr ;
20292035 int rc ;
20302036
20312037 hdev = ctx -> hdev ;
@@ -2037,8 +2043,6 @@ static int export_dmabuf_from_addr(struct hl_ctx *ctx, u64 addr, u64 size, u64 o
20372043 return - EINVAL ;
20382044 }
20392045
2040- export_addr = addr + offset ;
2041-
20422046 hl_dmabuf = kzalloc (sizeof (* hl_dmabuf ), GFP_KERNEL );
20432047 if (!hl_dmabuf )
20442048 return - ENOMEM ;
@@ -2054,18 +2058,19 @@ static int export_dmabuf_from_addr(struct hl_ctx *ctx, u64 addr, u64 size, u64 o
20542058 rc = PTR_ERR (phys_pg_pack );
20552059 goto dec_memhash_export_cnt ;
20562060 }
2057- rc = validate_export_params (hdev , export_addr , size , offset , phys_pg_pack );
2061+ rc = validate_export_params (hdev , addr , size , offset , phys_pg_pack );
20582062 if (rc )
20592063 goto dec_memhash_export_cnt ;
20602064
20612065 hl_dmabuf -> phys_pg_pack = phys_pg_pack ;
20622066 hl_dmabuf -> memhash_hnode = hnode ;
2067+ hl_dmabuf -> offset = offset ;
20632068 } else {
2064- rc = validate_export_params_no_mmu (hdev , export_addr , size );
2069+ rc = validate_export_params_no_mmu (hdev , addr , size );
20652070 if (rc )
20662071 goto err_free_dmabuf_wrapper ;
20672072
2068- hl_dmabuf -> device_phys_addr = export_addr ;
2073+ hl_dmabuf -> device_phys_addr = addr ;
20692074 }
20702075
20712076 rc = export_dmabuf (ctx , hl_dmabuf , size , flags , dmabuf_fd );
0 commit comments