From: "Garg, Shivank" <shivankg@amd.com>
To: "pbonzini@redhat.com" <pbonzini@redhat.com>,
"seanjc@google.com" <seanjc@google.com>
Cc: "kvm@vger.kernel.org" <kvm@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH 1/7] KVM: selftests: Account for kernel's off-by-one bug in NUMA node syscalls
Date: Sun, 6 Sep 2026 10:08:45 +0000 [thread overview]
Message-ID: <ef6ef8be43d667f9cce9780b3c54e397ee31fe3b.camel@amd.com> (raw)
In-Reply-To: <20260903001625.2792367-2-seanjc@google.com>
On Wed, 2026-09-02 at 17:16 -0700, Sean Christopherson wrote:
> Add and use MAXNODE_FOR_MASK() to compute the "correct" maxnode value that
> is passed to various NUMA-related syscalls, e.g. get_mempolicy(), mbind(),
> migrate_pages(), etc. In quotes, because the kernel has an undocumented,
> longstanding off-by-one bug that requires userspace to specify the number
> of bits plus one, i.e. the max node plus two.
>
> The kernel bug has been known since 2007[*]:
>
> : And this is I think the reason why we can't change this now. I assume
> : numactl allocates 1024 bits (0 to 1023) and passes 1025 to make sure all
> : 1024 bits are processed. If we change it now, kernel will process 1025
> : bits (0 to 1024) and overflow the allocated bitmask. If it happens to be
> : at the border of mmaped vma, it's a segfault...
>
> But unfortunately the manpages haven't yet been updated, e.g.
>
> : The maxnode argument is the maximum node number in the bit mask plus one
>
> Link: https://lore.kernel.org/all/63ccc890-fd57-118b-5997-e0259f507d28@suse.cz[*]
> Signed-off-by: Sean Christopherson <seanjc@google.com>
> ---
> tools/testing/selftests/kvm/guest_memfd_test.c | 2 +-
> tools/testing/selftests/kvm/include/numaif.h | 11 +++++++++++
> tools/testing/selftests/kvm/x86/xapic_ipi_test.c | 2 +-
> 3 files changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/guest_memfd_test.c b/tools/testing/selftests/kvm/guest_memfd_test.c
> index 2233d871a38f..cd5df88bc642 100644
> --- a/tools/testing/selftests/kvm/guest_memfd_test.c
> +++ b/tools/testing/selftests/kvm/guest_memfd_test.c
> @@ -80,7 +80,7 @@ static void test_mbind(int fd, size_t total_size)
> {
> const unsigned long nodemask_0 = 1; /* nid: 0 */
> unsigned long nodemask = 0;
> - unsigned long maxnode = BITS_PER_TYPE(nodemask);
> + unsigned long maxnode = MAXNODE_FOR_MASK(nodemask);
> int policy;
> char *mem;
> int ret;
> diff --git a/tools/testing/selftests/kvm/include/numaif.h b/tools/testing/selftests/kvm/include/numaif.h
> index 29572a6d789c..71f261eafc90 100644
> --- a/tools/testing/selftests/kvm/include/numaif.h
> +++ b/tools/testing/selftests/kvm/include/numaif.h
> @@ -6,6 +6,7 @@
>
> #include <dirent.h>
>
> +#include <linux/bitops.h>
> #include <linux/mempolicy.h>
>
> #include "kvm_syscalls.h"
> @@ -30,6 +31,16 @@ KVM_SYSCALL_DEFINE(mbind, 6, void *, addr, unsigned long, size, int, mode,
> const unsigned long *, nodemask, unsigned long, maxnode,
> unsigned int, flags);
>
> +/*
> + * Calculate the @maxnode param for the above syscalls given the mask that will
> + * be passed to the kernel, to account for a longstanding off-by-one bug in the
> + * kernel that isn't properly documented in the manpages. The manpages say
> + * that @maxnode is "the maximum node ID plus one", but the kernel's actual
> + * behavior is "the number of bits in the mask plus one", i.e. "the maximum
> + * node ID plus two".
> + */
> +#define MAXNODE_FOR_MASK(mask) (BITS_PER_TYPE(mask) + 1)
> +
> static inline int get_max_numa_node(void)
> {
> struct dirent *de;
> diff --git a/tools/testing/selftests/kvm/x86/xapic_ipi_test.c b/tools/testing/selftests/kvm/x86/xapic_ipi_test.c
> index 469e3ab16460..1ddcf95d7fe4 100644
> --- a/tools/testing/selftests/kvm/x86/xapic_ipi_test.c
> +++ b/tools/testing/selftests/kvm/x86/xapic_ipi_test.c
> @@ -248,7 +248,7 @@ void do_migrations(struct test_data_page *data, int run_secs, int delay_usecs,
> delay_usecs);
>
> /* Get set of first 64 numa nodes available */
> - kvm_get_mempolicy(NULL, &nodemask, sizeof(nodemask) * 8,
> + kvm_get_mempolicy(NULL, &nodemask, MAXNODE_FOR_MASK(nodemask),
> 0, MPOL_F_MEMS_ALLOWED);
>
> fprintf(stderr, "Numa nodes found amongst first %lu possible nodes "
LGTM!
Reviewed-by: Shivank Garg <shivankg@amd.com>
Thanks,
Shivank
next prev parent reply other threads:[~2026-09-06 10:08 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-03 0:16 [PATCH 0/7] KVM: selftests: Fix maxnodes bugs and cleanup related code Sean Christopherson
2026-09-03 0:16 ` [PATCH 1/7] KVM: selftests: Account for kernel's off-by-one bug in NUMA node syscalls Sean Christopherson
2026-09-06 10:08 ` Garg, Shivank [this message]
2026-09-03 0:16 ` [PATCH 2/7] KVM: selftests: Fix maxnode argument to migrate_pages() in xapic_ipi_test Sean Christopherson
2026-09-03 0:16 ` [PATCH 3/7] KVM: selftests: use BITS_PER_TYPE() for NUMA masks Sean Christopherson
2026-09-03 0:16 ` [PATCH 4/7] KVM: selftests: Compute node masks on-demand in xAPIC IPI test Sean Christopherson
2026-09-06 17:05 ` Garg, Shivank
2026-09-03 0:16 ` [PATCH 5/7] KVM: selftests: Add common helper to get mask+number of usable memory NUMA nodes Sean Christopherson
2026-09-06 17:53 ` Garg, Shivank
2026-09-03 0:16 ` [PATCH 6/7] KVM: selftests: Automatically run xAPIC IPI migration test when possible Sean Christopherson
2026-09-06 18:01 ` Garg, Shivank
2026-09-03 0:16 ` [PATCH 7/7] KVM: selftests: Skip xAPIC IPI migration test when forced but unsupported Sean Christopherson
2026-09-06 18:13 ` Garg, Shivank
2026-09-21 14:05 ` [PATCH 0/7] KVM: selftests: Fix maxnodes bugs and cleanup related code Sean Christopherson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ef6ef8be43d667f9cce9780b3c54e397ee31fe3b.camel@amd.com \
--to=shivankg@amd.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=seanjc@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.