Re: [PATCH 01/19] dma-buf-map: Add read/write helpers

2022-01-28 Thread Thomas Zimmermann

Hi

Am 27.01.22 um 17:34 schrieb Lucas De Marchi:

On Thu, Jan 27, 2022 at 03:26:43PM +0100, Thomas Zimmermann wrote:

Hi

Am 26.01.22 um 21:36 schrieb Lucas De Marchi:

In certain situations it's useful to be able to read or write to an
offset that is calculated by having the memory layout given by a struct
declaration. Usually we are going to read/write a u8, u16, u32 or u64.

Add a pair of macros dma_buf_map_read_field()/dma_buf_map_write_field()
to calculate the offset of a struct member and memcpy the data from/to
the dma_buf_map. We could use readb, readw, readl, readq and the write*
counterparts, however due to alignment issues this may not work on all
architectures. If alignment needs to be checked to call the right
function, it's not possible to decide at compile-time which function to
call: so just leave the decision to the memcpy function that will do
exactly that on IO memory or dereference the pointer.

Cc: Sumit Semwal 
Cc: Christian König 
Cc: linux-me...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: linaro-mm-...@lists.linaro.org
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Lucas De Marchi 
---
 include/linux/dma-buf-map.h | 81 +
 1 file changed, 81 insertions(+)

diff --git a/include/linux/dma-buf-map.h b/include/linux/dma-buf-map.h
index 19fa0b5ae5ec..65e927d9ce33 100644
--- a/include/linux/dma-buf-map.h
+++ b/include/linux/dma-buf-map.h
@@ -6,6 +6,7 @@
 #ifndef __DMA_BUF_MAP_H__
 #define __DMA_BUF_MAP_H__
+#include 
 #include 
 #include 
@@ -229,6 +230,46 @@ static inline void dma_buf_map_clear(struct 
dma_buf_map *map)

 }
 }
+/**
+ * dma_buf_map_memcpy_to_offset - Memcpy into offset of dma-buf mapping
+ * @dst:    The dma-buf mapping structure
+ * @offset:    The offset from which to copy
+ * @src:    The source buffer
+ * @len:    The number of byte in src
+ *
+ * Copies data into a dma-buf mapping with an offset. The source 
buffer is in
+ * system memory. Depending on the buffer's location, the helper 
picks the

+ * correct method of accessing the memory.
+ */
+static inline void dma_buf_map_memcpy_to_offset(struct dma_buf_map 
*dst, size_t offset,

+    const void *src, size_t len)
+{
+    if (dst->is_iomem)
+    memcpy_toio(dst->vaddr_iomem + offset, src, len);
+    else
+    memcpy(dst->vaddr + offset, src, len);
+}


Please don't add a new function. Rather please add the offset 
parameter to dma_buf_map_memcpy_to() and update the callers. There are 
only two calls to dma_buf_map_memcpy_to() within the kernel. To make 
it clear what the offset applies to, I'd call the parameter 'dst_offset'.



+
+/**
+ * dma_buf_map_memcpy_from_offset - Memcpy from offset of dma-buf 
mapping into system memory

+ * @dst:    Destination in system memory
+ * @src:    The dma-buf mapping structure
+ * @src:    The offset from which to copy
+ * @len:    The number of byte in src
+ *
+ * Copies data from a dma-buf mapping with an offset. The dest 
buffer is in
+ * system memory. Depending on the mapping location, the helper 
picks the

+ * correct method of accessing the memory.
+ */
+static inline void dma_buf_map_memcpy_from_offset(void *dst, const 
struct dma_buf_map *src,

+  size_t offset, size_t len)
+{
+    if (src->is_iomem)
+    memcpy_fromio(dst, src->vaddr_iomem + offset, len);
+    else
+    memcpy(dst, src->vaddr + offset, len);
+}
+


With the dma_buf_map_memcpy_to() changes, please just call this 
function dma_buf_map_memcpy_from().



 /**
  * dma_buf_map_memcpy_to - Memcpy into dma-buf mapping
  * @dst:    The dma-buf mapping structure
@@ -263,4 +304,44 @@ static inline void dma_buf_map_incr(struct 
dma_buf_map *map, size_t incr)

 map->vaddr += incr;
 }
+/**
+ * dma_buf_map_read_field - Read struct member from dma-buf mapping 
with

+ * arbitrary size and handling un-aligned accesses
+ *
+ * @map__:    The dma-buf mapping structure
+ * @type__:    The struct to be used containing the field to read
+ * @field__:    Member from struct we want to read
+ *
+ * Read a value from dma-buf mapping calculating the offset and 
size: this assumes
+ * the dma-buf mapping is aligned with a a struct type__. A single 
u8, u16, u32

+ * or u64 can be read, based on the offset and size of type__.field__.
+ */
+#define dma_buf_map_read_field(map__, type__, field__) 
({    \

+    type__ *t__;    \
+    typeof(t__->field__) val__;    \
+    dma_buf_map_memcpy_from_offset(&val__, map__, offsetof(type__, 
field__),    \

+   sizeof(t__->field__));    \
+    val__;    \
+})
+
+/**
+ * dma_buf_map_write_field - Write struct member to the dma-buf 
mapping with

+ * arbitrary size and handling un-aligned accesses
+ *
+ * @map__:    The dma-buf mapping structure
+ * @type__:    The struct to be used containing the field to write
+ * @field__:    Member f

Re: [PATCH 01/19] dma-buf-map: Add read/write helpers

2022-01-27 Thread Lucas De Marchi

On Thu, Jan 27, 2022 at 03:26:43PM +0100, Thomas Zimmermann wrote:

Hi

Am 26.01.22 um 21:36 schrieb Lucas De Marchi:

In certain situations it's useful to be able to read or write to an
offset that is calculated by having the memory layout given by a struct
declaration. Usually we are going to read/write a u8, u16, u32 or u64.

Add a pair of macros dma_buf_map_read_field()/dma_buf_map_write_field()
to calculate the offset of a struct member and memcpy the data from/to
the dma_buf_map. We could use readb, readw, readl, readq and the write*
counterparts, however due to alignment issues this may not work on all
architectures. If alignment needs to be checked to call the right
function, it's not possible to decide at compile-time which function to
call: so just leave the decision to the memcpy function that will do
exactly that on IO memory or dereference the pointer.

Cc: Sumit Semwal 
Cc: Christian König 
Cc: linux-me...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: linaro-mm-...@lists.linaro.org
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Lucas De Marchi 
---
 include/linux/dma-buf-map.h | 81 +
 1 file changed, 81 insertions(+)

diff --git a/include/linux/dma-buf-map.h b/include/linux/dma-buf-map.h
index 19fa0b5ae5ec..65e927d9ce33 100644
--- a/include/linux/dma-buf-map.h
+++ b/include/linux/dma-buf-map.h
@@ -6,6 +6,7 @@
 #ifndef __DMA_BUF_MAP_H__
 #define __DMA_BUF_MAP_H__
+#include 
 #include 
 #include 
@@ -229,6 +230,46 @@ static inline void dma_buf_map_clear(struct dma_buf_map 
*map)
}
 }
+/**
+ * dma_buf_map_memcpy_to_offset - Memcpy into offset of dma-buf mapping
+ * @dst:   The dma-buf mapping structure
+ * @offset:The offset from which to copy
+ * @src:   The source buffer
+ * @len:   The number of byte in src
+ *
+ * Copies data into a dma-buf mapping with an offset. The source buffer is in
+ * system memory. Depending on the buffer's location, the helper picks the
+ * correct method of accessing the memory.
+ */
+static inline void dma_buf_map_memcpy_to_offset(struct dma_buf_map *dst, 
size_t offset,
+   const void *src, size_t len)
+{
+   if (dst->is_iomem)
+   memcpy_toio(dst->vaddr_iomem + offset, src, len);
+   else
+   memcpy(dst->vaddr + offset, src, len);
+}


Please don't add a new function. Rather please add the offset 
parameter to dma_buf_map_memcpy_to() and update the callers. There are 
only two calls to dma_buf_map_memcpy_to() within the kernel. To make 
it clear what the offset applies to, I'd call the parameter 
'dst_offset'.



+
+/**
+ * dma_buf_map_memcpy_from_offset - Memcpy from offset of dma-buf mapping into 
system memory
+ * @dst:   Destination in system memory
+ * @src:   The dma-buf mapping structure
+ * @src:   The offset from which to copy
+ * @len:   The number of byte in src
+ *
+ * Copies data from a dma-buf mapping with an offset. The dest buffer is in
+ * system memory. Depending on the mapping location, the helper picks the
+ * correct method of accessing the memory.
+ */
+static inline void dma_buf_map_memcpy_from_offset(void *dst, const struct 
dma_buf_map *src,
+ size_t offset, size_t len)
+{
+   if (src->is_iomem)
+   memcpy_fromio(dst, src->vaddr_iomem + offset, len);
+   else
+   memcpy(dst, src->vaddr + offset, len);
+}
+


With the dma_buf_map_memcpy_to() changes, please just call this 
function dma_buf_map_memcpy_from().



 /**
  * dma_buf_map_memcpy_to - Memcpy into dma-buf mapping
  * @dst:   The dma-buf mapping structure
@@ -263,4 +304,44 @@ static inline void dma_buf_map_incr(struct dma_buf_map 
*map, size_t incr)
map->vaddr += incr;
 }
+/**
+ * dma_buf_map_read_field - Read struct member from dma-buf mapping with
+ * arbitrary size and handling un-aligned accesses
+ *
+ * @map__: The dma-buf mapping structure
+ * @type__:The struct to be used containing the field to read
+ * @field__:   Member from struct we want to read
+ *
+ * Read a value from dma-buf mapping calculating the offset and size: this 
assumes
+ * the dma-buf mapping is aligned with a a struct type__. A single u8, u16, u32
+ * or u64 can be read, based on the offset and size of type__.field__.
+ */
+#define dma_buf_map_read_field(map__, type__, field__) ({  
\
+   type__ *t__;
\
+   typeof(t__->field__) val__; 
 \
+   dma_buf_map_memcpy_from_offset(&val__, map__, offsetof(type__, 
field__),\
+  sizeof(t__->field__));   
 \
+   val__;  
\
+})
+
+/**
+ * dma_buf_map_write_field - Write struct member to the dma-buf mapping

Re: [PATCH 01/19] dma-buf-map: Add read/write helpers

2022-01-27 Thread Thomas Zimmermann

Hi

Am 26.01.22 um 21:36 schrieb Lucas De Marchi:

In certain situations it's useful to be able to read or write to an
offset that is calculated by having the memory layout given by a struct
declaration. Usually we are going to read/write a u8, u16, u32 or u64.

Add a pair of macros dma_buf_map_read_field()/dma_buf_map_write_field()
to calculate the offset of a struct member and memcpy the data from/to
the dma_buf_map. We could use readb, readw, readl, readq and the write*
counterparts, however due to alignment issues this may not work on all
architectures. If alignment needs to be checked to call the right
function, it's not possible to decide at compile-time which function to
call: so just leave the decision to the memcpy function that will do
exactly that on IO memory or dereference the pointer.

Cc: Sumit Semwal 
Cc: Christian König 
Cc: linux-me...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: linaro-mm-...@lists.linaro.org
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Lucas De Marchi 
---
  include/linux/dma-buf-map.h | 81 +
  1 file changed, 81 insertions(+)

diff --git a/include/linux/dma-buf-map.h b/include/linux/dma-buf-map.h
index 19fa0b5ae5ec..65e927d9ce33 100644
--- a/include/linux/dma-buf-map.h
+++ b/include/linux/dma-buf-map.h
@@ -6,6 +6,7 @@
  #ifndef __DMA_BUF_MAP_H__
  #define __DMA_BUF_MAP_H__
  
+#include 

  #include 
  #include 
  
@@ -229,6 +230,46 @@ static inline void dma_buf_map_clear(struct dma_buf_map *map)

}
  }
  
+/**

+ * dma_buf_map_memcpy_to_offset - Memcpy into offset of dma-buf mapping
+ * @dst:   The dma-buf mapping structure
+ * @offset:The offset from which to copy
+ * @src:   The source buffer
+ * @len:   The number of byte in src
+ *
+ * Copies data into a dma-buf mapping with an offset. The source buffer is in
+ * system memory. Depending on the buffer's location, the helper picks the
+ * correct method of accessing the memory.
+ */
+static inline void dma_buf_map_memcpy_to_offset(struct dma_buf_map *dst, 
size_t offset,
+   const void *src, size_t len)
+{
+   if (dst->is_iomem)
+   memcpy_toio(dst->vaddr_iomem + offset, src, len);
+   else
+   memcpy(dst->vaddr + offset, src, len);
+}


Please don't add a new function. Rather please add the offset parameter 
to dma_buf_map_memcpy_to() and update the callers. There are only two 
calls to dma_buf_map_memcpy_to() within the kernel. To make it clear 
what the offset applies to, I'd call the parameter 'dst_offset'.



+
+/**
+ * dma_buf_map_memcpy_from_offset - Memcpy from offset of dma-buf mapping into 
system memory
+ * @dst:   Destination in system memory
+ * @src:   The dma-buf mapping structure
+ * @src:   The offset from which to copy
+ * @len:   The number of byte in src
+ *
+ * Copies data from a dma-buf mapping with an offset. The dest buffer is in
+ * system memory. Depending on the mapping location, the helper picks the
+ * correct method of accessing the memory.
+ */
+static inline void dma_buf_map_memcpy_from_offset(void *dst, const struct 
dma_buf_map *src,
+ size_t offset, size_t len)
+{
+   if (src->is_iomem)
+   memcpy_fromio(dst, src->vaddr_iomem + offset, len);
+   else
+   memcpy(dst, src->vaddr + offset, len);
+}
+


With the dma_buf_map_memcpy_to() changes, please just call this function 
dma_buf_map_memcpy_from().



  /**
   * dma_buf_map_memcpy_to - Memcpy into dma-buf mapping
   * @dst:  The dma-buf mapping structure
@@ -263,4 +304,44 @@ static inline void dma_buf_map_incr(struct dma_buf_map 
*map, size_t incr)
map->vaddr += incr;
  }
  
+/**

+ * dma_buf_map_read_field - Read struct member from dma-buf mapping with
+ * arbitrary size and handling un-aligned accesses
+ *
+ * @map__: The dma-buf mapping structure
+ * @type__:The struct to be used containing the field to read
+ * @field__:   Member from struct we want to read
+ *
+ * Read a value from dma-buf mapping calculating the offset and size: this 
assumes
+ * the dma-buf mapping is aligned with a a struct type__. A single u8, u16, u32
+ * or u64 can be read, based on the offset and size of type__.field__.
+ */
+#define dma_buf_map_read_field(map__, type__, field__) ({  
\
+   type__ *t__;
\
+   typeof(t__->field__) val__; 
 \
+   dma_buf_map_memcpy_from_offset(&val__, map__, offsetof(type__, 
field__),\
+  sizeof(t__->field__));   
 \
+   val__;  
\
+})
+
+/**
+ * dma_buf_map_write_field - Write struct member to the dma-buf mapping with
+ * arbitrary size and handling un-ali

Re: [PATCH 01/19] dma-buf-map: Add read/write helpers

2022-01-26 Thread Christian König

Am 27.01.22 um 08:36 schrieb Matthew Brost:

[SNIP]

   /**
* dma_buf_map_memcpy_to - Memcpy into dma-buf mapping
* @dst: The dma-buf mapping structure
@@ -263,4 +304,44 @@ static inline void dma_buf_map_incr(struct dma_buf_map 
*map, size_t incr)
map->vaddr += incr;
   }
+/**
+ * dma_buf_map_read_field - Read struct member from dma-buf mapping with
+ * arbitrary size and handling un-aligned accesses
+ *
+ * @map__: The dma-buf mapping structure
+ * @type__:The struct to be used containing the field to read
+ * @field__:   Member from struct we want to read
+ *
+ * Read a value from dma-buf mapping calculating the offset and size: this 
assumes
+ * the dma-buf mapping is aligned with a a struct type__. A single u8, u16, u32
+ * or u64 can be read, based on the offset and size of type__.field__.
+ */
+#define dma_buf_map_read_field(map__, type__, field__) ({  
\
+   type__ *t__;
\
+   typeof(t__->field__) val__; 
 \
+   dma_buf_map_memcpy_from_offset(&val__, map__, offsetof(type__, 
field__),\
+  sizeof(t__->field__));   
 \
+   val__;  
\
+})
+
+/**
+ * dma_buf_map_write_field - Write struct member to the dma-buf mapping with
+ * arbitrary size and handling un-aligned accesses
+ *
+ * @map__: The dma-buf mapping structure
+ * @type__:The struct to be used containing the field to write
+ * @field__:   Member from struct we want to write
+ * @val__: Value to be written
+ *
+ * Write a value to the dma-buf mapping calculating the offset and size.
+ * A single u8, u16, u32 or u64 can be written based on the offset and size of
+ * type__.field__.
+ */
+#define dma_buf_map_write_field(map__, type__, field__, val__) ({  
\
+   type__ *t__;
\
+   typeof(t__->field__) val = val__;   
 \
+   dma_buf_map_memcpy_to_offset(map__, offsetof(type__, field__),  
\
+&val, sizeof(t__->field__));   
 \
+})
+

Uff well that absolutely looks like overkill to me.


Hold on...


That's a rather special use case as far as I can see and I think we should
only have this in the common framework if more than one driver is using it.


I disagree, this is rather elegant.

The i915 can't be the *only* driver that defines a struct which
describes the layout of a dma_buf object.


That's not the problem, amdgpu as well as nouveau are doing that as 
well. The problem is DMA-buf is a buffer sharing framework between drivers.


In other words which importer is supposed to use this with a DMA-buf 
exported by another device?



IMO this base macro allows *all* other drivers to build on this write
directly to fields in structures those drivers have defined.


Exactly that's the point. This is something drivers should absolutely 
*NOT* do.


That are driver internals and it is extremely questionable to move this 
into the common framework.


Regards,
Christian.


  Patches
later in this series do this for the GuC ads.

Matt
  

Regards,
Christian.


   #endif /* __DMA_BUF_MAP_H__ */




Re: [PATCH 01/19] dma-buf-map: Add read/write helpers

2022-01-26 Thread Matthew Brost
On Thu, Jan 27, 2022 at 08:24:04AM +0100, Christian König wrote:
> Am 26.01.22 um 21:36 schrieb Lucas De Marchi:
> > In certain situations it's useful to be able to read or write to an
> > offset that is calculated by having the memory layout given by a struct
> > declaration. Usually we are going to read/write a u8, u16, u32 or u64.
> > 
> > Add a pair of macros dma_buf_map_read_field()/dma_buf_map_write_field()
> > to calculate the offset of a struct member and memcpy the data from/to
> > the dma_buf_map. We could use readb, readw, readl, readq and the write*
> > counterparts, however due to alignment issues this may not work on all
> > architectures. If alignment needs to be checked to call the right
> > function, it's not possible to decide at compile-time which function to
> > call: so just leave the decision to the memcpy function that will do
> > exactly that on IO memory or dereference the pointer.
> > 
> > Cc: Sumit Semwal 
> > Cc: Christian König 
> > Cc: linux-me...@vger.kernel.org
> > Cc: dri-devel@lists.freedesktop.org
> > Cc: linaro-mm-...@lists.linaro.org
> > Cc: linux-ker...@vger.kernel.org
> > Signed-off-by: Lucas De Marchi 
> > ---
> >   include/linux/dma-buf-map.h | 81 +
> >   1 file changed, 81 insertions(+)
> > 
> > diff --git a/include/linux/dma-buf-map.h b/include/linux/dma-buf-map.h
> > index 19fa0b5ae5ec..65e927d9ce33 100644
> > --- a/include/linux/dma-buf-map.h
> > +++ b/include/linux/dma-buf-map.h
> > @@ -6,6 +6,7 @@
> >   #ifndef __DMA_BUF_MAP_H__
> >   #define __DMA_BUF_MAP_H__
> > +#include 
> >   #include 
> >   #include 
> > @@ -229,6 +230,46 @@ static inline void dma_buf_map_clear(struct 
> > dma_buf_map *map)
> > }
> >   }
> > +/**
> > + * dma_buf_map_memcpy_to_offset - Memcpy into offset of dma-buf mapping
> > + * @dst:   The dma-buf mapping structure
> > + * @offset:The offset from which to copy
> > + * @src:   The source buffer
> > + * @len:   The number of byte in src
> > + *
> > + * Copies data into a dma-buf mapping with an offset. The source buffer is 
> > in
> > + * system memory. Depending on the buffer's location, the helper picks the
> > + * correct method of accessing the memory.
> > + */
> > +static inline void dma_buf_map_memcpy_to_offset(struct dma_buf_map *dst, 
> > size_t offset,
> > +   const void *src, size_t len)
> > +{
> > +   if (dst->is_iomem)
> > +   memcpy_toio(dst->vaddr_iomem + offset, src, len);
> > +   else
> > +   memcpy(dst->vaddr + offset, src, len);
> > +}
> > +
> > +/**
> > + * dma_buf_map_memcpy_from_offset - Memcpy from offset of dma-buf mapping 
> > into system memory
> > + * @dst:   Destination in system memory
> > + * @src:   The dma-buf mapping structure
> > + * @src:   The offset from which to copy
> > + * @len:   The number of byte in src
> > + *
> > + * Copies data from a dma-buf mapping with an offset. The dest buffer is in
> > + * system memory. Depending on the mapping location, the helper picks the
> > + * correct method of accessing the memory.
> > + */
> > +static inline void dma_buf_map_memcpy_from_offset(void *dst, const struct 
> > dma_buf_map *src,
> > + size_t offset, size_t len)
> > +{
> > +   if (src->is_iomem)
> > +   memcpy_fromio(dst, src->vaddr_iomem + offset, len);
> > +   else
> > +   memcpy(dst, src->vaddr + offset, len);
> > +}
> > +
> 
> Well that's certainly a valid use case, but I suggest to change the
> implementation of the existing functions to call the new ones with offset=0.
> 
> This way we only have one implementation.
> 
Trivial - but agree with Christian that is a good cleanup.

> >   /**
> >* dma_buf_map_memcpy_to - Memcpy into dma-buf mapping
> >* @dst:  The dma-buf mapping structure
> > @@ -263,4 +304,44 @@ static inline void dma_buf_map_incr(struct dma_buf_map 
> > *map, size_t incr)
> > map->vaddr += incr;
> >   }
> > +/**
> > + * dma_buf_map_read_field - Read struct member from dma-buf mapping with
> > + * arbitrary size and handling un-aligned accesses
> > + *
> > + * @map__: The dma-buf mapping structure
> > + * @type__:The struct to be used containing the field to read
> > + * @field__:   Member from struct we want to read
> > + *
> > + * Read a value from dma-buf mapping calculating the offset and size: this 
> > assumes
> > + * the dma-buf mapping is aligned with a a struct type__. A single u8, 
> > u16, u32
> > + * or u64 can be read, based on the offset and size of type__.field__.
> > + */
> > +#define dma_buf_map_read_field(map__, type__, field__) ({  
> > \
> > +   type__ *t__;
> > \
> > +   typeof(t__->field__) val__; 
> > \
> > +   dma_buf_map_memcpy_from_offset(&val__, map__, offsetof(type__, 
> > field__),\
> > +  

Re: [PATCH 01/19] dma-buf-map: Add read/write helpers

2022-01-26 Thread Christian König

Am 26.01.22 um 21:36 schrieb Lucas De Marchi:

In certain situations it's useful to be able to read or write to an
offset that is calculated by having the memory layout given by a struct
declaration. Usually we are going to read/write a u8, u16, u32 or u64.

Add a pair of macros dma_buf_map_read_field()/dma_buf_map_write_field()
to calculate the offset of a struct member and memcpy the data from/to
the dma_buf_map. We could use readb, readw, readl, readq and the write*
counterparts, however due to alignment issues this may not work on all
architectures. If alignment needs to be checked to call the right
function, it's not possible to decide at compile-time which function to
call: so just leave the decision to the memcpy function that will do
exactly that on IO memory or dereference the pointer.

Cc: Sumit Semwal 
Cc: Christian König 
Cc: linux-me...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: linaro-mm-...@lists.linaro.org
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Lucas De Marchi 
---
  include/linux/dma-buf-map.h | 81 +
  1 file changed, 81 insertions(+)

diff --git a/include/linux/dma-buf-map.h b/include/linux/dma-buf-map.h
index 19fa0b5ae5ec..65e927d9ce33 100644
--- a/include/linux/dma-buf-map.h
+++ b/include/linux/dma-buf-map.h
@@ -6,6 +6,7 @@
  #ifndef __DMA_BUF_MAP_H__
  #define __DMA_BUF_MAP_H__
  
+#include 

  #include 
  #include 
  
@@ -229,6 +230,46 @@ static inline void dma_buf_map_clear(struct dma_buf_map *map)

}
  }
  
+/**

+ * dma_buf_map_memcpy_to_offset - Memcpy into offset of dma-buf mapping
+ * @dst:   The dma-buf mapping structure
+ * @offset:The offset from which to copy
+ * @src:   The source buffer
+ * @len:   The number of byte in src
+ *
+ * Copies data into a dma-buf mapping with an offset. The source buffer is in
+ * system memory. Depending on the buffer's location, the helper picks the
+ * correct method of accessing the memory.
+ */
+static inline void dma_buf_map_memcpy_to_offset(struct dma_buf_map *dst, 
size_t offset,
+   const void *src, size_t len)
+{
+   if (dst->is_iomem)
+   memcpy_toio(dst->vaddr_iomem + offset, src, len);
+   else
+   memcpy(dst->vaddr + offset, src, len);
+}
+
+/**
+ * dma_buf_map_memcpy_from_offset - Memcpy from offset of dma-buf mapping into 
system memory
+ * @dst:   Destination in system memory
+ * @src:   The dma-buf mapping structure
+ * @src:   The offset from which to copy
+ * @len:   The number of byte in src
+ *
+ * Copies data from a dma-buf mapping with an offset. The dest buffer is in
+ * system memory. Depending on the mapping location, the helper picks the
+ * correct method of accessing the memory.
+ */
+static inline void dma_buf_map_memcpy_from_offset(void *dst, const struct 
dma_buf_map *src,
+ size_t offset, size_t len)
+{
+   if (src->is_iomem)
+   memcpy_fromio(dst, src->vaddr_iomem + offset, len);
+   else
+   memcpy(dst, src->vaddr + offset, len);
+}
+


Well that's certainly a valid use case, but I suggest to change the 
implementation of the existing functions to call the new ones with offset=0.


This way we only have one implementation.


  /**
   * dma_buf_map_memcpy_to - Memcpy into dma-buf mapping
   * @dst:  The dma-buf mapping structure
@@ -263,4 +304,44 @@ static inline void dma_buf_map_incr(struct dma_buf_map 
*map, size_t incr)
map->vaddr += incr;
  }
  
+/**

+ * dma_buf_map_read_field - Read struct member from dma-buf mapping with
+ * arbitrary size and handling un-aligned accesses
+ *
+ * @map__: The dma-buf mapping structure
+ * @type__:The struct to be used containing the field to read
+ * @field__:   Member from struct we want to read
+ *
+ * Read a value from dma-buf mapping calculating the offset and size: this 
assumes
+ * the dma-buf mapping is aligned with a a struct type__. A single u8, u16, u32
+ * or u64 can be read, based on the offset and size of type__.field__.
+ */
+#define dma_buf_map_read_field(map__, type__, field__) ({  
\
+   type__ *t__;
\
+   typeof(t__->field__) val__; 
 \
+   dma_buf_map_memcpy_from_offset(&val__, map__, offsetof(type__, 
field__),\
+  sizeof(t__->field__));   
 \
+   val__;  
\
+})
+
+/**
+ * dma_buf_map_write_field - Write struct member to the dma-buf mapping with
+ * arbitrary size and handling un-aligned accesses
+ *
+ * @map__: The dma-buf mapping structure
+ * @type__:The struct to be used containing the field to write
+ * @field__:   Member from struct we want to write
+ * @val__: