@@ -46,11 +46,13 @@
#include <rdma/ib_verbs.h>
#include <rdma/ib_umem.h>
#include <rdma/ib_user_verbs.h>
+#include <rdma/ib_user_ioctl.h>
#define INIT_UDATA(udata, ibuf, obuf, ilen, olen) \
do { \
(udata)->inbuf = (const void __user *) (ibuf); \
(udata)->outbuf = (void __user *) (obuf); \
+ (udata)->outptr = (void __user *)(obuf); \
(udata)->inlen = (ilen); \
(udata)->outlen = (olen); \
} while (0)
@@ -59,6 +61,7 @@
do { \
(udata)->inbuf = (ilen) ? (const void __user *) (ibuf) : NULL; \
(udata)->outbuf = (olen) ? (void __user *) (obuf) : NULL; \
+ (udata)->outptr = (olen) ? (void __user *)(obuf) : NULL; \
(udata)->inlen = (ilen); \
(udata)->outlen = (olen); \
} while (0)
@@ -1360,6 +1360,7 @@ struct ib_uobject {
struct ib_udata {
const void __user *inbuf;
void __user *outbuf;
+ void __user *outptr;
size_t inlen;
size_t outlen;
};
@@ -1990,7 +1991,12 @@ static inline int ib_copy_from_udata(void *dest, struct ib_udata *udata, size_t
static inline int ib_copy_to_udata(struct ib_udata *udata, void *src, size_t len)
{
- return copy_to_user(udata->outbuf, src, len) ? -EFAULT : 0;
+ int ret = copy_to_user(udata->outptr, src, len) ? -EFAULT : 0;
+
+ if (!ret)
+ udata->outptr += len;
+
+ return ret;
}
static inline bool ib_is_udata_cleared(struct ib_udata *udata,