aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhenlei Huang <zlei@FreeBSD.org>2026-02-28 11:35:42 +0000
committerZhenlei Huang <zlei@FreeBSD.org>2026-02-28 11:35:42 +0000
commit32beb3ae71cb320dbe4190a01c036943d99083b3 (patch)
treeb4a9e8a84cda8f24d1b24bed985042fac28a5bc5
parentd44d79e577eab3e66b993c783b969b82678792d1 (diff)
vnet: Ensure the space allocated by vnet_data_alloc() is sufficent aligned
Some 32-bit architectures, e.g., armv7, require strict 8-byte alignment while doing atomic 64-bit access. Hence aligning to the pointer type (4-byte alignment) does not meet the requirement on those architectures. Make the space allocated by vnet_data_alloc() sufficent aligned to avoid unaligned access. PR: 265639 Diagnosed by: markj Reviewed by: jhb, markj Co-authored-by: jhb MFC after: 5 days Differential Revision: https://reviews.freebsd.org/D55560
-rw-r--r--sys/net/vnet.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/sys/net/vnet.c b/sys/net/vnet.c
index a2b827052dd3..5ef68d11227a 100644
--- a/sys/net/vnet.c
+++ b/sys/net/vnet.c
@@ -172,10 +172,16 @@ static MALLOC_DEFINE(M_VNET_DATA, "vnet_data", "VNET data");
#define VNET_SIZE roundup2(VNET_BYTES, PAGE_SIZE)
/*
+ * Ensure space allocated by vnet_data_alloc() is suitably aligned for any
+ * object.
+ */
+#define VNET_DATAALIGN _Alignof(__max_align_t)
+
+/*
* Space to store virtualized global variables from loadable kernel modules,
* and the free list to manage it.
*/
-VNET_DEFINE_STATIC(char, modspace[VNET_MODMIN] __aligned(__alignof(void *)));
+VNET_DEFINE_STATIC(char, modspace[VNET_MODMIN] __aligned(VNET_DATAALIGN));
/*
* A copy of the initial values of all virtualized global variables.
@@ -385,7 +391,7 @@ vnet_data_alloc(int size)
void *s;
s = NULL;
- size = roundup2(size, sizeof(void *));
+ size = roundup2(size, VNET_DATAALIGN);
sx_xlock(&vnet_data_free_lock);
TAILQ_FOREACH(df, &vnet_data_free_head, vnd_link) {
if (df->vnd_len < size)
@@ -403,6 +409,8 @@ vnet_data_alloc(int size)
}
sx_xunlock(&vnet_data_free_lock);
+ KASSERT(((uintptr_t)s & (VNET_DATAALIGN - 1)) == 0,
+ ("unaligned vnet alloc %p", s));
return (s);
}
@@ -417,7 +425,7 @@ vnet_data_free(void *start_arg, int size)
uintptr_t start;
uintptr_t end;
- size = roundup2(size, sizeof(void *));
+ size = roundup2(size, VNET_DATAALIGN);
start = (uintptr_t)start_arg;
end = start + size;
/*