From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jiri Benc <jbenc@redhat.com>
Date: Wed, 19 Feb 2020 11:52:19 +0100
Subject: [PATCH] redhat: rh_kabi: introduce RH_KABI_EXTEND_WITH_SIZE
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

RH-Acked-by: Toke Høiland-Jørgensen <toke@redhat.com>
RH-Acked-by: Hangbin Liu <haliu@redhat.com>

Upstream status: RHEL only

This allows addition of a struct into struct while reserving extra space.
See the documentation in rh_kabi.h for details.

The check for size is automatically disabled in -debug kernels that have
many fields larger than the production kernels (mutexes etc.) and that are
not under kABI guarantee.

I'm also moving a misplaced comment for RH_KABI_FILL_HOLE.

(Pointed out by Sabrina:) We need to force align the added field to 8 byte
offset. Otherwise, if the required alignment of the added field changed
later (e.g. it was a structure with only a single field that was changed
from int to char) and the previous field was smaller than long, it could
lead to the whole union shifting position and offsets of the following
fields could change. It's also safer to align the size, too.

Let the 'size' parameter specify number of longs to be added and not number
of bytes. Note we assume a 64 bit architecture, which is the case for RHEL.

Upstream Status: RHEL only
Signed-off-by: Jiri Benc <jbenc@redhat.com>
---
 include/linux/rh_kabi.h | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/include/linux/rh_kabi.h b/include/linux/rh_kabi.h
index cdc636d3013d..4debb7aaad48 100644
--- a/include/linux/rh_kabi.h
+++ b/include/linux/rh_kabi.h
@@ -45,11 +45,24 @@
  * RH_KABI_EXTEND
  *   Simple macro for adding a new element to a struct.
  *
- *   Warning: only use if a hole exists for _all_ arches.  Use pahole to verify.
+ * RH_KABI_EXTEND_WITH_SIZE
+ *   Adds a new element (usually a struct) to a struct and reserves extra
+ *   space for the new element.  The provided 'size' is the total space to
+ *   be added in longs (i.e. it's 8 * 'size' bytes), including the size of
+ *   the added element.  It is automatically checked that the new element
+ *   does not overflow the reserved space, now nor in the future. However,
+ *   no attempt is done to check the content of the added element (struct)
+ *   for kABI conformance - kABI checking inside the added element is
+ *   effectively switched off.
+ *   For any struct being added by RH_KABI_EXTEND_WITH_SIZE, it is
+ *   recommended its content to be documented as not covered by kABI
+ *   guarantee.
  *
  * RH_KABI_FILL_HOLE
  *   Simple macro for filling a hole in a struct.
  *
+ *   Warning: only use if a hole exists for _all_ arches.  Use pahole to verify.
+ *
  * RH_KABI_RENAME
  *   Simple macro for renaming an element without changing its type.  This
  *   macro can be used in bitfields, for example.
@@ -133,8 +146,12 @@
 		_Static_assert(__alignof__(struct{_new;}) <= __alignof__(struct{_orig;}), \
 			       __FILE__ ":" __stringify(__LINE__) ": "  __stringify(_orig) " is not aligned the same as " __stringify(_new) RH_KABI_ALIGN_WARNING); \
 	}
+# define __RH_KABI_CHECK_SIZE(_item, _size)				\
+	_Static_assert(sizeof(struct{_item;}) <= _size,			\
+		       __FILE__ ":" __stringify(__LINE__) ": " __stringify(_item) " is larger than the reserved size (" __stringify(_size) " bytes)" RH_KABI_ALIGN_WARNING)
 #else
 # define __RH_KABI_CHECK_SIZE_ALIGN(_orig, _new)
+# define __RH_KABI_CHECK_SIZE(_item, _size)
 #endif

 # define _RH_KABI_DEPRECATE(_type, _orig)	_type rh_reserved_##_orig
@@ -186,6 +203,16 @@

 #define RH_KABI_EXCLUDE(_elem)		_RH_KABI_EXCLUDE(_elem);

+/*
+ * Extending a struct while reserving extra space.
+ */
+#define RH_KABI_EXTEND_WITH_SIZE(_new, _size)				\
+	RH_KABI_EXTEND(union {						\
+		_new;							\
+		unsigned long __UNIQUE_ID(rh_kabi_reserved)[_size];	\
+		__RH_KABI_CHECK_SIZE(_new, 8 * (_size));		\
+	})
+
 /*
  * RHEL macros to extend structs.
  *
-- 
2.26.2

