summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKartik <kkartik@nvidia.com>2023-10-17 10:53:15 +0530
committerThierry Reding <treding@nvidia.com>2024-02-01 15:58:05 +0100
commit7092e9b3bed1252c7d3f5812b9fb9d82375b73a6 (patch)
treef394199a150ef9400a8967586a481d87e4e14768
parent9863084dd9939e53eb67a689f13503e8025434ac (diff)
downloadlinux-7092e9b3bed1252c7d3f5812b9fb9d82375b73a6.tar.gz
linux-7092e9b3bed1252c7d3f5812b9fb9d82375b73a6.tar.bz2
linux-7092e9b3bed1252c7d3f5812b9fb9d82375b73a6.zip
mm/util: Introduce kmemdup_array()
Introduce kmemdup_array() API to duplicate `n` number of elements from a given array. This internally uses kmemdup to allocate and duplicate the `src` array. Signed-off-by: Kartik <kkartik@nvidia.com> Acked-by: Kees Cook <keescook@chromium.org> Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--include/linux/string.h1
-rw-r--r--mm/util.c17
2 files changed, 18 insertions, 0 deletions
diff --git a/include/linux/string.h b/include/linux/string.h
index ab148d8dbfc1..4795ee5c50c6 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -217,6 +217,7 @@ extern char *kstrndup(const char *s, size_t len, gfp_t gfp);
extern void *kmemdup(const void *src, size_t len, gfp_t gfp) __realloc_size(2);
extern void *kvmemdup(const void *src, size_t len, gfp_t gfp) __realloc_size(2);
extern char *kmemdup_nul(const char *s, size_t len, gfp_t gfp);
+extern void *kmemdup_array(const void *src, size_t element_size, size_t count, gfp_t gfp);
extern char **argv_split(gfp_t gfp, const char *str, int *argcp);
extern void argv_free(char **argv);
diff --git a/mm/util.c b/mm/util.c
index 5a6a9802583b..5faf3adc6f43 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -136,6 +136,23 @@ void *kmemdup(const void *src, size_t len, gfp_t gfp)
EXPORT_SYMBOL(kmemdup);
/**
+ * kmemdup_array - duplicate a given array.
+ *
+ * @src: array to duplicate.
+ * @element_size: size of each element of array.
+ * @count: number of elements to duplicate from array.
+ * @gfp: GFP mask to use.
+ *
+ * Return: duplicated array of @src or %NULL in case of error,
+ * result is physically contiguous. Use kfree() to free.
+ */
+void *kmemdup_array(const void *src, size_t element_size, size_t count, gfp_t gfp)
+{
+ return kmemdup(src, size_mul(element_size, count), gfp);
+}
+EXPORT_SYMBOL(kmemdup_array);
+
+/**
* kvmemdup - duplicate region of memory
*
* @src: memory region to duplicate