anitazha / rpms / ndctl

Forked from rpms/ndctl a year ago
Clone

Blame 0034-util-add-the-struct_size-helper-from-the-kernel.patch

Jeff Moyer 2c91dc
From 7aa7c7be6e803de267a165237e23577ab496e792 Mon Sep 17 00:00:00 2001
Jeff Moyer 2c91dc
From: Vishal Verma <vishal.l.verma@intel.com>
Jeff Moyer 2c91dc
Date: Thu, 7 Oct 2021 02:21:26 -0600
Jeff Moyer 2c91dc
Subject: [PATCH 034/217] util: add the struct_size() helper from the kernel
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
Add struct_size() from include/linux/overflow.h which calculates the
Jeff Moyer 2c91dc
size of a struct with a trailing variable length array.
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
Suggested-by: Dan Williams <dan.j.williams@intel.com>
Jeff Moyer 2c91dc
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Jeff Moyer 2c91dc
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
Jeff Moyer 2c91dc
---
Jeff Moyer 2c91dc
 util/size.h | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++
Jeff Moyer 2c91dc
 util/util.h |  6 ++++++
Jeff Moyer 2c91dc
 2 files changed, 68 insertions(+)
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
diff --git a/util/size.h b/util/size.h
Jeff Moyer 2c91dc
index 646edae..a0f3593 100644
Jeff Moyer 2c91dc
--- a/util/size.h
Jeff Moyer 2c91dc
+++ b/util/size.h
Jeff Moyer 2c91dc
@@ -4,6 +4,8 @@
Jeff Moyer 2c91dc
 #ifndef _NDCTL_SIZE_H_
Jeff Moyer 2c91dc
 #define _NDCTL_SIZE_H_
Jeff Moyer 2c91dc
 #include <stdbool.h>
Jeff Moyer 2c91dc
+#include <stdint.h>
Jeff Moyer 2c91dc
+#include <util/util.h>
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
 #define SZ_1K     0x00000400
Jeff Moyer 2c91dc
 #define SZ_4K     0x00001000
Jeff Moyer 2c91dc
@@ -30,4 +32,64 @@ static inline bool is_power_of_2(unsigned long long v)
Jeff Moyer 2c91dc
 #define BITS_PER_LONG (sizeof(unsigned long) * 8)
Jeff Moyer 2c91dc
 #define HPAGE_SIZE (2 << 20)
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
+/*
Jeff Moyer 2c91dc
+ * Helpers for struct_size() copied from include/linux/overflow.h (GPL-2.0)
Jeff Moyer 2c91dc
+ *
Jeff Moyer 2c91dc
+ * For simplicity and code hygiene, the fallback code below insists on
Jeff Moyer 2c91dc
+ * a, b and *d having the same type (similar to the min() and max()
Jeff Moyer 2c91dc
+ * macros), whereas gcc's type-generic overflow checkers accept
Jeff Moyer 2c91dc
+ * different types. Hence we don't just make check_add_overflow an
Jeff Moyer 2c91dc
+ * alias for __builtin_add_overflow, but add type checks similar to
Jeff Moyer 2c91dc
+ * below.
Jeff Moyer 2c91dc
+ */
Jeff Moyer 2c91dc
+#define check_add_overflow(a, b, d) (({	\
Jeff Moyer 2c91dc
+	typeof(a) __a = (a);			\
Jeff Moyer 2c91dc
+	typeof(b) __b = (b);			\
Jeff Moyer 2c91dc
+	typeof(d) __d = (d);			\
Jeff Moyer 2c91dc
+	(void) (&__a == &__b);			\
Jeff Moyer 2c91dc
+	(void) (&__a == __d);			\
Jeff Moyer 2c91dc
+	__builtin_add_overflow(__a, __b, __d);	\
Jeff Moyer 2c91dc
+}))
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+#define check_mul_overflow(a, b, d) (({	\
Jeff Moyer 2c91dc
+	typeof(a) __a = (a);			\
Jeff Moyer 2c91dc
+	typeof(b) __b = (b);			\
Jeff Moyer 2c91dc
+	typeof(d) __d = (d);			\
Jeff Moyer 2c91dc
+	(void) (&__a == &__b);			\
Jeff Moyer 2c91dc
+	(void) (&__a == __d);			\
Jeff Moyer 2c91dc
+	__builtin_mul_overflow(__a, __b, __d);	\
Jeff Moyer 2c91dc
+}))
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+/*
Jeff Moyer 2c91dc
+ * Compute a*b+c, returning SIZE_MAX on overflow. Internal helper for
Jeff Moyer 2c91dc
+ * struct_size() below.
Jeff Moyer 2c91dc
+ */
Jeff Moyer 2c91dc
+static inline size_t __ab_c_size(size_t a, size_t b, size_t c)
Jeff Moyer 2c91dc
+{
Jeff Moyer 2c91dc
+	size_t bytes;
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	if (check_mul_overflow(a, b, &bytes))
Jeff Moyer 2c91dc
+		return SIZE_MAX;
Jeff Moyer 2c91dc
+	if (check_add_overflow(bytes, c, &bytes))
Jeff Moyer 2c91dc
+		return SIZE_MAX;
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	return bytes;
Jeff Moyer 2c91dc
+}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+/**
Jeff Moyer 2c91dc
+ * struct_size() - Calculate size of structure with trailing array.
Jeff Moyer 2c91dc
+ * @p: Pointer to the structure.
Jeff Moyer 2c91dc
+ * @member: Name of the array member.
Jeff Moyer 2c91dc
+ * @count: Number of elements in the array.
Jeff Moyer 2c91dc
+ *
Jeff Moyer 2c91dc
+ * Calculates size of memory needed for structure @p followed by an
Jeff Moyer 2c91dc
+ * array of @count number of @member elements.
Jeff Moyer 2c91dc
+ *
Jeff Moyer 2c91dc
+ * Return: number of bytes needed or SIZE_MAX on overflow.
Jeff Moyer 2c91dc
+ */
Jeff Moyer 2c91dc
+#define struct_size(p, member, count)					\
Jeff Moyer 2c91dc
+	__ab_c_size(count,						\
Jeff Moyer 2c91dc
+		    sizeof(*(p)->member) + __must_be_array((p)->member),\
Jeff Moyer 2c91dc
+		    sizeof(*(p)))
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
 #endif /* _NDCTL_SIZE_H_ */
Jeff Moyer 2c91dc
diff --git a/util/util.h b/util/util.h
Jeff Moyer 2c91dc
index ae0e4e1..b2b4ae6 100644
Jeff Moyer 2c91dc
--- a/util/util.h
Jeff Moyer 2c91dc
+++ b/util/util.h
Jeff Moyer 2c91dc
@@ -63,6 +63,12 @@
Jeff Moyer 2c91dc
 #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
Jeff Moyer 2c91dc
 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
+/* Are two types/vars the same type (ignoring qualifiers)? */
Jeff Moyer 2c91dc
+#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+/* &a[0] degrades to a pointer: a different type from an array */
Jeff Moyer 2c91dc
+#define __must_be_array(a)	BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
 enum {
Jeff Moyer 2c91dc
 	READ, WRITE,
Jeff Moyer 2c91dc
 };
Jeff Moyer 2c91dc
-- 
Jeff Moyer 2c91dc
2.27.0
Jeff Moyer 2c91dc