diff --git a/sys/compat/linuxkpi/common/include/linux/slab.h b/sys/compat/linuxkpi/common/include/linux/slab.h --- a/sys/compat/linuxkpi/common/include/linux/slab.h +++ b/sys/compat/linuxkpi/common/include/linux/slab.h @@ -41,6 +41,8 @@ MALLOC_DECLARE(M_KMALLOC); +void *lkpi_mallocarray(size_t, size_t, gfp_t); + #define kmalloc(size, flags) lkpi_kmalloc(size, flags) #define kvmalloc(size, flags) kmalloc(size, flags) #define kvzalloc(size, flags) kmalloc(size, (flags) | __GFP_ZERO) @@ -121,7 +123,7 @@ kcalloc(size_t n, size_t size, gfp_t flags) { flags |= __GFP_ZERO; - return (mallocarray(n, size, M_KMALLOC, linux_check_m_flags(flags))); + return (lkpi_mallocarray(n, size, linux_check_m_flags(flags))); } static inline void * @@ -154,7 +156,7 @@ static inline void * kmalloc_array(size_t n, size_t size, gfp_t flags) { - return (mallocarray(n, size, M_KMALLOC, linux_check_m_flags(flags))); + return (lkpi_mallocarray(n, size, linux_check_m_flags(flags))); } static inline void * @@ -167,7 +169,7 @@ static inline void * kvmalloc_array(size_t n, size_t size, gfp_t flags) { - return (mallocarray(n, size, M_KMALLOC, linux_check_m_flags(flags))); + return (lkpi_mallocarray(n, size, linux_check_m_flags(flags))); } static inline void * diff --git a/sys/compat/linuxkpi/common/src/linux_slab.c b/sys/compat/linuxkpi/common/src/linux_slab.c --- a/sys/compat/linuxkpi/common/src/linux_slab.c +++ b/sys/compat/linuxkpi/common/src/linux_slab.c @@ -260,3 +260,12 @@ llist_add(addr, &linux_kfree_async_list); taskqueue_enqueue(linux_irq_work_tq, &linux_kfree_async_task); } + +void * +lkpi_mallocarray(size_t n, size_t size, gfp_t flags) +{ + if (WOULD_OVERFLOW(n, size)) + panic("%s: %zu * %zu overflowed", __func__, n, size); + + return (__kmalloc(size * n, flags)); +}